简介:这份《DB2异机恢复》文档面向DB2数据库管理员及备份运维人员,聚焦借助NetBackup完成DB2数据库异机恢复的典型场景,帮助读者理清恢复前需要具备的配置条件与策略关联。资源包仅含1个doc文件,大小约314KB,篇幅紧凑,适合作为实施前的速查材料或恢复演练时的对照清单。文档围绕DB2 Agent配置、用户出口程序部署、归档日志模式参数、db2_backup脚本变量含义展开,并说明db2.conf中数据库备份与归档日志备份的策略、计划及ARCFUNC、RETDIR等设置,同时涉及完整备份、累积增量和差异增量的调度区分,便于读者建立从备份配置到异机恢复的整体认识。内容侧重配置项解释与关联关系梳理,不绑定特定业务数据,便于在不同DB2实例上参照调整。目前已有340人学习,对需要打通NetBackup与DB2备份恢复链路的中高级运维人员具有参考价值。
1. 备份能跑不代表能恢复:DB2 异机恢复卡在哪
备份作业每天按时跑完、状态全是绿色,真到要换机器的时候,db2 restore一敲下去却报找不到映像,这种场面在数据库运维里不算少见。DB2 异机恢复要解决的正是这个问题:把源库的在线或离线备份,从备份存储里拉回到另一台主机上,再配合归档日志前滚到指定时间点,让业务在备用机上继续跑。它考验的不是一条 restore 命令,而是前面一长串几乎没人愿意提前配好的开关:日志模式、用户出口程序、db2.conf、备份脚本、策略类型、异机授权文件。
这份资料围绕的就是这一整套链路,覆盖 NBU 侧 Agent 配置、DB2 侧的三个 db cfg 参数、db2.conf 与 db2_backup 脚本、备份策略的调度类型,以及离线、在线、异机三种恢复场景下的命令写法。适合日常要接 DB2 备份窗口的 DBA、备份运维,也适合正在搭灾备环境、需要把恢复流程写成可复现手册的人。下面按我实际排障的顺序拆,从 DB2 侧一直走到异机恢复后怎么验证。
2. DB2 侧先把日志交出去:userexit、logretain 与 trackmod 三个开关
2.1 循环日志为什么撑不起异机恢复
DB2 默认使用循环日志,日志文件写满一轮就被覆盖,能做的事情只有一件:恢复到最近一次备份完成的那个点。备份之后的变更全部丢失,异机恢复拿到的是一份“死”数据。归档日志模式则不同,日志写满后不覆盖,而是被保留下来,恢复时按顺序重放,也就是 rollforward,可以把库推到任意一个日志覆盖到的时间点。异机恢复真正依赖的是“一次全备 + 一串归档日志”,少了后半段,换机器只能回到备份时刻。
归档日志怎么落地也有两条路。一条是把日志写到本地磁盘目录,另一条是交给外部程序,由它把日志送进备份系统。资料里走的是第二条:打开 userexit 之后,DB2 每次切换日志都会调用实例目录下的用户出口程序 db2uext2,这个程序再调用 NBU 客户端,把日志作为文件备份送进一条 Standard 类型的策略里。恢复时反向走一遍,DB2 通过同一个出口程序把需要的日志从备份系统里取回来。链路一旦通了,日志就不占本地空间,也不会因为磁盘满而中断。
这里有个容易被忽略的前提:归档日志必须在备份策略里有对应的 Schedule,否则日志生了却没人收,等到 rollforward 时才发现缺一段,前面 restore 做得再顺也白搭。这条链路要在做第一次备份之前就配好,不能等出事再补。
2.2 三个 db cfg 参数怎么改、什么时候生效
资料里给的三条 update 命令是这套方案的起点,顺序无所谓,但必须在同一个库上执行,并且执行前确认没有应用连着。
su - db2inst1 db2 connect to sample db2 update db cfg for sample using logretain on db2 update db cfg for sample using userexit on db2 update db cfg for sample using trackmod yes db2 terminate db2 deactivate db sample db2 get db cfg for sample | grep -Ei "log retain|user exit|track modified"logretain on把日志模式从循环改成归档保留,日志不再被覆盖;userexit on指定日志通过用户出口程序外送,而不是留在本地;trackmod yes打开页修改跟踪,增量备份才有依据。三条命令执行完不会立刻全部生效,DB2 对这几个参数的要求是数据库上没有活动连接,比较稳妥的做法是先db2 force applications all再db2 deactivate db sample,最后重新激活。生产环境里 force 应用要挑窗口,别在业务高峰手一抖。
验证输出大致长这样,三个值都对了才算配置到位:
Log retain for recovery status = RECOVERY User exit for logging status = YES Track modified pages = YES注意:不同大版本对归档日志的参数名有差异,有的环境已经改用 LOGARCHMETH1 这类参数统一管理归档路径,仍然用 logretain/userexit 的写法会直接报参数不存在。改之前先用
db2 get db cfg for sample看清当前字段,别照着老文档硬敲。
2.3 db2_config 到底做了什么:db2uext2 与 vendor 库
Agent 装完之后第一件事是跑配置脚本,它把 NBU 提供的用户出口程序复制到实例的 adm 目录,这一步不做,userexit 打开也没人接活。
/usr/openv/netbackup/bin/db2_config ls -l /home/db2inst1/sqllib/adm/db2uext2 ls -l /usr/openv/netbackup/bin/nbdb2.so64第一行是 NBU 自带的配置脚本,交互式地把 db2uext2 放到当前实例的sqllib/adm下,属主需要是实例用户,权限一般是 755。第二行确认文件到位。第三行确认 vendor 库文件存在,这个库是 DB2 备份命令里LOAD子句要加载的目标,恢复和备份都要用。库文件名跟平台和位数绑定,选错了 restore 会在加载阶段直接失败:
| 平台 | 位数 | vendor 库文件名 |
|---|---|---|
| Linux | 32 位 | nbdb2.so |
| Linux | 64 位 | nbdb2.so64 |
| AIX / HP-UX | 32 位 | nbdb2.sl |
| AIX / HP-UX | 64 位 | nbdb2.sl64 |
脚本跑完还会生成备份用的样例脚本,路径和内容各版本略有差别,但结构一致:读环境变量、拼 db2 backup 命令、用实例用户执行。样例只是模板,里面的库名、用户、库文件路径都要按实际环境改,直接拿来用大概率备份的是别人的库。
2.4 改完参数必须补一次全备,否则库连不上
这是整套流程里最容易翻车的一步。打开 logretain 和 userexit 之后,数据库立刻进入 backup pending 状态,此时任何应用连接都会报 SQL1116N,提示数据库或别名处于备份暂挂状态。解决办法只有一个:马上做一次全备。
su - db2inst1 db2 backup db sample to /db2backupto后面是本地备份路径,实际生产中更常见的是直接用 NBU 脚本发起一次全备,让映像直接进存储。这次全备不只是解 backup pending,它还是后续所有增量备份的基线:trackmod 打开之前做的备份不能作为增量链的起点,增量恢复时必须先找到一个全备映像,再依次叠加增量。我一般会在改完参数后立刻跑一次全备,然后马上做一次恢复演练,确认这条链是通的,而不是等到半年后真出事才发现基线根本不存在。
3. db2.conf 与 db2_backup:把备份命令交给 NBU 调度
3.1 db2.conf 的两段结构:数据库段与归档日志段
db2.conf 是 NBU 的 DB2 扩展读取的配置文件,默认放在/usr/openv/netbackup/db2.conf。它用DATABASE开头、ENDOPER结尾划分操作块,一个库通常要写两段:一段描述数据库备份属于哪条策略,一段描述归档日志走哪条策略。
DATABASE SAMPLE OBJECTTYPE DATABASE POLICY DB2_Backup SCHEDULE Default-Application-Backup ENDOPER DATABASE SAMPLE OBJECTTYPE ARCHIVE POLICY DB2_Log SCHEDULE User_Backup ARCFUNC SAVE ENDOPER第一段里OBJECTTYPE DATABASE表示这是数据库备份映像,POLICY填 DB2 类型的策略名,SCHEDULE填该策略下自动备份的调度名。第二段OBJECTTYPE ARCHIVE对应归档日志,策略必须是 Standard 类型,调度是 User Backup 类型,ARCFUNC SAVE表示日志由 NBU 直接存到存储单元,恢复时也从存储取。想改成先把日志落到本地目录再备份,可以换成ARCFUNC COPY并配上ARCDIR和RETDIR,前者是日志落地目录,后者是恢复时的日志来源目录。
异机恢复时会多出一行CLIENT_NAME,值填源客户端名。这一行的作用是告诉 NBU:这次操作虽然发生在目标机上,但映像属于那台源主机。不写这行,目标机上执行 restore 会沿着自己的客户端名去找映像,结果自然是什么都找不到。
3.2 db2_backup 脚本:环境变量、库文件与执行用户
NBU 调用备份脚本时不是空手来的,它通过 bphdb 传入一组环境变量,脚本靠这些变量判断本次该做全备还是增量。资料里的脚本骨架可以直接抄,我把容易出问题的几处补全了:
#!/bin/sh # NBU 通过 bphdb 注入以下变量,脚本只读不写 echo "DB2_CLIENT = $DB2_CLIENT" echo "DB2_SERVER = $DB2_SERVER" echo "DB2_POLICY = $DB2_POLICY" echo "DB2_SCHED = $DB2_SCHED" echo "DB2_FULL = $DB2_FULL" echo "DB2_CINC = $DB2_CINC" echo "DB2_INCR = $DB2_INCR" # 按平台和位数选择 vendor 库,64 位 Linux 用 nbdb2.so64 MY_LIB=/usr/openv/netbackup/bin/nbdb2.so64 # 需要备份的数据库名 MY_DB2=SAMPLE # 执行备份的实例用户 MY_USER=db2inst1 # 根据调度类型决定是否带增量关键字 if [ "$DB2_FULL" = "1" ]; then MY_SCHED="" elif [ "$DB2_CINC" = "1" ]; then MY_SCHED="INCREMENTAL" elif [ "$DB2_INCR" = "1" ]; then MY_SCHED="INCREMENTAL DELTA" else MY_SCHED="" fi # LOAD 与库路径之间必须有空格,否则 DB2 会把整串当成文件名 CMD_LINE="db2 BACKUP DATABASE $MY_DB2 ONLINE $MY_SCHED LOAD $MY_LIB" echo "Executing: $CMD_LINE" su - $MY_USER -c "$CMD_LINE" RETURN_STATUS=$? exit $RETURN_STATUS几个参数值得单独说。MY_LIB必须和上表里的平台位数对齐,AIX 上写 so64 会加载失败。MY_DB2是数据库名,不是实例名,多个库就多写一条 CMD_LINE 依次执行。ONLINE表示在线备份,要求库已经打开归档日志,离线备份则要去掉这个关键字并确保没有连接。最后的exit $RETURN_STATUS很关键,NBU 靠退出码判断本次作业成败,脚本里如果吞掉了错误码,作业会显示成功但实际什么都没备,这种假绿比失败更麻烦。
注意:
LOAD后面一定要留空格,资料原文里LOAD$MY_LIB这种写法把关键字和路径粘在一起,执行时会报语法错误或者被当成另一个参数,属于典型的复制粘贴翻车点。
3.3 增量调度变量:Full、Cumulative、Differential 怎么映射
脚本里三个变量对应 NBU 的三种调度类型,映射关系不能搞反。全备时DB2_FULL=1,命令不带增量关键字;累积增量时DB2_CINC=1,对应 DB2 的INCREMENTAL,它备份的是自上次全备以来所有被修改的页;差异增量时DB2_INCR=1,对应INCREMENTAL DELTA,只备份自上次任意类型备份以来修改的页。资料原脚本里差异增量那个分支是空的,等于差异调度跑起来会退化成全备,数据量一大窗口就爆,这一点我在自己的脚本里补上了。
恢复时的叠加顺序也由此决定:全备打底,然后按时间顺序依次恢复累积或差异增量,最后 rollforward 日志。中间缺一个增量,后面全部作废。所以增量策略的保留周期要覆盖住全备周期,别出现“全备只剩一份、增量已经过期”的组合。
3.4 策略侧要点:类型选 DB2,Backup Selections 指向脚本
NBU 控制台里的操作步骤资料写得很细,核心就几项。新建策略时Policy type必须选 DB2,选成 Standard 会导致脚本根本不被当作数据库备份执行;Policy storage unit和Policy volume pool按存储规划填;Clients里加源库主机名;Backup Selections里填脚本的绝对路径,比如/usr/openv/netbackup/bin/db2_backup,路径要和实际存放位置一致,并且对 NBU 服务账号可读可执行。
Schedules里按需建四条:全备用 Automatic Full Backup,差异增量用 Automatic Differential Incremental Backup,累积增量用 Automatic Cumulative Incremental Backup,日志归档用 User Backup。每条调度单独设保留周期和发起窗口,全备窗口要给足,增量窗口可以短一些。
日志那条策略单独建,类型是 Standard,调度类型是 User Backup,客户端还是源库主机。这条策略不写 Backup Selections 脚本,它只负责接收 db2uext2 送过来的日志文件。少了这条,数据库备份再成功,rollforward 阶段也会因为取不到日志而卡住。
4. restore 与 rollforward:三种恢复场景的命令差异
4.1 离线备份恢复:一条命令加 without rolling forward
离线备份是不带日志的,恢复完就是备份那一刻的状态,不需要前滚,但 DB2 默认会把恢复后的库置成 rollforward pending,必须显式告诉它不要前滚。
su - db2inst1 db2 restore db sample load /usr/openv/netbackup/bin/nbdb2.so64 \ without rolling forward without promptingload后面跟 vendor 库的绝对路径,告诉 DB2 从 NBU 取映像而不是从本地磁盘;without rolling forward让库恢复后直接可用;without prompting跳过交互确认,适合放进脚本。如果目标机上根本没有这个库,需要加to指定新的数据库目录:
db2 restore db sample load /usr/openv/netbackup/bin/nbdb2.so64 \ to /db2tgt/sample without rolling forward without promptingto是数据库目录,不是表空间容器目录,两者别混。异机恢复时目标机目录结构和源机不一样,这一步基本都要带,否则 restore 会尝试往源机的路径写,权限或空间立刻报错。
4.2 在线备份恢复:restore 之后必须 rollforward
在线备份恢复分两步,restore 只把映像落回来,rollforward 才把日志重放上去。两步之间库处于 rollforward pending,业务连不上,属于正常中间态。
db2 restore db sample load /usr/openv/netbackup/bin/nbdb2.so64 without prompting db2 rollforward db sample to end of logs and completeto end of logs表示一直前滚到能找到的最后一条日志,and complete表示前滚完成后把库置为可用状态。想停在某个时间点,就把时间写进去:
db2 rollforward db sample to 2025-02-26-12:07:11 using local time and complete时间格式是年-月-日-时.分.秒,using local time表示按本地时区解释。有些版本没有这个选项,如果操作系统时间和标准时间存在偏差,写进去的时间要手动减掉这个差值,否则前滚会多走或少走一段,这种偏差在追账类业务里是致命的。
前滚过程中如果报缺日志,库会停在 pending 状态,可以先查状态再决定是补日志还是取消:
db2 rollforward db sample query status确认不打算继续前滚,用db2 rollforward db sample cancel收尾。cancel 之后这个库就不能再往前滚了,属于没有后悔药的操作,执行前想清楚。
4.3 bplist 找时间点,taken at 精确恢复
在线库一天多次备份时,光靠 restore 默认取最新映像不一定满足需求,得先找到目标映像的时间点。NBU 的 bplist 就是干这个的:
bplist -C db2src -t 18 -R /-C指定源客户端名,异机场景下这个参数必须写源机而不是本机;-t 18对应 DB2 备份映像类型;-R递归列出。输出里会出现类似/DB2/SAMPLE/db2src/20250226120711/SAMPLE.0.db2inst1...的路径,中间那串 14 位数字就是映像时间戳,格式是年月日时分秒。
拿到时间戳后,用taken at精确恢复:
db2 restore db sample load /usr/openv/netbackup/bin/nbdb2.so64 \ taken at 20250226120711 without prompting同一个时间戳下往往能看到多个以.1、.2、.3结尾的条目,那是并行会话切出来的分片,属于同一次备份,不要误以为是多个版本。挑版本看时间戳,不看后缀编号。
4.4 to 参数与容器重定向:异机路径不一致时怎么办
异机恢复最常见的失败原因不是权限,而是表空间容器路径不存在。to只改数据库目录,表空间容器还是按源机的绝对路径去找,目标机没有对应目录时 restore 会在容器创建阶段失败。
db2 restore db sample load /usr/openv/netbackup/bin/nbdb2.so64 \ to /db2tgt/sample redirect without prompting db2 set tablespace containers for 2 using \ \(path '/db2tgt/containers/ts1' size 1024000\) db2 restore db sample continue第一条带redirect只做元数据恢复,不创建容器;第二条按表空间编号重新指定容器路径和大小,size单位是 4KB 页,要按原库大小换算;第三条continue完成实际数据写入。三步顺序不能乱,中间那条的表空间编号要先用db2 list tablespaces在源库上确认,写错编号会把容器指到别的表空间上,恢复出来的库结构是乱的。
5. 避坑与排查:异机恢复现场最常见的五个翻车点
5.1 改完参数库连不上,报 SQL1116N
现象:logretain 和 userexit 改完,应用立刻连不上,报数据库处于备份暂挂状态。
原因:打开归档日志后 DB2 要求立刻有一次全备作为新基线,这个状态不解除,任何连接都会被拒。
解决:马上用实例用户做一次全备,db2 backup db sample to /db2backup,或者直接用 NBU 脚本发起一次全备。全备完成后状态自动解除。这个动作要在变更窗口内做完,不要留到第二天,中间任何连接失败都会被当成故障上报。
5.2 目标机 restore 报找不到映像
现象:源机上 bplist 能列出映像,换到目标机执行 restore 却提示没有可用备份。
原因:目标机的 db2.conf 里没有指定CLIENT_NAME,NBU 沿着目标机自己的客户端名去找,自然找不到属于源机的映像;另一种情况是 Master 上没有放开异机恢复限制。
解决:在 db2.conf 的两个操作块里都加上CLIENT_NAME 源客户端名,再确认 Master 上的异机授权文件已创建。两处缺一处都恢复不了,排查时按这个顺序看。
5.3 加载 vendor 库失败
现象:restore 一执行就报加载共享库失败,或者提示找不到符号。
原因:load后面的库文件路径写错,或者位数不匹配,比如 64 位实例加载了 32 位的 nbdb2.so。
解决:ls -l确认文件存在,用file命令看位数,Linux 64 位统一用 nbdb2.so64,AIX 用 nbdb2.sl64。路径写绝对路径,别依赖环境变量。
5.4 在线恢复后库停在 rollforward pending
现象:restore 成功,业务连不上,db2 list db directory看库状态不对。
原因:在线备份恢复必须前滚,restore 本身不会让库可用,这是设计行为不是故障。
解决:执行db2 rollforward db sample to end of logs and complete。如果不打算前滚,必须回到 restore 阶段加without rolling forward,已经进了 pending 再想跳过前滚,只能重新恢复一次。
5.5 rollforward 报缺日志
现象:前滚跑到一半报缺少某段日志,库停在 pending。
原因:归档日志没有真正进入 NBU,常见于日志策略没建、调度类型不是 User Backup、db2.conf 里 ARCHIVE 段写错,或者 db2uext2 权限不对导致日志送出失败。
解决:先查日志策略的作业历史有没有成功记录,再确认sqllib/adm/db2uext2的属主和权限,最后核对 db2.conf 的 ARCHIVE 段策略名和调度名。三处都对了仍然缺日志,说明那段日志在产生时就失败了,只能恢复到缺失点之前,这一点没有补救办法,只能靠平时的作业监控提前发现。
6. 最后一道开关:No.Restrictions、CLIENT_NAME 与恢复后的验证
异机恢复在 NBU 侧还有一道门,不开门命令写得再对也过不去。Master Server 上默认只允许客户端恢复自己的备份,要放开跨主机恢复,得用 root 建授权文件:
# Master Server 上以 root 执行 touch /usr/openv/netbackup/db/altnames/No.Restrictions chmod 644 /usr/openv/netbackup/db/altnames/No.Restrictions # 更细粒度的做法:文件名是源客户端,内容是被允许的目标客户端 echo db2tgt > /usr/openv/netbackup/db/altnames/db2srcNo.Restrictions是一刀切,所有客户端都能互相恢复,方便但范围太大;按源客户端建同名文件、内容写目标主机名,是更稳妥的做法,出问题也容易定位。改完不需要重启服务,下一次 restore 就生效。
6.1 恢复完成后怎么验证
三条命令,按顺序走一遍,基本能确认这次异机恢复是干净的:
# 1. 确认目标机能看到的映像与源机一致 bplist -C db2src -t 18 -R / # 2. 看恢复历史,确认全备和增量都进了链 db2 list history backup all for sample # 3. 确认库不在 pending 状态 db2 rollforward db sample query status第一条验证授权和连通性,第二条验证备份链完整,第三条验证库已经可用。三条都过,再让应用连上去做一次简单查询,比任何作业状态截图都可靠。
提示:演练时把目标库名改成和源库不同的名字,用
to恢复到新目录,避免误覆盖同名的生产库,这个习惯能省掉很多事后解释。
从那以后我每次做 DB2 异机恢复,都先在测试机上把 bplist、taken at、rollforward 这三件事完整走一遍,再动生产环境的命令。备份能不能恢复,只有真恢复过一次才算数。希望帮到你。
本文还有配套的精品资源,点击获取