ITPub博客

首页 > Linux操作系统 > Linux操作系统 > DB2 V9.7 新特性:在线移动表

DB2 V9.7 新特性:在线移动表

原创 Linux操作系统 作者:ArtCode 时间:2009-11-13 16:39:14 0 删除 编辑

转自:http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0911luohq/index.html?ca=drs-cn-1112

简介

目前大多企业 DB2 生产环境都要求高可用,不能承担片刻停机带来的损失。当 DBA 希望将表从一个表空间移动到另一个表空间中,在 DB2 V9.7 以前的版本中要实现这个目标比较复杂,总有一段时间表对外是不可用的。DB2 V9.7 提供了 ADMIN_MOVE_TABLE 存储过程将表中的数据移至名称相同的新表对象,而新表是存放在不同的表空间上具有不同的存储特征,同时数据保持联机可供访问。我们还可以在表移动时为表生成新的优化压缩字典。

DB2 V9.7 通过自动将表数据移至新表对象并同时允许数据保持联机以进行查询、插入、更新和删除访问,降低了企业的总体拥有成本(TCO)和复杂性。

在表数据移动过程中我们还可以使用 ADMIN_MOVE_TABLE 存储过程修改表的定义,如增加删除列、修改列数据类型等。

在线数据移动过程

ADMIN_MOVE_TABLE 过程涉及三个表:

  • 源表。源表是指数据将被移动走的表,通过参数形式传递给 ADMIN_MOVE_TABLE 存储 过程。
  • 目标表。目标表由 ADMIN_MOVE_TABLE 根据传递入的参数定义新创建的表,所有源表中的数据将复制到目标表中,并且最后被命名成与源表相同的表名。
  • 登台表。由 ADMIN_MOVE_TABLE 存储 过程创建,在表移动过程中用于临时保持对源表的所有 Update、Insert、Delete 操作。当移动完成后,该表将被删除。

数据移动过程还涉及一个表被成为协议表(protocol table),这个表将用于保存数据移动的过程数据和配置信息,如数据移动使用的参数、COPY 开始的时间、结束时间、COPY 使用的选项等。此表定义如下:


清单 1. 协议表的定义

				
 C:\>db2 describe table systools.ADMIN_MOVE_TABLE 

 数据类型  列
列名 模式 数据类型名称 长 小数位 NULL 
 --------------- --------- ------------------- ---------- ----- - 
 ----- 
 TABSCHEMA SYSIBM VARCHAR 128 0 否
 TABNAME SYSIBM VARCHAR 128 0 否
 KEY SYSIBM VARCHAR 32 0 否
 VALUE SYSIBM CLOB 10485760 0 是


其中关键字(KEY)都有特定含义,当我们对表数据移动进行问题诊断、调整性能时都会使用到该表。

ADMIN_MOVE_TABLE 过程将首先创建源表的影子副本。在复制阶段,DB2 将使用触发器捕获对源表的插入、更新和删除操作并将其放入到登台表中。完成复制阶段后,DB2 在登台表中捕获的数据更改操作将在影子副本中重现。最后 DB2 使用 ADMIN_MOVE_TABLE 过程将使表短暂脱机以交换对象名。ADMIN_MOVE_TABLE 默认情况下使用 INSERT Cursor 的方式将数据从源表复制到目标表,也可以指定选项使用 LOAD 方式复制数据以提高性能。

