High Availability Disaster Recovery (HADR)是数据库级别的高可用性数据复制机制,最初被应用于Informix数据库系统中,称为High Availability Data Replication(HDR)。IBM收购Informix之后,这项技术就应用到了新的DB2发行版中。一个HADR环境需要两台数据库服务器:主数据库服务器(primary)和备用数据库服务器(standby)。当主数据库中发生事务操作时,会同时将日志文件通过TCP/IP协议传送到备用数据库服务器,然后备用数据库对接受到的日志文件进行重放(Replay),从而保持与主数据库的一致性。当主数据库发生故障时,备用数据库服务器可以接管主数据库服务器的事务处理。此时,备用数据库服务器作为新的主数据库服务器进行数据库的读写操作,而客户端应用程序的数据库连接可以通过自动客户端重新路由(Automatic Client Reroute)机制转移到新的主服务器。当原来的主数据库服务器被修复后,又可以作为新的备用数据库服务器加入HADR。通过这种机制,DB2 UDB实现了数据库的灾难恢复和高可用性,最大限度地避免了数据丢失。
DB2 HADR工作原理
1.HADR同步方式说明同一台机器配置hadr ,实例db2inst1 db2inst2 都已经创建, dbname: sample端口规划: SVCENAME HADR_LOCAL_SVCPrimary 50000 60000Standby 50001 60001需求: 开归档模式 同步方式: 在上面的配置实例中我们将主数据库和备用数据库的HADR_SYNCMODE参数值设置为NEARSYNC,当主数据库和备用数据库处于对等状态时,HADR采用NEARSYNC(接近同步)同步方式管理日志写入。DB2提供了三种日志同步方式:SYNC(同步):采用SYNC方式时,仅当主数据库日志写入成功,并收到备用数据库的应答,确保备用数据库的日志也成功写入的情况下,才认为日志写入成功。这种方式下的事务响应时间最长,但最大限度的确保不发生事务丢失。NEARSYNC(接近同步):采用NEARSYNC方式时,当主数据库日志写入成功,并收到备用数据库的应答,确定备用数据库已经接收到日志时,即认为日志写入成功。也就是说,备用数据库接收到的日志并不一定能成功写入持久存储设备上的日志文件。这种方式下的事务响应时间比SYNC方式短,且仅当两台服务器同时发生故障时,才会发生事务丢失。ASYNC(异步):采用ASYNC方式时,当主数据库日志写入成功,并将日志发送出去之后,即认为日志写入成功。此方式并不保证备用数据库能收到日志,这要依赖于TCP/IP网络情况。这种方式下的事务响应时间最短,但产生事务丢失的可能性也最大超级异步模式(SUPERASYNC)从 DB2 LUW V9.7.5 和 V9.5.8 开始,HADR 引入了一种新的同步模式,即超同步模式。在该同步模式下,主数据库上数据库日志的产生与发送完全分离,二者没有任何依赖,这样 HADR 对于主数据库业务的影响降到了最低;同时,由于日志的产生与发送分离,可能导致主数据库和备机数据库之间的差距较大,此时如果主机发生故障,会有较多的数据丢失;并且非强制接管(non-force TAKEOVER)可能需要更多时间。2. 主数据库开归档和传输备份1.主数据开启归档$ db2 get db cfg for sample |grep -i logarchmeth1$ db2 update db cfg for sample using logarchmeth1 DISK:/home/db2inst1/archlog$ db2 force application all$ db2 get db cfg for sample |grep -i logarchmeth12.开启归档后,需要离线备份,才能连接数据库$ db2 backup db sample to /home/db2inst1SAMPLE.0.db2inst1.DBPART000.20180328081612.001传输备份文件到另一个实例目录下3. 备库恢复on standby db2inst2:# su - db2inst2$ cp /home/db2inst1/SAMPLE.0.db2inst1.DBPART000.20180328081612.001 ~恢复方式二选一:如果不需要改变数据库路径,可以直接恢复。如果要改变数据库路径,需要用生成脚本方式恢复。1.直接命令恢复$ db2 restore db sample from /home/db2inst1 taken at 201803280816122.生成脚本恢复$ db2 restore db sample from /home/db2inst1 taken at 20180328081612 on /home/db2inst2 into sample redirect generate script sample.clp$ sed -i 's/db2inst1/db2inst2/g' sample.clp$ db2 -tvf sample.clp$ db2 connect to sample4. 主数据库HADR配置开启备机只读模式$ db2set DB2_HADR_ROS=ON$ db2set DB2_STANDBY_ISO=UR$ db2set DB2_HADR_SOSNDBUF=1024000$ db2set DB2_HADR_SORCVBUF=1024000ACR自动路由,设置指向备机端口$ db2 update alternate server for database sample using hostname 127.0.0.1 port 50001$ db2 update database configuration for sample using INDEXREC RESTART$ db2 update database configuration for sample using LOGINDEXBUILD ONHADR参数设置$ db2 update db cfg for sample using HADR_LOCAL_HOST 127.0.0.1$ db2 update db cfg for sample using HADR_LOCAL_SVC 60000$ db2 update db cfg for sample using HADR_REMOTE_HOST 127.0.0.1$ db2 update db cfg for sample using HADR_REMOTE_SVC 60001$ db2 update db cfg for sample using HADR_REMOTE_INST db2inst2$ db2 update db cfg for sample using HADR_TIMEOUT 60$ db2 update db cfg for sample using HADR_SYNCMODE NEARSYNC$ db2 update db cfg for sample using HADR_PEER_WINDOW 120查看hadr参数$ db2 get db cfg for sample |grep -i hadr5. 备数据库HADR配置开启备机只读模式$ db2set DB2_HADR_ROS=ON$ db2set DB2_STANDBY_ISO=UR$ db2set DB2_HADR_SOSNDBUF=1024000$ db2set DB2_HADR_SORCVBUF=1024000ACR自动路由,设置指向主机端口$ db2 update alternate server for database sample using hostname 127.0.0.1 port 50000$ db2 update database configuration for sample using INDEXREC RESTART$ db2 update database configuration for sample using LOGINDEXBUILD ONHADR参数设置$ db2 update db cfg for sample using HADR_LOCAL_HOST 127.0.0.1$ db2 update db cfg for sample using HADR_LOCAL_SVC 60001$ db2 update db cfg for sample using HADR_REMOTE_HOST 127.0.0.1$ db2 update db cfg for sample using HADR_REMOTE_SVC 60000$ db2 update db cfg for sample using HADR_REMOTE_INST db2inst1$ db2 update db cfg for sample using HADR_TIMEOUT 60$ db2 update db cfg for sample using HADR_SYNCMODE NEARSYNC$ db2 update db cfg for sample using HADR_PEER_WINDOW 120查看hadr参数$ db2 get db cfg for sample |grep -i hadr6.激活HADR注意: DB2_HADR_ROS 这个参数需要重启实例才能生效。激活HADR需要重启实例# su - db2inst1$ db2stop force;db2start激活HADR备机$ db2 start hadr on db sample as standby激活HADR主机$ db2 start hadr on db sample as primary检查HADR状态$ db2pd -hadr -db sample测试HADRon primary$ db2 "create table t1(c1 int)"for i in {1..10}dodb2 "insert into t1 values(2)"done$ db2 "select count(*) from t1"on standby$ db2 connect to sample user db2inst1 using db2inst1$ db2 "select count(*) from t1"$ db2 "select count(*) from t1"1 ----------- 10 1 record(s) selected.7. HADR 启停顺序停止顺序--standby stop$ db2 deactivate db sample$ db2 stop hadr on db sample$ db2stop--primary stop$ db2 stop hadr on db sample$ db2stop启动顺序--standby start$ db2start$ db2 start hadr on db sample as standby--primary start$ db2start$ db2 start hadr on db sample as primary