pt-online-schema-change 如何确保数据复制过程中的一致性

Uda*_*day 4 mysql alter-table percona percona-tools percona-toolkit

我已阅读pt-online-schema-change文档并了解它的工作原理是创建触发器并在块时间秒内复制数据块(默认为 0.5 秒)

让我们考虑下面的情况。

我们有一个 5 GB 的表 TBL1,正在使用 PT-ONLINE-SCHEMA-CHANGE 进行更改

PT-ONLINE-SCHEMA-CHANGE 使用所需的更改创建了新表,在 TBL1 上添加了触发器并开始复制。

复制了 10 个数据块,并开始复制第 11 个数据块,其大小约为“X”MB。根据工具,该块最多可在 500 毫秒或 0.5 秒内复制

在第 11 个块复制期间,应用程序发出了一个 UPDATE,它必须修改属于第 11 个数据块的有效行。

我的问题是现在发生以下哪些事情。原始表现在发生?

A) Update will be blocked till the chunk be copied and then applied on original table 
   which gets updated through triggers on new one.

B) Update will be performed on original table and data chunk will be re copied all 
   over again.
Run Code Online (Sandbox Code Playgroud)

如果选项 A 是答案,那么 PT-ONLINE-SCHEMA-CHANGE 如何实现无锁?

如果选项 B 是答案,它如何知道正在复制的块已被修改?

提前致谢。

jyn*_*nus 6

pt-online-schema-change 利用关系数据库在表级别的一致性特性。让我们看看当我们写入原始表时会发生什么,以下三种情况之一:

  1. 该块已经被复制。没问题,触发器将覆盖事务内附件表的值

  2. 该块尚未被复制。触发器可能会失败,但由于触发器上的IGNORE选项,原始修改将完成。INSERT/UPDATE/DELETE没问题,当 pt-osc 进程到达它时,它将复制较新的值。

  3. 你的问题。正在复制该块。有 2 种子情况,具体取决于哪个进程首先启动。

    a) 如果首先开始修改原始表,则整个表(在 MyISAM 的情况下)或行集(在 InnoDB 的情况下)将被锁定以进行其他修改,因此 pt-osc 必须等待写入完成。当该工具工作时,您应该避免非常耗时的写入操作,或者在负载太高时依赖它来暂停,但在不幸的情况下,您正在并发执行另一个大型更新,会话变量(innodb_lock_wait_timout由pt-osc 的参数lock-wait-timeout(默认为 1 秒)应该启动并恢复/中止该块的副本。在这种情况下,该工具将再次重试该块--retries(默认为 3 次),否则整个过程将中止,理论上会优雅地中止。在大多数情况下,一旦锁消失(因为并发写入完成),您基本上就会遇到情况 2。

    b) 如果 pt-osc 首先启动,它实际上会再次锁定整个表(在 MyISAM 中)或那些特定行(在 InnoDB 中)以进行写入(读锁),从而防止并发写入。理想情况下,该时间最多只能保持 0.5 秒,因为已经计算了块大小,因此块复制所花费的时间不应超过该时间。一旦完成,您基本上就处于案例 1 中。

所以,是的,没有 100% 无锁的工具,但如果你想保证一致性,就不存在这样的工具。即使重命名表过程也需要几微秒(毕竟,必须在磁盘上重命名一个/多个文件),并且在这些微秒内,表将被锁定。这个想法是拥有最少量的锁定。对于 MyISAM,每次写入一行(并发插入除外)时,整个表都会被锁定,而对于 InnoDB,至少会锁定该特定行(有时更多)。除非牺牲更改的原子性和持久性,否则您无法更改这一点。但是,您可以采取一些技巧来尽量减少其问题:

  • 使用 InnoDB 而不是 MyISAM 以获得额外的写入并发性
  • 在复制过程中避免该表上的缓慢/大量写入事务
  • 降低块时间参数的值。在极端情况下,您可以将 chunk-size 设置为 1,一次复制并锁定一行,但这会非常慢。当您碰巧写入当时正在复制的确切行时,块时间将是最大锁定时间的启发式最坏情况。
  • MySQL 5.6 允许在某些 DDL 运行时进行并发写入。它不太灵活,但它应该工作得更快,因为它可以访问底层逻辑。在某些情况下,这可能效果更好,但是当执行太多并发写入时(因为这些写入将被缓冲),它会遇到类似的问题。

阅读该工具的代码并不难,我邀请您阅读它以获取更多信息