我们有一张包含 5 亿行的表。不幸的是,其中一列是 int(11),这是一个有符号的 int,它是一个递增值,刚好超过了 21 亿这个神奇数字。这立即导致大约 10,000 名用户停机。我们讨论了许多解决方案,并决定我们可以安全地回滚这个值,比如说 10 亿。但我们必须对每一行都进行回滚。
以下是我们所做的:
更新表 1 设置 MessageId = case when MessageId < 1073741824 then 0 else MessageId - 1073741824 end;
我在一个包含 1000 万行数据的表上测试了此操作,耗时 11 分钟。因此我假设更大的表将耗时 550 分钟,即 9 小时。这将是我们 3 年来最长的停机时间。(我们是一家初创公司)。现在已经持续了 18 个小时。
我们应该做什么?
请不要说我们应该做什么。我认为我们应该一次更新几百万行。
有没有办法查看进度?Mysql 可能挂了?使用 mysql 5.0.22。
谢谢!
答案1
尝试查看 SHOW PROCESSLIST 的输出;它应该可以让您简要了解该线程内部发生的情况;最坏的情况是,您可以终止该线程(使用 KILL $threadID),然后手动清理。
嗨嗨。
答案2
您的意思是:更新 Table1 设置 MessageId = case when MessageId < 1073741824 then消息ID否则 MessageId - 1073741824 结束;
否则我会看到一堆具有相同 ID 的消息。
在 SQL 级别,其他方法可能更快:
create table new_table as
select (all other fields),
case msg id > xxx then msg_id - 1000000 else msg_id
from old_table;
这样,您就可以完全扫描一个表并一次性写入另一个表,而不是进行大量随机 i/o(您可以使用 iostat 检查)。