MySQL - 当UPDATE命令被中断时会发生什么?

6

我在MySQL命令行客户端中发布了一条长时间运行的UPDATE查询(错误的查询),并在几秒钟后使用Ctrl-C停止了它。该命令尚未完成运行。我的数据库是否会更新某些条目,还是发生在事务中并且所有内容都将被回滚?

mysql> <LONG RUNNING INCORRECT UPDATE STATEMENT>
^CCtrl-C -- sending "KILL QUERY 12088743" to server ...
Ctrl-C -- query aborted.
ERROR 1317 (70100): Query execution was interrupted
mysql> 
更新:查询涉及的所有表都是InnoDB表。

这取决于所使用的存储引擎。请查看下面的答案。 - woofmeow
3个回答

10
对于InnoDB: MySQL手册指出,InnoDB(一种事务性存储引擎)提供了完全的ACID兼容性。因此,在一次操作中完成所有操作或在中断的情况下不执行操作并回滚。

MySQL包括诸如InnoDB存储引擎之类的组件,紧密遵循ACID模型,以便数据不会被损坏,结果不会因软件崩溃和硬件故障等异常条件而失真。

对于MyISAM: 然而,对于非事务性的MyISAM存储引擎。这些存储引擎采用一种每次写入一个语句的模型来操作。使用原子操作完成这项工作。所以如果中断了过程,那么你只能获得中断时的进度。

MySQL服务器中的非事务性存储引擎(例如MyISAM)遵循称为“原子操作”的数据完整性不同范例。MyISAM表实际上始终处于autocommit = 1模式。由于更改的数据一次写入磁盘一个语句,因此很难保证一系列相关DML操作的一致性,这些操作可能在中途被中断。因此,此模式适用于主要是读取的工作负载。在事务处理方面,当每个特定的更新正在运行时,没有其他用户可以干扰它,永远不会有自动回滚,并且没有脏读取。

但是你可以使用LOCK TABLES作为解决方法。*这是MySQL 5.5之前的默认存储引擎。
因此答案取决于你使用哪种存储引擎。希望这有所帮助 :)

2
很好的回答,比我先说了 :) 我也想说autocommit在这里是一个重要因素,而且这个之前的问题很好地解决了关于启用自动提交与显式START TRANSACTION和COMMIT/ROLLBACK之间常见的混淆问题:https://dev59.com/mnA85IYBdhLWcg3wF_YO - cerd
谢谢。我更新了问题。幸运的是,所有的表都是InnoDB,所以我没有破坏任何数据 :-) - arun
谢谢@cerd。是的,你很幸运,如果你使用MyISAM,那么@arun会很糟糕:) 如果有改进的地方,请告诉我。 - woofmeow

2
在启用autocommit的InnoDb中,简单的UPDATE操作将会完全回滚。回滚对于ACID兼容性非常重要,但可能会成为问题的源头,因此谨慎使用forced rollback可以减轻这些问题,与没有回滚相比,这些问题很少发生。
在以前的版本中存在一个错误,它没有像应该的那样发生:http://bugs.mysql.com/bug.php?id=45923
这个问题中,了解有关作为全局变量开启自动提交和使用START TRANSACTION / COMMIT行为之间差异的一些最佳实践。

-1
据我所知,MySQL查询是“原子性”的,这意味着您的数据库应该看起来好像从未运行过您的查询。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接