1. 程式人生 > >四巨頭第十五周作業翻譯

四巨頭第十五周作業翻譯

number 有一個 客戶端 identity abort 數據庫檢查 files oss strings

SQL Server中事務日誌管理的階梯,第一級:事務日誌概述

系列

本文是階梯系列的一部分:SQL Server中的事務日誌管理的階梯。

當事情進展順利時,不需要特別註意事務日誌的作用或它是如何工作的。你只需要確信每個數據庫都有正確的備份機制。當事情出錯時,對事務日誌的理解對於采取糾正措施非常重要,特別是當需要一個時間點恢復數據庫時,這是非常緊急的!Tony Davis提供了每個DBA都應該知道的適當的細節級別。

第1級:事務日誌概述

事務日誌是一個文件,其中SQL Server存儲與日誌文件相關聯的數據庫上執行的所有事務和數據修改的記錄。如果發生導致SQL Server意外關閉的災難(例如實例或硬件故障),則使用事務日誌來恢復數據庫,並立即執行數據完整性。在重新啟動時,數據庫進入一個恢復過程,在該過程中讀取事務日誌,以確保將所有有效的已提交數據寫入數據文件(前滾),並撤消任何部分未提交的事務的影響(回滾)。簡而言之,事務日誌是SQL Server確保數據庫完整性和事務的ACID屬性(尤其是持久性)的基本手段。

DBA在管理事務日誌方面的一些最重要職責如下:

l 選擇正確的恢復模型- SQL Server提供三個數據庫恢復模型:FULL(默認),SIMPLE和BULK日誌。DBA必須根據數據庫的業務需求選擇適當的模型,然後建立適合該模式的維護過程。

l 執行事務日誌備份——除非以簡單模式工作,否則DBA執行事務日誌的常規備份是至關重要的。一旦在備份文件中捕獲,日誌記錄可以隨後應用到完整的數據庫備份,以便執行數據庫恢復,因此可以重新創建以前存在的數據庫,例如在發生故障之前。

l 監視和管理日誌增長—在繁忙的數據庫中,事務日誌的大小可以快速增長。如果沒有定期備份,或者大小不合適,或者分配了不正確的增長特征,事務日誌文件就會被填滿,導致臭名昭著的“9002”(事務日誌已滿)錯誤,這將使SQL Server進入“只讀”模式(如果在恢復期間發生,則進入“資源暫掛”模式)。

l 優化日誌吞吐量和可用性——除了進行備份等基本維護之外,DBA還必須采取步驟確保事務日誌的適當性能。這包括硬件方面的考慮,以及避免可能影響事務性能的日誌碎片等情況。

在這個樓梯系列中,我們將詳細地考慮這些核心維護任務。在這裏,首先,我們將概述SQL Server如何使用事務日誌,以及它影響DBA生命周期的兩種最重要的方式,即數據庫恢復和恢復,以及磁盤空間管理。

SQL Server如何使用事務日誌

在SQL Server中,事務日誌是一個物理文件,通過擴展LDF按常規標識(盡管不是強制標識)。它是在創建數據庫和主數據文件時自動創建的,主數據文件通常由MDF擴展標識,不過也可以使用任何擴展來存儲數據庫對象和數據本身。事務日誌雖然通常作為單個物理文件實現,但也可以作為一組文件實現。然而,即使在後一種情況下,它仍然是被SQL Server作為一個順序文件,因此,SQL Server不能並行,不寫多個日誌文件,所以沒有性能優勢實現事務日誌的多個文件。這將在第7級-調整大小和增加事務日誌中進行更詳細的討論。

每當T-SQL代碼對數據庫對象(DDL)或它包含的數據進行更改時,不僅數據文件中更新了數據或對象,而且更改的細節也被記錄為事務日誌中的日誌記錄。每個日誌記錄都包含關於執行更改的事務ID的詳細信息,當事務開始和結束時,更改了哪些頁面,更改了哪些數據,等等。

註意:事務日誌不是審計跟蹤。它不提供對數據庫所做更改的審計跟蹤;它不保存對數據庫執行的命令的記錄,只保存數據如何變化的結果。

當進行數據修改時,相關的數據頁有望從數據緩存中讀取,如果不在緩存中,則首先從磁盤中檢索。在數據緩存中修改數據,並在日誌緩存中創建描述事務影響的日誌記錄。當提交事務時,日誌記錄被寫到磁盤上的事務日誌中。但是,實際更改的數據可能直到稍後發生數據庫檢查點時才寫入磁盤。緩存中的任何頁面在從磁盤讀取之後被修改,因此緩存中的數據值與磁盤上的數據不同,稱為臟頁。這些臟頁可能包含這兩種內容:

l 已提交並“硬化”到事務日誌文件但尚未提交到數據文件的數據

l 由開放事務修改的數據,即尚未提交(或回滾)的數據

定期的數據庫檢查點進程掃描數據緩存,並將所有臟頁面刷新到磁盤,在此情況下,修改將反映在物理數據文件和日誌文件中。即使在事務仍然打開的情況下也會發生這種情況;在檢查點期間,與打開事務相關的臟頁被刷新到磁盤,SQL Server始終確保在臟頁刷新到數據文件之前,與這些打開事務相關的日誌記錄從日誌緩存刷新到事務日誌文件。

註意:另一個掃描數據緩存的進程LazyWriter,如果由於內存壓力而被迫這樣做,也可以將臟數據頁寫到檢查點之外的磁盤上。

這裏需要註意的重要一點是,日誌緩沖區管理器總是確保在將數據頁寫到物理數據文件之前,將更改描述(日誌記錄)寫到磁盤上的事務日誌。這種機制稱為預寫日誌記錄。它本質上是SQL Server確保事務持久性的機制(參見數據庫事務的ACID屬性)。

總是先寫更改日誌文件,SQL Server的基礎機制,可以保證所有已提交的事務的影響最終將反映在數據文件,並修改磁盤上的任何數據,來自不完整的交易,即那些提交和回滾的最終發行不反映在數據文件中。

例如,如果數據庫崩潰,在提交某個事務(T1)之後,但在將受影響的數據寫到數據文件之前,然後在重新啟動時,啟動數據庫恢復進程,該進程試圖協調事務日誌文件和數據文件的內容。它將讀取事務日誌文件,並確保在日誌文件中記錄的包含事務T1的所有操作都被“前滾”(重做),以便在數據文件中反映出來。

同樣,在數據庫崩潰之後,通過從日誌文件中讀取相關操作並對數據執行反向物理操作,恢復過程將“回滾”(撤消)與未提交事務關聯的數據庫中的任何數據更改。

以這種方式,在發生崩潰時,SQL Server可以將數據庫返回到一致的狀態。更一般地說,如果:

l 為顯式事務發出回滾命令

l 發生錯誤並打開XACT_ABORT

l 如果數據庫檢測到數據庫和觸發事務的客戶端之間的通信中斷。

在這種情況下,將讀取與中斷事務相關的日誌記錄(或顯式發出回滾命令的日誌記錄),並回滾更改。通過這些方式,SQL Server確保與事務相關的所有操作作為一個單元獲得成功,或者所有操作都失敗。因此,事務日誌是SQL Server在日常操作中確保數據一致性和完整性的基本方法之一。

然而,事務日誌扮演著另一個重要的角色,它提供了一種機制,在發生災難時,通過這種機制可以將數據庫恢復到以前的某個時間點。通過適當的計劃和管理,你可以使用這些日誌文件的備份來恢復所有數據,直到數據損壞或無法使用為止。

事務日誌和數據庫恢復

正如前面所討論的,事務日誌文件存儲一系列日誌記錄,按照事務開始時的順序排列,這提供了針對該數據庫的修改和事務的歷史記錄。每個日誌記錄都包含關於執行更改的事務ID的詳細信息,當事務開始和結束時,更改了哪些頁面,更改了哪些數據,等等。事務日誌文件中的日誌記錄被組織成多個部分,稱為虛擬日誌文件(VLFs)——這些在第2級事務日誌體系結構中有更詳細的介紹。

SQL Server的預寫日誌機制保證在將修改後的數據本身寫入數據文件之前,修改的描述(即日誌記錄)將被寫入VLF。因此,日誌記錄可能包含已關閉(提交)事務或打開(未提交)事務的詳細信息,在每種情況下,事務修改的數據可能已經寫入數據文件,也可能沒有寫入,這取決於是否發生了檢查點。

註意:通過定期將臟頁從緩存刷新到磁盤,數據庫檢查點過程控制數據庫恢復操作期間SQL Server需要完成的工作量。如果SQL Server必須為大量與臟頁相關的提交事務前滾更改,那麽恢復過程可能會非常漫長。

與開放事務相關的任何日誌記錄都可能需要在恢復期間進行回滾操作,並且始終是被稱為活動VLF的一部分,並且將始終保留在日誌文件中。與已關閉事務相關的日誌記錄也將是活動VLF的一部分,直到到達與開放事務關聯的整個VLF中沒有日誌記錄的點時,VLF將變得不活動。

