DB2 表空间扩容
文章目录11 节
这篇文章记录一次 DB2 9.7 DMS 表空间手工扩容实验:我先把 ASSP_CLOB 写满,稳定复现 SQL0289N,再对已有容器执行 EXTEND 50M,最后重试原失败写入,确认数据库恢复正常。
本文已对数据库名、主机名和存储目录做脱敏处理,但保留 DB2 版本、表空间名、页数、错误码和实测结果。文中的
LABDB和容器路径必须按实际环境替换。
一、实验环境
| 项目 | 实验值 |
|---|---|
| 操作系统 | SUSE Linux Enterprise Server 12 SP5 |
| DB2 版本 | DB2 v9.7.0.6 Fix Pack 6 |
| 实例用户 | db2inst1 |
| 数据库 | LABDB(脱敏名) |
| 目标表空间 | ASSP_CLOB |
| 表空间类型 | DMS / LARGE |
| 页大小 | 4 KiB |
| 容器数量 | 1 |
| 自动扩容 | AUTORESIZE=NO |
| 扩容方式 | 手工 EXTEND |
这次实验中,ASSP_CLOB 是独立的实验表空间,只存放测试表的 CLOB 数据。不应在与其他业务表共用的生产表空间中模仿“写满”步骤。
二、先分清文件系统和 DB2 表空间
DB2 容器扩容前,先确认底层文件系统是否有足够剩余空间:
- 如果文件系统已经有足够空间,可以直接扩展 DB2 容器。
- 如果文件系统也已经接近用满,必须先完成虚拟磁盘、LVM 和文件系统扩容。
- 不能因为 DB2 表空间不足,就默认必须新增硬盘。
风险等级:INFO(只读)
作用: 核对
/db2data所在文件系统、挂载点和块设备。 注意事项: 这些命令不修改存储。如果剩余空间不足,应另行制定底层扩容和回退方案,不要直接复制pvcreate或lvextend -l +100%FREE一类高风险命令。
df -h /db2data
findmnt /db2data
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,WWN,SERIAL本次实验前,/db2data 仍有约 85 GiB 可用,因此不需要修改 LVM 或文件系统。
三、查询表空间 ID
风险等级:INFO(只读)
作用: 连接目标数据库,查找
ASSP_CLOB的表空间 ID、总页数、可用页数、页大小和当前状态。 需替换:LABDB是脱敏后的数据库别名。
db2 connect to LABDB
db2 list tablespaces show detail本次实验查到:
Tablespace ID = 6
Name = ASSP_CLOB
Type = Database managed space
Contents = All permanent data. Large table space.
Page size (bytes) = 4096
Number of containers = 1表空间 ID 由数据库当前目录决定,不能在其他数据库中永久假定为 6。
四、由 ID 查询真实容器路径
风险等级:INFO(只读)
作用: 查看表空间 6 的容器 ID、真实路径、总页数、可用页数和可访问状态。 注意事项: 后续
EXTEND必须使用这里返回的已有容器路径。
db2 list tablespace containers for 6 show detail扩容前容器状态如下,其中路径已脱敏:
Container ID = 0
Name = /db2data/labdb/tablespaces/assp_clob_01
Type = File
Total pages = 25600
Useable pages = 25568
Accessible = Yes25600 × 4 KiB = 100 MiB,这就是扩容前的容器大小。
五、用可分配页面计算使用率
风险等级:INFO(只读)
作用: 查询各表空间的总容量、可分配容量、已用容量、剩余容量和真实使用率。 计算边界:
TBSP_TOTAL_PAGES包含管理页,因此使用率以TBSP_USABLE_PAGES为分母。1024.0用于保留 MiB 小数,避免整数除法截断。
db2 "
SELECT
SUBSTR(TBSP_NAME, 1, 20) AS NAME,
TBSP_TYPE AS TYPE,
DECIMAL(BIGINT(TBSP_TOTAL_PAGES) * TBSP_PAGE_SIZE / 1024.0 / 1024.0, 12, 2) AS TOTAL_MIB,
DECIMAL(BIGINT(TBSP_USABLE_PAGES) * TBSP_PAGE_SIZE / 1024.0 / 1024.0, 12, 2) AS USABLE_MIB,
DECIMAL(BIGINT(TBSP_USED_PAGES) * TBSP_PAGE_SIZE / 1024.0 / 1024.0, 12, 2) AS USED_MIB,
DECIMAL(BIGINT(TBSP_FREE_PAGES) * TBSP_PAGE_SIZE / 1024.0 / 1024.0, 12, 2) AS FREE_MIB,
DECIMAL(TBSP_USED_PAGES * 100.0 / NULLIF(TBSP_USABLE_PAGES, 0), 5, 2) AS USED_PCT,
TBSP_AUTO_RESIZE_ENABLED AS AUTO_RESIZE
FROM SYSIBMADM.TBSP_UTILIZATION
ORDER BY USED_PCT DESC
"六、把 ASSP_CLOB 写满并复现 SQL0289N
实验表 DB2INST1.TSX_CLOB_FILL 的普通数据、索引和 CLOB 分别放在 ASSP、ASSP_INDEX 和 ASSP_CLOB。扩容前,该表已有 1600 行测试数据,我从第 17 批继续填充。
风险等级:DANGER(故意耗尽表空间)
作用: 每批插入 100 个 32 KB CLOB,直到
ASSP_CLOB无法分配新页面。 执行对象: 仅限独立实验库中的DB2INST1.TSX_CLOB_FILL。 不可直接用于生产: 如果其他表也使用ASSP_CLOB,此操作会导致其他写入同样失败。 恢复路径: 准备足够的文件系统空间并事先确认容器路径,出现SQL0289N后通过EXTEND增加容量。
batch=17
while [ "$batch" -le 40 ]; do
db2 "
INSERT INTO DB2INST1.TSX_CLOB_FILL (BATCH_NO, PAYLOAD)
WITH R(N) AS (
VALUES 1
UNION ALL
SELECT N + 1 FROM R WHERE N < 100
)
SELECT
$batch,
REPEAT(CAST('X' AS CLOB(32K)), 32000)
FROM R
" || break
batch=$((batch + 1))
done第 17 至第 31 批成功提交,第 32 批失败:
SQL0289N Unable to allocate new pages in table space "ASSP_CLOB".
SQLSTATE=57011失败后的实测状态:
成功行数 = 3100
成功批次 = 1 - 31
CLOB 总长度 = 99200000 字节
TBSP_TOTAL_SIZE = 102400 KiB
TBSP_USED_SIZE = 102272 KiB
TBSP_FREE_SIZE = 0 KiB
使用率 = 100.00%
AUTORESIZE = 0第 32 批是一条原子 SQL 语句,失败时没有留下部分行。
七、手工 EXTEND 现有容器
风险等级:CAUTION(持久扩大 DMS 容器)
作用: 对
ASSP_CLOB的已有文件容器再增加 50 MiB。 执行前检查: 重新执行df -h、LIST TABLESPACES SHOW DETAIL和LIST TABLESPACE CONTAINERS ... SHOW DETAIL,确认文件系统容量、表空间 ID 和容器路径。 参数含义:50M表示“在当前容量上再增加 50 MiB”,不是“调整到 50 MiB”。 影响: 命令会持久占用底层文件系统空间,不应在未评估收缩和回退方案时重复执行。 完成验证: 扩容后核对容器页数、文件大小、剩余空间和AUTORESIZE。
db2 "
ALTER TABLESPACE ASSP_CLOB
EXTEND (
FILE '/db2data/labdb/tablespaces/assp_clob_01' 50M
)
"这个容器的页大小是 4 KiB,因此下面两种写法的增量等价:
12800 页 × 4 KiB = 50 MiB
EXTEND ... 12800
EXTEND ... 50M扩容后查询到:
Container ID = 0
Name = /db2data/labdb/tablespaces/assp_clob_01
Total pages = 38400
Useable pages = 38368
Accessible = Yes
容器文件大小 = 157286400 字节
表空间总容量 = 150 MiB
表空间可用容量 = 149.875 MiB
剩余容量 = 50 MiB
AUTORESIZE = 0容器从 100 MiB 增加到 150 MiB,容器数量仍然是 1,也没有开启自动扩容。
八、重试失败批次
风险等级:CAUTION(继续写入实验数据)
作用: 重新执行原来因空间不足失败的第 32 批,用实际写入验证扩容是否恢复业务能力。 执行对象: 仅限
DB2INST1.TSX_CLOB_FILL。
db2 "
INSERT INTO DB2INST1.TSX_CLOB_FILL (BATCH_NO, PAYLOAD)
WITH R(N) AS (
VALUES 1
UNION ALL
SELECT N + 1 FROM R WHERE N < 100
)
SELECT
32,
REPEAT(CAST('X' AS CLOB(32K)), 32000)
FROM R
"这次写入成功:
DB20000I The SQL command completed successfully.
总行数 = 3200
最大批次 = 32
CLOB 总长度 = 102400000 字节
表空间使用率 = 67.22%
剩余容量 = 50304 KiB
AUTORESIZE = 0这证明本次故障确实由 ASSP_CLOB 可分配页面耗尽引起,手工 EXTEND 后,原失败写入可以正常完成。
九、EXTEND 和 ADD 不是一回事
| 对比项 | EXTEND | ADD |
|---|---|---|
| 操作对象 | 已有容器 | 新容器 |
| 容器数量 | 不变 | 增加 |
| 原容器文件 | 变大 | 不变 |
| 新文件 | 不创建 | 创建 |
| 数据重平衡 | 通常不需要 | 可能触发 rebalance |
| 适用场景 | 原路径有足够空间 | 需要新路径或新存储单元 |
EXTEND 使用的必须是现有容器路径。如果希望新增另一个容器,应使用 ADD,不能在 EXTEND 中填写一个尚未登记的新路径。
十、生产环境操作要点
- 先查表空间 ID,再根据 ID 查容器,不要凭经验猜路径。
- 同时查表空间剩余页和底层文件系统剩余容量。
- 确认容器是 DMS
FILE,不要把 SMS、自动存储或其他节点的命令直接套用过来。 EXTEND 50M是增加 50 MiB,重复执行会继续累加。- 扩容后不只查页数,还要执行实际写入验证。
- 手工管理环境要复查
TBSP_AUTO_RESIZE_ENABLED=0,避免把自动扩容当成手工操作的结果。 - 不要通过删除容器文件回退表空间扩容,这会破坏数据库。
总结
这次实验完整验证了一条可复现的故障与恢复链路:
ASSP_CLOB 可分配页耗尽
↓
SQL0289N / SQLSTATE=57011
↓
确认表空间 ID 和已有容器路径
↓
EXTEND 50M:100 MiB → 150 MiB
↓
重试第 32 批写入成功
↓
AUTORESIZE 仍为 0关键不是记住一条 ALTER TABLESPACE,而是形成“文件系统预检、表空间定位、容器路径核对、增量含义确认、扩容后真实写入验证”的完整操作顺序。