12-09
12-09
12-09
12-09
12-09
12-09
12-09
12-09
12-09
12-09
12-09
12-09
ADADADADAD
mysql数据库 时间:2024-12-25 09:56:20
作者:文/会员上传
12-09
12-09
12-09
12-09
12-09
12-09
12-09
12-09
12-09
12-09
12-09
12-09
当truncate table发生时,如何进行恢复,相信大部分人都会选择通过还原备份到truncate table前,然后将数据重新导入正式表中。那么在SQL Server中是不是真的只有这种方法呢,当然不
以下为本文的正文内容,内容仅供参考!本站为公益性网站,复制本文以及下载DOC文档全部免费。
当truncate table发生时,如何进行恢复,相信大部分人都会选择通过还原备份到truncate table前,然后将数据重新导入正式表中。
那么在SQL Server中是不是真的只有这种方法呢,当然不是,这也是本文即将介绍的内容,前提条件是SQL Server完整恢复模式(大容量日志模式未做测试,暂不介绍)。
首先,了解一下truncate table的一些相关知识
官档:
TRUNCATE TABLE 通过释放用于存储表数据的数据页删除数据,且仅在事务日志中记录页释放。
这句话包含的信息量是很大的,通过实验进行验证,解释如下:
truncate table时,数据库日志中不会记录确切的已删除值,只记录截断记录的页的ID,并且这些记录所占用的空间会被标识为可重写,
mdf中会暂时保留这些页内的数据,当有新事务写入这些页时,truncate table的数据将会被覆盖(数据页被format,然后重新使用)。
测试:
创建一张表,并插入数据
createtabletest_truncate(idint,namevarchar(20),addressvarchar(20))goinsertintotest_truncateselect1,'zhangsan','firstroad'goinsertintotest_truncateselect2,'wangxiao','secondroad'go
利用dbcc ind找到该表的数据页,如下PageType=1为数据页,即为:288
使用dbcc page查看数据页内容
PAGE:(1:288)BUFFER:BUF@0x000000000563C600bpage=0x0000000150020000bhash=0x0000000000000000bpageno=(1:288)bdbid=9breferences=0bcputicks=0bsampleCount=0bUse1=56673bstat=0x10bblog=0x7adb21ccbnext=0x0000000000000000PAGEHEADER:Page@0x0000000150020000m_pageId=(1:288)m_headerVersion=1m_type=1m_typeFlagBits=0x0m_level=0m_flagBits=0x8000m_objId(AllocUnitId.idObj)=489m_indexId(AllocUnitId.idInd)=256Metadata:AllocUnitId=72057594069975040Metadata:PartitionId=72057594062241792Metadata:IndexId=0Metadata:ObjectId=935674381m_prevPage=(0:0)m_nextPage=(0:0)pminlen=8m_slotCnt=2m_freeCnt=8021m_freeData=167m_reservedCnt=0m_lsn=(49:7380:2)m_xactReserved=0m_xdesId=(0:0)m_ghostRecCnt=0m_tornBits=0DBFragID=1AllocationStatusGAM(1:2)=ALLOCATEDSGAM(1:3)=ALLOCATEDPFS(1:1)=0x61MIXED_EXTALLOCATED50_PCT_FULLDIFF(1:6)=CHANGEDML(1:7)=NOTMIN_LOGGEDSlot0Offset0x60Length35RecordType=PRIMARY_RECORDRecordAttributes=NULL_BITMAPVARIABLE_COLUMNSRecordSize=35MemoryDump@0x000000006DDF80600000000000000000:30000800010000000300000200190023007a68610..............#.zha0000000000000014:6e6773616e666972737420726f6164ngsanfirstroadSlot0Column1Offset0x4Length4Length(physical)4id=1Slot0Column2Offset0x11Length8Length(physical)8name=zhangsanSlot0Column3Offset0x19Length10Length(physical)10address=firstroadSlot1Offset0x83Length36RecordType=PRIMARY_RECORDRecordAttributes=NULL_BITMAPVARIABLE_COLUMNSRecordSize=36MemoryDump@0x000000006DDF80830000000000000000:300008000200000003000002001900240077616e0..............$.wan0000000000000014:677869616f7365636f6e6420726f6164gxiaosecondroadSlot1Column1Offset0x4Length4Length(physical)4id=2Slot1Column2Offset0x11Length8Length(physical)8name=wangxiaoSlot1Column3Offset0x19Length11Length(physical)11address=secondroadDBCCexecutioncompleted.IfDBCCprintederrormessages,contactyoursystemadministrator.
可以看到数据页中存在的记录
Slot0Column1Offset0x4Length4Length(physical)4id=1Slot0Column2Offset0x11Length8Length(physical)8name=zhangsanSlot0Column3Offset0x19Length10Length(physical)10address=firstroadSlot1Column1Offset0x4Length4Length(physical)4id=2Slot1Column2Offset0x11Length8Length(physical)8name=wangxiaoSlot1Column3Offset0x19Length11Length(physical)11address=secondroad
执行truncate table后
可以看到数据页中仍保留着truncate table的相关记录。
那么,truncate table的第二种恢复方法就显而易见了,在这些数据被覆盖之前,从页面中将数据提取出来,并恢复到表中。
11-20
11-19
11-20
11-20
11-20
11-19
11-20
11-20
11-19
11-20
11-19
11-19
11-19
11-19
11-19
11-19