恢复失败的 pt-online-schema-change

pt-online-schema-change 是 Percona Toolkit 中的一个工具,其主要作用是在不阻塞数据库写入操作的情况下在线修改 MySQL 表结构。这个功能对于生产环境中的大表尤其重要,因为传统的 ALTER TABLE 操作通常需要锁定表,从而导致写入操作被阻塞。

具体来说,pt-online-schema-change 可以在不锁定原表的情况下执行 ALTER TABLE 操作。它通过创建一个与原表结构相同但包含所需更改的新表(通常称为“中间表”或“幽灵表”),然后在新表上执行 ALTER TABLE 操作。接下来,它会创建触发器来捕获对原表的任何更改,并将这些更改应用到新表上。一旦新表与原表的数据同步,pt-online-schema-change 就会重命名原表和新表(这个过程需要短暂的元数据锁),然后用新表替换原表,最后删除旧表和触发器。

从 Percona Toolkit 3.6.0 开始,如果 pt-online-schema-change 被中断,您可以恢复它,接下来我给大家在测试中演示一下

要重新启动,首先需要知道它失败的位置。这就是为什么必须使用的第一个选项是 –history。它指示 pt-online-schema-change 将其进度存储在历史记录表中。默认情况下,历史记录表名称为 percona.pt_osc_history。您可以使用选项 –history-table 覆盖此名称。历史记录表结构如下

