(转)解释一下SQLSERVER事务日志记录

本文转载自桦仔的博客http://www.cnblogs.com/lyhabc/archive/2013/07/16/3194220.html

解释一下SQLSERVER事务日志记录

大家知道在完整恢复模式下,SQLSERVER会记录每个事务所做的操作,这些记录会存储在事务日志里,有些软件会利用事务日志来读取

操作记录恢复数据,例如:log explorer

那么事务日志记录怎麽查看,里面都记录了些什么?

打开可以利用下面SQL语句来查看所在数据库的事务日志记录

1 USE [GPOSDB] --要查看事务日志记录的数据库
2 GO
3 SELECT * FROM [sys].[fn_dblog](NULL,NULL)

事务日志记录里很多东西可以看的,里面记录了非常详细的数据库活动信息

我这里只介绍一些重要的需要知道的字段,其他字段由于本人能力有限而且觉得其他字段不是很重要就不介绍了

CurrentLSN:当前LSN号,事务日志中的每个记录都由一个唯一的日志序列号 (LSN) 标识。LSN 是这样排序的:如果 LSN2 大于 LSN1,

则 LSN2 所标识的日志记录描述的更改发生在日志记录 LSN1 描述的更改之后

MSDN解释:http://msdn.microsoft.com/zh-cn/library/ms190411(v=SQL.90).aspx

Operation:当前LSN所做的操作

Context:操作的上下文

TransactoinID:事务ID号

Log Record Fixed Length:LSN记录的所占虚拟日志文件的固定长度

Previous LSN:前一个LSN号

--------------------------------------------------------------------------------------------------------------

AllocUnitID:修改的那条数据所属分配单元ID

AllocUnitName:修改了数据的表名

Page ID:0001:00000121 转换成十进制:289    所以查看pageid为289页  DBCC PAGE([pratice],1,289,3)

Slot ID:数据所在数据页面的第几条记录

PartitionID:数据所在数据页面的所在分区ID

如上图,修改数据的表名是Insert_Test,Page ID是0001:00000121 转换为十进制为289  Slot ID是6(即数据页的第6条记录)

通过下面SQL语句就可以查看页面所在数据

1 USE [pratice]
2 GO
3 DBCC TRACEON(3604,-1)
4 GO
5
6 DBCC PAGE([pratice],1,289,3)
7 GO

 1 Slot 6 Offset 0x552 Length 211
 2
 3 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP
 4 Memory Dump @0x0A2AC552
 5
 6 00000000:   1000d000 3f080000 61616120 20202020 †....?...aaa
 7 00000010:   20202020 20202020 20202020 20202020 †
 8 00000020:   20202020 20202020 20202020 20202020 †
 9 00000030:   20202020 20202020 20202020 20202020 †
10 00000040:   20202020 20202020 20202020 20202020 †
11 00000050:   20202020 20202020 20202020 20202020 †
12 00000060:   20202020 20202020 20202020 20202020 †
13 00000070:   20202020 20202020 20202020 20202020 †
14 00000080:   20202020 20202020 20202020 20202020 †
15 00000090:   20202020 20202020 20202020 20202020 †
16 000000A0:   20202020 20202020 20202020 20202020 †
17 000000B0:   20202020 20202020 20202020 20202020 †
18 000000C0:   20202020 20202020 20202020 20202020 †
19 000000D0:   0200fc†††††††††††††††††††††††††††††††...
20
21 Slot 6 Column 0 Offset 0x4 Length 4
22
23 id = 2111
24
25 Slot 6 Column 1 Offset 0x8 Length 200
26
27 name = aaa                                            

这个表只有两个字段,我们看一下表数据

--------------------------------------------------------------------------------------------------------

Checkpoint Begin:Checkpoint开始时间

Checkpoint Begin DB Version:当前数据库版本 SQL2005是611  SQL2012是706

Checkpoint End:checkpoint的结束时间,这个时间肯定在Checkpoint Begin的下一条事务日志记录的位置

Minimum LSN: 这个第一个日志记录的日志序列号 (LSN),称为最小恢复 LSN (MinLSN)

Dirty Pages:脏的数据页

Oldest Replicated Begin LSN:如果数据库配置复制的话,那么最老的复制起始LSN

Next Replicated End LSN:下一个复制结尾LSN

Last Distributed End LSN:最新的分发结尾LSN

