今天三思问我一个问题:RMAN备份FORMAT格式中%a的含义。



其实Oracle的文档有这个表述:


%a

Specifies the activation ID of the database.

不过这个描述很不明确。其实junsansi的意思是,这个%a对应的信息在数据库中的哪里体现出来。

下面先看看备份信息里面的这个值:

[oracle@yans1 ~]$ rman target /


Recovery Manager: Release10.2.0.3.0 - Production on星期四7月16 14:18:14 2009


Copyright (c) 1982, 2005, Oracle.  All rights reserved.


connected to target database: TEST08 (DBID=3812548755)


RMAN> backup tablespace users format '/data/backup/test08_%a';


Starting backup at 16-7月-09


using target database control file instead of recovery catalog


allocated channel: ORA_DISK_1


channel ORA_DISK_1: sid=100 devtype=DISK


channel ORA_DISK_1: starting full datafile backupset


channel ORA_DISK_1: specifying datafile(s) in backupset


RMAN-00571: ===========================================================


RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============


RMAN-00571: ===========================================================


RMAN-03009: failure of backup command on ORA_DISK_1 channel at 07/16/2009 14:18:38


ORA-19602: cannot backup or copy active file in NOARCHIVELOG mode


RMAN> sql 'alter tablespace users read only';


sql statement: alter tablespace users read only


RMAN> backup tablespace users format '/data/backup/test08_%a';


Starting backup at 16-7月-09


using channel ORA_DISK_1


channel ORA_DISK_1: starting full datafile backupset


channel ORA_DISK_1: specifying datafile(s) in backupset


input datafile fno=00004 name=/data/oradata/test08/users01.dbf


channel ORA_DISK_1: starting piece 1 at 16-7月-09


channel ORA_DISK_1: finished piece 1 at 16-7月-09


piece handle=/data/backup/test08_657125523 tag=TAG20090716T141924 comment=NONE


channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01


Finished backup at 16-7月-09


RMAN> exit



Recovery Manager complete.


可以看到,对应的activation的ID是657125523。

而且根据文档的描述,这个属性是数据库的,但是在V$DATABASE视图中找不到这个对应的值。

SQL> SELECT VIEW_DEFINITION FROM V$FIXED_VIEW_DEFINITION


 2  WHERE VIEW_NAME = 'GV$DATABASE';


VIEW_DEFINITION


--------------------------------------------------------------------------------------------


select di.inst_id,di.didbi,di.didbn,to_date(di.dicts,'MM/DD/RR HH24:MI:SS','NLS_CALENDAR=Gregorian'),to_number(di.dirls)


