首页 > 解决方案 > db2 HADR 环境中创建表空间问题

问题描述

我们在 centos 6.9 和 TSAMP 3.2 上使用 Db2 10.5.0.7 作为我们的高可用性解决方案,当我们在主数据库中创建表空间时,我们在备用数据库中遇到以下错误:

2019-08-31-08.47.32.164952+270 I87056E2779 级别:错误(OS)PID:4046 TID:47669095425792 PROC:db2sysc 0 实例:db2inst1 节点:000 DB:SAMDB APP11HDL:0-8 APPID25:*LOCAL11DB221。主机名:samdb-b EDUID:155 EDUNAME:db2redom (SAMDB) 0 功能:DB2 Common,OSSe,ossGetDiskInfo,探针:130 消息:ECF=0x90000001=-1879048191=ECF_ACCESS_DENIED 访问被拒绝调用:OS,-,fopen OSERR:EACCES( 13) DATA #1:字符串,12 字节 /proc/mounts DATA #2:字符串,25 字节 /dbdata1/samdbTsContainer DATA #3:无符号整数,8 字节

2019-08-31-08.47.32.185625+270 E89836E494 级别:错误 PID:4046 TID:47669095425792 PROC:db2sysc 0 实例:db2inst1 节点:000 DB:SAMDB APPHDL:0-8 APPID:*2231111126 -b EDUID:155 EDUNAME:db2redom (SAMDB) 0 功能:DB2 UDB,高可用性服务,sqlhaGetLocalDiskInfo,探针:9433 消息:ECF=0x90000001=-1879048191=ECF_ACCESS_DENIED 访问被拒绝

2019-08-31-08.47.32.186258+270 E90331E484 级别:错误 PID:4046 TID:47669095425792 PROC:db2sysc 0 实例:db2inst1 节点:000 DB:SAMDB APPHDL:0-8 APPID:*22311111126 -b EDUID:155 EDUNAME:db2redom (SAMDB) 0 功能:DB2 UDB,高可用性服务,sqlhaCreateMount,探针:9746 RETCODE:ZRC=0x827300AA=-2106392406=HA_ZRC_FAILED“SQLHA API 调用错误”

2019-08-31-08.47.32.186910+270 I90816E658 级别:错误 PID:4046 TID:47669095425792 PROC:db2sysc 0 实例:db2inst1 节点:000 DB:SAMDB APPHDL:0-8 APPID:*223111126 -b EDUID:155 EDUNAME:db2redom (SAMDB) 0 FUNCTION:DB2 UDB,缓冲池服务,sqlbDMSAddContainerRequest,探针:812 MESSAGE:ZRC=0x827300AA=-2106392406=HA_ZRC_FAILED“SQLHA API 调用错误”数据:字符串,36 字节集群添加挂载操作失败:DATA #2:字符串,37 字节 /dbdata1/samdbTsContainer/TSPKGCACH.1 DATA #3:字符串,8 字节 SAMDB

2019-08-31-08.47.47.32.190537+270 E113909E951级:错误PID:4046 TID:47669095425792 PROC:DB2SYSC 0实例:db2inst1 node:db2inst1 node:000 db:samdb apphdl:0-8 samph:0-8 samd: *botial.8 samd: *botial.8 samd: *7-8 samd: *7-8 samd: *7-8 samd: * *7-8 samd: *botem. *hotmy: * *7-8: *7-8 -b EDUID:155 EDUNAME:db2redom (SAMDB) 0 功能:DB2 UDB、缓冲池服务、sqlblog_reCreatePool、探针:3134 消息:ADM6106E 前滚操作期间无法创建表空间“TSPKGCACH”(ID = “49”)。最可能的原因是没有足够的空间来创建与表空间关联的容器。在前滚操作完成后连接到数据库并使用 SET TABLESPACE CONTAINERS 命令将容器分配给表空间。然后,发出另一个 ROLLFORWARD DATABASE 命令来完成该表空间的恢复。

2019-08-31-08.47.32.200949+270 E114861E592 LEVEL: Error PID : 4046 TID : 47669095425792 PROC : db2sysc 0 INSTANCE: db2inst1 NODE : 000 DB : SAMDB APPHDL : 0-8 APPID: *LOCAL.DB2.190725231126 HOSTNAME: samdb -b EDUID : 155 EDUNAME: db2redom (SAMDB) 0 FUNCTION: DB2 UDB, buffer pool services, sqlbIncPoolState, probe:4628 MESSAGE : ADM12512W HADR 备用数据库上的日志重放已在表空间“TSPKGCACH”(ID“49”)上停止,因为它已被置于“ROLLFORWARD PENDING”状态。