SPID:执行当前操作的进程ID

Beginlog Status:开始记录事务日志的状态,这个状态表示现时能够正常记录事务日志

Begin Time:事务开始时间

Transaction Name:事务名称

End Time:事务结束时间

Transaction Begin:记录这个事务的begin transaction的时候的cureent LSN

Master DBID:显示当前master数据库的DBID

Preplog Begin LSN:启动数据库前的前一个事务日志LSN

Prepare Time:准备启动数据库的时间

New Split Page:哪个数据页产生了页拆分

Rows Deleted:数据页有多少行被删除了

Description:描述这个事务是干什么的,有时候事务名称不一定就是他所做的操作名称,

比如这里碰巧事务名和描述都是CREATE TABLE 如果你为这个事务命名的话,那么只能看Description列看这个事务是做什么的

-------------------------------------------------华丽的分割线-------------------------------------------------------------------

现在解释一下 一些常见operation和context,一些不常见的我也不知道 ,呵呵o(∩_∩)o

Operation:当前LSN所做的操作

Context:操作的上下文

DCM页的资料:http://www.cnblogs.com/lyhabc/archive/2013/01/21/2870392.html


Operation


Context


解释


LOP_SET_BITS


LCX_DIFF_MAP


设置位图,资料: 差异(Differential)备份:只备份上次完整备份后,做修改的部分。备份单位是区(Extent)。意味着某个区内即使只有一页做了变动,则在差异备份里会被体现.差异备份依靠一个BitMap进行维护,一个Bit对应一个区,自上次完整备份后,被修改的区会被置为1,而BitMap中被置为1对应的区会被差异备份所备份。而到下一次完整备份后,BitMap中所有的Bit都会被重置为0

而这个BitMap在数据库第7页:

DCM页 差异变更(Differential Changed Map,DCM)页面他跟踪一个文件中的哪一个区在最新一次完整数据库备份之后被修改过。SQLSERVER用在增量备份时只对已发生数据变更的分区进行增量备份即可


LOP_BEGIN_XACT


事务开始


LOP_MODIFY_ROW


LCX_HEAP


修改堆表中的某一行记录


LOP_PREP_XACT


准备启动数据库


LOP_COMMIT_XACT


提交事务


LOP_MODIFY_ROW


LCX_BOOT_PAGE


修改数据库启动页


LOP_MODIFY_HEADER


LCX_PFS


修改PFS页的页头部信息


LOP_INSERT_ROWS


LCX_CLUSTERED


插入数据到聚集索引的索引页


LOP_INSERT_ROWS


LCX_INDEX_LEAF


插入数据到索引的叶子节点即数据页


LOP_FORMAT_PAGE


LCX_CLUSTERED


重新组织聚集索引


LOP_DELETE_SPLIT


LCX_CLUSTERED


删除聚集索引表的一行记录引起页拆分


LOP_MODIFY_HEADER


LCX_HEAP


修改堆表的某页的页头信息


LOP_BEGIN_CKPT


LCX_NULL


检查点开始


LOP_END_CKPT


LCX_NULL


检查点结束


LOP_SET_FREE_SPACE


LCX_PFS


修改PFS页设置那个数据页是空闲的


LOP_ROOT_CHANGE


LCX_CLUSTERED


聚集索引的根节点改变


LOP_INSERT_ROWS


LCX_HEAP


插入数据到堆表


LOP_FORMAT_PAGE


LCX_HEAP


格式化堆里的数据页


Operation


Lock Information


解释


LOP_LOCK_XACT


HoBt 0:ACQUIRE_LOCK_SCH_M METADATA: database_id = 14   STATS(object_id = 7, stats_id = 11)


在事务里获取锁

-------------------------------------------------------华丽的分割线---------------------------------------------------

在大容量日志恢复模式下,在事务日志记录里你会看不到对数据页的操作,当你使用bcp ,bulk inert, select into大容量操作语句的时候

像下图的那样修改数据和插入数据的记录你在事务日志记录里找不到的

所以大容量日志恢复模式时,ldf文件才这麽小,插入速度才这麽快

下面引用MSDN:

http://msdn.microsoft.com/zh-cn/library/ms190925.aspx
可以尽量减少日志量的操作
“最小日志记录”是指只记录在不支持时间点恢复的情况下恢复事务所需的信息。 本主题介绍在大容量日志恢复模式下(以及简单恢复模式下)按最小方式记录、但在运行备份时例外的操作。
 注意
