MySQL零停机模式更新解决方案
场景:你正安静地坐在办公室舒适的小角落里,全神贯注地想着自己的事情,突然,你的产品经理向你提出了一个想法,这个想法可以让你的应用程序上的交互量激增。
几个API调用到另一个微服务,一个数据库迁移,完成了一天。这似乎是一个微不足道的任务。但命运为我写了一些其他的东西。
作为一名软件开发人员,有时候你会遇到一些任务,这些任务在第一次尝试时看起来很简单,但在后面的阶段,它会让你惊讶于不可预见的问题和障碍。老实说,这是开发人员生活的一部分。解决这些不那么微不足道的问题会让工程变得有趣!
这是另一个在平常日子里需要解决的重要问题。那天我面对的问题让我兴奋到了一个程度,我知道这不是我们作为一个开发人员所面临的日常挑战。
问题:
我不得不提出的解决问题的方法涉及到迁移数据库的一个表(向表中添加一个新列)。一个关键的微服务正在使用这个数据库,所有的身份验证和授权都通过它进行。这听起来像是一个微不足道的任务,但实际上并不是。需要修改的表包含2200万行,和算法到位是不工作。MySQL给了一个错误,让我尝试算法复制。(免责声明:如果您不熟悉algorithm copy/inplace之类的术语,不用担心,我将在本文的后面解释)。使用algorithm copy而不是inplace将涉及到在迁移期间(以小时为单位)对表的写锁定。这样的锁定将使数据库在更新期间不可用。
当然,我们承受不起这样的停机时间。
什么是MySQL的算法副本和算法就位?
Algorithm inplace -顾名思义,它在不创建原始表的临时表的情况下更改表的模式,而是在原始表本身中进行更改。在更改表模式(DDL)期间,它不会导致对原始表的DML操作(数据操纵语言)的读写锁定。例如,向现有表添加新列。
Algorithm Copy -顾名思义,它通过创建一个新的临时表来改变现有表的模式(在我们的例子中,添加一个新列),将数据迁移到新的临时表,更改到新表的链接,删除旧表,完成。但是有一个问题,MySQL文档会告诉我们。
因此,通俗地说,复制允许读取,但不允许写入/更新,具体取决于操作使用的锁定策略。
为什么algorithm inplace在我的场景中不起作用?
简单介绍一下背景,我想要迁移的表是在MySQL 5.5版中构建的,现在数据库升级到了MySQL 5.6版。
当算法到位,没有工作,我深入挖掘MySQL文档,我发现这一点
从MySQL 5.6.16开始,ALTER TABLE会升级MySQL 5.5暂时的 数据行转换为5.6格式,以进行ADD COLUMN、CHANGE COLUMN、MODIFY COLUMN、ADD INDEX和FORCE作业。因为必须重建数据表,所以无法使用INPLACE算法来完成此转换,因此在这些情况下指定ALGORITHM=INPLACE会导致错误。如有必要,请指定ALGORITHM=COPY。
用外行的话来说,MySQL建议我使用算法复制,但我不能在我们的生产实例上使用。(读取停机时间只有几个小时,而我们甚至无法承受几分钟)。
那么,什么是时态列呢?在花更多的时间和医生在一起的时候,我发现了这个!!
对联机DDL操作的限制:
错误1846(0A 000):不支持ALGORITHM=INPLACE。原因:无法更改列类型INPLACE。请尝试ALGORITHM=COPY。
时间类型的一个小概述-
日期和时间类型 用于表示暂时的 值为日期、时间、日期时间、时间戳和年份。每个时态类型 有一个有效值的范围,以及一个“零”值,当您指定MySQL数据库 不能代表。
存储日期、时间、日期时间、时间戳等的数据类型是时态类型。
最后我得到了inplace不起作用的原因。原因在文档中写得很清楚。
我想添加列的表是在MySQL 5.5版中构建的
此表具有时态类型。
MySQL版本已更新至5.6
无法使用就地算法对此表的架构进行任何更改,因为需要重新生成架构。
若要立即更改架构,必须首先运行算法复制,这将通过重建架构来更改架构。
在使用copy重新生成架构后,可以使用inplace执行对架构的任何后续更改。
因此,我没有其他选择了(至少MySQL文档是这样建议我的)。
我必须用算法复制。
正是我当时的情况
解决方案:percona工具包提供的pt-online-schema-change
我找到了我们技术部门的专家,他建议我使用Flash般的速度pt-online-schema-change
以减轻上述问题。
文档中有我们问题的解决方案。
pt-online-schema-change 更改表的结构,而不会阻止读取或写入。pt-online-schema-change模拟MySQL在内部更改表的方式,但它只对您要更改的表的副本起作用。这意味着原始表未被锁定,客户端可以继续读取和更改其中的数据。pt-online-schema-change会先建立要变更之数据表的空白复本,然后视需要加以修改,再将原始数据表中的数据列复制到新数据表中。复制完成后,它会移走原始数据表,并以新数据表取代它。依预设,它也会卸除原始数据表。
在复制期间对原始表中的数据所做的任何修改都将反映在新表中,因为该工具会在原始表上创建触发器,以更新新表中的相应行。使用触发器意味着,如果已在表上定义了任何触发器,则该工具将无法工作。
因此,简而言之,pt-online-schema-change的作用如下
使用更新的模式创建新的临时表。
将数据从旧表按块复制到新创建的表中。
不锁定读取。
不锁定写入。
创建将旧表中新添加的数据复制到新表中的触发器。
对新表执行原子RENAME操作。
删除旧表。
问题似乎已解决,已在服务器上运行以下两个命令进行迁移-
还有......
当然,第一次没有成功。
我想是因为pt-online-schema-change 需要更多的内存来运行。所以第一次尝试失败了。
我们增加了内存并再次尝试,所以第二次尝试,*** 鼓声再次响起 ***
成功了!不过先给予你一下,我们是在晚上11点半,而当它完成的时候,它已经是上午5点45分!它花了大约6个小时 运行迁移2200万行不过,这次行动最棒的部分是无停机时间 呼!!!事情做完了,省了一天,又是一个通宵,学到了新东西!
所以我在那六个小时里做的-
举报/反馈