數據庫熱備之SQLServer的數據庫鏡像實施筆記

轉載自:http://kb.cnblogs.com/page/45937/
最初在爲公司設計SQLServer數據庫鏡像的時候,首先考慮的是高可用性(三臺計算機,一臺見證服務器,一臺作主數據庫,一臺作鏡像)
在虛擬機環境下部署成功,一切都是那麼的完美。故障轉移3秒以內就能夠順利完成。
1.高可用性的實施代碼:
  
/********************************************************
此腳本在主體服務器執行
********************************************************/
--鏡像只支持徹底恢復模式,在備份數據庫以前檢查恢復的模式
--對要鏡像的數據庫進行完整備份後,複製到鏡像數據庫以NORECOVERNY選項進行恢復
USE master;
--DROP MASTER KEY
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'P@ssw0rd0';
GO
--爲此服務器實例製做一個證書。
--DROP CERTIFICATE HOST_A_cert
CREATE CERTIFICATE HOST_A_cert 
   WITH SUBJECT = 'HOST_A certificate',START_DATE  = '01/01/2012',EXPIRY_DATE ='01/01/2020';
GO 設置上開始日期,證書有效期爲一年。不設開始日期,即日啓算有效期也爲一年。爲了不麻煩,使用上述參數設置有效期,不然任期內你會很慘。。。。。。EXPIRY_DATE ='01/01/2020'有效期到2020年,這個必定要有
--使用該證書爲服務器實例建立一個鏡像端點。
--DROP ENDPOINT Endpoint_Mirroring
CREATE ENDPOINT Endpoint_Mirroring
   STATE = STARTED
   AS TCP (
      LISTENER_PORT=5022
      , LISTENER_IP = ALL
   ) 
   FOR DATABASE_MIRRORING ( 
      AUTHENTICATION = CERTIFICATE HOST_A_cert
      , ENCRYPTION = REQUIRED ALGORITHM AES
      , ROLE = PARTNER
   );
GO

--備份 HOST_A 證書,並將其複製到其餘機器,將 C:\backup\HOST_A_cert.cer 複製到 HOST_B\HOST_C。
BACKUP CERTIFICATE HOST_A_cert TO FILE = 'C:\backup\HOST_A_cert.cer';
GO
--爲入站鏈接配置 Host_A
--在 HOST_A 上爲 HOST_B 建立一個登陸名。 
USE master;
--DROP LOGIN HOST_B_login
CREATE LOGIN HOST_B_login WITH PASSWORD = 'P@ssw0rd0';
GO

--建立一個使用該登陸名的用戶。
--DROP USER HOST_B_user
CREATE USER HOST_B_user FOR LOGIN HOST_B_login;
GO
--使證書與該用戶關聯。
--DROP CERTIFICATE HOST_B_cert
CREATE CERTIFICATE HOST_B_cert
   AUTHORIZATION HOST_B_user
   FROM FILE = C:\backup\HOST_B_cert.cer'
GO


--授予對遠程鏡像端點的登陸名的 CONNECT 權限。
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_B_login];
GO
 
--在 HOST_A 上爲 HOST_C 建立一個登陸名。 
USE master;
--DROP LOGIN HOST_C_login
CREATE LOGIN HOST_C_login WITH PASSWORD = 'P@ssw0rd0';
GO

--建立一個使用該登陸名的用戶。
--DROP USER HOST_C_user
CREATE USER HOST_C_user FOR LOGIN HOST_C_login;
GO
--使證書與該用戶關聯。
--DROP CERTIFICATE HOST_C_cert
CREATE CERTIFICATE HOST_C_cert
   AUTHORIZATION HOST_C_user
   FROM FILE = C:\backup\HOST_C_cert.cer'
GO

--授予對遠程鏡像端點的登陸名的 CONNECT 權限。
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_C_login];
GO

USE master;
--DROP LOGIN HOST_A_login
CREATE LOGIN HOST_A_login WITH PASSWORD = 'P@ssw0rd0';
GO
--建立一個使用該登陸名的用戶。
--DROP USER HOST_A_user
CREATE USER HOST_A_user FOR CERTIFICATE HOST_A_cert;
GO

--授予對遠程鏡像端點的登陸名的 CONNECT 權限。
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_A_login];
GO

--必需要在鏡像數據庫中先設置好夥伴後,才能在主體服務器執行
--在 HOST_A 的主體服務器實例上,將 HOST_B 上的服務器實例設置爲夥伴(使其成爲初始鏡像服務器實例)。
ALTER DATABASE crm 
    SET PARTNER = 'TCP://192.168.1.205:5022';
GO

--設置見證服務器
ALTER DATABASE crm SET WITNESS = N'TCP://192.168.1.204:5022';
GO

 
  
