【DB2 数据库】05 模拟故障排查系列:表空间自动扩容(AUTORESIZE)实验
一、这篇文章要解决什么问题
前面的实验里,我已经分别验证了两种手工扩容方式:
ADDEXTEND
但在真实运维里,除了手工扩容,还经常会碰到另外一个问题:
表空间能不能自己长大?
这篇文章要解决的就是这个问题。
这次我单独创建了一个新的小表空间 TS3,专门验证下面 3 件事:
- 开启
AUTORESIZE后,表空间是否真的会自动扩容 - 自动扩容时,DB2 是新增容器,还是把原来的容器直接做大
- 到了
MAXSIZE上限后,表空间会不会再次被打满
如果说上一篇文章解决的是:
手工扩容到底怎么做
那么这一篇解决的就是:
自动扩容到底是怎么工作的
二、实验环境
- 操作系统:
SUSE Linux Enterprise Server 12 SP5 - DB2 版本:
DB2 v9.7.0.6 Fix Pack 6 - 实例:
db2inst1 - 数据库:
TESTDB - 实验表空间:
TS3 - 容器文件:
/DB2_DATA/TESTDB/ts3/ts3_01.dat - 测试表:
T4
这次实验故意不再复用已经做过很多手工动作的 TS2,而是单独做一个新的 TS3,这样现象会更干净,结论也更适合写成一篇独立文章。
三、为什么这篇要单独写
很多人第一次接触表空间扩容时,脑子里容易把这几件事混在一起:
ADDEXTENDAUTORESIZE
但这三者虽然都和“空间变大”有关,本质上并不是一回事。
前两篇已经把手工扩容讲清楚了,这一篇就单独把 AUTORESIZE 拆出来讲。
这样整条知识线就会更完整:
- 先构造表空间打满
- 再通过手工扩容恢复
- 再对比不同扩容方式
- 最后验证自动扩容的真实表现
四、实验设计思路
这次实验的设计很简单,但很有代表性。
1. 先创建一个很小的表空间
让 TS3 初始只有 1000 pages,这样后面很容易被写满。
2. 开启自动扩容
给 TS3 配置:
AUTORESIZE YESINCREASESIZE 100 PERCENTMAXSIZE 8000 K
这意味着:
- 初始容量比较小
- 空间不够时,它会按当前大小的
100%自动增长 - 但自动增长不是无限的,会受到
MAXSIZE限制
3. 再用大字段测试表持续插数
我创建了表 T4(id int, c1 varchar(3000)),明确放进 TS3,再持续插入大字段数据。
这样做的目的是让表空间容量变化变得非常明显。
五、实验开始前的 TS3 状态
在真正大量插入数据之前,我先确认了 TS3 的初始状态。
当时 TS3 的关键信息如下:
Tablespace ID = 7
Name = TS3
Type = Database managed space
Contents = All permanent data. Regular table space.
State = 0x0000
Detailed explanation:
Normal
Total pages = 1000
Useable pages = 960
Used pages = 96
Free pages = 864
High water mark (pages) = 96
Page size (bytes) = 4096
Extent size (pages) = 32
Prefetch size (pages) = 32
Number of containers = 1从这里可以确认:
TS3初始总页数确实只有1000- 当前只有
1个容器 - 这是一个非常适合观察自动扩容的小表空间
六、第一阶段:先验证自动扩容确实发生了
接下来,我没有直接插到极限,而是先做第一阶段验证:
如果没有自动扩容,理论上它应该很快失败;如果还能继续写,就说明扩容已经发生。
插入到第一阶段后,我先查看 T4 的记录数:
db2 "select count(*) from T4"
1
-----------
1200
1 record(s) selected.1200 条能成功写入,这已经说明一件事:
TS3 不可能还停留在最初那 1000 页的状态。`
也就是说,AUTORESIZE 确实已经发生了作用。
七、第二阶段:继续插到再次打满
为了验证自动扩容是不是“无限生效”,我继续向 T4 插入数据。
继续插入后,记录数最终变成:
db2 "select count(*) from T4"
1
-----------
1823
1 record(s) selected.然后再次查看 TS3 状态,得到的真实结果如下:
Tablespace ID = 7
Name = TS3
Type = Database managed space
Contents = All permanent data. Regular table space.
State = 0x0000
Detailed explanation:
Normal
Total pages = 1984
Useable pages = 1952
Used pages = 1952
Free pages = 0
High water mark (pages) = 1952
Page size (bytes) = 4096
Extent size (pages) = 32
Prefetch size (pages) = 32
Number of containers = 1这一组结果非常关键,因为它一次性说明了两件事:
1. 自动扩容确实发生过
Total pages 已经从最初的 1000 增长到了 1984。
这说明表空间容量已经不是最初那一小块了。
2. 它后来又被打满了
现在已经出现:
Used pages = 1952Free pages = 0
这说明:
自动扩容虽然发生了,但最后空间还是被吃光了。
八、为什么看到的是 1984,而不是理论上的 2000
实验设计时,我最初按“页大小 4KB、最大 8000K”去估算,理论上很容易先想到:
8000K ÷ 4K = 2000 pages
但实际跑出来看到的是:
Total pages = 1984Useable pages = 1952
这并不表示实验失败,反而是很有价值的现场结论。
因为在 DB2 9.7 的 DMS 表空间里,最终看到的页数并不一定会是我们手工估算出来的那个“整值”,它会受到以下因素影响:
- 表空间管理页开销
- extent 对齐
- DB2 内部页分配方式
所以这次实验里最应该记住的,不是“必须正好看到 2000”,而是:
- 它确实从
1000长大到了更大的值 - 它确实没有新增容器
- 它最终还是再次打满
这才是 AUTORESIZE 实验最重要的结论。
九、自动扩容后,容器到底发生了什么
很多人看到“表空间变大了”,会下意识以为:
是不是自动帮我新增了一个容器文件?
所以这一步一定要看容器详情。
实验时执行:
db2 list tablespace containers for 7 show detail真实输出如下:
Tablespace Containers for Tablespace 7
Container ID = 0
Name = /DB2_DATA/TESTDB/ts3/ts3_01.dat
Type = File
Total pages = 1984
Useable pages = 1952
Accessible = Yes这一段输出特别有说服力,因为它把最关键的问题说明白了:
- 仍然只有
1个容器 - 容器名还是原来的
/DB2_DATA/TESTDB/ts3/ts3_01.dat - 变化的是这个容器本身的页数,从初始的小容量长大了
也就是说:
AUTORESIZE 的表现更接近“把原来的容器自动做大”,而不是“自动给你 ADD 一个新容器”。`
这正是它和 ADD 的核心区别之一。
十、这次实验到底证明了什么
到这里,这次实验已经把 AUTORESIZE 最重要的三层结论都跑出来了。
1. AUTORESIZE 可以自动扩容
如果没有自动扩容,T4 不可能顺利插到 1200 条,更不可能继续到 1823 条。
2. AUTORESIZE 不会新增容器数量
表空间从头到尾:
Number of containers = 1
容器详情里也始终只有:
ts3_01.dat
3. AUTORESIZE 不是无限扩容
当达到上限后,表空间还是会再次打满。
这次最直接的证据就是:
Free pages = 0
所以在实际运维里,千万不要把 AUTORESIZE 理解成:
开了以后就永远不会再满。
真正正确的理解应该是:
AUTORESIZE 只是按规则自动扩,仍然受增长策略和 MAXSIZE 约束。
十一、实验结束后的收尾动作
为了让环境先回到可控状态,我在实验结束后执行了:
db2 "drop table T4"
db2 terminate执行结果:
DB20000I The SQL command completed successfully.
DB20000I The TERMINATE command completed successfully.这样做的意义是:
- 删除测试表,结束本轮数据写入实验
- 终止当前会话,避免把实验连接一直挂着
如果后面希望把环境彻底还原得更干净,还可以再单独决定是否删除 TS3 表空间本身。
十二、这篇实验里最值得记住的 4 个观察点
这次实验里,我认为最值得初学者反复记住的不是命令本身,而是下面 4 个观察点:
1. 看扩容前总页数
- 初始:
Total pages = 1000
2. 看扩容后总页数
- 自动扩容后:
Total pages = 1984
3. 看容器数量有没有变化
- 整个过程中:
Number of containers = 1
4. 看最终是否再次打满
- 最终:
Free pages = 0
这 4 个点连起来,才是真正完整的运维判断链。
十三、把这篇文章压缩成三句话
最后把这次实验压缩成三句话:
AUTORESIZE能让表空间自动变大。AUTORESIZE变大的是原来的容器,不是自动新增新容器。AUTORESIZE不是无限扩容,到达上限后表空间仍然会再次打满。
十四、到这里,表空间扩容这条线已经基本完整了
写到这里,其实关于表空间容量故障,已经串起了一条非常完整的学习路径:
- 构造表空间打满
- 观察打满后的状态
- 用
ADD恢复 - 区分
ADD和EXTEND - 验证
AUTORESIZE
这一套做下来,基本已经把日常运维里最常见的表空间容量问题讲清楚了。
十五、下一篇最自然写什么
如果继续沿着“运维故障排查”这条线往下写,下一篇最自然的方向有两个:
- 继续写
MAXSIZE调整与再次恢复 - 转去做“容器路径异常 / 权限异常”故障演练
如果更偏实战,我会更推荐下一篇写:
【DB2 数据库】06 模拟故障排查系列:表空间容器不可访问(路径/权限异常)实验
因为做到这里,读者已经知道:
- 表空间怎么满
- 怎么扩
- 自动扩容怎么工作
下一步就很适合进入:
空间没问题,但容器文件本身出问题时,DB2 会怎样报错,又该怎么排。