DBMS_REDEFINITIONパッケージを使用したOracleオンライン表パーティション
Oracle®10g以降では、DBMS_REDEFINITIONパッケージを使用することで、アプリケーションのダウンタイムなしでテーブルをオンラインでパーティション化できます。
次の手順を使用して、DBMS_REDEFINITIONを使用して非パーティションテーブルをパーティションテーブルに変更します。この例では、非パーティションテーブルTABLEAを範囲間隔パーティションテーブルに変更します。
ステップ1:パーティション解除テーブルをバックアップします
次のコードを実行して、テーブルTABLEAの完全なエクスポートバックアップを作成します。
expdp \"/ as sysdba\" directory=EXPDP_DIR dumpfile=tableA_UNPAR.dmp logfile=tableA_UNPAR.log TABLES=TEST.TABLEA
expdp \"/ as sysdba\" directory=EXPDP_DIR dumpfile=tableA_metaunpar.dmp logfile=tableA_metaunpar.log TABLES=TEST.TABLEA content=metadata_only
ステップ2:データベースオブジェクトを調べる
次の依存(D)データベースオブジェクトは、テーブルがドロップされるときにドロップされる可能性があります。
-
制約(制約)D
-
INDEX(インデックス)D
-
MATERIALIZED_VIEW_LOG(マテリアライズドビューログ)D
-
OBJECT_GRANT(オブジェクト付与)D
-
TRIGGER(トリガー)D
次のSQLコマンドを実行し、出力をcons_trig_indx.txt
などのスプールファイルに保存します。 :
set LINESIZE 500
set PAGESIZE 1000
SQL> spool cons_trig_indx.txt
SQL> select name, type, owner from all_dependencies where referenced_owner = 'TEST' and referenced_name = 'TABLEA';
NAME TYPE OWNER
-------------- -------------- -------
PROC_TABLEA PROCEDURE TEST
TABLEA_TRIGG TRIGGER TEST
PKG_TABLEA PACKAGE BODY TEST
SQL> select OWNER, INDEX_NAME, TABLE_OWNER, TABLE_NAME, STATUS, TABLESPACE_NAME
from dba_indexes where TABLE_OWNER='TEST' and TABLE_NAME='TABLEA';
OWNER INDEX_NAME TABLE_OWNER TABLE_NAME STATUS TABLESPACE_NAME
---------------------------------------------------------------------------
TEST TABLEA_IDX_ID01 TEST TABLEA VALID TABLEA_TBL
TEST TABLEA_IDX_ID04 TEST TABLEA VALID TABLEA_TBL
TEST TABLEA_IDX_PK TEST TABLEA VALID TABLEA_TBL
SQL> select STATUS, OBJECT_TYPE, OBJECT_NAME from dba_objects
where OWNER='TEST' and OBJECT_TYPE = 'TRIGGER' and STATUS='INVALID';
no rows selected
SQL> select CONSTRAINT_NAME, CONSTRAINT_TYPE from dba_constraints
where TABLE_NAME='TABLEA' and owner='TEST';
SQL> spool off
CONSTRAINT_NAME C
------------------ -----
SYS_C002004601 C
SYS_C002004602 C
SYS_C002004603 C
IDX_PK P
FK01 R
ステップ3:TABLEAのDDLをキャプチャする
次のコマンドを実行して、TABLEAのデータ定義言語(DDL)をキャプチャし、スクリプトをスプールファイルDEF_TABLEA.sql
に保存します。 パーティションテーブルを作成する前に:
set echo off
set feedback off
set linesize 160
set long 2000000
set pagesize 0
set trims on
column txt format a150 word_wrapped
SQL> spool DEF_TABLEA.sql
SQL> select DBMS_METADATA.GET_DDL('TABLE','TABLEA','TEST') txt FROM dual;
SQL> spool off
ステップ4:DDLスクリプトをコピーする
次のコマンドを実行して、手順3で作成したDDLスクリプトをコピーします。
cp DEF_TABLEA.sql DEF_TABLEA_PAR.sql
ステップ5:非パーティションテーブルの日付を確認します
次のコマンドを実行して、TABLEAの日付を検索します。
SQL> select * from (select DT from TEST.TABLEA where rownum <15 order by DT DESC);
ステップ6:DEF_TABLEA_PAR.sqlファイルを編集する
DEF_TABLEA_PAR.sql
を編集します 次の変更を行うには:
-
TABLEAのすべての出現箇所を変更します TABLEA_PARへ 。
-
NOTNULLやその他の制約などのすべての制約を削除します。
-
次のコマンドを挿入して、テーブルが新しいテーブルスペースに作成されるようにします。
TABLESPACE "TABLEA_TBL_PAR" LOGGING
-
次のコマンドを挿入して、手順5で特定した日付に基づいてパーティション定義を追加します。
PARTITION BY RANGE(DT) interval (numtoyminterval(1,'MONTH')) (partition TABLEA_2004 values less than (to_date('01/01/2005','DD/MM/YYYY')), partition TABLEA_2005 values less than (to_date('01/01/2006','DD/MM/YYYY')));
DEF_TABLEA_PAR.sql
ファイルは次の例のようになります。
CREATE TABLE "TEST"."TABLEA_PAR"
( "ID" NUMBER(6,0),
"CEID" NUMBER(6,0),
"DT" DATE,
"AMT" NUMBER(14,4),
"RET" NUMBER(14,4),
"CNT" NUMBER(4,0),
"VCNT" NUMBER(4,0),
"EXEDT" DATE,
"LASTUPDBY" VARCHAR2(15),
"VENUM" NUMBER(6,0),
"LASTUPDDT" TIMESTAMP (6))
TABLESPACE "TABLEA_TBL_PAR" LOGGING
PARTITION BY RANGE(DT)
interval (numtoyminterval(1,'MONTH'))
(partition TABLEA_2004 values less than (to_date('01/01/2005','DD/MM/YYYY')),
partition TABLEA_2005 values less than (to_date('01/01/2006','DD/MM/YYYY')));
ステップ7:パーティションテーブルを作成する
次の手順を実行してパーティションテーブルを作成し、DEF_TABLEA_PAR.sql
を実行します。 スクリプト:
SQL> spool DEF_TABLEA_PAR.outp.txt
SQL> @DEF_TABLEA_PAR.sql
Table Created.
SQL> spool off
ステップ8:パーティションテーブルを確認します
次のコマンドを実行して、パーティションテーブルを確認し、定義されたパーティションを返します。
SQL> spool verify_partition.txt
SQL> select partition_name from DBA_tab_partitions where table_name ='TABLEA_PAR' and table_owner = 'TEST';
SQL> spool off
PARTITION_NAME
-----------------
TABLEA_2004
TABLEA_2005
ステップ9:非パーティションテーブルの統計を収集する
次のコマンドを実行して、非パーティションテーブルの統計を収集し、スプールファイルに保存します。
SQL> SPOOL gather_stats.txt
SQL> exec dbms_stats.gather_table_stats ('TEST', 'TABLEA',cascade => TRUE);
SQL> spool off
ステップ10:再定義の実現可能性を確認する
注 :再定義パッケージを使用する前に、ソーステーブル(パーティション化されていない)に主キーは必要ありません。
次のコマンドを実行して再定義が可能かどうかを確認し、結果をスプールファイルに保存します。
SQL> spool check_the_redefinition.txt
SQL> EXEC DBMS_Redefinition.can_redef_table ('TEST', 'TABLEA');
SQL> spool off
ステップ11:再定義を開始する
check_the_redefinition.txt
にエラーがリストされていない場合 、次の長時間実行コマンドを使用して再定義を開始します。
SQL> spool start_redef_table.txt
SQL>begin
dbms_redefinition.start_redef_table
(
uname => 'TEST',
orig_table => 'TABLEA',
int_table => 'TABLEA_PAR');
end;
/
SQL> spool off
ステップ12:再定義中のテーブルスペースエラーを監視します
手順11の再定義操作により、次の例のような表領域アラートが発生する可能性があります。
ERROR at line 1:
ORA-12008: error in materialized view refresh path
ORA-01688: unable to extend table TEST.TABLEA_PAR
partition SYS_P42 by 1024 in tablespace TABLEA_TBL
ORA-06512: at "SYS.DBMS_REDEFINITION", line 52
ORA-06512: at "SYS.DBMS_REDEFINITION", line 1646
ORA-06512: at line 2
ERROR at line 1:
ORA-12008: error in materialized view refresh path
ORA-14400: inserted partition key does not map to any partition
ORA-06512: at "SYS.DBMS_REDEFINITION", line 52
ORA-06512: at "SYS.DBMS_REDEFINITION", line 1646
ORA-06512: at line 2
前の例と同様のテーブルスペースエラーが表示された場合は、次の手順を実行する必要があります。
-
次のコマンドを実行して、再定義プロセスを停止します。
SQL> spool abort_redef_table.txt SQL> begin dbms_redefinition.abort_redef_table ( uname => 'TEST', orig_table => 'TABLEA', int_table => 'TABLEA_PAR'); end; / SQL> spool off
-
パーティションテーブルとマテリアライズドビューを削除します。
-
表領域のサイズを増やします。この例では、表領域TABLEA_TBLのサイズを増やす必要があります。
-
手順11を再実行します。
ステップ13:再定義エラーを確認する
再定義プロセスが正常に完了したら、次のコマンドを実行してエラーをチェックします。
SQL> spool copy_table_dependents.txt
SQL> SET SERVEROUTPUT ON
DECLARE
l_num_errors PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.copy_table_dependents(
uname => 'TEST',
orig_table => 'TABLEA',
int_table => 'TABLEA_PAR',
copy_indexes => DBMS_REDEFINITION.cons_orig_params, -- Non-Default
num_errors => l_num_errors);
DBMS_OUTPUT.put_line('l_num_errors=' || l_num_errors);
END;
/
SQL> spool off
再定義が成功すると、copy_table_dependents.txt
の次のような結果が表示されます。 ファイル:
l_num_errors=0
PL/SQL procedure successfully completed.
ステップ14:(オプション)パーティションテーブルを再同期します
必要に応じて、次のコマンドを実行して、パーティションテーブルを暫定名で再同期します。
SQL> spool sync_interim_table.txt
SQL>
BEGIN
DBMS_REDEFINITION.sync_interim_table
(
uname => 'TEST',
orig_table => 'TABLEA',
int_table => 'TABLEA_PAR');
END;
/
SQL> spool off
ステップ15:パーティションテーブルの統計を収集する
次のコマンドを実行して、パーティションテーブルの統計を収集します。
SQL> spool gather_statistics_par.txt
SQL> exec dbms_stats.gather_table_stats ('TEST', 'TABLEA_PAR',cascade => TRUE);
SQL> spool off
ステップ16:制約スクリプトを作成する
次のコマンドを実行して、検証制約を有効にするスクリプトを準備します。
SQL> spool constraint_enable_validate.txt
SET LINESIZE 500
SET PAGESIZE 1000
SQL> select 'alter table' ||' '||OWNER||'.'||TABLE_NAME||' enable validate constraint'||' '||CONSTRAINT_NAME||';' from dba_constraints where TABLE_NAME = 'TABLEA_PAR' and OWNER='TEST';
'ALTERTABLE'||''||OWNER||'.'||TABLE_NAME||'ENABLEVALIDATECONSTRAINT'||''||CONSTR
--------------------------------------------------------------------------------
alter table TEST.TABLEA_PAR enable validate constraint TMP$$_SYS_C002004601;
alter table TEST.TABLEA_PAR enable validate constraint TMP$$_SYS_C002004602;
alter table TEST.TABLEA_PAR enable validate constraint TMP$$_SYS_C002004603;
alter table TEST.TABLEA_PAR enable validate constraint TMP$$_IDX_PK;
alter table TEST.TABLEA_PAR enable validate constraint TMP$$_FK01;
SQL> spool off
ステップ17:検証制約を有効にする
次の例に示すように、手順16で作成したスクリプトとコマンドを実行します。
SQL> spool constraint_enable_execute.outp.txt
SQL>@constraint_enable.sql
alter table TEST.TABLEA_PAR enable validate constraint TMP$$_SYS_C002004601;
alter table TEST.TABLEA_PAR enable validate constraint TMP$$_SYS_C002004602;
alter table TEST.TABLEA_PAR enable validate constraint TMP$$_SYS_C002004603;
alter table TEST.TABLEA_PAR enable validate constraint TMP$$_IDX_PK;
alter table TEST.TABLEA_PAR enable validate constraint TMP$$_FK01;
SQL> spool off
ステップ18:非パーティションテーブルとパーティションテーブルを比較する
元の非パーティションテーブルと新しいパーティションテーブルを比較して、すべての属性が同じであることを確認します。
ステップ19:テーブルの名前を変更する
次のコマンドを実行して、中間テーブルを実際のテーブルとして設定し、テーブル名を切り替えます。
SQL> spool finish_redef_table.txt
BEGIN
DBMS_REDEFINITION.finish_redef_table
(
uname => 'TEST',
orig_table => 'TABLEA',
int_table => 'TABLEA_PAR');
END;
/
--------------------------------------------
@?/rdbms/admin/utlrp.sql
--------------------------------------------
SQL>spool off
ステップ20:テーブルを比較する
次のコマンドを実行して、両方のテーブルのレコード数を比較し、それらが一致することを確認します。
SQL> spool table_count.outp.txt
SQL> select count(*) from TEST.TABLEA;
COUNT(*)
----------
890540
SQL> select count (*) from TEST.TABLEA_PAR;
COUNT(*)
----------
890540
SQL> spool off
ステップ21:パーティションの成功を確認する
次のコマンドを実行して、パーティションプロセスが成功したことを確認します。
SQL> spool check_partition.txt
SQL> select partitioned from dba_tables where table_name = 'TABLEA' and owner='TEST';
PAR
------
YES
SQL> select partition_name , SUBPARTITION_COUNT, TABLESPACE_NAME from dba_tab_partitions where table_name='TABLEA' and table_owner='TEST';
SQL> select table_name, partition_name, high_value, partition_position from DBA_tab_partitions where table_name='TABLEA' and table_owner='TEST';
SQL> spool off
ステップ22:データベースオブジェクトを再調査します
次のコマンドを実行してデータベースオブジェクトを調べ、結果を手順2と比較します。
SET LINESIZE 500
SET PAGESIZE 1000
SQL> spool cons_indx_trigg.txt
SQL> select name, type, owner from all_dependencies where referenced_owner = 'TEST' and referenced_name = 'TABLEA';
NAME TYPE OWNER
---------------- --------------- ------------
PROC_TABLEA PROCEDURE TEST
TABLEA_TRIGG TRIGGER TEST
PKG_TABLEA PACKAGE BODY TEST
SQL> select OWNER, INDEX_NAME, TABLE_OWNER, TABLE_NAME, STATUS, TABLESPACE_NAME from dba_indexes where TABLE_OWNER='TEST' and TABLE_NAME='TABLEA';
OWNER INDEX_NAME TABLE_OWNER TABLE_NAME STATUS TABLESPACE_NAME
------------------------------------------------------------------------
TEST TABLEA_IDX_ID01 TEST TABLEA VALID TABLEA_TBL
TEST TABLEA_IDX_ID04 TEST TABLEA VALID TABLEA_TBL
TEST TABLEA_IDX_PK TEST TABLEA VALID TABLEA_TBL
SQL> select STATUS, OBJECT_TYPE, OBJECT_NAME from dba_objects where OWNER='TEST' and OBJECT_TYPE = 'TRIGGER' and STATUS='INVALID';
no rows selected
SQL> select CONSTRAINT_NAME, CONSTRAINT_TYPE from dba_constraints where TABLE_NAME='TABLEA' and owner='TEST';
CONSTRAINT_NAME C
------------------- ----------
SYS_C002004601 C
SYS_C002004602 C
SYS_C002004603 C
IDX_PK P
FK01 R
12 rows selected.
SQL> spool off
ステップ23:インデックスを再構築する
次のコマンドを実行して、新しいテーブルスペースのインデックスを再構築します。
SQL> spool rebuild_indx.txt
SQL>@rebuild_index.sql
ALTER INDEX TEST.TABLEA_IDX_ID01 REBUILD TABLESPACE TABLEA_TBL_PAR ONLINE;
ALTER INDEX TEST.ITABLEA_IDX_ID04 REBUILD TABLESPACE TABLEA_TBL_PAR ONLINE;
ALTER INDEX TEST.TABLEA_IDX_PK REBUILD TABLESPACE TABLEA_TBL_PAR ONLINE;
SQL> spool off
ステップ24:インデックスを検証する
次のコマンドを実行して、ステータスがvalid
であることを確認します また、すべてのインデックスのテーブルスペースはTABLEA_TBL_PAR:
SQL> spool verify_indx.outp.txt
SQL> select OWNER, INDEX_NAME, TABLE_OWNER, TABLE_NAME, STATUS, TABLESPACE_NAME from dba_indexes where TABLE_OWNER='TEST' and TABLE_NAME='TABLEA';
OWNER INDEX_NAME TABLE_OWNER TABLE_NAME STATUS TABLESPACE_NAME
---------------------------------------------------------------------------
TEST TABLEA_IDX_ID01 TEST TABLEA VALID TABLEA_TBL_PAR
TEST TABLEA_IDX_ID04 TEST TABLEA VALID TABLEA_TBL_PAR
TEST TABLEA_IDX_PK TEST TABLEA VALID TABLEA_TBL_PAR
SQL>spool off
ステップ25:元の非パーティションテーブルを削除します
DBAがすべてが正常に見えることを確認したら、次のコマンドを実行して元のテーブルを削除します。元のテーブルには、暫定可能なTEST.TABLEA_PARという名前が付けられています。
SQL> DROP table TEST.TABLEA_PAR cascade constraints;
前の手順では、暫定テーブルTEST.TABLEA_PARを使用して、アプリケーションのダウンタイムなしでテーブルTEST.TABLEAを範囲間隔テーブルに分割しました。
[フィードバック]タブを使用して、コメントを書き込んだり、質問したりします。
-
Oracle19cでDBCAコマンドを使用してデータベースのクローンを作成する
このブログでは、Oracle19cの新機能であるDatabaseConfiguration Assistant(DBCA)を使用して、ソースデータベースのバックアップを作成せずにリモートプラガブルデータベース(PDB)をコンテナデータベース(CDB)に複製する方法を紹介します。 ソースからターゲットへのクローン作成にかかる時間は最小限です。 ソースDBの詳細 CDB:LCONCDBPDB:LCON 以下は総数です。ソース内の各コンテナ(CDBおよびPDB)の下にあるDBFファイルのうち、クローンがターゲット内にある後に検証する必要があります。上記のソースDBから、ターゲットホスト内にCDB
-
OracleSQLプロファイルとベースライン
この投稿では、SQLプロファイルとOracle®のベースラインの違いに焦点を当て、クエリを調整するときにどのように機能するかを説明します。 オプティマイザー、プロファイル、およびベースライン 大まかに言うと、これら3つの要素は次のように連携して機能します。 クエリオプティマイザは、システム統計、バインド変数、コンパイルなどの情報を使用して、クエリ実行の最適なプランを取得します。ただし、入力の欠陥が最適ではない計画につながる場合があります。 SQLプロファイルには、この問題を軽減する補助情報が含まれています。SQLプロファイルは、これらの間違いを最小限に抑え、オプティマイザーが最適