承接上篇,本文深入解析MySQL-Proxy嵌入式Lua腳本如何實現「讀寫分離」核心邏輯:事務性查詢路由至主庫,SELECT查詢路由至空閒從庫,並解決連線池預先認證難題。
if is_in_transaction == 0 and
packet:byte() == proxy.COM_QUERY and
packet:sub(2, 7) == "SELECT" then
local max_conns = -1
local max_conns_ndx = 0
for i = 1, #proxy.servers do
local s = proxy.servers[i]
-- 選擇擁有空閒連線的從庫
if s.type == proxy.BACKEND_TYPE_RO and
s.idling_connections > 0 then
if max_conns == -1 or
s.connected_clients < max_conns then
max_conns = s.connected_clients
max_conns_ndx = i
end
end
end
-- 找到最空閒從庫,切換後端
if max_conns_ndx > 0 then
proxy.connection.backend_ndx = max_conns_ndx
end
else
-- 非SELECT或事務中 → 路由至主庫
end
return proxy.PROXY_SEND_QUERY
| 技術點 | 說明 |
|---|---|
is_in_transaction | 事務狀態標記,事務內所有查詢(含SELECT)必須路由主庫,保證ACID |
packet:byte() == proxy.COM_QUERY | 識別MySQL協議查詢封包 |
packet:sub(2,7) == "SELECT" | 快速檢查SQL關鍵字(大小寫不敏感建議用string.upper) |
BACKEND_TYPE_RO | 標記唯讀從庫節點 |
idling_connections > 0 | 確保有預先認證的空閒連線,**解決協議握手時序限制** |
connected_clients | 最少連線優先策略,實現負載均衡 |