签到成功

知道了

CNDBA社区CNDBA社区

SQL Server 恢复过程中的相关概念

2020-07-27 12:58 3353 0 原创 SQLServer
作者: dave

在之前的博客我们了解到SQL Server 数据库的三种恢复模式,如下:http://www.cndba.cn/cndba/dave/article/4497

SQL Server 三种数据恢复模式 说明
https://www.cndba.cn/dave/article/4494

在SQL Server 恢复中还会涉及到如下概念。http://www.cndba.cn/cndba/dave/article/4497

1 脏页

SQL Server 使用预写日志(write-ahead logging)的方法来保证一切数据修改的持久性。先将修改写入事务日志,然后将修改的数据写入内存。这种更新数据的方式可以提高数据库的性能,还能在需要的时候通过事务日志恢复所做的修改。

http://www.cndba.cn/cndba/dave/article/4497
http://www.cndba.cn/cndba/dave/article/4497

当 SQL Server 从磁盘中读取页到内存时,页中的内容和其在磁盘上的内容完全一致,此时该页称为干净(clean)页。一旦这个页面在内存中被修改了,这个页就被标记为脏页。

可以使用 dbcc dropcleanbuffers 语句将干净页移出缓存。在对开发和测试环境进行故障排除的时候,可以用这条语句移出所有的干净页面,这样就可以迫使 SQL Server 在后续的数据读取中都保证从磁盘而不是缓存中读取数据。这条语句不会从缓存中移出任何脏页。

通过sys.dm_os_buffer_descriptors视图可以查看每个数据库中脏页的数量∶

SELECT DB_NAME(database_id) AS 'Database',
       COUNT(page_id) AS 'Dirty Pages'
FROM sys.dm_os_buffer_descriptors
WHERE is_modified = 1
GROUP BY DB_NAME(database_id)
ORDER BY COUNT(page_id) DESC;

当空闲缓冲列表(free buffer list)显示空闲缓冲数目过少或到达检查点的时候,SQL Server会定期将脏页写回磁盘上的数据库文件。为了保证能够高效率地分配页面,SQL Server 总是力图在缓存中维持一定数目的空闲页面,空闲缓冲列表负责记录这些空闲页面。

当一个工作线程请求读数据时,这个工作线程会得到缓存中 64 个页面的列表,并且检查空闲缓冲列表的大小是否低于一个特定的阈值。如果空闲缓冲列表记录的空闲页面数目低于这个特定的阈值,这个工作线程就会尝试老化其列表中的一些页面,这个过程也会导致所有的脏页写回磁盘。http://www.cndba.cn/cndba/dave/article/4497

2 惰性写入器

惰性写入器(lazy writer)的线程也是基于低空闲缓冲列表进行工作的。该线程定期检查空闲缓冲列表的大小,当这个值过低的时候,惰性写入器会扫描整个数据缓存,将所有一段时间没被使用的页面老化。如果找到一段时间没有被使用的脏页,惰性写入器则将其写入磁盘,然后将这个页面的内存空间标记为空闲空间。

惰性写入器还要监视服务器上的空闲物理内存,一旦空闲的物理内存很少,惰性写入器就会从空闲缓冲列表中释放内存给 Windows。在 SQL Server负载很重的时候,惰性写入器还会在服务器有空闲物理内存且已分配内存没有达到最大服务器内存(max server memory)阈值的情况下增加空闲缓冲列表的大小以适应负载的需要。

3 检查点进程

检查点是检查点进程创建的一个时间点,在这个时间点,SOL Server 可以确认所有提交的事务所做的修改都已经写入磁盘。检查点标记了数据库恢复的起始点。http://www.cndba.cn/cndba/dave/article/4497

检查点进程确保和已提交的事务相关的所有脏页都被写入磁盘。为提高写入磁盘的效率,检查点进程会将未提交的脏页也写入磁盘。不过和惰性写入器不同,发生检查点的时候,并不会从缓存中移出脏页;检查点进程要做的工作只是保证脏页被写入磁盘,并且在页面头将缓存中的这个页面标记为干净的页面。

在一台繁忙的服务器上,SQL Server 默认大约每分钟就会发起一次检查点,每个检查点都在事务日志中有标记。如果重启了 SQL Server 实例或数据库,恢复进程会读取事务日志,并知道对于检查点之前所做的修改不需要做任何操作。

检查点之间的时间表示从前一个检查点之后所有需要前滚的已经提交的事务的工作量,以及后一个检查点之前所有需要回滚的未提交的事务的工作量。通过每分钟一次的检查点,SQL Server 可尝试在每次数据库启动的时候只需要不到一分钟的时间就能完成恢复操作。但如果在这段时间内写入日志的数据不到10MB,SQL Server 就不会自动发起检查点。http://www.cndba.cn/cndba/dave/article/4497

也可使用T-SQL 中的 CHECKPOINT 命令来手动执行一次检查点,检查点也可以因为 SQL Server 中的其他事件而产生。例如,提交一个备份命令的时候,系统首先就会执行一次检查点。

可以通过跟踪标志(trace flag)3502 在错误日志中记录了检查点的开始和结束位置。关于跟踪日志的更多内容参考我之前的博客:http://www.cndba.cn/cndba/dave/article/4497

SQL Server 跟踪标志 说明
https://www.cndba.cn/dave/article/4495

4 恢复间隔

恢复间隔(recovery interval)选项用于设置 Microsoft SQL Server 恢复数据库时每个数据库所需的最大分钟数。每次当 SQL Server 实例启动时,它就会恢复各个数据库,回滚未提交的事务,并前滚已提交但更改内容在 SQL Server 实例停止时尚未写入磁盘中的事务。该配置选项设置了 SQL Server 在恢复每个数据库时所应花时间的上限。默认值为 0,指示由 SQL Server 自动配置。实际上,这表示每个数据库的恢复时间不超过 1 分钟,对于每个活动的数据库大约每 1 分钟有一个检查点。

http://www.cndba.cn/cndba/dave/article/4497

https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008-r2/ms190770(v=sql.105)?redirectedfrom=MSDN

恢复间隔大于0 的设置表示检查点之间间隔的分钟数。大多数情况下,不需要对这个值进行修改。只有在对检查点进程的开销的在意程度大于对恢复时间的在意程度的时候,才需要配置这个选项。http://www.cndba.cn/cndba/dave/article/4497

SQL Server 会自动平衡检查点的 I/O操作,以防检查点进程对磁盘子系统的影响过大,一旦在服务器上看到了 SLEEP BPOOL FLUSH等待类型,就说明系统正在限制检查点的 I/O 操作以保证系统整体的性能。

版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2283
    原创
  • 3
    翻译
  • 579
    转载
  • 196
    评论
  • 访问:8177720次
  • 积分:4428
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