你們知道在完整恢復模式下,SQLSERVER會記錄每一個事務所作的操做,這些記錄會存儲在事務日誌裏,有些軟件會利用事務日誌來讀取html
操做記錄恢復數據,例如:log explorerweb
那麼事務日誌記錄怎麼查看,裏面都記錄了些什麼?數據庫
打開能夠利用下面SQL語句來查看所在數據庫的事務日誌記錄ide
1 USE [GPOSDB] --要查看事務日誌記錄的數據庫 2 GO 3 SELECT * FROM [sys].[fn_dblog](NULL,NULL)
事務日誌記錄裏不少東西能夠看的,裏面記錄了很是詳細的數據庫活動信息測試
我這裏只介紹一些重要的須要知道的字段,其餘字段因爲本人能力有限並且以爲其餘字段不是很重要就不介紹了spa
CurrentLSN:當前LSN號,事務日誌中的每一個記錄都由一個惟一的日誌序列號 (LSN) 標識。LSN 是這樣排序的:若是 LSN2 大於 LSN1,3d
則 LSN2 所標識的日誌記錄描述的更改發生在日誌記錄 LSN1 描述的更改以後日誌
MSDN解釋:http://msdn.microsoft.com/zh-cn/library/ms190411(v=SQL.90).aspxcode
Operation:當前LSN所作的操做orm
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數據庫事務日誌的疑問
------------------------------------------------------------------------------------------------------
文章有什麼不對的地方,你們必定要拍磚哦o(∩_∩)o