博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
检查点(Checkpoint)过程如何处理未提交的事务
阅读量:5319 次
发布时间:2019-06-14

本文共 2294 字,大约阅读时间需要 7 分钟。

每次我讲解SQL Server之前,我都会先简单谈下当我们执行查询时,在SQL Server内部发生了什么。执行一个SELECT语句非常简单,但是执行DML语句更加复杂,因为SQL Server要修改内存中的相关页,并在事务日志里记录整个事务。

介绍完这些特定步骤后,我总会问同样的问题:当我们有个未提交的事务,这个时候刚好有检查点(Checkpoint)发生,SQL Server会崩溃么?在我们数据文件里有我们未提交的数据么?先思考下,然后再写下你的答案。

创建测试场景

现在我想和你一起重建这个特定场景,最后你会看到你是否回答对了。这个场景的第一步,我创建了一个新的数据库,一个新的表,并插入一些记录。

1 -- Create a new database 2 CREATE DATABASE Checkpointing 3 GO 4  5 -- Use it 6 USE Checkpointing 7 GO 8  9 -- Create a new table10 CREATE TABLE Foo11 (12     Col1 CHAR(100) NOT NULL,13     Col2 CHAR(100) NOT NULL,14     Col3 CHAR(100) NOT NULL15 )16 GO17 18 -- Insert a record19 INSERT INTO Foo VALUES20 (21     REPLICATE('A', 100),22     REPLICATE('B', 100),23     REPLICATE('C', 100)24 )25 GO26 27 -- Retrieve the record28 SELECT * FROM Foo29 GO

在我们插入数据后,我想知道SQL Server存储特定记录的页号。我们可以使用DBCC IND命来来返回特定表的所有页。在我的服务器上SQL Server使用的Page id是79。

1 -- Retrieve the first data page for the specified table (columns PageFID and PagePID)2 DBCC IND(Checkpointing, Foo, -1)3 GO

现在当我们用DBCC PAGE命令输出页内容时(使用这个命令前,要先启用3604跟踪标记),我们可以看到插入的A,B,C的16进制值。

1 -- Enable DBCC trace flag 36042 DBCC TRACEON(3604)3 GO4 5 -- Dump the first data page of the table Customers retrieved by DBCC IND previously6 DBCC PAGE (Checkpointing, 1,79, 3)7 GO

现在当我们进行检查点(Checkpoint)过程,并最终杀掉SQL Server会发生什么?未提交的数据会物理写入数据文件么?我们来试验下...

崩溃并恢复SQL Server

现在我们开始一个新的事务,并更新插入记录的第一列。

1 -- Begin a new transaction without committing it...2 BEGIN TRANSACTION3 4 UPDATE Foo5 SET Col1 = REPLICATE('X', 100)

从代码里你可以看到,我们并没有提交这个事务!它还是待定的,未提交的事务。现在我们打开另一个会话,我们人为进行一次检查点(Checkpoint)过程,并最终关闭SQL Server。

1 -- Execute it in a different session2 CHECKPOINT3 GO4 5 SHUTDOWN WITH NOWAIT6 GO

现在你认为未提交的事务已经写入数据文件了么?不确定?我们来找出答案!我们在16进制的编辑器(例如)里打开数据文件。跳到页号79的开始。在数据文件里,页号是物理偏移量,即页开始的地方——乘上8192字节,因为在SQL Server里页的大小是8kb。因此页79的开始整数偏移量是647168(79*8192).当我们查看hex值时,我们看到了我们未提交的数据。

检查点(Checkpoint)过程不会区分提交和未提交的事务。它只会到缓存管理器(Buffer Manager)索取所有脏页,不管它们事务的状态。

现在我们有不一致,损坏的数据库了么?没有,并不真的是。因为现在当我们启动SQL Server,每个数据库都经过故障恢复阶段,所有没提交的事务都会回滚。当SQL Server启动的时候,我们可以在SQL Server日志里看到这个行为:

小结

检查点(Checkpoint)不会在意你的事务状态。来自缓存池(Buffer Pool)的每个脏页会写入数据页。如果SQL Server崩溃了也没关系,因为故障恢复能恢复你的数据库到完全一致的状态。我希望这篇日志能让你更好的理解检查点(Checkpoint)过程,还有它如何与未提交的事务打交道。

作为家庭作业,你能否留言告诉我,还有哪些情形,SQL Server需要运行故障恢复为你的数据库还原到一致状态。在SQL Server里你知道多少个不同的场景呢?

参考文章:

转载于:https://www.cnblogs.com/woodytu/p/5164359.html

你可能感兴趣的文章
epoll使用具体解释(精髓)
查看>>
AndroidArchitecture
查看>>
原生JavaScript第六篇
查看>>
安装Endnote X6,但Word插件显示的总是Endnote Web"解决办法
查看>>
python全栈 计算机硬件管理 —— 硬件
查看>>
大数据学习
查看>>
简单工厂模式
查看>>
Delphi7编译的程序自动中Win32.Induc.a病毒的解决办法
查看>>
Objective-C 【关于导入类(@class 和 #import的区别)】
查看>>
倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-点击运行按钮进入到运行状态报错Error starting TwinCAT System怎么办 AdsWarning1823怎么办...
查看>>
【转】javascript 中的很多有用的东西
查看>>
Centos7.2正常启动关闭CDH5.16.1
查看>>
Android 监听返回键、HOME键
查看>>
Android ContentProvider的实现
查看>>
sqlserver 各种判断是否存在(表名、函数、存储过程等)
查看>>
给C#学习者的建议 - CLR Via C# 读后感
查看>>
Recover Binary Search Tree
查看>>
Java 实践:生产者与消费者
查看>>
[转]IOCP--Socket IO模型终结篇
查看>>
(五)归一化
查看>>