CREATE TABLE pt_osc_history (
  job_id     INT           NOT NULL AUTO_INCREMENT,
  db         CHAR(64)      NOT NULL,
  tbl        CHAR(64)      NOT NULL,
  new_table_name CHAR(64)      DEFAULT NULL,
  altr       TEXT          NOT NULL,
  args       TEXT          NOT NULL,
  lower_boundary TEXT,
  upper_boundary TEXT,
  done       ENUM('yes','no')  NOT NULL DEFAULT 'no',
  ts         TIMESTAMP     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (job_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

解释一下参数

  • job_idpt-online-schema-change 运行的唯一标识符
  • db 是数据库的名称
  • tbl 是已更改表的名称
  • new_table_namept-online-schema-change 为执行其作业而创建的表副本的名称
  • altr 是指定为 –alter 参数的 ALTER TABLE 命令
  • args 是传递给 pt-online-schema-change 命令的其他参数
  • lower_boundary 是最新 proceed 块的下限
  • upper_boundary 是最新 proceed 块的上限
  • done 是工作是否完成的指示器
  • ts 是更新任务条目时记录的时间戳。实际上,这是处理最新 chunk 时的时间戳。

如果您的表索引包含二进制列(如 BLOB 或 BINARY),请使用选项 –binary-index 创建历史记录表。在这种情况下,lower_boundary 和 upper_boundary 将是 BLOB 数据类型,而不是 TEXT。相同的思路用于 pt-table-checksum 中的 –replicate 表。

使用 –history 选项运行 pt-online-schema-change 后,它将创建包含作业详细信息的记录。如果作业失败,您可以在工具输出或历史记录表中轻松找到其唯一标识符,然后重新启动它。

以下是运行几次 pt-online-schema-changepercona.pt_osc_history 表内容的示例:

mysql> select * from percona.pt_osc_historyG
*************************** 1. row ***************************
        job_id: 1
            db: test
           tbl: pt1717
new_table_name: __pt1717_new
          altr: engine=INNODB
          args: {"history":1,"execute":1,"progress":["time","5"],"drop-new-table":0,
          "max-lag":"10","chunk-size":"10","alter":"engine=INNODB","drop-triggers":0}
lower_boundary: 9991
upper_boundary: 10000
          done: yes
            ts: 2024-06-05 13:32:09
*************************** 2. row ***************************
        job_id: 2
            db: test
           tbl: pt1717
new_table_name: __pt1717_new
          altr: engine=INNODB
          args: {"alter":"engine=INNODB","max-lag":"10","drop-new-table":0,
          "drop-triggers":0,"progress":["time","5"],"history":1,"chunk-size":"10","execute":1}
lower_boundary: NULL
upper_boundary: NULL
          done: no
            ts: 2024-06-05 13:32:09
*************************** 3. row ***************************
     job_id: 3
            db: test
           tbl: pt1717
new_table_name: __pt1717_new
          altr: engine=INNODB
          args: {"progress":["time","5"],"execute":1,"chunk-size":"10","history":1,
          "drop-new-table":0,"alter":"engine=INNODB","max-lag":"10","drop-triggers":0}
lower_boundary: NULL
upper_boundary: NULL
          done: no
            ts: 2024-06-05 13:32:09
*************************** 4. row ***************************
        job_id: 4
            db: test
           tbl: pt1717
new_table_name: __pt1717_new
          altr: engine=INNODB
          args: {"drop-triggers":0,"alter":"engine=INNODB","progress":["time","5"],
          "history":1,"chunk-size":"10","drop-new-table":0,"max-lag":"10","execute":1}
lower_boundary: 4901
upper_boundary: 4910
          done: no
            ts: 2024-06-05 13:32:12
4 rows in set (0,00 sec)

在上面的输出中

  • 第一条已经完成
done: yes
  • 第二条和第三条还没有开始
lower_boundary: NULL
upper_boundary: NULL
          done: no
  • 第四条在中间被打断
lower_boundary: 4901
upper_boundary: 4910
          done: no

要重新启动作业,请使用 –resume=ID_OF_YOUR_PREVIOUSLY_FAILED_JOB 选项运行 pt-online-schema-change。该工具将检查之前创建的表副本及其触发器是否仍然存在,并将从之前失败的 chunk 开始作业。

$ ./bin/pt-online-schema-change h=127.0.0.1,P=12345,u=root,p=lmx,D=test,t=pt1717 \
 --execute --chunk-size 10 --max-lag 10 --alter 'engine=INNODB' --progress time,5 \
 --no-drop-new-table --no-drop-triggers --history --resume=4
#输出如下

2025-01-12T15:27:11 Job 5 started.
Found 2 slaves:
s76 -> 127.0.0.1:12346
s76 -> 127.0.0.1:12347
Will check slave lag on:
s76 -> 127.0.0.1:12346
s76 -> 127.0.0.1:12347
Operation, tries, wait:
  analyze_table, 10, 1
  copy_rows, 10, 0.25
  create_triggers, 10, 1
  drop_triggers, 10, 1
  swap_tables, 10, 1
  update_foreign_keys, 10, 1
Altering `test`.`pt1717`...
Altering new table...
Altered `test`.`__pt1717_new` OK.
2024-06-05T13:54:11 Creating triggers...
2024-06-05T13:54:11 Created triggers OK.
2024-06-05T13:54:11 Copying approximately 9956 rows...
2024-06-05T13:54:14 Job 5 finished successfully.
2024-06-05T13:54:14 Copied rows OK.
2024-06-05T13:54:14 Analyzing new table...
2024-06-05T13:54:14 Swapping tables...
2024-06-05T13:54:14 Swapped original and new tables OK.
Not dropping old table because --no-drop-triggers was specified.
Not dropping triggers because --no-drop-triggers was specified.  To drop the triggers, execute:
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_pt1717_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_pt1717_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_pt1717_ins`
Successfully altered `test`.`pt1717`.

可以将选项 –history 与 –resume 一起使用,也可以跳过它。请注意,如果不使用选项 –history,则当作业再次失败时,将无法重新启动作业。

选项 –resume 的另一个先决条件是 –no-drop-new-table 和 –no-drop-triggers如果删除了新表和触发器,则 pt-online-schema-change 无法重新启动作业,因为不存在以前复制的数据。

$ ./bin/pt-online-schema-change h=127.0.0.1,P=12345,u=root,p=lmx,D=test,t=pt1717 \
--execute --chunk-size 10 --max-lag 10 --alter 'engine=INNODB' --progress time,5 \
--history --resume=9

#输出如下
2024-06-05T13:58:10 Job 10 started.
Found 1 slaves:
s76 -> 127.0.0.1:12346
Will check slave lag on:
s76 -> 127.0.0.1:12346
Operation, tries, wait:
  analyze_table, 10, 1
  copy_rows, 10, 0.25
  create_triggers, 10, 1
  drop_triggers, 10, 1
  swap_tables, 10, 1
  update_foreign_keys, 10, 1
Altering `test`.`pt1717`...
New table `test`.`___pt1717_new` not found, restart operation from scratch
`test`.`pt1717` was not altered.
History saved. Job id: 10

如果要在失败后恢复 pt-online-schema-change请将其与选项 –history –no-drop-new-table –no-drop-triggers 一起使用如果作业失败可以通过提供作业 ID 作为选项 –resume 的参数来恢复它。您将在 pt-online-schema-change 输出和历史记录表中找到失败作业的 ID。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值