数据库有可用空间,并且服务器上存在指定的路径(/dbdata1/samdbTsContainer),我们可以在其上手动创建文件。主要和备用上的所有设置都是等效的。db2inst1是/dbdata1/samdbTsContainer的拥有者,权限是drwxr-xr-x,su - db2inst1 “ulimit -Hf”的结果是无限的,ext3是文件系统类型,create tablespace语句如下:

CREATE LARGE TABLESPACE TSPKGCACH IN DATABASE PARTITION GROUP IBMDEFAULTGROUP PAGESIZE 8 K MANAGED BY DATABASE USING (FILE '/dbdata1/samdbTsContainer/TSPKGCACH.1' 5120) ON DBPARTITIONNUM (0) EXTENTSIZE 64 PREFETCHSIZE 64 BUFFERPOOL BP8KPKGCACH OVERHEAD 10.5 TRANSFERRATE 0.14 DATA TAG NONE   NO FILE SYSTEM CACHING;

SELinux 被禁用,扇区大小为 512 字节。挂载选项如下:

/dev/sdf1 /dbdata1 ext3 rw,relatime,errors=continue,barrier=1,data=ordered 0 0

我们无法重新创建问题有时会发生此问题,我们不知道其原因,但问题仍然存在,直到服务器重新启动。当我们重新启动备用服务器问题解决但我们需要删除表空间并重新创建它时,有没有办法解决这个问题?

标签: db2db2-luw

解决方案


从错误来看,我认为问题不在于文件访问本身,而/proc/mounts在于 Db2 使用它来进行容器和文件系统之间的映射(例如,了解 FS 类型)。因此,我建议测试是否全部:

cat /proc/mounts
cat /proc/self/mounts
mount

工作正常以 Db2 实例所有者 ID (db2inst1) 的身份运行。如果不是,这意味着 Db2 是一些奇怪的操作系统问题的受害者,我们需要更多的操作系统诊断(例如strace来自cat /proc/mounts命令)来理解它。

编辑:

为了证实这一理论,我使用 Db2 11.1 进行了快速测试。请注意,这必须是 TSA 控制的环境,Db2 才能遵循sqlhaCreateMount代码路径(因为如果这将是单独的挂载,则 Db2 会将其添加到 TSA 资源模型中)

在主备服务器上:

mkdir /db2data
chown db2v111:db2iadm /db2data

然后待机:

chmod o-rx /proc

(找不到“更智能”的方式来获取EACCES挂载信息)。

当我将在主节点上运行时:

db2 "create tablespace test managed by database using (file '/db2data/testts' 100 M)"

它在主服务器上可以正常完成,但备用服务器恰好遇到您看到的错误:

2019-06-21-03.00.37.087693+120 I1774E2661            LEVEL: Error (OS)
PID     : 10379                TID : 46912992438016  PROC : db2sysc 0
INSTANCE: db2v111              NODE : 000            DB   : SAMPLE
APPHDL  : 0-4492               APPID: *LOCAL.DB2.190621005919
HOSTNAME: rhel-hadrs.kkuduk.com
EDUID   : 61                   EDUNAME: db2redom (SAMPLE) 0
FUNCTION: DB2 Common, OSSe, ossGetDiskInfo, probe:130
MESSAGE : ECF=0x90000001=-1879048191=ECF_ACCESS_DENIED
          Access denied
CALLED  : OS, -, fopen                            OSERR: EACCES (13)
DATA #1 : String, 12 bytes
/proc/mounts
DATA #2 : String, 8 bytes
/db2data
DATA #3 : unsigned integer, 8 bytes
1
CALLSTCK: (Static functions may not be resolved correctly, as they are resolved to the nearest symbol)
  [0] 0x00002AAAB9CFD84B /home/db2v111/sqllib/lib64/libdb2osse.so.1 + 0x23F84B
  [1] 0x00002AAAB9CFED51 ossLogSysRC + 0x101
  [2] 0x00002AAAB9D19647 ossGetDiskInfo + 0xF07
  [3] 0x00002AAAAC52402C _Z21sqlhaGetLocalDiskInfoPKcjPcjS1_jS1_ + 0x26C
  [4] 0x00002AAAAC523C5F _Z16sqlhaGetDiskInfoPKcS0_jPcjS1_jS1_ + 0x29F
  [5] 0x00002AAAAC521CA0 _Z16sqlhaCreateMountPKcS0_m + 0x350
  [6] 0x00002AAAACDE8D5D _Z26sqlbDMSAddContainerRequestP12SQLB_POOL_CBP16SQLB_POOLCONT_CBP12SQLB_GLOBALSP14SQLB_pfParIoCbbm + 0x90D
  [7] 0x00002AAAACE14FF9 _Z29sqlbDoDMSAddContainerRequestsP12SQLB_POOL_CBP16SQLB_POOLCONT_CBjP26SQLB_AS_CONT_AND_PATH_INFOP12SQLB_GLOBALS + 0x2D9
  [8] 0x00002AAAACE0C20F _Z17sqlbDMSCreatePoolP12SQLB_POOL_CBiP16SQLB_POOLCONT_CBbP12SQLB_GLOBALS + 0x103F
  [9] 0x00002AAAACDB1EAC _Z13sqlbSetupPoolP12SQLB_GLOBALSP12SQLB_POOL_CBPKciiiihiP19SQLB_CONTAINER_SPECllblsib + 0xE4C

