注册 登录
  • 欢迎访问"运维那点事",推荐使用Google浏览器访问,可以扫码关注本站的"微信公众号"。
  • 如果您觉得本站对你有帮助,那么可以扫码捐助以帮助本站更好地发展。

GH-OST:原子切换原理

MySQL Tools 彭东稳 1561次浏览 已收录 0个评论
用过GH-OST工具就会知道,其最后也需要有一个cut-over的动作,就是原表跟新表的切换。作者提供了一个原子可靠的切换方式,并且写了三篇文章来阐述cut-over操作过程,其中还对比了Facebook OSC切换算法。

这里主要说第三篇文章:解决非原子表切换问题,使其成为原子表切换

我们提供的解决方案仅基于两个连接(之前是三个,采用乐观方式)。这里我们假设“GH-OST”工具的连接将是C10,C20;正常的应用程序连接是C1..C9,C11..C19,C21..C29。

  • 连接C1..C9:正常DML操作tbl表
  • 连接C10:CREATE TABLE tbl_old (id int primary key) COMMENT=’magic-be-here’
  • 连接C10:LOCK TABLES tbl WRITE, tbl_old WRITE
  • 连接C11..C19:新进来的请求,或许有DML和SELECT都会因LOCK而等待
  • 连接C20:RENAME TABLE tbl TO tbl_old, ghost TO tbl,会因LOCK而等待
  • 连接C21..C29:新进来的请求在tbl上发出查询,但由于LOCK和由于RENAME而在队列中等待而被阻塞
  • 连接C10:检查C20的RENAME是否正在执行(在show processlist中查找被阻止的RENAME)连接C10:DROP TABLE tbl_old,什么也没有发生,tbl仍然锁定,所有其他连接仍然被阻止
  • 连接C10:UNLOCK TABLES

这里注意了!此时存在C1..C9、C11..C19、C21..C29、C20都在等待锁,无固定先后顺序。此时,RENAME是第一个执行的,ghost表被交换代替tbl,然后C1..C9、C11..C19、C21..C29都可以运行在新的tbl表上。

注意点:

1. 创建tbl_old表是为了防止tbl表过早交换,导致数据丢失。

2. 在同一个会话下执行了write lock后是可以drop表的,这个lock本身的机制。

3. 无论DML和RENAME谁先执行,被阻塞后RENAME总是优先于DML语句被执行,这个很重要。

在gh-ost issue #82,有哥们提出一个问题就是怎么保证RENAME总是会优先于DML被执行,因为这个很关键。如果不能保证RENAME优先于DML被执行,就有数据丢失的风险。作者回答说他并没有保证,这个确实需要依赖MySQL内部行为,并且这种行为已经在MySQL中存在十年之久,并且与MySQL工程师讨论过这个问题。

整个cut-over方案的出现主要还是因为MySQL的局限性,你无法在同一个会话中锁定表后再去RENAME表(其他操作是可行的)。

如果执行失败会发生什么?

  • 如果C10的CREATE执行错误,GH-OST不会继续往下执行了。
  • 如果C10的LOCK语句出现错误,GH-OST不会继续,表未锁定,应用程序继续正常运行。
  • 如果C10在C20执行RENAME前挂掉了:

A. C10锁被释放,查询C1..C9,C11..C19立即在tbl上运行。

B. C20的RENAME立即失败,因为tbl_old表存在。

C. 整个操作都失败了,但没有什么可怕的事情发生,有些查询被阻止了一段时间,我们需要重试。

  • 如果C10在C20执行RENAME被阻塞时挂掉了:大部分与上述类似,锁释放,则C20执行RENAME失败(因为tbl_old表存在),则所有查询恢复正常操作。
  • 如果C20在C10 DROP表之前挂掉了,GH-OST会捕获该错误并让C10按计划进行:DROP,UNLOCK。并不会有什么可怕的事情发生,一些查询被阻止了一段时间,我们需要重试。
  • 如果C20在C10 DROP表之后但在解锁之前挂掉了,则与上面情况相同。C10线程挂掉后自然锁就释放了,然后C20的RENAME会在DML之前操作。
  • 如果C10和C20都挂掉了,没问题:LOCK被清除,RENAME锁被清除。 C1..C9,C11..C19,C21..C29可以在tbl上自由运行。

无论发生什么事,在操作结束时,我们都会寻找ghost表。它还在,然后我们知道操作失败了。它不在,然后它被重命名为tbl,并且该操作以原子方式工作。

关于失败的一个注意事项是清理tbl_old,也许只是让它存在下去,避免重新创建它;或者如果你喜欢,你可以删除它。

对应用程序的影响?

应用程序连接保证被阻止,直到交换ghost表或直到操作失败。在前者中,他们继续在新表上进行操作。在后者中,他们继续在原表上进行操作。

对复制的影响?

复制从库只能看到RENAME,二进制日志中没有LOCK。因此,复制会看到一个原子两表交换,没有表中断。

PS:关于表锁定看这边文章“http://www.ywnds.com/?p=14202”。


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (0)or分享 (0)
关于作者:

您必须 登录 才能发表评论!