Loadの考慮点
前回は以下を考慮してデータベースをExportをしました。
- レコード長が32KBを超える
- ラージオブジェクト(LOB)がある
前回の記事:Db2:データベースをLoadで全部移行してくれ
今回は以下を考慮してExportしたファイルをデータベースにLoadします。
- 自動生成列(GENERATED ALWAYS AS IDENTITY)がある
環境
Windows Server 2008 → 2016
Db2 Windows V10.1 → V11.5
Loadするやり方
Importは使わず、パフォーマンスに優れるLoadコマンドを使います。
- 自動生成列があるテーブルは"modified by identityoverride"を追加
- 自動生成列なしと自動生成列ありで処理を分割
- Load後、自動生成列のカウンターを修正
Loadではトリガーは起動しませんが後作業でImportをするなら、トリガーをに一旦ドロップし、作業完了後に再定義することを勧めます。
自動生成列なしテーブルをLoadするSQL
select current date as date, current time as time from sysibm.sysdummy1 ;
load from TACCTL.ixf of ixf replace into TACCTL ;
select current date as date, current time as time from sysibm.sysdummy1 ;
load from TADLDT.ixf of ixf replace into TADLDT ;
select current date as date, current time as time from sysibm.sysdummy1 ;
コマンドでシステムテーブルから自動生成列なしテーブルをLoadするSQLを生成します。
db2 -txf load_AllTable_without_ALWAYS.gen -z load_AllTable_without_ALWAYS.ddl
自動生成列なしLoadを生成するSQL(左の三角をクリックすると展開)
values( 'select current date as date, current time as time from sysibm.sysdummy1 ;' ) ;
select 'load from '
|| substr(concat(rtrim(TABNAME),'.ixf '),1,29)
|| ' of ixf replace into '
|| substr(TABNAME,1,25)
|| ' ;'
|| chr(10)
|| 'select current date as date, current time as time from sysibm.sysdummy1 ;'
from SYSCAT.TABLES
where not exists ( select * from SYSIBM.SYSCOLUMNS
where TABNAME = TBNAME
and GENERATED = 'A' )
and TYPE = 'T'
and TABSCHEMA = 'DB2ADMIN'
and TABNAME not like ('ADVISE_%')
and TABNAME not like ('EXPLAIN_%')
and TABNAME not in ('LOCKEVMON','OBJECT_METRICS')
order by TABSCHEMA, TABNAME ;
自動生成列ありテーブルをLoadするSQL
select current date as date, current time as time from sysibm.sysdummy1 ;
load from TC83TRGWT2_X2.ixf of ixf modified by identityoverride replace into TC83TRGWT2_X2 ;
select current date as date, current time as time from sysibm.sysdummy1 ;
load from TGW91UKE.ixf of ixf modified by identityoverride replace into TGW91UKE ;
select current date as date, current time as time from sysibm.sysdummy1 ;
"modified by identityoverride"を追加することで自動生成列の値をそのままLoadします。
コマンドでシステムテーブルから自動生成列ありテーブルをLoadするSQLを生成します。
db2 -txf load_AllTable_only_ALWAYS.gen -z load_AllTable_only_ALWAYS.ddl
自動生成列ありLoadを生成するSQL(左の三角をクリックすると展開)
values( 'select current date as date, current time as time from sysibm.sysdummy1 ;' ) ;
select 'load from '
|| substr(concat(rtrim(TABNAME),'.ixf '),1,29)
|| ' of ixf modified by identityoverride replace into '
|| substr(TABNAME,1,25)
|| ' ;'
|| chr(10)
|| 'select current date as date, current time as time from sysibm.sysdummy1 ;'
from SYSCAT.TABLES
where exists ( select * from SYSIBM.SYSCOLUMNS
where TABNAME = TBNAME
and GENERATED = 'A' )
and TYPE = 'T'
and TABSCHEMA = 'DB2ADMIN'
and TABNAME not like ('ADVISE_%')
and TABNAME not like ('EXPLAIN_%')
and TABNAME not in ('LOCKEVMON','OBJECT_METRICS')
order by TABSCHEMA, TABNAME ;
Loadの前処理
データベース構成パラメーターの変更
update db cfg for QIITA01 using LOGSECOND 50 ;
update db cfg for QIITA01 using LOGPRIMARY 100 ;
update db cfg for QIITA01 using MIRRORLOGPATH "" ;
update db cfg for QIITA01 using LOGARCHMETH1 off ;
update db cfg for QIITA01 using LOGARCHMETH2 off ;
update db cfg for QIITA01 using FAILARCHPATH "" ;
update db cfg for QIITA01 using LOGINDEXBUILD off ;
途中でバックアップを要求されないようアーカイブログを無効にしておきます。
Loadの実行
コマンドでLoadを実行します。
db2- tvf load_AllTable_without_ALWAYS.ddl -z load_AllTable_without_ALWAYS.log
db2 -tvf Load_AllTable_only_ALWAYS.ddl -z Load_AllTable_only_ALWAYS.log
Loadの後処理
自動生成列のカウンターを最大値+1に更新します。
IBM ウェブサイト:DB2: 自動生成列の値の確認方法
- データベースバックアップ
- Runstats(テーブル統計情報の更新)
- 自動生成列のカウンターを更新
- データベース構成パラメーターを元に戻す
自動生成列のカウンターを更新するSQL
alter table TKNPATD alter column N_SEQ restart with 1 ;
alter table TEVNTLOG alter column SEQ_NO restart with 63372804 ;
alter table TC83TRGWT alter column TRG_ID restart with 103501 ;
最大値に1を加算した値で更新します。現行の最大値は以下のSQLで確認します。
db2 select max(N_SEQ) from TKNPATD
コマンドでシステムテーブルからカウンターを更新するSQLを生成します。
db2 -txf update_seq.gen -z update_seq.sql
db2 -txf update_seq.sql -z update_seq.ddl
カウンターを更新するSQLを生成するSQL(左の三角をクリックすると展開)
select 'select ''alter table '
|| substr(TBNAME,1,25)
|| ' alter column '
|| substr(NAME,1,20)
|| ' restart with '' || char(case when max('
|| rtrim(NAME)
|| ') is null then 1 else max('
|| rtrim(NAME)
|| ')+1 end) || '';'' from '
|| rtrim(TBNAME)
|| ' ;'
from SYSIBM.SYSCOLUMNS
where GENERATED in('A','D') ;
さいごに
Export/Loadは以下の処理がキモになります。
- 32KBを超えるレコード
- ラージオブジェクト(LOB)
- 自動生成列(GENERATED ALWAYS AS IDENTITY)
最後までお読みいただき誠にありがとうございました。