【问题标题】:MySQL - what happens when an UPDATE command is interrupted?MySQL - 更新命令被中断时会发生什么?
【发布时间】:2013-08-12 16:27:19
【问题描述】:

我通过 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表。

【问题讨论】:

  • 这取决于使用的存储引擎。看看下面的答案。

标签: mysql transactions sql-update interrupt


【解决方案1】:

FOR INNODB : Mysql 手册说InnoDB(事务存储引擎) 提供full ACID 投诉。因此,它将一次完成所有操作,或者在中断的情况下不执行操作并回滚。 这是 MySQL 5.5 及更高版本的默认引擎。

MySQL 包含 InnoDB 存储引擎等组件,这些组件与 ACID 模型密切相关,因此数据不会因软件崩溃和硬件故障等异常情况而损坏,结果也不会失真。

对于 MYISAM:但是对于MyISAM 存储引擎,它是非事务性的。此类存储引擎遵循一次写入一条语句的模型。这是使用原子操作完成的。所以如果你打断了这个过程,那么你就会明白这一点,直到你被打断。

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

但是,您可以使用LOCK TABLES 作为解决方法。 这是 MySQL 5.5 之前的默认存储引擎。 *

所以答案取决于您使用的存储引擎。希望有帮助:)

【讨论】:

  • 很好的答案,打败了我 :) 还想说autocommit 是这里的一个重要因素,这个上一个问题很好地解决了一个常见的混淆来源:启用自动提交与显式开始交易并提交/回滚:stackoverflow.com/questions/2950676/…
  • 谢谢。我更新了qn。幸运的是所有表都是 InnoDB,所以我没有损坏任何数据:-)
  • 谢谢@cerd。是的,你很幸运@arun 如果你一直在使用MyISAM 会很糟糕:) 让我知道它是否可以改进。
【解决方案2】:

在启用 autocommit 和简单的 UPDATE 的 InnoDb 中,它将完全启动回滚。回滚对于 ACID 合规性很重要,但可能是问题的根源,因此仔细使用 forced rollback 可以缓解这些问题,与没有回滚的问题相比,这些问题很少出现。

在以前的版本中解决了一个错误,该错误没有发生,因为它应该有:http://bugs.mysql.com/bug.php?id=45923

来自this question 关于自动提交作为全局变量与使用 START TRANSACTION/COMMIT 行为之间的区别,您可以了解有关一些最佳实践的更多信息。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-03
      • 2015-04-21
      • 2012-02-12
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多