SQL SERVER 基於數據庫鏡像的主從同步
Author:chaoqun.guo createtime:2019-03-26
1、概念
1.1、服務器概念
◆ 主體服務器(Principal Server)
其中一個實例為客戶端提供服務,這個實例稱為"主體服務器"。該服務器"扮演"主體角色",其數據庫副本為當前的"主體數據庫"。
◆ 鏡像服務器(Mirror Server)
另一個實例則充當備用服務器,這個實例稱為"鏡像服務器"(Mirror Server)。該服務器扮演"鏡像角色",其數據庫副本為當前的"鏡像數據庫"。鏡像數據庫不能供客戶端訪問,但是可以為鏡像數據庫創建一個快照,讓客戶端訪問這個快照。
◆ 見證服務器(Witness Server)
見證服務器並不能用於數據庫,只是用來支持自動故障轉移。見證服務器驗證主體服務器是否保持運行,當見證服務器與主體服務器斷開連接之后,如果此時鏡像服務器和見證服務器保持相互連接,則鏡像服務器啟動自動故障轉移,成為新的主體服務器。
1.2、模式概念
數據庫鏡像會話以同步操作或異步操作運行。
在同步操作下,事務將在伙伴雙方處提交。由於主體數據庫需要等待鏡像數據庫將日志寫入磁盤后返回的確認消息,因此會延長事務滯后時間。在異步操作下,事務不需要等待鏡像服務器將日志寫入磁盤便可提交,這樣可最大程度地提高性能。
在SQL SERVER 2008之后,主庫和鏡像庫之間的日志流傳送會默認使用壓縮,壓縮一方面降低了網絡壓力,另一方面增大了鏡像兩端的CPU壓力。 可以打開 TF 1462 來關閉日志流壓縮,SQL SERVER 2005 上日志傳送沒有使用壓縮。
根據是否同步操作以及是否支持自動故障轉移功能,數據庫鏡像有以下三種運行模式。
(1) 高安全性模式:主庫把事務日志數據信息發給從庫,從庫返回事務日志持久化確認信息,確認同步后,事務將在主從庫一起提交。
(2) 高性能模式:主庫把事務日志數據信息發給從庫,發完后無需等待從庫返回確認信息。
(3) 自動故障轉移模式(高可用模式):在高安全模式運行時,可以添加見證服務器,從而實現自動故障轉移。
1.3、數據庫鏡像的優勢
數據庫鏡像技術有以下優勢:
(1)消除存儲方面的單一故障點:不用共享磁盤
(2)提高數據庫可用性:快速自動/手動主從切換
(3)增強的數據保護:提供完整的數據冗余
(4)自動頁修復:2008企業版在某些類型的錯誤導致頁損壞,使其無法讀取后,在 SQL Server 2008 企業版或更高版本上運行的數據庫鏡像伙伴(主體或鏡像)將嘗試自動修復該頁。無法讀取該頁的伙伴將從其伙伴請求該頁的新副本。如果此請求成功,則將以可讀副本替換不可讀的頁,並且這通常會解決該錯誤。
1.4、數據庫鏡像的不足
鏡像數據庫技術有以下不足之處:
(1)版本限制
對於標准版的 SQL Server 實例,只可以使用"高安全模式",即主體數據庫與鏡像數據庫必須實現同步操作。在這種運行模式時,如果任何一個伙伴遇到性能問題,都將使同步操作帶來較大的延時。通常標准版的 SQL Server 受到一些技術限制導致性能不能提升,從而使同步操作的延時更加明顯。
(2)鏡像數據庫的訪問限制
鏡像數據庫甚至不可以提供只讀訪問,只有通過創建快照才能訪問,因此鏡像數據庫的利用率不高。
由於數據庫鏡像技術存在上述不足,SQL Server 后續產品將刪除此項功能,建議改用 AlwaysOn 可用性組。SQL Server 2012 中已經引入了"AlwaysOn 基本可用性組",用來替代數據庫鏡像技術。
2、實施前提(基於證書訪問實現)
(1)實例版本:必須是2005 SP1及以上(且兼容級別也要在這個版本及以上),且主從版本一致。
(2)數據庫版本:必須是標准版及更高的開發/評估/企業,且只有企業版/開發版才能實現高性能模式。且主從一致。
(3)通信:確認網絡能ping通,確定端點端口(默認一般是5022)與實例端口(默認1433)可以telnet 通實現訪問。
(4)磁盤:足夠的磁盤空間(全備復制+事務備復制+還原空間+預留空間)。最好主從是相同的目錄(不同會造成無法加文件)。
(5)限制:不支持 FILESTREAM。不能在主體上創建它。不能為包含 FILESTREAM 文件組的數據庫配置數據庫鏡像。
(6)系統:32位系統下,單實例最多支持10個數據庫做鏡像。
(7)主數據庫:鏡像的數據庫對象不能是系統數據庫。主庫必須是完整恢復模式。且主從庫必須是相同的數據庫名。
(8)從數據庫:利用主數據庫的相關備份進行還原,必須以norecovery模式(RESTORING 狀態)
(9)權限:登錄名具有實施步驟權限,最好sysadmin。可能還需要實例賬戶擁有一定程度的windows權限,最好是admin組;
(10)端點:鏡像兩端的加密算法必須保持一致,否則無法搭建。(因為不同版本默認加密算法不一樣)小版本沒關系,但前提是從庫可以還原主庫。
3、實施步驟(基於證書訪問實現)
3.1、步驟目錄
主服務器host_A |
從服務器host_B |
【1】在master中,創建數據庫秘鑰 |
【1】創建master數據庫秘鑰 |
【2】基於【1】中秘鑰,創建服務器實例加密證書的出站證書 |
【2】基於【1】中秘鑰,創建服務器實例加密證書的出站證書 |
【3】使用服務器實例的證書為該服務器實例創建端點。 |
【3】使用服務器實例的證書為該服務器實例創建端點。 |
【4】將證書備份到文件,並將其安全地復制到從服務器。 |
【4】將證書備份到文件,並將其安全地復制到主服務器。 |
【5】為從服務器創建登錄名。 |
【5】為主服務器創建登錄名。 |
【6】創建一個使用該登錄名(【5】中的)的用戶 |
【6】創建一個使用該登錄名(【5】中的)的用戶 |
【7】使用從服務器的證書對【6】中用戶授權 |
【7】使用主服務的證書對【6】中用戶授權 |
【8】對【5】中登錄名進行連接端點的授權 |
【8】對【5】中登錄名進行連接端點的授權 |
【9】主數據庫設置為完全恢復模式,並以全備傳輸到從服務器 |
【9】以norecovery模式還原需要鏡像的庫 |
【10】(后做)設置鏡像伙伴為從庫 |
【10】(先做)設置鏡像伙伴為主庫 |
【11】核驗,基於SSMS與T-SQL |
【11】核驗,基於SSMS與T-SQL |
3.2、實操
主服務器:SQLSVR1, 192.168.1.1 |
從服務器:SQLSVR2, 192.168.1.2 |
--1、創建 master 數據庫主密鑰 Use master; CREATE MASTER KEY ENCRYPTION BY PASSWORD = '23987hxJ#KL95234nl0zBe'; GO
GO
|
--1、創建 master 數據庫主密鑰 Use master; CREATE MASTER KEY ENCRYPTION BY PASSWORD = '23987hxJ#KL95234nl0zBe'; GO
Use master;
|
11、核驗—基於SSMS
【11.1】主服務器/從服務器,查看數據庫狀態
右擊數據庫,刷新一下,看是否有出現這種情況
主服務器 從服務器
【11.2】查看數據庫屬性,鏡像選項卡
12、核驗—基於T-SQL
--創建快照
create database dbtank_demo1
on (name='db_tank_data',filename='d:\temp_bak\db_tank20190325.snap')
as SNAPSHOT of db_tank
go
--查看表數據最早時間(可以多弄幾個表之類的看看)
select top(5) gettime from dbtank_demo1..sys_users_runegoods
where gettime >='20190320'
order by gettime desc
--刪除快照
drop databases dbtank_demo1
3.3、主備切換
(額外注意事項:(1)系統庫的存儲過程 (2)孤立用戶 (3)作業)
【1】.在高安全模式下:
在主機執行:
use master;
alter database Demo1 set partner failover;
即完成主備切換
【2】.在高性能模式下,需要先切換到高安全模式下再執行切換
use master;
alter database Demo1 set partner safety full;
alter database Demo1 set partner failover;
【3】.在主機(SQLSVR1)宕機的情況下在備機(SQLSVR2)進行強制切換:
use master;
alter database Demo1 set partner FORCE_SERVICE_ALLOW_DATA_LOSS;
當主機(SQLSVR1)重新開機后,在SQLSVR2機器上執行
use master;
alter database Demo1 set partner resume;
此時SQLSVR1成為了備機,而SQLSVR2成為了主機。
再到SQLSVR2機器上執行
alter database Demo1 set partner failover;
就成了SQLSVR1成為主機,SQLSVR2成為備機
【4】切換鏡像在高性能模式下(慎用,可能會丟失數據)
use master;
alter database Demo1 set partner safety off;
【5】.關閉數據庫鏡像
ALTER DATABASE Demo1 SET PARTNER OFF
【6】.暫停與恢復數據庫鏡像
在主體鏡像服務器上,若是不小心日志過大,可以進行暫停來設置日志上限
(1)暫停:ALTER DATABASE AdventureWorks2012 SET PARTNER SUSPEND;
(2)恢復:ALTER DATABASE AdventureWorks2012 SET PARTNER RESUME;
【7】移除見證服務器
USE [master]
GO
ALTER DATABASE Demo1 SET WITNESS OFF
GO
4、數據庫鏡像監控
4.1、數據庫鏡像監視器
【1】啟動數據庫鏡像監視器
-
打開數據庫鏡像監視器
4.2、系統存儲過程監視(聯機叢書—監視數據庫鏡像)
創建定期更新服務器實例上每個鏡像數據庫的狀態信息的作業。 |
|
更改數據庫鏡像監視參數的值。 |
|
返回當前更新持續時間。 |
|
返回所監視數據庫的狀態行,使您能夠選擇此過程是否預先獲取最新的狀態。 |
|
停止並刪除服務器實例上所有數據庫的鏡像監視器作業。 |
重點查看
Use msdb
Go
--查看2個小時以內的同步數據記錄
EXEC sp_dbmmonitorresults db_tank, 2, 0;
【5】常見故障排查
【5.1】服務器網絡地址 "TCP://xxx:5022″ 無法訪問或不存在。
請檢查網絡地址名稱,並檢查本地和遠程端點的端口是否正常運行。 (Microsoft SQL Server,錯誤: 1418)
后來在SQLServer日志中看到了如下錯誤: Database mirroring connection error 4 'An error occurred while receiving data: '10054(遠程主機強迫關閉了一個現有的連接。)'.' for 'TCP://xxx:5022′.
通過這個錯誤找到了問題,c:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\ 沒有讀寫權限,一看真的是這樣,加入管理員(即sqlserver的運行用戶)的讀寫權限后一切正常!(如果還不行,配置權限后,再重新配置鏡像)
具體見:http://dba.stackexchange.com/questions/6222/mirroring-problems-after-removing-domain
【5.2】TCP://xxx:5022 的數據庫鏡像連接錯誤
5 'Connection handshake failed. The login 'ZBIAN\Administrator' does not have CONNECT permission on the endpoint. State 84.'。
在日志中看到如上這個錯誤,發現是因為鏡像數據庫實例沒有權限
對主數據庫與鏡像數據庫進行了調整,主數據庫與鏡像數據庫使用相同的實例賬戶,並重新啟動數據庫服務SQL Server (MSSQLSERVER)
【5.3】程序如何在主從切換時自動切換連接?
(1)標准辦法的連接字符串示例(參考:聯機叢書—鏡像數據庫的連接字符串)
一般形式:"Server=Partner_A; Failover Partner=Partner_B; Database=AdventureWorks; "
舉例演示:"Server=250.65.43.21,4734; Failover Partner=Partner_B; Database=AdventureWorks; "
(2)程序控制:
直接做IP判斷即可,斷線重試,重試幾次后進行伙伴服務器連接嘗試。
【5.4】孤立用戶問題
當一個數據庫從一個實例遷移(恢復)到另外一個實例時,登錄名數據並沒有隨之一起遷移。即使重新新建與數據庫用戶相同的登錄名,卻因為SID不同,也成了孤立的用戶/孤立的登錄名。即-》只有數據庫用戶。沒有登錄名,無法登陸實例,則數據庫用戶無用。 即-》有登錄名與同名數據庫用戶,但是兩者沒有關聯起來,則登錄名登錄到實例無法訪問數據庫。解決方案如下:
- 當一個庫剛遷移(恢復)到另外一台實例時,新建同名登錄名-》進行用戶與登錄名更新關聯
- 在主庫上查詢得到需要同步的用戶sid,上在從庫上創建登錄並設定該登錄的sid為查詢到的sid
- 推薦做法:直接重構一遍,刪除所有的數據庫用戶與同名登錄名,重新建立登錄名與用戶映射關系
【5.5】自增鍵在鏡像中的影響
- 在對表TB1插入兩條數據后,表中自增列當期值為 2 發生故障轉移
- 故障轉移后,對表TB1插入一條數據,發現表中自增列當期值變成1002
結論:假設故障轉移前自增列的當前值為 X ,在故障轉移后,自增列的初始值會變成:((X/1000)+1)*1000+1
【5.6】鏡像服務器與主服務器斷開
(1). 因為主庫或鏡像庫存在內存壓力,導致無法完成鏡像日志傳送和重做
解決辦法:設置數據庫最小內存,保證數據庫有足夠內存完成鏡像操作
(2) 因為主庫和鏡像庫斷開連接,導致鏡像失敗
解決辦法:
1.使用TELNET IP 5022來檢查雙方之間的網絡和端口是否打開
2.重啟主庫和鏡像庫的鏡像端口
ALTER ENDPOINT [Endpoint_Mirroring] STATE=STOPPED
ALTER ENDPOINT [Endpoint_Mirroring] STATE=STARTED
連接上以后,如果主庫與鏡像沒有自動開始繼續同步,則使用如下進行嘗試
(1)暫停:ALTER DATABASE AdventureWorks2012 SET PARTNER SUSPEND;
(2)恢復:ALTER DATABASE AdventureWorks2012 SET PARTNER RESUME;
3. 檢查證書是否過期和被更換
use master;
select *from sys.certificates
--過期了就新建一個新的證書,然后alter endpoint endpoint_name來應用新的證書。然后從新關聯用戶與證書。
--查看鏡像端點與證書的關系,是否被更換了
4.檢查主庫是否有非法關機的情況,如果存在,優先運行DBCC CHECKDB和檢查備份
如果主庫上備份還原失敗,則需要使用備份從新搭建鏡像
【5.7】其他相關
- 更換證書:過期或不安全時使用
- 如何在主庫上增加文件:磁盤不足或需要做文件組規划時使用
附錄1:數據庫鏡像主從+見證中斷情況
1.1、1個點中斷的情況
-
principal 與 witness 連接中斷:
(1)狀態:主庫會變成Disconected 狀態,表示失去與mirror連接,切斷所有客戶端連接, 停止讀寫服務,等待故障切換(默認超時為10S)
(2)結果:如果mirror與witness正常連接,mirror成為新的principal,開始對外提供讀寫服務。
-
mirror 與 witness 連接中斷
(1)狀態:principal與witness連接正常,principal狀態變為Disconected,表示終止與mirror連接,mirror狀態變為suspend; principal不再向mirror發送事務日志,等待mirror重新建立到witness鏈接后,principal才會恢復與mirror進行數據同步;
-
principal 與 mirror 連接中斷:
principal與mirror同時保持witness的連接會話,但是principal與mirror之間會話中斷,witness會通知mirror,principal依然保持連接狀態,不會觸發故障切換;此時principal由於保持有witness的連接會話,服務正常;
1.2、2個點中斷的情況
-
principal 與所有節點會話中斷
只要mirror與witness會話正常,即可完成正常的故障轉移;如果mirror與witness連接也中斷,則無法完成,即便是后來mirror與witness的會話優先恢復,則也無法故障切換,因為已然不確定mirror是否擁有全部principal的數據,此時即便principal處於運行狀態,也無法提供服務,等待principal與任意節點會話恢復正常,即可恢復讀寫服務;
【2】mirror 與 所有節點會話中斷
不會觸發故障切換,principal切入公開運行模式(異步),即不會再向mirror發送事務日志,也不再需要等待mirror的響應,直到mirror重新恢復會話。
【3】witness 與 所有節點會話中斷
不會觸發故障切換,principal繼續提供讀寫服務,與mirror數據繼續同步,鏡像集群喪失自動故障轉移能力,退化為不帶故障轉移的高安全模式;如果三方會話同時連接中斷,則principal無法提供服務,直到principal與任意節點通信恢復正常。
1.3、鏡像集群監控概述
鏡像集群的監控可以通過SQL Server Management stdio啟動鏡像監視器,或者系統內置的存儲過程來實現,監控的主要指標包括:
(1)未發送日志:principal上未發送的日志超過指定的閾值,會在principal上生成一個警告,在高性能模式下,強制服務時可以作為評估principal上事務丟失數量的依據,同樣也適用於在高安全模式切換成異步模式狀態下(mirror失去連接)
(2)未還原日志:重做隊列中的未被應用的事務日志數量(KB),超過閾值,會在mirror上生成一個警告,該值可以作為評估故障轉移時間的主要因素。
(3)最早未被發送的事務:principal發送隊列中,最早未被發送的事務的至今的時間,單位時分鍾,超過閾值,會在principal上生成警告,與未發送日志量一起,從時間維度,衡量高性能模式下和高安全異步模式下,數據丟失數量;
(4)鏡像提交開銷:高安全模式下,principal上事務從提交到等到mirror響應的時間開銷的平均值,如果超過閾值,則在principal上生成一個警告,在同步模式下,該值可以i衡量同步開銷;
附錄2:鏡像相關信息查閱
2.1、查看master中的證書
USE master;
SELECT * FROM sys.certificates;
2.2、查看鏡像端點狀態(聯機叢書視圖參考)
(1)數據庫鏡像端點
SELECT name, role_desc, state_desc, connection_auth_desc, encryption_algorithm_desc
FROM sys.database_mirroring_endpoints;
(2)查看所有端點
select * from sys.endpoints
修改狀態:
ALTER ENDPOINT Endpoint_Mirroring
STATE = STARTED
AS TCP (LISTENER_PORT = <port_number>)
FOR database_mirroring (ROLE = ALL);
GO
2.3、查看端點連接權限
SELECT 'Metadata Check';
SELECT EP.name, SP.STATE,
CONVERT(nvarchar(38), suser_name(SP.grantor_principal_id))
AS GRANTOR,
SP.TYPE AS PERMISSION,
CONVERT(nvarchar(46),suser_name(SP.grantee_principal_id))
AS GRANTEE
FROM sys.server_permissions SP , sys.endpoints EP
WHERE SP.major_id = EP.endpoint_id
ORDER BY Permission,grantor, grantee;
GO
2.4、常見刪除語句
查看與修改:
更多查閱參考:聯機叢書--鏡像
刪除:
【1】. 刪除某終端點(終端點不帶引號) drop endpoint <endpoint_name>
【2】. 刪除證書 在master | Security | Certificates (drop master key...)
【3】. 刪除用戶 在master |User
【4】. 然后可以刪除登錄名 drop login <login_name>
【5】. 修改master key : alter master key drop encryption by service master key
【6】. 刪除master key : drop master key
【7】. 刪除鏡像的命令: alter databse <dbname> set partner off
2.5、查看鏡像狀態
參考:如何使用T-SQL查看鏡像狀態

