Data Pump インポート時の統計情報を確認する (Oracle Database 19c)

Data Pumpによるインポート時のパラメーターによって統計情報がどのように動作するのか確認します。

# 統計情報のロック

impdpコマンドにcontent=METADATA_ONLYを追加してインポートを行うと、オブジェクトの定義情報（メタデータ）のみがインポートされます。このオプションを指定すると、オブジェクトのオプティマイザ統計がロックされた状態になります。統計情報がロックされると、デフォルトで動作している自動統計収集ジョブの対象からはずれるため、統計情報の更新が行われません。
  [マニュアル](https://docs.oracle.com/cd/F19136_01/sutil/datapump-import-utility.html#GUID-1609551D-212C-4DB1-B9D7-508FB75DD20C)には以下の記載があります。

> CONTENT=METADATA_ONLYを指定した場合、ダンプ・ファイルからインポートされる任意の索引または表の統計は、インポート操作の完了後にロックされることに注意してください。

# 準備
まずテーブルとインデックスの作成とデータの格納、統計情報の取得を行います。

```
SQL> CREATE TABLE data1 (c1 NUMBER, c2 VARCHAR2(10));
表が作成されました。

SQL> CREATE INDEX idx1_data1 ON data1(c1);
索引が作成されました。

SQL> INSERT INTO data1 SELECT LEVEL c1, 'data1' c2 FROM DUAL CONNECT BY LEVEL <= 100000;
100000行が作成されました。

SQL> EXECUTE DBMS_STATS.GATHER_SCHEMA_STATS('SCOTT');
PL/SQLプロシージャが正常に完了しました。

SQL> SELECT TABLE_NAME, NUM_ROWS, LAST_ANALYZED FROM USER_TABLES;

TABLE_NAME                       NUM_ROWS LAST_ANALYZED
------------------------------ ---------- -------------------
DATA1                              100000 2020/02/04 23:28:28
```

次にデータ付きでエクスポートします。

```
$ expdp userid=SYSTEM/{password} schemas=SCOTT dumpfile=scott.dmp content=ALL

Export: Release 19.0.0.0.0 - Production on 火 2月 4 23:36:07 2020
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

接続先: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
"SYSTEM"."SYS_EXPORT_SCHEMA_01"を起動しています: userid=SYSTEM/******** schemas=SCOTT dumpfile=scott.dmp content=ALL

<<<途中省略>>

マスター表"SYSTEM"."SYS_EXPORT_SCHEMA_01"は正常にロード/アンロードされました
******************************************************************************
SYSTEM.SYS_EXPORT_SCHEMA_01に設定されたダンプ・ファイルは次のとおりです:
  /u01/app/oracle/admin/O19A/dpdump/scott.dmp
ジョブ"SYSTEM"."SYS_EXPORT_SCHEMA_01"が火 2月 4 23:37:31 2020 elapsed 0 00:01:22で正常に完了しました

```

# インポート
  メタデータのみインポートを行います。

```
$ impdp userid=SYSTEM/{password} schemas=SCOTT dumpfile=scott.dmp content=METADATA_ONLY

Import: Release 19.0.0.0.0 - Production on 火 2月 4 23:40:11 2020
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

接続先: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
マスター表"SYSTEM"."SYS_IMPORT_SCHEMA_01"は正常にロード/アンロードされました
"SYSTEM"."SYS_IMPORT_SCHEMA_01"を起動しています: userid=SYSTEM/******** schemas=SCOTT dumpfile=scott.dmp content=METADATA_ONLY

<<途中省略>>

オブジェクト型SCHEMA_EXPORT/STATISTICS/MARKERの処理中です
ジョブ"SYSTEM"."SYS_IMPORT_SCHEMA_01"が火 2月 4 23:40:56 2020 elapsed 0 00:00:43で正常に完了しました
```

インポートが完了したら統計情報を確認します。

```
SQL> SELECT TABLE_NAME, NUM_ROWS, STATTYPE_LOCKED, LAST_ANALYZED FROM USER_TAB_STATISTICS;

TABLE_NAME                       NUM_ROWS STATT LAST_ANALYZED
------------------------------ ---------- ----- -------------------
DATA1                              100000 ALL   2020/02/04 23:28:28

```

統計情報の取得時間（LAST_ANALYZED列）はエクスポートした時点の統計情報と同じ時刻になっています。またUSER_TAB_STATISTICSビューのSTATTYPE_LOCKED列の値がALLになっています。これは統計情報がロックされていることを示します。この状態では統計情報をアップデートしようとするとロックされているというエラーが発生します。ただし、統計情報がロックされた状態でも DBMS_STATS.GATHER_SCHEMA_STATSプロシージャは成功します。

```
SQL> EXECUTE DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'DATA1');
BEGIN DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'DATA1'); END;

*
行1でエラーが発生しました。:
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512: "SYS.DBMS_STATS", 行40751
ORA-06512: "SYS.DBMS_STATS", 行40035
ORA-06512: "SYS.DBMS_STATS", 行9393
ORA-06512: "SYS.DBMS_STATS", 行10317
ORA-06512: "SYS.DBMS_STATS", 行39324
ORA-06512: "SYS.DBMS_STATS", 行40183
ORA-06512: "SYS.DBMS_STATS", 行40732
ORA-06512: 行1

SQL> EXECUTE DBMS_STATS.GATHER_SCHEMA_STATS('SCOTT');

PL/SQLプロシージャが正常に完了しました。

```


# データのみのインポート
  データのみインポートした場合に統計情報がどうなるのかを確認します。統計情報のロックを解除し、統計情報を削除します。

```
SQL> EXECUTE DBMS_STATS.UNLOCK_TABLE_STATS('SCOTT', 'DATA1');

PL/SQLプロシージャが正常に完了しました。

SQL> EXECUTE DBMS_STATS.DELETE_TABLE_STATS('SCOTT', 'DATA1');

PL/SQLプロシージャが正常に完了しました。
```
データのみインポートするために、content=DATA_ONLYを指定してインポートを行います。

```
$ impdp userid=SYSTEM/{password} schemas=SCOTT dumpfile=scott.dmp content=DATA_ONLY

Import: Release 19.0.0.0.0 - Production on 火 2月 4 23:55:18 2020
Version 19.3.0.0.0
<<途中省略>>
オブジェクト型SCHEMA_EXPORT/TABLE/TABLE_DATAの処理中です
. . "SCOTT"."DATA1"                            1.425 MB  100000行がインポートされました
ジョブ"SYSTEM"."SYS_IMPORT_SCHEMA_01"が火 2月 4 23:55:27 2020 elapsed 0 00:00:07で正常に完了しました
```

統計情報を確認すると、統計情報はインポートされないことがわかります。

```
SQL> SELECT TABLE_NAME, NUM_ROWS, STATTYPE_LOCKED, LAST_ANALYZED FROM USER_TAB_STATISTICS;

TABLE_NAME                       NUM_ROWS STATT LAST_ANA
------------------------------ ---------- ----- --------
DATA1

```

# 統計情報がロックされた状態でインポート

統計情報が取得されず、ロックされた状態でメタデータのみインポートを行った時の動作を検証します。

```
SQL> SELECT TABLE_NAME, NUM_ROWS, STATTYPE_LOCKED, LAST_ANALYZED FROM USER_TAB_STATISTICS;

TABLE_NAME                       NUM_ROWS STATT LAST_ANALYZED
------------------------------ ---------- ----- -------------------
DATA1                                     ALL

```

インポートを行います。ユーザーの作成でエラーになることはわかっているので EXCLUDE=USER を指定します。

```
$ impdp userid=SYSTEM/{password} schemas=SCOTT dumpfile=scott.dmp content=METADATA_ONLY exclude=USER

Import: Release 19.0.0.0.0 - Production on 水 2月 5 00:03:52 2020
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

接続先: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
マスター表"SYSTEM"."SYS_IMPORT_SCHEMA_01"は正常にロード/アンロードされました
"SYSTEM"."SYS_IMPORT_SCHEMA_01"を起動しています: userid=SYSTEM/******** schemas=SCOTT dumpfile=scott.dmp content=METADATA_ONLY exclude=USER
オブジェクト型SCHEMA_EXPORT/SYSTEM_GRANTの処理中です
オブジェクト型SCHEMA_EXPORT/DEFAULT_ROLEの処理中です
オブジェクト型SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMAの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/TABLEの処理中です
ORA-39151: 表"SCOTT"."DATA1"が存在します。スキップのtable_exists_actionのため、すべての依存メタデータおよびデータはスキップされます

オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/INDEXの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICSの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICSの処理中です
オブジェクト型SCHEMA_EXPORT/STATISTICS/MARKERの処理中です
ジョブ"SYSTEM"."SYS_IMPORT_SCHEMA_01"が完了しましたが、1エラーが水 2月 5 00:04:00 2020 elapsed 0 00:00:07で発生しています
```

テーブルの作成でエラーになっていますが、統計情報については何の出力もありません。統計情報を確認すると、何も入っていないことがわかります。

``` 
SQL> SELECT TABLE_NAME, NUM_ROWS, STATTYPE_LOCKED, LAST_ANALYZED FROM USER_TAB_STATISTICS;

TABLE_NAME                       NUM_ROWS STATT LAST_ANALYZED
------------------------------ ---------- ----- -------------------
DATA1                                     ALL

```