Loading...

文章背景图

PhxSQL:超详细部署与使用教程

2026-10-27
0
- 字
- 分钟
|

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 验证部署成功(通用)

  1. 初始化命令输出 master initialization is finished;
  2. mysql -uroot -h <任一节点IP> -P 8001 能连上并执行 show master status;;
  3. 管理工具查成员列表正常:phxbinlogsvr_tools_phxrpc -f GetMemberList -h <任一节点> -p 17000 返回 3 个节点;
  4. 杀掉当前 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 导入→等待自动恢复。


六、部署注意事项与最佳实践

  1. 节点数为奇数且 ≥3:官方建议 N≥3 奇数;2 台不满足 Paxos 多数派容错,4 台与 3 台容错能力相同(挂 1 台仍可用,挂 2 台都不可用)。
  2. 版本锁定 Percona 5.6.31-77.0:不要图新换成 Percona 5.7/8.0 或原生 MySQL 8.0,phx_percona 插件基于该版本 API 开发。
  3. 账号管理只走工具:admin / replica 账号一律用 phxbinlogsvr_tools_phxrpc 修改,切勿手动改 MySQL。
  4. 端口规划前置:54321(Paxos)、6000、11111(MySQL)、17000(binlogsvr)、8001/8002(proxy 读写)在防火墙/安全组全部放行,且节点间必须互通。
  5. 时钟同步:Paxos 选主与租约(MasterLease)依赖节点时钟,所有节点配 NTP。
  6. 磁盘与数据目录:binlog 会持续增长,EventDataDir 与 CheckPointTime 要按业务写入量规划;官方测试用 SSD RAID10,生产建议 SSD。
  7. 网络延迟:官方测试主从延迟 3~4ms,跨机房部署前先测 RTT;Paxos 多数派写会受 RTT 影响,跨地域集群需谨慎。
  8. 只读流量走 Slave Port:把报表/查询类流量引导到 8002 只读端口,主库 8001 只承接写与强一致读,可显著降低主库压力。
  9. GPL-2.0 合规:PhxSQL 源码与二进制均为 GPL-2.0,二次开发/对外提供服务前评估 GPL 传染性要求;其中 percona 等第三方组件另有各自许可。
  10. 先验证再上线:用 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
评论交流

文章目录