ProxySQL 是一款高性能、高可定制化的 MySQL 代理,支持读写分离、故障转移和查询缓存等功能,广泛用于大规模生产环境中。
主库(master)通过 ProxySQL 暴露给应用:
应用 → ProxySQL(6033) → master(写)
└→ node1/node2(读)
ProxySQL 会根据我们配置的查询规则,把写操作转发给 master,把读操作发给其中一个从库。
下面所有命令,「都在 master 机器上执行」。我们假设 master IP 为 192.168.0.10
。
ProxySQL 默认管理端口是 「6032」,使用 admin 用户(默认密码 admin)登录:
mysql -u admin -padmin -h 127.0.0.1 -P6032
「提示」:如果报 “Access denied”,请检查
/etc/proxysql.cnf
中admin_credentials
配置。
在管理界面里执行:
-- 清空已有配置(仅首次配置时可做)
DELETEFROM mysql_servers;
-- 添加主库
INSERTINTO mysql_servers
(hostgroup_id, hostname, port, weight)
VALUES (10, '192.168.0.10', 3306, 100);
-- 添加从库1
INSERTINTO mysql_servers
(hostgroup_id, hostname, port, weight)
VALUES (20, '192.168.0.11', 3306, 100);
-- 添加从库2
INSERTINTO mysql_servers
(hostgroup_id, hostname, port, weight)
VALUES (20, '192.168.0.12', 3306, 100);
-- 提交到运行时内存
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
10
代表写组,20
代表读组ProxySQL 需要知道如何连接后端,先在 ProxySQL 内配置一个 MySQL 用户(与前文 repl
不同,这里给应用使用):
-- 删除旧用户
DELETEFROM mysql_users;
-- 添加应用用户(假设数据库中已有 testdb 和 t_user 表)
INSERTINTO mysql_users (username, password, default_hostgroup)
VALUES ('appuser', 'appuserpass', 10);
-- 提交
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
10
ProxySQL 的查询规则使用正则匹配 SQL,下面配置把 SELECT
且不包含 FOR UPDATE
的语句,都路由到读组(20):
-- 删除旧规则
DELETEFROM mysql_query_rules;
-- 规则1:写操作全部发到写组(10)
INSERTINTO mysql_query_rules
(rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES
(1, 1, '^INSERT|^UPDATE|^DELETE|^REPLACE|^CREATE|^ALTER|^DROP', 10, 1);
-- 规则2:普通 SELECT 发到读组(20)
INSERTINTO mysql_query_rules
(rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES
(2, 1, '^SELECT(?!.*FOR UPDATE)', 20, 1);
-- 规则3:SELECT … FOR UPDATE 或 LOCK IN SHARE MODE 发写组
INSERTINTO mysql_query_rules
(rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES
(3, 1, 'FOR UPDATE|LOCK IN SHARE MODE', 10, 1);
-- 加载并保存
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
「小技巧」:
apply=1
表示匹配后不再往下匹配,顺序很重要,要先写写规则,再写读规则。
在管理端运行:
SELECT hostgroup, srv_host, srv_port, status
FROM stats_mysql_connection_pool;
如果看到从库的连接在 hostgroup = 20
,主库在 10
,并且 status 都是 ONLINE
,说明注册成功。
假设你的应用只需要连接到 master:
mysql -u appuser -pappuserpass -h 192.168.0.10 -P6033 testdb
「写验证」:
INSERTINTO t_user (id, name) VALUES (2, 'ProxySQL');
然后登录 node1(或 node2)查看:
mysql -uroot -p123456 -h192.168.0.11 testdb -e "SELECT * FROM t_user;"
能看到 (2, 'ProxySQL')
就说明写操作正确路由到主库并同步到了从库。
「读验证」:
在应用连接中执行:
SELECT*FROM t_user;
正常会从从库返回数据。你可通过如下方式强制读主库,验证路由:
SELECT/* PROXYSQL_HOSTGROUP=10 */*FROM t_user;
这样就能在读的时候也走写组,方便调试。
检查后端 MySQL 网络、防火墙;用 telnet IP 3306测试连通性
掌握了本篇内容,你就具备了生产环境中最常见的 「读写分离」能力。下一篇,我们将深入「ProxySQL 性能调优与监控」——让你的数据库集群跑得更稳、更快!