从过程上看,表数据移动大致分为以下几个阶段:

  • INIT 阶段。本阶段验证数据移动是否可以发生,并且初始化后继数据移动所需要的各种数据,如目标表、登台表、源表触发器。
  • COPY 阶段。本阶段将源表中的所有数据复制到 INIT阶段创建的目标表中,如果在此时有用户对源表执行 DML语句,则 INIT阶段创建的触发器将会捕获到这些语句,并且将任何更新、删除、插入操作保存到登台表中。在复制阶段结束后,如果我们没有使用 COPY_WITH_INDEXES选项,则目标表上将会建立新的索引。而且如果需要的话,源表、目标表上将会建立辅助索引帮助提高 REPLAY阶段的性能。COPY阶段只能在 INIT阶段完成后开始。
  • REPLAY 阶段。在 COPY阶段保存到登记表的所有数据将在本阶段被 Replay到目标表。REPLAY阶段只能在 COPY阶段完成后开始。
  • VERIFY 阶段。本阶段是可选的,用于检查目标表和源表是否在内容上等同。检查过程首先在源表、目标表上获取 S锁,然后 Replay源表上的所有变化,然后与目标表进行比较。如果表拥有唯一索引,则会比较两个表中都存在的列的所有值,如果没有唯一索引将不比较 LONG、LOB、XNML列的值。.验证工作是一个成本很高的操作,我们在使用时必须要判断是否真的需要这么做。VERIFY阶段只能在 COPY阶段或者 REPLAY阶段完成后开始。
  • SWAP 阶段。在 Replay阶段完成后或者达到协议表中保存的 REPLAY_THRESHOLD值设置时,源表将被脱机,然后 DB2交互源表和目标表的名字,重新把表联机。SWAP阶段可以在 COPY完成后启动,最好时在 REPLAY调用完成后启动。
  • CLEANUP 阶段。本阶段将会删除在 INIT阶段创建的登台表,触发器。如果调用过程中没有使用 KEEP选项,源表也将会被删除。CLEANUP阶段可以在 SWAP阶段之后被调用。

我们需要注意的是 ADMIN_MOVE_TABLE 可以将源表上定义的触发器、视图也同时移动到目标表,但是当前它并不能支持将外键关系复制到目标表,无论源表是外键的父表还是子表。因此如果源表上有外键关系存在,我们首先需要捕获这些外键定义,然后在移动完成后在目标表上重新创建。

ADMIN_MOVE_TABLE 语法

DB2 中存在两种合法的 ADMIN_MOVE_TABLE 语法形式。第一种方法用于我们修改在目标表上修改指定的部分的定义,如我们有一个定义很长的表,而我们希望做的仅仅时修改表存放的表空间,用第一种语法我们就不需要重新创建表而直接使用 ADMIN_MOVE_TABLE 修改。我们需要做的仅仅是在参数中指定 data_tbsp、index_tbsp、和 lob_tbsp,而把其他可选参数设置为空即可。

DB2 提供的第二种语法让我们更加灵活、方便的控制目标表的创建,而不使用存储过程创建目标表。这让我们能够在第一种方法没有办法创建目标表的情况下手工创建目标表。


清单 2. 方法 1 语法

				
 >>-ADMIN_MOVE_TABLE--(--tabschema--,--tabname--,----------------> 

 >--data_tbsp--,--index_tbsp--,--lob_tbsp--,--mdc_cols--,--------> 

                             .-,-------. 
                             V | 
 >--partkey_cols--,--data_part--,--coldef--,----options-+--,-----> 

 >--operation--)------------------------------------------------>< 



清单 2. 方法 2 语法
				
 >>-ADMIN_MOVE_TABLE--(--tabschema--,--tabname--,----------------> 

               .-,-------. 
               V | 
 >--target_tabname--,----options-+--,--operation--)------------->< 