這些非活動的VLFs中的日誌記錄實質上提供了以前完成的數據庫事務的“歷史”,而這些非活動的VLFs發生了什麽變化取決於數據庫的恢復模型。我們將詳細討論這些復蘇模型級別3 - 6的樓梯,但這裏的關鍵是,如果你使用的是完整的(或批量記錄)數據庫恢復模型,那麽事務日誌保留在不活躍的甚低頻日誌記錄,直到一個日誌備份(不久)。

通過備份事務日誌,我們可以將活動日誌中的所有日誌記錄(包括這些非活動的VLFs中的記錄)捕獲到一個備份文件中。然後可以使用這些日誌備份將數據庫恢復到以前的時間點;希望時間上的某個點非常接近發生“災難”的那個點。這樣的災難時,日誌備份文件可以應用於恢復完全數據庫備份文件的副本,和完整備份之後發生的任何交易將“向前滾”,在數據庫恢復,恢復數據庫和恢復數據到一個給定的時間點上,所以任何數據損失最小化。當然,這假定你不僅已經進行了這些日誌備份,而且還將它們轉移到一個安全的位置。如果你的日誌備份文件與活動日誌文件位於同一驅動器上,並且該驅動器崩潰,那麽您可能會丟失所有備份。

當一個數據庫處於簡單的恢復模型中(第3和第4級對此有更多了解)時,將保留活動VLFs中的日誌記錄,因為回滾操作可能需要這些記錄。但是,當發生檢查點時,非活動的VLFs將被截斷,這意味著可以立即用新的日誌記錄覆蓋這些VLFs中的日誌記錄。這就是為什麽在簡單恢復中操作的數據庫被稱為處於自動截斷模式。在這種模式下,日誌中不維護“歷史”,因此無法在日誌備份中捕獲歷史並作為恢復過程的一部分使用。

控制日誌文件的大小

希望前面的討論已經清楚地表明,對於運行在完全恢復模型中的大多數生產數據庫,有必要對事務日誌文件進行定期備份,以便使數據庫恢復到特定的時間點。

但是,在以FULL(或bulk_log)模式操作時進行這些日誌備份還有第二個重要原因,即控制日誌的大小。請記住,對於修改SQL Server數據庫中的數據或對象的每個事務,日誌記錄都被寫入到日誌文件中。在一個繁忙的系統中,有許多並發事務,或者有許多數據編寫,事務日誌的大小可以快速增長。

在使用FULL(或bulk_log)模式時,在備份文件中捕獲非活動VLFs中的日誌記錄副本是使這些VLFs符合截斷條件的惟一操作,這意味著日誌記錄所占用的空間可以被重用。

關於截斷和事務日誌大小的簡要說明:有一個常見的誤解,即截斷日誌文件意味著刪除日誌記錄,文件的大小減少。並不是這樣;日誌文件的截斷僅僅是標記空間以便重用的行為。在每個不同恢復模型的上下文中,將在後續的級別中更詳細地討論截斷。

因此,當在FULL(或bulk_log)模式下工作時,執行常規事務日誌備份至關重要,其中一個原因是控制日誌的大小。

備份事務日誌的簡單示例

為了簡要說明我們在第一個級別中討論過的一些概念,我們將介紹一個非常簡單的示例,該示例支持在完全恢復模式下操作的數據庫的事務日誌。每個進程和命令的詳細信息將在後續的級別中詳細介紹。

在清單1.1中,我們在SQL Server 2008實例上創建了一個新的TestDB數據庫,然後使用DBCC SQLPERF (LOGSPACE)命令立即獲得日誌文件的大小。

USE master ;

IF EXISTS ( SELECT name

FROM sys.databases

WHERE name = ‘TestDB‘ )

DROP DATABASE TestDB ;

CREATE DATABASE TestDB ON

(

NAME = TestDB_dat,

FILENAME = ‘C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Data\TestDB.mdf‘

) LOG ON

(

NAME = TestDB_log,

FILENAME = ‘C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Data\TestDB.ldf‘

) ;

DBCC SQLPERF(LOGSPACE) ;

Database Name Log Size (MB) Log Space Used (%) Status

---------------------------------------------------------

master 1.242188 34.27673 0

...<snip>...

TestDB 0.9921875 31.74213 0

清單1.1:新TestDB數據庫的初始日誌文件大小

如您所見,日誌文件的大小目前大約為1 MB,滿了大約30%。

註意:在實例上創建的用戶數據庫的初始大小和增長特征由模型數據庫的屬性決定,每個數據庫將使用的默認恢復模型(在本例中為FULL)也是如此。我們將在第7級中詳細討論這些屬性的影響,並增加事務日誌。

只需在磁盤上定位物理文件,就可以確定文件的大小,如圖1.1所示。

技術分享圖片

圖1.1:TestDB的數據和日誌文件

