前幾天在羣裏有個朋友問到max_allowed_packet被自動重置的問題,於是打算寫個文章來描述下,因爲遇到這個問題的人不少,但是提到的解決方案幾乎沒有。
max_allowed_packet指的是服務器接收的包的大小,該值設置過小,可能導致數據寫入失敗,通常可以通過修改my.cnf或者在命令行通過set max_allowed_packet來實現。
但是在實際情況中,我們很多時候會遇到這樣的一種情況:通過各種方式設置了max_allowed_packet的值,但是一段時間後,max_allowed_packet還是莫名其妙的變成了1024,而my.cnf裏面的值還是之前設置的大於1024的值。
這個問題看起來很詭異,但是至少可以確定一點,那就是該值通過某某連接,在連接裏面通過set命令給重置了。
一般來說,引起該問題不外乎如下幾種情況:
設置不當
:設置該值需要修改my.cnf配置,但是一共需要設置兩處,如下:
[client]
max_allowed_packet=10240
[mysqld]
max_allowed_packet=10240
mysqld裏面控制的是服務端,mysql裏面控制的是客戶端,如果只設置一處,則當有客戶端連接的時候,該值會被重置。
內存不足
:當mysql執行大批次查詢語句大時候,因爲服務器內存不足,引起預警,mysql會重置這個值,已保證數據庫的穩定。
黑客攻擊
:其實在生產環境下,大多數的情況,還真是被攻擊了,針對這個情況,需要集中查看,安全不容小覷,mysql 有general_log, 會記錄所有執行的sql命令,因爲耗費性能,默認是關閉。
mysql> show variables like '%log%';
+-----------------------------------------+---------------------------------+
| Variable_name | Value |
+-----------------------------------------+---------------------------------+
| back_log | 50 |
| binlog_cache_size | 32768 |
| binlog_direct_non_transactional_updates | OFF |
| binlog_format | STATEMENT |
| expire_logs_days | 0 |
| general_log | OFF |
| general_log_file | /var/run/mysqld/mysqld.log |
打開general_log:
mysql> set global general_log = ON;
查看general_log:
tail -f /var/run/mysqld/mysqld.log |grep max_allowed_packet (查看log,但打印大量實時sql操作)
tail -f /var/run/mysqld/mysqld.log |grep max_allowed_packet >1.txt (過濾max_allowed_packet,並輸出到文件1.txt)
通過日誌查看修改的對應的ip地址,然後通過設置黑名單或者修改數據庫密碼來解決。
總結:生產環境下,應該絕對避免使用root作爲數據庫連接用戶,另外對授權需要嚴格控制,儘量不要分配給應用的賬戶修改配置的權限,這樣可以避免這類情況的發生,同時提升服務器的安全性。
轉自:http://www.bucry.com/archives/1872.html