在DB2数据库中,游标cursor和LOAD技术相结合是进行数据迁移的有效解决方法,它的优点是迁移速度快,耗用时间短,当迁移海量数据时该优点尤其显著,而且被迁移的数据无需从源库导出保存到服务器文件系统上,节省存储空间,既适用于同一数据库内的数据迁移,也适用于异构操作系统平台上的不同DB2数据库间的数据迁移。
1、前言
在信息系统建设中,常常存在将某数据库中的数据一次性迁移到另一个数据库中的需求,这种迁移既可能发生在同一个数据库内的不同数据表之间,也可能会发生于不同数据库的数据表之间。本文假设场景是进行DB2数据库的数据迁移,如何准确、高效、方便地完成数据迁移,是DBA的重要工作。
2、游标和LOAD技术
DB2数据库进行数据迁移时,通常做法是首先从源库将数据用export方法导出保存到服务器文件系统上,然后再连接上目标数据库,用import方法将数据导入。但是这种方法存在两个缺点:
(1)、需要先将被迁移数据export导出保存到文件系统上,这将占用文件系统存储空间,尤其是当迁移海量数据时,导出文件所耗用的存储空间将十分巨大和可观。
(2)、import方法无法满足性能要求。用import方法向目标数据库加载数据时,速度低耗时长。尤其是当加载海量数据时,所耗费的时间将十分漫长。
使用游标和LOAD技术相结合进行数据迁移,可有效避免上述两个缺点:
(1)、使用游标方式的数据迁移,可避免导出文件耗用大量存储空间的缺点。它直接在源表、目标表之间进行数据的抽取、传输和加载,不需要将源表的数据先导出保存到文件系统上,不会产生中间数据文件。该方法快速高效、语法简洁,是一种数据迁移的好方法。
游标(cursor)是关系型数据库中的一个重要概念,它提供了一种对从表中检索出的数据进行操作的灵活有效的手段。游标是一个指针,检索出数据结果后,游标首先指向结果集中的第一条数据,当第一条数据读取完成后,指针自动移动指向结果集中的下一条数据,直至遍历完成整个数据集。
使用游标进行数据迁移时,需要事先创建出目标表的数据结构,而且目标表和源表的数据结构要保持一致或字段的数据类型是兼容的。
(2)、LOAD加载方式能显著提升数据加载速度,明显缩短所耗用的时间。LOAD的加载原理及与import的区别是:import加载数据时,是对数据按照行方式进行处理,使用数据库SQL引擎把数据一行一行加载进入数据库,而LOAD方式则是对加载数据按照DB2物理存储方式进行格式化,然后将格式化的数据按页进行处理,绕过数据库SQL引擎直接在底层将页数据加载进入数据库,数据处理效率十分高效,非常适合于加载海量数据的场景。
3、实现过程
3.1 语法说明
定义一个游标,然后使用LOAD方法操作游标将数据从源表写入目标表。假设迁移场景是:源表与目标表位于同一数据库(数据库的日志模式是循环日志模式),将源数据表tab1中的数据迁移到目标数据表newtab,目标表newtable的数据结构已经创建而且与源表保持一致,语法示例如下:
connect to dbname user username@
declare cur_1 cursor for select * from tab1@
load from cur_1 of cursor insert into newtab@
第一条语句的作用是连接数据库(语句中dbname指的是数据库名称,username指的是连接数据库的用户名);第二条语句的作用是游标的定义语句,cur_1是游标名称,从数据表tab1中检索所有字段的数据;第三条语句是使用load命令将游标中的数据加载进入目标表newtab。
执行上述语法需要在数据库服务器上执行,在数据库服务器上将上述语法保存成一个txt文件,然后在DB2 CLP环境中执行db2 �Ctd@ -vf filename.txt即可,在执行过程中,系统会提示用户输入密码,输入密码后,系统开始进行数据迁移。
3.2 特定数据类型的数据加载
若数据表中含有generated always as identity或generated always 类型的字段,那么上面的load命令在加载这种类型的字段时会出现报错,这时需要在load命令中添加特定的修饰符才能使数据加载成功。
当表中包含有generated always as identity类型的字段时,需要添加的修饰符是:modified by identityoverride。完整语法是:
connect to dbname user username@
declare cur_1 cursor for select * from tab1@
load from cur_1 of cursor modified by identityoverride insert into newtab@
当表中包含有generated always 类型的字段时,需要添加的修饰符是:modified by generatedoverride。完整语法是:
connect to dbname user username@
declare cur_1 cursor for select * from tab1@ load from cur_1 of cursor modified by generatedoverride insert into newtab@
3.3 不同数据库之间的数据迁移
以上场景中描述的是源表和目标表在同一数据库中的数据迁移,若源表和目标表位于两个不同的数据库中,这时就需要游标的database选项,以指定从哪个数据库来加载数据,语法是:
declare cur_1 cursor database srcdb user dbuser using pwd for select * from tab1@
上述语法中,srcdb指的是源表所在的数据库的名字,dbuser指的是连接源数据库的用户名,pwd是该用户名的密码,在实际使用时,用相应具体值代替。
完整语法是:
connect to dbname user username@
declare cur_1 cursor database srcdb user dbuser using pwd for select * from tab1@
load from cur_1 of cursor insert into newtab@
上面语法中,dbname指的是目标表newtable所在的数据库,srcdb是源表所在的数据库。执行上述语法需要在目标表newtable所在的数据库服务器上进行。
3.4 日志模式对数据加载的影响
load在对数据加载过程中,对数据库的影响与数据库的日志模式有关:当数据库的日志模式是循环日志模式时,load加载过程对数据库中其他数据表的存取并无影响,但当数据库的日志模式是归档日志模式时则会产生重要影响:load命令一运行就会立即将目标数据表所在的表空间置为backup pending状态,load命令运行完成后,表空间仍然处于backup pending状态,直至对整个数据库或对该表空间进行一次备份才会使表空间脱离backup pending状态回到正常状态。在此期间,表空间中的所有表的增删改操作都将会失败。如果目标数据库是一个已经投运在用的数据库,那么这种情况会使连接到此数据库的业务系统的运行发生中断,对于需要7X24连续不间断运行的信息系统来说,这种情况是不可接受的。
为避免这种情况,可以使用load命令的nonrecoverable选项,语法如下:
load from cur_1 of cursor insert into newtab nonrecoverable@
按照上述语法运行load数据加载,就不会影响表空间的状态,表空间仍然处于正常状态,对表空间中表的增删改操作都将继续正常进行,业务系统继续处于正常运行状态。
4、结束语
游标和LOAD技术相结合,能够实现快速迁移DB2数据库中的数据,对于迁移海量数据尤其有效。对于DBA,是一种迁移数据的较好方案。