在测试环境搭建、数据迁移、版本升级验证等场景中,经常需要把一个DB2数据库完整地复制一份出来。如果直接采用备份恢复的方式,对源库的离线窗口和目标环境的版本都有严格要求,操作也比较重。其实DB2自带了两个轻量级工具:db2look负责导出对象定义,db2move负责搬移数据,两者组合起来就能快速克隆一个数据库,几乎不需要额外安装任何软件。

一、db2look工具:导出数据库对象定义
db2look是DB2提供的DDL生成工具,它连接到数据库后读取系统编目表,把表结构、索引、约束、触发器、视图、存储过程等对象的定义抽取出来,生成一份可以直接执行的SQL脚本。它是克隆流程中的第一步,因为必须先有目标表,才能往里面灌数据。
最基础的使用方式是指定数据库名和操作用户,配合-e参数导出对象的DDL,配合-o参数指定输出文件。一个典型的命令如下:
db2look -d SAMPLE -e -z DB2INST1 -o schema.sql # -d 指定数据库名 # -e 导出对象的DDL(表、视图、索引、约束等) # -z 限定模式名,只导出该schema下的对象 # -o 输出到schema.sql文件
如果希望克隆出来的库和源库在授权上保持一致,可以加上-x参数导出GRANT授权语句;如果还想把表空间定义、数据库配置参数、缓冲池等信息一并导出,则使用-l和-f参数。对于包含自增列的表,-a配合-createdb等选项也能满足更完整的需求。参数组合不同,导出的完整度也不同,建议在正式克隆前先用小库测试一遍,确认生成的脚本符合预期。
需要注意,db2look默认只导出当前用户有权限访问的对象。如果数据库里有多个schema,克隆时要么用有足够权限的用户执行,要么对每个schema分别用-z参数导出,避免遗漏业务表。
二、db2move工具:批量导出与导入数据
结构建好之后,搬数据交给db2move。它的原理很简单:读取编目中的表清单,对每张表自动调用EXPORT导出数据,导入时再自动调用IMPORT或LOAD批量装回去。所有数据文件采用IXF格式,这种格式自带表结构描述信息,兼容性好,是DB2之间搬数据的首选格式。
导出时在源库所在的服务器上执行:
db2 connect to SAMPLE db2move SAMPLE export # 执行完成后当前目录会生成: # db2move.lst 表与导出文件的对应清单 # EXPORT.out 导出日志 # 若干.tab文件 每张表对应的IXF数据文件
导出完成后,把整个目录连同db2move.lst清单一起拷贝到目标服务器,然后执行导入:
db2move NEWDB import -io replace_create # NEWDB 为目标数据库名 # import 表示采用IMPORT方式装入数据 # -io replace_create 指定导入选项:目标表存在则替换数据,不存在则自动建表
这里要说明一点:replace_create选项虽然方便,但如果前面已经用db2look精细建好了表结构,建议改用insert或replace。因为通过db2move自动建的表会丢失一些细节定义,比如某些约束和权限信息,精细克隆时以db2look的DDL为准更可靠。
导入结束后一定要查看db2move.lst和IMPORT.out文件。清单里每张表都有状态标记,正常完成的表会显示导入成功的记录数,失败的表会保留错误信息,方便针对性重跑。
三、完整克隆流程与LOAD加速技巧
把两个工具串起来,一个标准的克隆流程分为四步:第一步在源库执行db2look生成DDL脚本;第二步执行db2move export导出数据;第三步在目标库创建数据库并执行DDL脚本建结构;第四步把数据文件传过去执行db2move import。整个过程不需要停止源库,对生产影响很小。
当数据量达到千万级甚至更多时,IMPORT方式的性能会成为瓶颈,因为它逐行处理并记录日志。这时可以把导入方式换成LOAD,命令只需把import换成load:
db2move NEWDB load -lo replace # load方式直接把数据页写入表空间,绕过SQL层 # -lo replace 表示清空目标表后装载 # 速度通常比IMPORT快一个数量级以上
LOAD的代价是绕过了常规日志,装载完成后表会处于待验证状态,需要执行SET INTEGRITY语句让约束检查生效。db2move在LOAD结束后一般会提示哪些表需要执行该操作,照着清单逐个执行即可:
SET INTEGRITY FOR DB2INST1.ORDERS IMMEDIATE CHECKED; -- 让处于SET INTEGRITY PENDING状态的表完成约束校验
另外LOAD默认不写恢复日志,如果目标库开了归档日志模式,可以加NONRECOVERABLE相关选项或事后做一次备份,避免影响后续的日志链。
四、克隆过程中的常见问题与解决办法
第一个常见问题是外键依赖导致的建表失败。db2look生成的DDL中,外键约束是独立于建表语句单独输出的,所以只要按脚本顺序执行通常没问题;但如果手工拆分过脚本,就可能遇到表还不存在就建外键的情况。解决办法是分两遍执行脚本,第一遍只执行建表语句,第二遍再执行约束和索引部分。
第二个问题是字符集与排序规则不一致。目标库创建时的代码页如果和源库不同,导入中文数据时可能乱码或直接报错。建议用db2 get db cfg for 源库查看代码页和整理顺序,创建目标库时保持一致,例如:
db2 "CREATE DB NEWDB USING CODESET UTF-8 TERRITORY CN COLLATE USING SYSTEM"
第三个问题是自增列的计数器。数据导入后,IDENTITY列的当前值不会自动同步,后续插入可能触发主键冲突。可以在导入完成后执行一次ALTER TABLE ... ALTER COLUMN ... RESTART WITH,把计数器设置到最大值之上,或者直接对相关表执行一次重组。此外,如果表中有大对象字段或XML字段,导出时会在目录下生成额外的资产文件,打包传输时千万别漏掉,否则大对象数据会丢失。
掌握db2look与db2move这对组合后,绝大多数DB2克隆和迁移需求都能低成本搞定。只要提前规划好字符集、依赖顺序和导入方式,再配合LOAD加速,即使是TB级别的库也能在可接受的时间窗口内完成复制。