背景:php
用的ThinkPHP5的框架。(相比以前的3.2版本,版本5都用了PDO處理數據庫)html
症狀:mysql
報錯信息:sql
SQLSTATE[HY000]: General error: 1243 Unknown prepared statement handler (1) given to mysqld_stmt_execute
具體的錯誤SQL,多是任何一條正常的SQL。thinkphp
不是每次必報錯,是偶爾,可是出現頻率較高。通過測試:1000次請求,可能會有30次錯誤。數據庫
錯誤排查:segmentfault
本地測試,無問題(PHP直連MySQL)。安全
線上的ThinkPHP3.2系統,無問題(PHP經過MySQL-proxy代理鏈接數據庫)。框架
而後排查得出懷疑對象,線上的PHP PDO與MySQL-proxy。thinkphp5
而後給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
題外: