SQL Server 维护着一个叫做buffer cache的东西, 在buffer cache中SQL Server 读取必须被取回的data pages. 数据在修改时并不是直接写到磁盘上的, 而是写在buffer cache中原本在磁盘上的对应数据页的拷贝中. 修改什么时候落盘呢? 答案是在checkpoint发生的时候, 或者是当修改必须被写回到磁盘上之后buffer cache才可以腾出空间用来放新的页面的时候. 把buffer cache中被修改了的数据写回到盘上的过程叫做flushing the page. 如果一个page在cache中被修改了, 但是还没写到磁盘上, 那么它就叫做dirty page.

 

任何时候, 只要buffer cache中的page一有修改, 那么一条记录就会被写在log cache中用来记录这次修改. 这条日志记录必须在dirty page被从buffer cache给flush到盘上之前先被写到盘上. 如果dirty page在log record之前被写到了盘上, 那么这个dirty page就在磁盘上创建了一次修改, 该修改在当server挂掉而log record还没落盘的时候是不能回滚的.

 

SQL Server有阻止dirty page在log record写好之前被flush到磁盘上的逻辑. 当transaction commit了之后, log record才会被写到盘上, 之后dirty page才可以被flush到盘上.

 

先后顺序如下:

Commit Transaction –> Log record written to disk –> Dirty page flush to disk.

 

从IO的角度来看, 数据库引擎生成的写IO有两种, 一种叫做logical write另一种叫做physical writes. logical write在buffer cache中的页面有修改的时候发生. physicalwrite在页面从buffer cache中写道盘上的时候发生. 当一个页面在buffer cache中修改了, 它不会马上被写回到磁盘上, 它会被标记为dirty. 这意味着, 一个page可以在physical write发生之前发生多次logical write. 对于每次logical write, 都会有一条transaction log record被添加到log cache中, 用来记录这次修改. 下图说明了写data page的过程:

当buffer manager准备写一个page到盘上的时候, 它会搜索邻近的能够凑成一个集中写操作的dirty page. 邻近的page拥有的是连续的page ID, 并且是来自于相同的file, 这些页面并不需要是在内存中是连续的. 这种搜索是前后两个方向都有的, 会一直持续下去, 直到下面的事件发生:

  • 找到了一个clean page
  • 找到了32个page
  • 找到了一个dirty page, 并且这个dirty page的log sequence number (LSN)还没有被flush到log中去.
  • 找到了一个不能被立即latch的page.

通过这种方式, 一个集合的page可以在一个single gather-write operation中写到盘上去.

 

Dirty page是通过三种方式中的一种写到盘上的:

  • Lazy writing - 一个叫做lazy writer的进程会把不常用的page从buffer cache中移除出去, 写到盘上.
  • Eager writing – Eager writer进程会将注入bulk insert, select into这样没有log的dirty data page写到盘上.
  • Checkpoint - checkpoint进程定期扫描buffer cache, 寻找某个数据库中所有的dirty page, 全部写到盘上.

 

Lazy writing, eager writing, checkpoint 进程都不会等待IO操作的结束. 他们永远是使用异步IO之后继续他们的工作的, 稍后再检查IO是否成功了. 这能让SQL Server最大化的将CPU和IO资源使用在恰当的任务上.

 

资料来源

=====================

Write-Ahead Transaction Log

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

Writing Pages

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

