【IT168 技术文档】前言
在一些实时性要求高的行业,数据库系统的高可用性和灾难恢复一直是备受关注的。本文旨在通过介绍DB2 HADR的功能和基本的工作原理,并且通过一个实例(在单机环境中快速实践DB2-HADR),使您能更好的学习和了解DB2 HADR的功能和基本的工作原理,你可以在这个环境中作一些简单DB2 HADR的练习和测试,并真心希望本文能够为您在学习和应用DB2 HADR在您的数据库系统的高可用性灾难恢复方面提供一些帮助。
DB2 HADR简介
High Availability Disaster Recovery (HADR)是数据库级别的高可用性数据复制机制,HADR 实现是基于 HDR 的 Informix 实现的(是数据库中高可用性灾难恢复相对比较成熟的功能)。本质上讲,HADR 是一种日志传送功能(DB2 UDB 现在支持这种功能),但它传送的不是固化的磁盘上的日志,而是日志缓冲区中的日志。这种方法提供了充分的粒度来满足解决方案的高可用性需求。HADR 复制发生在数据库层。
在生产环境下,HADR环境需要两台数据库服务器:主数据库服务器(primary)和备用数据库服务器(standby)。当主数据库中发生事务操作时,会同时将日志文件通过TCP/IP协议传送到备用数据库服务器,然后备用数据库对接受到的日志文件进行重放(Replay),从而保持与主数据库的一致性。当主数据库发生故障时,备用数据库服务器可以接管主数据库服务器的事务处理。此时,备用数据库服务器作为新的主数据库服务器进行数据库的读写操作,而客户端应用程序的数据库连接可以通过自动客户端重新路由(Automatic Client Reroute)机制转移到新的主服务器。当原来的主数据库服务器被修复后,又可以作为新的备用数据库服务器加入HADR。通过这种机制,DB2 UDB实现了数据库的灾难恢复和高可用性,最大限度的避免了数据丢失。下图为DB2 HADR的工作原理图:

开始配置单机环境的DB2-HADR
首先,您必须拥有DB2 UDB Enterprise Server Edition (ESE)安装介质,笔者使用的是DB2 ESE v9.1 for Windows 32bit,操作系统为Windows XP(主机名为hadr-server,后面配置hadr时候用到)。为简单起见,我们就采用DB2的样本数据库
SAMPLE作为配置对象。
1、 在您的机器上安装DB2 UDB Enterprise Server Edition(安装过程参见DB2的安装文档),并创建两个实例,我们使用缺省的实例所有者用户db2admin,密码db2admin:
db2icrt inst1
db2icrt inst2
2、 修改新创建的实例-db2inst1的参数db2comm和服务端口号svcename,并使用db2sampl在实例-db2inst1下创建缺省数据库sample:
set db2instance=db2inst1
db2start
db2 update dbm cfg using svcename 33333
db2set db2comm=tcpip
db2 terminate
db2stop
db2start
db2sampl
3、 修改SAMPLE数据库配置参数LOGRETAIN为ON,以使该数据库日志记录方式改为存档日志:
db2 update db cfg for sample using logretain on
db2 update db cfg for sample using trackmod on
4、 修改SAMPLE数据库索引日志记录参数:
db2 update db cfg for sample using logindexbuild on
db2 update db cfg for sample using indexrec restart
注:这两个参数不是必须修改。
5、 备份数据库SAMPLE:
db2 backup db sample to d:\dbbak
注:其中" d:\dbbak "是笔者用来存放数据库备份文件的目录。备份完成之后,在d:\dbbak目录下我们会看到数据库备份映像文件(您备份的文件名的时间标志部分和这个文件名是不一样的,在下面的恢复数据库命令中要作相应的修改):
SAMPLE.0.db2inst1.NODE0000.CATN0000.20070707131011.001
6、 修改新创建的另一个实例-db2inst2的参数db2comm和服务端口号svcename:
set DB2INSTANCE=db2inst2
db2start
db2 update dbm cfg using svcename 44444
db2set db2comm=tcpip
db2 terminate
db2stop
db2start
7、 在实例-db2inst2下恢复数据库SAMPLE:
db2 restore database sample from "d:\dbbak" taken at 20070707131011 replace history file without prompting
8、 修改实例-db2inst2下SAMPLE数据库的配置参数:
db2 update db cfg for sample using HADR_LOCAL_HOST hadr-server
db2 update db cfg for sample using HADR_LOCAL_SVC 44455
db2 update db cfg for sample using HADR_REMOTE_HOST hadr-server
db2 update db cfg for sample using HADR_REMOTE_SVC 33344
db2 update db cfg for sample using HADR_REMOTE_INST db2inst1
db2 update db cfg for sample using HADR_SYNCMODE NEARSYNC
9、 修改实例-db2inst1下SAMPLE数据库的配置参数:
set db2instance=db2inst1
db2 update db cfg for sample using HADR_LOCAL_HOST hadr-server
db2 update db cfg for sample using HADR_LOCAL_SVC 33344
db2 update db cfg for sample using HADR_REMOTE_HOST hard-server
db2 update db cfg for sample using HADR_REMOTE_SVC 44455
db2 update db cfg for sample using HADR_REMOTE_INST db2inst2
db2 update db cfg for sample using HADR_SYNCMODE NEARSYNC
10、 启动HADR:
首先启动备用数据库的HADR(实例-db2inst2下的数据库):
set db2instance=db2inst2
db2 deactivate database sample
db2 start hard on database sample as standby
然后启动主数据库的HADR(实例-db2inst1下的数据库):
set db2instance=db2inst1
db2 deactivate database sample
db2 start hard on database sample as primary
注:如果你先启动主数据库(实例-db2inst1)的HADR,那么你必须保证在HADR_TIMEOUT参数指定的时间内(单位为秒)启动备用数据库(实例-db2inst2)的HADR。否则将启动失败。
DB2 HADR测试
我们已经成功地完成了单机环境下的DB2 HADR配置并启动了它。下面我们将对这个配置好的单机环境下的DB2 HADR进行一些测试来验证它的工作。
通过db2pd查看主数据库和备用数据库的状态:
实例-db2inst1下的数据库sample(主数据库)