存储过程中使用的参数含义如下:

  • tabschema ,源表模式。
  • tabname,源表名称
  • data_tbsp,指定目标表的新数据存放表空间。如果此参数有值,则 index_tbsp and lob_tbsp 参数需要存在。如果该值未提供,则源表数据表空间用来保持目标表的数据。
  • index_tbsp,指定目标表的新索引表空间。如果该值被提供,则 data _tbsp and lob_tbsp 参数需要存在。如果该值未被提供,则源表索引表空间被用来保存目标表的索引。
  • lob_tbsp, 指定目标表的大对象表空间,如果该值被提供,则 data _tbsp and index_tbsp 参数需要存在。如果该参数未指定值,则源表大对象表空间被用来保存目标表的大对象。
  • mdc_cols,指定目标表的多维列(MDC),多列之间使用逗号隔开。如果值为 NULL 或者’ - ‘,目标表将不会使用 ORGANIZE BY DIMENSIONS 子句创建 MDC 表。如果值为空串或者’ - ‘,DB2 将检查源表上是否指定了 MDC,如果存在则使用源表的 MDC。
  • partkey_cols,指定目标表的分区键列,多列之间使用逗号隔开。如果值未 NULL 或者’ - ‘,目标表将不会 PARTITIONING KEY 子句创建目标表。如果值为空串或者’ - ‘,DB2 将检查源表上是否指定了分区键,,如果存在则使用源表的分区键。
  • data_part,本参数提供目标表的数据分区详细规格。本语句定义了如何将表根据表的一个或多个列的值存放在多个存储目标上。如果值未 NULL 或者’ - ‘,目标表将不会 PARTITIONING RANGE 子句。如果值为空串或者’ - ‘,DB2 将检查源表上是否指定了分区模式,如果存在则使用源表的分区模式。
  • coldef,指定目标表的列定义,方便我们将列的修改为兼容的数据类型,不过列名必须相同。该参数提供了增加新列、删除存在的列功能,只有存在唯一索引或主键索引的表中才能删除列,同时列不能是主键或者唯一键的一部分。
  • target_tabname ,指定目标表名称,在完成数据移动后该名称将作为新表的名字。当我们指定,目标表的名字时,我们我们可以对目标表进行以下变化:
    • 数据、索引、LOB 表空间可以改变
    • 可以增加或变化多维列(MDC)规格。
    • 可以增加或者变化分区键列规格。
    • 可以增加或者变化数据分区规格。
    • 可以启动或者停止数据压缩。
    • 可以增加新列。

    当指定目标表的名字时,存在以下约束:

    • 源表与目标表的模式必须相同
    • 如果目标表已经存在,则目标表必须为空
    • 不能为类型表、物化查询表、登台表、远程表、或者聚集表
  • 选项。多个选项可以使用逗号隔开:
    • KEEP。该选项将会使源表保存为另外一个名字的 COPY。如源表名为 T1,在数据移动完成后,源表将被命名为 T1AAAAVxo。我们可以在协议表中的 ORIGINAL 关键字下找到源表的新名字。
    • COPY_USE_LOAD。该选项使用不可恢复的 db2Load API 从源表复制数据到目标表。如果使用该选项,则 FORCE 选项需要被包含。
    • COPY_WITH_INDEXES。此选项指定在 COPY 源表之前创建索引。默认情况下 DB2 时在源表 COPY 后创建索引的。使用该选项的好处是在 COPY 后不在需要每创建一个索引进行一次表扫描,索引创建受需要活动日志的事务控制;缺点是会使得 COPY 的性能下降,因为需要在目标表上维护索引,同时索引上有很多伪删除的键。
    • FORCE。如果指定此选项 SWAP 阶段将不会检查源表是否修改了其定义。
    • NO_STATS。该选项指定不启动对目标表的 Runstats 命令或者复制统计信息。
    • COPY_STATS。该选项指定在 SWAP 阶段之前从源表中复制统计信息到目标表。
    • NO_AUTO_REVAL。该选项防止自动进行表的 Revalid 操作,而是直接重新创建所有索引、视图。
    • REORG。该选项指定在 SWAP 之前对目标表进行脱机重组,可以用于重构数据字典。
  • Operation。该选项指定期望进行的操作,一般为 MOVE。我们也可以手工把 MOVE 拆分开,依次手工执行 INIT、COPY、REPLAY、VERIFY、SWAP、CLEANUP。当移动到某个阶段,我们想取消移动时,可以使用 CANCEL 操作。


ADMIN_MOVE_TABLE_UTIL 的使用

我们知道 DB2 在移动表数据时,会使用表 systools .ADMIN_MOVE_TABLE 保存数据移动配置和状态信息,该表是以 tabschema、tabname、key 列为主键。ADMIN_MOVE_TABLE_UTIL 存储过程可以用来更改协议表 ADMIN_MOVE_TABLE 中定义的键值。


清单 4. ADMIN_MOVE_TABLE_UTIL 语法

				
 >>-ADMIN_MOVE_TABLE_UTIL--(--tabschema--,--tabname--,--action--,--key--,--value--)->< 