現在讓我們為TestDB執行數據文件的備份,如清單1.2所示(您首先需要創建“備份”目錄)。註意,此備份操作確保數據庫在完全恢復模式下運行;更多信息請參見第3級——事務日誌、備份和恢復。

-- full backup of the database
BACKUP DATABASE TestDB
TO DISK =‘C:\Backups\TestDB.bak‘
WITH INIT;
GO

清單1.2:TestDB的初始完全備份

由於這個備份操作,數據或日誌文件的大小沒有變化,日誌空間的百分比也沒有變化,這也許並不奇怪,因為數據庫中還沒有用戶表或數據。讓我們將其放到正確的位置,並在這個數據庫上創建一個名為LogTest的表,填充100萬行數據,並重新檢查日誌文件大小,如清單1.3所示。這個腳本的作者是Jeff Moden,他經常出現在SQLServerCentral.com論壇上。不要擔心代碼的細節;這裏唯一重要的是我們插入了很多行。這段代碼可能需要幾秒鐘在您的機器上執行,這並不是因為代碼效率低下;所有的工作都在幕後進行,寫數據和日誌文件。

USE TestDB ;
GO
IF OBJECT_ID(‘dbo.LogTest‘, ‘U‘) IS NOT NULL 
    DROP TABLE dbo.LogTest ;
--===== AUTHOR: Jeff Moden
--===== Create and populate 1,000,000 row test table.
-- "SomeID" has range of 1 to 1000000 unique numbers
-- "SomeInt" has range of 1 to 50000 non-unique numbers
-- "SomeLetters2";"AA"-"ZZ" non-unique 2-char strings
-- "SomeMoney"; 0.0000 to 99.9999 non-unique numbers
-- "SomeDate" ; >=01/01/2000 and <01/01/2010 non-unique
-- "SomeHex12"; 12 random hex characters (ie, 0-9,A-F) 
SELECT TOP 1000000
        SomeID = IDENTITY( INT,1,1 ),
        SomeInt = ABS(CHECKSUM(NEWID())) % 50000 + 1 ,
        SomeLetters2 = CHAR(ABS(CHECKSUM(NEWID())) % 26 + 65)
        + CHAR(ABS(CHECKSUM(NEWID())) % 26 + 65) ,
        SomeMoney = CAST(ABS(CHECKSUM(NEWID())) % 10000 / 100.0 AS MONEY) ,
        SomeDate = CAST(RAND(CHECKSUM(NEWID())) * 3653.0 + 36524.0 AS DATETIME) ,
        SomeHex12 = RIGHT(NEWID(), 12)
INTO    dbo.LogTest
FROM    sys.all_columns ac1
        CROSS JOIN sys.all_columns ac2 ;
DBCC SQLPERF(LOGSPACE) ;

清單1.3:在TestDB中向LogTest表插入100萬行

請註意,日誌文件的大小已經膨脹到大約110 MB,日誌已滿91%(您的系統上的數據可能略有不同)。如果要插入更多的數據,就必須再次增大數據大小,以容納更多的日誌記錄。同樣,可以從物理文件(數據文件已經增長到64 MB)確定大小的增加。

現在,我們可以通過重新運行清單1.2再次備份數據文件,它對日誌文件的大小或文件中使用的空間百分比沒有影響。但是,現在讓我們備份事務日誌文件並重新檢查值,如清單1.4所示。

-- now backup the transaction log
BACKUP Log TestDB
TO DISK =‘C:\Backups\TestDB_log.bak‘
WITH INIT;
GO
DBCC SQLPERF(LOGSPACE) ;
Database Name   Log Size (MB) Log Space Used (%) Status
-------------------------------------------------------
master          1.242188      63.52201           0
...<snip>…
TestDB          99.74219      6.295527           0

清單1.4:為TestDB備份事務日誌

日誌文件仍然是相同的物理大小,但是通過備份文件,SQL Server能夠截斷日誌,使日誌文件中的“非活動”VLFs中的空間可以重用;可以添加更多的日誌記錄,而不需要物理地擴展文件。當然,我們已經將日誌記錄捕獲到一個備份文件中,因此,如果需要將TestDB數據庫恢復到以前的狀態,則可以將該文件用作數據庫恢復過程的一部分。

總結

在第一個級別中,我們介紹了事務日誌,並通過寫前日誌機制解釋了SQL Server如何使用它來保持數據一致性和完整性。我們還描述並簡要演示了DBA如何將事務日誌文件的內容捕獲到一個備份文件中,然後可以重用該文件以作為恢復過程的一部分來恢復數據庫。最後,我們強調了備份在控制事務日誌大小方面的重要性。

在下一個級別中,我們將更深入地研究事務日誌的體系結構。

四巨頭第十五周作業翻譯