原文:https://www.ibm.com/developerworks/cn/data/library/techarticles/dm-1010baosf/
HADR 简介
HADR( 高可用性灾难恢复 ) 是 DB2 数据库的一个组件,是 DB2 提供给用户的一种高可用性和灾难恢复的解决方案。组成 HADR 需要一对机器,一个主机和一个备机。它的基本原理是主机将数据库产生的日志通过网络传输到备机,然后备机将这些日志重新应用,整个过程类似于前滚恢复。从而保证主机和备机数据库的一致。当主机发生意外停机以后,例如停电或者灾难等,备机可以很快的接替主机继续工作。从 DB2 V97FP1 开始,HADR 开始支持 ROS(Read On Standby),备机除了做备份数据库以外,还可以接收连接,执行读操作。
HADR 的监控
通过数据库参数获取 HADR 的配置信息
通过获取数据库配置信息,可以看到 HADR 的一些基本配置,如图 1,可以看到 HADR 的角色、同步方式、超时时间等等。
图 1. 通过获取数据库信息查看 HADR 配置
如果需要修改这些参数,可是使用“db2 update db cfg for dbname using CONFIG_PARAM value”命令对相应的参数进行修改。修改以后,需要重新启动数据库新的配置才生效。
通过数据库快照获取 HADR 的运行状况
DB2 的快照信息显示了某个时刻数据库的运行状况。从这些数据里面,也可以观察到 HADR 的运行情况。例如,从图 2 中,可以看到 HADR 的角色、状态、连接状况、当前正在操作的日志文件等等。
图 2. 通过获取数据库信息查看 HADR 的运行状况
通过 DB2PD 获取 HADR 运行状况
Db2pd 是一个很强大的工具。通过这个工具,可以看到 DB2 在运行时,内存里面的一些状况。所以通过 db2pd 看到的信息都是实时信息。
通过 db2pd – hadr 看到的信息是非常完整的,下面会对这些输出项目进行详细的解释。
图 3. 通过 DB2PD 获取 HADR 的运行状况
通过以上方式,可以看到如下监控项。
角色(Role):标志数据库是主数据库还是从数据库。
状态(State):HADR 当前的状态。包括 Local Catchup、Remote Catchup、Remote Catchup Pending、Peer、Disconnect Peer。
Local Catchup: 如果备机在这种状态下,表明备机这在从本地的磁盘上读取日志文件,并且对日志进行重新重做;如果主机在这种状态下,表明它正在等待备机的连接。HADR 的主机并没有从本地读日志并重做的过程,我们之所以让主机显示这个状态,就是通过主机上的这个状态告诉用户,备机正在做本地日志的重做。
Remote Catchup: 处于这个状态的 HADR 的主机正在从本地读日志,并且将这些日志发送给备机;而备机会从主机接受日志,并且将这些日志写入它本地的磁盘,并且对这些日志进行重做。
Remote Catchup Pending: 如果备机出于这种状态,表明它正在尝试连接主机。出现这种状态,一般是因为主机不存在或者主机还没有完全的启动起来,导致连接没有成功。
Peer: 如果 HADR 的主备机器处于这种状态,表明主机和备机的网络连接良好。日志可以顺利的从主机发送到备机。
Disconnect Peer: 如果 HADR 的主备机器处于这种状态,表明主机和备机的网络已经断开,但是连接断开的时间并没有超过 PEER_WINDOW。这个状态内,主机上的事务不可以提交。如果这个时候网络恢复,主机和备机重新建立连接,主备机器会重新回到 PEER 状态;如果双方进入这个状态的原因是主机出现了故障,当在备机上做接管(takeover)操作时,不会发生数据丢失。就是说不会出现主机提交了某个事务,但是备机没有提交这个事务的情况。
Disconnected: 如果主机处于这种状态,表明主机没有收到来自备机的连接。如果备机处于这种状态,表明备机不能连接到主机。
同步方式(SyncMode):HADR 传输日志的三种方式,同步模式,近同步模式,异步模式。由于这三种方式对 HADR 来说特别重要,笔者在这里将详细介绍这三种方式。
1. 同步模式:这种模式下,主机首先将日志写入本地磁盘,然后发送给备机。备机收到这些日志以后,首先将这些日志写入本地磁盘以后,然后向主机发送一个回应。当主机收到这个回应以后,事务才可以提交。
图 4. 同步模式示意图
这种模式下,因为当事务提交时,相应的日志已经保存在了备机的磁盘上。所以主机在任何时间下发生故障,备机切换以后可以保证不丢失数据。
2. 近同步模式:在这种模式下,主机在将日志写入磁盘的同时将日志发送到备机。当备机收到日志以后,就会向主机发送回应消息。主机收到这条回应消息以后,事务才可以提交。
也就是说,当主机收到回应消息时,刚才发送备机的日志不一定写到了备机的磁盘上,而有可能还在备机的内存里。如图 5 所示:
图 5. 近同步模式示意图
这种模式下,因为主机发送的日志已经保存在了备机的内存中。只有当主机和备机同时出现故障停机的时候,才会丢失数据。
3. 异步模式:与近同步模式类似,在这种模式下,主机也是写日志到磁盘的同时发送日志到备机。与近同步模式不同的是,在异步模式下,主机并不会等备机的回应消息。而是日志发送成功以后,事务就可以提交。在这里,日志发送成功并不代表主次一定收到了这条消息,这条消息也可能保存在了主机的 TCP 发送缓冲区里面。
图 6. 异步模式示意图
这种模式下,因为日志有可能仍然在主机的 TCP 缓冲区里面,如果这个时候主机出现故障停机,这些数据就会丢失。但是和另两种模式相比,异步模式网络上的开销减小了,这种模式对数据库性能影响是最小的。
心跳丢失数量(HeartBeatMissed):主机会不断地向备机发送心跳,以确认仍然可以和对方通信。这个值表明了有多少心跳信号没有发送成功或者没有接收成功。
日志 LSN 差异(LogGapRunAvg):这个值表示一段时间以内,主机和备机日志差异的平均值。如果这个值一直很大,可能表明网络状况比较差,或者备机的性能和主机差异太大,以至于日志不能及时的从主机传到备机。
连接状态(ConnectStatus):包括三种 CONNECTED, DISCONNECTED, CONGESTED。CONNECTED 表示连接状况良好;DISCONNECTED 表示主机和备机已经断开连接;CONGESTED 表示当前的网络状况不太好,日志或者消息的发送遇到拥塞。
连接时间(ConnectTime):如果主机和备机是连接的,表示连接建立起来的时间;如果连接时断开的,表示的是连接断开的时间;如果发生了网络拥塞,则表示上次网络拥塞的时间。
超时时间(Timeout):如果 HADR 在这段时间内没有收到来自同伴的任何消息,它就会断开网络连接。需要注意的是,这个时间并一定是网络出现错误以后的等待时间。HADR 可以发现网络上的大部分错误,当这些错误发生时,HADR 会立刻断开和对方的连接,而并不会等待。另外,这项配置还有另外两个作用:
1. 心跳的时间间隔为 HADR_TIMEOUT/4 和 30 秒钟两者之间的较小的那个值
2. 如果首先在主机上执行启动 HADR 的操作,如果主机没有在 HADR_TIMEOUT 时间以内没有收到备机的连接,主机上的数据库就会停掉,以防止两台主数据库的存在而导致脑裂。
同伴窗口(PeerWindow):相对应 DB2 配置文件中的 HADR_PEER_WINDOW,该参数只对 SYNC 和 NEARSYNC 两种同步模式有效。如果该参数不为零,当主机和备机断开连接时,在 HADR_PEER_WINDOW 这段时间以内,数据库处于 DISCONNECTED PEER 状态。主机在这段时间内不能提交任何事务。所以,这段时间内,如果备机做了接管,备机不会丢失任何事务。这个参数通对于在 TSA 对 HADR 自动做接管的环境中特别重要,因为 TSA 执行“takeover hard on db dbname by force peer window only”这个命令进行接管。
同伴窗口结束时间(PeerWindowEnd):显示了同伴窗口的结束时间。过了这个时间以后,HADR 将处于 DISCONNECTED 状态。
本地主机名(LocalHost):本地 HADR 所在的主机名或者 IP 地址。
本地服务名(LocalService):本地 HADR 所使用的服务名称或者端口号。
远程主机名(RemoteHost):对端 HADR 所在机器的的主机名或者 IP 地址。
远程服务名(RemoteService):对端 HADR 使用的服务名称或者端口号。
远程实例(RemoteInstance):对端 HADR 数据库所在的实例的名字。
主机日志文件(PrimaryFile):主机目前正在写的日志文件。
主机日志页号(PrimaryPg):主机目前正在写的日志文件中的页号。
主机日志序号(PrimaryLSN):主机正在处理的日志记录的序列号。
备机日志文件(StandByFile):备机目前正在写的日志文件。
备机日志页号(StandByPg):备机目前正在写的日志文件中的页号。
备机日志序号(StandByLSN):备机正在处理的日志记录的序列号。
对于很多 DBA 来说,知道主机和备机的同步情况很重要。从主机日志序号和备机日志序号里面,我们可以判断出来主机还有多少日志没有传输到备机。例如以下图 7 的 db2pd 的结果:
图 7. DB2PD 输出
我们可以看出来主机和备机的日志相差 0x0000000000FA179C-0x0000000000FA16E6 = 0xB6。也就是十进制的 182 个字节。
通过 db2trace 来计算 HADR 对交易性能的影响
db2trc 命令是 DB2 提供的跟踪工具。该跟踪工具记录有关操作的信息并将此信息格式化为可读格式。需要注意的是,运行跟踪时会增加开销,所以启用跟踪工具可能会影响系统性能。
db2trace 可以跟踪每个函数以及该函数的执行时间。利用这一性质,我们可以计算出来每次写日志花费的时间以及 HADR 带来的开销。
首先,我们需要找到主机上的写日志的 EDU(Engine Dispatchable Unit),即 db2loggw 的线程号(或进程号)。对于 v91 及以前的版本,我们使用 db2procs,如图 8:
图 8. 通过 DB2PROCS 查看 EDU 的进程号
对于 v95 及以后版本,db2 基于线程模型,使用 db2pd – edus,如图 9:
图 9. 通过 DB2PD 查看 EDU 的线程号
找到 HADR 的 EDU 以后,我们可以通过 db2trc 去跟踪 loggw 这个进程(或者线程)。例如对于图 8,使用命令:
1 | db2trc on -t -p 32567 -f trace.dump |
等主机上运行过了需要写日志的交易(例如插入,删除,修改)以后,将 db2trc 关掉,然后格式化 db2trace 的 dump 文件:
1 2 | db2trc off; db2trc flow -t trace.dump trace.flow |
打开文件 trace.flow,以图 10 为例。
图 9. 格式化以后的 TRACE 文件
注意标记红线和红色框里面的内容,计算 hadr 的方法如下:
- 找到 sqlpgwlp 函数,
- 找到这个函数内的 sqloWaitEDUWaitPost
- 计算 sqlpgwlp 的执行时间。T1 = 0.196988000 - 0.192810000 = 0.004178000
- 计算 sqloWaitEDUWaitPost 的执行时间。T2 = 0.196951000 - 0.196946000 = 0.000005000
T1 是完成这次写日志的总时间,T2 就是这次写日志时,HADR 带来的开销
如果我们跟踪了多次写日志的操作,就跟得到多个上面的片段。可以根据所有的片段计算平均值,从而得到更精确地开销比例。
总结
通过对 HADR 的监控,管理员可以更清楚的了解当前主机和备机的配置以及运行情况,可以根据监控的结果做出优化或者相应的管理措施。
通过计算 HADR 对整个数据库交易的影响,管理员可以作出相应的调优方案,例如改进 IO 性能,网络性能,修改 HADR 的同步模式等等。
本文对以上监控的各个项目进行了详细的解释,并提供了一种计算 HADR 开销的方法。希望对读者有所帮助。