{
  "date": "2017-09-06T20:20:38",
  "slug": "impdp-contentmetadata_only-locks-the-stats",
  "link": "https://www.dbi-services.com/blog/impdp-contentmetadata_only-locks-the-stats/",
  "title": {
    "rendered": "impdp content=metadata_only locks the stats"
  },
  "content": {
    "rendered": "<h2>By Franck Pachot</h2>\n<p>.<br />\nWith Oracle you can learn something every day. Today, preparing a migration to 12.2, I found all tables had locked statistics. I learned that it is the expected behavior since 10.2 when importing metadata_only including statistics, to avoid that the automatic job gathering comes and replaces the stats by &#8216;0 rows&#8217;.<br />\n<!--more--><br />\nIt is documented in <a href=\"https://support.oracle.com/epmos/faces/DocContentDisplay?id=415081.1\" target=\"_blank\" rel=\"noopener noreferrer\">DataPump Import Without Data Locks Table Statistics (Doc ID 415081.1)</a> but as I was really surprised about that (and also frustrated to learn a 10.2 thing when migrating to 12.2) that I wanted to test myself.</p>\n<p>I create a table DEMO with statistics:</p>\n<pre><code>\nSQL&gt; connect sys/oracle@//localhost/pdb1 as sysdba\nConnected.\nSQL&gt; create table demo.demo as select * from dual;\nTable created.\n&nbsp;\nSQL&gt; create index demo.demo on demo.demo(dummy);\nIndex created.\n&nbsp;\nSQL&gt; exec dbms_stats.gather_table_stats('DEMO','DEMO');\nPL/SQL procedure successfully completed.\n&nbsp;\nSQL&gt; create or replace directory TMP as '/tmp';\nDirectory created.\n&nbsp;\nSQL&gt; select count(*) from DEMO.DEMO;\n&nbsp;\n  COUNT(*)\n----------\n         1\n&nbsp;\nSQL&gt; select object_type from dba_objects where owner='DEMO' and object_name='DEMO';\n&nbsp;\nOBJECT_TYPE\n-----------------------\nTABLE\nINDEX\n&nbsp;\nSQL&gt; select owner,table_name,last_analyzed,stattype_locked,num_rows from dba_tab_statistics where owner='DEMO' and table_name='DEMO';\n&nbsp;\nOWNER      TABLE_NAME           LAST_ANALYZED        STATTYPE_LOCKED        NUM_ROWS\n---------- -------------------- -------------------- -------------------- ----------\nDEMO       DEMO                 06-SEP-17                                          1\n</code></pre>\n<p>I export it:</p>\n<pre><code>\nConnected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production\nStarting \"SYS\".\"SYS_EXPORT_TABLE_01\":  \"sys/********@//localhost/pdb1 AS SYSDBA\" tables=DEMO.DEMO directory=TMP\nProcessing object type TABLE_EXPORT/TABLE/TABLE_DATA\nProcessing object type TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS\nProcessing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS\nProcessing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER\nProcessing object type TABLE_EXPORT/TABLE/TABLE\nProcessing object type TABLE_EXPORT/TABLE/INDEX/INDEX\n. . exported \"DEMO\".\"DEMO\"                               5.054 KB       1 rows\nMaster table \"SYS\".\"SYS_EXPORT_TABLE_01\" successfully loaded/unloaded\n******************************************************************************\nDump file set for SYS.SYS_EXPORT_TABLE_01 is:\n  /tmp/expdat.dmp\nJob \"SYS\".\"SYS_EXPORT_TABLE_01\" successfully completed at Wed Sep 6 19:14:44 2017 elapsed 0 00:00:09\n</code></pre>\n<p>And drop it:</p>\n<pre><code>\nSQL&gt; connect sys/oracle@//localhost/pdb1 as sysdba\nConnected.\nSQL&gt; drop table demo.demo;\nTable dropped.\n</code></pre>\n<p>Now import metadata only (for example because I want to change NLS semantics before importing the data)</p>\n<pre><code>\nImport: Release 12.2.0.1.0 - Production on Wed Sep 6 19:21:28 2017\n&nbsp;\nCopyright (c) 1982, 2017, Oracle and/or its affiliates.  All rights reserved.\n&nbsp;\nConnected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production\nMaster table \"SYS\".\"SYS_IMPORT_TABLE_01\" successfully loaded/unloaded\nStarting \"SYS\".\"SYS_IMPORT_TABLE_01\":  \"sys/********@//localhost/pdb1 AS SYSDBA\" tables=DEMO.DEMO directory=TMP content=metadata_only exclude=index\nProcessing object type TABLE_EXPORT/TABLE/TABLE\nProcessing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS\nProcessing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER\nJob \"SYS\".\"SYS_IMPORT_TABLE_01\" successfully completed at Wed Sep 6 19:21:39 2017 elapsed 0 00:00:11\n</code></pre>\n<p>If I check the statistics:</p>\n<pre><code>\nSQL&gt; select owner,table_name,last_analyzed,stattype_locked,num_rows from dba_tab_statistics where owner='DEMO' and table_name='DEMO';\n&nbsp;\nOWNER      TABLE_NAME           LAST_ANALYZED        STATTYPE_LOCKED        NUM_ROWS\n---------- -------------------- -------------------- -------------------- ----------\nDEMO       DEMO                 06-SEP-17            ALL                           1\n</code></pre>\n<p>Stats are locked. I suppose that the idea is that you have the tables with same statistics as production for example, and you can load them with a subset of data but expect the same execution plans as in production. But this is not what I want for a migration.</p>\n<p>One possibility is to unlock the stats once you have imported the data.</p>\n<p>The other possibility is to import metadata without the statistics:</p>\n<pre><code>\nConnected to: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production\nMaster table \"SYS\".\"SYS_IMPORT_TABLE_01\" successfully loaded/unloaded\nStarting \"SYS\".\"SYS_IMPORT_TABLE_01\":  \"sys/********@//localhost/pdb1 AS SYSDBA\" tables=DEMO.DEMO directory=TMP content=metadata_only exclude=index exclude=table_statistics\nProcessing object type TABLE_EXPORT/TABLE/TABLE\nJob \"SYS\".\"SYS_IMPORT_TABLE_01\" successfully completed at Wed Sep 6 21:11:03 2017 elapsed 0 00:00:03\n</code></pre>\n<p>Then the table statistics are not locked:</p>\n<pre><code>\nOWNER      TABLE_NAME           LAST_ANALYZED        STATTYPE_LOCKED        NUM_ROWS\n---------- -------------------- -------------------- -------------------- ----------\nDEMO       DEMO\n</code></pre>\n<p>Once you have changed what you want on the tables, you import the data (table_exists_action=truncate) and then you import the remaining: indexes, ref_constraints, triggers.<br />\nThis is where you can also add include=table_statistics:</p>\n<pre><code>\nStarting \"SYS\".\"SYS_IMPORT_TABLE_01\":  \"sys/********@//localhost/pdb1 AS SYSDBA\" tables=DEMO.DEMO directory=TMP table_exists_action=truncate include=index include=table_statistics\nProcessing object type TABLE_EXPORT/TABLE/INDEX/INDEX\nProcessing object type TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS\nProcessing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS\nProcessing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER\n</code></pre>\n<p>So that you have the statistics from the source, unlocked.</p>\n<pre><code>\nOWNER      TABLE_NAME           LAST_ANALYZED        STATTYPE_LOCKED        NUM_ROWS\n---------- -------------------- -------------------- -------------------- ----------\nDEMO       DEMO                 06-SEP-17                                          1\n</code></pre>\n",
    "protected": false
  }
}
