一、环境说明
本次对 DB2 11.5 HADR 进行主备切换验证。
数据库:TESTDB
192.0.2.10:PRIMARY
192.0.2.11:STANDBY
HADR_SYNCMODE = NEARSYNC
HADR_STATE = PEER
HADR_CONNECT_STATUS = CONNECTED
NEARSYNC 为近同步模式,在数据安全和事务性能之间进行平衡。日常主要关注:
HADR_STATE = PEER
HADR_CONNECT_STATUS = CONNECTED
HADR_LOG_GAP ≈ 0
本文主要记录三个实际问题:
-
DB2 HADR 如何实现主备来回切换;
-
第一次切换后新主库出现
SQL1639N认证失败; -
Standby 开启只读后是否影响后续 Takeover。
二、DB2 HADR 可以来回切换
初始状态:
192.0.2.10 PRIMARY
↓ HADR
192.0.2.11 STANDBY
在备库执行:
db2 takeover hadr on db TESTDB
成功后:
192.0.2.10 STANDBY
192.0.2.11 PRIMARY
原来的 PRIMARY 会自动成为新的 STANDBY,不需要重新搭建 HADR。
之后还可以在原主库上再次执行:
db2 takeover hadr on db TESTDB
恢复:
192.0.2.10 PRIMARY
192.0.2.11 STANDBY
因此正常 PEER 状态下可以:
A主 → B主 → A主
但这并不是双主双写,正常情况下始终只有一个 PRIMARY 可以写入。
计划内切换使用:
db2 takeover hadr on db TESTDB
不要随意使用:
BY FORCE
BY FORCE 主要用于故障接管场景。
三、第一次切换后出现 SQL1639N
第一次将备库切换成 PRIMARY 后,Takeover 本身成功:
DB20000I The TAKEOVER HADR ON DATABASE command completed successfully.
但远程连接新主库时出现:
SQL1639N
The database server was unable to perform authentication because
security-related database manager files on the server do not have
the required operating system permissions.
这说明:
HADR 切换已经成功,但新主机的 DB2 操作系统认证权限存在问题。
1. 对比认证文件权限
在两个节点分别检查:
stat -c '%A %a %U:%G %n' \
/home/db2inst1/sqllib/security/db2ckpw \
/home/db2inst1/sqllib/security/db2chpw
正常节点:
-r-s--x--x 4511 root:db2iadm1 db2ckpw
-r-s--x--x 4511 root:db2iadm1 db2chpw
异常节点:
-r-x--x--x 511 db2inst1:db2iadm1 db2ckpw
-r-x--x--x 511 db2inst1:db2iadm1 db2chpw
主要差异:
正常:
Owner = root
权限 = 4511
存在 setuid
异常:
Owner = db2inst1
权限 = 511
缺少 setuid
2. 检查文件系统是否禁止 setuid
findmnt -T /home/db2inst1/sqllib/security/db2ckpw
重点确认挂载参数中没有:
nosuid
如果存在 nosuid,即使文件权限设置为 4511,setuid 也无法正常生效。
3. 恢复认证权限
确认安装方式及健康节点权限后,将异常节点恢复为一致状态:
chown root:db2iadm1 \
/home/db2inst1/sqllib/security/db2ckpw \
/home/db2inst1/sqllib/security/db2chpw
chmod 4511 \
/home/db2inst1/sqllib/security/db2ckpw \
/home/db2inst1/sqllib/security/db2chpw
再次确认:
stat -c '%A %a %U:%G %n' \
/home/db2inst1/sqllib/security/db2ckpw \
/home/db2inst1/sqllib/security/db2chpw
结果:
-r-s--x--x 4511 root:db2iadm1 db2ckpw
-r-s--x--x 4511 root:db2iadm1 db2chpw
之后远程连接不再出现 SQL1639N。
生产环境不要机械照抄权限,建议先与同版本正常节点对比,再处理。
四、修复认证后为什么又出现 SQL1776N?
认证修复后,再连接 Standby 出现:
SQL1776N
The command cannot be issued on an HADR database.
当时状态:
HADR_ROLE = STANDBY
READS_ON_STANDBY_ENABLED = N
这不是故障,而是备库未开启只读。
整个过程其实变成了:
TCP连接正常
↓
用户名密码认证正常
↓
DB2认证正常
↓
发现数据库是STANDBY
↓
STANDBY未开启只读
↓
SQL1776N
因此:
SQL1639N
→ 操作系统认证权限异常
SQL1776N
→ 认证已经通过,只是Standby不允许普通查询
这个区别非常重要。
五、Standby 开启只读
如果:
READS_ON_STANDBY_ENABLED = N
Standby 不允许普通查询。
开启后:
READS_ON_STANDBY_ENABLED = Y
可以连接备库执行 SELECT 等只读操作:
db2 connect to TESTDB
此时可以简单理解为:
PRIMARY
→ 可读、可写
STANDBY + ROS=N
→ 不可普通读、不可写
STANDBY + ROS=Y
→ 可读、不可写
即使开启了 Read on Standby,备库依然不能进行正常业务写入。
六、开启备库只读会影响 Takeover 吗?
不会。
例如:
192.0.2.10:PRIMARY
192.0.2.11:STANDBY + READS_ON_STANDBY_ENABLED=Y
在备库执行:
db2 takeover hadr on db TESTDB
依然可以正常变成:
192.0.2.11:PRIMARY
192.0.2.10:STANDBY
成为 PRIMARY 后自然恢复正常读写。
以后再次切回,重新成为 STANDBY 时,如果启用了 ROS,则继续允许只读查询。
因此:
不需要为了后续能够来回切换而关闭
READS_ON_STANDBY_ENABLED。
是否开启 ROS,应该看有没有备库查询需求。
如果需要:
巡检
报表查询
数据核验
只读业务
可以保持开启。
如果备库只承担纯灾备,不希望任何业务访问,也可以关闭。
大量只读查询仍然会占用:
CPU
内存
磁盘 I/O
所以 ROS 是否开启主要是资源和访问策略问题,而不是 Takeover 问题。
七、切回原主库时出现 SQL1433N
在测试回切时还遇到:
SQL1433N
The application is already connected to "TESTDB_REMOTE"
while the command issued requires a connection to "TESTDB".
原因是之前为了测试新主库,当前 DB2 CLP 会话还连接着远程数据库别名。
例如:
当前连接:TESTDB_REMOTE
准备操作:TESTDB
此时直接执行:
db2 takeover hadr on db TESTDB
就会发生连接上下文冲突。
处理方法:
db2 connect reset
db2 terminate
然后重新检查:
db2pd -db TESTDB -hadr
确认:
HADR_ROLE = STANDBY
HADR_STATE = PEER
HADR_CONNECT_STATUS = CONNECTED
再执行:
db2 takeover hadr on db TESTDB
即可成功。
因此建议计划内切换前固定执行:
db2 connect reset
db2 terminate
这两条只清理当前 CLP 会话,不会停止数据库服务。
八、推荐的 HADR 计划内切换流程
切换前:
db2 connect reset
db2 terminate
检查:
db2pd -db TESTDB -hadr
确认:
HADR_ROLE = STANDBY
HADR_STATE = PEER
HADR_CONNECT_STATUS = CONNECTED
HADR_LOG_GAP 接近 0
STANDBY_ERROR_TIME = NULL
执行:
db2 takeover hadr on db TESTDB
成功后:
DB20000I The TAKEOVER HADR ON DATABASE command completed successfully.
再次检查:
db2pd -db TESTDB -hadr
确认角色已经互换,并重新进入:
HADR_STATE = PEER
HADR_CONNECT_STATUS = CONNECTED
即可。
九、HADR_LOG_GAP 有少量差值是否正常?
正常。
例如:
PRIMARY:
HADR_LOG_GAP = 几十字节或几KB
STANDBY:
HADR_LOG_GAP = 0
通常只是两边查询时间不同,同时主库还在持续产生新日志。
只要:
HADR_STATE = PEER
HADR_CONNECT_STATUS = CONNECTED
STANDBY_ERROR_TIME = NULL
HADR_LOG_GAP 没有持续增长
就属于正常状态。
需要关注的是:
几MB
→ 几十MB
→ 几百MB
→ 持续增加
特别是同时出现脱离 PEER 或连接断开。
十、最终总结
本次 DB2 HADR 主备切换测试主要验证了三个问题。
1. HADR 支持主备角色正常互换
A PRIMARY
↓ takeover
B PRIMARY
↓ takeover
A PRIMARY
原来的 PRIMARY 会自动成为新的 STANDBY,不需要重新建立复制关系。
2. HADR 正常不代表操作系统认证一定正常
如果切换后出现:
SQL1639N
应重点检查:
db2ckpw
db2chpw
Owner / Group
4511 setuid
文件系统 nosuid
3. Read on Standby 不影响 Takeover
ROS=N → Standby不能普通查询
ROS=Y → Standby可读、不可写
PRIMARY → 正常读写
所以不需要为了后续来回切换而关闭 Standby 只读。
最终可以把 DB2 HADR 简单理解为:
PRIMARY
↓ 日志同步
STANDBY(可选只读)
执行 takeover
原STANDBY → PRIMARY
原PRIMARY → STANDBY
HADR 的关键是角色交换,而不是每次切换后重新搭建主备复制关系。