今天三思问我一个问题:RMAN备份FORMAT格式中%a的含义。
其实Oracle的文档有这个表述:
%a
Specifies the activation ID of the database.
不过这个描述很不明确。其实junsansi的意思是,这个%a对应的信息在数据库中的哪里体现出来。
下面先看看备份信息里面的这个值:
[oracle@yans1 ~]$ rman target /
Recovery Manager: Release 10.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: Release 10.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 Database 10g Enterprise Edition Release 10.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, image: 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 oct=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 obj=0 op='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=0a avl=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=0a avl=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=0a avl=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 oct=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 obj=0 op='SORT AGGREGATE (cr=0 pr=0 pw=0 time=19 us)'
STAT #3 id=2 cnt=0 pid=1 pos=1 obj=0 op='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的时候有一定的规则。