/***********************************************
在鏡像服務器執行此腳本
***********************************************/
USE master;
--DROP MASTER KEY
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'P@ssw0rd0';
GO
--爲 HOST_B 服務器實例製做一個證書。
--DROP CERTIFICATE HOST_B_cert
CREATE CERTIFICATE HOST_B_cert 
   WITH SUBJECT = 'HOST_B certificate for database mirroring', START_DATE  = '01/01/2012',EXPIRY_DATE ='01/01/2020';
;
GO
--在 HOST_B 中爲服務器實例建立一個鏡像端點。
--DROP ENDPOINT Endpoint_Mirroring
CREATE ENDPOINT Endpoint_Mirroring
   STATE = STARTED
   AS TCP (
      LISTENER_PORT=5022
      , LISTENER_IP = ALL
   ) 
   FOR DATABASE_MIRRORING ( 
      AUTHENTICATION = CERTIFICATE HOST_B_cert
      , ENCRYPTION = REQUIRED ALGORITHM AES
      , ROLE = PARTNER
   );
GO
--備份 HOST_B 證書,將 C:\HOST_B_cert.cer 複製到 HOST_A\HOST_C。
BACKUP CERTIFICATE HOST_B_cert TO FILE = 'c:\backup\HOST_B_cert.cer';
GO 

--爲入站鏈接配置 Host_B
--在 HOST_B 上爲 HOST_A 建立一個登陸名。
USE master;
--DROP LOGIN HOST_A_login
CREATE LOGIN HOST_A_login WITH PASSWORD = 'P@ssw0rd0';
GO
--建立一個使用該登陸名的用戶。
--DROP USER HOST_A_user
CREATE USER HOST_A_user FOR LOGIN HOST_A_login;
GO
--使證書與該用戶關聯。
--DROP CERTIFICATE HOST_A_cert
CREATE CERTIFICATE HOST_A_cert
   AUTHORIZATION HOST_A_user
   FROM FILE = 'c:\backup\HOST_A_cert.cer'
GO

--授予對遠程鏡像端點的登陸名的 CONNECT 權限。 
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_A_login];
GO

--在 HOST_B 上爲 HOST_C 建立一個登陸名。
USE master;
--DROP LOGIN HOST_C_login
CREATE LOGIN HOST_C_login WITH PASSWORD = 'P@ssw0rd0';
GO

--建立一個使用該登陸名的用戶。
--DROP USER HOST_C_user 
CREATE USER HOST_C_user FOR LOGIN HOST_C_login;
GO
--使證書與該用戶關聯。
--DROP CERTIFICATE HOST_C_cert
CREATE CERTIFICATE HOST_C_cert
   AUTHORIZATION HOST_C_user
   FROM FILE = 'c:\backup\HOST_C_cert.cer'
GO

--授予對遠程鏡像端點的登陸名的 CONNECT 權限。
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_C_login];
GO

--在 HOST_B 上爲 HOST_B 建立一個登陸名。 
USE master;
--DROP LOGIN HOST_B_login
CREATE LOGIN HOST_B_login WITH PASSWORD = 'P@ssw0rd0';
GO
--建立一個使用該登陸名的用戶。
--DROP USER HOST_B_user
CREATE USER HOST_B_user FOR CERTIFICATE HOST_B_cert;
GO
--授予對遠程鏡像端點的登陸名的 CONNECT 權限。
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_B_login];
GO
--在 HOST_B 的鏡像服務器實例上,將 HOST_A 上的服務器實例設置爲夥伴(使其成爲初始主體服務器實例)。
ALTER DATABASE crm 
    SET PARTNER = 'TCP://192.168.1.203:5022';
GO
 
  
/****************************
見證服務器執行
*****************************/
--ALTER DATABASE MirrorDB SET PARTNER OFF
USE master;
--DROP MASTER KEY
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'P@ssw0rd0';
GO

--爲此服務器實例製做一個證書。
--DROP CERTIFICATE HOST_C_cert
CREATE CERTIFICATE HOST_C_cert 
   WITH SUBJECT = 'HOST_C certificate',START_DATE  = '01/01/2009';
GO

--使用該證書爲服務器實例建立一個鏡像端點。
--DROP ENDPOINT Endpoint_Mirroring
CREATE ENDPOINT Endpoint_Mirroring
   STATE = STARTED
   AS TCP (
      LISTENER_PORT=5022
      , LISTENER_IP = ALL
   ) 
   FOR DATABASE_MIRRORING ( 
      AUTHENTICATION = CERTIFICATE HOST_C_cert
      , ENCRYPTION = REQUIRED ALGORITHM AES
      , ROLE = WITNESS
   );
GO
 

--備份 HOST_C 證書,並將其複製到其餘系統,即 HOST_B\HOST_A。
BACKUP CERTIFICATE HOST_C_cert TO FILE = 'c:\backup\HOST_C_cert.cer';
GO

