Home

DB2 表空间扩容

这篇文章记录 DB2 服务器表空间所在磁盘容量不足时,一种常见的扩容方式。整体思路是先在虚拟化平台新增硬盘,再在 Linux 中完成 LVM 和文件系统扩容,最后让 DB2 使用到新增空间。

处理思路

这类扩容不要只盯着 DB2 本身,而是要分两层处理:

  • 先扩底层存储,包括虚拟磁盘、LVM 和文件系统。
  • 再扩 DB2 表空间容器,让数据库真正使用到新增空间。

只有这两层都完成,表空间扩容才算真正落地。

在虚拟化平台添加硬盘

  1. 在您的VMware vSphere、Proxmox、Hyper-V等管理界面中,为虚拟机db2server02添加一块新的SCSI硬盘(例如:100GB)。
  2. 确保硬盘控制器类型为SCSI(推荐使用LSI Logic SAS或PVSCSI)

在 Linux 中整合新硬盘

识别新硬盘

登录系统后,首先确认系统是否识别到了新硬盘。

sudo lsblk

输出示例:

NAME                      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda                         8:0    0  100G  0 disk
├─sda1                      8:1    0  512M  0 part /boot/efi
├─sda2                      8:2    0    1G  0 part /boot
└─sda3                      8:3    0 98.5G  0 part
  ├─datavg-db2data_lv 253:0    0 88.5G  0 lvm  /db2data
  └─datavg-other_lv   253:1    0   10G  0 lvm  /other
sdn                         8:16   0  100G  0 disk  # <--- 这就是新添加的硬盘!
sr0                        11:0    1 1024M  0 rom

在这个例子中,新硬盘被识别为 /dev/sdn。请记下您的设备名。

重要提醒: 如果 lsblk 没有立即显示新硬盘,可以尝试让系统重新扫描SCSI总线来识别新设备:

# 重新扫描SCSI主机总线(host# 请根据您的系统调整,通常是host0)
echo "- - -" | sudo tee /sys/class/scsi_host/host0/scan

# 如果不行,可以尝试扫描所有主机
for host in /sys/class/scsi_host/host*/scan; do echo "- - -" | sudo tee $host; done

再次运行 sudo lsblk 确认新硬盘出现。

假设您新添加的硬盘在系统中识别为 /dev/sdn

创建物理卷

# 跳过 fdisk 分区,直接在整个磁盘上创建物理卷
sudo pvcreate /dev/sdn

系统会提示你 Physical volume "/dev/sdn" successfully created.。这会将必要的 LVM 元数据直接写入磁盘的起始部分。

扩展卷组

# 假设您的卷组名是 datavg,不知道可以vgdisplay
sudo vgextend datavg /dev/sdn

使用 sudo vgdisplay datavg 确认 “Free PE / Size” 已经增加。

扩展逻辑卷

# 将卷组中的所有空闲空间都扩展到你的逻辑卷
sudo lvextend -l +100%FREE /dev/mapper/datavg-datalv

(你也可以指定具体大小,如 -L +50G,但通常直接用完所有空间更方便)

扩展文件系统

# 扩展文件系统以使用新的空间(假设是XFS,挂载在 /db2data)
sudo xfs_growfs /db2data

# 如果是 ext4,命令如下:
sudo resize2fs /dev/mapper/datavg-datalv

建议在这里先执行一次 df -h /db2data,确认底层文件系统已经拿到新容量,再继续处理 DB2 表空间。

DB2 表空间扩容流程

确认当前状态

在进行任何操作前,先记录下表空间的初始状态。

# 1. 连接到数据库
db2 connect to dzzf

# 2. 查看表空间详情,重点关注ASSP的ID、总页数、可用页数
echo "=== 当前所有表空间状态 ==="
db2 list tablespaces show detail

# 如下
db2inst1@db2server02:~> db2 list tablespaces | grep ASSP
 Name                                 = ASSP
 Name                                 = ASSP_INDEX
 Name                                 = ASSP_CLOB

# 检查当前连接的数据库所有表的表空间使用率MB显示
db2 "SELECT SUBSTR(TBSP_NAME, 1, 20) AS NAME, TBSP_TYPE AS TYPE, TBSP_TOTAL_PAGES * TBSP_PAGE_SIZE / 1024 / 1024 AS TOTAL_MB, TBSP_USED_PAGES * TBSP_PAGE_SIZE / 1024 / 1024 AS USED_MB, TBSP_FREE_PAGES * TBSP_PAGE_SIZE / 1024 / 1024 AS FREE_MB, DECIMAL((TBSP_USED_PAGES * 100.0) / NULLIF(TBSP_TOTAL_PAGES, 0), 5, 2) AS USED_PCT FROM SYSIBMADM.TBSP_UTILIZATION ORDER BY USED_PCT DESC"

# 3. 查看ASSP表空间的容器列表,记住容器路径和大小
echo "=== ASSP表空间的容器详情 ==="

# 首先获取ASSP的表空间ID(例如:6)
db2 list tablespaces | grep ASSP

# 假设查到的ID是 2,则查看其容器
  db2 list tablespace containers for 6

记录关键信息:

  • 表空间 ID (TSID): 例如 6
  • 总页数 (Total Pages): 例如 12800 (约50MB)
  • 容器路径: /db2data/assp_container1
  • 容器大小: 初始应为 50M

方法一:扩展现有容器

这种方式适合继续沿用原容器路径,不额外增加容器数量。下面示例将现有容器再扩大 50M

# 1. 执行EXTEND命令,在原有50M基础上再增加50M
echo "=== 开始EXTEND扩容:为现有容器增加50M ==="
db2 "ALTER TABLESPACE ASSP_CLOB EXTEND (FILE '/db2data/assp_container1' 50M)"

# 2. 立即验证结果
echo "=== EXTEND操作完成,验证新大小 ==="
db2 list tablespace containers for 6
db2 list tablespaces show detail | grep -A 3 -B 3 ASSP_CLOB

预期结果:

  • 容器路径不变,但 total_pagesusable_pages 应该大约翻倍(例如从 ~12800 变为 ~25600)。
  • 操作几乎是瞬时的,因为不涉及数据移动。

方法二:新增容器

如果希望后续容量分布更灵活,也可以直接新增一个容器。这种方式通常会触发 rebalance。

# 1. 执行ADD命令,添加一个新容器
echo "=== 开始ADD扩容:添加一个新容器 ==="
db2 "ALTER TABLESPACE ASSP ADD (FILE '/db2data/assp_container2' 50M)"

# 2. 监控重新平衡(REBALANCE)进程
echo "=== 监控ADD触发的REBALANCE工具状态 ==="
db2 list utilities show detail

# 上述命令会显示一个状态为‘Executing’的REBALANCE utility。

# 可以多次运行此命令,直到其状态变为‘Completed’。

# 注意:Rebalance可能需要一些时间,即使数据量很小。

# 3. Rebalance完成后,验证最终结果
echo "=== REBALANCE完成,验证最终大小和容器列表 ==="
db2 list tablespace containers for 6
db2 list tablespaces show detail | grep -A 4 -B 4 ASSP

预期结果:

  • list tablespace containers 会显示两个容器/db2data/assp_container1 (100M) 和 /db2data/assp_container2 (50M)。
  • list tablespaces 显示的总页数应该是三个容器页数的总和(~25600 + ~12800 = ~38400)。
  • 表空间状态 (tbsp_state) 在 rebalance 期间可能是 0x0001000 (Quiesced: SHARE),完成后会恢复正常状态 0x0000000 (Normal)。

最终验证

进行最后一次全面检查,确认扩容完全成功。

# 最终状态检查
echo "========== 扩容最终验证 =========="
echo "1. 表空间总体状态:"
db2 list tablespaces show detail | grep -A 1 -B 1 ASSP
echo "2. 容器详细列表:"
db2 list tablespace containers for 6
db2 "SELECT SUBSTR(TBSP_NAME, 1, 20) AS NAME, TBSP_TYPE AS TYPE, TBSP_TOTAL_PAGES * TBSP_PAGE_SIZE / 1024 / 1024 AS TOTAL_MB, TBSP_USED_PAGES * TBSP_PAGE_SIZE / 1024 / 1024 AS USED_MB, TBSP_FREE_PAGES * TBSP_PAGE_SIZE / 1024 / 1024 AS FREE_MB, DECIMAL((TBSP_USED_PAGES * 100.0) / NULLIF(TBSP_TOTAL_PAGES, 0), 5, 2) AS USED_PCT FROM SYSIBMADM.TBSP_UTILIZATION ORDER BY USED_PCT DESC"
echo "3. 文件系统空间检查(确认/db2data仍有充足空间):"
df -h /db2data

总结

这次扩容本质上完成了两件事:

  1. 扩展了 /db2data 所在的底层存储空间。
  2. 通过 EXTENDADD 让 DB2 表空间获得新增容量。

如果更在意操作简单和变更面小,优先使用 EXTEND;如果更在意后续容量布局的灵活性,可以使用 ADD,但要留意 rebalance 的执行时间。

Linux VMware LVM ext4 虚拟化