MySQL Proxy 作為中間件實現讀寫分離,早期版本(0.6.x、0.7.x)存在 Lua 腳本 API 變更導致的兼容性問題、Prepare 協議不兼容、進程穩定性不足等痛點。本文記錄實戰排查全過程及解決方案。
啟動 Proxy 後客戶端頻繁報 MySQL Server has gone away。簡化環境(單後端、本地連接)無效。查看 Proxy 日志發現關鍵信息:
(critical) proxy-plugin.c:1367: (connect_server) [string "/usr/local/share/mysql-proxy/..."]:69: .address is deprecated. Use .src.name or .dst.name instead
(critical) (read_query) [string "/usr/local/share/mysql-proxy/..."]:179: .address is deprecated. Use .src.name or .dst.name instead
(critical) proxy-plugin.c.1115: I have no server backend, closing connection
MySQL Proxy 0.6.1 時代的 rw-splitting.lua 使用舊 API .address,但 0.7.0 版本棄用該屬性,要求使用 .src.name 或 .dst.name。官方發布包附帶的腳本未同步更新,導致腳本執行失敗,Proxy 無可用後端而關閉連接。
從官方倉庫下載最新 rw-splitting.lua 替換舊版:
# 官方 Lua 腳本分支(Launchpad)
https://launchpad.net/mysql-proxy-lua-scripts
# 或直接從源碼構建獲取最新腳本
bzr branch lp:mysql-proxy-lua-scripts
替換後問題顯著緩解。
現象: PHP PDO 使用原生 Prepare (PDO::ATTR_EMULATE_PREPARES = 0) 時,查詢隨機無結果返回,日志無有效線索。
繞過方案: 強制使用模擬 Prepare 模式:
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_EMULATE_PREPARES => 1 // 關鍵設置
]);
官方聲稱模擬模式性能更優,且規避了 Proxy 對 Prepare 協議處理的缺陷。
Lua 腳本更新滯後於 Proxy 核心,社區建立獨立維護分支:
https://launchpad.net/mysql-proxy-lua-scripts
建議生產環境鎖定穩定版本腳本,並關注上游更新。
Proxy 進程偶發 Crash,啟動參數添加 --keepalive:
mysql-proxy --keepalive [其他參數...]
進程異常退出時自動重啟,顯著提升可用性。但需注意:keepalive 僅守護進程存活,不解決連接狀態恢復,應用層仍需實現重連邏輯。
本文基於 MySQL Proxy 0.7.0 開發版實戰記錄,現僅供歷史參考。新項目請直接選用 ProxySQL 等現代中間件。