Data Pump で統計情報がロックされるもう一つの条件

以前、インポート時にCONTENT=METADATA_ONLYを指定すると、統計情報がロックされる仕様を[書きました](https://qiita.com/plusultra/items/4abf68c96cf2427f07ae)。impdpコマンドの[マニュアル](https://docs.oracle.com/cd/F19136_01/sutil/datapump-import-utility.html#GUID-1609551D-212C-4DB1-B9D7-508FB75DD20C)には以下の記述があります。

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

expdpコマンドにも同じオプションがあり、こちらにも同じように[説明](https://docs.oracle.com/cd/F19136_01/sutil/oracle-data-pump-export-utility.html#GUID-F7994C75-CC86-4A5D-AA9A-361A94FD9C03)があります。この説明は Oracle Database 11g Release 2 以降のマニュアルにのみ記述があります。

> METADATA_ONLYを指定すると、データベース・オブジェクト定義のみがアンロードされ、表の行データはアンロードされません。CONTENT=METADATA_ONLYを指定した場合、ダンプ・ファイルが後でインポートされるときに、ダンプ・ファイルからインポートされる索引または表の統計はインポート後にロックされることに注意してください。

エクスポート時にCONTENT=METADATA_ONLYオプションを指定した場合の統計情報について検証します。

# 準備
SCOTTスキーマ内にテーブルを作成し、データを格納します。その後統計情報を取得し、取得された統計情報を確認します。統計情報はロックされていない（USER_TAB_STATISTICS ビューの STATTYPE_LOCKED 列が NULL ）ことを確認しています。


```
SQL> CREATE TABLE data1(c1 NUMBER, c2 VARCHAR2(10));

表が作成されました。

SQL> INSERT INTO data1 SELECT LEVEL c1, 'data1' c2 FROM DUAL CONNECT BY LEVEL <= 100000;

100000行が作成されました。

SQL> COMMIT;

コミットが完了しました。

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

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

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

TABLE_NAME                       NUM_ROWS LAST_ANALYZED       STATT
------------------------------ ---------- ------------------- -----
DATA1                              100000 2020/02/17 22:43:59 NULL

SQL>
```

# Export/Import
  CONTENT=METADATA_ONLY オプションを指定してエクスポートを行います。

```
$ expdp USERID=SYSTEM/{password} SCHEMAS=scott DUMPFILE=scott_meta.dmp DIRECTORY=DATA_PUMP_DIR CONTENT=METADATA_ONLY

Export: Release 19.0.0.0.0 - Production on 月 2月 17 23:13:02 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_02"を起動しています: USERID=SYSTEM/******** SCHEMAS=scott DUMPFILE=scott_meta.dmp DIRECTORY=DATA_PUMP_DIR CONTENT=METADATA_ONLY
オブジェクト型SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICSの処理中です
オブジェクト型SCHEMA_EXPORT/STATISTICS/MARKERの処理中です
オブジェクト型SCHEMA_EXPORT/USERの処理中です
オブジェクト型SCHEMA_EXPORT/SYSTEM_GRANTの処理中です
オブジェクト型SCHEMA_EXPORT/ROLE_GRANTの処理中です
オブジェクト型SCHEMA_EXPORT/DEFAULT_ROLEの処理中です
オブジェクト型SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMAの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/TABLEの処理中です
マスター表"SYSTEM"."SYS_EXPORT_SCHEMA_02"は正常にロード/アンロードされました
******************************************************************************
SYSTEM.SYS_EXPORT_SCHEMA_02に設定されたダンプ・ファイルは次のとおりです:
  /u01/app/oracle/admin/O19A/dpdump/scott_meta.dmp
ジョブ"SYSTEM"."SYS_EXPORT_SCHEMA_02"が月 2月 17 23:13:30 2020 elapsed 0 00:00:28で正常に完了しました

$
```

CONTENT=ALLオプション（デフォルト）を指定してインポートを行います。

```
$ impdp USERID=SYSTEM/{password} SCHEMAS=scott DUMPFILE=scott_meta.dmp DIRECTORY=DATA_PUMP_DIR CONTENT=ALL

Import: Release 19.0.0.0.0 - Production on 月 2月 17 23:19:45 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_meta.dmp DIRECTORY=DATA_PUMP_DIR CONTENT=ALL
オブジェクト型SCHEMA_EXPORT/USERの処理中です
オブジェクト型SCHEMA_EXPORT/SYSTEM_GRANTの処理中です
オブジェクト型SCHEMA_EXPORT/ROLE_GRANTの処理中です
オブジェクト型SCHEMA_EXPORT/DEFAULT_ROLEの処理中です
オブジェクト型SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMAの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/TABLEの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICSの処理中です
オブジェクト型SCHEMA_EXPORT/STATISTICS/MARKERの処理中です
ジョブ"SYSTEM"."SYS_IMPORT_SCHEMA_01"が月 2月 17 23:20:02 2020 elapsed 0 00:00:17で正常に完了しました

$
```

統計情報の状態を確認すると、STATTYPE_LOCKED 列の値が ALL になっており、統計情報がロックされていることがわかります。

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

TABLE_NAME                       NUM_ROWS LAST_ANALYZED       STATT
------------------------------ ---------- ------------------- -----
DATA1                              100000 2020/02/17 22:43:59 ALL

```

# SQLファイルの比較

CONTENT=ALLオプション指定時とCONTENT=METADATA_ONLY指定時でSQLFILEオプションを使ってダンプファイルの内容を比較しましたが、SQLFILEの出力には差が無いことがわかりました。

```
$ expdp USERID=SYSTEM/{password} SCHEMAS=scott DUMPFILE=scott_all.dmp DIRECTORY=DATA_PUMP_DIR CONTENT=ALL
$ impdp USERID=SYSTEM/{password} SCHEMAS=scott DUMPFILE=scott_all.dmp DIRECTORY=DATA_PUMP_DIR SQLFILE=scott_all.sql

$ expdp USERID=SYSTEM/{password} SCHEMAS=scott DUMPFILE=scott_meta.dmp DIRECTORY=DATA_PUMP_DIR CONTENT=METADATA_ONLY
$ impdp USERID=SYSTEM/{password} SCHEMAS=scott DUMPFILE=scott_meta.dmp DIRECTORY=DATA_PUMP_DIR SQLFILE=scott_meta.sql

$ diff scott_all.sql scott_meta.sql
29c29
< sys.dbms_logrep_imp.instantiate_schema(schema_name=>SYS_CONTEXT('USERENV','CURRENT_SCHEMA'), export_db_name=>'O19A', inst_scn=>'14477566');
---
> sys.dbms_logrep_imp.instantiate_schema(schema_name=>SYS_CONTEXT('USERENV','CURRENT_SCHEMA'), export_db_name=>'O19A', inst_scn=>'14482672');
$

```