MySQL级联复制下大表字段扩容方案与实操

阿澈
阿澈
发布时间:2026-10-15| 3人浏览过
原创

针对4亿行级别的大表进行字段扩容(如VARCHAR长度调整),直接在主库执行可能导致长时间DML阻塞或资源耗尽。本文介绍一种基于MySQL级联复制(M-S1-S2)的变通方案:利用空闲从库执行OnlineDDL,通过数据一致性与GTID比对完成主从切换,从而将核心变更窗口期压缩至分钟级,大幅降低对线上业务的干扰。

背景与挑战

在某客户场景中,需将约4亿行的表中 open_id 字段从 varchar(50) 扩容至 varchar(500)。该表数据文件超过280GB。由于业务24小时有流量,无法接受长时间的读写阻塞,仅争取到4小时的维护窗口。常见的修改方式包括原生OnlineDDL、gh-ost、pt-online-schema-change (pt-osc) 以及自定义的级联复制切换。

经过评估:

  • OnlineDDL: 在主库使用 ALGORITHM=COPY 会阻塞DML,且最后Rename阶段不可读写,风险不可控。
  • Gh-ost: 虽可通过连接从库减少主库负载,但4亿数据量测试耗时长达70小时,效率难以满足短期窗口要求。
  • Pt-osc: 第三方工具,大表操作失败回滚代价极大,且依赖触发器,逻辑复杂。

最终选择“备份恢复+级联复制切换”的方案,即利用多级从库异步执行DDL,待同步完成后进行主从切换,将漫长的DDL时间转移到非关键路径。

前置准备

  1. 环境检查: 确保Master和级联Slave开启GTID模式。检查磁盘空间,剩余空间需大于待变更表大小的2倍。
  2. Binlog保留: 为保证足够的时间窗口进行全量备份与恢复,建议延长Binlog过期时间。
    SHOW GLOBAL VARIABLES LIKE 'binlog_expire_logs_seconds';
    SET GLOBAL binlog_expire_logs_seconds=1209600; -- 设置为14天
  3. 结构构建: 搭建 M -> S1 -> S2 的级联复制拓扑。注意 lower_case_table_names 设置一致性。

第1步:在从库(S2)执行OnlineDDL

此步骤的核心目的是利用从库的IO资源完成耗时最长的数据重建过程,同时保持主库(M)正常对外服务。

1. 配置从库运行参数

为防止因字段定义差异导致复制报错,并优化IO性能,需在S2上执行以下设置:

-- 防止复制报错 SQL_Errno: 13146
SET GLOBAL slave_type_conversions='ALL_NON_LOSSY';
-- 防止超时中断
SET GLOBAL interactive_timeout=144000;
SET GLOBAL wait_timeout =144000;

-- 增加Buffer Pool避免锁表过大报错(根据实际内存调整)
SET GLOBAL innodb_buffer_pool_size=32*1024*1024*1024;
-- 优化刷盘策略以加速DDL
SET GLOBAL sync_binlog=20000;
SET GLOBAL innodb_flush_log_at_trx_commit=2;
-- 提高IO能力上限
SET GLOBAL innodb_io_capacity=600000;
SET GLOBAL innodb_io_capacity_max=1200000;

2. 执行ALTER TABLE

建议使用 screen 或 tmux 挂起会话执行,监控进度:

# 替换 dbname, tablename 及实际socket路径
time mysql -S /data/mysql/3306/data/mysqld.sock -p'' dbname -NBe "ALTER TABLE tablename MODIFY COLUMN open_id VARCHAR(500) NULL DEFAULT NULL COMMENT 'Id' COLLATE 'utf8mb4_bin';"

查看DDL进度:

SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_current;

3. 等待级联同步

DDL完成后,S2上的物理文件已变更。此时需等待 M -> S1 -> S2 的Binlog事件传播完毕,确保S1和S2的逻辑数据(除新字段外)与M一致。可通过比对主从的GTID Executed集合来确认延迟归零。

主从切换与收尾

当S2数据变更后,下一步是将其提升为主库,并将原主库降级或作为新从库。

第2步:移除S1并建立M-S2直连

