通常进行了物理备份还不足够,因为在很多情况下使用物理备份进行恢复会相对复杂,比如误操作TRUNCATE了数据表,这样的恢复有时候使用逻辑备份来恢复会更迅速、更有效。所以通常将逻辑备份作为物理备份的辅助手段进行配置。
比如以下示例简单的按照用户模式的导出:
exp username/password file=dumpfile.dmp
expdp username/password dumpfile=dumpfile.dmp directory=expdir
然而如果数据库的数据量较大,全部按用户导出就可能代价高昂,所有通常可以采用按照表模式,将重要数据表进行导出备份。可是如何进行排除部分表的逻辑备份呢?
自从存在EXP工具以来,大家就一直在寻求一种方法,以便在全库或按照用户模式导出时排除部分不需要备份的数据表,但是Oracle一直没有提供这个功能,直到Oracle10g在新推出的数据泵(EXPDP/IMPDP)中,支持使用EXCLUDE参数排除特定的对象或对象类型。
在Oracle10g以前的版本中,可以通过指定tables列表的方法,来排除不需要导出的数据表,但是指定固定的列表存在一个最严重的问题是,当数据库中的数据表发生变化时,如增加了新的数据表,则必须重新修改这个列表文件,很多朋友因为复杂而且维护困难而头痛。
下面介绍我经常采用的一种方法(范例来自Solaris平台,其他平台可以酌情修改),供读者朋友参考。
首先创建一个Shell脚本(本例脚本名为tables.sh),这个脚本用于动态生成一个需要备份的数据表列表文件tables.lst,在查询语句中,就可以排除不需要备份的用户或特定数据表,不需要备份的表应该有限,所以维护这个查询应该容易得多:
sqlplus -S "/ as sysdba" >/dev/null <<EOF
set echo off
set termout off
set feedback off
set heading off
set linesize 120
set pagesize 0
select to_char(sysdate,'''yyyy-mm-dd hh:mm:ss''') from dual;
spool /usr/oracle/backup/tables.lst
SELECT 'tables=(' || CHR (10) FROM DUAL;
SELECT owner || '.' || table_name || ',' || CHR (10)
FROM dba_tables
WHERE owner NOT IN ('SYS', 'SYSTEM', 'CTXSYS', 'ORDSYS', 'MDSYS')
AND table_name NOT IN
('SMS_LOG','SMS_RESPREPT_ERROR','SMS_STATUSREPT','PUSH_USER_INFO_LOG')
ORDER BY owner;
SELECT 'SYS.DUAL' FROM DUAL;
SELECT ')' FROM DUAL;
spool off
EOF
此处生成的tables.lst文件类似如下格式,这个列表排除了我们不需要备份的数据表:
tables=(
DBMON.EXTEND_TEMP,
DBMON.DBA_IOEXTEND_DAY,
DBMON.DBA_IOEXTEND_WEEK,
DBMON.DBA_IOEXTEND_MONTH,
DBY.DBY2_SYSTEM_INFO,
DBY.DBY2_AREA_PROPERTY,
SYS.DUAL
)
然后定义一个包含不变参数的参数文件,这个文件名为exp_temp.parfile,这个文件的内容类似:
userid=username/passwd
filesize=2046M
file=(/u02/backup/oracle/expfull/fulldmp1.dmp,/u02/backup/oracle/expfull/fulldmp2.dmp,…..,/u02/backup/oracle/expfull/fulldmp15.dmp)
rows=y
log=/usr/oracle/backup/expfull.log
compress=n
buffer=40960000
direct=y
注意这里的file参数和filesize参数配合,当一个导出文件大于filesize指定的大小时,即开始转储内容到下一个文件,在某些不支持大文件的平台上,这个两个参数极为有效。
接下来我们可以通过shell的基本命令生成一个正式的导出参数文件:
cat /usr/oracle8/backup/exp_temp.parfile > /usr/oracle8/backup/expfull.parfile
cat /usr/oracle8/backup/tables.lst >> /usr/oracle8/backup/expfull.parfile
这时生成的expfull.parfile文件就包含了所有需要备份的数据表,当然是排除了一些不需要备份数据表的参数文件。
然后可以通过一个脚本来执行EXP,调用参数文件执行备份,这个脚本叫做start_exp.sh(做了适当简化):
BACK_HOME=/u02/backup/oracle
BACK_DEST=$BACK_HOME/expfull
SH_HOME=/usr/oracle/backup
DBA="eygle@eygle.com"
DATE=`date +%m%d:%H.%M`
IP="11.15.112.19"
exp_log_file=$SH_HOME/expfull.log
MAIL_COMMAND=/usr/bin/mailx
$ORACLE_BIN/exp parfile=$SH_HOME/expfull.parfile;
cat $exp_log_file |$MAIL_COMMAND -s "exp backup message from $IP $DATE " $DBA
最后还需要一个脚本顺序执行之前的所有步骤,这个脚本成为expfull.sh:
/usr/oracle/backup/tables.sh
cat /usr/oracle/backup/exp_temp.parfile > /usr/oracle/backup/expfull.parfile
cat /usr/oracle/backup/tables.lst >> /usr/oracle/backup/expfull.parfile
/usr/oracle/backup/start_exp.sh
当执行expfull.sh脚本时,数据库将按照定义的参数文件进行导出,也可以通过crontab来定时导出:
oracle >crontab -l
30 1 * * * /oracle/oracle/backup/expfull.sh
这样就定制了一个部分表逻辑备份的策略。
从Oracle 10g开始,Oracle的EXPDP增加了排除或包含表的特定功能,方便了我们的某些特殊需求。在EXPDP的帮助文件中,可以看到存在EXCLUDE和INCLUDE参数:
EXCLUDE 排除特定的对象类型, 例如 EXCLUDE=TABLE:EMP。
FILESIZE 以字节为单位指定每个转储文件的大小。
FLASHBACK_SCN 用于将会话快照设置回以前状态的 SCN。
FLASHBACK_TIME 用于获取最接近指定时间的 SCN 的时间。
FULL 导出整个数据库 (N)。
HELP 显示帮助消息 (N)。
INCLUDE 包括特定的对象类型, 例如 INCLUDE=TABLE_DATA。
这两个参数分别用于指定排除或包含特定类型的数据,但是文档中介绍的命令格式存在问题,这两个参数的正确用法是:
EXCLUDE = object_type[:name_clause] [, ...]
INCLUDE = object_type[:name_clause] [, ...]
Examples:
expdp <other_parameters> SCHEMAS=scott EXCLUDE=SEQUENCE, TABLE:"IN ('EMP', 'DEPT')"
impdp <other_parameters> SCHEMAS=scott INCLUDE=FUNCTION, PACKAGE, PROCEDURE, TABLE:"= 'EMP'"
其中,object_type可以同时定义多个对象类别,name_clause语句可以定义多个对象列表,通过示例可以很好地了解这两个参数的用法。
但是有了这些还不够,由于命令中包含了多个特殊字符,在不同操作系统下需要通过转义字符才能使以上命令顺利执行,下面通过实例来介绍一下这两个参数的使用。
以下是Solaris上Exclude参数的使用范例,需要通过转义字符“\”来将特殊字符转义:
expdp \'/ as sysdba\' directory=DATA_PUMP_DIR \
schemas=rman dumpfile=expdp_rman.dmp EXCLUDE=TABLE:\"IN\(\'DB\',\'TS\'\)\"
当然,最简单的方式仍然是将参数写入一个参数文件来调用,这样就可以避免复杂的参数转义,来看一下以下一个范例,首先定义一个参数文件:
bash-2.03$ cat parfile.par
directory=DATA_PUMP_DIR
schemas=rman
dumpfile=expdp_rman.dmp
INCLUDE=TABLE:"IN('DB','TS')"
然后调用这个参数文件执行导出:
bash-2.03$ expdp \'/ as sysdba\' PARFILE=parfile.par
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
. . exported "RMAN"."DB" 0 KB 0 rows
. . exported "RMAN"."TS" 0 KB 0 rows
Master table "SYS"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYS.SYS_EXPORT_SCHEMA_01 is:
/data2/ora10g/10.2.0/rdbms/log/expdp_rman.dmp
Job "SYS"."SYS_EXPORT_SCHEMA_01" successfully completed at 16:13:59
同样,EXPDP也支持通配符匹配的导出操作,例如,如下参数文件将导出表名中包含E字母的所有表:
bash-2.03$ cat parfile.par
directory=DATA_PUMP_DIR
schemas=rman
dumpfile=expdp_rman.dmp
INCLUDE=TABLE:"LIKE '%E%'"
看一下执行过程:
bash-2.03$ expdp \'/ as sysdba\' PARFILE=parfile.par
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
. . exported "RMAN"."RCVER" 4.929 KB 1 rows
. . exported "RMAN"."NODE" 0 KB 0 rows
Master table "SYS"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYS.SYS_EXPORT_SCHEMA_01 is:
/data2/ora10g/10.2.0/rdbms/log/expdp_rman.dmp
Job "SYS"."SYS_EXPORT_SCHEMA_01" successfully completed at 16:16:43
在Window上的转义与UNIX下有所不同,请参考EXP部分关于查询子句部分的介绍。