--爲入站鏈接配置 Host_C
--在 HOST_C 上爲 HOST_B 建立一個登陸名。 
USE master;
--DROP LOGIN HOST_B_login
CREATE LOGIN HOST_B_login WITH PASSWORD = 'P@ssw0rd0';
GO

--建立一個使用該登陸名的用戶。
--DROP USER HOST_B_user
CREATE USER HOST_B_user FOR LOGIN HOST_B_login;
GO
--使證書與該用戶關聯。
--DROP CERTIFICATE HOST_B_cert
CREATE CERTIFICATE HOST_B_cert
   AUTHORIZATION HOST_B_user
   FROM FILE = 'c:\backup\HOST_B_cert.cer'
GO

--授予對遠程鏡像端點的登陸名的 CONNECT 權限。
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_B_login];
GO
 
--在 HOST_C 上爲 HOST_A 建立一個登陸名。 
USE master;
--DROP LOGIN HOST_A_login
CREATE LOGIN HOST_A_login WITH PASSWORD = 'P@ssw0rd0';
GO
--建立一個使用該登陸名的用戶。
--DROP USER HOST_A_user
CREATE USER HOST_A_user FOR LOGIN HOST_A_login;
GO
--使證書與該用戶關聯。
--DROP CERTIFICATE HOST_A_cert
CREATE CERTIFICATE HOST_A_cert
   AUTHORIZATION HOST_A_user
   FROM FILE = 'c:\backup\HOST_A_cert.cer'
GO

--授予對遠程鏡像端點的登陸名的 CONNECT 權限。 
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_A_login];
GO

--在 HOST_C 上爲 HOST_C 建立一個登陸名。 
USE master;
--DROP LOGIN HOST_C_login
CREATE LOGIN HOST_C_login WITH PASSWORD = 'P@ssw0rd0';
GO
--建立一個使用該登陸名的用戶。
--DROP USER HOST_C_user
CREATE USER HOST_C_user FOR CERTIFICATE HOST_C_cert;
GO
 可能有朋友們會比較有疑惑,你一下搞兩個數據庫出來,他們的ip地址都不同,到時候數據庫切換過去了,個人數據庫的鏈接字符串可如何是好?難道還得在代碼中去控制是鏈接哪一個數據庫嗎?
其實這個問題是這樣的,使用ADO.NET或者SQL Native Client可以自動鏈接到故障轉移後的夥伴,鏈接字符串以下所示:
ConnectionString="DataSource= A;Failover Partner=B;Initial Catalog=AdventureWorks;Integrated Security=true;"
DataSource= A;這個就是咱們經常使用的主數據庫的ip地址,Failover Partner=B;這個填寫的就是鏡像數據庫的ip地址,一旦出現了鏈接錯誤,ado.net會在超時之後自動去鏈接鏡像數據庫。


2.高級別保護模式
在昨天晚上加班作實施的時候,才發現個人設計已經被修改了,因爲之前的項目有java寫的也有c#寫的,全自動的故障轉移不可以實現。換句話說,因爲老項目中的歷史遺留問題,以及特殊模塊的耦合性太高,沒法解耦,只能在高級別保護模式或高性能模式中選擇一種了。那麼這二者有什麼區別呢?
簡單一點來講,區別就在與事務安全模式上跟應用場景上。
高級別保護模式採用的是同步鏡像, SAFETY FULL。應用場景:一般在局域網中或對數據要求比較高的場景中。
高性能保護模式採用的是異步鏡像, SAFETY OFF。應用場景:一般在廣域網或對數據要求不過高,丟失幾條數據是容許的,可是必須保證它不中斷服務。
在微軟的SQLServer2005的課程上是這麼說的。若是是高級別保護模式的話,主、從數據庫只要有一臺不能正常保證服務,數據庫就不可以對外進行服務了,我在開始的時候就沒有打算採用這種模式,由於部門經理說了,丟失一兩條數據是能夠接受的,何況咱們公司是作運營的,按照起先微軟的課程的理論,高級別保護模式是不太適合咱們公司的應用場景的,萬一有一臺數據庫出問題了,整個服務就被中斷,這是不能讓人接受的。再說了,公司對數據要求不太苛刻,兩臺服務器都有內網線鏈接,因爲內網傳輸速度很是的快,即便採用高性能模式,通常來講也是不會丟失數據的。因而我打算採用高性能模式來作數據庫的鏡像。因爲公司服務器沒有域環境,因此我就採用了證書驗證來作SQLServer鏡像。
意外收穫:
兩臺服務器所有都安裝了SQLServer2008,在設置事務安全模式的時候,才發現SQLServer2008不支持異步模式。提示大概以下:此SQLServer版本不支持修改事務安全模式,alter database失敗。我當時汗都出來了,忙活了一夜,到最後竟然是這個結果。
因爲是服務器維護時間,我大膽的把鏡像服務器中止了,結果卻讓我大吃一驚,主數據庫依舊能夠正常工做,正常對外提供服務。也就是說,起先微軟的課程講的知識是錯誤的,兩臺數據庫作鏡像,不論是哪臺數據庫出了問題,另外的一臺數據庫均可以保證正常對外提供服務。因而我反覆試驗反覆切換了一下,結果依然是這樣。
因爲高級別保護模式與高性能模式代碼差不太多,只是在事務安全模式的設置上有些小區別,前面已經提到,這裏就再也不多解釋了。實施的代碼以下:
  
