祥积宫 无限进步

【DB2 数据库】04 模拟故障排查系列:表空间扩容方式对比(ADD、EXTEND)

一、这篇文章要解决什么问题

在前两篇关于 TS2 的实验里,我已经分别完成了:

  • 表空间打满
  • 通过 ADD 新容器恢复

但在实际运维中,“表空间扩容”并不只有一种方式。

最常见、也最容易混淆的两种方式就是:

  • ADD
  • EXTEND

这篇文章的目标,就是基于真实实验,把这两种扩容方式彻底区分开:

  • ADD 到底加了什么
  • EXTEND 到底改了什么
  • 两者在容器数量、文件数量、总页数上的表现有什么差异
  • 什么时候更适合用 ADD
  • 什么时候更适合用 EXTEND

二、实验环境

  • 操作系统:SUSE Linux Enterprise Server 12 SP5
  • DB2 版本:DB2 v9.7.0.6 Fix Pack 6
  • 实例:db2inst1
  • 数据库:TESTDB
  • 实验表空间:TS2
  • 容器目录:/DB2_DATA/TESTDB/ts2/

本篇实验完全建立在前面系列文章的基础上:

  • TS2 已经存在
  • T3 已经落在 TS2
  • TS2 之前已经通过 ADD 做过一次扩容

所以这篇文章既有前情基础,也有非常直观的对比条件。

三、先说结论:ADD 和 EXTEND 的本质区别

在正式进入实验前,先把最核心的一句话说出来:

ADD 是新增容器,EXTEND 是扩大已有容器。

再展开一点就是:

  • ADD

    • 表空间里会多一个新的容器文件
    • 容器数量增加
    • 总容量增加
  • EXTEND

    • 不会新增容器文件
    • 只是把现有容器做大
    • 容器数量不变,但总容量增加

也就是说,两者都能“扩容”,但底层动作完全不同。

四、先回顾前一篇里的 ADD 扩容

在上一篇实验中,我使用的是:

db2 "alter tablespace TS2 add (file '/DB2_DATA/TESTDB/ts2/ts2_02.dat' 2000)"
# 给 TS2 新增第二个容器

执行这个命令之后,TS2 发生了两个非常典型的变化:

1. 容器数增加

原来只有:

  • ts2_01.dat

扩容后变成:

  • ts2_01.dat
  • ts2_02.dat

2. 表空间总页数增加

实验中,TS2 扩容后的状态如下:

Tablespace ID                        = 5
Name                                 = TS2
Type                                 = Database managed space
Contents                             = All permanent data. Regular table space.
State                                = 0x0000
  Detailed explanation:
    Normal
Total pages                          = 4000
Useable pages                        = 3904
Used pages                           = 1952
Free pages                           = 1952
High water mark (pages)              = 1952
Page size (bytes)                    = 4096
Extent size (pages)                  = 32
Prefetch size (pages)                = 64
Number of containers                 = 2

这里最关键的是:

  • Total pages = 4000
  • Number of containers = 2

这就是 ADD 的典型特征:

通过增加新容器文件,把表空间容量扩出来。

五、为什么还要再做 EXTEND 实验

虽然通过 ADD 已经能解决“空间不够”的问题,但它并不是唯一答案。

在一些场景下,运维并不想新增一个新容器文件,而是希望:

  • 原来路径不变
  • 原来文件不变
  • 只是把某个已有容器直接变大

这时就要用到:

EXTEND

相比 ADD,它更像是:

不是多盖一间房,而是把原来的房间扩建。

六、EXTEND 实验前的起点状态

在开始 EXTEND 实验前,我先确认了 TS2 的当前状态。

1. 当前表空间整体状态

实验开始前,TS2 的状态是:

Tablespace ID                        = 5
Name                                 = TS2
Type                                 = Database managed space
Contents                             = All permanent data. Regular table space.
State                                = 0x0000
  Detailed explanation:
    Normal
Total pages                          = 4000
Useable pages                        = 3904
Used pages                           = 1984
Free pages                           = 1920
High water mark (pages)              = 1984
Page size (bytes)                    = 4096
Extent size (pages)                  = 32
Prefetch size (pages)                = 64
Number of containers                 = 2

2. 当前容器状态

实验开始前,TS2 已经有两个容器:

db2 list tablespace containers for 5 show detail
# 查看 TS2 当前容器

当时两个容器分别是:

  • /DB2_DATA/TESTDB/ts2/ts2_01.dat
  • /DB2_DATA/TESTDB/ts2/ts2_02.dat

它们的 Total pages 当时都还是 2000

这正好非常适合用来做 EXTEND(FILE ...) 实验。

七、为什么这次不做 EXTEND(ALL),而是做 EXTEND(FILE)

理论上,EXTEND 也可以有不同写法。

例如:

  • EXTEND (ALL ...)
  • EXTEND (FILE '...' ...)

这次我故意选择的是:

EXTEND(FILE ...)

原因很简单:

  • 它的教学效果最好
  • 只会改一个容器
  • 对比最直观

这样实验完成后,我们就能清楚看到:

  • 第一个容器变大了
  • 第二个容器没变
  • 容器数量没有变

这比 EXTEND(ALL ...) 更容易讲清楚底层行为。

八、页数和容量是怎么换算的

在正式执行 EXTEND(FILE ...) 之前,还要先解决一个非常关键的问题:

页数和容量到底怎么换算?

换算公式其实很简单:

容量 = 页数 × 页大小

而在这次实验里,TS2 的页大小是:

  • Page size = 4096 bytes
  • 也就是 4KB

所以在当前环境里,可以直接记:

1 页 = 4KB

例如:

  • 500 页 = 500 × 4KB = 2000KB
  • 1024 页 = 1024 × 4KB = 4096KB = 4MB

这个换算关系后面在 EXTEND(FILE ...) 中非常实用。

九、只扩一个容器:EXTEND(FILE …) 实验

这次实验中,我执行的是:

db2 "alter tablespace TS2 extend (file '/DB2_DATA/TESTDB/ts2/ts2_01.dat' 4096K)"
# 只扩 TS2 的第一个容器
# 扩 4096K,也就是 4MB

为什么选 4096K

因为在当前环境里:

  • 页大小 = 4KB
  • 4096K ÷ 4K = 1024 pages

也就是说,这条命令本质上是:

只给 ts2_01.dat 增加 1024 页。

十、EXTEND 后,预期应该看到什么

如果这个实验成功,那么理论上应该出现以下现象:

1. 容器数不变

Number of containers 仍然应该是:

  • 2

2. 只改第一个容器

第一个容器:

  • ts2_01.dat
  • 2000 -> 3024 pages

第二个容器:

  • ts2_02.dat
  • 仍然保持 2000 pages

3. 表空间总页数增加

总页数应该从:

  • 4000

增加到:

  • 5024

这正是 EXTEND(FILE ...) 最有代表性的特征。

十一、这次实验成功验证了什么

实验结果完全符合预期,也就是说,这次已经成功验证了下面三件事:

1. EXTEND(FILE ...) 不会新增容器

它只是扩大已有容器。

2. EXTEND(FILE ...) 可以只针对单个指定容器生效

不是所有容器都会一起长大。

3. 表空间总容量会增加

虽然没有新增文件,但原容器变大后,表空间的总页数依然会增加。

十二、和 ADD 放在一起看,差异就很清楚了

ADDEXTEND(FILE ...) 摆在一起,就特别好理解:

ADD

db2 "alter tablespace TS2 add (file '/DB2_DATA/TESTDB/ts2/ts2_02.dat' 2000)"

特点:

  • 多一个新容器
  • 多一个新文件
  • 容器数增加

EXTEND(FILE …)

db2 "alter tablespace TS2 extend (file '/DB2_DATA/TESTDB/ts2/ts2_01.dat' 4096K)"

特点:

  • 不增加文件数量
  • 只让已有文件变大
  • 容器数不变

这两种方式虽然都叫“扩容”,但运维上的含义完全不一样。

十三、那什么时候适合用 ADD

一般来说,下面这些情况更适合用 ADD

  • 想新增一块盘或新路径
  • 想把扩容空间放到新的挂载点上
  • 希望多个容器一起分担数据
  • 想保留原容器不动,只增加新空间

ADD 更像是:

往现有表空间里新接入一个新的存储单元。

十四、那什么时候适合用 EXTEND

下面这些情况更适合用 EXTEND

  • 现有路径还有空间
  • 不想增加新文件数量
  • 只想把已有容器做大
  • 想精确控制某一个容器的大小

EXTEND(FILE ...) 更像是:

原地扩建,不新增新文件。

十五、这一篇最重要的结论

这篇文章最重要的结论,可以压缩成三句话:

  1. ADD 是新增容器,EXTEND 是扩大已有容器。
  2. EXTEND(FILE ...) 只影响指定容器,不会新增文件。
  3. 两者都会让表空间变大,但底层表现完全不同。

十六、到这里为止,这个系列已经讲清了什么

写到这里,关于 TS2 这个实验对象,其实已经把很关键的一条运维主线讲出来了:

  1. 先构造表空间打满
  2. 再看删表后为什么空间回 DB2 不回 OS
  3. 再通过 ADD 做恢复
  4. 再进一步区分 ADDEXTEND

这套过程非常适合写成系列,因为它不只是给命令,而是把运维脑子里真正要分清的概念一点点建立起来。

十七、下一篇最自然写什么

到这一步,下一篇最自然的方向就是:

AUTORESIZE

也就是:

【DB2 数据库】05 模拟故障排查系列:表空间自动扩容(AUTORESIZE)实验

这样下一篇就可以把第三种扩容思路补齐:

  • ADD
  • EXTEND
  • AUTORESIZE

整个表空间扩容体系就完整了。

Linux 存储