SQL Server事務(wù)日志及其組織

事務(wù)日志又稱為重做日志,Oracle與SQL Server中的事務(wù)日志功能是類似的。與Oracle不同的是,對(duì)數(shù)據(jù)庫(kù)添加重做日志文件時(shí),可以如同SQL Server數(shù)據(jù)庫(kù)的數(shù)據(jù)文件一樣指定初始化大小及增長(zhǎng)率、最大大小屬性等屬性。Oracle數(shù)據(jù)庫(kù)添加事務(wù)日志文件時(shí),只能指定初始大小,不能指定增長(zhǎng)率、最大大小屬性等屬性

事務(wù)日志支持的操作

SQL Server中靠日志來(lái)維護(hù)一致性(當(dāng)然,日志的作用非常多,但一致性是日志的基本功能,其他功能可以看作是額外的功能)。
??事務(wù)日志支持以下操作:

  • 恢復(fù)個(gè)別的事務(wù)
    如果應(yīng)用程序發(fā)出 ROLLBACK 語(yǔ)句,或者數(shù)據(jù)庫(kù)引擎檢測(cè)到錯(cuò)誤(例如失去與客戶端的通信),使用日志記錄回退未完成的事務(wù)所做的修改。
  • 在 SQL Server 啟動(dòng)時(shí)恢復(fù)所有未完成的事務(wù)
    運(yùn)行 SQL Server 的服務(wù)器發(fā)生故障時(shí),數(shù)據(jù)庫(kù)可能處于這樣的狀態(tài):還沒(méi)有將某些修改從緩存寫(xiě)入數(shù)據(jù)文件,在數(shù)據(jù)文件內(nèi)有未完成的事務(wù)所做的修改。 啟動(dòng) SQL Server 實(shí)例時(shí),它將對(duì)每個(gè)數(shù)據(jù)庫(kù)執(zhí)行恢復(fù)操作,在事務(wù)日志中找到的每個(gè)未完成的事務(wù)并進(jìn)行回滾,以確保數(shù)據(jù)庫(kù)的完整性。這種恢復(fù)稱為實(shí)例恢復(fù)。
  • 將還原的數(shù)據(jù)庫(kù)、文件、文件組或頁(yè)前滾至故障點(diǎn)
    在硬件丟失或磁盤(pán)故障影響到數(shù)據(jù)庫(kù)文件后,用戶用過(guò)去的數(shù)據(jù)庫(kù)備份來(lái)恢復(fù)數(shù)據(jù)庫(kù)。而過(guò)去的數(shù)據(jù)庫(kù)備份數(shù)據(jù)顯然是當(dāng)初備份時(shí)的狀態(tài),不會(huì)包含從備份完成到數(shù)據(jù)庫(kù)崩潰時(shí)刻這段時(shí)間內(nèi)產(chǎn)生的數(shù)據(jù),因?yàn)橹刈鋈罩疚募杏涗浟怂袛?shù)據(jù)的修改,SQL Server會(huì)把事務(wù)日志中的操作記錄應(yīng)用到恢復(fù)的數(shù)據(jù)文件,從而可以使數(shù)據(jù)庫(kù)恢復(fù)到數(shù)據(jù)庫(kù)存儲(chǔ)介質(zhì)發(fā)生故障的時(shí)刻,這種恢復(fù)稱為介質(zhì)恢復(fù)。
  • 支持事務(wù)復(fù)制
    事務(wù)復(fù)制的原理是先將發(fā)布服務(wù)器數(shù)據(jù)庫(kù)中的初始快照發(fā)送到各訂閱服務(wù)器,然后監(jiān)控發(fā)布服務(wù)器數(shù)據(jù)庫(kù)中數(shù)據(jù)發(fā)生的變化,捕獲個(gè)別數(shù)據(jù)變化的事務(wù)并將變化的數(shù)據(jù)發(fā)送到訂閱服務(wù)器。日志讀取器代理程序監(jiān)視已為事務(wù)復(fù)制配置的每個(gè)數(shù)據(jù)庫(kù)的事務(wù)日志,并將已設(shè)復(fù)制標(biāo)記的事務(wù)從事務(wù)日志復(fù)制到分發(fā)數(shù)據(jù)庫(kù)中。只有已提交的事務(wù)才能發(fā)送到分發(fā)數(shù)據(jù)庫(kù)中。
  • 支持高可用性和災(zāi)難恢復(fù)解決方案
    備用服務(wù)器解決方案、AlwaysOn 可用性組、數(shù)據(jù)庫(kù)鏡像和日志傳送極大程度上依賴于事務(wù)日志。

