简介:数据库异机恢复是运维中的常见难题。这份操作文档以NetBackup备份环境为背景,系统梳理了数据库异机恢复的完整配置流程,面向负责数据库备份与恢复的运维人员,旨在解决跨主机恢复时备份链路不通、日志归档不完整等实际问题。资源包含一份文档格式的操作指南,压缩包仅314KB,内容精炼完整,目前已有335人学习下载。文档覆盖了数据库代理端的安装与用户出口程序配置、日志保留等关键参数设置,并详解了备份脚本中环境变量的作用、备份策略与归档日志策略的写法,以及归档日志保存方式与目录设定方法。针对异机恢复场景,文档特别强调了将数据库备份策略与归档日志备份策略分开配置的思路,帮助读者理解如何确保数据库在切换主机后能够可靠还原,是一份实践性很强的参考资料。
1. DB2异机恢复:备份文件搬过去,数据库就能站起来吗
机房一台 DB2 服务器彻底起不来,备机已经装好了操作系统,备份文件完整躺在备份机或带库上——这是 DB2 异机恢复最常见的出场场景。把备份文件从 A 机搬到 B 机,用 RESTORE DATABASE 命令把数据库拉起来,听起来像拷贝目录一样简单,真做起来会撞上版本、路径、日志、端口和授权五道坎。这篇笔记把我做 DB2 异机恢复的完整流程拆开讲:备份类型怎么选、恢复命令怎么填、表空间容器怎么重定向、日志和端口参数怎么调,最后附上五条现场踩坑记录和一套恢复后的验证清单。适合要接手实例迁移、机房整机搬迁,或者想在另一台机器上搭一套与生产等价的恢复演练环境的人。
2. 动手前先看这三点:备份类型、版本口径与目标机环境
异机恢复不是把 dump 文件拷贝完就结束,最先决定的不是命令怎么写,而是三个前提:备份是哪一类、目标机 DB2 能不能吃下这份备份、目标机上的实例和目录是否就绪。这三件事里任何一件没确认,后面的 restore 命令都会变成反复试错的来源。
2.1 离线备份与在线备份:决定恢复完要不要回滚日志
DB2 备份按数据库状态分两类:离线备份需要先把数据库停下来,备份期间的日志保持在同一时刻点上,恢复后可以直接 restart 进入可用状态;在线备份则允许业务继续读写,靠日志归档来保证一致性,恢复后必须把归档日志重放一遍才能打开库。从异机恢复的角度看,这个区别直接决定命令是两条还是三条。
离线备份适合能接受停库窗口的场景:凌晨维护、准生产环境、纯备份性节点。在线备份适合不能停业务的系统,但代价是你必须同时把日志归档一起搬到目标机。很多工程师第一次做异机恢复翻车,就是把在线备份当离线备份用,restore 完发现库一直停在“前滚暂挂”状态,连接就报错。
| 备份类型 | 一致性保证 | 异机恢复是否要回滚日志 | 适用场景 |
|---|---|---|---|
| 离线备份 | 备份瞬间一致 | 不需要,restore 后 restart 即可 | 停库窗口、机房搬迁、演练 |
| 在线备份 | 依赖归档日志 | 需要 rollforward 到日志末尾 | 7x24 生产库、无停窗口 |
选型建议:如果异机恢复的目标是“把生产库复制一份到测试机”,我更倾向在生产库上直接做在线备份并保留日志,恢复出来的数据离当前时刻最近;如果只是验证备份文件能不能用,离线备份就够了,不用背日志包袱。
2.2 版本和字位先把关:DB2 11.1 备份集不能恢复到更低版本
DB2 备份文件头部记录了源数据库的版本与 fix pack 级别,restore 时目标实例会做一次兼容性核对。常见做法是要求目标机版本不低于源机,比如你用 DB2 11.1 安装包装出来的实例,可以恢复 10.5 的备份;但一台 10.5 的实例去恢复 11.1 的备份,restore 会直接按“不支持的备份格式”拒绝。操作系统位数也一样,x86_64 的备份放到 32 位实例上是跑不通的。
我一般会在动手前做一次清单核对:源机 db2level 输出、备份文件头部、目标机 db2level 输出,三者放在同一个文本里对比。比较关键的是目标机的 fix pack 也不能低于源机,因为跨大版本恢复完成后,目标机还要对内部元数据做升级转换,版本越旧越容易在恢复后期报错。
| 源机版本 | 目标机版本 | 能否恢复 |
|---|---|---|
| DB2 10.5 | DB2 11.1 | 可以,恢复后自动转换 |
| DB2 11.1 | DB2 10.5 | 不可以,restore 拒绝 |
| DB2 10.5 | DB2 10.5 同 fix pack | 最稳妥 |
| 32 位实例 | 64 位实例 | 通常不可行,换同架构 |
这里还有一个隐含的坑:目标机装好后如果没有打过补丁,默认版本可能只有基础 fix pack。最好在恢复前就把官方最新 fix pack 打好,否则恢复完成后数据库能起,但后续应用兼容性问题会暴露得很晚。
2.3 目标机上的最小环境:实例、用户、目录和 license
目标机上最少要有三样东西:能与源库 uid 对应的实例用户、能绑定端口的实例、以及与被恢复库同目录权限的可写路径。实例用 db2icrt 创建,常见做法是先建好系统用户,再注册库文件目录,命令如下。
# 创建实例用户(Linux 示例,用户名与源机保持一致) useradd -m -g db2iadm1 db2inst1 passwd db2inst1 # 创建实例,-u 后面指实例用户,最后一个是实例名 /opt/ibm/db2/V11.1/instance/db2icrt -u db2inst1 db2inst1 # 启动实例并检查实例级别参数 su - db2inst1 -c "db2start" su - db2inst1 -c "db2 get dbm cfg | grep SVCENAME"db2icrt 执行后会自动做好实例目录和 sqllib 软链,但不会帮你建数据库目录。恢复时如果备份里的容器路径在目标机上不存在,restore 会报错,所以还要提前把路径创建出来并改成实例用户所有。授权方面不要凭经验觉得“换机器没事”,DB2 的 license 跟着机器走,目标机上没有对应的许可授权时,库恢复起来也会进入受限模式。
3. 异机恢复的标准操作:从备份文件到能连库的最小命令
前提确认完就进入主流程。这一章按实际操作顺序写,命令可以整段复制,但每个命令后面都标注了必改项和可选参数的用途。备份文件名里带时间戳的 NODE 路径,实际以 db2ckbkp 输出为准。
3.1 把备份文件和安全头信息核对清楚
备份文件到了目标机,先别急着 restore,第一件事是用 db2ckbkp 验证文件完整性和头部信息。db2ckbkp 不读数据库,只解析备份文件本身,跑完你能拿到源数据库名、实例名、分区节点号、备份时间戳、备份类型是离线还是在线。
# -h 表示只打印头部信息,不展开完整校验 db2ckbkp -h /backup/SAMPLE.0.db2inst1.NODE0000.CATN0000.20240101000000.001输出里有一行Timestamp = 20240101000000,这就是 restore 命令里taken at要填的值。如果源库是分区环境,备份文件名里会有多个 NODE,需要把所有节点文件都拷过来,缺一个分区整个恢复都不能做。在线备份的头部会标记成 online,这决定你后面要不要执行 rollforward 步骤。
3.2 恢复数据库并重启:restore + restart 基本用法
离线备份的恢复路径最短:执行 restore,然后 restart 让数据库结束内部恢复流程,连接测试即可。目标库名不一定要和源库名一致,用into子句可以改名,但应用连接串也要跟着改。
# 先连接实例(不需要连接目标库) db2 attach to db2inst1 # 执行恢复;taken at 填 db2ckbkp 输出里的时间戳 db2 restore database SAMPLE from /backup taken at 20240101000000 into SAMPLE # 将数据库从恢复状态拉起 db2 restart database SAMPLErestore 的from后面可以是绝对路径,也可以是备份文件所在目录;into后面是目标库名,如果目录上已经存在同名库,需要先drop database或加replace existing选项。这里要解释一下 restart 的作用:对离线备份它快速把库文件置为一致状态,对需要前滚的库它会提示当前处于 pending 状态,不能直接连接。
3.3 在线备份必须做的日志回滚:rollforward 参数怎么填
在线备份恢复后数据库处于 rollforward pending 状态,必须把归档日志重放一遍才能放开连接。先在 restore 时用logtarget指定日志落地目录,把备份期间产生的日志归档放进去,再执行 rollforward:
# 恢复时指定日志目标目录 db2 restore database SAMPLE from /backup taken at 20240101000000 logtarget /dbarch # 查询前滚状态,确认 pending db2 rollforward database SAMPLE query status # 前滚到日志末尾并结束 db2 rollforward database SAMPLE to end of logs and stoplogtarget是承接日志的临时目录,不是数据库日志目录本身。rollforward 的to end of logs表示把所有能拿到的日志全部应用,and stop表示应用完立即结束前滚,把库切到可用状态。如果归档日志有缺口,rollforward 会在缺号位置停下来并报日志序列错位,这时要把缺失的日志段从源机重新拷过来。日志文件默认命名规则是 SAMPLE 加日志号,拷贝时连目录层级一起拷最保险。
3.4 用脚本批量改表空间容器:redirected restore 的常见做法
目标机的磁盘布局和源机几乎不可能完全一样,容器路径因此最常见需要调整。DB2 提供的标准做法是重定向恢复:restore 时不真正写盘,先生成一份带所有表空间容器信息的脚本,改完脚本里的路径再执行。
# 生成重定向脚本,不启动实际恢复 db2 restore database SAMPLE from /backup taken at 20240101000000 redirect generate script autorestore.clp # 查看脚本中容器部分,典型行如下 # SET TABLESPACE CONTAINERS FOR 2 USING (PATH '/db2data/SAMPLE/NODE0000/T0000002/C0000002.CAT') # 把源路径批量替换为目标机路径 sed -i 's#/db2data/SAMPLE#/db2data2/restore_test#g' autorestore.clp # 按脚本执行恢复 db2 -tvf autorestore.clpredirect generate script生成的是 CLP 格式脚本,里面除了容器路径还有数据库配置参数和日志参数。改路径建议用 sed 做全局替换,但不要只改 SQL 语句里出现的路径,脚本里还有目录创建动作,遗漏一处恢复就会半路失败。脚本执行完如果返回码正常,再补db2 restart database SAMPLE。对于在线备份的恢复,脚本执行后还需再走一次 rollforward 步骤,重定向不影响日志回滚逻辑。
4. 异机恢复的参数调优与路径重定向:四个一改就生效的配置
数据库能 restore 起来只是第一步,很多问题出在参数上。异机环境的 CPU、内存、磁盘性能和源机不同,数据库配置参数不能原样照搬,至少得先处理日志、归档、容器路径和端口这四组配置。
4.1 日志三兄弟:logfilsiz、logprimary、logsecond 与 SQL0964C
恢复完成后第一次跑业务就报日志满或事务回滚,多半是生产的日志参数和你备机不一致。跟日志直接相关的三个配置分别是单个日志文件大小 logfilsiz、主日志文件数 logprimary、辅助日志文件数 logsecond。源机如果是高并发写入环境,日志文件通常很大,换到备机上磁盘空间却不够,恢复时日志目录直接被撑爆。
# 查看当前日志配置 db2 get db cfg for SAMPLE | grep -E "logfilsiz|logprimary|logsecond" # 调整为适合目标机的值;单位为 4KB 页 db2 update db cfg for SAMPLE using logfilsiz 8192 db2 update db cfg for SAMPLE using logprimary 32 db2 update db cfg for SAMPLE using logsecond 64 # 必须重启数据库使主日志参数生效 db2 force applications all db2 deactivate database SAMPLE db2 activate database SAMPLElogfilsiz 8192 表示每个日志文件 32MB,logprimary 32 个主日志文件,logsecond 64 个辅助日志文件,这个组合适合中等写入压力的系统。要注意 logprimary 是静态参数,activate 之后才会重新分配日志空间;logsecond 是动态参数,不需要重启。异机恢复时如果目标机内存比源机小,日志参数反而要调小,否则日志缓冲池会挤占普通缓冲池。
4.2 日志归档参数:异机恢复后第二个在线备份为什么失败
恢复完的库如果继续被当作生产库使用,日志归档通常已经被源机的 LOGARCHMETH1 参数指向旧路径,目标机上继续用会报“无法归档日志文件”之类的错误,后续在线备份也随之失败。正确顺序是恢复完成后立刻把归档路径改到目标机本地磁盘。
# 把归档方法改成磁盘目录,DB2 版本不同参数名可能略有差异 db2 update db cfg for SAMPLE using LOGARCHMETH1 disk:/dbarch # 确认生效 db2 get db cfg for SAMPLE | grep LOGARCHLOGARCHMETH1 的disk:写法表示归档到本地目录,前提是目录必须存在且实例用户可写。如果恢复演练只是为了验证备份可用,可以把这个参数保持关闭状态,但一旦它指向源机上的不存在路径,后续任何在线备份都会失败,这是异机恢复后最常见的慢性问题。
4.3 容器路径能改到什么程度:重定向的边界
3.4 节的脚本可以改所有表空间容器路径,但要知道边界:能改的是路径、设备名和容器数量,不能改表空间 ID、表空间类型和页大小。DMS 表空间换成自动存储表空间、增加容器数量这类操作,目标机的存储布局必须重新规划,不能靠改脚本一步到位。
自动化存储数据库的容器路径在恢复时可以直接用ON子句指定新路径,传统 DMS 表空间则要在脚本里逐条写SET TABLESPACE CONTAINERS。实操经验是:脚本中把所有容器都改成同一个根目录下的子目录,而不是保持源机的多级分散路径,这样后续扩容、备份都能统一管理。
# 脚本内典型修改;/db2data2/restore_test 是目标机新根目录 SET TABLESPACE CONTAINERS FOR 3 USING (PATH '/db2data2/restore_test/T0000003/C0000003.CAT')改路径前还需要确认目标文件系统类型。源机如果是裸设备,目标机不要改成普通文件路径,虽然 restore 能成功,但 IO 行为和性能会明显不一样;反过来也一样。文件系统不适合硬换,异机恢复最好连存储类型一起对齐。
4.4 连库地址与端口:实例服务名在异机上为什么失效
异机恢复最容易被忽略的是应用连接配置。DB2 实例默认通过 /etc/services 里注册的服务名暴露端口,源机上的服务名和端口可能和目标机冲突,或者目标机压根没注册。应用连不上时,日志里很多表现为连接超时或拒绝连接,配置完全是另外一回事。
# 确认当前服务名 db2 get dbm cfg | grep SVCENAME # 设定新服务名,端口要写进 /etc/services db2 update dbm cfg using SVCENAME db2c_db2inst1 # 查看 /etc/services 里是否有对应行,没有就追加 # db2c_db2inst1 50000/tcp # 更新后需要重启实例生效 db2stop db2start端口变更后,应用端连接串里的端口也必须同步改。如果目标机只用于恢复演练,建议连数据库别名都改掉,避免应用误连到演练库。SVCENAME 是实例级参数,同一个实例下所有数据库共享这个端口,这一点和单库级配置不同,改的时候要留意是否影响同一实例下的其他库。
5. DB2异机恢复避坑:五条现场记录与排查顺序
异机恢复的报错五花八门,多数问题集中在备份头信息、日志回滚、路径权限和实例端口,下面五条踩坑记录按出现频率从高到低排,每一条都按现象、原因、解决三步写。
5.1 恢复报版本不兼容或文件头错误:目标机版本低于源机
现象:执行 restore 时直接返回错误,提示备份文件格式不支持或版本无效,有的环境只在 db2diag.log 里留下版本比对记录。原因:目标机 DB2 版本或 fix pack 级别低于源机,备份文件里的元数据结构比目标机识别范围更“新”。解决:先看源机db2level,把目标机升级到同级别或更高版本的修复包;如果情况紧急,至少把实例的 fix pack 升到比源机最大版本高的那个。不要试图通过改备份文件头部来绕过去,DB2 对备份内容有校验和,改完之后恢复过程中还会二次报错。
5.2 恢复完库能起但应用连不上:端口没注册
现象:restore 和 restart 都返回成功,数据库 activate 也正常,但应用连接时报通信错误,类似 SQL30081N,错误文本里带 TCP/IP 字样。原因:目标机 /etc/services 里没有实例服务名对应的端口,或 SVCENAME 配的端口被防火墙、其他进程占用。解决:用db2 get dbm cfg | grep SVCENAME查实际服务名,再确认端口是否监听;监听正常就检查应用连接串里的端口是不是旧端口。备机如果是从镜像模板克隆的,多台机器共用同一个服务名和端口也会触发这个问题。
5.3 在线备份恢复后数据库处于 pending:日志没回滚到位
现象:库只能以单用户或维护模式访问,业务连接报数据库正在恢复中或处于前滚暂挂状态。原因:备份是 online 类型,但恢复时没有指定 logtarget,或者指定了目录却没把日志归档文件放齐。解决:执行db2 rollforward database SAMPLE query status看当前日志位置,把缺失的日志文件从源机归档目录按日志序列补齐,再执行db2 rollforward database SAMPLE to end of logs and stop。最常见的是日志文件本身已损坏,rollforward 卡在某一个日志上不前进,这时要先恢复更接近时间点的备份,不要死磕损坏日志。
5.4 restore 半路报路径不存在或权限不足:容器落点不对
现象:restore 进度到中后期中断,提示目录不存在或无法创建文件,检查目标目录时发现根本没有对应子目录。原因:目标机磁盘布局和源机不一致,备份里记录的容器路径在当前机器上不存在,或存在但属主是 root。解决:用 redirect generate script 生成脚本后先检查所有容器路径,把不存在的目录用mkdir -p建好,再把属主改成实例用户;属主问题在自动化构建的镜像机上特别常见,模板机里目录是 root,恢复进程自然没有写权限。改完路径后重新执行脚本前,记得把上一次 restore 留下的临时状态清掉,方法是对同一个库再执行一次带replace existing的 restore。
5.5 库起来了但功能受限或授权检查失败:许可证没跟着机器走
现象:数据库能连接,但特定功能不可用,或 db2diag.log 出现许可证超限、试用期到期的记录。原因:DB2 许可证授权是跟着机器绑定的,异机恢复只搬了备份文件,没把许可证文件搬过来。解决:先执行db2licm -l查看目标机当前授权类型,再用db2licm -a 许可证文件路径导入正式许可证。做恢复演练的环境如果长期使用,建议现在就把授权导入,否则恢复完第一次跑批量任务时才发现功能受限,等于白干一场。导入后要重启实例让授权缓存刷新,否则个别版本会一直读取旧值。
6. 恢复后的验证与最小停机演练:四件事做完我才敢交库
restore 成功、rollforward 结束、应用能连上,这套操作只证明“库起来了”,不证明“数据是对的”。我自己的习惯是恢复完成后按固定顺序做四件事,做完才敢告诉业务方来接。
6.1 备份文件本身先过审:db2ckbkp 看完整性
恢复前用 db2ckbkp 只验证了头部,恢复后如果怀疑数据有问题,可以再用一次不带 -h 的完整校验,把备份文件从头到尾读一遍,检查页校验和。命令:db2ckbkp /backup/SAMPLE.0.db2inst1.NODE0000.CATN0000.20240101000000.001。文件越大耗时越长,但这一步不能省,带库抽回来的备份经常在校验阶段暴露坏扇区。
6.2 恢复库做一致性体检:表状态与 db2dart 抽查
库起来后先看表状态,确认没有表处于恢复暂挂状态:db2 list tablespaces show detail,每个表空间状态应该是0x00000000正常。进一步检查就用 db2dart 做页级校验,命令是db2dart SAMPLE /DB,但我必须提醒:db2dart 要求目标数据库处于停止状态,跑之前先 force 应用并 deactivate 数据库,否则结果不可信。抽查回表空间状态后,再重新 activate 数据库。
6.3 应用侧最小验证:重新绑定包与一条连接测试
应用连异机恢复的库经常会报包未找到一类的错误,原因是数据库里缓存的 SQL 包绑定了源机实例路径。常见做法是进入实例的 bnd 目录重绑一遍:cd ~/sqllib/bnd && db2 bind db2schema.bnd blocking all grant public,再把应用用到的 CLI 包也绑一次。最后跑一条连接加查询的最小用例,这里我会用最常用的业务表做 count,验证数据可见性,而不是只查系统表。
总结成一句经验:异机恢复这条路我走了很多年,最大的教训是永远不要在业务高峰当天临时做。备份恢复到异机,时间不可控的地方太多了,一次完整演练至少要在正式迁移前两周跑通,把所有路径、端口和授权问题暴露在演练环境里。每一台机器都要按“恢复完就真的投入使用”的标准去验证,否则演练永远是演习,真到翻车那天没人替你扛。希望这篇笔记能帮你把恢复演练做成一个靠得住的例行项目。
本文还有配套的精品资源,点击获取