SQL Server中数据的修改是如何落盘的?
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中数据的修改是如何落盘的?的更多相关文章
- SQL Server对数据进行修改
SQL Server对数据进行修改,修改数据库中的数据. auto"> <tr style="background:red"> <td>编号 ...
- MS SQL Server中数据表、视图、函数/方法、存储过程是否存在判断及创建
前言 在操作数据库的时候经常会用到判断数据表.视图.函数/方法.存储过程是否存在,若存在,则需要删除后再重新创建.以下是MS SQL Server中的示例代码. 数据表(Table) 创建数据表的时候 ...
- 《SQL Server企业级平台管理实践》读书笔记——SQL Server中数据文件空间使用与管理
1.表和索引存储结构 在SQL Server2005以前,一个表格是以一个B树或者一个堆(heap)存放的.每个B树或者堆,在sysindexes里面都有一条记录相对应.SQL Server2005以 ...
- 记录sql server中数据创建时间和最后修改时间,方便查找问题
getdate()用例: 2008-12-29 16:25:46.635 1.创建时间:将字段设置为datetime类型,并设置默认值为 getdate() 2.修改时间:通过触发器,在 update ...
- SQL Server中数据去重单列数据合并
sql中我们偶尔会用到对数据进行合并,但其中的某一列数据要进行合并的操作: 如下图,一个用户有多个角色ID,如果我们想要统计一个用户有哪些角色,并且以单列的展现形式,单纯的用DISTINCT去掉肯定是 ...
- sql server中数据约束相关的查询
根据表名查找数据约束 SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'CMS_EventLog'; SEL ...
- SQL Server 中数据查询注意事项
1.查询语句不用区分大小写,而且即使每张表的表名或者列名出现大写字母,在写查询语句的时候也不用区分大小写,查询结果保持一致,所以查询语句小写即可. 2.在写查询语句的时候列名不需要带单引号,数值型的字 ...
- 浅谈SQL Server中的事务日志(二)----事务日志在修改数据时的角色
简介 每一个SQL Server的数据库都会按照其修改数据(insert,update,delete)的顺序将对应的日志记录到日志文件.SQL Server使用了Write-Ahead logging ...
- 在SQL Server中实现关系模型的阶梯到级别3的t -SQL DML
在SQL Server中实现关系模型的阶梯到级别3的t -SQL DML 格雷戈里·拉森(Gregory Larsen),2017/08/02(第一次出版:2011 /11/09) 原文链接:http ...
随机推荐
- linux 下nginx安装
一.一键安装四个依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 二.创建一个安装目录,并下载nginx安装 ...
- Python闭包Closure 2
由于Python中,变量作用域为LEGB,所以在函数内部可以读取外部变量,但是在函数外不能读取函数内的变量.但是出于种种原因,我们需要读取函数内的变量时候怎么办?那就是在函数内在加一个函数. def ...
- 基于特征码文件恢复工具magicrescue
基于特征码文件恢复工具magicrescue 常见类型的文件都包含一些特殊的字节,用来标识文件的类型.这些字节被称为特征码.在磁盘中,当记录文件存储位置的簇损坏后,就可以基于这些特征码来恢复文件. ...
- 机器学习之路: 深度学习 tensorflow 神经网络优化算法 学习率的设置
在神经网络中,广泛的使用反向传播和梯度下降算法调整神经网络中参数的取值. 梯度下降和学习率: 假设用 θ 来表示神经网络中的参数, J(θ) 表示在给定参数下训练数据集上损失函数的大小. 那么整个优化 ...
- 机器学习之路:tensorflow 深度学习中 分类问题的损失函数 交叉熵
经典的损失函数----交叉熵 1 交叉熵: 分类问题中使用比较广泛的一种损失函数, 它刻画两个概率分布之间的距离 给定两个概率分布p和q, 交叉熵为: H(p, q) = -∑ p(x) log q( ...
- Python 面向对象编程——类定义与对象
<类定义与对象声明> 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对 ...
- C# 复制、粘贴文本信息到系统剪贴板
复制: Clipboard.SetDataObject(textBox1.SelectedText); 粘贴: IDataObject iData = Clipboard.GetDataObject( ...
- wpf企业应用之SelectButton(用于列表页之类的选择)
在企业级应用中,通常我们会遇到这样的需求,需要点击一个按钮选择列表中的一项或者多项,然后将结果显示到按钮中.这里我给自己的控件命名为SelectButton,具体效果见 wpf企业级开发中的几种常见业 ...
- codevs 1005 生日礼物
1005 生日礼物 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 9月12日是小松的朋友小寒的生日.小松知 ...
- bzoj 3211 线段树
开方操作最多进行5次就可以把出现的任何数变成1. 所以用线段树暴力修改,以后修改时只需看一下是否当前区间都是0或1,如果是那么就直接返回. /***************************** ...