接手了同事的項目,其中有一個功能是保存郵件模板(包含圖片),同事之前的做法是把圖片進行base64編碼然后存在mysql數據庫中(字段類型為mediumtext)
然后保存三張圖片(大概400k)的時候報錯
MySQL server has gone away
然后查看官方文檔https://dev.mysql.com/doc/ref...
得知可能是以下幾個原因
服務器超時
服務器斷開
向服務器發送不正確或太大的查詢
INSERT或者 REPLACE是插入大量行
開始以為是服務器超時導致的,在網上搜的解決辦法(好吧,先試一下 ,發現還是不行):
<?php
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
PDO::ATTR_PERSISTENT => true
));
?>
Note:
如果想使用持久連接,必須在傳遞給 PDO 構造函數的驅動選項數組中設置 PDO::ATTR_PERSISTENT 。如果是在對象初始化之后用 PDO::setAttribute() 設置此屬性,則驅動程序將不會使用持久連接。
直接在Navicat上執行sql語句,報錯 [Err] 1153 - Got a packet bigger than 'max_allowed_packet' bytes
搜索得知:當MySQL客戶端或mysqld服務器收到大於max_allowed_packet字節的信息包時,將發出“信息包過大”錯誤,並關閉連接。對於某些客戶端,如果通信信息包過大,在執行查詢期間,可能會遇到“丟失與MySQL服務器的連接”錯誤。
客戶端和服務器均有自己的max_allowed_packet變量,因此,如你打算處理大的信息包,必須增加客戶端和服務器上的該變量。一般情況下,服務器默認max-allowed-packet為1MB
這下問題精確定位了,就是max_allowed_packet配置的問題,
查一下配置 show VARIABLES like '%max_allowed_packet%'; 發現是1048576(1024*1024),也就是1MB,
但是我的圖片才400K,不應該啊,然后網上一查:Base64-encoded 數據要比原始數據多占用 33% 左右的空間。
還是不確定,直接strlen()返回base64字符串長度1451334,utf8編碼下英文字符1字符占1字節,所以base64編碼后是1451334B(這個是我自己的理解),大於1MB
修改max_allowed_packet配置 set global max_allowed_packet = 410241024;
發現問題完美解決