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

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

创建测试场景

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

 -- Create a new database
CREATE DATABASE Checkpointing
GO -- Use it
USE Checkpointing
GO -- Create a new table
CREATE TABLE Foo
(
Col1 CHAR(100) NOT NULL,
Col2 CHAR(100) NOT NULL,
Col3 CHAR(100) NOT NULL
)
GO -- Insert a record
INSERT INTO Foo VALUES
(
REPLICATE('A', 100),
REPLICATE('B', 100),
REPLICATE('C', 100)
)
GO -- Retrieve the record
SELECT * FROM Foo
GO

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

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

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

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

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

崩溃并恢复SQL Server

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

 -- Begin a new transaction without committing it...
BEGIN TRANSACTION UPDATE Foo
SET Col1 = REPLICATE('X', 100)

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

 -- Execute it in a different session
CHECKPOINT
GO SHUTDOWN WITH NOWAIT
GO

现在你认为未提交的事务已经写入数据文件了么?不确定?我们来找出答案!我们在16进制的编辑器(例如XVI32)里打开数据文件。跳到页号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.sqlpassion.at/archive/2016/01/25/how-the-checkpoint-process-deals-with-uncommitted-transactions/

检查点(Checkpoint)过程如何处理未提交的事务的更多相关文章

  1. sql 查看 锁定的表 或者 未提交 的事务

    --查看锁定的 表select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName from sy ...

  2. 如何找出长时间未提交的事务session ID

    收到报警某台mysql数据库慢查询数量超过5,登录上去看,发现阻塞的SQL全部是update,处于Updating状态 +---------+------+-----------+------+--- ...

  3. 查找mysql中未提交的事务

    1.查找未提交事务 在mysql中运行: select t.trx_mysql_thread_id from information_schema.innodb_trx t 2.删除线程 kill   ...

  4. 记一次mysql事务未提交导致锁未释放的问题

    记一次mysql事务未提交导致锁未释放的问题 ## 查看未提交的事务(3秒内未操作的事务) SELECT p.ID AS conn_id, P.USER AS login_user, P.HOST A ...

  5. SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  6. SQL Server中的事务与其隔离级别之脏读, 未提交读,不可重复读和幻读

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  7. .NET分布式事务未提交造成6107错误或系统被挂起的问题分析定位

    问题描述: 系统中多个功能不定期出现“Unable to get error message (6107) (0).”错误,即分布式事务超时,但报出错误的部分功能根本没有使用分布式事务. 原因分析: ...

  8. SQLServer之创建事务未提交读

    未提交读注意事项 使用 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 指定会话的锁定级别. 一次只能设置一个隔离级别选项,而且设置的选项将一直对那个 ...

  9. 曲苑杂坛--DML操作中如何处理那些未提交的数据

    对数据库稍有了解的人,数据库使用排他锁X锁来避免两个事务同时修改同一条数据,同时使用较低级别如行上加锁来提高并发度. 以下了两种场景很容易理解: 1>事务1执行 UPDATE TB1 SET C ...

随机推荐

  1. PHP版微信公共平台消息主动推送,突破订阅号一天只能发送一条信息限制

    2013年10月06日最新整理. PHP版微信公共平台消息主动推送,突破订阅号一天只能发送一条信息限制 微信公共平台消息主动推送接口一直是腾讯的私用接口,相信很多朋友都非常想要用到这个功能. 通过学习 ...

  2. smartsvn 用法

    都说SMART SVN是最全的Mac上的SVN客户端工具,分Pro版和基础版,基础版跟Versions差不多,这里找了Pro版下载并破解:mac版本smartSVN客户端下载:http://www.s ...

  3. Unsafe与CAS

    Unsafe 简单讲一下这个类.Java无法直接访问底层操作系统,而是通过本地(native)方法来访问.不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作 ...

  4. dojo Provider(script、xhr、iframe)源码解析

    总体结构 dojo/request/script.dojo/request/xhr.dojo/request/iframe这三者是dojo提供的provider.dojo将内部的所有provider构 ...

  5. 【T-SQL基础】01.单表查询-几道sql查询题

    概述: 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础 ...

  6. Wix 安装部署教程(十一) ---QuickWix

    这次发布的是这两天做的一个WIX工具QuickWIX,主要解决两个问题点1.对大文件快速生成wix标签(files,Directories,ComponentRef):2.比较前后两次工程的差异.大的 ...

  7. 【读书笔记】Programming Entity Framework CodeFirst -- 初步认识

    以下是书<Programming Entity Framework Code First>的学习整理,主要是一个整体梳理. 一.模型属性映射约定 1.通过 System.Component ...

  8. java提高篇(十)-----详解匿名内部类

    在java提高篇-----详解内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意的事项.如何初始 ...

  9. 实现tip浮层

    实现简单的tip浮层: html代码: <!doctype html> <html> <head> <meta charset="utf-8&quo ...

  10. Linux—解压缩

    压缩和解压("//"命令的解释) 常用压缩格式    .zip    .gz    .bz2    .tar.bz2        .tar.gz .zip格式压缩: zip 压缩 ...