Home

DB2 表空间容器迁移指南

这篇文章记录 DB2 表空间容器迁移到新磁盘或新卷组时的一套相对稳妥的做法。整体思路是:先准备独立存储,再停 DB2、挂载新卷、同步旧数据,最后恢复实例运行。

迁移思路

这类迁移通常分成五个阶段:

  1. 提前准备新的 LVM 存储
  2. 停止 DB2 并清理残留 IPC
  3. 备份旧目录并挂载新卷
  4. rsync 同步数据
  5. 修复权限并写入 fstab

第一阶段:准备新存储

1. 确认新硬盘

先确认系统已经识别到新盘,例如:

lsblk

文中的示例盘符是 /dev/sdd/dev/sde/dev/sdf

2. 创建物理卷

pvcreate /dev/sdd
pvcreate /dev/sde
pvcreate /dev/sdf

3. 创建卷组

为了让每个节点对应自己的存储,文中采用的是每个节点单独一个 VG 的方式:

vgcreate vg_node0001 /dev/sdd
vgcreate vg_node0002 /dev/sde
vgcreate vg_node0003 /dev/sdf

4. 创建逻辑卷

lvcreate -l 100%FREE -n lv_node0001 vg_node0001
lvcreate -l 100%FREE -n lv_node0002 vg_node0002
lvcreate -l 100%FREE -n lv_node0003 vg_node0003

5. 格式化文件系统

针对文中的 SUSE 11 SP3 环境,格式化为 ext3

mkfs.ext3 /dev/vg_node0001/lv_node0001
mkfs.ext3 /dev/vg_node0002/lv_node0002
mkfs.ext3 /dev/vg_node0003/lv_node0003

第二阶段:停止 DB2 并清理环境

1. 停止实例

su - db2inst1
db2 force application all
db2stop force

2. 清理残留进程和 IPC

db2_kill
ipclean -a
exit

这一步非常关键。只有确认 DB2 进程和共享内存都清干净了,后面的目录改名和数据同步才不会踩坑。

第三阶段:切换目录并挂载新卷

1. 先备份旧目录

cd /db2fs/db2inst1/
mv NODE0001 NODE0001_old
mv NODE0002 NODE0002_old
mv NODE0003 NODE0003_old

2. 创建新的挂载点并挂载

mkdir NODE0001 NODE0002 NODE0003
mount -t ext3 /dev/vg_node0001/lv_node0001 /db2fs/db2inst1/NODE0001
mount -t ext3 /dev/vg_node0002/lv_node0002 /db2fs/db2inst1/NODE0002
mount -t ext3 /dev/vg_node0003/lv_node0003 /db2fs/db2inst1/NODE0003

第四阶段:同步数据

rsync 把旧目录的数据完整同步到新卷。这里源路径末尾的 / 一定要保留。

rsync -avh --progress /db2fs/db2inst1/NODE0001_old/ /db2fs/db2inst1/NODE0001/
rsync -avh --progress /db2fs/db2inst1/NODE0002_old/ /db2fs/db2inst1/NODE0002/
rsync -avh --progress /db2fs/db2inst1/NODE0003_old/ /db2fs/db2inst1/NODE0003/

第五阶段:修复权限并持久化挂载

1. 修复属主和权限

新卷挂载后,目录属主通常会变成 root,而且会出现 lost+found。因此必须重新修复权限:

chown -R db2inst1:db2iadm1 /db2fs/db2inst1/NODE0001
chown -R db2inst1:db2iadm1 /db2fs/db2inst1/NODE0002
chown -R db2inst1:db2iadm1 /db2fs/db2inst1/NODE0003
chmod 755 /db2fs/db2inst1/NODE0001
chmod 755 /db2fs/db2inst1/NODE0002
chmod 755 /db2fs/db2inst1/NODE0003

2. 写入 /etc/fstab

为了避免重启后丢挂载,建议把新卷写进 fstab。文中示例直接使用设备路径:

/dev/vg_node0001/lv_node0001  /db2fs/db2inst1/NODE0001  ext3  defaults  0  0
/dev/vg_node0002/lv_node0002  /db2fs/db2inst1/NODE0002  ext3  defaults  0  0
/dev/vg_node0003/lv_node0003  /db2fs/db2inst1/NODE0003  ext3  defaults  0  0

如果条件允许,更推荐使用 UUID 挂载,避免设备名漂移。

写完后执行一次:

mount -a

确认没有报错后,再准备启动 DB2。

关于几个关键命令

为什么用 rsync -avh

因为它不仅复制文件,还能保留:

  • 属主
  • 属组
  • 权限
  • 时间戳

而 DB2 对这些属性是很敏感的,如果简单 cp -r 后权限乱了,实例很可能直接起不来。

为什么要执行 db2_kill

有时候 db2stop force 并不会把所有 DB2 相关进程都清干净。db2_kill 的作用,就是从操作系统层面把残留 DB2 进程彻底清理掉。

为什么还要 ipclean -a

因为 DB2 尤其在 DPF 场景下,会使用大量共享内存和信号量。如果实例被异常停掉,这些 IPC 资源可能还留在系统里。ipclean -a 的作用,就是把这些残留一起清理掉,避免后续 db2start 时再次报错。

总结

表空间容器迁移最怕的,不是命令多,而是“停得不彻底、挂得不干净、权限没修好”。只要把这三件事控制住:

  1. DB2 完整停干净
  2. 新卷和旧目录切换准确
  3. 权限和自动挂载配置无误

整个迁移过程其实是可控的。

Linux LVM 存储 数据库