MySQL Proxy 定位
官方 C 語言開發的 MySQL 協議層代理,支援 Lua 腳本可編程控制連線路由、查詢改寫、審計、熔斷。定位:輕量、透明、可編程的中間件。
注意:MySQL Proxy 0.8.x 後官方停止維護,生產環境建議改用 ProxySQL(高效能、多執行緒、生產就緒)或 MySQL Router(官方、InnoDB Cluster 整合)。本文為歷史版本教學保留。
環境準備
# CentOS 5.2 範例
yum install -y autoconf automake libtool flex pkgconfig bzr mysql-devel
# 手動編譯依賴(系統版本過低)
wget https://monkey.org/~provos/libevent-1.4.9-stable.tar.gz
tar zxf libevent-1.4.9-stable.tar.gz && cd libevent-1.4.9-stable && ./configure && make && make install
wget https://ftp.gnome.org/pub/gnome/sources/glib/2.18/glib-2.18.4.tar.gz
tar zxf glib-2.18.4.tar.gz && cd glib-2.18.4 && ./configure && make && make install
wget https://www.lua.org/ftp/lua-5.1.4.tar.gz
tar zxf lua-5.1.4.tar.gz && cd lua-5.1.4
# 64位需修改 src/Makefile CFLAGS += -fPIC
make linux && make install
cp etc/lua.pc /usr/local/lib/pkgconfig/
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
編譯安裝 MySQL Proxy 0.7.0
wget https://dev.mysql.com/get/Downloads/MySQL-Proxy/mysql-proxy-0.7.0.tar.gz
tar zxf mysql-proxy-0.7.0.tar.gz && cd mysql-proxy-0.7.0
./configure && make && make check && make install
# 驗證
mysql-proxy -V
# 輸出版本、glib、libevent、lua 版本
SELinux 阻擋問題解決
# 錯誤:error while loading shared libraries: libmysql-chassis.so.0: cannot restore segment prot after reloc: Permission denied
# 方案 1:關閉 SELinux(永久)
vi /etc/selinux/config
SELINUX=disabled
reboot
# 方案 2:針對性放行(不關閉 SELinux)
chcon -t texrel_shlib_t /usr/local/lib/libmysql-chassis.so.0
chcon -t texrel_shlib_t /usr/local/lib/libmysql-proxy.so.0
核心參數速查
| 參數 | 說明 | 預設 |
| --proxy-address | 監聽地址:埠(應用連這裡) | :4040 |
| --proxy-backend-addresses | 後端 Master 寫入節點,可多個 | 無 |
| --proxy-read-only-backend-addresses | 後端 Slave 唯讀節點,可多個 | 無 |
| --proxy-lua-script | Lua 腳本路徑(核心邏輯) | 無 |
| --admin-address | 管理介面埠 | :4041 |
| --daemon | 守護進程模式 | 前景 |
| --proxy-skip-profiling | 關閉查詢分析 | 開啟 |
啟動腳本範例
#!/bin/bash
# /etc/init.d/mysql-proxy
export LUA_PATH=/usr/local/share/mysql-proxy/?.lua
case "$1" in
start)
/usr/local/sbin/mysql-proxy --daemon \
--proxy-address=192.168.1.6:3306 \
--proxy-backend-addresses=192.168.1.6:3307 \
--proxy-read-only-backend-addresses=192.168.1.10:3306 \
--proxy-lua-script=/usr/local/share/mysql-proxy/rw-splitting.lua
;;
stop)
killall mysql-proxy
;;
restart)
$0 stop && $0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
Lua 腳本核心邏輯:rw-splitting.lua 關鍵點
-- 內建讀寫分離腳本關鍵片段
function read_query(packet)
if packet:byte() == proxy.COM_QUERY then
local sql = packet:sub(2)
if sql:match("^%s*SELECT") then
-- SELECT 路由到 Slave
proxy.connection.backend_ndx = proxy.global.config.rnd:get_n()
else
-- 非 SELECT(含事務、DDL、DML)路由到 Master
proxy.connection.backend_ndx = 1
end
end
end
-- 修正 Bug:DEFAULT DB 同步問題
if cmd.type ~= proxy.COM_INIT_DB and
c.default_db and c.default_db ~= s.default_db then
proxy.queries:prepend(2, string.char(proxy.COM_INIT_DB) .. c.default_db)
end
管理介面驗證
mysql -u root -h 127.0.0.1 -P 4041
SELECT * FROM proxy_connections;
SELECT * FROM proxy_config;
負載均衡驗證腳本
-- test-conn.lua
function read_query(packet)
print("read_query: connection.backend_ndx: " .. proxy.connection.backend_ndx)
end
# 啟動帶測試腳本
mysql-proxy --proxy-address=192.168.1.6:3306 \
--proxy-backend-addresses=192.168.1.231:3306 \
--proxy-backend-addresses=192.168.1.10:3306 \
--proxy-lua-script=/opt/test-conn.lua
# 客戶端多次連線,觀察輸出輪詢 1,2,1,2...
生產級替代方案對比
| 中間件 | 語言 | 多執行緒 | 熱加載配置 | 監控指標 | 推薦指數 |
| MySQL Proxy | C + Lua | 單執行緒 | 支援 | 基礎 | ⭐ (停止維護) |
| ProxySQL | C++ | 多執行緒 | 支援 (Admin 介面) | 豐富 (Prometheus Exporter) | ⭐⭐⭐⭐⭐ |
| MySQL Router | C++ | 多執行緒 | 支援 (配置檔/Metadata) | 基礎 | ⭐⭐⭐⭐ (InnoDB Cluster 首選) |
| MaxScale | C++ | 多執行緒 | 支援 | 豐富 | ⭐⭐⭐⭐ (MariaDB 生態) |
MySQL Proxy 是啟蒙教材,ProxySQL 是生產主力。理解 Proxy 協議層路由原理,遷移 ProxySQL 只需改配置與管理介面習慣。