其中:

  • Tabschema 指定准备修改的正在移动的表的模式
  • Tabname 指定准备修改的正在移动的表的名称
  • Action 指定存储过程即将执行的动作,可以取以下执行
    • UPSERT,插入更新。如果 Key 值指定的关键值存在则使用新值更新,否则则在表 ADMIN_MOVE_TABLE 中使用 Key、Value 指定的值插入一行
    • DELETE,删除。根据 Tabschema、Tabname、key 指定的删除表 ADMIN_MOVE_TABLE 中行。
  • Key 指定准备修改的数据移动过程中的参数。Key 可以取以下值:
    • COMMIT_AFTER_N_ROWS。指定在 COPY 阶段多少行 Commit 一次。默认值为 0 表示 COPY 阶段执行过程中不 Commit。
    • DEEPCOMPRESSION_SAMPLE。如果源表是压缩的,本参数指定创建压缩数据字典时采样数据的大小(KB 为单位)。默认值为 0 表示不采样。
    • COPY_ARRAY_SIZE。指定 COPY_ARRAY_INSERT 时 ARRAY 的大小,如果小于或等于 0 表示不使用 COPY_ARRAY_INSERT
    • COPY_INDEXSCHEMA。在 COPY 阶段用于聚焦目标表的索引模式。
    • COPY_ INDEXNAME。在 COPY 阶段用于聚焦目标表的索引名称。
    • REPLAY_MAX_ERR_RETRIES。在 REPLAY 阶段允许的最大错误重试次数。REPLAY 阶段经常碰到的错误为锁超时或者死锁。
    • REPLAY_THRESHOLD。在一轮 REPLAY 阶段过程中,当应用了登台表中指定的行数后,REPLAY 将停止,及时同时登台表中有了新的条目。
    • REORG_USE_TEMPSPACE。如果我们在表移动中使用了 REORG 选项,我们可以通过本参数指定 REORG 过程中使用的临时表空间。如果未指定该参数,REORG 将使用与表相同的表空间执行重组。
    • SWAP_MAX_RETRIES。指定在 SWAP 阶段,允许的最大错误重试次数。SWAP 阶段经常碰到的错误为锁超时或者死锁。
  • Value。准备设置 Key 指定关键字的值,该参数为 CLOB(10M) 数据类型,可以取 NULL 或空串。


清单 5. ADMIN_MOVE_TABLE_UTIL 例子

			
 CALL SYSPROC.ADMIN_MOVE_TABLE('SVALENTI','T1','','','','','','','','','INIT') 
 CALL SYSPROC.ADMIN_MOVE_TABLE_UTIL('SVALENTI','T1','UPSERT', 
  'DEEPCOMPRESSION_SAMPLE','30720') 
 CALL SYSPROC.ADMIN_MOVE_TABLE_UTIL('SVALENTI','T1','DELETE','COPY_INDEXSCHEMA','') 
 CALL SYSPROC.ADMIN_MOVE_TABLE_UTIL('SVALENTI','T1','DELETE','COPY_INDEXNAME','') 
 CALL SYSPROC.ADMIN_MOVE_TABLE('SVALENTI','T1','','','','','','','','','COPY') 
 CALL SYSPROC.ADMIN_MOVE_TABLE('SVALENTI','T1','','','','','','','','','REPLAY') 
 CALL SYSPROC.ADMIN_MOVE_TABLE('SVALENTI','T1','','','','','','','','','SWAP') 

上面清单中首先使用默认值启动数据移动 INIT 阶段,然后使用 ADMIN_MOVE_TABLE_UTIL 过程修改压缩采样大小为 30720 KB,并删除 COPY_INDEXSCHEMA、COPY_INDEXNAME 设置,然后继续数据移动过程。

数据移动例子

使用 DB2 在线表移动功能,我们可以进行:

  • 在线表压缩。
  • 在表重组或者重分布
  • 在线将表空间转换为 LARGE 表空间
  • 将数据 / 索引 /LONG 移动到新的不同的表空间
  • 支持表模式变化,如增加列、删除列、修改列数据类型,增加或修改 MDC 维定义,增加或修改范围分区键、增加或修改表分区键

我们首先创建测试表 EMP_TEST,并创建索引,然后向表中插入 10 万条测试数据。


清单 6. 创建测试表

				
 CREATE TABLE emp_test ( 
  EMPNO INTEGER NOT NULL, 
  first_name VARCHAR(128) NOT NULL, 
  last_name VARCHAR(128), 
  SALARY DECIMAL, 
  BONUS DECIMAL, 
  COMM DECIMAL, 
  CONSTRAINT EMPNO_pk PRIMARY KEY (EMPNO) 
		 ) 
  IN USERSPACE1; 
  
 Create index first_name_idx on emp_test(first_name); 
 Create index last_name_idx on emp_test(last_name); 
  
				 
 INSERT INTO emp_test (EMPNO, first_name, last_name,SALARY,BONUS,COMM) 
 WITH TEMP (COUNTER,  first_name, last_name,SALARY,BONUS,COMM) AS 
 ( 
  VALUES (0, 
  VARCHAR(MOD(INT(RAND() * 100000), 99999)), 
  VARCHAR(MOD(INT(RAND() * 100000), 99999)), 
  MOD(INT(RAND() * 100000), 99999), 
  MOD(INT(RAND() * 100000), 99999), 
   MOD(INT(RAND() * 100000), 99999) 
  ) 
  UNION ALL 
  SELECT 
  (COUNTER + 1), 
  VARCHAR(MOD(INT(RAND() * 100000), 99999)), 
  VARCHAR(MOD(INT(RAND() * 100000), 99999)), 
  MOD(INT(RAND() * 100000), 99999), 
  MOD(INT(RAND() * 100000), 99999), 
  MOD(INT(RAND() * 100000), 99999) 

  FROM 
  TEMP 
  WHERE 
  (COUNTER + 1) < 100000 
 ) 
 SELECT 
  COUNTER, first_name, last_name,SALARY,BONUS,COMM 
 FROM 
  TEMP 
 ; 

 runstats on table db2admin.emp_test and indexes all; 

测试一:移动表到新表空间

我们创建测试表空间 TS_TEST,然后将 EMP_TEST 中的数据、索引、LONG 对象全部移动到 TS_TEST 表空间中。

 CREATE TABLESPACE TS_TEST; 
  
 CALL SYSPROC.ADMIN_MOVE_TABLE 
  ('DB2ADMIN', 'EMP_TEST', 
  'TS_TEST', 'TS_TEST', 'TS_TEST', 
  '', '', '', '', '', 'MOVE'); 

  结果集 1 
  -------------- 

  KEY VALUE 
		 -------------------------- ------------------------ 
  AUTHID USERID 
				 CLEANUP_END 2009-08-18-14.38.40.390000 
				 CLEANUP_START 2009-08-18-14.38.39.827000 
				 COPY_END 2009-08-18-14.38.29.546000 
				 COPY_OPTS OVER_INDEX,ARRAY_INSERT 
				 COPY_START 2009-08-18-14.38.20.452000 
				 COPY_TOTAL_ROWS 100000 
				 INDEXNAME EMPNO_PK 
				 INDEXSCHEMA USERID 
				 INDEX_CREATION_TOTAL_TIME 7 
				 INIT_END 2009-08-18-14.38.20.311000 
				 INIT_START 2009-08-18-14.38.19.124000 
				 REPLAY_END 2009-08-18-14.38.38.905000 
				 REPLAY_START 2009-08-18-14.38.29.561000 
				 REPLAY_TOTAL_ROWS 0 
				 REPLAY_TOTAL_TIME 0 
				 STATUS COMPLETE 
  SWAP_END 2009-08-18-14.38.39.733000 
				 SWAP_RETRIES 0 
				 SWAP_START 2009-08-18-14.38.39.108000 
				 VERSION 09.07.0000 

  21 条记录已选择。

  返回状态 = 0 

数据移动结果集实际上是从协议表 ADMIN_MOVE_TABLE 中选择出来的数据。结果集显示 COPY 10 万行数据花费了 9.1 秒,REPLAY 花费 9.4 秒,SWAP 花费 0.6 秒,合计 21.1 秒,这表明数据移动过程绝大部分时间花费在 COPY 和 REPLAY 阶段。如果我们希望能够优化数据移动过程,应主要从这个阶段入手。

测试二:性能优化

在 COPY 有两个对性能影响比较大的选项,一个为 COPY_WITH_INDEXES,一个为 COPY_USE_LOAD。

