让我们看一下在在删除动作的过程当中事务日志里发生了什么(请记住在测试数据库上做实验,不然后果自负)
我已经去除了大部分没有用的列
1 DECLARE @a CHAR(20)
2 SELECT @a = [Transaction ID] FROM fn_dblog(NULL, NULL)
3 WHERE [Transaction Name] = 'PaulsTran'
4
5 SELECT * FROM fn_dblog(NULL, NULL)
6 WHERE [Transaction ID] = @a;
7 GO
可以看到有两个插入然后跟着一个删除,删除记录标记为了鬼影记录
不过,在哪里更新PFS页呢?更新PFS页里的鬼影位不是一个事务的一部分。我们需要用另一方法查找,
除非在事务日志记录里dump所有的步骤并动手查找
1 SELECT Description, * FROM fn_dblog (null, null)
2 WHERE Context like '%PFS%' AND AllocUnitName like '%t1%';
3 GO
首先PFS分配了一页,然后第二个就是我们要找的,他为了告诉大家有鬼影记录就改变了位图里面的位。
下面提交事务,看一下有什么事发生,过滤掉先前的事务日志
1 --先执行下面这句,看一下最大的LSN的LSN号是多少
2 SELECT MAX ([Current LSN]) FROM fn_dblog (null, null);
3 GO
4 – 00000014:000000fc:020c
5 -----------------------------------------------------
6 --然后提交事务
7 COMMIT TRAN
8 GO
9 SELECT [Page ID], * FROM fn_dblog (null, null) WHERE [Current LSN] > '00000014:000000fc:020c'; --填入最大的LSN号
我们看到几乎是只要提交事务,鬼影记录清理任务就会进行清理工作。
PFS页也进行了位图中的位的相关改变,因为鬼影记录已经没有了,所以他也要改变位图中相应的位
现在检查一下页面dump信息确保记录已经删除掉了,还有页面的头部信息不再显示鬼影记录了
1 DBCC PAGE ('gposdb', 1, 324, 3);
2 GO
3
4 DBCC PAGE ('gposdb', 1, 324, 2);
5 GO
如果文中有不对的地方,欢迎大家拍砖o(∩_∩)o