USE  master;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'password';
CREATE CERTIFICATE HOST_A_cert WITH SUBJECT = 'HOST_A certificate' ,
START_DATE  = '01/01/2012',EXPIRY_DATE ='01/01/2020';
;


CREATE  ENDPOINT Endpoint_Mirroring
STATE = STARTED
AS
TCP ( LISTENER_PORT=5022 , LISTENER_IP = ALL )
FOR
DATABASE_MIRRORING
( AUTHENTICATION = CERTIFICATE HOST_A_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL );


BACKUP  CERTIFICATE HOST_A_cert TO  FILE  =  'c:\backup\HOST_A_cert.cer';


CREATE  LOGIN HOST_B_login WITH  PASSWORD  =  'password';
CREATE USER HOST_B_user FOR LOGIN HOST_B_login;
CREATE CERTIFICATE HOST_B_cert AUTHORIZATION HOST_B_user FROM FILE = 'c:\backup\HOST_B_cert.cer';
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_B_login];


ALTER  DATABASE crm SET  PARTNER  =  'TCP://10.10.10.8:5022';

  USE  master;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'password';
CREATE CERTIFICATE HOST_B_cert WITH SUBJECT = 'HOST_B certificate',
START_DATE  = '01/01/2012',EXPIRY_DATE ='01/01/2020';
;


CREATE  ENDPOINT Endpoint_Mirroring
STATE = STARTED
AS
TCP ( LISTENER_PORT=5022 , LISTENER_IP = ALL )
FOR
DATABASE_MIRRORING
( AUTHENTICATION = CERTIFICATE HOST_B_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL );


BACKUP  CERTIFICATE HOST_B_cert TO  FILE  =  'c:\backup\HOST_B_cert.cer';


CREATE  LOGIN HOST_A_login WITH  PASSWORD  = 'password';
CREATE USER HOST_A_user FOR LOGIN HOST_A_login;
CREATE CERTIFICATE HOST_A_cert AUTHORIZATION HOST_A_user FROM FILE = 'c:\backup\HOST_A_cert.cer';
GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_A_login];


ALTER  DATABASE crm SET  PARTNER  =  'TCP://10.10.10.6:5022';
 
可能有朋友會比較奇怪,你這裏也沒有使用ALTER DATABASE crm SET SAFETY FULL; 按理應該是高性能模式纔對呀?
其實這個問題是這樣的,個人這個SQLServer2008默認已是將事務安全模式設置爲full了,即便是手動設置也同樣,而且我實施的時候SQLServer2008不支持將事務安全模式設置爲OFF。
OK,一切都設置好了,那麼就能夠模擬服務器真的down機時候的操做了,後續的工做我也把代碼作了總結,具體代碼以下:
  
--主備互換
--主機執行:

ALTER DATABASE crm SET PARTNER FAILOVER

--主服務器Down掉,備機緊急啓動而且開始服務
ALTER DATABASE crm SET PARTNER FORCE_SERVICE_ALLOW_DATA_LOSS


原來的主服務器恢復,能夠繼續工做,須要從新設定鏡像
--備機執行:
USE master
ALTER DATABASE crm SET PARTNER RESUME  --恢復鏡像

ALTER DATABASE crm SET PARTNER FAILOVER; --切換主備


3.監視數據庫鏡像
SQLServer提供了一些視圖,能夠供查詢鏡像的各類狀態,到時候能夠根據這個作一個監視,一旦發生故障轉移羣集,發郵件給系統管理員,好讓系統管理員及時的知道數據庫服務器發生了什麼問題,即便的作故障分析、排查。有關這方面資料,MSDN上已經提供太多資料了。感興趣的朋友能夠去查這方面的資料。
在文章的最後提出一個有爭議的問題:SQLServer(2008)高級別保護模式,只要有一臺數據庫可以保證正常運行,就能夠正常對外提供服務。個人實驗結果是這樣的,這的確跟以往的理論知識有些出入。
還等什麼,趕快搭環境動手實驗一下吧,體驗一下SQLServer鏡像帶來的快感。但願有興趣的朋友們一塊兒學習探討。
相關文章
相關標籤/搜索