为了缩短后续切换时的同步距离,先断开S1,让S2直接同步M。

在S1上(可选清理):

STOP SLAVE;
RESET SLAVE ALL;
-- systemctl stop mysql_3306

在S2上:

STOP SLAVE;
RESET SLAVE ALL;
CHANGE MASTER TO
  MASTER_HOST='M主机IP',
  MASTER_USER='replication_user',
  MASTER_PASSWORD='password',
  MASTER_PORT=3306,
  MASTER_AUTO_POSITION=1,
  MASTER_CONNECT_RETRY=10;
START SLAVE;
FLUSH PRIVILEGES; -- 验证是否可正常拉取BINLOG

第3步:利用XtraBackup恢复S1并重新级联

使用S2的全量备份重新初始化S1,使S1成为S2的从库。这样可以将S2的压力分担出去。

在S1服务器上操作:

rm -rf binlog/*
rm -rf redolog/*
# 执行XtraBackup恢复
xtrabackup --defaults-file=/data/mysql/3306/my.cnf.3306 --move-back --target-dir=/data/actionsky/xtrabackup_recovery/data
chown -R mysql. data/
chown -R mysql. binlog/*
chown -R mysql. redolog/*
systemctl start mysql_3306

-- 重置GTID以适配新的复制关系
SET GLOBAL gtid_purged='';
RESET SLAVE ALL;

-- 指向新的主库S2
CHANGE MASTER TO
  MASTER_HOST='S2主机IP',
  MASTER_USER='replication_user',
  MASTER_PASSWORD='password',
  MASTER_PORT=3306,
  MASTER_AUTO_POSITION=1,
  MASTER_CONNECT_RETRY=10;
-- MySQL 8.0 需注意安全连接
SET GLOBAL GET_MASTER_PUBLIC_KEY=1;
START SLAVE;

第4步:应用停服切换与回归

这是唯一的短停服窗口。由于S2已经是M的直接从库且完成了DDL,数据一致性极快达成。

1. 停服准备:在主库M设置只读并停止写入。

SET GLOBAL read_only=ON;
SET GLOBAL super_read_only=OFF; -- 视具体情况,若要做写操作则需关闭,通常此时M即将退役,保持readonly防误改

2. 确认一致:比对M与S2的GTID Executed,完全一致后,停止M的应用线程。

3. 切换主库:将S2提升为新的Master。

STOP SLAVE;
RESET SLAVE ALL;
SET GLOBAL read_only=OFF;
SET GLOBAL super_read_only=OFF;
SHOW MASTER STATUS; -- 观察是否有新事务产生

4. 应用层更新:修改前端连接配置,指向新的主库S2 IP。进行业务回归测试。

参数复原

切换完成后,记得将S2(新主库)上临时调整的DDL相关参数还原,以确保日常生产安全性(如 sync_binlog=1, innodb_flush_log_at_trx_commit=1):

SET GLOBAL interactive_timeout=28800;
SET GLOBAL wait_timeout =28800;
SET GLOBAL innodb_buffer_pool_size=8*1024*1024*1024; -- 根据服务器实际内存设定
SET GLOBAL slave_type_conversions='';
SET GLOBAL sync_binlog=1;
SET GLOBAL innodb_flush_log_at_trx_commit=1;
SET GLOBAL innodb_io_capacity=2000;
SET GLOBAL innodb_io_capacity_max=4000;

效果对比与总结

通过磁盘IO能力的测试对比可知:

  • NVME物理机:若无流量,直接修改约需5小时。
  • 机械盘虚拟机:同样情况需40小时。

采用级联复制方案的收益在于:

  1. 并行处理:DDL时间在后台悄然进行,不占用应用响应时间。
  2. 风险隔离:若S2 DDL失败,不影响主库M;即使失败,M数据未受损,可快速重试S2。
  3. 切换快速:最后一步只需等待秒级的网络同步,即可切换VIP或配置,满足严苛的SLA要求。

注意:大表操作应贴合场景寻找合适方案,而非盲目追求单种最优工具。不建议在生产环境并行执行多个DDL。以上就是MySQL级联复制下进行大表的字段扩容的详细内容,更多关于MySQL数据库运维与大表优化的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。