mysql錯誤碼:2006-MySQL server has gone away詳解

mysql錯誤碼:2006-MySQL server has gone away詳解

1.背景

代碼測試過程中發現程序運行一段時間之後mysql數據庫就報2006的錯誤碼,程序重啓之後恢復正常。

2.產生原因與解決方案一(mysql長連接)

2.1.mysql_ping與mysql長連接(此方案適用於解決代碼開發中遇到的mysql錯誤碼:2006—治標又治本)

重點參考有"//20190730 changlq add 修復mysql長連接長時間沒有操作會被自動關閉的bug,錯誤信息:2006:MySQL server has gone away"的兩塊代碼

#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include<mysql/mysql.h>
void free_conn(MYSQL *mysql){
	mysql_close(mysql);
	free(mysql);
}
int main(){
  /* gcc -o mysql_eg mysql_eg.c -L /usr/lib64/mysql -lmysqlclient */
  MYSQL *my_con=(MYSQL *)malloc(sizeof(MYSQL));
  my_con=mysql_init(my_con);
  if(!my_con){
    printf("mysql_init error\n");
    return -1;
  }
  my_con=mysql_real_connect(my_con,"db_ip","db_name","db_pass","db_name",3306,NULL,0);
  if(my_con){
    printf("connect success!\n");
    
    //20190730 changlq add 修復mysql長連接長時間沒有操作會被自動關閉的bug,錯誤信息:2006:MySQL server has gone away
    char value = 1;
    int mo_flag=mysql_options(my_con, MYSQL_OPT_RECONNECT, &value);
    if(mo_flag!=0){
    	printf("mysql_options set fail\n");
    }
    
  }else{
  	printf("connect fail![errno:%d][error:%s][sqlstat:%s]\n",mysql_errno(my_con),mysql_error(my_con),mysql_sqlstate(my_con));
  }
  
  int i=0;
  char *alo_sql_str=(char *)malloc(2048);
  while(i++<10){
  	//20190730 changlq add 修復mysql長連接長時間沒有操作會被自動關閉的bug,錯誤信息:2006:MySQL server has gone away
  	//20190730 changlq add 每次循環都監聽一次數據庫連接
	int mp_local_flag=mysql_ping(my_con);
	if(mp_local_flag!=0){
      printf("mysql_ping local operation fail");
    }
    
    /* 一次執行多條語句+讀完整個resault集 */
    memset(alo_sql_str,0x00,2048);
    sprintf(alo_sql_str,"LOCK TABLES test_table WRITE;INSERT INTO test_table VALUES(10);UNLOCK TABLES");
    // 執行多條語句:功能打開-多語句執行-功能關閉
    mysql_set_server_option(my_con,MYSQL_OPTION_MULTI_STATEMENTS_ON);
    int res=mysql_query(my_con,alo_sql_str);
    mysql_set_server_option(my_con,MYSQL_OPTION_MULTI_STATEMENTS_OFF);
    if(res != 0){
      printf("insert fail,msg:[%s]", alo_sql_str );
      free(alo_sql_str);
      free_conn(my_con);
      return -1;
    }
    // 當使用執行多語句功能後,一定要讀完整個resault集,否則會出現錯誤:erron:2014 error:Commands out of sync; you can't run this command now 
    MYSQL_RES    *my_res; //查詢結果
    do
    {
        my_res = mysql_store_result( my_con );
        if(my_res) mysql_free_result(my_res);
    }while( !mysql_next_result(my_con) );  /* more my_con? -1 = no, >0 = error, 0 = yes (keep looping) */
  }
  free(alo_sql_str);
  free_conn(my_con);
  return 0;
}

2.2.調整數據庫相關參數閾值(此方案適用於臨時解決錯誤碼:2006—治標不治本)

2.2.1 找到mysql配置文件/etc/my.cnf,加入以下代碼
wait_timeout=288000 # 參數含義:服務器關閉交互式連接前等待活動的秒數。
interactive_timeout = 288000 # 參數含義:服務器關閉非交互連接之前等待活動的秒數。
相關參數詳解
2.2.2 重啓MySQL數據庫
service mysql restart

3.產生原因與解決方案二(數據庫max_allowed_packet參數限制)

3.1調整數據庫參數max_allowed_packet閾值

3.1.1 臨時調整max_allowed_packet閾值

mysql> show global variables like 'max_allowed_packet';
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 1048576 |
+--------------------+---------+
1 row in set (0.00 sec)
mysql> set global max_allowed_packet=1024*1024*16;

3.1.2 永久調整max_allowed_packet閾值
a. 查看現有閾值

[root@localhost:/root]#cat /etc/my.cnf | grep "max_allowed_packet"
max_allowed_packet = 1M

b. 修改閾值

[root@localhost:/root]#sed -i 's/max_allowed_packet = 1M/max_allowed_packet = 16M/g' /etc/my.cnf
[root@localhost:/root]#cat /etc/my.cnf | grep "max_allowed_packet"
max_allowed_packet = 16M

c. 重啓MySQL數據庫
service mysql restart

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章