断电 - 查询完成了吗?

9 mysql

有没有办法检查查询是否完成?上周外出度假时,我运行了 3 个非常长的更新查询(每个 +/- 25 小时)。不幸的是,在一周内的某个地方停电了,运行 MYSQL 的机器关闭了。有没有办法检查并查看 3 个(或所有三个)查询中的哪一个已完成?

我知道我可以检查数据是否已更新,但是在正确且完整的执行情况下会出现 NULL,并且有 4800 万行数据需要仔细阅读。有什么想法吗?

Shl*_*ach 9

如果您在启用二进制日志的情况下运行,则可以以相对较高的可靠性进行检查。

首先,要查看是否确实启用了二进制日志,请运行:

SHOW BINARY LOGS;
Run Code Online (Sandbox Code Playgroud)

如果它们被启用,你应该得到这样的输出:

+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000244 |  15462544 |
| mysql-bin.000245 | 102622775 |
+------------------+-----------+
Run Code Online (Sandbox Code Playgroud)

否则,您将收到错误消息。

现在,如果启用了二进制日志,那么任何成功的提交也会写入二进制日志。我说的是“提交”,但事实是任何成功的操作,即使是在 MyISAM 等非事务性表上,都写在那里。但是,老实说,为了确定您的查询结果,我确实希望您使用 InnoDB 等事务引擎,否则您无法确定任何事情。

好的,假设现在您打开了二进制日志,并且您的表是事务性的(希望是 InnoDB),那么您的查询的成功完成应该会写入二进制日志。

您现在必须查找相关的二进制日志并在那里查找查询。如果您找到查询 - 很好!如果没有 - 很可能不存在。我很快就会解释。

哪个二进制日志包含您的查询?查看二进制日志文件本身,通常在您的数据目录中。寻找他们的时间戳。上电后,创建了一个新的二进制日志。找到它。您的查询很可能之前的二进制日志中。这是一个猜测。它也可能是在那之前的一个,等等。但这是一个很好的猜测。

现在,使用该mysqlbinlog实用程序,从命令行执行如下操作:

mysqlbinlog mysql-bin.000245
Run Code Online (Sandbox Code Playgroud)

用您怀疑包含查询的文件名替换文件名。

这会将这个二进制日志文件中的所有查询输出到标准输出中。在 Unix 上,使用grep来查找您的查询:

mysqlbinlog mysql-bin.000245 | grep "something which identifies the query"
Run Code Online (Sandbox Code Playgroud)

在 Windows 上,祝你好运。用记事本++或其他东西打开并手动搜索。

查询在那里?很棒 - 你知道它已经提交了。

查询不存在吗?需要检查sync_binlog参数。是1吗?然后查询不在二进制日志中 ==> 查询未提交。但是如果sync_binlog不是1,仍然有可能查询已经提交但不在二进制日志中,因为崩溃可能发生commit在二进制日志刷新到磁盘之后和之前。然后您需要恢复到其他方式。

那些是:(希望您再次使用 InnoDB):查找可以识别查询结果的单行。使用 InnoDB,您将得到“全有或全无”。如果您可以确定受查询影响的单行 - 您可以确定查询已完成。

编辑:当然,如果启用了慢速日志,您也可以期望在完成后在那里记录这么长的查询......

祝你好运!

  • 我希望你坚持下去。 (2认同)
  • @jcolebrand Rolando 可以在这里参加一些比赛:) (2认同)