如何读懂SQL Server的事务日志

简介

本文将介绍SQL Server的事务日志中记录了哪一些信息,如何来读懂这些事务日志中信息。首先介绍一个微软没有公开的函数fn_dblog,在文章的接下来的部分主要用到这个函数来读取事务日志。 数据库

  1. fn_dblog (@StartingLSN,@EndingLSN)
  2. --@StartingLSN:表示起始的LSN号,若是为NULL值则表示从首日志记录开始查询。
  3. --@EndingLSN:表示结束的LSN号,若是为NULL值则表示查询到尾日志记录。
  4. --须要注意的是咱们平时所看到的LSN都是十六进制的,而这边的参数须要转化为十进制,如00000021:00000077:0003在做为参数传给fn_dblog时须要转换为33:119:3

正文

  1. --建立测试数据库
  2. USE [master];
  3. GO
  4. CREATE DATABASE TestDB;
  5. GO
  6. -- 建立表
  7. USE TestDB;
  8. GO
  9. CREATE TABLE [Location] (
  10.     [Sr.No] INT IDENTITY,
  11.     [Date] DATETIME DEFAULT GETDATE (),
  12.     [City] CHAR (25) DEFAULT 'xiamen');

经过上面的代码建立了一个名为TestDB的数据库,并建立了一个三个字段的表。接下看看事务日志的内容 函数

  1. USE TestDB;
  2. GO
  3. select [Current LSN],
  4.        [Operation],
  5.        [Transaction Name],
  6.        [Transaction ID],
  7.        [Transaction SID],
  8.        [SPID],
  9.        [Begin Time]

从上图能够看出总共产生了195行日志记录,我截取了部分的结果,在Operation列中记录了对应的LSN所作的操做,其中LOP_BEGIN_XACT表示一个事务的开始,Transaction Name显示了建立的数据库的名称,而Trasaction ID则记录了所对应的事务ID。下面列出Operation几种比较常见而重要的值 测试

  • LOP_BEGIN_XACT 事务的开始
  • LOP_LOCK_XACT 获取锁
  • LOP_MODIFY_ROW 修改行(具体修改的对象能够查看AllocUnitName)
  • LOP_COMMIT_XACT 提交事务
  • LOP_DELETE_ROWS 删除数据
  • LOP_INSERT_ROWS 插入数据

接下来向表中插入100行数据,并查看对应的事务日志,代码以下: ui

  1. GO 100
  2. GO
  3.  
  4.  [Current LSN],
  5.  [Transaction ID],
  6.  [Operation],
  7.   [Transaction Name],
  8.  [CONTEXT],
  9.  [AllocUnitName],
  10.  [Page ID],
  11.  [Slot ID],
  12.  [Begin Time],
  13.  [End Time],
  14.  [Number of Locks],
  15.  [Lock Information]
  16. WHERE Operation = 'LOP_INSERT_ROWS' AND AllocUnitName = 'dbo.Location'

获得如上图所示的结果,返回的行数与咱们insert的次数一致,接下来取其中的一个Trasaction ID来看看一次insert在事务日志中记录了哪些动做。 spa

  1.  [Current LSN], [Transaction ID], [Operation], [Transaction Name], [CONTEXT], [AllocUnitName], [Page ID], [Slot ID], [Begin Time], [End Time], [Number of Locks], [Lock Information]
  2. WHERE [Transaction ID] = '0000:000002fc'

从图中能够看出这个Transaction执行步骤的详细信息 3d

  • 2014/05/25 18:35:39:197事务开始
  • 在堆表dbo.LocationPAGEID0001:0000004f插入数据
  • 2014/05/24 18:35:39:200提交事务

下面这一段是我从Lock Information栏位复制出的内容,来详细的看一下 日志

  1. HoBt 72057594039042048:ACQUIRE_LOCK_IX OBJECT: 6:245575913:0 ;ACQUIRE_LOCK_IX PAGE: 6:1:79 ;ACQUIRE_LOCK_X RID: 6:1:79:0

经过下面的代码咱们来验证一下,这样一条INSERT语句所得到的锁信息 orm

  1. DBCC TRACEON(-1,3604)
  2. DBCC TRACEON (-1,1200)--查看当前Session的锁信息
  3. DBCC TRACEOFF ( -1,1200)
  4. DBCC TRACEOFF ( -1,3604)
  5. /*
  6. Process 57 acquiring IX lock on OBJECT: 6:245575913:0 (class bit2000000 ref1) result: OK
  7. Process 57 acquiring IX lock on PAGE: 6:1:79 (class bit2000000 ref0) result: OK
  8. Process 57 acquiring X lock on RID: 6:1:79:90 (class bit2000000 ref0) result: OK
  9. */

能够看到Lock Information栏位所记录的信息与1200跟踪标记锁输出的信息是一致的。 对象

另外从事务日志中还能够看到SQL Server的一些内部操做,并看到这些操做一些具体信息,如开始的时间,进行的次数,操做的步骤等等。接下来看看页拆分的动做 blog

  1. --查找页拆分动做的Transaction
  2.  [Current LSN], [Transaction ID], [Operation], [Transaction Name], [CONTEXT], [AllocUnitName], [Page ID], [Slot ID], [Begin Time], [End Time], [Number of Locks], [Lock Information]
  3. WHERE [Transaction Name] = 'SplitPage'
  4. --查看具体Transaction中的动做
  5.  [Current LSN], [Transaction ID], [Operation], [Transaction Name], [CONTEXT], [AllocUnitName], [Page ID], [Slot ID], [Begin Time], [End Time], [Number of Locks], [Lock Information]
  6. WHERE [Transaction ID] = '0000:000002f8'

结语

经过了解事务日志中所记录的内容,能够更方便咱们去了解SQL Server所作的一些操做的执行过程。

相关文章
相关标签/搜索