[SQL Server]内存缓存数据写入磁盘(一)首部曲

很少扎实的实践SQL Server Database Engine内部的行为,最近发现某个客户的性能瓶颈可能在Transaction log的I/O,同时另外一家客户正在导入保存厂商异地备援(DR site)的解决方案(不打算用AlwaysOn传送到异地),由于保护的是磁盘资源,我们需要确保磁盘上的mdf、ndf与ldf的一致性。

来笔记Buffer Flush To Disk读书心得以及SQL2012/2014/SQL2016相关的新古与全新功能。


维持ACID的完整性(Atomicity)及持久性(Durability)

为了维持关联式数据库A.C.I.D的重要使命,SQL Server采用事务纪录(Transaction log)来实现完整性Atomicity及持久性(Durability),这边先简单解释完整性Atomicity及持久性(Durability):

  • 完整性Atomicity:?事务必须全部完成执行,要不就是全部不执行。?
  • 持久性(Durability):事务完成之后,其作用便永远存在于系统之中。

为了能拥有飞快的I/O性能,更新数据库数据时,SQL Server会先将数据档及纪录档更新在Buffer Pool(也称Buffer cache),也就是内存缓存区内,而为了确保完整性及持久性,一个事务的Commit完成,则是将写入Buffer Pool中的Log Flush到Disk上作为确认,也就是write-ahead log (WAL),先确保log保存磁盘正确(这与AlwaysOn的同步认可很类似)。

因为数据分页(Data Page)还在Buffer Pool上,此时若SQL Server所在的服务器发生内存异常,只要Transaction log的磁盘文件(.ldf)正确,DataBase Engine还是可以使用Transaction Log完成ReDo及UnDo将Disk上的mdf/ndf文件追回或复原正确。

*如果直接同步mdf、ndf与ldf到异地机房(DR Site),可能会碰上log(ldf)是新的,但data file(mdf ndf)还是旧的情境。


从Buffer Pool写入Log到磁盘的时间点

前面文章理解到Transaction Log写入磁盘的其中一个时间点是事务Commit的Ending pose,整理几个写入磁盘的时间点:

  • 事务commit
  • log Buffer到达60K的容量
  • checkpoint 检查点

这边我们先简单测试事务commit前后,DataBase Engine在磁盘上的活动。

1.建立测试数据库、测试数据表及测试数据

CREATE DATABASE [FlushDiskDb]
 CONTAINMENT = NONE
 ON  PRIMARY
( NAME = N‘FlushDiskDb‘, FILENAME = N‘C:tempdbFlushDiskDb.mdf‘ , SIZE = 5120KB , FILEGROWTH = 1024KB )
 LOG ON
( NAME = N‘FlushDiskDb_log‘, FILENAME = N‘C:tempdbFlushDiskDb_log.ldf‘ , SIZE = 2048KB , FILEGROWTH = 10%)
GO

USE [master]
GO
ALTER DATABASE [FlushDiskDb] SET RECOVERY FULL WITH NO_WAIT
GO

create table t1
(
   c1 int identity,
   c2 varchar(30)
)

insert t1 VALUES(‘Stanley‘)
insert t1 VALUES(‘Taiwan‘)

2.打开process monitor

3.设定Filter条件

Ctrl + L?热键跳出Filer选项

设定Filter条件: Path > Contaons > database file路径

4.建立一个事务,然后先不要Commit

use FlushDiskDb

BEGIN tran tran_one
 update t1
    set c2 = ‘France‘
 where c1 = 2 

5.果然在process monitor中: 空空如也!

6.但如果此时在事务的最后面下了commit

process monitor 出现了写入.ldf的磁盘活动! 而且只有ldf没有mdf磁盘活动喔。

write-ahead log (WAL),先保证log写入磁盘来确保ACID的AD!


从Buffer Pool写入数据分页到磁盘的时间点