实例-db2inst2下的数据库sample(备用数据库)

连接实例-db2inst1下的sample主数据库,创建一个test表,插入两条测试数据:
set db2instance=db2inst1
db2 connect to sample user db2admin using db2admin
db2 create table test(c1 integer not null ,c2 varchar(2),primary key (c1))
db2 insert into test (c1,c2) values (11,'aa')
db2 insert into test (c1,c2) values (22,'bb')
db2 commit
查看结果:

在实例-db2inst2下的sample数据库上执行takeover命令,接管实例-db2inst1下的sample数据库(手工执行备用数据库接管主数据库):
set db2instance=db2inst2
db2 takeover hadr on database sample user db2admin using db2admin
通过db2pd再查看主数据库和备用数据库的状态:
实例-db2inst1下的数据库sample(新的备用数据库)

实例-db2inst2下的数据库sample(新的主数据库)

连接到新的主数据库实例-db2inst2下的sample数据库,查看结果:

我们配置的单机环境的DB2 HADR已经正常工作了。如果感兴趣您可以自己再针对一些其它的数据库操作进行测试。
自动配置DB2 HADR脚本
@echo off rem ------------------------------------------------------------------ rem 单机环境DB2 HADR生成脚本 rem 您可以将这个脚本保存到一个脚本文件hadr.cmd中,然后按一下语法执行: rem hadr.cmd <hostname> rem ------------------------------------------------------------------ if "%1" == "" goto usage rem ------------------------------------------------------------------ rem 清除原有环境 rem ------------------------------------------------------------------ echo 清除环境 set db2instance=db2inst1 db2start db2 drop db sample db2stop db2idrop db2inst1 set db2instance=db2inst2 db2start db2 drop db sample db2stop db2idrop db2inst2 rem ------------------------------------------------------------------ rem 创建db2inst1实例 rem ------------------------------------------------------------------ echo 创建db2inst1实例.... db2icrt db2inst1 if errorlevel 1 goto end echo 成功创建db2inst1实例 set db2instance=db2inst1 db2start db2 update dbm cfg using svcename 33333 db2set db2comm=tcpip db2 terminate db2stop db2start echo 在实例db2inst1下创建sample数据库 db2sampl if errorlevel 1 goto end db2 update db cfg for sample using LOGRETAIN RECOVERY echo 备份sample数据库到当前路径 db2 backup db sample to . if errorlevel 1 goto end rem ------------------------------------------------------------------ rem 创建db2inst2实例 rem ------------------------------------------------------------------ echo 创建db2inst2实例.... db2icrt db2inst2 if errorlevel 1 goto end echo 成功创建db2inst2实例 set db2instance=db2inst2 db2start db2 update dbm cfg using svcename 44444 db2set db2comm=tcpip db2 terminate db2stop echo 在实例db2inst2下恢复sample数据库 db2start db2 restore db sample from . if errorlevel 1 goto end rem ------------------------------------------------------------------ rem 配置HADR参数 rem ------------------------------------------------------------------ echo 配置实例db2inst2下的sample数据库的HADR参数 db2 update db cfg for sample using HADR_LOCAL_HOST %1 db2 update db cfg for sample using HADR_LOCAL_SVC 44455 db2 update db cfg for sample using HADR_REMOTE_HOST %1 db2 update db cfg for sample using HADR_REMOTE_SVC 33344 db2 update db cfg for sample using HADR_REMOTE_INST db2inst1 db2 update db cfg for sample using HADR_SYNCMODE NEARSYNC db2 update db cfg for sample using LOGINDEXBUILD on echo 配置实例db2inst1下的sample数据库的HADR参数 SET db2instance=db2inst1 db2 update db cfg for sample using HADR_LOCAL_HOST %1 db2 update db cfg for sample using HADR_LOCAL_SVC 33344 db2 update db cfg for sample using HADR_REMOTE_HOST %1 db2 update db cfg for sample using HADR_REMOTE_SVC 44455 db2 update db cfg for sample using HADR_REMOTE_INST db2inst2 db2 update db cfg for sample using HADR_SYNCMODE NEARSYNC db2 update db cfg for sample using LOGINDEXBUILD on rem ------------------------------------------------------------------ rem 启动HADR rem ------------------------------------------------------------------ echo 启动实例db2inst2下的sample数据库作为备用数据库standby set db2instance=db2inst2 db2 start hadr on db sample as standby if errorlevel 1 goto end echo 启动实例db2inst1下的sample数据库作为主数据库primary set db2instance=db2inst1 db2 start hadr on db sample as primary if errorlevel 1 goto end echo 祝贺您成功配置HADR. exit :usage echo "语法: handson.cmd <hostname>" :end Echo "运行错误,请检查脚本"
DB2 HADR管理说明
启动和停止DB2 HADR
使用START HADR命令启动主数据库和备用数据库的HADR。启动主数据库使用AS PRIMARY子句,启动备用数据库使用AS STANDBY 子句。如果想以其他用户启动HADR,可以通过USER user-name USING password子句指定用户名和密码,在启动主数据库的HADR时,如果在数据库HADR_TIMEOUT所指定的时间内未能建立与备用数据库HADR的连接,启动将失败。这时候,你可以等排除故障并成功启动备用数据库HADR后再启动主数据库HADR,也可以通过指定BY FORCE子句强行启动主数据库。:
启动备用数据库:
start hadr on database sample [using db2admin using db2admin] as standby
启动主数据库:
start hadr on database sample [using db2admin using db2admin] as primary[by force]
使用STOP HADR 停止主数据库和备用数据库的HADR,如果在活动的主数据库上发出此命令,所有的数据库连接都被断开,数据库恢复为标准数据库,并保持联机状态;如果在活动的备用数据库上发出此命令,将停止失败。你必须先使用
DEACTIVATE DATABASE命令取消激活,然后再停止HADR。
停止备用数据库:
deactivate database sample
stop hadr on database sample [using db2admin using db2admin]
停止主数据库:
stop hard on database sample [using db2admin using db2admin]
查看HARD的配置及运行状态
当备用数据库的HADR启动时,它首先进入本地同步更新状态。并根据本地日志路径配置参数及日志归档方法的设置检索本地系统中的日志文件并重放。当本地日志文件重放完毕,备用数据库进入远程同步暂挂状态。当与主数据库建立连接之后,备用数据库进入远程同步更新状态。即主数据库将自己的日志文件通过TCPIP协议发送给备用数据库,备用数据库接收到日志文件并重放,直到所有日志文件都重放完毕,备用数据库和主数据库进入对等状态。
查看DB2 HADR状态:
db2pd -d sample -hadr
主数据库和备用数据库的接管/故障转移
当主数据库发生故障时,备用数据库可以接管主数据库的服务,成为新的主数据库(称为故障转移)。当原主数据库修复后,又可以作为备用数据库加入HADR对。即使主数据库服务器没有故障,我们通过接管命令(TAKEOVER)切换主数据库和备用数据库的角色。接管命令只能用在备用数据库上。HADR提供两种接管方式:
紧急接管:
takeover hadr on database sample by force
普通接管:
t
akeover hadr on database sample
主数据库和备用数据库的同步方式
在上面的配置实例中我们将主数据库和备用数据库的HADR_SYNCMODE参数值设置为NEARSYNC,当主数据库和备用数据库处于对等状态时,HADR采用NEARSYNC(接近同步)同步方式管理日志写入。DB2提供了三种日志同步方式:
SYNC(同步):
采用SYNC方式时,仅当主数据库日志写入成功,并收到备用数据库的应答,确保备用数据库的日志也成功写入的情况下,才认为日志写入成功。这种方式下的事务响应时间最长,但最大限度的确保不发生事务丢失;
NEARSYNC(接近同步):
采用NEARSYNC方式时,当主数据库日志写入成功,并收到备用数据库的应答,确定备用数据库已经接收到日志时,即认为日志写入成功。也就是说,备用数据库接收到的日志并不一定能成功写入持久存储设备上的日志文件。这种方式下的事务响应时间比SYNC方式短,且仅当两台服务器同时发生故障时,才会发生事务丢失;
ASYNC(异步):
采用ASYNC方式时,当主数据库日志写入成功,并将日志发送出去之后,即认为日志写入成功。此方式并不保证备用数据库能收到日志,这要依赖于TCP/IP网络情况。这种方式下的事务响应时间最短,但产生事务丢失的可能性也最大。
自动客户端重新路由(Automatic Client Reroute)
要配置自动客户端重新路由,使用UPDATE ALTERNATE SERVER命令设置备用数据库信息(使用方法参考上面的配置实例),这些信息将被存放在数据库的系统目录中。请注意:必须使用此命令来设置备用数据库,而不是HADR_REMOTE_HOST 和 HADR_REMOTE_SVC 数据库配置参数,自动客户端重新路由不使用这两个参数。当客户端与数据库建立连接时,备用数据库的配置信息(主机/IP 及 端口号)也同时被发送给DB2客户端。当客户端与主数据库的连接被中断时,客户端就使用这些信息连接到备用数据库,从而最小限度的降低了数据库故障所造成的影响。需要强调的是,这个过程由DB2客户端自动完成,不需要用户用程序干涉。通过LIST DB DIRECOTRY 命令可以查看系统数据库目录中自动客户端重新路由的配置。
索引日志记录
索引的创建、重建、重组也是HADR环境中需要考虑的一个方面,DB2通过数据库配置参数LOGINDEXBUILD和CREATE TABLE或ALTER TABLE语句中的LOG INDEX BUILD选项来控制是否对索引的相关操作进行详细的日志记录。我们在上面的HADR配置实例中将LOGINDEXBUILD数据库参数配置为ON,意为让DB2记录索引创建、重建、重组的完整日志。这显然会降低主数据库的运行效率并占用更多的日志空间。但因为备用数据库可以通过重放日志来重新构建索引,所以当主数据库发生故障,备用数据库的索引仍然可用。用户可以通过CREATE TABLE或ALTER TABLE语句的LOG INDEX BUILD选项来对单个表设定索引日志记录级别。LOG INDEX BUILD选项有三个可选参数:
• NULL:这是缺省值,当使用此参数时,表的索引日志记录级别由数据库配置参数LOGINDEXBUILD的值决定。
• ON:使用此参数,数据库配置参数LOGINDEXBUILD的值将被忽略,DB2将记录这个表上所有索引维护的详细日志。
• OFF:使用此参数时,数据库配置参数LOGINDEXBUILD的值将被忽略,DB2将不记录这个表上索引维护的日志。
如果表选项LOG INDEX BUILD设置为OFF,或者LOG INDEX BUILD设置为NULL但数据库配置参数LOGINDEXBUILD设置为OFF,DB2将不记录这些表的索引维护日志,备用数据库也就无法重放索引维护操作,致使这些索引在备用数据库上变为无效状态。当主数据库发生故障,备用数据库切换为新主数据库后,这些无效的索引必须重建才能被使用。DB2通过数据库配置参数INDEXREC来指定在什么时候检查并重建无效索引。INDEXREC参数有三个可选值:
• RESTART:DB2将在显式或隐式重启数据库(RESTART DATABASE)的时候检查并重新构建无效索引。
• ACCESS:DB2将在无效索引第一次被访问的时候才会重新构建它。
• SYSTEM:使用数据库管理器配置参数(Database Manager Configuration)INDEXREC的值。
在上面的配置实例中,我们将INDEXREC的值设为RESTART,备用数据库将在接管为新的主数据库时检查并重新构建所有无效索引。
DB2 HADR的限制
-只有DB2 UDB Enterprise Server Edition(ESE)支持HADR,但HADR不能支持分区数据库(Database Partitioning Feature,DPF)。
-主数据库和备用数据库必须运行在相同的操作系统版本上,并且DB2 UDB的版本也必须一致,除非短暂的软件升级过程。
-主数据库和备用数据库的位大小必须一致(32位或64位)。
-不能在备用数据库上进行备份操作
-备用数据库是不能访问的,客户端程序无法连接备用数据库。
-日至归档操作只能在主数据库上进行。
-带有COPY NO选项的LOAD命令是不支持的
-主数据库和备用数据库必须是一对一的。
-HADR不能使用循环日志
-HADR不复制数据库配置参数、共享库、DLL、UDF或存储过程
结束语
正如序言所说,本文介绍在一个简单的单机环境中如何配置DB2 HADR,旨在让您能够在一个简单的环境中学习、配置、管理DB2 HADR,使您能更好的了解和利用DB2 HADR,为您的数据库系统在高可用性灾难恢复方面提供更好的保障。
作者简介:丛军 IBM信息管理工程师