DB2 HADR 主备切换实战:SQL1639N 认证问题、备库只读与双向 Takeover

一、环境说明

本次对 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

本文主要记录三个实际问题:

  1. DB2 HADR 如何实现主备来回切换;

  2. 第一次切换后新主库出现 SQL1639N 认证失败;

  3. 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 的关键是角色交换,而不是每次切换后重新搭建主备复制关系。

相关推荐
吠品1 小时前
Nginx负载均衡配置与线上故障排查的一些经验
java·开发语言·数据库
半仙白桑1 小时前
内核篇第一讲:linux创建进程
linux·fork·创建进程
吴声子夜歌1 小时前
Shell编程实例——bash的配置与自定义(二)
linux·运维·shell
风笙9781 小时前
[内存管理] page数据结构
linux
Dovis(誓平步青云)1 小时前
突破 32 位瓶颈:64 位 XID 如何化解事务号回卷危机
运维·服务器·人工智能·docker·容器
达梦数据1 小时前
达梦数据复制软件DMDRS搭建部署示例:源数据库DM8到目标数据库DM8双向数据同步
数据库
Awh-1 小时前
ARM 裸机开发 day02 学习笔记
linux·arm开发·arm