-> 这是 /proc/mounts 访问的问题,而不是目标路径本身,我可以毫无问题地编写:

[db2v111@rhel-hadrs ~]$ echo "test" > /db2data/testfile

如果那将是路径访问问题:

chmod o+rx /proc
chmod a-rw /db2data

那么在待机时“CREATE TABLESPACE”重做期间的错误将是不同的:

2019-06-21-03.07.29.175486+120 I35023E592            LEVEL: Error
PID     : 10379                TID : 46912992438016  PROC : db2sysc 0
INSTANCE: db2v111              NODE : 000            DB   : SAMPLE
APPHDL  : 0-4492               APPID: *LOCAL.DB2.190621005919
HOSTNAME: rhel-hadrs.kkuduk.com
EDUID   : 61                   EDUNAME: db2redom (SAMPLE) 0
FUNCTION: DB2 UDB, buffer pool services, sqlbCreateAndLockParent, probe:918
MESSAGE : ZRC=0x8402001E=-2080243682=SQLB_CONTAINER_NOT_ACCESSIBLE
          "Container not accessible"
DATA #1 : <preformatted>
Failed at directory /db2data.

2019-06-21-03.07.29.175799+120 I35616E619            LEVEL: Severe
PID     : 10379                TID : 46912992438016  PROC : db2sysc 0
INSTANCE: db2v111              NODE : 000            DB   : SAMPLE
APPHDL  : 0-4492               APPID: *LOCAL.DB2.190621005919
HOSTNAME: rhel-hadrs.kkuduk.com
EDUID   : 61                   EDUNAME: db2redom (SAMPLE) 0
FUNCTION: DB2 UDB, buffer pool services, sqlbCreateAndLockParent, probe:722
MESSAGE : ZRC=0x8402001E=-2080243682=SQLB_CONTAINER_NOT_ACCESSIBLE
          "Container not accessible"
DATA #1 : <preformatted>
Failed to create a portion of the path /db2data/testts2

(更多错误直接指向 /db2data 上的权限)

这证明这是 /proc 访问问题,您需要与您的操作系统团队一起调试它。也许 /proc 完全卸载了?无论如何,实际问题是 db2sysc 进程EACCES正在运行fopen/proc/mounts您需要与操作系统团队进一步调试它。

编辑:

当涉及到调试和证明错误是由操作系统返回时,我们必须跟踪 Db2 完成的 open() 系统调用。Strace可以做到这一点,但是对于生产系统来说开销太高了。如果你可以SystemTap在系统上安装,我建议这样的脚本(这是一个基本版本):

probe nd_syscall.open.return 
{   
    if ( user_string( @entry( pointer_arg(1) ) ) =~ ".*mounts") 
    {   
        printf("exec: %s pid: %d uid: %d (euid: %d) gid: %d (egid: %d) run open(%s) rc: %d\n", execname(), pid(), uid(), euid(), gid(), egid(), user_string(@entry(pointer_arg(1)), "-"), returnval() )
    } 
}

它使用nd_syscall探针,因此即使没有内核调试信息包它也可以工作。你可以像这样运行它:

$ stap open.stap 
exec: cat pid: 24159 uid: 0 (euid: 0) gid: 0 (egid: 0) run open(/proc/mounts) rc: 3
exec: cat pid: 24210 uid: 0 (euid: 0) gid: 0 (egid: 0) run open(/proc/mounts) rc: 3
exec: cat pid: 24669 uid: 1111 (euid: 1111) gid: 1001 (egid: 1001) run open(/proc/mounts) rc: 3
exec: cat pid: 24734 uid: 1111 (euid: 1111) gid: 1001 (egid: 1001) run open(/proc/mounts) rc: -13
exec: cat pid: 24891 uid: 1111 (euid: 1111) gid: 1001 (egid: 1001) run open(/proc/self/mounts) rc: -13
exec: ls pid: 24971 uid: 1111 (euid: 1111) gid: 1001 (egid: 1001) run open(/proc/mounts) rc: -13

-> 在某些时候,我已经撤销了 /proc 的访问权限,并且打开尝试以 -13 ( EACCES) 失败。您只需要在看到错误时在系统上启用它,并查看 Db2 失败时是否记录了某些内容。


推荐阅读