背景
- 近期對負責項目,配置了一套 主從復制的
MySQL
集群
使用了中間件mycat
但測試發現,替換了原來的數據連接后,會出現Packets out of order
的報錯
同時注意到,有的框架代碼中竟然也會失效,比如 controller 類中,獲取
$request->all()
竟然變空了
分析、排查
- 首先,切換
mycat
后,程序報錯的一段源碼如下:
[2024-07-04 10:48:58] local.ERROR: Packets out of order. Expected 1 received 5. Packet size=85 (SQL: select `cms_password_resets`.* where `memberid` = 122 and `cms_password_resets`.`deleted_at` is null order by `id` desc) at D:\\phpstudy_pro\\WWW\\projzqb1b\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Connection.php:664, ErrorException(code: 0): Packets out of order. Expected 1 received 5. Packet size=85 at D:\\phpstudy_pro\\WWW\\projzqb1b\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Connection.php:332)
- 另外一段報錯源碼如下 (也是跟數據庫連接有關):
[2024-07-04 16:14:53] local.ERROR: Allowed memory size of 268435456 bytes exhausted (tried to allocate 842087056 bytes) {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalErrorException(code: 1): Allowed memory size of 268435456 bytes exhausted (tried to allocate 842087056 bytes) at D:\\phpstudy_pro\\WWW\\projzqb1b\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Connection.php:330)
[stacktrace]SQLSTATE[HY000]: General error: 1047 Unsupported statement
-
根據百度經驗,提示需要修改
mysql.cnf
中的max_allowed_packet
參數
但是,發現不應該是這個問題,畢竟不使用 mycat 時不會出現問題 -
繼續查找發現,這個問題的原因很可能是數據庫配置參數的 【預處理】問題
設置database.php
中的options
的預處理可以解決報錯 (但是查詢出來的數據全部轉為了字符串
)
因為上述的變動,代碼中的判斷,可能會出現問題,尤其是一些 數字類型的
===
比對
- 希望得到的結果:同時滿足 PDO::ATTR_EMULATE_PREPARES => true 和結果集數據類型不被隱式轉換
解決方案:Laravel取出mysql數據全部被轉成string類型問題
- 【建議】
配置使用了兩天,發現在laravel框架中,會出現很多問題
甚至還會出現其他未注意到的隱藏BUG
比如,當前測試發現,當使用事務時,也會報錯
通過百度經驗,基本定位在 mycat 的版本與適用性上,對于初步摸索的開發者來說
我認為,選用macat 不合適(且官方已不再維護,百度經驗也少)- 后面,探索 laravel 框架直接使用 主從配置,試試看吧
附錄
- 關于 MySQL 的 Packets out of order 問題
- thinkphp5+mycat 查詢出現 Packets out of order. Expected 4 received 0. Packet size=10
- Laravel連接mycat報錯?
- PDO::ATTR_EMULATE_PREPARES為True時如何避免結果集中Int類型被轉換為String