mysql更新大表工具

前言:

如果在对一个数据量非常大的mysql进行表级更新时,如果直接在mysql上执行更新可能会造成数小时的锁表,而导致数据库不可以。因此使用第三方工具就显得尤为重要,下面介绍一款工具:gh-ost

项目地址:https://github.com/github/gh-ost

1、下载与安装(mysql机器或者可以连接mysql的机器):

wget https://github.com/github/gh-ost/releases/download/v1.1.10/gh-ost-binary-linux-amd64-20260604164252.tar.gz
tar -xzf gh-ost-binary-linux-amd64-20230717194200.tar.gz
chmod +x gh-ost
sudo mv gh-ost /usr/local/bin/

2、使用的前置条件

-- 确认 binlog 格式
SHOW VARIABLES LIKE 'binlog_format';  -- 必须是 ROW
-- 确认 log_slave_updates(如果有从库)
SHOW VARIABLES LIKE 'log_slave_updates'; -- 必须是 ON
-- 确认主键
SHOW CREATE TABLE xxxxx  \G
-- 必须有主键或唯一索引,gh-ost 靠它做 chunk 复制

3、执行dry-run预运行下

gh-ost \
  --host="your_mysql_host" \
  --port=3306 \
  --user="gh_ost_user" \
  --password="your_password" \
  --database="your_db" \
  --table="t_user_token_deduct_record" \
  --alter="
    ADD COLUMN billing_version tinyint NOT NULL DEFAULT 1 COMMENT '计费版本:1旧Token链
    .........
    ADD KEY idx_user_token_deduct_delivery_timeout (billing_version, settlement_status, delivery_process_start_time, id),
    ADD KEY idx_user_token_deduct_user_time (user_id, stat_start_time)
  " \
  --chunk-size=1000 \
  --max-load=Threads_running=50 \
  --critical-load=Threads_running=100 \
  --throttle-control-replicas="replica_host1,replica_host2" \   #这里表示从库的ip,如果没有从库 就把这参数去掉
  --max-lag-millis=3000 \
  --default-retries=120 \
  --postpone-cut-over-flag-file=/tmp/gh-ost.postpone.t1.flag \
  --initially-drop-ghost-table \
  --initially-drop-old-table  
  --execute    #加上就代表是正式执行了,不加代表干跑

4、整体流程

1. 先执行 gh-ost(不带 --execute,先测试)
   → 只创建 ghost 表,不真正执行,看是否有语法错误

2. 正式执行(带 --execute)
   ├─ gh-ost 创建 ghost 表(_t_user_token_deduct_record_gho)
   ├─ 在 ghost 表上应用 ALTER
   ├─ 开始全量复制数据(chunk by chunk)
   ├─ 通过 binlog 增量同步新写入
   ├─ 数据追平后,等待 --postpone-cut-over-flag-file 被删除
   ├─ 你检查:数据量是否一致、从库延迟是否正常
   └─ 删除 flag 文件 → gh-ost 做原子性 rename 切换  

  

5、切表前检查(关键) 

当 gh-ost 输出变成:

INFO Row copy complete
INFO Grabbing voluntary lock: gh-ost.1234567890.lock
INFO Setting LOCK timeout as 6 seconds
INFO Looking for magic cut-over table
这时候它已经复制完所有数据,在等你确认。
新开一个窗口执行检查:
-- 检查数据量是否一致
SELECT COUNT(*) FROM t_user_token_deduct_record;
SELECT COUNT(*) FROM _t_user_token_deduct_record_gho;

-- 检查从库延迟
SHOW SLAVE STATUS\G
确认无误后,删除 flag 文件,触发切换:
rm /tmp/gh-ost.postpone.t1.flag
gh-ost 会立刻完成原子 rename,输出:
 
INFO Renamed `_t_user_token_deduct_record_gho` to `t_user_token_deduct_record`
INFO Removed file /tmp/gh-ost.postpone.t1.flag
INFO Done migrating

 

  

  

  

  

posted @ 2026-07-24 17:22  ZANAN  阅读(6)  评论(0)    收藏  举报