【DB2 数据库】06 模拟故障排查系列:表空间容器不可访问(权限异常)实验
一、这篇文章要解决什么问题
前面的几篇实验,我已经把表空间容量这一条线基本讲完整了:
- 表空间打满
ADD扩容EXTEND扩容AUTORESIZE自动扩容
但在真实运维里,表空间出问题并不只有“空间不够”这一种情况。
还有一类非常典型、也非常容易让人一开始看懵的故障:
表空间的底层容器文件还在,但 DB2 突然不让访问了。
这篇文章就专门验证这一类问题。
这次实验的目标有 4 个:
- 人为构造一个“容器文件权限异常”的故障
- 观察业务层会报什么错
- 观察 DB2 会把表空间置成什么状态
- 验证把权限修好以后,表空间和业务是否能恢复
如果说前几篇讲的是:
空间怎么满,怎么扩
那么这一篇讲的就是:
空间本身没问题,但容器文件访问不了时,DB2 会怎样出故障。
二、实验环境
- 操作系统:
SUSE Linux Enterprise Server 12 SP5 - DB2 版本:
DB2 v9.7.0.6 Fix Pack 6 - 实例:
db2inst1 - 数据库:
TESTDB - 实验表空间:
TS4 - 容器文件:
/DB2_DATA/TESTDB/ts4/ts4_01.dat - 测试表:
T5
为了让现象足够干净,这次没有继续复用前面做过容量实验的 TS2 或 TS3,而是单独使用一个新的小表空间 TS4 来做容器访问异常实验。
这样做的好处是:
- 故障现象不容易被前面历史动作干扰
- 证据链更清楚
- 后续写成排障文章时更容易讲明白
三、实验前先打快照
这次实验和前面的“纯插数”不同,因为它会直接修改底层容器文件权限。
所以正式开始前,我先建议打一个快照:
10-准备做TS4容器权限异常实验
原因很简单:
- 这次会主动制造故障
- 会让表空间短时间内不可访问
- 一旦恢复步骤做乱了,快照可以快速回退
这种习惯很重要,因为真实运维里“先留后路”本身就是操作规范的一部分。
四、故障前的基线状态
在真正制造故障前,我先确认了当前环境是否正常。
1. 表空间状态
实验开始前,TS4 的状态如下:
Tablespace ID = 8
Name = TS4
Type = Database managed space
Contents = All permanent data. Regular table space.
State = 0x0000
Detailed explanation:
Normal
Total pages = 1000
Useable pages = 960
Used pages = 160
Free pages = 800
High water mark (pages) = 160
Page size (bytes) = 4096
Extent size (pages) = 32
Prefetch size (pages) = 32
Number of containers = 1从这里可以确认:
TS4当前处于Normal- 还有可用页
- 表空间本身没有容量问题
2. 容器状态
继续看容器详情:
Tablespace Containers for Tablespace 8
Container ID = 0
Name = /DB2_DATA/TESTDB/ts4/ts4_01.dat
Type = File
Total pages = 1000
Useable pages = 960
Accessible = Yes这里最关键的是:
- 容器文件存在
Accessible = Yes
3. 业务访问状态
再看测试表 T5:
db2 "select count(*) from T5"
1
-----------
1
1 record(s) selected.所以这次实验的起点非常清楚:
- 业务可访问
- 表空间正常
- 容器可访问
五、这次故障是怎么构造的
这次没有删文件,也没有卸载数据盘,而是选择了一个最简单、最可控、最适合教学的办法:
直接把容器文件权限改坏。
故障注入前,容器文件权限是:
-rw------- 1 db2inst1 db2iadm1 4096000 4月 8 10:59 /DB2_DATA/TESTDB/ts4/ts4_01.dat然后执行:
chmod 000 /DB2_DATA/TESTDB/ts4/ts4_01.dat改完后,权限变成:
---------- 1 db2inst1 db2iadm1 4096000 4月 8 10:59 /DB2_DATA/TESTDB/ts4/ts4_01.dat这一步的本质就是:
文件还在,但 DB2 实例用户已经没有任何读写权限。
相比直接删文件,这种做法更适合实验,因为:
- 故障现象明显
- 根因清晰
- 恢复简单可逆
六、故障发生后,业务层先出现了什么现象
权限改坏后,我没有先去看管理命令,而是先从业务访问层去观察。
1. 查询失败
执行:
db2 "select count(*) from T5"真实返回:
1
-----------
SQL0290N Table space access is not allowed. SQLSTATE=550392. 写入也失败
执行:
db2 "insert into T5 values (2, repeat('P',3000))"真实返回:
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0290N Table space access is not allowed. SQLSTATE=55039这一步很重要,因为它说明:
并不是只有写入失败,连查询也已经失败了。
而且两条 SQL 都指向同一个核心报错:
SQL0290N Table space access is not allowed
这已经可以初步判断:
问题不是表 T5 自己坏了,而是 T5 所在的表空间 TS4 已经不允许访问。
七、再看管理视角:表空间和容器状态发生了什么变化
接下来我再回到管理视角,继续看表空间和容器状态。
1. 表空间状态变成 Offline
执行 db2 list tablespaces show detail 后,TS4 变成了:
Tablespace ID = 8
Name = TS4
Type = Database managed space
Contents = All permanent data. Regular table space.
State = 0x4000
Detailed explanation:
Offline这一步非常关键,因为它说明:
DB2 已经把 TS4 从正常状态打成了 Offline。
2. 容器状态变成不可访问
继续执行:
db2 list tablespace containers for 8 show detail真实输出如下:
Tablespace Containers for Tablespace 8
Container ID = 0
Name = /DB2_DATA/TESTDB/ts4/ts4_01.dat
Type = File
Total pages = 1000
Useable pages = 960
Accessible = No这里最关键的一行就是:
Accessible = No
到这里,业务层和管理层的现象已经可以完全对上:
- 业务层:
SQL0290N - 表空间层:
Offline - 容器层:
Accessible = No
也就是说,这不是单纯的 SQL 报错,而是:
底层容器文件不可访问 -> 表空间下线 -> 业务无法访问
八、诊断日志里 DB2 是怎么写这个故障的
这一步是整个实验里最有价值的排障证据。
查看 db2diag.log 后,可以看到非常明确的系统级报错:
FUNCTION: DB2 Common, OSSe, ossErrorIOAnalysis, probe:100
CALLED : OS, -, open OSERR: EACCES (13)
Target file = /DB2_DATA/TESTDB/ts4/ts4_01.dat这表示:
- DB2 在尝试
open这个文件时 - 操作系统返回了
EACCES (13) - 也就是典型的权限拒绝
后面日志里还继续给出了权限分析:
Information of each subdirectory leading up to the first inaccessible one is shown in the format below :
<UID>:<GID>:<permissions> (subdirectories)
101:901:755 (DB2_DATA)
101:901:755 (TESTDB)
101:901:755 (ts4)
101:901:0 (ts4_01.dat)这一段其实已经把问题说透了:
- 上层目录都没问题
- 真正出问题的是
ts4_01.dat - 它的权限已经被改成了
0
这时再往下看 DB2 自己的内部错误码,又能看到:
SQLO_ACCD "Access Denied"
SQLB_CONTAINER_NOT_ACCESSIBLE
ADM6081W The table space "TS4" (ID "8") is in the OFFLINE state这就把整个故障链彻底闭环了:
- OS 层拒绝访问文件
- DB2 无法打开容器
- 容器被判定为
not accessible - 表空间进入
Offline - 业务访问报
SQL0290N
九、恢复动作其实很简单
既然根因就是权限被改坏,那恢复动作也应该非常直接:
chmod 600 /DB2_DATA/TESTDB/ts4/ts4_01.dat恢复后再看文件权限:
-rw------- 1 db2inst1 db2iadm1 4096000 4月 8 10:59 /DB2_DATA/TESTDB/ts4/ts4_01.dat这一步恢复的是:
让 db2inst1 重新具备正常读写这个容器文件的权限。
十、恢复权限后,表空间会不会自动回来
这一步很有学习价值,因为很多人会下意识以为:
是不是还要执行额外的表空间恢复命令?
在这次实验环境里,结果是:
不需要。
权限恢复后,再回到 db2inst1 下检查,发现 TS4 已经自动恢复正常。
1. 表空间恢复为 Normal
Tablespace ID = 8
Name = TS4
Type = Database managed space
Contents = All permanent data. Regular table space.
State = 0x0000
Detailed explanation:
Normal
Total pages = 1000
Useable pages = 960
Used pages = 160
Free pages = 800
High water mark (pages) = 160
Page size (bytes) = 4096
Extent size (pages) = 32
Prefetch size (pages) = 32
Number of containers = 12. 容器恢复为可访问
Tablespace Containers for Tablespace 8
Container ID = 0
Name = /DB2_DATA/TESTDB/ts4/ts4_01.dat
Type = File
Total pages = 1000
Useable pages = 960
Accessible = Yes3. 查询恢复正常
db2 "select count(*) from T5"
1
-----------
1
1 record(s) selected.这说明在当前这套环境里:
只要底层权限修复正确,TS4 会自动从 Offline 回到 Normal。
十一、最后再验证一次写入恢复
为了确保不是“只能查,不能写”,我又继续做了一次写入验证。
执行:
db2 "insert into T5 values (2, repeat('R',3000))"
db2 "select count(*) from T5"真实结果:
DB20000I The SQL command completed successfully.然后再查:
1
-----------
2
1 record(s) selected.这说明恢复已经彻底闭环:
- 查询恢复
- 写入恢复
- 表空间恢复
- 容器恢复
十二、这次实验到底证明了什么
到这里,这次实验实际上已经跑出了一个非常标准的运维故障模型:
1. 容器文件权限异常,会直接影响表空间可用性
即使文件还在,只要 DB2 无法访问它,表空间照样会出问题。
2. 业务报错不一定是 SQL 本身有问题
这次 select 和 insert 都报了:
SQL0290N Table space access is not allowed
真正的根因并不在 SQL 语句本身,而是在底层容器不可访问。
3. list tablespace containers 是非常关键的排障命令
因为它能直接告诉你:
- 容器文件是谁
- 容器现在能不能访问
这比一上来盲猜问题快得多。
4. db2diag.log 能把根因打到文件权限级别
这次日志里明确给出了:
EACCES (13)Access DeniedSQLB_CONTAINER_NOT_ACCESSIBLE- 文件权限链分析
这就是非常标准的“证据型排障”。
5. 在这套环境里,修复权限后表空间会自动恢复
这次不需要额外执行复杂恢复命令,权限修好以后,TS4 自动从 Offline 回到了 Normal。
这一点也很值得记下来,因为它能帮助你判断:
哪些场景只要修底层资源就够,哪些场景还需要进一步的 DB2 恢复动作。
十三、实验结束后的收尾
这次实验结束后,最简单的收尾动作是:
db2 "drop table T5"
db2 terminate如果想把环境彻底清理干净,也可以进一步执行:
db2 connect to TESTDB
db2 "drop tablespace TS4"
db2 terminate但如果后面还想继续做“容器路径异常”实验,保留 TS4 会更方便。
十四、把这篇文章压缩成三句话
最后把这次实验压缩成三句话:
- 容器文件权限异常,会直接导致表空间
Offline。 - 业务层常见表现是
SQL0290N,管理层常见表现是Accessible = No。 - 修复容器文件权限后,表空间和业务都可以恢复。
十五、到这里,表空间这条线已经从“容量”走到了“可访问性”
前几篇主要讲的是:
- 空间会不会满
- 满了怎么扩
而这篇开始进入另外一条非常实战的线:
- 空间本身没问题
- 但容器文件不可访问
这类问题在生产里并不少见,尤其是:
- 权限被误改
- 挂载异常
- 存储切换后属主不对
- 运维脚本误操作
所以这篇实验的价值很高,因为它让你真正看到:
“表空间不可访问” 这件事到底是怎么从底层文件一直传导到业务 SQL 报错的。
十六、下一篇最自然写什么
如果沿着这条线继续往下走,下一篇最自然的方向就是:
【DB2 数据库】07 模拟故障排查系列:表空间容器不可访问(路径异常)实验
因为当前我们已经验证了:
- 权限异常会让容器不可访问
那下一步最值得继续验证的,就是:
- 文件路径本身失效
- 文件被挪走
- 路径存在但容器不在
这样“容器不可访问”这一类故障,就会从权限问题扩展到路径问题,整个排障知识链也会更完整。