事務(wù)日志文件的組織

1. 事務(wù)日志物理體系結(jié)構(gòu)

事務(wù)日志僅僅是記錄與其對(duì)應(yīng)數(shù)據(jù)庫(kù)上的事務(wù)行為和對(duì)數(shù)據(jù)庫(kù)修改的日志文件。在你新建數(shù)據(jù)庫(kù)時(shí),伴隨著數(shù)據(jù)庫(kù)文件,會(huì)有一個(gè)默認(rèn)以ldf為擴(kuò)展名的事務(wù)日志文件。當(dāng)然,一個(gè)數(shù)據(jù)庫(kù)也可以配有多個(gè)日志文件。
??SQL Server把一個(gè)物理日志文件從邏輯上劃分為多個(gè)虛擬日志文件(Virtual Log File,VLF)。用個(gè)類比方法來(lái)看,日志文件(ldf)好比一趟火車,每一節(jié)車廂都是一個(gè)虛擬日志文件(VLF)。


??那為什么SQL Server要把日志文件劃分出多個(gè)VLF呢?因?yàn)镾QL Server通過(guò)這種方式使得存儲(chǔ)引擎管理事務(wù)日志更加有效。物理日志以虛擬日志(VLF)為最小單位進(jìn)行增長(zhǎng)、收縮和使用,維護(hù)日志的時(shí)候也只需維護(hù)少量的VLF,這樣對(duì)于日志空間的重復(fù)利用也會(huì)更加高效。
??SQL Server把所有物理日志文件當(dāng)成一個(gè)連續(xù)的文件看待,順序?qū)懭肴罩居涗?,用完第一個(gè),再用下一個(gè)。即第一個(gè)日志文件的當(dāng)前空間,如果沒(méi)有可分配的VLF時(shí),就會(huì)使用下一個(gè)日志文件的VLF,直到最后一個(gè)日志文件也沒(méi)有可分配的VLF時(shí),會(huì)重新回到第一個(gè)日志開(kāi)始增長(zhǎng)。多個(gè)日志文件之間并不存在鏡像關(guān)系,也沒(méi)有重做日志組的概念。VLF的使用如下圖:

??VLF的數(shù)量以及每個(gè)VLF的大小由SQL Server根據(jù)日志文件的大小及增長(zhǎng)率自動(dòng)確定,即VLF沒(méi)有固定大小,且日志文件所包含的VLF數(shù)不固定。在日志文件增長(zhǎng)時(shí),SQL Server也會(huì)重新規(guī)劃VLFS的數(shù)量。
??SQL Server創(chuàng)建數(shù)據(jù)庫(kù)時(shí),根據(jù)日志文件(ldf)的大小,生成VLF的數(shù)量公式如下:

