借助gh-ost,对MySQL大表进行表结构的变更
gh-ost 是 GitHub 开发的一个 MySQL 在线表结构变更工具(online schema migration tool)。它的全称是 "GitHub's Online Schema Translator"。 gh-ost 现在已经是大型互联网公司进行数据库运维的重要工具。 gh-ost 允许在不锁表、不影响业务的情况下,对 MySQL 数据库表进行结构变更(如添加列、修改索引等)。 基本命令: 测试迁移: 真实迁移: 假设你有一个用户表需要添加新字段: 场景说明: gh-ost 目前只适用于 MySQL(包括 Percona Server 和 MariaDB)。它依赖 MySQL 的 binlog 机制,因此不支持 PostgreSQL、Oracle 等其他数据库。 gh-ost 不支持有外键的表。如果表有外键关系,迁移会失败。 必须使用 ROW 格式的 binlog,STATEMENT 或 MIXED 格式不支持。 表必须有主键或唯一索引,否则 gh-ost 无法正常工作。 会创建影子表,需要额外的磁盘空间(大约是原表的大小)。如果磁盘空间不足,迁移会失败。 如果主从复制本身就有延迟,gh-ost 的迁移会进一步加重延迟。需要监控 虽然 gh-ost 本身不用触发器,但如果原表上已有触发器,可能会导致数据不一致。 影子表的字符集需要与原表一致,否则可能出现乱码或数据截断。 如果迁移过程很长(几天),期间 MySQL 重启或 binlog 被清理,会导致迁移失败需要重新开始。 如果 gh-ost 不适用,可以考虑:关于 gh-ost
主要作用
核心特点
工作原理
使用方法
gh-ost 可以直接从最新的 发布页面 下载二进制文件,支持 Linux 和 macOS。gh-ost --test-on-replica --database=mydb --table=mytable --alter="ADD COLUMN new_col INT" --executegh-ost --database=mydb --table=mytable --alter="ADD COLUMN new_col INT" --execute实际例子
gh-ost \
--host=localhost \
--user=root \
--password=password \
--database=mydb \
--table=users \
--alter="ADD COLUMN age INT DEFAULT 0" \
--executeusers 有 1000 万条数据ALTER TABLE 可能需要锁表数小时适用场景
数据库支持范围
常见的坑
1. 外键约束问题
解决办法: 需要先删除外键,迁移完成后再重新添加2. binlog 格式要求
-- 检查 binlog 格式
SHOW VARIABLES LIKE 'binlog_format';
-- 如果不是 ROW,需要修改配置
SET GLOBAL binlog_format = 'ROW';3. 主键要求
4. 磁盘空间
5. 复制延迟
--max-lag-millis 参数。6. 触发器冲突
7. 字符集问题
8. 长时间迁移中断
实践建议
# 先在从库测试
gh-ost \
--host=slave-host \
--test-on-replica \
--migrate-on-replica \
--database=mydb \
--table=users \
--alter="ADD COLUMN age INT" \
--execute
# 设置合理的限流参数
gh-ost \
--max-load=Threads_running=25 \
--critical-load=Threads_running=100 \
--chunk-size=1000 \
--throttle-query="SELECT HOUR(NOW()) BETWEEN 2 AND 6" \
--execute替代方案