根据Oracle的文档的描述,数据泵采用不同的方式导出导入,性能也会有明显的差别,这次正好有机会测试一下,迁移表空间、直接路径、外部表方式,以及数据库链方式导出、导入的性能差异。
这篇介绍一下测试环境。
源数据库和目标数据库的版本都是10.2.0.3,不存在版本差异,字符集都是ZHS16GBK,国家字符集都是AL16UTF16字符集,源数据库和目标数据库都是16k的BLOCK_SIZE,因此采用迁移表空间的方式不存在任何的问题:
SQL> SELECT GLOBAL_NAME FROM GLOBAL_NAME;
GLOBAL_NAME
------------------------------------------------------------------------
NEWDEMO
SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
Oracle Database10gEnterpriseEdition Release10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
SQL> SELECT PROPERTY_NAME, PROPERTY_VALUE
2 FROM DATABASE_PROPERTIES
3 WHERE PROPERTY_NAME LIKE '%CHARACTERSET';
PROPERTY_NAME PROPERTY_VALUE
------------------------------ --------------------------------------------------
NLS_CHARACTERSET ZHS16GBK
NLS_NCHAR_CHARACTERSET AL16UTF16
SQL> SHOW PARAMETER DB_BLOCK_SIZE
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 16384
上面是源数据库的查询结果,目标数据库上面的查询结果完全一致,除了GLOBAL_NAME之外:
SQL> SELECT GLOBAL_NAME FROM GLOBAL_NAME;
GLOBAL_NAME
----------------------------------------------------------------------------
TJSQ
SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
Oracle Database10gEnterpriseEdition Release10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
SQL>COLPROPERTY_VALUE FORMAT A50
SQL> SELECT PROPERTY_NAME, PROPERTY_VALUE
2 FROM DATABASE_PROPERTIES
3 WHERE PROPERTY_NAME LIKE '%CHARACTERSET';
PROPERTY_NAME PROPERTY_VALUE
------------------------------ --------------------------------------------------
NLS_CHARACTERSET ZHS16GBK
NLS_NCHAR_CHARACTERSET AL16UTF16
SQL> SHOW PARAMETER DB_BLOCK_SIZE
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 16384
要迁移的数据分布在两个表空间中:
SQL> SELECT TABLESPACE_NAME, FILE_NAME, BYTES/1024/1024/1024
2 FROM DBA_DATA_FILES
3 WHERE TABLESPACE_NAME LIKE 'TJ%'
4 ORDER BY 1, 2;
TABLESPACE_NAME FILE_NAME BYTES/1024/1024/1024
--------------- -------------------------------------------------- --------------------
TJSQ /data/oracle/oradata/newdemo/tjsq01.dbf 20
TJSQ /data/oracle/oradata/newdemo/tjsq02.dbf 4
TJSQ_TMP /data/oracle/oradata/newdemo/tjsq_tmp.dbf 4
数据分布在5个SCHEMA中:
SQL> SELECT OWNER, SUM(BYTES)/1024/1024/1024
2 FROM DBA_SEGMENTS
3 WHERE TABLESPACE_NAME LIKE 'TJ%'
4 GROUP BY OWNER
5 ORDER BY 2 DESC;
OWNER SUM(BYTES)/1024/1024/1024
------------------------------ -------------------------
TJSQ_TRADE 14.0916138
TJSQ_NDMAIN 8.00140381
TJSQ_NDMAIN_OPER 1.71221924
TJSQ_TRADE_OPER .194641113
TJSQ_GOV .080993652
可以看到,用户对象占用了大于24G的空间,仅比数据文件小4G,这种情况还是比较适合迁移表空间方式的,否则如果数据文件中包含了大量的空闲空间,使用迁移表空间方式效率很可能比直接数据泵导入导出效率还低。
虽然测试的数据量并不大,但是28G也可以说明一定问题了。
目标数据库使用的本地磁盘,6块300G做的RAID 1+0,IO性能肯定不会太好。局域网是百兆网络,同样也可能成为性能的瓶颈。有时候用一个普通的环境测试更能说明问题,因为如果IO不是瓶颈、网络也不是瓶颈,那么很可能几种方式的效率相差不了太多。
为了能体现数据泵的优势,显示外部表方式和直接路径效率的区别,目标数据库为非归档模式。
SQL> SELECT LOG_MODE FROM V$DATABASE;
LOG_MODE
------------
NOARCHIVELOG
SQL> SHOW SGA
Total System Global Area 3707764736 bytes
Fixed Size 2077104 bytes
Variable Size 721423952 bytes
Database Buffers 2969567232 bytes
Redo Buffers 14696448 bytes
由于测试的方法包括数据库链直接导入的方式,而这种方式将导出、数据传递以及导入合成到一个操作中进行,因此这个测试的最终时间由导出时间、数据传递时间,以及导入时间3个部分之和构成。
最后准备目标数据库重建用户的角色和权限:
SQL> SELECT 'GRANT ' || GRANTED_ROLE || ' TO ' || GRANTEE || ';'
2 FROM DBA_ROLE_PRIVS
3 WHERE GRANTEE LIKE 'TJ%'
4 ORDER BY GRANTEE, GRANTED_ROLE;
'GRANT'||GRANTED_ROLE||'TO'||GRANTEE||';'
-----------------------------------------------------------------------
GRANT CONNECT TO TJSQ_GOV;
GRANT RESOURCE TO TJSQ_GOV;
GRANT CONNECT TO TJSQ_NDMAIN;
GRANT RESOURCE TO TJSQ_NDMAIN;
GRANT CONNECT TO TJSQ_NDMAIN_OPER;
GRANT RESOURCE TO TJSQ_NDMAIN_OPER;
GRANT CONNECT TO TJSQ_TRADE;
GRANT RESOURCE TO TJSQ_TRADE;
GRANT CONNECT TO TJSQ_TRADE_OPER;
GRANT RESOURCE TO TJSQ_TRADE_OPER;
10 rows selected.
SQL> SELECT 'GRANT ' || PRIVILEGE || ' TO ' || GRANTEE || ';'
2 FROM DBA_SYS_PRIVS
3 WHERE GRANTEE LIKE 'TJ%'
4 AND PRIVILEGE NOT IN
5 (SELECT PRIVILEGE FROM DBA_SYS_PRIVS
6 WHERE GRANTEE IN ('CONNECT', 'RESOURCE'))
7 ORDER BY GRANTEE;
'GRANT'||PRIVILEGE||'TO'||GRANTEE||';'
---------------------------------------------------------------------------------
GRANT CREATE SYNONYM TO TJSQ_GOV;
GRANT CREATE SYNONYM TO TJSQ_NDMAIN;
GRANT CREATE SYNONYM TO TJSQ_NDMAIN_OPER;
GRANT CREATE DATABASE LINK TO TJSQ_TRADE;
GRANT CREATE SYNONYM TO TJSQ_TRADE;
GRANT CREATE SYNONYM TO TJSQ_TRADE_OPER;
6 rows selected.
在源数据库和目标数据库上建立对应DIRECTORY:
SQL> SELECT * FROM DBA_DIRECTORIES;
OWNER DIRECTORY_NAME DIRECTORY_PATH
--------------- --------------- ----------------------------------------
SYS TRAN /data/dmp
SYS D_DMPDP /data/dmp
SYS DATA_PUMP_DIR /data/oracle/product/10.2/rdbms/log/
SQL> CREATE DIRECTORY D_DATAFILE AS '/data/oracle/oradata/newdemo';
Directory created.
目标数据库建立DIRECTORIES:
SQL> CREATE DIRECTORY D_DMP AS '/data/dmp';
Directory created.
SQL> CREATE DIRECTORY D_DATAFILE AS '/data/oracle/oradata/tjsq';
Directory created.
建立到源数据库的数据库链,数据库链方式的导出,以及利用DBMS_FILE_TRANSFER包都会用到这个数据库链:
SQL> CREATE DATABASE LINK NEWDEMO
2 CONNECT TO SYSTEM
3 IDENTIFIED BY PASSWORD
4 USING 'NEWDEMO';
Database link created.
SQL> SELECT GLOBAL_NAME FROM GLOBAL_NAME@NEWDEMO;
GLOBAL_NAME
------------------------------------------------------------------------------------
NEWDEMO
下面就可以准备测试了。
oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html