前面的简单练习可以理解到Log写入磁盘的时间点,也许聪明的工程师一定很快想进一步知道,数据分页写入磁盘的时间点? 从Technet的文章很快找到答案:

  • checkpoint:检查点发生
  • Lazy writer:懒惰写入器工作了(因为很懒惰,触发的机会相较checkpoint少很多)
  • Eager writing:?热切的写入器被选择,然后大量载入事务发生了(nonlogged操作的一种,这边暂时不讨论)

简单把Data Page和log buffer一起划图来表示磁盘写入流程:


检查点(CheckPoint)触发时机

这边我们先study最常发生的CheckPoint,中文是检查点,CheckPoint会将目前内存中已修改的页面 (中途分页或称Dirty Page)和事务记录资讯从内存缓存(Buffer Cache)中写入磁盘上。

Database Engine 支持几种类型的检查点:

  • 自动:SQL DataBase Engine决定,可在执行个体层级设定(recovery interval)
  • 间接:SQL Server 2012中的新功能,在数据库层级设定固定周期的检查点时间(TARGET_RECOVERY_TIME)
  • 手动: 人为的方式执行checkpoint命令
  • 系统内部:?执行数据库备份、快照、停止 SQL Server (MSSQLSERVER) 服务、SQL Server 容错移转丛集执行个体 (FCI) 离线、使用 ALTER DATABASE 加入或移除数据库文件..

我们来试试刚刚的案例,新增查询窗口,手动输入checkpoint命令!

Process monitor多了写入.mdf的磁盘活动


Checkpoint vs Lazy writer

Checkpoint和Lazy writer很类似,但Checkpoint的设计出发点是为了缩短数据库的复原时间,但Lazy writer则是为了解决内存压力,两种执行后都会将Buffer Cache的数据分页写入磁盘,但只有Lazy Writer会释放出资源。

如果也希望checkpoint释放资源,举例来说,我们需要手动再执行DBCC DROPCLEANBUFFERS命令:

CHECKPOINT;
GO
DBCC DROPCLEANBUFFERS;
GO

查询目前Buffer Pool中的数据表

我们可以透过sys.dm_os_buffer_descriptors 这个dm查询到!


USE FlushDiskDb
SELECT
	DB_NAME(buf.database_id) AS DbName
	,o.name
	,buf.*
FROM sys.dm_os_buffer_descriptors buf
LEFT JOIN sys.allocation_units AS au WITH (NOLOCK)
	ON buf.allocation_unit_id = au.allocation_unit_id
LEFT JOIN sys.partitions AS pt WITH (NOLOCK)
	ON au.container_id = pt.hobt_id
LEFT JOIN sys.objects AS o WITH (NOLOCK)
	ON pt.object_id = o.object_id
LEFT JOIN sys.indexes AS idx WITH (NOLOCK)
	ON o.object_id = idx.object_id
		AND pt.index_id = idx.index_id
WHERE DB_NAME(buf.database_id) = db_name()
  and o.type_desc = ‘USER_TABLE‘

ORDER by name 

?

执行结果:

1.Checkpoint执行前: Dirty Page

2.Checkpoint执行后

3.DBCC DROPCLEANBUFFERS执行后:

今天先大致理解Buffer Pool写入磁盘的架构及时间点,周末继续笔记未完成的SQL2012/2014/2016新古和全新功能。


参考:

Writing Pages

https://technet.microsoft.com/en-us/library/aa337560(v=sql.105).aspx

数据库检查点 (SQL Server)

https://msdn.microsoft.com/zh-tw/library/ms189573(v=sql.120).aspx

原文:大专栏  [SQL Server]内存缓存数据写入磁盘(一)首部曲

原文地址:https://www.cnblogs.com/chinatrump/p/11505624.html

时间: 2024-11-03 21:16:31

[SQL Server]内存缓存数据写入磁盘(一)首部曲的相关文章

01. SQL Server 如何读写数据