在完整恢复模式下,所有大容量操作都将被完整地记录下来。 但是,可以通过将数据库暂时切换到用于大容量操作的大容量日志恢复模式,最小化一组大容量操作的日志记录。 最小日志记录比完整日志记录更为有效,并在大容量事务期间,降低了大规模大容量操作填满可用的事务日志空间的可能性。 不过,如果在最小日志记录生效时数据库损坏或丢失,则无法将数据库恢复到故障点。
下列操作在完整恢复模式下执行完整日志记录,而在简单和大容量日志恢复模式下按最小方式记录:
大容量导入操作(bcp、BULK INSERT 和 INSERT...SELECT)。 有关在何时对大容量导入表按最小方式进行记录的详细信息,请参阅在大容量导入中按最小方式记录日志的前提条件。
 注意
启用事务复制时,将完全记录 BULK INSERT 操作,即使处于大容量日志恢复模式下。
SELECT INTO 操作。
 注意
启用事务复制时,将完全记录 SELECT INTO 操作,即使处于大容量日志恢复模式下。
插入或追加新数据时,使用 UPDATE 语句中的 .WRITE 子句部分更新到大型值数据类型。 注意,在更新现有值时没有使用最小日志记录。 有关大型值数据类型的详细信息,请参阅数据类型 (Transact-SQL)。
在 text、ntext 和 image 数据类型列中插入或追加新数据时的 WRITETEXT 和 UPDATETEXT 语句。 注意,在更新现有值时没有使用最小日志记录。
 注意
不推荐使用 WRITETEXT 语句和 UPDATETEXT 语句,因此应该避免在新的应用程序中使用这些语句。
如果数据库设置为简单或大容量日志恢复模式,则无论是脱机还是联机执行操作,都会按最小方式记录一些索引 DDL 操作。 按最小方式记录的索引操作如下:
CREATE INDEX 操作(包括索引视图)。
ALTER INDEX REBUILD 或 DBCC DBREINDEX 操作。
 注意
不推荐使用 DBCC DBREINDEX 语句,因此应该避免在新的应用程序中使用该语句。
DROP INDEX 新堆重新生成(如果适用)。
 注意
DROP INDEX 操作期间将始终完整记录索引页的释放操作。

还可以看一下这篇帖子,关于大容量日志恢复模式

http://social.msdn.microsoft.com/Forums/zh-CN/958febc2-5eaf-46e4-b658-4bea087c0b0f

 1 0
 2 投票
 3 另外,做了下测试。
 4
 5 在Bulk logged模式下,日志中仅记录对Page(比如IAM,PFS和GAM)的操作,没有记录数据。。
 6
 7 Operation                          Context                   AllocUnitName
 8 LOP_MODIFY_ROW        LCX_PFS        dbo.SomeTable
 9 LOP_SET_BITS               LCX_IAM        dbo.SomeTable
10 LOP_SET_BITS               LCX_GAM        dbo.SomeTable
11 LOP_MODIFY_ROW        LCX_PFS        dbo.SomeTable
12 LOP_SET_BITS                LCX_IAM        dbo.SomeTable
13 LOP_SET_BITS                LCX_GAM        dbo.SomeTable
14 LOP_MODIFY_ROW        LCX_PFS        dbo.SomeTable
15 LOP_SET_BITS                LCX_IAM        dbo.SomeTable
16 但是对于处于Full模式下的DB,除了包含这部分数据,还有记录Data的部分。
17
18 那处于Bulk Logged模式下,所做的事务日志备份,是怎么抓取到数据变化的呢?
19
20 我做了实验,处于Bulk logged模式下,执行了事务备份,之后还是可以通过该备份文件来恢复到select * into 操作之后。
21
22 select * into ../....from ......这个应该是可以最小化日志的操作吧。

帖子里面说到,不记录事务日志,那么怎麽进行数据库还原呢?实际上通过数据库的系统页BCM页来记录数据页的变更的

参考资料:SQL Server 2008 存储结构之DCM、BCM

BCM页面结构

 1 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
 2
 3 PAGE: (1:7)
 4
 5
 6 BUFFER:
 7
 8
 9 BUF @0x03EDB9F4
