(以下内容转载自:http://www.bubuko.com/infodetail-1219283.html http://www.sohu.com/a/111740723_464104)
SQL Server 使用Write-ahead logging (WAL)方式保证任何数据变更的日志要比数据变更先发生。在完全恢复模式下,对数据库中任何对象的变更操作都会被记录在日志中。注意是所有的数据对象,包括:tables, views, stored procedures, users, permissions等。
使用fn_dblog()查询日志记录:
USE TestDB1
GO
SELECT * FROM [sys].[fn_dblog](NULL,NULL)
插入一条语句的日志记录如下:
LOP_BEGIN_XACT:标记一个事务的开始,也是日志中唯一包含事务开始时间的记录,同时还包含发出语句用户的SID
LOP_COMMIT_XACT:标记一个事务的结束
LOP_LOCK_XACT:锁
LOP_INSERT_ROWS、LOP_DELETE_ROWS、LOP_DELETE_ROWS:记录实际的数据修改信息
Current LSN:当前LSN
事务日志中的每一条日志记录由LSN(Log Sequence Number)唯一标识。LSN是有序的,如果LSN2大于LSN1,则LSN2的日志所代表的数据修改操作发生在LSN1之后。
Operation:当前LSN所做的操作
Context:操作的上下文
Transactoin ID:事务ID号
Log Record Fixed Length:LSN记录的所占虚拟日志文件的固定长度
Previous LSN:前一个LSN号
AllocUnitID:修改的那条数据所属分配单元ID
AllocUnitName:修改了数据的表名
Page ID:数据所在页面(16进制)
查看page id为289页的记录: DBCC Page ({dbid|db name}, file num, page num, [print opt])
Slot ID:数据所在数据页面的第几条记录
Partition ID:数据所在数据页面的所在分区ID
数据修改操作(如LOP_INSERT_ROWS)总是会记录它操作的物理内容(PageID,SlotID)和对象:分配单元(Allocation Unit ID)和分区ID(Partition ID)。
查看AllocUnitName列是确定哪一个对象被修改的最简单的方式。
Page ID 和Slot ID告诉我们哪个页的哪一个槽位被事务修改了。
可以通过DBCC PAGE来查看页内容。
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:事务名称
事务名称分类:
(1)显式提交-命名事务:[事务名]
begin transaction tran_test
use TestDB1
insert into test values(1,0)
commit
(2)显式提交-未命名事务:user_transaction
begin transaction
use TestDB1
insert into test values(0,0)
commit
(3)隐式提交-DML:INSERT、UPDATE、DELETE
use TestDB1
insert into test values(0,0)
(4)隐式提交-DDL:CREATE TABLE、ALTER TABLE、DROPOBJ
useTestDB1
create table test(
a int,
b int,
primary key(a),
)
SplitPage:页拆分
可以根据Parent Transaction ID获取执行页拆分的事务,页拆分是B-TREE根据排序键维护数据顺序的一种方式,CREATE TABLE插入元数据会导致内部元数据表的页拆分,
Allocate Root:页分配
正常情况,创建表时,不会分配页给它。第一个INSERT会触发分配第一个页给表。分配操作由单独的事务完成,并且会立即提交。即使触发页分配的那个INSERT事务被回滚或者延迟提交,也不会影响其它的数据插入操作。从这里也可以看出,一个会话中,可以开始和提交独立于会话主事务之外的事务的,只是这个功能没有提供给T-SQL,只是内部使用。
Transaction SID:启动事务的登录名的SID,可以用SUSER_SNAME()函数获取到实际的登录名。
End Time:事务结束时间
Transaction Begin:记录这个事务的begin transaction的时候的cureent LSN
Master DBID:显示当前master数据库的DBID
Preplog Begin LSN:启动数据库前的前一个事务日志LSN
Prepare Time:准备启动数据库的时间
New Split Page:哪个数据页产生了页拆分
Rows Deleted:数据页有多少行被删除了
Description:描述这个事务是干什么的,有时候事务名称不一定就是他所做的操作名称,需要通过Description指示
Lock Information:
Lock Information列的完整内容:
其中有表的Object ID,页ID和索引键的键锁信息。
对于B-TREE,键锁就是键值的HASH值,所以通过它能定位到数据行(就算发生页拆分,但是键值是不会变的)。
通过键锁信息,我们正确定位到第一个INSERT的行。
注意,HASH值存在HASH碰撞的可能,即不同的键值生成了同样的HASH值。碰撞的概率是非常低的,如果发生, 上面的查询会返回多行。
Offset in Row:
RowLog Contents 0:
RowLog Contents 1:
RowLog Contents 2:
RowLog Contents 3:
Log Record:
Operation:当前LSN所做的操作
Context:操作的上下文
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 |
格式化堆里的数据页 |
LOP_LOCK_XACT |
HoBt 0:ACQUIRE_LOCK_SCH_M METADATA: database_id = 14 STATS(object_id = 7, stats_id = 11) |
在事务里获取锁 |
|