--==================================================== --查看鏡像狀態 SELECT DB_NAME(database_id) AS DatabaseName, dm.mirroring_role AS MirroringRole, (CASE dm.mirroring_role WHEN 1 THEN '主體' WHEN 2 THEN '鏡像' END) AS MirroringRoleDesc, dm.mirroring_partner_name AS MirroringPartnerName, (CASE WHEN dm.mirroring_witness_name IS NULL THEN '--' ELSE dm.mirroring_witness_name END)AS MirroringWitnessName, dm.mirroring_state AS MirroringState, (CASE dm.mirroring_state WHEN 0 THEN '已掛起' WHEN 1 THEN '與其他伙伴斷開' WHEN 2 THEN '正在同步' WHEN 3 THEN '掛起故障轉移' WHEN 4 THEN '已同步' WHEN 5 THEN '伙伴未同步' WHEN 6 THEN '伙伴已同步' WHEN NULL THEN '無鏡像' END) AS MirroringStateDesc, dm.mirroring_safety_level AS MirroringSafetyLevel, (CASE dm.mirroring_safety_level WHEN 0 THEN '未知' WHEN 1 THEN '異步' WHEN 2 THEN '同步' WHEN NULL THEN '無鏡像' END) AS MirroringSafetyLevelDesc, dm.mirroring_witness_state AS MirroringWitnessState, (CASE dm.mirroring_witness_state WHEN 0 THEN '見證未知' WHEN 1 THEN '見證連接' WHEN 2 THEN '見證斷開' WHEN NULL THEN '無見證' END) AS MirroringWitnessStateDesc FROM sys.database_mirroring dm WHERE dm.mirroring_guid IS NOT NULL --============================================================ --查看鏡像的日志傳送 sp_dbmmonitorresults database_name , rows_to_return , update_status database_name 指定返回其鏡像狀態的數據庫。 rows_to_return 指定返回的行數: 0 = 最后一行 1 = 最后兩小時的行 2 = 最后四小時的行 3 = 最后八小時的行 4 = 最后一天的行 5 = 最后兩天的行 6 = 最后 100 行 7 = 最后 500 行 8 = 最后 1,000 行 9 = 最后 1,000,000 行 update_status 指定返回結果之前,過程: 0 = 不更新數據庫的狀態。僅使用最后兩行計算結果,其保留時間取決於何時刷新狀態表。 1 = 通過在計算結果之前調用 sp_dbmmonitorupdate 來更新數據庫的狀態。但是,如果在前 15 秒內已更新狀態表,或用戶不是 sysadmin 固定服務器角色的成員,則 sp_dbmmonitorresults 將運行,而不更新狀態。 --============================================================ --創建數據庫鏡像監視器作業,該作業可定期更新服務器實例上每個鏡像數據庫的鏡像狀態。 sp_dbmmonitoraddmonitoring [ update_period ] update_period:指定更新間隔(分鍾)。此值可以是介於 1 到 120 分鍾之間的值。默認值為 1 分鍾。 --============================================================ --自定義查詢 --sp_dbmmonitoraddmonitoring 數據來源於dbm_monitor_data WITH tmp AS( SELECT ROW_NUMBER()OVER( PARTITION BY dm.database_id ORDER BY dm.[local_time] DESC) AS RID, * FROM msdb.dbo.dbm_monitor_data dm) SELECT * FROM tmp WHERE RID=1 -------------------------------------------------------------------------------- --補充資料 --============================================ --MSDN: http://technet.microsoft.com/zh-cn/library/ms173768.aspx --sp_dbmmonitorupdate 會插入鏡像相關數據,並將超過天的歷史數據刪除。 復制代碼 復制代碼 --=================================================================== --創建數據庫鏡像監視器作業,該作業可定期更新服務器實例上每個鏡像數據庫的鏡像狀態。 --sp_dbmmonitoraddmonitoring [ update_period ] --update_period --指定更新間隔(分鍾)。此值可以是介於1 到120 分鍾之間的值。默認值為1 分鍾。 --要求具有sysadmin 固定服務器角色的成員身份運行,更新間隔過小會影響性能 EXEC msdb.sys.sp_dbmmonitoraddmonitoring 3; --=================================================================== --更改數據庫鏡像監視參數,設置監視器更新頻率 --sp_dbmmonitorchangemonitoring parameter, value --parameter --指定要更改的參數的標識符。當前,只有以下參數可用: --1 = 更新周期,數據庫鏡像狀態表的更新間隔期的分鍾數。默認間隔為1 分鍾。 --value --為正在更改的參數指定新值。范圍在1 到120 的整數,用於指定新的更新周期(分鍾)。 exec msdb.sys.sp_dbmmonitorchangemonitoring 1,2 --=================================================================== --查看監視器更新頻率 --sp_dbmmonitorhelpmonitoring exec msdb.sys.sp_dbmmonitorhelpmonitoring --=================================================================== --sp_dbmmonitorresults database_name , rows_to_return, update_status --database_name --指定返回其鏡像狀態的數據庫。 --rows_to_return --指定返回的行數: --0 = 最后一行 --1 = 最后兩小時的行 --2 = 最后四小時的行 --3 = 最后八小時的行 --4 = 最后一天的行 --5 = 最后兩天的行 --6 = 最后100 行 --7 = 最后500 行 --8 = 最后1,000 行 --9 = 最后1,000,000 行 --update_status --指定返回結果之前,過程: --0 = 不更新數據庫的狀態。僅使用最后兩行計算結果,其保留時間取決於何時刷新狀態表。 --1 = 通過在計算結果之前調用sp_dbmmonitorupdate 來更新數據庫的狀態。 --但是,如果在前15 秒內已更新狀態表,或用戶不是sysadmin 固定服務器角色的成員, --則sp_dbmmonitorresults 將運行,而不更新狀態。 EXEC msdb.sys.sp_dbmmonitorresults DB1, 2, 0; --=================================================================== --停止並刪除服務器實例上所有數據庫的鏡像監視器作業。 --要求具有sysadmin 固定服務器角色的成員身份。 EXEC msdb.sys.sp_dbmmonitordropmonitoring --=================================================================== --檢查dbm_monitor_data中數據是否有超過閥值數據,如果有,則報警 --status: 數據庫的狀態:= 已掛起1 = 已斷開2 = 正在同步3 = 掛起故障轉移4 = 已同步 --send_queue_size:在主體的發送隊列中未發送日志的大小(KB)。 --redo_queue_size:鏡像中重做隊列的大小(KB)。 --role:服務器實例的當前鏡像角色:= 主體1 = 鏡像, --witness_status:見證狀態:= 未知1 = 已連接2 = 已斷開 use msdb; GO IF (OBJECT_ID('tempdb.dbo.#MirrorResult') IS NOT NULL) BEGIN DROP TABLE #MirrorResult END GO WITH tmp AS( SELECT ROW_NUMBER()OVER(PARTITION BY Database_id ORDER BY local_time DESC) AS RID, * FROM msdb.dbo.dbm_monitor_data ) SELECT * INTO #MirrorResult FROM tmp WHERE RID=1 AND ( ([status]<>2 AND [status]<>4) OR send_queue_size>30000 OR redo_queue_size>30000) --如果表不為空,則鏡像可能出現問題 IF EXISTS(SELECT 1 FROM #MirrorResult) BEGIN DECLARE @databaseNames NVARCHAR(MAX); DECLARE @errorMessage NVARCHAR(MAX); SET @databaseNames=''; SELECT @databaseNames=@databaseNames+DBS.name+'/' FROM #MirrorResult MR INNER JOIN master.sys.databases DBS ON MR.database_id=DBS.database_id set @errorMessage= '數據庫:'+@databaseNames+' 鏡像斷開或者存在大量日志為發送或重做' --發送警告 PRINT @errorMessage END --=================================================================== 復制代碼 復制代碼 --============================================================================= --查看當前掛起的鏡像或有大量日志積壓的鏡像 WITH tmp AS( SELECT ROW_NUMBER()OVER(PARTITION BY Database_id ORDER BY local_time DESC) AS RID, * FROM msdb.dbo.dbm_monitor_data ) SELECT * INTO #MirrorResult FROM tmp WHERE RID=1 AND ( ([status]<>2 AND [status]<>4) OR send_queue_size>30000 OR redo_queue_size>30000)
附錄3:加入見證服務器,實現自動故障轉移(基於證書)
主服務器:SQLSVR3, 192.168.1.3 |
加入見證服務器
--USE master; --DROP MASTER KEY
--1、創建 master 數據庫主密鑰 Use master;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '23987hxJ#KL95234nl0zBe';
GO ------------ USE master; ---2、然后對服務器實例創建一個用於其數據庫鏡像出站連接的加密證書。 --drop CERTIFICATE SQLSVR3_cert CREATE CERTIFICATE SQLSVR3_cert WITH SUBJECT = 'SQLSVR3 certificate for database mirroring', start_date='2019-03-01',expiry_date='2030-01-01';
GO
--3、使用主體服務器實例的證書 SQLSVR3_cert 為主體服務器 SQLSVR3 創建端點。 CREATE ENDPOINT [默認的鏡像端點] STATE = STARTED AS TCP ( LISTENER_PORT=5022 , LISTENER_IP = ALL )
FOR DATABASE_MIRRORING ( AUTHENTICATION = CERTIFICATE SQLSVR3_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL );
GO
---4、備份見證服務器 SQLSVR3 的加密證書。請確保此證書保存在安全可靠的存儲介質上。
BACKUP CERTIFICATE SQLSVR3_cert TO FILE = 'D:\temp_bak\SQLSVR3.cer';
GO
--5、創建登錄名,在見證服務器實例的 master 數據庫中為主體、鏡像服務器分別創建1個登錄名
USE master;
CREATE LOGIN SQLSVR2_login WITH PASSWORD = 'Sample@#'; GO
CREATE LOGIN SQLSVR1_login WITH PASSWORD = 'Sample@#'; GO
--6、為新創建的2登錄名分別創建一個用戶
USE master;
CREATE USER SQLSVR2_user FOR LOGIN SQLSVR2_login; GO
CREATE USER SQLSVR1_user FOR LOGIN SQLSVR1_login; GO
--7、將用戶與鏡像服務器的證書相關聯 USE master;
CREATE CERTIFICATE SQLSVR2_cert AUTHORIZATION SQLSVR2_user FROM FILE = 'D:\temp_bak\SQLSVR2.cer' GO
CREATE CERTIFICATE SQLSVR1_cert AUTHORIZATION SQLSVR1_user FROM FILE = 'D:\temp_bak\SQLSVR1.cer' GO
--8、授予其各自的登錄名對數據庫鏡像端點的 CONNECT 權限。 USE master;
GRANT connect on endpoint::[默認的鏡像端點] TO [SQLSVR2_login]; GO
GRANT connect on endpoint::[默認的鏡像端點] TO [SQLSVR1_login]; GO
--9、然后在主、從庫上都創建登錄名、用戶、綁定證書、授權端點(已經復制見證服務器的SQLSVR3.cer證書過去) USE master;
CREATE LOGIN SQLSVR3_login WITH PASSWORD = 'Sample@#'; GO
CREATE USER SQLSVR3_user FOR LOGIN SQLSVR3_login; GO
CREATE CERTIFICATE SQLSVR3_cert AUTHORIZATION SQLSVR3_user FROM FILE = 'D:\temp_bak\SQLSVR3.cer' GO
GRANT connect on endpoint::[默認的鏡像端點] TO [SQLSVR3_login]; GO
--10、在主從庫上進行與見證服務器連接 ALTER DATABASE AdventureWorks2012 SET WITNESS = 'TCP://192.168.214.13:5022'
-- 驗證結果
復制代碼
這里的IP尾數,11為SQLSVR1,12為SQLSVR2,13為見證服務器 然后關掉主庫11的引擎服務,查看從庫是否實現故障轉移~
成功~ |
附錄4:基於域賬戶的鏡像搭建
4.1、操作步驟
主服務器:SQLSVR1 |
從服務器:SQLSVR1 |
【1】檢查:網絡,實例端口,鏡像端口(5022),版本信息一致性 |
【1】檢查:網絡,實例端口,鏡像端口(5022),版本信息一致性 |
【2】初始化:完整模式下,備份主庫 |
【2】初始化:以norecovery的方式還原從主庫獲取的完整日志鏈備份 |
【3】登錄名:可以手動構建域賬戶作為鏡像登錄名也可以在主數據庫鏡像配置向導中輸入一個不存在的,則sql server會自動創建該登錄名,並給與端點connect權限與數據庫的public權限; |
|
【4】配置:使用配置數據庫安全向導,配置主從與見證,端點與登錄名 |
|
【5】核驗:
|
4.2、操作實踐
【1】 檢查:略
(4.1)右擊數據庫-》屬性/右擊數據庫-》任務-》鏡像 (4.2)點擊上圖中的配置安全性,直接下一步 (4.3)選擇是否配置見證服務器,這里暫時先不配置 (4.4)主服務器實例與端口配置 配置向導默認使用 5022 端口進行偵聽。如果主體服務器已經手動創建了端點,配置向導將選取這個端點。 (4.5)鏡像服務器實例與端口配置 在"鏡像服務器實例"頁,單擊"連接"按鈕,連接到鏡像服務器實例。在連接到鏡像服務器時,請注意使用有權限的登錄帳戶,該登錄帳戶必須具有在鏡像服務器創建端點和登錄名的權限。配置向導可以默認為其分配偵聽器端口。如果鏡像服務器已經手動創建了端點,配置向導將選取這個端點。 (4.6)服務帳戶與端點授權 分別為主體和鏡像指定一個域帳戶。配置向導將為這些帳戶創建登錄名,並為其授予對端點的 CONNECT 權限。這個登錄名只需要 public 固定服務器角色即可 點擊下一步 點擊完成 (4.7)開始鏡像 完成"配置安全性"過程后,配置向導自動詢問是否立即開始鏡像。若要立即開始鏡像,則單擊"開始鏡像"。 如果單擊"不開始鏡像",將返回到數據庫鏡像配置的主界面。可以在配置界面上單擊"開始鏡像"。
(5.1)登錄名 配置向導如果沒有檢查到指定的登錄名,則將自動為 Windows 帳戶創建登錄名。 (5.2)端點 確認配置向導是否成功創建了端點。 (5.3)主體數據庫和輔助數據庫的狀態 配置成功后,主體數據庫的狀態應為"主體,已同步",鏡像數據庫的狀態應為"鏡像,已同步/正在還原..."。
|
參考文獻
基本故障問題排除請參考:聯機叢書—鏡像故障排除
證書方式配置與演示參考:聯機叢書---使用證書設置數據庫鏡像
暫停、恢復、刪除參考 :聯機叢書---暫停、恢復、刪除數據庫鏡像
監事數據庫鏡像參考 :聯機叢書---監視數據庫鏡像
設置數據庫鏡像:https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008-r2/ms190941(v%3dsql.105)
鏡像的實現方式參考:http://www.mssqlmct.cn/dba/?post=51
數據庫鏡像原理:https://blog.csdn.net/jessicaiu/article/details/81906899