??從上面的公式圖看到如果每次日志文件一點(diǎn)一點(diǎn)增長(zhǎng),比如1M1M地增長(zhǎng),那么到64M的時(shí)候,就會(huì)生成64x4個(gè)VLF;但是如果日志文件直接增長(zhǎng)64M,最終生成的VLF數(shù)量只有8個(gè)。如果這些日志文件由于許多微小增量而增長(zhǎng)到很大,則它們將具有很多VLF,也就是日志文件碎片, 這會(huì)降低數(shù)據(jù)庫(kù)啟動(dòng)以及日志備份和還原操作的速度。
??所以,當(dāng)我們?cè)趧?chuàng)建數(shù)據(jù)庫(kù)的時(shí)候需要設(shè)置合適的文件的大小,使得文件的大小起碼可以應(yīng)付一段時(shí)間的增長(zhǎng)。同時(shí),也不要一下子就去創(chuàng)建一個(gè)很大的日志文件,因?yàn)槔锩婵赡苤话苌俚腣LF,最后卻發(fā)揮不了太大作用,反而導(dǎo)致磁盤(pán)空間不足的錯(cuò)誤發(fā)生。
??一個(gè)VLF可以以下面4種狀態(tài)之一存在:

  • active:包含活動(dòng)的事務(wù),活動(dòng)的事務(wù)指未結(jié)束的事務(wù)。
  • recoverable:不包含活動(dòng)事務(wù),但數(shù)據(jù)庫(kù)此時(shí)處于維護(hù)一個(gè)完整日志序列的狀態(tài),而這些VLF還未進(jìn)行備份,所以這時(shí)不能轉(zhuǎn)變?yōu)?reusable狀態(tài)使得其被重用,如果被重用覆蓋,一個(gè)完整的日志序列就不連續(xù)了。
  • reusable:完全恢復(fù)模式下已經(jīng)備份,或者簡(jiǎn)單恢復(fù)模式下,未包含活動(dòng)事務(wù)。
  • unused:這個(gè)VLF從未被用到。
2. 事務(wù)日志邏輯體系結(jié)構(gòu)

當(dāng)針對(duì)數(shù)據(jù)庫(kù)對(duì)象所做的任何修改保存到數(shù)據(jù)庫(kù)之前,相應(yīng)的數(shù)據(jù)庫(kù)邏輯操作的記錄首先會(huì)被記錄到日志文件。這個(gè)記錄會(huì)被按照先后順序記錄到日志文件的邏輯末尾,并分配一個(gè)全局唯一的日志序列號(hào)(log sequence number,簡(jiǎn)稱LSN),這個(gè)序列號(hào)完全是按照順序來(lái)的,如果日志中兩個(gè)序列號(hào)LSN2>LSN1,則說(shuō)明LSN2所在LSN1之后發(fā)生的。


??數(shù)據(jù)庫(kù)中的事務(wù)日志映射在一個(gè)或多個(gè)物理文件上。 從概念上講,SQL Server 事務(wù)日志按邏輯運(yùn)行,就好像事務(wù)日志是一串日志記錄一樣。 從物理上講,日志記錄序列被有效地存儲(chǔ)在實(shí)現(xiàn)事務(wù)日志的物理文件集中。
?? 日志記錄按創(chuàng)建時(shí)的串行序列存儲(chǔ)。** 每條日志記錄都包含其所屬事務(wù)的 ID。** 對(duì)于每個(gè)事務(wù),與事務(wù)相關(guān)聯(lián)的所有日志記錄通過(guò)使用可提高事務(wù)回滾速度的向后指針挨個(gè)鏈接在一個(gè)鏈中。

SQL Server用日志記錄來(lái)保證事務(wù)的基本屬性,及數(shù)據(jù)庫(kù)恢復(fù)。

活動(dòng)日志
??MinLSN 是成功進(jìn)行數(shù)據(jù)庫(kù)范圍內(nèi)回滾所需的最早日志記錄的日志序列號(hào)。 日志文件中從 MinLSN 到最后寫(xiě)入的日志記錄這一部分稱為日志的活動(dòng)部分,或者稱為活動(dòng)日志。 這是進(jìn)行數(shù)據(jù)庫(kù)完整恢復(fù)所需的日志部分。 永遠(yuǎn)不能截?cái)嗷顒?dòng)日志的任何部分。 所有的日志記錄都必須從 MinLSN 之前的日志部分截?cái)唷?br>


??下圖顯示了具有兩個(gè)活動(dòng)事務(wù)的結(jié)束事務(wù)日志的簡(jiǎn)化版本。 檢查點(diǎn)記錄已壓縮成單個(gè)記錄。

LSN 148 是事務(wù)日志中的最后一條記錄。 在處理 LSN 147 處記錄的檢查點(diǎn)時(shí),Tran 1 已經(jīng)提交,而 Tran 2 是唯一的活動(dòng)事務(wù)。 這就使 Tran 2 的第一條日志記錄成為執(zhí)行最后一個(gè)檢查點(diǎn)時(shí)處于活動(dòng)狀態(tài)的事務(wù)(處于活動(dòng)狀態(tài)即還未commit,只有未commit的事務(wù)才能rollback)的最舊日志記錄。 這使 LSN 142(Tran 2 的開(kāi)始事務(wù)記錄)成為 MinLSN。
??活動(dòng)日志必須包括所有未提交事務(wù)的每一部分。 如果應(yīng)用程序開(kāi)始執(zhí)行一個(gè)事務(wù)但未提交或回滾,將會(huì)阻止數(shù)據(jù)庫(kù)引擎推進(jìn) MinLSN。

日志截?cái)?/h3>

物理日志的回繞
??事務(wù)日志是一種回繞的文件。 例如,假設(shè)有一個(gè)數(shù)據(jù)庫(kù),它包含一個(gè)分成四個(gè)虛擬日志文件的物理日志文件。 當(dāng)創(chuàng)建數(shù)據(jù)庫(kù)時(shí),邏輯日志文件(具有日志記錄的部分的VLF)物理日志文件(包含所有的VLF)的始端開(kāi)始。 新日志記錄被添加到邏輯日志的末端,然后向物理日志的末端擴(kuò)張。日志截?cái)鄬⑨尫庞涗浫吭谧钚』謴?fù)日志序列號(hào) (MinLSN) 之前出現(xiàn)的所有虛擬日志,被截?cái)嗟娜罩静糠謽?biāo)記為可重用。


當(dāng)邏輯日志的末端到達(dá)物理日志文件的末端時(shí),新的日志記錄將回繞到物理日志文件的始端。

這個(gè)循環(huán)不斷重復(fù),只要邏輯日志的末端不到達(dá)邏輯日志的始端。
??如果經(jīng)常截?cái)嗯f的日志記錄,始終為到下一個(gè)檢查點(diǎn)前創(chuàng)建的所有新日志記錄保留足夠的空間,則日志永遠(yuǎn)不會(huì)填滿。

日志截?cái)?/strong>
??日志截?cái)嘀饕糜谧柚谷罩咎畛洹?strong>日志截?cái)喟褦?shù)據(jù)庫(kù)日志文件中不包含活動(dòng)事務(wù)(未結(jié)束的事務(wù))的VLF狀態(tài)修改為reusable,釋放邏輯日志中的空間以便物理事務(wù)日志重用這些空間。 如果事務(wù)日志從不截?cái)?,它最終將填滿分配給物理日志文件的所有磁盤(pán)空間。 但是,在截?cái)嗳罩厩埃仨殘?zhí)行檢查點(diǎn)操作,將當(dāng)前內(nèi)存中的臟頁(yè)和事務(wù)日志信息從內(nèi)存寫(xiě)入磁盤(pán)。

??下列各圖顯示了截?cái)嗲昂蟮氖聞?wù)日志。 第一個(gè)圖顯示了從未截?cái)嗟氖聞?wù)日志。 當(dāng)前,邏輯日志使用四個(gè)虛擬日志文件。 邏輯日志開(kāi)始于第一個(gè)邏輯日志文件的前面,并結(jié)束于虛擬日志 4。 MinLSN 記錄位于虛擬日志 3 中。 虛擬日志 1 和虛擬日志 2 僅包含不活動(dòng)的日志記錄。 這些記錄可以截?cái)唷?虛擬日志 5 仍未使用,不屬于當(dāng)前邏輯日志。


