PhxSQL:超详细部署与使用教程
PhxSQL 是腾讯开源的基于 Paxos 与 Percona 的 MySQL 高可用、强一致性集群方案,用 Paxos 协议替代 MySQL 半同步复制,保证主从 binlog 零丢失,提供与 Zookeeper 同级别的线性一致性,已在腾讯大规模生产环境验证。
| 所属公司 | GitHub 仓库 | 官方文档/官网 | 开源协议 | Star 数 | 最新版本(截至 2026-10-27) | 主要语言 |
|---|---|---|---|---|---|---|
| 腾讯(THL A29 Limited) | github.com/Tencent/phxsql | 官方 Wiki:github.com/Tencent/phxsql/wiki(含编译手册、部署手册、Docker 快速上手) | GPL-2.0(源码;二进制同为 GPL-2.0) | 约 2.4k | v0.8.5 | C++(基于 Percona Server 5.6.31-77.0) |
目录
一、项目概述
1.1 项目定位
PhxSQL 是腾讯自研并开源的 MySQL 高可用集群方案,核心思路是:用腾讯自研的 Paxos 库(PhxPaxos)替换 MySQL 原生的 loss-less semi-sync(无损半同步)复制层,把 binlog 同步过程纳入 Paxos 多数派确认,从而在主库故障时自动 Failover 且不丢一条 binlog。整个集群只有 4 个组件(含 MySQL 本体),不依赖 ZooKeeper、etcd 等任何外部协调服务,可以像普通 MySQL 一样被 MySQL Client 直连使用。作者为 Junchao Chen、Haochuan Cui、Duokai Huang、Ming Chen、Sifan Liu,联系邮箱 phxteam@tencent.com。
1.2 核心功能
- 高可用自动故障转移:集群中超过半数节点存活且互通时即可正常服务,主节点宕机后 Paxos 自动选主、自动切换,无需人工介入。
- 强一致零丢失:以 Paxos 替代主从半同步复制,保证主从 binlog 零丢失,对外提供与 Zookeeper 同级别的线性化(linearizable)一致性。
- 完全兼容 MySQL:最高支持 Serializable 隔离级别,MySQL 客户端、ORM、备份工具均可原样使用,业务改造极小。
- 极简架构:全集群仅 4 个组件(MySQL + phx_percona 插件 + phxbinlogsvr + phxsqlproxy),无外部依赖,部署维护简单。
- 集群成员热变更:支持在线 AddMember / RemoveMember 动态扩缩容,无需停机。
- 官方预编译包:仓库附带 Ubuntu 64bit 预编译二进制,也支持完整源码编译。
- 配套开源组件:依赖的 PhxPaxos、PhxRPC、libco 均为腾讯同期开源项目,可一并编译。
1.3 技术架构
官方未在 README、README 中文版及 Wiki 各页面(Architecture、Build-Guide、中文部署手册、中文详细编译手册)中提供公开可用的架构图/logo 图;以下结构说明来自官方 README 目录定义与组件描述,以官方文档描述为准。尝试过的来源:GitHub 仓库 README 与 README.zh_cn.md、Wiki 全部页面(含 Architecture 专页)、仓库根目录文件列表,均无图片资源。
PhxSQL 集群每台节点上运行 3 类进程:
| 组件 | 作用 |
|---|---|
| MySQL(Percona 5.6.31-77.0)+ phxsync_phxrpc 插件 | 业务 SQL 执行本体;插件拦截 MySQL binlog 并转发给本机 phxbinlogsvr |
| phxbinlogsvr | 全局 binlog 同步与存储服务;基于 PhxPaxos 做跨节点多数派复制;同时负责主从身份(mastership)与成员关系(membership)管理 |
| phxsqlproxy | 位于 MySQL Client 与 MySQL 之间的代理层,对外暴露端口,把读写请求转发到当前 master / 本地 slave |
读写路径:业务 → phxsqlproxy(Master Port 转发到当前主库;Slave Port 走本地从库)→ phx_percona 插件 → binlog 经 phxbinlogsvr 以 Paxos 多数派复制到其他节点的 phxbinlogsvr → 各从库回放。任一节点故障时,剩余节点经 Paxos 选出新主,phxsqlproxy 自动把写请求切到新主。
二、环境要求
| 项目 | 要求 |
|---|---|
| 操作系统 | Linux(官方预编译包为 Ubuntu 64bit;源码编译亦以 Linux 为主) |
| 主机数量 | ≥ 3 台(官方建议 N≥3 且为奇数),节点间网络互通 |
| MySQL 版本 | 固定 Percona Server 5.6.31-77.0(官方注明「Only percona-server-5.6_5.6.31-77.0 is available」,其他版本不可用) |
| 编译工具 | gcc/g++、make、autoconf 等;Python 2.7(安装脚本 install.py 为 python2.7) |
| 第三方库 | glog、leveldb、protobuf(3.0+)、phxpaxos、colib(libco)、phxrpc,共 6 个,均随仓库 submodule 提供 |
| 内存 | 官方性能测试机为 32GB 内存、Xeon E5-2420,生产按 MySQL 实际负载规划 |
| 磁盘 | 官方测试用 SSD RAID10;binlog 与数据目录需足够空间 |
| 网络 | 节点间延迟官方测试为主从 3~4ms;建议内网低延迟组网 |
| 时间同步 | 集群节点建议 NTP 时钟同步(Paxos 与主从切换对时钟敏感) |
默认端口规划(官方 install.py 示例):
| 端口参数 | 示例值 | 用途 |
|---|---|---|
-p |
54321 | Paxos 节点间通信端口 |
-g |
6000 | phxbinlogsvr 相关端口(以官方部署手册为准) |
-y |
11111 | 本地 MySQL 端口 |
-P |
17000 | phxbinlogsvr 对外监听端口(管理工具均连此端口) |
-a |
8001 | phxsqlproxy 对外代理端口(Master Port,Slave Port=MasterPort+1=8002) |
三、部署方式
下面给出三条路径:① Docker 一键模拟集群(最快验证)→ ② 官方预编译包部署真实集群(生产推荐)→ ③ 源码编译部署(定制/二次开发)。
3.1 方式一:Docker 快速上手(单机模拟 3 节点集群)
官方 Wiki「Quick Start with Docker」提供镜像 phxsql/phxsql,适合快速验证。
# 1) 拉取官方镜像
docker pull phxsql/phxsql:latest
# 2) 起 3 个容器组成一个 PhxSQL 集群
docker run -d --name node1 phxsql/phxsql:latest
docker run -d --name node2 phxsql/phxsql:latest
docker run -d --name node3 phxsql/phxsql:latest
# 3) 查看各容器内网 IP(Docker 默认 bridge 网络)
ip1=$(docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" node1)
ip2=$(docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" node2)
ip3=$(docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" node3)
每个容器内部会自动拉起 3 个进程:mysqld_safe / mysqld(Percona,容器内 MySQL 端口 11111)、phxbinlogsvr_phxrpc、phxsqlproxy_phxrpc。可用以下命令确认进程齐全:
docker top node1
# 正常应看到:
# sh /phxsql/bin/mysqld_safe --defaults-file=/phxsql/etc/my.cnf --super_read_only
# /phxsql/sbin/phxbinlogsvr_phxrpc
# /phxsql/sbin/phxsqlproxy_phxrpc /phxsql/etc/phxsqlproxy.conf daemon
# /phxsql/sbin/mysqld --defaults-file=/phxsql/etc/my.cnf ... --port=11111
容器内数据落在自动创建的 Docker Volume /data,清理时用 docker rm -v 连带删除。
注意:单机 Docker 模拟仅用于功能验证;真实生产请用方式二在多台物理机/虚拟机上部署。仓库根目录还有
test-with-docker.sh一键测试脚本可供参考。
3.2 方式二:官方预编译包部署真实集群(3 台物理机)
步骤 1:获取安装包
方式 A:下载 Ubuntu 64bit 预编译包(仓库 Release 或源码包 make package 产物),文件形如 phxsql-$version.tar.gz。
方式 B:在已编译环境执行 make package,把 install_package 目录打包为 phxsql-$version.tar.gz 后分发到每台目标机器。
步骤 2:每台机器解压并安装
# 每台节点(ip1 / ip2 / ip3)分别执行
tar -xvf phxsql.tar.gz -C /opt/phxsql
cd /opt/phxsql/tools
# 查看安装脚本帮助
python2.7 install.py --help
# 按官方示例执行安装(参数含义见第二节端口表)
python2.7 install.py -i "your_inner_ip" -p 54321 -g 6000 -y 11111 -P 17000 -a 8001 -f /tmp/data/
安装前请先修改 tools/etc_template/my.cnf(安装后则改 etc/my.cnf)为你自己的 MySQL 配置。
步骤 3:初始化集群(任选一台机器执行一次)
./phxbinlogsvr_tools_phxrpc -f InitBinlogSvrMaster -h "ip1,ip2,ip3" -p 17000
当日志出现 master initialization is finished 类信息时,集群即进入可用状态。
步骤 4:验证
# 用 mysql 客户端连接任一台节点的 phxsqlproxy 执行 SQL
mysql -uroot -h "your_inner_ip" -P 8001 -e "show master status; show slave hosts;"
或运行官方自带测试脚本:
cd /opt/phxsql/tools
bash test_phxsql.sh 8001 ip1 ip2 ip3
3.3 方式三:源码编译部署
步骤 1:拉取源码(含 submodule)
git clone --recurse-submodules https://github.com/Tencent/phxsql.git
cd phxsql
不使用
--recurse-submodules会缺少 phxpaxos / phxrpc / libco 等关键依赖,务必带全。
步骤 2:准备第三方库与指定版本 Percona
第三方库 glog、leveldb、protobuf、phxpaxos、colib、phxrpc 需放在 third_party/ 目录(或软链接进去)。
⚠️ 官方硬性要求:编译 glog 与 protobuf 时必须加
-fPIC并指定--prefix为当前绝对路径,例如:
cd third_party/glog
./configure CXXFLAGS=-fPIC --prefix=/your/path/phxsql/third_party/glog
make && make install
然后只下载指定版本 Percona Server:
wget https://www.percona.com/downloads/Percona-Server-5.6/Percona-Server-5.6.31-77.0/source/tarball/percona-server-5.6.31-77.0.tar.gz
tar -xzf percona-server-5.6.31-77.0.tar.gz
# 重命名或软链接为仓库根目录下的 percona
ln -s percona-server-5.6.31-77.0 /your/path/phxsql/percona
步骤 3:编译与打包
# 指定安装前缀后一键编译
./autoinstall.sh --prefix=/the/path/you/want/to/install
make
make install
# 打成 tar.gz 包分发到目标机器
make package
# 产物:phxsql-$version.tar.gz(sbin 二进制在 install_package/sbin,
# 配置模板在 install_package/tools/etc_template,安装脚本在 install_package/tools)
之后按 3.2 的步骤 2~4 在目标机器部署。
3.4 验证部署成功(通用)
- 初始化命令输出
master initialization is finished; mysql -uroot -h <任一节点IP> -P 8001能连上并执行show master status;;- 管理工具查成员列表正常:
phxbinlogsvr_tools_phxrpc -f GetMemberList -h <任一节点> -p 17000返回 3 个节点; - 杀掉当前 master 的 mysqld,等待数十秒后写请求自动切到新主(Failover 生效)。
3.5 关键配置说明
phxbinlogsvr.conf(节选):
| Section | Key | 说明 |
|---|---|---|
| AgentOption | AgentPort | binlogsvr 与 MySQL 之间的连接端口 |
| AgentOption | EventDataDir | binlogsvr 数据存储目录 |
| AgentOption | MaxFileSize | 单个数据文件大小(字节) |
| AgentOption | MasterLease | 主节点租约时长(秒) |
| AgentOption | CheckPointTime | 早于该时间的 CheckPoint 数据可被删除(分钟),其他节点未追上前不删 |
| AgentOption | FollowIP | 从节点设置此项后从此 IP 拉 binlog,且不参与投票 |
| PaxosOption | PaxosLogPath | Paxos 日志存储目录 |
| PaxosOption | PaxosPort | Paxos 节点间互联端口 |
| PaxosOption | PacketMode | 1=100M 大包(网络超时 1 分钟);0=50M(超时 2 秒,动态调整) |
| Server | IP / Port | phxbinlogsvr 监听地址与端口(如 17000) |
| Server | LogFilePath / LogLevel | 日志目录与级别 |
phxsqlproxy.conf(节选):
| Key | 说明 |
|---|---|
| Server.IP / Port | phxsqlproxy 监听地址与 Master Port(读写端口,如 8001) |
| MasterEnableReadPort | 主节点是否开启只读端口;设为 0 时主节点会把只读请求转发给某个从节点(节省主库 CPU/IO) |
| TryBestIfBinlogsvrDead | 本机 phxbinlogsvr 挂掉后,代理是否尝试从其他机器的 phxbinlogsvr 获取主信息(设为 1 开启) |
双端口模型:
| 端口 | 别名 | 行为 |
|---|---|---|
| Master Port(如 8001) | 读写端口 | 所有请求转发到当前 master 执行 |
| Slave Port(MasterPort+1,如 8002) | 只读端口 | 请求在本地 MySQL 执行;若本地是 master 且 MasterEnableReadPort=0,会重定向到某个从节点 |
四、使用方法
4.1 基础用法:像连普通 MySQL 一样连接
# 连任意节点的 phxsqlproxy 即可,代理自动路由
# 写请求(走 Master Port)
mysql -uroot -h <phxsqlproxy_ip> -P 8001 -p
# 只读请求(走 Slave Port,端口 = MasterPort+1)
mysql -uroot -h <phxsqlproxy_ip> -P 8002 -p
$phxsqlproxyip 可以是集群中任意一台节点的 IP,业务无需关心当前 master 在哪台机器。
4.2 常用管理命令(phxbinlogsvr_tools_phxrpc)
查看当前主节点信息:
phxbinlogsvr_tools_phxrpc -f GetMasterInfoFromGlobal -h <任一节点IP> -p 17000
查看集群成员列表:
phxbinlogsvr_tools_phxrpc -f GetMemberList -h <任一节点IP> -p 17000
修改管理员账号(默认 root/空密码):
phxbinlogsvr_tools_phxrpc -f SetMySqlAdminInfo -h <任一节点IP> -p 17000 \
-u root -d "" -U newadmin -D newpassword
修改同步账号(默认 replica/replica123):
phxbinlogsvr_tools_phxrpc -f SetMySqlReplicaInfo -h <任一节点IP> -p 17000 \
-u root -d "" -U newreplica -D newreplica_pwd
⚠️ 官方强调:PhxSQL 集群需要 1 个 MySQL 管理员账号和 1 个同步账号,只能通过
phxbinlogsvr_tools_phxrpc工具修改,禁止直接在 MySQL 里手动改。
在线摘除节点:
phxbinlogsvr_tools_phxrpc -f RemoveMember -h <任一节点IP> -p 17000 -m <待摘除节点IP>
执行成功后,该节点一小段时间后停止学习 binlog。
在线加入新节点:
# 1) 先把新节点 A 加入成员关系
phxbinlogsvr_tools_phxrpc -f AddMember -h <任一节点IP> -p 17000 -m <节点A_IP>
# 2) 在 A 上安装 PhxSQL(按 3.2 步骤)
# 3) A 会开始追 binlog;再从其他节点拷贝一份 MySQL 快照到 A
# 4) 杀掉 A 上 phxbinlogsvr,通过本地端口/socket 直连 A 的 MySQL,执行:
mysql -uroot -S /data/percona.workspace/tmp/percona.sock
set global super_read_only = 0;
set global read_only = 0;
# 5) 把快照 dump 进 A 的 MySQL
# 6) A 一段时间后自动进入正常服务
4.3 进阶功能
- 跟随节点(不投票):在
phxbinlogsvr.conf中配置FollowIP,该节点只从 FollowIP 拉 binlog、不参与 Paxos 投票,适合做异地灾备只读副本。 - 性能表现:官方在 Xeon E5-2420×24 / 32GB / SSD RAID10 实测,200 并发下 insert 写 QPS 约 5076、select 读 QPS 约 46334、OLTP 混合 QPS 约 25657;500 并发下写 QPS 约 8260、读 QPS 约 105928,整体优于 MySQL 半同步方案(数据来自官方 README 性能章节)。
- 故障重装自愈:节点遇到不可恢复故障重装时,phxbinlogsvr 会自动从其他节点拉取 checkpoint 重启,看到
All sm load state ok, start to exit后重启 phxbinlogsvr 即可。 - 从现有 MySQL 迁移:官方 Wiki 提供「从现有 MySQL 数据库迁移」专页,指导存量数据迁入流程(以 Wiki 为准)。
4.4 适用场景
- 对数据一致性要求极高的交易类业务(支付、账务),要求主从切换零数据丢失;
- 需要强一致但不想引入 ZooKeeper/etcd 等额外中间件的团队;
- 已有 MySQL 业务希望平滑升级为高可用集群(客户端协议兼容,改造小);
- 需要在线扩缩容、异地灾备只读副本的中长期 MySQL 架构演进;
- 腾讯内部 WeChat 支付、微信公众号等核心业务曾长期使用该方案(官方背景)。
五、常见问题排查(FAQ)
Q1:执行 InitBinlogSvrMaster 后集群未起来
- 原因:某台节点 install.py 未执行、端口(54321/6000/11111/17000/8001)被占用或节点间网络不通。
- 解决:逐台确认 ps -ef | grep phxbinlogsvr 与 mysqld 进程存在;检查防火墙放行 Paxos 端口 54321 与 binlogsvr 端口 17000;确认 3 台机器时间已同步。
Q2:make 编译报 protobuf/glog 链接错误(fPIC 相关)
- 原因:官方硬性要求 glog、protobuf 编译时加 CXXFLAGS=-fPIC 并指定 --prefix。
- 解决:按 ./configure CXXFLAGS=-fPIC --prefix=/绝对路径 重新编译这两个库后再 make。
Q3:下载 Percona 后编译报版本不匹配
- 原因:PhxSQL 只认 percona-server-5.6.31-77.0,其他版本(5.7/8.0)插件 API 不兼容。
- 解决:卸载现有 Percona,严格下载官方指定版本并软链接为仓库根目录的 percona。
Q4:直接在 MySQL 里改了 root 密码导致集群异常
- 原因:PhxSQL 的管理员/同步账号必须通过 phxbinlogsvr_tools_phxrpc 统一管理。
- 解决:用 SetMySqlAdminInfo / SetMySqlReplicaInfo 工具改回一致账号;后续禁止手动改。
Q5:phxbinlogsvr 日志出现红色 err 或停止工作
- 原因:通常是本地 MySQL 数据出现问题(损坏、磁盘满)导致 binlogsvr 主动停止。
- 解决:先检查本机 MySQL 状态(error log、磁盘空间 df -h),修好 MySQL 后重启 phxbinlogsvr;不可恢复时按官方「故障重装」流程从其他节点拉 checkpoint。
Q6:docker top 看不到 phxsqlproxy 或 phxbinlogsvr 进程
- 原因:容器内启动失败(数据卷权限、端口冲突)。
- 解决:docker logs node1 查看启动日志;删除容器时用 docker rm -v 清理 /data 卷后重建;确认宿主机端口映射无冲突。
Q7:主节点挂了,业务读正常但写卡住
- 原因:新主未选出(剩余节点未过半数)或 phxsqlproxy 未刷新主信息。
- 解决:确认存活节点数 > 半数(3 节点集群至少 2 台活);在 phxsqlproxy.conf 中设置 TryBestIfBinlogsvrDead=1;用 GetMasterInfoFromGlobal 确认当前主。
Q8:AddMember 加新节点后新节点一直追不上
- 原因:未先拷贝 MySQL 快照,或快照后忘记关闭 super_read_only/read_only。
- 解决:按官方 6 步流程——加成员→安装→拉快照→直连 MySQL 执行 set global super_read_only=0; set global read_only=0;→dump 导入→等待自动恢复。
六、部署注意事项与最佳实践
- 节点数为奇数且 ≥3:官方建议 N≥3 奇数;2 台不满足 Paxos 多数派容错,4 台与 3 台容错能力相同(挂 1 台仍可用,挂 2 台都不可用)。
- 版本锁定 Percona 5.6.31-77.0:不要图新换成 Percona 5.7/8.0 或原生 MySQL 8.0,phx_percona 插件基于该版本 API 开发。
- 账号管理只走工具:admin / replica 账号一律用
phxbinlogsvr_tools_phxrpc修改,切勿手动改 MySQL。 - 端口规划前置:54321(Paxos)、6000、11111(MySQL)、17000(binlogsvr)、8001/8002(proxy 读写)在防火墙/安全组全部放行,且节点间必须互通。
- 时钟同步:Paxos 选主与租约(MasterLease)依赖节点时钟,所有节点配 NTP。
- 磁盘与数据目录:binlog 会持续增长,EventDataDir 与 CheckPointTime 要按业务写入量规划;官方测试用 SSD RAID10,生产建议 SSD。
- 网络延迟:官方测试主从延迟 3~4ms,跨机房部署前先测 RTT;Paxos 多数派写会受 RTT 影响,跨地域集群需谨慎。
- 只读流量走 Slave Port:把报表/查询类流量引导到 8002 只读端口,主库 8001 只承接写与强一致读,可显著降低主库压力。
- GPL-2.0 合规:PhxSQL 源码与二进制均为 GPL-2.0,二次开发/对外提供服务前评估 GPL 传染性要求;其中 percona 等第三方组件另有各自许可。
- 先验证再上线:用 Docker 三容器模拟跑通 install.py → InitBinlogSvrMaster → test_phxsql.sh 全流程,再上生产。
七、参考资料
- GitHub 仓库:https://github.com/Tencent/phxsql
- 官方 Wiki 首页:https://github.com/Tencent/phxsql/wiki
- 架构说明页:https://github.com/Tencent/phxsql/wiki/Architecture
- 编译指南(Build-Guide):https://github.com/Tencent/phxsql/wiki/Build-Guide
- 中文详细编译手册:https://github.com/Tencent/phxsql/wiki/中文详细编译手册
- 中文部署手册:https://github.com/Tencent/phxsql/wiki/中文部署手册
- Docker 快速上手:https://github.com/Tencent/phxsql/wiki/Quick-Start-with-Docker
- 成员管理:https://github.com/Tencent/phxsql/wiki/PhxSQL-成员管理
- 从现有 MySQL 迁移:https://github.com/Tencent/phxsql/wiki/从现有MySQL数据库迁移
- 依赖组件 PhxPaxos:https://github.com/Tencent/phxpaxos
- 依赖组件 PhxRPC:https://github.com/Tencent/phxrpc
- 依赖组件 libco:https://github.com/Tencent/libco
- Percona Server 5.6.31-77.0 源码:https://www.percona.com/downloads/Percona-Server-5.6/Percona-Server-5.6.31-77.0/
- 联系邮箱:phxteam@tencent.com