完整恢復模式下使用標記的事務

iSQlServer發表於2009-01-19

在對兩個或更多資料庫(“相關資料庫”)進行相關更新時,可以使用事務標記將它們恢復到邏輯上一致的點。但是,此恢復將丟失在作為恢復點的標記之後提交的所有事務。只有您在測試相關資料庫或不介意丟失近期提交的事務時,標記事務才適用。

在每個相關資料庫中定期標記相關事務將在資料庫中建立一系列公用恢復點。事務標記將記錄在事務日誌中幷包括在日誌備份中。發生災難時,可以將各資料庫還原到相同的事務標記,從而將它們恢復到一致的點。

注意:
可以對不同的資料庫獨立建立各日誌備份,而無需同時建立。
 


對於以下情況,若要恢復相關資料庫,則必須先對各相關資料庫中的事務進行標記:

一個或多個事務日誌已破壞。需要將資料庫集還原到上次進行日誌備份時的一致狀態。

需要將整個資料庫集還原到某個更早時間點的相互一致狀態。

重要提示:
您僅可以將相關資料庫恢復為標記事務,而不是特定時間點。
 


有關如何建立標記事務的資訊,請參閱本主題後面的“建立標記事務”。

 使用標記事務的典型方案
使用標記事務的典型方案包括以下步驟:

建立每個相關資料庫的完整資料庫備份或差異資料庫備份。

在所有資料庫中標記事務塊。

備份所有資料庫的事務日誌。

用 WITH NORECOVERY 還原資料庫備份。

用 WITH STOPATMARK 還原日誌。

 使用標記事務的注意事項
在將已命名的標記插入事務日誌之前,請注意以下事項:

事務標記佔用日誌空間,所以應當僅將它們用於在資料庫恢復策略中佔重要地位的事務。

提交標記事務之後,將在 msdb 的 logmarkhistory 表中插入一行。

如果標記事務跨同一資料庫伺服器或不同伺服器上的多個資料庫,則必須在所有受影響資料庫的日誌中記錄標記。

 建立標記事務
若要建立標記事務,請使用 BEGIN TRANSACTION 語句和 WITH MARK [description] 子句。可選內容 description 是關於標記的文字說明。必須為事務指定標記名稱。標記名稱可以重複使用。事務日誌記錄標記名稱、描述、資料庫、使用者、日期時間資訊以及日誌序列號 (LSN)。日期時間資訊與標記名稱一起使用,以便對標記進行唯一標識。

在資料庫集中建立標記事務:

用 BEGIN TRAN 語句命名事務,並使用 WITH MARK 子句。
您可以在現有事務中巢狀 BEGIN TRAN new_mark_name WITH MARK 語句。即使事務擁有事務名稱,new_mark_name 的值也是事務的標記名稱。
注意:
如果執行第二個巢狀 BEGIN TRAN...WITH MARK,那麼將跳過該語句,但會導致出現警告訊息。
 


對資料庫集中的所有資料庫進行更新。
將僅在執行 BEGIN TRAN...WITH MARK 語句的伺服器例項上的事務日誌中插入特定事務的標記。事務標記放置在由該伺服器例項上的標記事務更新過的各資料庫的事務日誌中。如果資料庫位於不同的伺服器例項上,則必須在各伺服器例項上建立相同的標記。

示例
以下示例將事務日誌還原到名為 ListPriceUpdate 的標記事務中的標記處。

  
USE AdventureWorks
GO
BEGIN TRANSACTION ListPriceUpdate
   WITH MARK 'UPDATE Product list prices';
GO

UPDATE Production.Product
   SET ListPrice = ListPrice * 1.10
   WHERE ProductNumber LIKE 'BK-%';
GO

COMMIT TRANSACTION ListPriceUpdate;
GO

-- Time passes. Regular database
-- and log backups are taken.
-- An error occurs in the database.
USE master
GO

RESTORE DATABASE AdventureWorks
FROM AdventureWorksBackups
WITH FILE = 3, NORECOVERY;
GO

RESTORE LOG AdventureWorks
   FROM AdventureWorksBackups
   WITH FILE = 4,
   RECOVERY,
   STOPATMARK = 'ListPriceUpdate'; 強制將標記分佈到其他伺服器
事務分散到其他伺服器時,事務標記名稱不會自動分佈到其他伺服器。若要強制標記分散到其他伺服器,必須編寫包含 BEGIN TRAN 名稱 WITH MARK 語句的儲存過程。然後,必須在發起伺服器上的事務作用域下,在遠端伺服器上執行該儲存過程。

例如,假設多個 SQL Server 例項上存在分割槽資料庫。每個例項上都有一個名為 coyote 的資料庫。首先,在每個資料庫中建立一個儲存過程,例如,sp_SetMark。

  
CREATE PROCEDURE sp_SetMark
@name nvarchar (128)
AS
BEGIN TRANSACTION @name WITH MARK
UPDATE coyote.dbo.Marks SET ne = 1
COMMIT TRANSACTION;
GO然後,建立包含在每個資料庫中放置標記的事務的儲存過程 sp_MarkAll。sp_MarkAll 可以從任意例項中執行。

  
CREATE PROCEDURE sp_MarkAll
@name nvarchar (128)
AS
BEGIN TRANSACTION
EXEC instance0.coyote.dbo.sp_SetMark @name
EXEC instance1.coyote.dbo.sp_SetMark @name
EXEC instance2.coyote.dbo.sp_SetMark @name
COMMIT TRANSACTION;
GO兩階段提交
提交分散式事務分為兩個階段:準備和提交。提交標記事務時,標記事務中每個資料庫的提交日誌記錄都放在日誌的某一點處,以使任何日誌中不存在有疑問的事務。此點保證不存在這樣的事務:在一個日誌中顯示為已提交,在另一個日誌中顯示為未提交。

為此,可在提交標記事務的過程中執行下列操作:

標記事務的準備階段停止所有新的準備和提交。

僅允許繼續提交準備好的事務。

標記事務將等待耗盡所有準備好的事務(帶超時設定)。

準備並提交標記事務。

取消停止新的準備和提交。

由跨多個資料庫的標記事務產生的停止會降低伺服器的事務處理效能。

建議不要執行併發標記事務。雖然很少見,但分散式標記事務有可能與其他同時提交的分散式標記事務發生死鎖。出現這種情況時,正在標記的事務將被選作死鎖犧牲品並回滾。出現此錯誤時,應用程式會重試標記事務。多個標記事務嘗試同時提交時,發生死鎖的可能性較大。

 恢復到標記的事務
有關如何將包含標記事務的資料庫恢復到特定標記或僅恢復到特定標記之前,請參閱恢復到標記的事務。


 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-541441/,如需轉載,請註明出處,否則將追究法律責任。

相關文章