,to_date(di.dirlc,'MM/DD/RR HH24:MI:SS','NLS_CALENDAR=Gregorian'),to_number(di.diprs),to_date(di.diprc,'MM/DD/RR HH24:MI


:SS','NLS_CALENDAR=Gregorian'),decode(di.dimla,0,'NOARCHIVELOG',1,'ARCHIVELOG','MANUAL'),to_number(di.discn),to_number(d


i.difas),decode(bitand(di.diflg,256),256,'CREATED',decode(bitand(di.diflg,1024),1024,'STANDBY',decode(bitand(di.diflg,32


768),32768,'CLONE',decode(bitand(di.diflg,4096),4096,'BACKUP','CURRENT')))),to_date(di.dicct,'MM/DD/RR HH24:MI:SS','NLS_


CALENDAR=Gregorian'),di.dicsq,to_number(di.dickp_scn),to_date(di.dickp_tim,'MM/DD/RR HH24:MI:SS','NLS_CALENDAR=Gregorian


'),decode(bitand(di.diflg,4),4,'REQUIRED',decode(di.diirs,0,'NOT ALLOWED','ALLOWED')),to_date(di.divts,'MM/DD/RR HH24:MI


:SS','NLS_CALENDAR=Gregorian'),decode(di.didor,0,'MOUNTED',decode(di.didor,1,'READ WRITE','READ ONLY')),decode(bitand(di


.diflg,65536),65536,'MAXIMUM PROTECTION',decode(bitand(di.diflg,128),128,'MAXIMUM AVAILABILITY',decode(bitand(di.diflg,1


34217728),134217728,'RESYNCHRONIZATION',decode(bitand(di.diflg,8),8,'UNPROTECTED','MAXIMUM PERFORMANCE')))),decode(di.di


prt,1,'MAXIMUM PROTECTION',2,'MAXIMUM AVAILABILITY',3,'RESYNCHRONIZATION',4,'MAXIMUM PERFORMANCE',5,'UNPROTECTED',  'UNK


NOWN'),decode(di.dirae,0,'DISABLED',1,'SEND',2,'RECEIVE',3,'ENABLED','UNKNOWN'),to_number(di.diacid),to_number(di.diacid


),decode(bitand(di.diflg,33554432),33554432,'LOGICAL STANDBY',decode(bitand(di.diflg,1024),1024,'PHYSICAL STANDBY','PRIM


ARY')),to_number(di.diars),decode(bitand(difl2,1),1,'ENABLED','DISABLED'),decode(di.disos,0,'IMPOSSIBLE',1,'NOT ALLOWED'


,2,'SWITCHOVER LATENT',3,'SWITCHOVER PENDING',4,'TO PRIMARY',5,'TO STANDBY',6,'RECOVERY NEEDED',7,'SESSIONS ACTIVE',8,'P


REPARING SWITCHOVER',9,'PREPARING DICTIONARY',10,'TO LOGICAL STANDBY','UNKNOWN'),decode(di.didgd,0,'DISABLED','ENABLED')


,decode(bitand(di.diflg,1048576),1048576,'ALL',decode(bitand(di.diflg,2097152),2097152,'STANDBY','NONE')),decode(bitand(


diflg,1073741824),1073741824, 'YES',               decode(bitand(diflg, 131072 + 262144 + 524288),0,


 decode(bitand(difl2,2), 0,'NO','IMPLICIT'),                     'IMPLICIT')),decode(bitand(di.diflg,131072),131072,'YE


S','NO'),decode(bitand(di.diflg,262144),262144,'YES','NO'),decode(bitand(di.diflg,268435456),268435456,'YES','NO'),di.di


plid, di.dipln, di2.di2rdi, di2.di2inc,to_number(di.dicur_scn),decode(bitand(di2.di2flag,1),1,'YES',               decod


e(di2.di2rsp_oldest,0,'NO','RESTORE POINT ONLY')),decode(bitand(diflg,524288),524288,'YES','NO'),decode(bitand(difl2,2),


2,'YES','NO'),di.didbun, to_number(di2.di2actiscn), decode(di.difsts,0,'DISABLED',1,'BYSTANDER',2,'SYNCHRONIZED',3,'UNSY


NCHRONIZED',4,'SUSPENDED',5,'STALLED',6,'LOADING DICTIONARY',7,'PRIMARY UNOBSERVED',8,'REINSTATE REQUIRED',9,'REINSTATE


IN PROGRESS',10,'REINSTATE FAILED',''), di.diftgt, di.difths,decode(di.difopr,1,'YES',2,'NO',3,'UNKNOWN',''), di.difobs


from x$kccdi di, x$kccdi2 di2


检查X$KCCDI视图,发现DIRLC_I列对应的数值就是format中%a对应的数值:

SQL> SELECT DIDBN, DIRLC, DIRLC_I


 2  FROM X$KCCDI;


DIDBN     DIRLC                   DIRLC_I


--------- -------------------- ----------


TEST08    06/11/2008 14:52:03   657125523


DIRLC列对应的是RESETLOG的时间,而这个DIRLC_I实际上RESETLOG时间对应的数值。

当然这个数值是通过比较备份结果和X$KCCDI视图的查询结果得到的。下面分析一下RMAN是如何获取这个值的:

[oracle@yans1 ~]$ rman target /


Recovery Manager: Release10.2.0.3.0 - Production on星期四7月16 17:23:41 2009


Copyright (c) 1982, 2005, Oracle.  All rights reserved.


connected to target database: TEST08 (DBID=3812548755)


RMAN> backup spfile;


Starting backup at 16-7月-09


using target database control file instead of recovery catalog


allocated channel: ORA_DISK_1


channel ORA_DISK_1: sid=69 devtype=DISK


channel ORA_DISK_1: starting full datafile backupset


channel ORA_DISK_1: specifying datafile(s) in backupset


including current SPFILE in backupset


channel ORA_DISK_1: starting piece 1 at 16-7月-09


channel ORA_DISK_1: finished piece 1 at 16-7月-09


piece handle=/opt/ora10g/product/10.2.0/db_1/dbs/05kk9u17_1_1 tag=TAG20090716T172351 comment=NONE


channel ORA_DISK_1: backup set complete, elapsed time: 00:00:02


Finished backup at 16-7月-09


首先登陆RMAN,并执行一个备份,确保RMAN进程都已经启动。后台检查RMAN对应的会话:

SQL> SELECT SID, SERIAL#, PROGRAM,


 2  (SELECT SPID FROM V$PROCESS WHERE ADDR = PADDR) SPID


 3  FROM V$SESSION


 4  WHERE USERNAME = 'SYS'


 5  AND PROGRAM LIKE 'rman%';


      SID    SERIAL# PROGRAM                                          SPID


---------- ---------- ------------------------------------------------ ------------


       69       1056 rman@yans1 (TNS V1-V3)                           3104


      104       1043 rman@yans1 (TNS V1-V3)                           3103


      111       1644 rman@yans1 (TNS V1-V3)                           3101


设置会话的TRACE:

SQL> EXEC DBMS_MONITOR.SESSION_TRACE_ENABLE(69, 1056, FALSE, TRUE)


PL/SQL procedure successfully completed.


SQL> EXEC DBMS_MONITOR.SESSION_TRACE_ENABLE(104, 1043, FALSE, TRUE)


PL/SQL procedure successfully completed.


SQL> EXEC DBMS_MONITOR.SESSION_TRACE_ENABLE(111, 1644, FALSE, TRUE)


PL/SQL procedure successfully completed.


在RMAN中备份,并退出:

RMAN> backup tablespace users format '/data/backup/%a_users';


Starting backup at 16-7月-09


using channel ORA_DISK_1


channel ORA_DISK_1: starting full datafile backupset


channel ORA_DISK_1: specifying datafile(s) in backupset


input datafile fno=00004 name=/data/oradata/test08/users01.dbf


channel ORA_DISK_1: starting piece 1 at 16-7月-09


channel ORA_DISK_1: finished piece 1 at 16-7月-09


piece handle=/data/backup/657125523_users tag=TAG20090716T173721 comment=NONE


channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01


Finished backup at 16-7月-09


RMAN> exit



Recovery Manager complete.


检查对应的trace信息:

[oracle@yans1 ~]$ more /opt/ora10g/admin/test08/udump/test08_ora_3104.trc


/opt/ora10g/admin/test08/udump/test08_ora_3104.trc


Oracle Database10gEnterprise Edition Release10.2.0.3.0 - 64bit Production


With the Partitioning, OLAP and Data Mining options


ORACLE_HOME = /opt/ora10g/product/10.2.0/db_1


System name:    Linux


Node name:      yans1


Release:        2.6.9-42.0.0.0.1.ELsmp


Version:        #1 SMP Sun Oct 15 15:13:57 PDT 2006


Machine:        x86_64


Instance name: test08


Redo thread mounted by this instance: 1


Oracle process number: 33


Unix process pid: 3104, p_w_picpath: oracle@yans1 (TNS V1-V3)


*** 2009-07-16 17:37:21.447


*** ACTION NAME:(0000027 FINISHED129) 2009-07-16 17:37:21.447


*** MODULE NAME:(backup full datafile) 2009-07-16 17:37:21.447


*** SERVICE NAME:(SYS$USERS) 2009-07-16 17:37:21.447


*** SESSION ID:(69.1056) 2009-07-16 17:37:21.447


RPC CALL:PROCEDURE SYS.DBMS_BACKUP_RESTORE.SETLIMIT(NAME IN BINARY_INTEGER, VALUE IN NUMBER);


RPC BINDS:


bind 0: dty=3 bfp=2a9732bfe8 flg=00 avl=04 mxl=04 val=06


bind 1: dty=6 bfp=2a9732c010 flg=00 avl=01 mxl=22 val=0


*** ACTION NAME:(0000028 FINISHED6) 2009-07-16 17:37:21.448


.


.


.


=====================


PARSING IN CURSOR #3 len=189 dep=0 uid=0 ct=3 lid=0 tim=1218493204547834 hv=3039982291 ad='f552eef0'


SELECT TO_CHAR(SYSDATE  , 'YYYY' , 'NLS_CALENDAR=Gregorian' )  , TO_CHAR(SYSDATE  , 'MM' , 'NLS_CALENDAR=Gregorian' )  , TO_CHAR(SYS


DATE  , 'DD' , 'NLS_CALENDAR=Gregorian' )  FROM X$DUAL  


END OF STMT


PARSE #3:c=1000,e=674,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=1218493204547832


BINDS #3:


EXEC #3:c=0,e=28,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1218493204547907


FETCH #3:c=0,e=27,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,tim=1218493204547952


STAT #3 id=1 cnt=1 pid=0 pos=1 bj=0 p='FIXED TABLE FULL X$DUAL (cr=0 pr=0 pw=0 time=22 us)'


RPC CALL:FUNCTION SYS.DBMS_BACKUP_RESTORE.GENPIECENAME(PNO IN NUMBER, SET_COUNT IN NUMBER, SET_STAMP IN NUMBER, FORMAT IN VARCHAR2,


COPYNO IN NUMBER, DEVTYPE IN VARCHAR2, YEAR IN BINARY_INTEGER, MONTH IN BINARY_INTEGER, DAY IN BINARY_INTEGER, DBID IN NUMBER


, NDBNAME IN VARCHAR2, CFSEQ IN NUMBER, FILENO IN NUMBER, TSNAME IN VARCHAR2, LOGSEQ IN VARCHAR2, LOGTHR IN NUMBER, IMAGCP IN BOOLEA


N, SAVEPNAME IN BOOLEAN) RETURN VARCHAR2;


RPC BINDS:


bind 0: dty=6 bfp=2a9732bfe8 flg=00 avl=02 mxl=22 val=1


bind 1: dty=6 bfp=2a9732c020 flg=00 avl=02 mxl=22 val=6


bind 2: dty=6 bfp=2a9732c058 flg=00 avl=06 mxl=22 val=692386641


bind 3: dty=1 bfp=2a9732c0a0 flg=08 avl=21 mxl=512 val="/data/backup/%a_users"


bind 4: dty=6 bfp=2a9732c2c0 flg=00 avl=02 mxl=22 val=1


bind 5: dty=1 bfp=2a9732c308 flg=08 avl=04 mxl=16 val="DISK"


bind 6: dty=3 bfp=2a9732c338 flg=00 avl=04 mxl=04 val=2009


bind 7: dty=3 bfp=2a9732c360 flg=00 avl=04 mxl=04 val=07


bind 8: dty=3 bfp=2a9732c388 flg=00 avl=04 mxl=04 val=16


bind 9: dty=6 bfp=2a9732c3b0 flg=02 avl=00 mxl=22 val=00


bind 10: dty=1 bfp=2a9732c3f8 flg=0aavl=00 mxl=08 val=""


bind 11: dty=6 bfp=2a9732c420 flg=02 avl=00 mxl=22 val=00


bind 12: dty=6 bfp=2a9732c458 flg=00 avl=02 mxl=22 val=4


bind 13: dty=1 bfp=2a9732c4a0 flg=08 avl=05 mxl=30 val="USERS"


bind 14: dty=1 bfp=2a9735cff8 flg=0aavl=00 mxl=32767 val=""


bind 15: dty=6 bfp=2a97380b80 flg=02 avl=00 mxl=22 val=00


bind 16: dty=3 bfp=2a97380bb8 flg=00 avl=04 mxl=04 val=00


bind 17: dty=3 bfp=2a97380be0 flg=00 avl=04 mxl=04 val=00


bind 18: dty=1 bfp=2a9736cff8 flg=0aavl=00 mxl=32767 val=""


*** ACTION NAME:(0000037 FINISHED91) 2009-07-16 17:37:21.457


RPC EXEC:c=0,e=475


RPC CALL:PROCEDURE SYS.DBMS_BACKUP_RESTORE.ISFILENAMEOMF(FNAME IN VARCHAR2, ISOMF OUT BOOLEAN, ISASM OUT BOOLEAN, ISTMPLT OUT BOOLEA


N);


RPC BINDS:


bind 0: dty=1 bfp=2a9732bff8 flg=08 avl=28 mxl=512 val="/data/backup/657125523_users"


bind 1: dty=3 bfp=2a9732c218 flg=02 avl=04 mxl=04 val=00


bind 2: dty=3 bfp=2a9732c240 flg=02 avl=04 mxl=04 val=00


bind 3: dty=3 bfp=2a9732c268 flg=02 avl=04 mxl=04 val=00


*** ACTION NAME:(0000038 FINISHED142) 2009-07-16 17:37:21.458


.


.


.


*** ACTION NAME:(0000046 FINISHED5) 2009-07-16 17:37:22.516


RPC EXEC:c=0,e=150


RPC CALL:PROCEDURE SYS.DBMS_BACKUP_RESTORE.BMRCANCEL();


RPC BINDS:


*** ACTION NAME:(0000047 FINISHED101) 2009-07-16 17:37:22.517


RPC EXEC:c=0,e=74


RPC CALL:PROCEDURE SYS.DBMS_BACKUP_RESTORE.FLASHBACKCANCEL();


RPC BINDS:


*** ACTION NAME:(0000048 FINISHED118) 2009-07-16 17:37:22.517


RPC EXEC:c=1000,e=79


=====================


PARSING IN CURSOR #3 len=32 dep=0 uid=0 ct=3 lid=0 tim=1218493205583311 hv=708194795 ad='f7893f18'


select count(*) from sys.x$kcrmx


END OF STMT


PARSE #3:c=0,e=32,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1218493205583309


BINDS #3:


EXEC #3:c=0,e=36,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=1218493205583425


FETCH #3:c=0,e=10,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,tim=1218493205583448


STAT #3 id=1 cnt=1 pid=0 pos=1 bj=0 p='SORT AGGREGATE (cr=0 pr=0 pw=0 time=19 us)'


STAT #3 id=2 cnt=0 pid=1 pos=1 bj=0 p='FIXED TABLE FULL X$KCRMX (cr=0 pr=0 pw=0 time=8 us)'


RPC CALL:PROCEDURE SYS.DBMS_BACKUP_RESTORE.SETRMANSTATUSROWID(RSID IN NUMBER, RSTS IN NUMBER);


RPC BINDS:


bind 0: dty=6 bfp=2a9732bfe8 flg=00 avl=01 mxl=22 val=0


bind 1: dty=6 bfp=2a9732c020 flg=00 avl=01 mxl=22 val=0


*** ACTION NAME:(0000049 FINISHED129) 2009-07-16 17:37:22.517


RPC EXEC:c=0,e=112


可以看到,Oracle通过调用函数DBMS_BACKUP_RESTORE.GENPIECENAME获取的BACKUP段名称,也就是说%a对应的值,是通过这个函数调用获取的。

而且这个函数调用的内部SQL语句Oracle没有跟踪到。说明这个包的实现可能不是在数据库的SQL层实现的。

不过分析RMAN的trace信息还是有一定意义的,在分析RMAN访问视图时,找到了对应的信息:

SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';


Session altered.


SQL> select incarnation#, resetlogs_change#, resetlogs_time, resetlogs_id, status


 2  from v$database_incarnation;


INCARNATION# RESETLOGS_CHANGE# RESETLOGS_TIME      RESETLOGS_ID STATUS


------------ ----------------- ------------------- ------------ -------


          1                 1 2008-06-11 14:52:03    657125523 CURRENT


其实这个RESETLOGS_ID的值在V$ARCHIVED_LOG视图中也可以找到。而且这个值对应的就是归档日志格式中的%r。只不过Oracle在不同的地方采用了不同的表示方式,而且描述上也有所区别。

另外这个RESETLOGS_ID显然是由RESETLOGS_TIME决定的,看一个有趣的现象:

SQL> select resetlogs_time - resetlogs_id/86400 from v$database_incarnation;


RESETLOGS_TIME-RESE


-------------------


1987-08-16 00:00:00


测试了很多数据库,得到的结果都是1987年8月的某一日。显然Oracle在记录这个RESETLOGS_ID的时候有一定的规则。



oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html