10
11 bpage = 0x170E4000                   bhash = 0x00000000                   bpageno = (1:7)
12 bdbid = 5                            breferences = 1                      bUse1 = 14098
13 bstat = 0xc00009                     blog = 0x32159                       bnext = 0x00000000
14
15 PAGE HEADER:
16
17
18 Page @0x170E4000
19
20 m_pageId = (1:7)                     m_headerVersion = 1                  m_type = 17
21 m_typeFlagBits = 0x0                 m_level = 0                          m_flagBits = 0x0
22 m_objId (AllocUnitId.idObj) = 99     m_indexId (AllocUnitId.idInd) = 0    Metadata: AllocUnitId = 6488064
23 Metadata: PartitionId = 0            Metadata: IndexId = 0                Metadata: ObjectId = 99
24 m_prevPage = (0:0)                   m_nextPage = (0:0)                   pminlen = 90
25 m_slotCnt = 2                        m_freeCnt = 6                        m_freeData = 8182
26 m_reservedCnt = 0                    m_lsn = (0:0:1)                      m_xactReserved = 0
27 m_xdesId = (0:0)                     m_ghostRecCnt = 0                    m_tornBits = 0
28
29 Allocation Status
30
31 GAM (1:2) = ALLOCATED                SGAM (1:3) = NOT ALLOCATED           PFS (1:1) = 0x44 ALLOCATED 100_PCT_FULL
32 DIFF (1:6) = CHANGED                 ML (1:7) = NOT MIN_LOGGED
33
34 ML_MAP: Header @0x09C2C064 Slot 0, Offset 96
35
36 status = 0x0
37
38 ML_MAP: Extent Alloc Status @0x09C2C0C2
39
40 (1:0)        - (1:43256)    = NOT MIN_LOGGED
41
42
43 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

----------------------------------------------------华丽的分割线-------------------------------------------------

大家有兴趣可以看一下我写的这篇文章,更加了解事务日志

对SQLSERVER数据库事务日志的疑问

 http://www.cnblogs.com/lyhabc/archive/2013/06/10/3130856.html 

根据上面事务日志中的这几个字段,LOG EXPLORER软件为什麽能恢复数据生成insert脚本,估计是读取事务日志中删除了数据的数据页id

然后到数据页里先保存下数据,但是如果使用大容量日志恢复模式或者使用truncate table语句估计LOG EXPLORER软件也救不了你

因为delete语句无论是where 删除某条记录还是全表delete应该都会每条记录生成一个事务日志记录,即生成一个LSN

但是大容量日志恢复模式或者使用truncate table语句是不记录每行数据的LSN的,可能只记录删除动作

AllocUnitID:修改的那条数据所属分配单元ID

AllocUnitName:修改了数据的表名

Page ID:数据页ID

Slot ID:数据所在数据页面的第几条记录

PartitionID:数据所在数据页面的所在分区ID

--------------------------------------------------华丽的分割线-------------------------------------------------------

当你备份事务日志并截断日志之后,然后你没有对数据库做任何操作,但是依然会看到有事务日记记录生成

至于原因,由于篇幅关系,大家可以到我的另一篇博文的最下面那个问题,里面有答案

为什麽完整备份之后日志记录会增加,有时候备份完之后会增加,有时候备份完之后会减少???

因为数据库启动的时候一定修改一些系统数据库页所以肯定会有一些事务日志记录生成

文章地址:对SQLSERVER数据库事务日志的疑问

时间: 2024-10-27 06:05:44

(转)解释一下SQLSERVER事务日志记录的相关文章

内存中OLTP(Hekaton)里的事务日志记录

在今天的文章里,我想详细讨论下内存中OLTP里的事务日志如何写入事务日志.我们都知道,对于你的内存优化表(Memory Optimized Tables),内存中OLTP提供你2个持久性(durability)选项: SCHEMA_ONLY SCHEMA_AND_DATA 今天我不想更多讨论SCHEMA_ONLY,因为使用这个选项,在事务日志里没有发生任何日志(SQL Server 重启后你的数据会丢失).今天我们会专门讲解下SCHEMA_AND_DATA选项的持久性. SCHEMA_AND_D

SqlServer 事务日志已满

use master go backup transaction logtest with no_log go DBCC SHRINKDATABASE(logtest) Go SqlServer 事务日志已满

sqlserver 事务日志已满解决方案