COPY_WITH_INDEXES 选择指定在 COPY 源表之前就创建索引,这样在复制过程中需要对索引进行维护,因此性能会下降,不过优点是索引创建收到事务保护。默认情况下不使用 COPY_WITH_INDEXES,如果大家在协议表 ADMIN_MOVE_TABLE 的 COPY 选项中发现”WITH_INDEXES”则表示先创建了索引。

DB2 进行表数据移动时,默认采用 INSERT FROM CURSOR 方法进行 COPY,这种方法需要对复制的每一行执行一个 Insert 操作,引起的负担与我们平时执行 Insert 完全相同。我们可以通过设置选项 COPY_USE_LOAD 采用 LOAD API 方式进行 COPY 以提高性能。使用 LOAD API 的优点是:

  • LOAD 过程不会对表的每一行记录日志 .
  • LOAD 可以利用 CPU 并行性和 IO 并行性
  • LOAD 可进行大块 IO,这有利于提高 IO 的效率

不过需要注意的是,使用 LOAD API 时,与使用 LOAD 命令加载数据一样,过程是不可恢复的。因此最好在 LOAD 后执行一次数据库备份,或者在 LOAD 时指定选项 COPY 或 KEEP 以保存一份原始数据。

 CALL SYSPROC.ADMIN_MOVE_TABLE 
('USERID', 'EMP_TEST', 'NEW_TS', 'NEW_TS', 'NEW_TS', '', '', '', '', 'COPY_USE_LOAD,FORCE', 'MOVE') 
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|


  结果集 1 
  -------------- 

  KEY VALUE 
		 ---------------------- ---------------------- 
 AUTHID USERID 
				 CLEANUP_END 2009-08-18-14.44.48.952000 
				 CLEANUP_START 2009-08-18-14.44.48.327000 
				 COPY_END 2009-08-18-14.44.45.155000 
				 COPY_OPTS OVER_INDEX,LOAD,WITH_INDEXES 
				 COPY_START 2009-08-18-14.44.37.171000 
				 COPY_TOTAL_ROWS 100000 
				 INDEXNAME EMPNO_PK 
  INDEXSCHEMA USERID 
				 INDEX_CREATION_TOTAL_TIME 1 
				 INIT_END 2009-08-18-14.44.36.640000 
				 INIT_START 2009-08-18-14.44.35.436000 
				 REPLAY_END 2009-08-18-14.44.47.186000 
				 REPLAY_START 2009-08-18-14.44.45.155000 
				 REPLAY_TOTAL_ROWS 0 
				 REPLAY_TOTAL_TIME 0 
				 STATUS COMPLETE 
				 SWAP_END 2009-08-18-14.44.48.155000 
				 SWAP_RETRIES 0 
				 SWAP_START 2009-08-18-14.44.47.186000 
				 VERSION 09.07.0000 
				 21 条记录已选择。

  返回状态 = 0 

上述结果集显示 COPY 10 万行数据花费了 8 秒,REPLAY 花费 2 秒,SWAP 花费 1 秒,合计 13.1 秒。在这个例子中我们使用了 COPY_USE_LOAD 选项,即采用 LOAD API 加载数据,比使用 INSERT FROM CURSOR 方法快 36%。

总结

DB2 V9.7 提供的 ADMIN_MOVE_TABLE 存储过程能够帮助 DBA 在线的修改表,包括表空间、表定列义、表压缩、表分区等,这为 DBA 保持系统高可用性。在使用 ADMIN_MOVE_TABLE 存储过程时,我们也会经常碰到错误,主要和表移动状态有关:

  • 联机移动表操作所处的状态不允许执行指定的操作
  • 没有正在执行中的联机移动表操作;因此,不允许执行指定的操作。
  • 存在正在执行中的联机移动表操作;不允许对同一个表执行并行的联机表移动操作。
  • 该表是联机表移动操作的目标表、登台表或协议表,因此不可移动。
  • 正在执行现场重组操作,此操作不允许执行联机移动表操作的复制阶段。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/15082138/viewspace-619593/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-08-05

  • 博文量
    269
  • 访问量
    609698