是否有可能(以及如何)将巨大的 MyISAM 表转换为 InnoDB,而无需使应用程序脱机。它需要每秒向该表中插入几行,但可以将其挂起约 2 分钟。
显然 ALTER TABLE ... engine=innodb 将不起作用。因此,我计划使用 innodb 引擎创建一个新表并将内容复制到其中。最后,暂停应用程序日志线程和重命名表。
不幸的是,即使以 100 行的小批量复制在一段时间后也会产生明显的延迟。
编辑:永远不会更改现有行,此表用于记录。
Der*_*ney 15
创建一个 Master-Master 设置,如下所示:
logTablelogTable_new为 innodbINSERT INTO logTable_new SELECT * FROM logTable在 MasterB 上运行(伪代码),它将复制发送到 MasterAlogTable_newMasterA 完成同步时,换出表Joe*_*Joe 10
鉴于以下约束:
我不在乎谈话需要几天或几周。但它必须在后台运行,不需要应用程序的停机时间,也不会造成明显的延迟
当您进行日志记录时,如果您有一些设置标记的好方法,以便您可以知道您开始该过程的内容,那么您就可以重新应用任何日志,或者将日志写出到文本文件中你可以稍后摄取它们 LOAD DATA INFILE
部分问题在于,小批量写入意味着必须一遍又一遍地重新计算索引;你最好一次运行它,但这可能会导致系统出现一些“明显”的滞后......但你不必在你的生产服务器上这样做。
LOAD DATA INFILE)不幸的是,即使以 100 行的小批量复制在一段时间后也会产生明显的延迟。
您是在每个批次之间添加任何延迟,还是只是批量更新并在上一个批次之后直接运行每个批次?
如果是这样,请尝试使用您喜欢的语言编写转换脚本,例如:
repeat
copy oldest 100 rows that haven't been copied yet to new table
sleep for as long as that update took
until there are <100 rows unprocessed
stop logging service
move the last few rows
rename tables
restart logging
delete the old table when you are sure the conversion has worked
Run Code Online (Sandbox Code Playgroud)
这应该确保转换不会占用服务器容量的一半以上,即使考虑到系统使用随时间变化而施加的负载差异。
或者,如果您想在服务相对空闲时使用尽可能多的时间,但在数据库需要为其用户做一些工作时退出(可能暂停很长时间),请替换sleep for as long as the update took为if the server's load is above <upper measure>, sleep for some seconds then check again, loop around the sleep/check until the load drops below <lower measure>. 这意味着它可以在安静的时候继续前进,但在服务器忙于执行其正常工作负载时会完全暂停。确定负载将取决于您的操作系统 - 在 Linux 下和类似的 1 分钟负载平均值来自/proc/loadavg或uptime应该做的输出。<lower measure>并且<upper measure>可能是相同的值,尽管在这样的控件中通常会有差异,因此您的过程不会继续启动然后立即暂停,因为它自己的重新启动会对负载测量产生影响。
当然,这不适用于可能修改旧行的表,但对于像您描述的日志表这样的日志表可以正常工作。
在这种情况下,您将要忽略在填充新表后创建索引的通常智慧。虽然当您希望事情尽可能快时这确实更有效(对系统其余部分的影响该死),但在这种情况下,您不希望在流程结束时出现大量负载,因为索引完全是一次性创建的,因为这是一个在事情变得忙碌时您无法暂停的过程。
| 归档时间: |
|
| 查看次数: |
1658 次 |
| 最近记录: |