适用于:SQL Server
Azure SQL 数据库
Azure SQL 托管实例
Azure Synapse Analytics
分析平台系统(PDW)
Microsoft Fabric中的SQL数据库
数据库引擎实例的 I/O 包括逻辑写入和物理写入。 当缓冲区缓存中的页数据被修改时,就会发生逻辑写入。 将页从 缓冲区缓存 写入磁盘时,发生物理写入。
在缓冲区缓存中修改页面时,不会立即将其写回到磁盘;而是将页面标记为脏。 这意味着页面在物理写入磁盘之前,可以有多个逻辑写入。 对于每次逻辑写入,都会在记录修改的日志缓存中插入一条事务日志记录。 必须先将这些日志记录写入磁盘,然后才能将对应的脏页从缓冲缓存中移除并写入磁盘。
SQL Server 使用一种称为预写日志记录(WAL)的技术,该技术可防止在将关联的日志记录写入磁盘之前写入脏页。 这对于保证恢复管理器的正常工作至关重要。 有关详细信息,请参阅 预写事务日志。
SQL Server 如何写入修改的数据页
下图显示了写入修改后的数据页的过程。
当缓冲区管理器写入某个页时,它会查找相邻的脏页,以便将其纳入一次聚集写入操作中。 相邻页具有连续的页面 ID,并且来自同一个文件;页面不必在内存中连续。 搜索将继续向前和向后进行,直到发生以下事件之一:
- 发现了一个空白页。
- 已找到 32 页。
- 找到一个日志序列号 (LSN) 尚未刷新到日志中的脏页。
- 找到一个无法立即闩锁的页。
通过这种方式,可以通过一次聚集-写入操作将整组页写入磁盘。
就在写入页面之前,会将数据库中指定的页面保护形式添加到该页面。
如果添加了残缺页保护,则必须以独占方式 (EX) 对 I/O 闩锁该页。 这是因为残缺页保护会修改该页,使其不适合任何其他线程读取。
如果添加了校验和页保护,或者数据库未使用页保护,则会使用更新 (UP) 闩锁对 I/O 闩锁该页。 该闩锁可防止任何其他人在写入期间修改该页,但仍然允许读取者使用它。
有关磁盘 I/O 页面保护选项的详细信息,请参阅 缓冲区管理。
如何将脏页写入磁盘
脏页被写入磁盘的方式有三种:
惰性写入、勤奋写入和检查点进程均不等待 I/O 操作完成。 它们始终使用异步(或重叠)I/O,并将继续执行其他工作,之后再检查 I/O 是否成功。 因此,SQL Server 在执行相应任务时可充分利用 CPU 和 I/O 资源。
延迟写入过程
惰性写入器是一个系统进程,它会删除缓冲区高速缓存中的不常用页,以保证存在可用的缓冲区。 脏页会先被写入磁盘。
勤奋写入过程
勤奋写入进程会写入与最少记录的操作(例如批量插入和选择插入)相关联的脏数据页。 该进程允许以并行方式创建和写入新页。 也就是说,调用操作无需等待整个操作完成,就可以开始将页面写入磁盘。
检查点进程
检查点过程会定期扫描缓冲区缓存中包含指定数据库页面的缓冲区,并将所有脏页写入磁盘。 检查点功能可以创建一个检查点,在该点保证全部脏页都已写入磁盘,从而在以后的恢复过程中节省时间。
用户可以使用 CHECKPOINT 命令请求检查点操作,或者数据库引擎可能会根据上次检查点以来日志空间使用量和时间的流逝自动生成检查点。 另外,在发生特定活动时会生成检查点。 例如,在数据库中添加或删除了数据或日志文件时,或在 SQL Server 实例停止时。
有关详细信息,请参阅 检查点和日志的活动部分。