第二個(gè)圖顯示了日志截?cái)嗪蟮那樾巍?已釋放虛擬日志 1 和虛擬日志 2 以供重新使用。 現(xiàn)在,邏輯日志開(kāi)始于虛擬日志 3 的開(kāi)頭。 虛擬日志 5 仍未使用,它不屬于當(dāng)前邏輯日志。

??除非由于某些原因?qū)е卵舆t,否則將在以下事件后自動(dòng)發(fā)生日志截?cái)啵?p>

  • 簡(jiǎn)單恢復(fù)模式下,在檢查點(diǎn)之后發(fā)生。
  • 完整恢復(fù)模式或大容量日志恢復(fù)模式下,在日志備份之后發(fā)生(如果自上次備份后出現(xiàn)檢查點(diǎn))。

如何查看事務(wù)日志記錄

大家知道在完整恢復(fù)模式下,SQLSERVER會(huì)記錄每個(gè)事務(wù)所做的操作,這些記錄會(huì)存儲(chǔ)在事務(wù)日志里,那么事務(wù)日志記錄怎么查看,里面都記錄了些什么?
??事務(wù)日志記錄里很多東西可以看的,里面記錄了非常詳細(xì)的數(shù)據(jù)庫(kù)活動(dòng)信息。打開(kāi)可以利用下面SQL語(yǔ)句來(lái)查看所在數(shù)據(jù)庫(kù)的事務(wù)日志記錄:

USE [GPOSDB] --要查看事務(wù)日志記錄的數(shù)據(jù)庫(kù)
GO
SELECT * FROM [sys].[fn_dblog](NULL,NULL)

在SSMS中執(zhí)行查詢?nèi)罩静僮髦罂梢钥吹剿械娜罩居涗?,我截取了部分的結(jié)果,圖中有幾列,下面說(shuō)明一下其中幾列的意思:

  • CurrentLSN:當(dāng)前LSN號(hào),事務(wù)日志中的每個(gè)記錄都由一個(gè)唯一的日志序列號(hào) (LSN) 標(biāo)識(shí)。LSN 是這樣排序的:如果 LSN2 大于 LSN1,則 LSN2 所標(biāo)識(shí)的日志記錄描述的更改發(fā)生在日志記錄 LSN1 描述的更改之后。
  • Operation列中記錄了對(duì)應(yīng)的LSN所做的操作。下面列出Operation幾種比較常見(jiàn)而重要的值:
  • LOP_BEGIN_XACT 事務(wù)的開(kāi)始
  • LOP_LOCK_XACT 獲取鎖
  • LOP_MODIFY_ROW 修改行(具體修改的對(duì)象可以查看AllocUnitName)
  • LOP_COMMIT_XACT 提交事務(wù)
  • LOP_DELETE_ROWS 刪除數(shù)據(jù)
  • LOP_INSERT_ROWS 插入數(shù)據(jù)
  • Context:操作的上下文。
  • Transaction Name顯示了創(chuàng)建的數(shù)據(jù)庫(kù)的名稱。
  • TransactoinID:事務(wù)ID號(hào)。
  • Log Record Fixed Length:LSN記錄的所占虛擬日志文件的固定長(zhǎng)度。
  • Previous LSN:前一個(gè)LSN號(hào)。
  • AllocUnitID:修改的那條數(shù)據(jù)所屬分配單元ID
  • AllocUnitName:修改了數(shù)據(jù)的表名。
  • Slot ID:數(shù)據(jù)所在數(shù)據(jù)頁(yè)面的第幾條記錄
  • PartitionID:數(shù)據(jù)所在數(shù)據(jù)頁(yè)面的所在分區(qū)ID
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容