Do you know the difference between exp/imp and expdp/impdp when it comes to importing HCC compressed data in Exadata?
If not, then follow me through two examples. This is on 11.2.0.3/11.2.3.3.1 but applies to all database releases you can have on Exadata. The task at hand is to export a table (which happens to be non-partitioned and HCC compressed for query high) and import it into a different user’s schema. This is quite a common approach when migrating data from a non-Exadata system into an Exadata system. You could for example pre-create the DDL for the tables and implement HCC before even importing a single row. When importing the data, the partitions’ HCC attributes will be honoured and data will be inserted compressed. Or won’t it?
The table
The table I want to export resides on our V2 system. Since I am (trying to be) a good citizen I want to use dbfs for the dump files. Beginning with 12.1.0.2 Grid Infrastructure you can also have ACFS by the way. Let’s start by creating the directory needed and some meta-information about the source table:
SQL> create or replace directory DBM01 as '/dbfs_direct/FS1/mbach/'; Directory created. SQL> select owner, table_name, partitioned, num_rows, compress_for from dba_tables where table_name = 'T1_QH'; OWNER TABLE_NAME PAR NUM_ROWS COMPRESS_FOR ------------------------------ ------------------------------ --- ---------- ------------ MARTIN T1_QH NO QUERY HIGH SQL> select bytes/power(1024,2) m, blocks from dba_segments where segment_name = 'T1_QH'; M BLOCKS ---------- ---------- 72 9216
The table is 72 MB in size, and HCC compressed (I actually ensured that it was by issuing an “alter table t1_qh move;” before the export started).
Data Pump
The first export uses expdp, followed by impdp to get the data back. I am remapping the schema so I don’t have to risk overwriting my source data.
[enkdb01:oracle:DBM011] /home/oracle/mbach > expdp martin/xxxxxx directory=DBM01 dumpfile=exp_t1_qh.dmp logfile=exp_t1_qh.log tables=t1_qh Export: Release 11.2.0.3.0 - Production on Tue Mar 24 06:15:34 2015 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options Starting "MARTIN"."SYS_EXPORT_TABLE_02": martin/******** directory=DBM01 dumpfile=exp_t1_qh.dmp logfile=exp_t1_qh.log tables=t1_qh Estimate in progress using BLOCKS method... Processing object type TABLE_EXPORT/TABLE/TABLE_DATA Total estimation using BLOCKS method: 72 MB Processing object type TABLE_EXPORT/TABLE/TABLE . . exported "MARTIN"."T1_QH" 9.675 GB 10000000 rows Master table "MARTIN"."SYS_EXPORT_TABLE_02" successfully loaded/unloaded ****************************************************************************** Dump file set for MARTIN.SYS_EXPORT_TABLE_02 is: /dbfs_direct/FS1/mbach/exp_t1_qh.dmp Job "MARTIN"."SYS_EXPORT_TABLE_02" successfully completed at 06:17:16
The interesting bit here is that the table on disk occupies around 72 MB, and yet expdp tells me the 10000000 rows occupy 9.7 GB. Can anyone guess why?
[enkdb01:oracle:DBM011] /home/oracle/mbach > ls -lh /dbfs_direct/FS1/mbach/exp_t1_qh.dmp -rw-r----- 1 oracle dba 9.7G Mar 24 06:17 /dbfs_direct/FS1/mbach/exp_t1_qh.dmp
Yes, 10GB. Data apparently is not exported in its compressed form. Now this table is going to be imported:
[enkdb01:oracle:DBM011] /home/oracle/mbach > impdp imptest/xxxxxx directory=DBM01 dumpfile=exp_t1_qh.dmp logfile=imp_t1_qh.log \ > tables=martin.t1_qh remap_schema=martin:imptest Import: Release 11.2.0.3.0 - Production on Tue Mar 24 06:23:44 2015 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options Master table "IMPTEST"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded Starting "IMPTEST"."SYS_IMPORT_TABLE_01": imptest/******** directory=DBM01 dumpfile=exp_t1_qh.dmp logfile=imp_t1_qh.log tables=martin.t1_qh remap_schema=martin:imptest Processing object type TABLE_EXPORT/TABLE/TABLE Processing object type TABLE_EXPORT/TABLE/TABLE_DATA . . imported "IMPTEST"."T1_QH" 9.675 GB 10000000 rows Job "IMPTEST"."SYS_IMPORT_TABLE_01" successfully completed at 06:29:53
This looks all right-all data back (the number of rows exported matches those imported). What about the segment size?
SQL> select owner, table_name, partitioned, num_rows, compress_for from dba_tables where table_name = 'T1_QH'; OWNER TABLE_NAME PAR NUM_ROWS COMPRESS_FOR ------------------------------ ------------------------------ --- ---------- ------------ MARTIN T1_QH NO QUERY HIGH IMPTEST T1_QH NO QUERY HIGH 2 rows selected. SQL> select bytes/power(1024,2) m, blocks from dba_segments where segment_name = 'T1_QH'; M BLOCKS ---------- ---------- 72 9216 72 9216 2 rows selected.
Identical down to the block.
Traditional Export/Import
Despite the fact that exp/imp are deprecated they are still included with 12.1.0.2, the current release at the time of writing. What if you did the same process with these instead? After all, many DBAs “grew up” with those tools and can use them in their sleep. This plus some initial deficits with Data Pump in 10g keep exp/imp high up in the list of tools we like.
Let’s export the table:
[enkdb01:oracle:DBM011] /home/oracle/mbach > exp martin/xxxxxxx file=/dbfs_direct/FS1/mbach/exp_t1_qh_classic.dmp log=/dbfs_direct/FS1/mbach/exp_t1_qh_classic.log tables=t1_qh Export: Release 11.2.0.3.0 - Production on Tue Mar 24 06:42:34 2015 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Data Mining and Real Application Tes Export done in US7ASCII character set and AL16UTF16 NCHAR character set About to export specified tables via Conventional Path ... . . exporting table T1_QH 10000000 rows exported Export terminated successfully without warnings.
The files are more or less identical in size to the ones created before by Data Pump:
[enkdb01:oracle:DBM011] /home/oracle/mbach > ls -lh /dbfs_direct/FS1/mbach/*classic* -rw-r--r-- 1 oracle dba 9.7G Mar 24 07:01 /dbfs_direct/FS1/mbach/exp_t1_qh_classic.dmp -rw-r--r-- 1 oracle dba 537 Mar 24 07:01 /dbfs_direct/FS1/mbach/exp_t1_qh_classic.log
What about the import?
[enkdb01:oracle:DBM011] /home/oracle/mbach > imp imptest/xxxxxx file=/dbfs_direct/FS1/mbach/exp_t1_qh_classic.dmp log=/dbfs_direct/FS1/mbach/imp_t1_qh_classic.log \ > FROMUSER=martin TOUSER=imptest tables=t1_qh Import: Release 11.2.0.3.0 - Production on Tue Mar 24 07:27:42 2015 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Data Mining and Real Application Tes Export file created by EXPORT:V11.02.00 via conventional path Warning: the objects were exported by MARTIN, not by you import done in US7ASCII character set and AL16UTF16 NCHAR character set . importing MARTIN's objects into IMPTEST . . importing table "T1_QH"
And this takes a loooong time. What’s happening in the background? I first checked what the session was doing. That’s simple-have a look at the output.
SQL> @scripts/as INST_ID SID SERIAL# USERNAME PROG SQL_ID CHILD PLAN_HASH_VALUE EXECS AVG_ETIME OFF SQL_TEXT ---------- ----- ---------- ------------- ---------- ------------- ------ --------------- ---------- ----------- --- ----------------------------------------- 1 594 23 IMPTEST imp@enkdb0 fgft1tcrr12ga 0 0 22723 .00 No INSERT /*+NESTED_TABLE_SET_REFS+*/ INTO "
The #execs were interesting and indeed, after a couple of minutes that counter has gone up a lot:
INST_ID SID SERIAL# USERNAME PROG SQL_ID CHILD PLAN_HASH_VALUE EXECS AVG_ETIME OFF SQL_TEXT ---------- ----- ---------- ------------- ---------- ------------- ------ --------------- ---------- ----------- --- ----------------------------------------- 1 594 23 IMPTEST imp@enkdb0 fgft1tcrr12ga 0 0 639818 .00 Yes INSERT /*+NESTED_TABLE_SET_REFS+*/ INTO "
You can probably guess what’s coming next. After quite some while the import finished:
> imp imptest/xxxxxxx file=/dbfs_direct/FS1/mbach/exp_t1_qh_classic.dmp log=/dbfs_direct/FS1/mbach/imp_t1_qh_classic.log \ > FROMUSER=martin TOUSER=imptest tables=t1_qh Import: Release 11.2.0.3.0 - Production on Tue Mar 24 07:27:42 2015 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP, Data Mining and Real Application Tes Export file created by EXPORT:V11.02.00 via conventional path Warning: the objects were exported by MARTIN, not by you import done in US7ASCII character set and AL16UTF16 NCHAR character set . importing MARTIN's objects into IMPTEST . . importing table "T1_QH" 10000000 rows imported Import terminated successfully without warnings.
And now for the reason of this blog post:
SQL> select owner, bytes/power(1024,2) m, blocks from dba_segments where segment_name = 'T1_QH'; OWNER M BLOCKS ------------------------------ ---------- ---------- MARTIN 72 9216 IMPTEST 11227 1437056
The newly important table was not compressed at all when importing using the traditional path.