一、描述
在生產環境中,不僅我們的應用服務器需要做高可用,數據服務器同樣需要做高可用,否則,一旦數據服務器出問題,整個系統就直接崩潰了。
這里我們介紹一下,使用SqlServer鏡像的方式實現SqlServer的高可用。
二、搭建准備
我使用的是虛擬機來搭建環境:
機器名 |
版本 |
IP |
WIN-SJPRGC2O1KO |
Windows server 2008 R2 |
192.168.213.148 |
WIN-73NJ6DU4SO7 |
Windows server 2008 R2 |
192.168.213.149 |
WIN-LMIMQ4P4OCB |
Windows server 2008 R2 |
192.168.213.150 |
我們分別為三台機器安裝數據庫SqlServer 2008 R2。
為了方便,我直接禁用了三台機器的防火牆,生產環境下,允許5022端口即可。
三、開始搭建
我們選取192.168.213.148這台機器當作主體機器(解釋一下,鏡像里面分為主體機器,鏡像機器和見證機器,主體就是我們實際用到的,而鏡像就相當於一個備份,見證機器的作用是監督主體機器,當主體機器發生故障時,會自動將鏡像機器變為主體機器,見證機器為可選方案,沒有見證機器時,故障切換需要手動進行;當有見證機器時,故障切換將自動進行),選取192.168.213.149,為鏡像機器。
1. 創建數據庫主密鑰
USE master GO CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Asd123';
*注:這個密鑰要相對復雜一些。
主體機器和鏡像機器都執行該語句。
2. 創建證書
CREATE CERTIFICATE CertA WITH Subject = 'CertA', Expiry_Date = '2019-1-1';
主體機器和鏡像機器都執行該語句。注意替換CertA 為CertB
3. 創建端點
IF NOT EXISTS ( SELECT 1 FROM sys.database_mirroring_endpoints ) BEGIN CREATE ENDPOINT [DatabaseMirroring] STATE = STARTED AS TCP ( LISTENER_PORT = 5022, LISTENER_IP = ALL ) FOR DATABASE_MIRRORING ( AUTHENTICATION = CERTIFICATE CertA , ENCRYPTION = REQUIRED Algorithm AES, ROLE = ALL ); END
主體機器和鏡像機器都執行該語句。注意替換CertA為CertB
4. 備份證書
BACKUP CERTIFICATE CertA TO FILE = 'C:\Shares\Certs\CertA.cer
主體機器和鏡像機器都執行該語句。注意替換CertA為CertB
每台機器上應該擁有所有的證書,即主體機器應該有CertA和CertB,鏡像機器也應該有CertA和CertB
5. 創建登陸賬戶
創建互相登陸的賬號,即為主體服務器創建鏡像服務器的登陸賬號,為鏡像服務器創建主體服務器的登陸賬號。
CREATE LOGIN LoginB WITH PASSWORD = 'Asd123';
主體機器和鏡像機器都執行該語句。注意替換LoginB為LoginA
6. 為登陸賬戶創建用戶
CREATE USER UserB For Login LoginB;
主體機器和鏡像機器都執行該語句。注意替換LoginB為LoginA, UserB為UserA
7. 使用證書為用戶授權
CREATE CERTIFICATE CertB AUTHORIZATION UserB FROM FILE = 'C:\Certs\CertB.cer';
主體機器和鏡像機器都執行該語句。注意替換CertB為CertA, UserB為UserA
8. 為登陸賬戶授權端口
GRANT CONNECT ON ENDPOINT::[DatabaseMirroring] TO [LoginB];
主體機器和鏡像機器都執行該語句。注意替換LoginB為LoginA
9. 備份與還原
備份沒什么好說的直接下一步就可以,還原時要注意一下:
10. 創建鏡像
分別在主體和鏡像上面點一下任務—鏡像,把圖中那個地址復制下來,備用。
鏡像機執行:
ALTER DATABASE HADBTest SET PARTNER = 'TCP://WIN-SJPRGC2O1KO:5022';
HADBTest為我要創建鏡像的數據庫
同樣在主機上將備機設置為PARTNER
執行完成后,我們刷新一下數據庫就可以看到如下的樣子
主體:
鏡像:
四、測試
1. 測試故障切換
我們已經完成了搭建,那么我們來測試一下,加入主體機器故障了,我們需要切換至鏡像機器。可以在鏡像機上執行如下代碼,將鏡像數據庫強制切換為主體數據庫。
USE master GO ALTER DATABASE HADBTest SET PARTNER FORCE_SERVICE_ALLOW_DATA_LOSS GO
待故障機器修復成功后,我們可以恢復掛起的鏡像
USE master GO ALTER DATABASE HADBTest SET PARTNER Resume GO
恢復已修復故障機為主體機器,在當前主體機器上執行
USE master GO ALTER DATABASE HADBTest SET PARTNER FAILOVER GO
五、完善
到這里我們已經完成了鏡像的搭配,也嘗試了故障切換,但是嘗試過后,我們發現了一個問題,就是發生故障時,我們還要人為去切換,這就是個很大的問題。所以為了解決這個問題,我們將見證機器加入進來。
與之前一樣,我們為見證機器建立證書:
--創建主密鑰 USE master GO CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Asd123'; --創建證書 CREATE CERTIFICATE CertC WITH SUBJECT = 'CertC ', EXPIRY_DATE ='2019-1-1' ; GO --授權端點 CREATE ENDPOINT DatabaseMirroring
STATE = STARTED AS TCP ( LISTENER_PORT=5022 ) FOR DATABASE_MIRRORING ( AUTHENTICATION = CERTIFICATE CertC , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL );
--備份證書
BACKUP CERTIFICATE CertC TO FILE = 'C:\Certs\CertC.cer';
每台機器上應該擁有所有的證書,即主體機器應該有CertA,CertB和CertC,鏡像機器也應該有CertA,CertB和CertC,見證機器上應該有CertA,CertB和CertC。
在見證機器上添加主體和鏡像機器的賬戶用戶和端點
--主體: USE master; CREATE LOGIN LoginA WITH PASSWORD = 'Asd123'; GO CREATE USER UserA FOR LOGIN LoginA; GO CREATE CERTIFICATE CertA AUTHORIZATION UserA FROM FILE = 'C:\Certs\CertA.cer' GO GRANT CONNECT ON ENDPOINT::DatabaseMirroring
TO LoginA;
GO --鏡像
CREATE LOGIN LoginB WITH PASSWORD = 'Asd123';
GO
CREATE USER UserB FOR LOGIN LoginB;
GO
CREATE CERTIFICATE CertB AUTHORIZATION UserB FROM FILE = 'C:\Certs\CertB.cer'
GO
GRANT CONNECT ON ENDPOINT::DatabaseMirroring TO LoginB;
GO
--在主體和鏡像機器上,將見證機器創建賬戶用戶和端點
USE master;
CREATE LOGIN LoginC WITH PASSWORD = 'Asd123';
GO
CREATE USER UserC FOR LOGIN LoginC;
GO
CREATE CERTIFICATE CertC AUTHORIZATION UserC FROM FILE = 'C:\Certs\CertC.cer'
GO
GRANT CONNECT ON ENDPOINT::DatabaseMirroring TO LoginC;
GO
--在主體機器上執行語句,將見證機器加入進來:
ALTER DATABASE HADBTest SET WITNESS = 'TCP:// WIN-LMIMQ4P4OCB '
現在加入見證機器成功了,我們就可以實現自動的故障轉移了。
六、訪問
故障轉移是完全沒問題了,但是似乎有一個更大的問題要解決,就是,主體和鏡像本身就是兩台不同ip的機器,那么怎么訪問呢?
在ADO.NET中提供了Failover Partner屬性來解決這個問題,填寫鏡像數據庫的ip地址,一旦出現了連接錯誤,ado.net會在超時以后自動去連接鏡像數據庫。
連接字符串示例如下:
<add name="Model1" connectionString="data source=192.168.213.149;Failover Partner=192.168.213.148;initial catalog=HADBTest;persist security info=True;user id=sa;password=Asd123;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />