为什么单事务的mysqldump比没有事务的mysqldump更一致?

时间:2012-05-22 15:28:04

标签: mysql mysqldump

我已经阅读了手册,并且提到每个事务都会在开始转储之前添加BEGIN语句。有人可以用更容易理解的方式详细阐述这个吗?

以下是我读到的内容:

  

此选项在从服务器转储数据之前发出BEGIN SQL语句。它仅适用于InnoDB和BDB等事务表,因为它   在发布BEGIN时转储数据库的一致状态而不阻塞任何应用程序。“

有人可以详细说明这个吗?

3 个答案:

答案 0 :(得分:22)

由于转储在一个事务中,因此您可以获得数据库中所有表的一致视图。这可能是一个反例最好的解释。假设您使用两个表OrdersOrderLines

转储数据库
  1. 您无需单笔交易即可启动转储。
  2. 另一个进程在Orders表中插入一行。
  3. 另一个进程在OrderLines表中插入一行。
  4. 转储处理OrderLines表。
  5. 另一个进程会删除OrdersOrderLines记录。
  6. 转储处理Orders表。
  7. 在此示例中,您的转储将包含OrderLines的行,但不包含Orders的行。如果OrdersOrderLines之间存在外键,则数据将处于不一致状态,并且在还原时将失败。

    如果您在单个事务中完成了此操作,则转储将既没有订单也没有行(但它会保持一致),因为两者都已插入,然后在事务开始后被删除。

答案 1 :(得分:5)

我曾经遇到过这样的问题:没有--single-transaction参数的mysqldump会因转储期间数据被更改而一直失败。据我所知,当您在单个事务中运行它时,它会阻止转储期间发生的任何更改导致问题。实质上,当您发出--single-transaction时,它会在此时获取数据库的快照并转储它,而不是转储在实用程序运行时可能正在更改的数据。

答案 2 :(得分:5)

这对备份很重要,因为这意味着您可以获得所有数据,就像在某个时间点那样。

例如,想象一下一个简单的博客数据库,一些典型的活动可能是

  1. 创建新用户
  2. 由用户创建新帖子
  3. 删除删除帖子的用户
  4. 现在,当您备份数据库时,备份可以按此顺序备份表

    1. 帖子
    2. 用户
    3. 如果有人删除了帖子所需的用户,备份到达#1后会发生什么?

      当您恢复数据时,您会发现您有一个帖子,但该用户在备份中不存在。

      围绕整个事务进行事务意味着备份不会看到备份期间发生在数据库上的所有更新,插入和删除。