原文:01. SQL Server 如何读写数据 一. 数据读写流程简要SQL Server作为一个关系型数据库,自然也维持了事务的ACID特性,数据库的读写冲突由事务隔离级别控制.无论有没有显示开启事务,事务都是存在的.流程图如下: 数据读写流程图 0. 事务开始(1) 所有DML语句必然是基于事务的,如果没有显式开启事务,即手动写下BEGIN TRAN,SQL Server则把每条语句作为一个事务,并自动提交事务. 也就是说SQL SERVER 默认不开启隐式事务,这点与ORACLE正好相反

SQL SERVER 内存分配及常见内存问题(2)——DMV查询

原文:SQL SERVER 内存分配及常见内存问题(2)--DMV查询 内存动态管理视图(DMV): 从sys.dm_os_memory_clerks开始. SELECT [type] , SUM(virtual_memory_reserved_kb) AS [VM Reserved] , SUM(virtual_memory_committed_kb) AS [VM Committed] , SUM(awe_allocated_kb) AS [AWE Allocated] , SUM(shar

XHNetworkCache,一行代码将请求数据写入磁盘缓存

XHNetworkCache 版本记录(持续更新)2016.07.01 Version 1.1(更新) 1.增加手动清除缓存接口 2.增加获取缓存大小接口 2016.06.24 Version 1.0(发布)使用方法:1.写入 [Objective-C] 查看源文件 复制代码 ? 1 2 3 //将数据写入磁盘缓存(参数1:服务器返回的JSON数据, 参数2:数据请求URL) //[按APP版本号缓存,不同版本APP,同一接口缓存数据互不干扰] [XHNetworkCache saveJsonR

SQL Server 内存中OLTP内部机制概述(一)

----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory OLTP Internals Overview>:http://technet.microsoft.com/en-us/library/dn720242.aspx ----------------------------我是分割线------------------------------- SQL S

SQL SERVER 内存分配及常见内存问题(1)——简介

原文:SQL SERVER 内存分配及常见内存问题(1)--简介 一.问题: 1.SQL Server 所占用内存数量从启动以后就不断地增加: 首先,作为成熟的产品,内存溢出的机会微乎其微.对此要了解SQL SERVER与windows是如何协调.共享内存.并且SQL SERVER的内部对内存的管理机制. 2.在Windows 2003以上版本运行的SQL Server,内存使用量突然急剧下降: 内存是Sqlserver的生命线.在errorlog中,出现一下情况:       这类问题往往不是

人人都是 DBA(IV)SQL Server 内存管理

SQL Server 的内存管理是一个庞大的主题,涉及特别多的概念和技术,例如常见的 Plan Cache.Buffer Pool.Memory Clerks 等.本文仅是管中窥豹,描述常见的内存管理相关概念. 在了解内存管理之前,通过 sys.dm_os_memory_clerks 视图可以查询内存的使用职责(Memory Clerks),也就是内存的消耗者. SELECT [type], SUM(pages_kb) AS total_pages_kb FROM sys.dm_os_memor

Sql Server 内存相关计数器以及内存压力诊断

在数据库服务器中,内存是数据库对外提供服务最重要的资源之一, 不仅仅是Sql Server,包括其他数据库,比如Oracle,MySQL等,都是一类非常喜欢内存的应用. 在Sql Server服务器中,最理想的情况是Sql Server把所有所需的数据全部缓存到内存中,但是这往往也是不现实的,因为数据往往总是大于可用的物理内存 可以说内存是否存在压力能够直接决定数据库能否高效运行,同时,如果内存出现压力,同时也会影响到CPU的使用和存储性能,可以说是一损俱损,具有连带性. 那么,如何识别内存是否

SQL Server 内存中OLTP内部机制概述(二)

----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory OLTP Internals Overview>:http://technet.microsoft.com/en-us/library/dn720242.aspx 译者水平有限,如有翻译不当之处,欢迎指正. ----------------------------我是分割线---------------

SQL Server 内存中OLTP内部机制概述(三)

----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory OLTP Internals Overview>:http://technet.microsoft.com/en-us/library/dn720242.aspx 译者水平有限,如有翻译不当之处,欢迎指正. ----------------------------我是分割线---------------