mysql不停机扩容
MySQL 实现不停机扩容(也称为在线扩容、热扩容)是保证业务连续性的关键需求。核心思路是在扩容过程中,应用依然可以读写数据库,数据保持最终一致性,且停机时间极短(秒级或毫秒级)。以下是几种主流的实现方案:
一、 基于主从复制 + 切换(最常用)
这是最经典、应用最广泛的方法,尤其适合读多写少的场景,也可以用于写扩展(需要应用配合)。
准备工作:
确保现有主库 (
Master) 开启二进制日志 (binlog) 且格式为ROW(或MIXED,但ROW最安全)。准备好新的、配置更高的数据库服务器 (
New Slave或Candidate Master)。确保新服务器与老服务器网络互通,防火墙规则允许复制端口通信。
安装相同或兼容版本的 MySQL。
搭建新从库:
逻辑备份恢复: 使用
mysqldump或mydumper对主库进行一致性备份。备份时使用--single-transaction --master-data(InnoDB) 或--lock-all-tables(MyISAM) 确保一致性并记录 binlog 位置。将备份恢复到新服务器。物理备份恢复: 使用 Percona XtraBackup / MySQL Enterprise Backup /
Clone Plugin(MySQL 8.0+) 进行在线热备份。恢复备份到新服务器。XtraBackup 会记录备份结束时对应的 LSN (Log Sequence Number)。配置复制:
如果是逻辑备份,备份文件里通常包含
CHANGE MASTER TO语句所需的MASTER_LOG_FILE和MASTER_LOG_POS(来自--master-data)。如果是物理备份 (如 XtraBackup),查看
xtrabackup_binlog_info文件获取 binlog 位置信息。在新服务器上执行
CHANGE MASTER TO ...命令,指向老主库 (Master),并启动复制 (START SLAVE)。数据同步追赶:
新从库 (
New Slave) 开始从老主库 (Master) 同步数据。监控Seconds_Behind_Master状态,直到它变为0,表示新从库已追平老主库。切换方案 (核心 - 决定"不停机"的关键):
方案 A: 主从角色切换 (Failover) - 适用于读写分离扩容读或整体替换主库
前提: 应用已经配置了读写分离(写指向主库,读指向从库池)。或者你准备将所有流量(读+写)切换到新机器上。
步骤:
短暂停止老主库写入 (可选但推荐): 在应用端或代理层(如 ProxySQL, MaxScale)短暂停止向老主库 (
Master) 发送写请求。目的是确保切换期间没有新数据写入老主库,保证数据一致性。此步骤通常只需几秒到几十秒。确保新从库完全同步: 再次确认
Seconds_Behind_Master = 0。提升新从库为主库: 在新从库 (
New Slave) 上执行STOP SLAVE; RESET SLAVE ALL;(清除复制信息)。然后将其设置为可写状态(如果之前只读)。切换应用指向:
如果是读扩容:将新提升的主库 (
New Master) 加入到应用的读库连接池即可。老主库 (Old Master) 现在可以作为新主库的一个从库(需要反向配置复制),或者下线。如果是替换主库 (写扩容):
修改应用配置或代理配置,将所有写请求指向新的主库 (
New Master)。修改应用配置或代理配置,将所有读请求指向新的主库和/或其他从库(包括老主库,如果它被设置为新主库的从库)。
恢复写入: 如果第1步停止了写入,现在恢复应用写入流量到新主库。
重配老主库 (可选): 将老主库 (
Old Master) 配置为新主库 (New Master) 的从库,开始同步新数据。之后可以将其降级为只读从库或下线。方案 B: 级联复制 + 切换写 - 适用于需要完全隔离的新写库
前提: 需要将部分或全部写流量迁移到全新的主库上,老主库可能不再接受写或下线。
步骤:
搭建新主库的从库: 按照步骤1-3,搭建一个从库 (
New Slave),但其主库是新主库 (New Master),而不是老主库。此时New Master还没有数据。初始化新主库: 使用
mysqldump/mydumper/XtraBackup将老主库 (Old Master) 的数据恢复到New Master上。恢复时记录 binlog 位置。配置新主从关系: 在
New Slave上配置复制源指向New Master,使用第2步记录的 binlog 位置启动复制。新主库追赶老主库:
在
New Master上配置其作为老主库 (Old Master) 的从库 (CHANGE MASTER TO ...),使用第2步备份结束时记录的Old Master的 binlog 位置。启动
New Master的复制线程 (START SLAVE),让它从Old Master同步数据,直到Seconds_Behind_Master = 0。此时New Master和Old Master数据一致,New Slave也同步着New Master。切换写流量:
短暂停止应用对
Old Master的写入。确保
New Master的Seconds_Behind_Master = 0。在
New Master上执行STOP SLAVE; RESET SLAVE ALL;,断开与Old Master的复制关系。修改应用配置或代理配置,将所有写请求指向
New Master。恢复应用写入。
处理老主库:
Old Master可以下线,或者配置为New Master的只读从库(需要反向设置复制)。优点:
技术成熟,基于 MySQL 原生复制。
对应用侵入性相对较小(尤其是读写分离场景)。
停机时间极短(主要发生在切换写流量时的短暂停止写入)
缺点:
复制延迟 (
Replication Lag) 是核心问题,切换前必须确保延迟为0。切换过程需要人工干预或借助自动化工具,有操作风险。
主从切换后可能出现数据不一致(如半同步复制未确认的事务),需配合半同步或增强半同步降低风险。
写扩展需要应用配合修改写连接地址。
二、 使用数据库中间件 (Proxy)
这类方案在应用和数据库之间引入一个代理层(如 ProxySQL, MaxScale, ShardingSphere-Proxy, MyCat, DBLE),由代理负责 SQL 路由、读写分离、分库分表、故障转移等。
扩容读:
按 "主从复制+切换" 的方法添加新的只读从库。
将新从库的信息注册到中间件配置中。
中间件会自动将读请求分发到包括新从库在内的所有可用读节点。这个过程通常可以在线完成,对应用透明。
扩容写 (分片扩容): 当单个主库写性能不足时,需要分库分表。中间件是实现分库分表的关键组件。
垂直拆分: 将不同的表或业务模块放到不同的数据库实例上。扩容时,将需要扩容的模块迁移到新的、更大的实例上(迁移过程本身通常需要停写或使用类似双写的逻辑)。
水平拆分 (分片): 将一个大表的数据按规则(如 range, hash, list)分散到多个数据库实例(分片)上。
增加新分片:
准备新的数据库节点(可能是一主多从)。
在线数据迁移: 这是最复杂的部分。需要工具(如 ShardingSphere-Scaling, pt-online-schema-change 的变种,或自研)将原有分片的部分数据在线迁移到新分片,并在迁移过程中同步增量数据(通常利用 binlog)。中间件需要支持动态添加分片和迁移规则。
双写 & 流量切换: 迁移过程中,应用可能需要在写入老分片的同时,也写入新分片(双写)。迁移完成并验证后,通过修改中间件配置,将对应新分片键范围/哈希值的读写请求路由到新分片,并最终停止老分片的双写和迁移进程。
优点: 理论上可以无限水平扩展写能力;对应用透明(应用像操作单库一样操作)。
缺点: 架构复杂,引入新组件;分片扩容(增加节点)操作复杂,风险高,通常涉及大量数据迁移;跨分片查询、事务处理困难;需要专业的中间件运维。
三、 利用云数据库服务
主流云厂商(AWS RDS/Aurora, Google Cloud SQL, Azure Database for MySQL, Aliyun RDS/PolarDB)都提供了高度自动化的在线扩容能力。
存储扩容:
许多云服务支持在线调整存储大小(如 AWS RDS Storage Autoscaling, Aurora Serverless v2, Aliyun ESSD Autoresize)。后台会自动完成存储扩展,通常对应用影响极小(可能有短暂I/O波动)。
计算扩容 (CPU/Memory):
在线变更实例规格: 云服务通常提供变更实例类型(如从小型升级到大型)的操作。后台会执行类似主从切换的操作:
在后台新建一个更大规格的实例作为从库。
同步数据。
在维护窗口或用户指定时间进行秒级切换(VIP 或 DNS 切换)。
只读副本扩展: 轻松添加新的只读副本,只需点击按钮或API调用,云服务自动完成复制搭建和加入负载均衡池。
Aurora/PolarDB 共享存储架构: 这类架构将计算与存储分离。
计算节点扩容: 可以秒级添加新的只读节点或更改主节点规格。因为存储是共享的,添加只读节点非常快,只需启动计算实例并挂载共享存储卷。
存储扩容: 存储池按需自动扩展,通常对计算节点完全透明。
优点:
极度简化: 用户操作简单(控制台点击或API调用),后台自动化完成复杂流程。
风险低: 云服务商有成熟的工具和流程保障。
速度快: 特别是基于共享存储的架构(Aurora/PolarDB)。
缺点:
依赖特定云厂商。
成本可能高于自建。
底层细节对用户不透明。
选择哪种方案取决于你的具体需求(是扩读、扩写、扩存储)、业务规模、技术栈、运维能力和预算。充分测试、严密监控、制定回滚计划是任何不停机扩容操作成功的关键保障。
