在第 2 章介紹了 HA 集群(雙機熱備)的同步解決方案,在該方案中數據文件存在於共享的物理存儲器上。該方案盡管在一定程度上提高了系統的可用性,但當共享的物理存儲器發生故障時,系統便無法繼續提供服務。異步 HA 集群通過提供多個數據副本解決了這個問題。
本章就來介紹一個異步 HA 集群解決方案——高可用性災難恢復(High Availability Disaster Recovery ,HADR) 。一個 HADR 環境需要有主數據庫(primary )和備用數據庫(standby )兩台數據庫服務器。通常情況下,備用服務器不接收應用程序的讀寫操作,只是通過對主服務器日志文件的重放(replay ),保持與主數據庫的一致性。當主數據庫發生故障時,備用數據庫服務器可以接管主數據庫服務器的事務處理 , 成為新的主數據庫服務器。當原來的主數據庫服務器被修復後,又可以作為新的備用數據庫服務器加入 HADR 。通過這種機制,DB2 UDB 實現了數據庫的災難恢復和高可用性,最大限度地避免了數據丟失。
查看原圖(大圖)
本章內容:
HADR 的工作原理
搭建 HADR
HADR 的管理
難點與重點:
搭建 HADR
3.1 HADR 概述
DB2 數據庫的高可用性災難恢復(HADR)是 DB2 提供的高可用性解決方案,屬於高可用性集群中的數據復制機制。它通過將源數據庫(主數據庫)上的變更日志應用到目標數據庫(備用數據庫)中,以實現數據的復制,避免數據的丟失和損壞。當主服務器發生故障時,備用數據庫會檢測到這個故障,並在數秒內接管主數據庫的工作。而 DB2 客戶端也自動將訪問重定向到備用數據庫上。當發生故障的主服務器故障排除後,可以重新作為主服務器接管備用服務器的工作。
高可用性災難恢復的原理如圖 3.1 所示。
圖 3.1 HADR 工作原理
1. 主數據庫和備用數據庫
一個 HADR 系統需要有兩台數據庫服務器組成,主數據庫(Primary)和備用數據庫(Standby)。通常情況下,客戶端應用程序只是連接主數據庫服務器,對主數據庫服務器進行讀寫操作。當客戶端的事務請求到來的時候,主數據庫服務器除了處理該事務外,還對包含該事務的日志文件進行日志捕獲,並通過 TCP/IP 協議發送到備用數據庫服務器。備用數據庫服務器將接收的日志重放以更新到備用數據庫中。
2. HADR 系統的狀態遷移
HADR 系統的狀態遷移過程如圖 3.2 所示。
圖 3.2 備用數據庫服務的狀態變化
(1)備用數據庫服務器啟動後,首先嘗試讀取本地日志路徑中的日志文件,並將該日志文件應用到備用數據庫中,更新備用數據庫的內容。
(2) 等本地日志文件處理完成後,備用數據庫嘗試與遠程的主服務器建立連接,並進入遠程同步更新暫掛狀態。
(3)與遠程的主服務器建立連接後,備用數據庫進入遠程同步更新狀態。備用數據庫服務器接收主數據庫服務器發送過來的日志文件,並將該日志文件在備用數據庫重放。
(4)重放完成後,主數據庫服務器和備用數據庫服務器進入對等狀態。在對等狀態下,主數據庫的每一次更新,都會同時把日志發送到備用數據庫中。備用數據庫隨即將該日志保存至本地並應用該日志文件,以確保與主數據庫完全一致。
3. 客戶端自動重路由
DB2 的 HADR 的顯著特點之一就是 DB2 客戶端的自動重路由。DB2 客戶端自動重路由的過程如圖 3.3 所示。
圖 3.3 客戶端自動重路由
(1)用戶應用程序通過 DB2 客戶端請求連接主數據庫服務器;
(2)正常情況下,DB2 客戶端連接上主數據庫服務器,並同時獲得備用數據庫服務器的連接參數;
(3)當主數據庫服務器發生故障的時候,DB2 客戶端無法連接主數據庫,導致客戶端超時失敗;
(4)DB2 客戶端將請求重定向到備用服務器中,而無需提供額外的連接參數;
(5)備用數據庫接收到連接請求後,首先將所有的日志文件重放以保持與主服務器的數據一致性,然後轉換角色成為新的主數據庫服務器;
(6)備用數據庫服務器處理完客戶端應用程序的事務請求並將結果返回給 DB2 客戶端;
(7)用戶應用程序從 DB2 客戶端取回處理的結果,而感覺不到主數據庫服務器的故障。
3.2 HADR 配置實踐
3.2.1 構成
為了實現高可用性災難恢復,兩個系統應該滿足下面的條件:
主服務器和備用服務器使用相同的硬件平台和操作系統(包括版本號);
主服務器和備用服務器相互之間通過網絡互聯;
主數據庫和備用數據庫的版本必須一致,容器、表空間、日志大小、緩沖池等等對象也應完全一致。
本節介紹一下在兩台 Linux CentOS 5.2 操作系統下,使用 DB2 V9.5 for Linux(32)搭建 HADR 環境的步驟(見圖 3.4)。這兩個節點分別為主服務器節點 Primary,IP 地址 192.168.189.128;備用服務器節點 Standby,IP 地址 192.168. 189.129。
圖 3.4 HADR 實例
3.2.2 配置
1. 創建實例
在主數據庫服務器(Primary)和備用服務器(Standby)上分別創建實例 db2hadr。
(1)創建實例所有者賬戶:db2hadr。
# useradd – u 505 – g db2iadm1 – m – d /home/ db2hadr db2hadr
(2)創建實例 db2hadr。
# db2icrt – u db2fenc1 db2hadr
2. 創建數據庫
用 db2hadr 賬戶登錄主數據庫服務器(Primary),啟動 db2hadr 實例並創建 HADB 數據庫。
# su – db2hadr
$ db2start
$ db2 create database HADB
3. 修改存檔方式
修改數據庫配置參數,將數據庫日志記錄方式改為歸檔方式(通常情況下,原有數據庫記錄方式為循環)。
$ db2 update db cfg for HADB using logretain on
其中:
logretain:設置日志類別為歸檔日志。為了使用聯機備份,必須打開歸檔日志記錄。
改變上面的參數後,再次連接數據庫會顯示數據庫處於備份暫掛(BACKUP PENDING)狀態。這時,需要做一次對數據庫的脫機備份(db2 backup db),才能使數據庫狀態變為正常。
DB2 的日志類型
DB2 數據庫支持兩種不同的日志模式:循環(Circular)和歸檔(Archival)。在循環日志模式中,日志文件的內容最終會被新日志條目重寫。而歸檔日志的內容永遠都不會被覆蓋。
4. 備份數據文件
將主數據庫服務器上的 HADB 備份到指定路徑,db2hadr 用戶需要有對該目錄的寫入權限。備份數據庫的命令為 BACKUP DATABASE,其語法格式為:
BACKUP DATABASE database-alias
[ USER username [Using passwrod]]
[ TABLESPACE (tablespace-name, … ) ]
[ ONLINE ]
[ INCREMENTAL ][ DELTA ]
[ TO [dir | dev ]]
其中:
DATABASE database-alias:要執行備份的數據庫(別)名。
USER username:執行備份的用戶名。
Using passWord:執行備份用戶名的密碼。
TABLESPACE tablespace-name:要執行備份的表空間。
ONLINE:執行聯機備份。
INCREMENTAL:增量備份。增量備份是對自上次完全備份之後發生變化的數據的備份。
DELTA:差異備份。差異備份是對自上次任意類型的備份之後發生變化的數據的備份。
TO dir|dev:用來保存備份文件的目錄 / 驅動器。
本例中,將 HADB 備份到 /mnt/hgfs/share 路徑下,該命令變為:
# db2 backup database HADB TO /mnt/hgfs/share
可以看到備份命令的返回信息以及備份出來的鏡像文件中,都包含著備份時的時間戳 20090201125734(如圖 3.5 所示)。
圖 3.5 備份數據庫
查看原圖(大圖)
5. 還原數據文件
將主服務器的 HADB 備份復制到備份服務器上,並在備份服務器的 db2hadr 實例上還原 HADB。還原數據庫的命令為 RESTORE DATABASE,其基本語法為:
RESTORE DATABASE database-alias
[ USER username [Using passwrod]]
[ TABLESPACE (tablespace-name, … ) ]
[FROM directory | dev]
[TAKEN AT timestamp]
[REPLACE HISTORY FILES ]
DATABASE database-alias:要執行還原的數據庫(別)名。
USER username:執行還原的用戶名。
Using passWord:執行還原用戶名的密碼。
TABLESPACE tablespace-name:要執行還原的表空間。
FROM directory |dev:用來提取鏡像文件的目錄 / 驅動器。
TAKEN AT timestamp:鏡像文件備份時的時間戳。
REPLACE HISTORY FILES:用備份中的歷史文件覆蓋本地的歷史文件。
本例中,執行下面的命令來還原數據庫:
# su – db2hadr
$ db2start
$ db2 RESTORE DATABASE HADB FROM “/mnt/hgfs/share”
TAKEN AT 20090201125734 REPLACE HISTORY FILE
6. 配置客戶端重路由
配置 HADR 節點的可替換服務器要使用命令 UPDATE ALTERNATE SERVER。其基本語法為:
UPDATE ALTERNATE SERVER FOR DATABASE database-alias
USING HOSTNAME hostname PORT port-numbe
其中:
DATABASE database-alias:為 HADR 服務器的(別)名。
HOSTNAME hostname:可替換服務器所在的主機名。
PORT port-numbe:可替換服務器所在主機的端口號。
在本例中,在主數據庫服務器(primary)上設置下面的參數:
# db2 UPDATE ALTERANATE SERVER FOR DATABASE HADB
USING HOSTNAME 192.168.189.129 PORT 50000
在備用數據庫服務器上(standby)上設置下面的參數:
# db2 UPDATE ALTERANATE SERVER FOR DATABASE HADB
USING HOSTNAME 192.168.189.128 PORT 50000
7. 配置 HADR 服務
配置 HADR 服務和偵聽端口(兩台機器同設)。
用 vi 編輯 /etc/services 文件(需要 root 用戶),並加入下面兩行:
## /etc/services
DB2_HADR_1 55001/tcp
DB2_HADR_2 55002/tcp
由上面的定義可以看出,DB2_HADR_1 服務的端口為 55001,DB2_HADR_2 服務的端口為 55002。
/etc/services 文件是什麼?
Internet 網絡服務文件,記錄網絡服務名和它們對應使用的端口號及協議。文件中的每一行對應一種服務,它由 4 個字段組成,中間用 TAB 或空格分隔,分別表示“服務名稱”“使用端口”“協議名稱”以及“別名”。
8. 配置主數據庫服務器
修改主數據庫(Primary)的配置參數。
01 # db2 UPDATE DB CFG FOR HADB USING HADR_LOCAL_HOST 192.168.189.128
02 # db2 UPDATE DB CFG FOR HADB USING HADR_LOCAL_SVC DB2_HADR_1
03 # db2 UPDATE DB CFG FOR HADB USING HADR_REMOTE_HOST 192.168.189.129
04 # db2 UPDATE DB CFG FOR HADB USING HADR_REMOTE_SVC DB2_HADR_2
05 # db2 UPDATE DB CFG FOR HADB USING HADR_REMOTE_INST db2hadr
06 # db2 UPDATE DB CFG FOR HADB USING HADR_SYNCMODE NEARSYNC
07 # db2 UPDATE DB CFG FOR HADB USING HADR_TIMEOUT 120
08 # db2 CONNECT TO HADB
09 # db2 QUIESCE DATABASE IMMEDIATE FORCE CONNECTIONS
10 # db2 UNQUIESCE DATABASE
11 # db2 CONNECT RESET
其中:
hadr_local_host:HADR 本地主機名配置參數。
hadr_local_svc:HADR 本地服務名稱配置參數。
hadr_remote_host:HADR 遠程主機名配置參數。
hadr_remote_svc:HADR 遠程服務名稱配置參數。
hadr_remote_inst:遠程服務器的 HADR 實例名稱配置參數。
hadr_syncmode:處於對等狀態時日志寫操作的 HADR 同步方式配置參數。
hadr_timeout:HADR 超時值配置參數。
QUIESCE DATABASE:斷開除管理員以外用戶對數據庫的連接。
9. 配置備用數據庫
修改備用數據庫(Standby)的配置參數:
01 # db2 UPDATE DB CFG FOR HADB USING HADR_LOCAL_HOST 192.168.189.129
02 # db2 UPDATE DB CFG FOR HADB USING HADR_LOCAL_SVC DB2_HADR_2
03 # db2 UPDATE DB CFG FOR HADB USING HADR_REMOTE_HOST 192.168.189.128
04 # db2 UPDATE DB CFG FOR HADB USING HADR_REMOTE_SVC DB2_HADR_1
05 # db2 UPDATE DB CFG FOR HADB USING HADR_REMOTE_INST db2hadr
06 # db2 UPDATE DB CFG FOR HADB USING HADR_SYNCMODE NEARSYNC
07 # db2 UPDATE DB CFG FOR HADB USING HADR_TIMEOUT 120
10. 啟動 HADR
啟動 HADR 的命令為 START HADR,其基本語法為:
START HADR ON DATABASE dbname AS [Primary | Standby]
其中:
DATABASE dbname:要啟動的 HADR 數據庫。
AS Primary | Standby:以主服務器 / 備用服務器的方式啟動 HADR。
首先啟動備用數據庫服務器的 HADR:
# db2 deactivate database hadb
# db2 start hadr on database hadb as standby
然後啟動主數據庫服務器的 HADR:
# db2 deactivate database hadb
# db2 start hadr on database hadb as primary
3.2.3 測試
(1)查看數據庫的狀態。用 get snapshot 命令可查看主數據庫服務器和備用數據庫的狀態。本例中使用的命令如下:
# db2 GET SNAPSHOT FOR DB ON Primary
# db2 GET SNAPSHOT FOR DB ON Standby
從圖 3.6 中可以看到 Primary 節點的角色是主節點,Standby 節點的角色是備用節點(見圖 3.7)。
圖 3.6 主服務器的 HADR 狀態
查看原圖(大圖)
圖 3.7 備用服務器的 HADR 狀態
查看原圖(大圖)
(2)使用用戶 db2hadr 來連接到主數據庫,創建測試表 hatbl,並插入測試數據。
01 # su – db2hadr
02 # db2 connect to hadr user db2hadr1 using xxxxxx
03 # db2
04 db2=>create table hatbl(msgid char(5),msg char(20))
05 db2=>insert into hatbl values( ‘ msg01 ’ , ’ hello HADR ’ )
(3)使用備用數據庫接管主數據庫,觀察主數據庫和備用數據庫的狀態。接管數據庫的命令為 TAKEOVER,其語法為:
TAKEOVER HADR ON DATABASE database-alias USER user-name BY FORCE
USING passWord-'
其中,BY FORCE 選項告訴備用節點不用確認主節點的狀態。
本例中執行下面的命令以使備用服務器節點接管主服務器節點的服務。
# db2 takeover HADR on database HADB user db2hadr using xxxxxx
(4)再次通過 snapshot 查看 Standby 節點(192.168.189.129)和 Primary 節點(192.168.189.128)的狀態。從圖 3.8 和圖 3.9 中可以看出,原來的備用服務器節點已成為新的主服務器節點;原來的主服務器節點已經成為備用服務器節點。
圖 3.8 備用數據庫狀態(新的主服務器)
查看原圖(大圖)
圖 3.9 主數據庫狀態(新的備用服務器)
查看原圖(大圖)
(5)連接到新的主數據庫(原備用數據庫),並查詢 hatbl 表,得到插入其中的數據,如圖 3.10 所示。