我已经阅读了手册,并提到每笔交易都会BEGIN
在开始转储之前添加一条语句。有人可以以更易于理解的方式详细说明吗?
这是我读到的:
此选项在从服务器转储数据之前发出 BEGIN SQL 语句。它仅对 InnoDB 和 BDB 等事务表有用,因为它会在发出 BEGIN 时转储数据库的一致状态,而不会阻塞任何应用程序。”
有人可以详细说明一下吗?
由于转储在一个事务中,因此您可以获得数据库中所有表的一致视图。这可能最好用一个反例来解释。假设您转储一个包含两个表的数据库,Orders
并且OrderLines
Orders
另一个进程在表中插入一行。OrderLines
另一个进程在表中插入一行。OrderLines
表。Orders
和OrderLines
记录。Orders
表。在此示例中,您的转储将包含 的行OrderLines
,但没有Orders
。Orders
如果和之间存在外键,则数据将处于不一致状态并且在还原时将失败OrderLines
。
如果您在单个事务中完成了它,则转储将既没有顺序也没有行(但它会是一致的),因为两者都被插入,然后在事务开始后被删除。
我曾经遇到过没有 --single-transaction 参数的 mysqldump 会由于转储期间更改数据而始终失败的问题。据我所知,当您在单个事务中运行它时,它可以防止转储期间发生的任何更改导致问题。本质上,当您发出 --single-transaction 时,它会拍摄当时数据库的快照并转储它,而不是转储在实用程序运行时可能会更改的数据。
这对于备份可能很重要,因为这意味着您可以获取所有数据,就像它在某个时间点一样。
例如,想象一个简单的博客数据库,一个典型的活动可能是
现在,当您备份数据库时,备份可能会按此顺序备份表
如果有人在您的备份到达 #1之后删除了帖子所需的用户,会发生什么?
当你恢复你的数据时,你会发现你有一个帖子,但是用户在备份中并不存在。
围绕整个事物进行事务意味着备份期间数据库上发生的所有更新、插入和删除操作都不会被备份看到。