CHECKPOINT或COMMIT写入磁盘?


12

假设对于具有完整恢复模式数据库的SQLServer2008R2及更高版本。

我一直以为:

  1. 提交事务(COMMIT)后,该事务将写入RAM中的事务日志中。

  2. 当发生CHECKPOINT时(经过一些时间和/或某些事务和其他条件之后),最后一个CHECKPOINT和当前事务之间的事务将写入磁盘。

  3. 发生备份日志时,数据将写入MDF文件。

我对么?我的一些同事说我错了,即使有了BOL,也很难找到正确的答案。

谢谢!


Answers:


20

不幸的是,到目前为止,关于COMMIT的工作方式,答案中存在许多错误,因此,我将添加另一个错误。有关详细信息SQL Server 2000 I / O基础知识,请参见工作原理:Bob Dorr的SQL Server I / O演示。下面是它的工作原理:

  • 所有完全记录的数据写入(更改)均按以下顺序进行(请参阅了解SQL Server如何执行查询:写入数据):

    • 数据页被独家锁存
    • 将描述更改的日志记录添加到内存中的日志中。新的日志记录将生成一个新的LSN,请参阅什么是LSN:日志序列号
    • 数据页面被修改(数据记录和页面上的last_update_lsn)。现在已修改(“脏”)页面。
    • 数据页锁存器被释放
    • 更新不会直接将任何内容写入磁盘
  • COMMIT执行以下操作

    • 将描述COMMIT的新日志记录添加到日志中的内存中
    • 所有未刷新到磁盘的日志记录(包括以上生成的所有日志记录)均被刷新(写入磁盘)
    • 线程块等待,直到操作系统报告上述写入为持久性(IO完成)为止
    • COMMIT语句(或具有隐式提交的DML语句)完成
  • CHECKPOINT执行以下操作(简化),请参阅检查点如何工作以及记录的内容

    • 内存中的所有脏页都写入磁盘
      • 对于每个脏页,在开始写入磁盘之前,都会刷新(包括该磁盘上的last_update_lsn的)LSN上的日志(包括该磁盘)。请注意,刷新任何LSN都意味着所有以前的LSN也都被刷新了,因此对于最脏的页面,这是一个空操作,因为它自己的last_update可能已经被刷新了。
    • 描述检查点的日志记录被写入日志并刷新
    • 数据库启动页面将使用上面生成的记录的LSN更新

对于最少记录的操作,写入方式有所不同,请参阅可以最小记录的操作。最少记录的操作大致如下(简化):

  • 作为最小记录操作的一部分在页面中插入行之前,将生成描述该页面参与最小记录操作的事实的日志记录并将其附加到日志中(在内存中)
  • 记录最少的页面正在更新,因为它上面写着许多插入内容。什么都不记录,nothign写入磁盘。
  • 提交最少记录操作时,在提交该记录之前,要求将所有参与该事务中最少记录操作的页面都写入磁盘。Onyl写入完成后,可以将COMMIT日志记录追加到日志(在内存中),然后将直到(包括此新添加的提交日志记录)的日志刷新(写入)到磁盘。

8

提交事务(COMMIT)后,该事务将写入RAM中的事务日志中。

在甚至根据查询请求更改页面或数据之前,将事务写入事务日志。这称为预写日志记录(WAL)。如果在内存中更新页面时SQL Server崩溃,则WAL确保DB引擎可以读取事务日志并回滚事务。这是RDBMS的ACID属性。

当发生CHECKPOINT时(经过一些时间和/或某些事务和其他条件之后),最后一个CHECKPOINT和当前事务之间的事务将写入磁盘。

一个检查点将脏页从缓冲区刷新到磁盘。对于tempdb,其行为略有不同。脏页是自从磁盘读取以来已更改的页。此检查点过程会在事务日志中创建一个标记,直到已提交事务为止。发生故障后,恢复会知道所有已达到该标记的事务都已提交。您可以使用TSQL命令手动发出检查点。

发生备份日志时,数据将写入MDF文件。

否,发生备份日志时,SQL Server将事务日志信息从数据库日志文件复制到要写入备份的磁盘上。备份操作从磁盘读取数据并将数据写入磁盘。

我希望您阅读以下链接

Mark已指出了解SQL Server中的日志记录和恢复

SQL Server 2008内部和故障排除书

事务日志架构和管理


好的,似乎很清楚。只是为了确定:当COMMIT发生时,您说它已写入事务日志;您是指缓冲区还是磁盘(LDF)?
观赏者

总是先将其写入日志缓存,然后再刷新到磁盘上的事务日志。我已经添加了事务日志管理链接,以了解WAL的工作方式
-Shanky

“如果在内存中更新页面时SQL Server崩溃,则WAL确保DB引擎可以读取事务日志并回滚事务。” 仅当未提交事务时才如此。如果已经提交,则无法回滚。事务日志中的信息用于更新数据文件。即使在崩溃前缓冲区没有被写入数据文件。
miracle173 2014年

@Miracle:我想如果与特定交易相关的页面正在更新,当然交易就不会提交。
Shanky

4

下面将为您澄清一些事情:

提交事务(COMMIT)后,该事务将写入RAM中的事务日志中。

  • COMMIT(或BEGIN)与恢复模型无关。它在事务级别。事务必须完全完成或失败(记住ACID属性)。因此,从本质上讲,COMMIT将标记成功事务的结束(隐式或显式)。COMMIT语句将保证所有事务的修改都将成为数据库的永久部分。
  • 为了进行任何更改,SQL Server将使用WAL(预写日志记录),其中它将首先在日志中描述将要进行的任何更改,然后再修改数据。

当发生CHECKPOINT时(经过一些时间和/或某些事务和其他条件之后),最后一个CHECKPOINT和当前事务之间的事务将写入磁盘。

发生备份日志时,数据将写入MDF文件。

参考:

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.