sqlserver 事务日志已满解决方案 一.手动收缩: 1.数据库右键属性-选项-恢复模式-下拉选择简单-最后点击确定 2.右键数据库-任务-收缩-文件类型-下拉选择日志-收缩操作-在释放未使用....(默认收缩到1MB)-最后点击确定 3.最后别忘了回到第一步骤把恢复模式改为完整! 二.自动收缩: 原文地址:https://www.cnblogs.com/zlp520/p/9191373.html

解析SQLServer事务日志压缩与删除的方法

做项目的时候拿到一个只有280M的数据库备份,可是在SQLServer 2000下恢复的时候等了半天才都没有恢复完毕,感觉很不可思议,于是怀疑有什么猫腻.到了数据文件的目录下一看,果不其然竟然声称了一个接近10G的数据库日志文件!以前从来没有做过那么多数据的数据库,而且更没有做过有3年数据库日志记录的数据库. 这对于硬盘空间不是很充裕的我来说已经超过了能够忍受的极限,而且另一个80M的数据库回复之后生成的日志文件更是夸张的达到了5G+!这是不能忍受的,也是不能被原谅的. 刚开始的时候不太懂,直接

SqlServer 事务日志传输

基本概念 可以使用日志传送将事务日志不间断地从一个数据库(主数据库)发送到另一个数据库(辅助数据库).不间断地备份主数据库中的事务日志,然后将它们复制并还原到辅助数据库,这将使辅助数据库与主数据库基本保持同步.目标服务器充当备份服务器,并可以将查询处理从主服务器重新分配到一个或多个只读的辅助服务器.日志传送可与使用完整或大容量日志恢复模式的数据库一起使用. 日志传送由三项操作组成: 在主服务器实例中备份事务日志. 将事务日志文件复制到辅助服务器实例. 在辅助服务器实例中还原日志备份. 日志可传送

Linux定时器工具-crontab 各參数具体解释及怎样查看日志记录

要使用crontab定时器工具,必需要启动cron服务: service cron start crontab的语法,以备日后救急.先上张超给力的图: crontab各參数说明: -e : 运行文字编辑器来编辑crontab,内定的文字编辑器是VI -r : 删除眼下的crontab -l : 列出眼下的crontab(查看专用) -i : 会和-r 配合使用,在删除当前的crontab时询问,输入y 则删除 注意crontab是分用户的,以谁登录就会编辑到谁的crontab crontab特殊

(转)对SQLSERVER数据库事务日志的疑问

本文转载自桦仔的博客http://www.cnblogs.com/lyhabc/archive/2013/06/10/3130856.html 对SQLSERVER数据库事务日志的疑问 摸不透SQLSERVER了 实验环境:SQLSERVER2005 SP4,Windows7 本来没什么心情写文章,反正没人看,关于我文章中提到的问题,有些可以从文章结尾的MSDN补充那里找到答案,而有些还没有答案 根据CSDN博客的这篇文章介绍,大家可以先看一下,然后再继续往下看,因为下面会引用到CSDN博客里的

(4.19)深入理解SQLSERVER的日志链

您真的理解了SQLSERVER的日志链了吗? 转自:https://www.cnblogs.com/lyhabc/p/3460272.html 先感谢宋沄剑给本人指点迷津,还有郭忠辉童鞋今天在QQ群里抛出的问题 这个问题跟宋沄剑讨论了三天,再次感谢宋沄剑 一直以来,SQLSERVER提供了一个非常好的管理工具:SSMS 又因为这个管理工具太好了,所有操作的简单化,以至于使我们中毒太深, 对于SQLSERVER内部的一些概念搞得不清不楚 比如这些概念:日志备份链,备份日志链,日志链,备份链,备份集

XenDesktop SQL Server Mirror事务日志维护

当使用SQL Server高可用性功能的时候,例如,XenDesktop站点数据库使用完整的事务日志记录模式下运行的数据库镜像. 通过完整的事务日志记录模式下运行的事务日志会增长过大,直到数据库空间被填满或事务日志空间大小被填满.如果事务日志文件不会被监视的,默认情况下,SQL Server的配置日志文件会自动增长.这将导致2个问题: 1.事务日志文件会占用大量的磁盘空间 2.事物日志增长填满数据库空间,导致数据库不可用. 因此Citrix建议定期备份日志文件.这可以通过调度作业或维护计划来完成