SQL Server中数据的修改是如何落盘的?的更多相关文章

  1. SQL Server对数据进行修改

    SQL Server对数据进行修改,修改数据库中的数据. auto"> <tr style="background:red"> <td>编号 ...

  2. MS SQL Server中数据表、视图、函数/方法、存储过程是否存在判断及创建

    前言 在操作数据库的时候经常会用到判断数据表.视图.函数/方法.存储过程是否存在,若存在,则需要删除后再重新创建.以下是MS SQL Server中的示例代码. 数据表(Table) 创建数据表的时候 ...

  3. 《SQL Server企业级平台管理实践》读书笔记——SQL Server中数据文件空间使用与管理

    1.表和索引存储结构 在SQL Server2005以前,一个表格是以一个B树或者一个堆(heap)存放的.每个B树或者堆,在sysindexes里面都有一条记录相对应.SQL Server2005以 ...

  4. 记录sql server中数据创建时间和最后修改时间,方便查找问题

    getdate()用例: 2008-12-29 16:25:46.635 1.创建时间:将字段设置为datetime类型,并设置默认值为 getdate() 2.修改时间:通过触发器,在 update ...

  5. SQL Server中数据去重单列数据合并

    sql中我们偶尔会用到对数据进行合并,但其中的某一列数据要进行合并的操作: 如下图,一个用户有多个角色ID,如果我们想要统计一个用户有哪些角色,并且以单列的展现形式,单纯的用DISTINCT去掉肯定是 ...

  6. sql server中数据约束相关的查询

    根据表名查找数据约束 SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'CMS_EventLog'; SEL ...

  7. SQL Server 中数据查询注意事项

    1.查询语句不用区分大小写,而且即使每张表的表名或者列名出现大写字母,在写查询语句的时候也不用区分大小写,查询结果保持一致,所以查询语句小写即可. 2.在写查询语句的时候列名不需要带单引号,数值型的字 ...

  8. 浅谈SQL Server中的事务日志(二)----事务日志在修改数据时的角色

    简介 每一个SQL Server的数据库都会按照其修改数据(insert,update,delete)的顺序将对应的日志记录到日志文件.SQL Server使用了Write-Ahead logging ...

  9. 在SQL Server中实现关系模型的阶梯到级别3的t -SQL DML

    在SQL Server中实现关系模型的阶梯到级别3的t -SQL DML 格雷戈里·拉森(Gregory Larsen),2017/08/02(第一次出版:2011 /11/09) 原文链接:http ...

随机推荐

  1. C++雾中风景5:Explicit's better than implicit.聊聊Explicit.

    关于Explicit还是Implicit一直是编程语言中能让程序员们干起架的争议.那些聪明的老鸟总是觉得Implicit的规则让他们能够一目十行,减少样板代码的羁绊.而很多时候,Implicit的很多 ...

  2. CSUOJ 1973 给自己出题的小X DFS

    Description 小X学习了dfs,为了练习搜索,开始给自己出题玩. 玩着玩着,一会把自己难住了,一会又被自己难倒了,真是有趣诶! 小X出的题: 现在有N个不同的正整数,求它们可以组成多少个这样 ...

  3. CSU - 2056 a simple game

    Description 这一天,小A和小B在玩一个游戏,他俩每人都有一个整数,然后两人轮流对他们的整数进行操作,每次在下列两个操作任选一个: (1)对整数进行翻转,如1234翻转成4321 ,1200 ...

  4. 解决mysql中limit和in不能同时使用的问题

    先给出数据表 CREATE TABLE `test_tb_grade` ( `ID` ) NOT NULL AUTO_INCREMENT, `) DEFAULT NULL, `COURSE` ) DE ...

  5. 交换机高级特性MUX VLAN

    MUX VLAN 基本概念 lMUX VLAN(Multiplex VLAN)提供了一种通过VLAN进行网络资源控制的机制. 例如,在企业网络中,企业员工和企业客户可以访问企业的服务器. 对于企业来说 ...

  6. shell run 屏蔽一切log

    &命令: xxx >/dev/null 2>&1 &                           屏蔽一切logxxx >/tmp/xxx.log 2 ...

  7. C++使用new和不使用new创建对象区别

    前言 在使用面向对象的时候,发现使用new和不使用new创建的对象区别还是蛮大的,做个总结: 总结 new创建的是一个指向类对象的指针,需要指针进行接收,一处初始化,多处使用,但是不用new创建的话不 ...

  8. 洛谷P2657 Loj10165 SCOI2009 windy数

    题目描述 windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和B,总共有多少个windy数? 输入输出格式 输 ...

  9. python 加密方式(MD5&sha&hashlib)

    1.MD5加密 import md5 m = md5.new() #或者m = md5.md5() m.update('123456') m.hexdigest() #或者md5.md5('12345 ...

  10. opencv 利用Haar 人脸识别

    #include <opencv2/opencv.hpp> #include <cstdio> #include <cstdlib> #include <io ...