數據庫:mysql5.6
framework: play framework 1.2.4
近日處理批量數據的insert,update,涉及的保存更新sql大概有18w。我的操作如下:
1)每次取1000條數據進行相關邏輯判斷,以及需要的保存操作;
2)每100條sql做一次transaction.commit。
今天在執行過程中,保存含有些Blob字段的數據表時,報錯如下:
Packet for query is too large ( 1663020 > 1048576 ). You can change this value on the server by setting the max_allowed_packet ' variable.
關於max_allowed_packet, 官方解釋 如下:
The maximum size of one packet or any generated/intermediate string, or any parameter sent by the mysql_stmt_send_long_data()
C API function. The default is 4MB as of MySQL 5.6.6, 1MB before that.
The packet message buffer is initialized to net_buffer_length
bytes, but can grow up to max_allowed_packet
bytes when needed. This value by default is small, to catch large (possibly incorrect) packets.
You must increase this value if you are using large BLOB
columns or long strings. It should be as big as the largest BLOB
you want to use. The protocol limit for max_allowed_packet
is 1GB. The value should be a multiple of 1024; nonmultiples are rounded down to the nearest multiple.
大致上看,max_allowed_packet是字符串緩沖區的最大長度。MySQL5.6.6默認值是4MB,之前版本默認值是1MB。如果我們使用blob類型或者其它常字符串類型字段,那么必須將max_allowed_packet值設置成我們需要的最大長度。
設置方式 官方 ,具體如下:
1)查看自己的max_allowed_packet,進入mysql console:mysql>show VARIABLES like '%max_allowed_packet%';
2.1)修改配置文件方式:unix,mac,linux的配置文件 my.cnf,windows的配置文件是my.cnf。配置中添加" max_allowed_packet =xxx" ,xxx為需要設置的長度,單位默認是比特。比如:max_allowed_packet=1024*1024,即max_allowed_packer設置成1MB。
2.2)命令行配置: set global max_allowed_packet = 1024*1024;
3)最后都需要重啟mysql服務才能生效。
以上是我查到了關於mysql設置選項max_allowed_packet的相關,我本地試過用2.2方式修改,成功了。
但是后來我發現我真正的問題是另一個字段設計上的遺漏,就是我給一張表加了2個blob的字段,對應到數據庫中是longtext類型。這兩個字段的值相同,然后沒條數據在保存的時候,都會向mysql字符緩沖區中放入這兩個blob,這才導致了數據packet過大,超過buffer限制。后來我刪了2個字段中的那個測試字段,job妥妥的執行下去了,也沒有卡住,或者越跑越慢的現象。
總之,又學到了一點。如果有什么理解錯的,務必請幫忙糾正,謝謝。
最后,貼一張上面的報錯截圖: