Home

DB2 DPF 跨机器重定向还原迁移

实验环境定义

  • 源环境(A): db2dpfa (节点 0-7)
  • 目标环境:
  • 目标机器 B (db2dpfa): 承载节点 0, 1, 2, 3 (Node 0 为编目节点)
  • 目标机器 C (db2dpfb): 承载节点 4, 5, 6, 7
  • 数据库名: GXCXXTDB

第一阶段:源端备份与文件传输

  1. 联机备份(包含日志)有两种方式使用第二种异步:
    在源机 A 上执行:
#同步备份方式
db2 "BACKUP DATABASE GXCXXTDB ON ALL DBPARTITIONNUMS ONLINE TO /db2data/backup COMPRESS INCLUDE LOGS"
#异步备份方式
db2_all "db2 BACKUP DB GXCXXTDB ONLINE TO /db2data/backup COMPRESS INCLUDE LOGS"
  1. 分发备份文件:
    将不同节点的备份文件 scp 到目标机器对应的目录下:
  • 传给目标集群 a 机(db2dpfb): NODE0000NODE0003
scp /db2data/backup/GXCXXTDB.0.db2inst1.NODE000{0,1,2,3}.CATN0000.*.001 db2dpfa:/db2data/backup
  • 传给目标集群 b 机 (db2dpfc): NODE0004NODE0007
scp /db2data/backup/GXCXXTDB.0.db2inst1.NODE000{4,5,6,7}.CATN0000.*.001 db2dpfb:/db2data/backup

第二阶段:目标端基础设施配置(已经改好了,检查过了)

  1. **修改 db2nodes.cfg**:
    在目标集群 a 和 b 两台机器上同步修改 ~/sqllib/db2nodes.cfg,定义新的逻辑节点与物理机器映射:
0 db2dpfb 0
1 db2dpfb 1
2 db2dpfb 2
3 db2dpfb 3
4 db2dpfc 0
5 db2dpfc 1
6 db2dpfc 2
7 db2dpfc 3
  1. 建立 SSH 免密登录:
    确保 db2inst1 用户在 a 和 b 之间可以无需密码互相登录(db2_all 依赖此环境)。

第三阶段:重定向还原(核心步骤)

  1. 生成重定向脚本:
    在 目标集群机器 a (Node 0) 执行,生成初始脚本:
db2 RESTORE DB GXCXXTDB FROM /db2data/backup TAKEN AT 20260204165528 REDIRECT GENERATE SCRIPT my_restore.sql

时间戳就看备份的 节点 0 的时间戳,异步备份每个备份的时间戳都不一样

  1. **编辑脚本 my_restore.sql**:
    这是最关键的一步,需修改全部表空间容器路径(检查过环境两边都是/db2data/db2inst1 里面的所以不用改)。
  • 确保路径在 a 和 b 机器上物理存在。
  • 确保 db2inst1 有写入权限。
  • 修改开头的循环日志的路径 NEWLOGPATH ‘/share/db2inst1/db2inst1/NODE0000/SQL00002/‘指向备集群的路径SQL00004 文件夹是自己创建的两边都要创建并且属主授权要写好使用 db2_all 两边都能操作,因为一会儿要解压出备份里面包含的日志所以要创建对应的文件夹并把对应包含的日志文件放到对应的文件夹里面

db2_all 'mkdir -p /share/db2inst1/db2inst1/NODE000$DB2NODE/SQL00002/SQLOGDIR/'

# 2. 再次刷新权限
db2_all 'chown -R db2inst1:db2iadm1 /share/db2inst1'

# 3. 验证确认(确保 0-7 号全部能列出,没有报错)
db2_all 'ls -d /share/db2inst1/db2inst1/NODE000$DB2NODE/SQL00002/SQLOGDIR/'
  1. 执行 Node 0 还原:
    在 目标集群机器 a 上运行:
db2 -tvf my_restore.sql

看到 RESTORE DATABASE ... CONTINUE 成功即表示 Node 0 已建好。
4. 并行还原剩余节点(1-7):
利用 db2_all 触发其他节点的物理还原:

db2_all "<<-0< db2 RESTORE DB GXCXXTDB FROM /db2data/backup NEWLOGPATH /share/db2inst1/db2inst1/NODE000\$DB2NODE/SQL00002/SQLOGDIR/ WITHOUT PROMPTING"

第四阶段:日志提取与全库前滚

由于是联机备份,数据库目前处于 Rollforward Pending 状态。

  1. 为各分区创建独立日志目录:
    防止并行提取日志时发生同名文件冲突(Reason Code 3):
db2_all "mkdir -p /db2data/backup/logs/node\$DB2NODE"
  1. 提取备份集中的日志:
db2_all "db2 RESTORE DB GXCXXTDB LOGS FROM /db2data/backup LOGTARGET /db2data/backup/logs/node\$DB2NODE WITHOUT PROMPTING"
  1. 日志归位:

创建对应日志目录将提取出的日志移入各节点默认的活动日志目录:

这一步非常容易出错,我建议恢复完成后查看一下 CFG 再进行目录的编写不然非常容易出错

# 1. 创建所有节点的日志目录,这个活动目录是我们开头 sql 文件的日志目录
#如果上面创建了这里就不用创建
db2_all "mkdir -p /share/db2inst1/db2inst1/NODE000\$DB2NODE/SQL00002/SQLOGDIR/"

# 2. 重新投送日志
db2_all "cp /db2data/backup/logs/node\$DB2NODE/S*.LOG /share/db2inst1/db2inst1/NODE000\$DB2NODE/SQL00002/SQLOGDIR/"
  1. 执行全库前滚:
    在 集群 机器 a (Node 0) 发起:
db2 "ROLLFORWARD DATABASE GXCXXTDB TO END OF LOGS AND STOP"

第五阶段:验证与验收

  1. 在集群 a 机 激活数据库(正常情况下已经激活,但是确保一下):
db2_all "db2 activate db GXCXXTDB"
  1. 检查表空间记录:
    确保所有表空间在 8 个分区上均处于 NORMAL 状态:
db2 "SELECT DBPARTITIONNUM, TBSP_NAME, TBSP_STATE FROM TABLE(MON_GET_TABLESPACE('',-2)) ORDER BY DBPARTITIONNUM"
  1. 验证业务数据:
    检查测试数据是否完整迁移:
db2 "SELECT DBPARTITIONNUM(ID) AS NODE_ID, COUNT(*) AS ROW_COUNT FROM MIGRATE_TEST GROUP BY DBPARTITIONNUM(ID) ORDER BY NODE_ID"

踩坑和避坑总结

  • SQL1035N (Database in use): 执行还原或日志提取前,务必 db2 force applications alldb2 deactivate db
  • SQL2542N (File not found): 时间戳必须以 Node 0 为准,且文件必须放在 db2nodes.cfg 指向的物理机器上。
  • **DB2NODE 变量**: 在 `db2_all` 中使用时,必须加反斜杠转义(`\DB2NODE`),否则会在本地被解析。
  • 记得节点分布逻辑:Node 0 包含系统目录,其他节点只含数据空间。

如果还原过程有分区还原失败

专门针对报错的分区重试还原

既然 Node 1-6 都已经 <font style="color:rgb(0, 0, 0);">completed ok</font> 了,只需要把失败的那个分区(假设是 Node 7)补齐:

# 假设是 Node 7 报错,
db2_all "<<+7< db2 RESTORE DB GXCXXTDB FROM /db2data/backup WITHOUT PROMPTIN

实验环境清理

  1. 踢掉所有连接并删除数据库(全分区)

db2_all “db2 force applications all”

db2_all “db2 deactivate db GXCXXTDB”

db2 drop db GXCXXTDB

db2 terminate

A. 删除所有节点的数据目录和日志目录

注意:这会删除 NODE000X 下所有以 SQL 开头的文件夹,确保没有其他数据库在这里

db2_all “rm -rf /share/db2inst1/db2inst1/NODE000*/SQL000*”

db2_all “rm -rf /share/db2inst1/db2inst1/NODE000*/ts1”
db2_all “rm -rf /share/db2inst1/db2inst1/NODE000*/dbfiles”

db2_all “rm -rf /db2data/backup/logs/node*/*”

B. 清理你之前建的容器目录(ts1, dbfiles 等)

db2_all “rm -rf /db2data/db2inst1/db2inst1/NODE000*/ts1”
db2_all “rm -rf /db2data/db2inst1/db2inst1/NODE000*/dbfiles”

C. 清空日志提取的“中转站”

db2_all “rm -rf /db2data/backup/logs/node*/*”

D. 如果你之前用了 /share 路径,也一并清理

db2_all “rm -rf /share/db2inst1/db2inst1/NODE000*/SQL000*”

修改数据库归档配置

db2 "UPDATE DB CFG FOR CXSUBDB USING LOGARCHMETH1 DISK:/db2dpf_backup/archived_logs/GXSUB"

然后执行全备

db2 "BACKUP DATABASE CXSUBDB ON ALL DBPARTITIONNUMS TO /db2dpf_backup"
数据库