[SQL SERVER][HA]利用SQL Express打造Log Shipping

  • 4634
  • 0
  • 2012-08-17

[SQL SERVER][HA]利用SQL Express打造Log Shipping

前言
TechNet論壇網友詢問如何利用SQL Express自行建立Log Shipping,
當然我個人是不建議自己打造輪子,因為SQL Express沒有SQL Agent也沒有壓縮功能,
而且後續執行時,一定也要管理維護次要資料庫還原交易記錄檔是否成功或失敗,
那這樣你又得自己在打造另一顆輪子(Error Handling和效能都是讓人很感冒的問題)..anyway
了解記錄傳送主要的三項作業,我們依然可以使用SQL Express自行打造Log Shipping,
下面自行記錄整各過程(For SQL2005),不過我事先聲明,
利用該方法建立Log Shipping後續有任何問題時請自行負責....

三項主要作業
1.主要執行個體備份交易記錄檔
2.複製交易記錄檔到次要執行個體上
3.次要執行個體上還原交易記錄檔
image 
監視伺服器可有可無。
image 
必要條件:
1.主要資料庫需要完整復原模式
2.兩個資料庫定序請一致
3.SQL Server請使用Standard以上版本(這就先忽略了...)

需求:
Log Shipping是SQL Server高可用性解決方案之一(硬體成本較低),
可以為主要資料庫提供災難復原(但DBA需手動執行Failover)或分擔資料庫查詢工作(次要資料庫可唯獨存取)。
早期因為SQL2012以前的版本 DB Mirroring 次要資料庫無法存取,
所以那時我為了模擬正式資料庫環境,
我還會在另一台伺服器上建置Log Shipping來讓開發人員使用(相對成本也較高),
但現在SQL2012 AlwaysOn Availability Groups 解決了以往的問題(進階版的DB Mirroring),
最大化你的伺服器硬體利用率(閒置少)。

單獨使用Log Shipping將面臨問題:
1.當主要伺服器故障時,DBA只能手動執行容錯移轉(Failover)。
2.可能遭遇資料遺失問題。這取決於你設定傳送交易記錄檔並還原到次要資料庫的時間週期,
3.執行容錯移轉到次要伺服器後,為了讓應用程式執行正常,你可能需要修改Server IP、DB Name...等。

Log Shipping建立步驟:
1.主要資料庫執行完整備份。
--1.full backup db
BACKUP database db1 to disk='d:\db1.bak' WITH init 

 

2.還原到次要資料庫

--2.restore db with standby
--請自行修改DBName和standby file
RESTORE DATABASE [db2] FROM  DISK = N'D:\db1.bak' WITH  FILE = 1,  
MOVE N'db1' TO N'd:\sqldata\db2.mdf',  
MOVE N'db1_log' TO N'd:\sqldata\db2_1.ldf',  
STANDBY = N'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Backup\ROLLBACK_UNDO_db2.BAK',  
NOUNLOAD,  STATS = 10

3.restore master to standby instance
這是為了解決執行容錯移轉後,登入帳號SID不一致問題,
不過這裡我都再同一執行個體示範,所以就沒執行該步驟。
RESTORE database master from disk='...' WITH REPLACE

 

成功如下圖

image

db2為待命/唯讀狀態。

 

查詢db2.dbo.tbl資料

image

目前該資料表只有4筆。

 

底下可以利用cmd呼叫sqlcmd執行相關語法並搭配windows scheduled來處理交易記錄檔

4.主要執行個體建立BackupLog 預存程序(store procedure)

USE [master] 
GO 
CREATE Proc dbo.usp_BackupLog 
        @LogPath nvarchar(1000), 
        @DBName nvarchar(100) 
AS 
BEGIN   
    SET NOCOUNT ON; 
    --Default:NOINIT, NOSKIP, NOFORMAT  
    BACKUP LOG @DBName to disk=@LogPath with NOINIT, NOSKIP, NOFORMAT 
END 
GO
 

5.次要執行個體建立RestoreLog 預存程序(store procedure)

先建立取得還原的交易記錄檔數量

CREATE PROCEDURE dbo.usp_GetRestoreCount
@FileName AS varchar(1000) 
AS 
RESTORE HEADERONLY FROM DISK=@FileName 

 

建立執行還原交易記錄檔

--自行修改 standbyfile path
CREATE PROCEDURE dbo.usp_RestoreLog 
    @LogPath nvarchar(1000), 
    @DBName nvarchar(100) 
AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @StandbyFile nvarchar(1000); 
    SET @StandbyFile = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Backup\ROLLBACK_UNDO_' + @DBName + '.BAK'; 
    DECLARE @spid as varchar(10) 
    DECLARE @mycmd as varchar(1000) 
    DECLARE cur CURSOR FOR SELECT spid FROM master.dbo.sysprocesses WHERE dbid = 
    (SELECT dbid FROM sysdatabases WHERE name = @DBName) 
    open cur 
    FETCH NEXT FROM cur INTO @spid 
    --kill process
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
    SET @mycmd = 'kill ' + @spid 
    EXEC (@mycmd) 
    FETCH NEXT FROM cur INTO @spid 
    END 
    CLOSE cur 
    DEALLOCATE cur 

    DECLARE @i int 
    DECLARE @j int  
    SET @j = 1 
    SET @i = 0 
    --For SQL2005
    CREATE TABLE #HeaderBackupTable 
    (BackupName varchar(255), 
    BackupDescription varchar(255), 
    BackupType int, 
    ExpirationDate datetime, 
    Compressed int, 
    Position int, 
    DeviceType int, 
    UserName VarChar(255), 
    ServerName varchar(255), 
    DatabaseName varchar(255), 
    DatabaseVersion int, 
    DatabaseCreationDate datetime, 
    BackupSize numeric(24,0), 
    FirstLsn numeric(24,0), 
    LastLsn numeric(24,0), 
    CheckpointLsn numeric(24,0), 
    DatabaseBackupLsn numeric(24,0), 
    BackupStartDate datetime, 
    BackupFinishDate datetime, 
    SortOrder int, 
    CodePage int, 
    UnicodeLocaleID int, 
    UnicodeComparisonStyle int, 
    CompatibilityLevel int, 
    SoftwareVendorID int, 
    SoftwareVersionMajor int, 
    SoftwareVersionMinor int, 
    SoftwareVersionBuild int, 
    MachineName varchar(255), 
    Flags int, 
    BindingID uniqueidentifier, 
    RecoveryForkID uniqueidentifier, 
    Collation varchar(255), 
    FamilyGUID uniqueidentifier, 
    HasBulkLoggedData bit, 
    IsSnapshot bit, 
    IsReadOnly bit, 
    IsSingleUser bit, 
    HasBackupChecksums bit, 
    IsDamaged bit, 
    BeginsLogChain bit, 
    HasIncompleteMetaData bit, 
    IsForceOffline bit, 
    IsCopyOnly bit, 
    FirstRecoveryForkID uniqueidentifier, 
    ForkPointLSN numeric(24, 0), 
    RecoveryModel varchar(256), 
    DifferentialBaseLSN numeric(24, 0), 
    DifferentialBaseGUID uniqueidentifier, 
    BackupTypeDescription varchar(256), 
    BackupSetGUID uniqueidentifier 
    --CompressedBackupSize int 
    ) 
    INSERT INTO #HeaderBackupTable 
    EXEC master.dbo.usp_GetRestoreCount @LogPath 
    SET @i = (SELECT COUNT(*) FROM #HeaderBackupTable  ) 
    DROP TABLE #HeaderBackupTable 
    WHILE @i+1 > (@j) 
    BEGIN 
    RESTORE LOG @DBName FROM DISK=@LogPath 
    WITH FILE = @j, 
    STANDBY = @StandbyFile 
    SET @j = @j + 1 
    END 
END 

 

 

 

 

 

測試:

DML相關測試

主要資料庫新增資料後執行備份交易記錄檔


INSERT into tb1 VALUES('rico4',getdate())
INSERT into tb1 VALUES('rico5',getdate())

 


exec dbo.usp_BackupLog 'D:\sqllogshipping\db1.trn','db1'

 

 

傳送交易記錄檔並還原到次要資料庫


exec dbo.usp_RestoreLog 'D:\sqllogshipping\db1.trn','db2' 

 

image

 

確認次要資料庫上的資料

image

可以看到主要資料庫剛剛新增的2筆資料。

 

再次新增資料並執行備份交易記錄檔


INSERT into tb1 VALUES('rico6',getdate())
INSERT into tb1 VALUES('rico7',getdate())
INSERT into tb1 VALUES('rico8',getdate())
INSERT into tb1 VALUES('rico9',getdate())

 

exec dbo.usp_BackupLog 'D:\sqllogshipping\db1.trn','db1'

 

還原交易記錄檔並確認資料


exec dbo.usp_RestoreLog 'D:\sqllogshipping\db1.trn','db2' 

 


image 

 

確認db2資料

image 

 

刪除資料測試

DELETE tb1 WHERE c1 >=5 AND c1 <=10

 


image 

 

更新資料測試

UPDATE tb1 SET c2='ricoisme' WHERE c2='rico'

 


image 

 

DDL相關測試

ALTER TABLE dbo.tb1 ADD c4 bit null;

 

image

 

 


CREATE table tb2
(
c1 int 
)

 


image 

 

DROP TABLE tb2

 


image 

 

 

 

建立索引測試 

CREATE index idx_1 on tb1(c1)

 

確認DB2索引

SELECT * FROM sys.indexes
where object_id=object_id('tb1')

 

 

參考

記錄傳送概觀

容錯移轉至記錄傳送次要 (SQL Server)

How to Perform SQL Server Log Shipping