背景:
用的ThinkPHP5的框架。(相比之前的3.2版本,版本5都用了PDO處理數據庫)
症狀:
報錯信息:
SQLSTATE[HY000]: General error: 1243 Unknown prepared statement handler (1) given to mysqld_stmt_execute
具體的錯誤SQL,可能是任何一條正常的SQL。
不是每次必報錯,是偶爾,但是出現頻率較高。經過測試:1000次請求,可能會有30次錯誤。
錯誤排查:
本地測試,無問題(PHP直連MySQL)。
線上的ThinkPHP3.2系統,無問題(PHP通過MySQL-proxy代理連接數據庫)。
然后排查得出懷疑對象,線上的PHP PDO與MySQL-proxy。
然后給ThinkPHP5的數據庫配置加一條:
// 數據庫連接參數 'params' => [ PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_EMULATE_PREPARES => true, ],
線上線下測試,均未再出現此問題。
當然,這個解決方案並不是很好。預處理強制給PHP自身處理,不會更安全。但總歸是找到了問題所在。
感謝一起討論指點的朋友。
后記:用Mycat代理MySQL,無此報錯。不過要注意一點:因為Mycat是JAVA開發的,所以對數據庫里時間的字段,不能值為 0000-00-00 00:00:00,會報錯。
以及感謝如下參考:
http://www.thinkphp.cn/topic/47606.html
https://www.jb51.net/article/56612.htm
http://php.net/manual/zh/pdo.setattribute.php
https://www.kancloud.cn/manual/thinkphp5/211524
https://segmentfault.com/q/1010000012302149/a-1020000013069236
題外: