_use_adaptive_log_file_sync know more

Configuration Parameters
The following parameters affect the behavior of adaptive log file sync:

  • _use_adaptive_log_file_sync
    • TRUE: Enable adaptive log file sync (default)
    • FALSE: Disable adaptive log file sync (i.e., just use post/wait)
    • POLLING_ONLY: Use polling with adaptive polling interval
  • _adaptive_log_file_sync_use_polling_threshold
    • Larger values make it harder to switch to polling
    • Default value is 110%, which means the current redo synch time must exceed the expected poll time
    • by at least 10% for the algorithm to favor polling over post/wait
    • In the pseudocode above, refer to the use_polling_threshold variable
  • _adaptive_log_file_sync_use_postwait_threshold
    • Smaller values make it harder to switch to post/wait
    • Default value is 50%, which means the current scheduling delay needs to drop to half of that when
    • polling was first used for the algorithm to favor post/wait over polling
    • In the pseudocode above, refer to the use_postwait_threshold variable
  • _adaptive_log_file_sync_poll_aggressiveness
    • Larger values result in smaller polling intervals
    • Default value is 0%, which means none of the current scheduling delay is subtracted from the polling interval
  • _adaptive_log_file_sync_sched_delay_window
    • The window over which the current scheduling delay is computed
    • Default value is 60 seconds, and it is unlikely you need to adjust this
  • _adaptive_log_file_sync_high_switch_freq_threshold
    • A warning is printed if adaptive log file sync switches frequently between post/wait and polling
    • If it is an LRG, a soft assert is also signalled
    • Default threshold is 3 switches per minute
  • _fg_sync_sleep_usecs
    • A non-zero value specified will use polling with a fixed interval and disable adaptive log file sync
  • _log_file_sync_timeout
    • How long the foreground waits for LGWR to post it when post/wait is used
    • Default value is 100 msecs

Maclean教你读SQL TRACE TKProf报告

在《Maclean教你读Oracle 10046 SQL TRACE》中我介绍了10046 TRACE的阅读以及其中个字段的含义, 接着我们介绍 10046 sql trace的搭档工具TKPROF。

 

TKPROF是一个可执行文件,自带在Oracle Server软件中,无需额外的安装。 该工具文件可以用来解析ORACLE的SQL TRACE(10046) 以便生成更可读的内容。  实际上tkprof是对10046 SQL trace的内容作了汇总,例如一个语句遇到过的wait event 、其在PARSE、Execute、Fetch三阶段的耗时、CPU_TIME等等。

 

由于tkprof是对10046 SQL TRACE的汇总,所以tkprof中的信息 完全可以从10046中获得, 10046的问题是 由于巨细靡遗 所以TRACE内容可能过多,内容多则难以快速分析, TKPROF将10046  trace 解析过后更适合调优者阅读。

 

TKPROF的语法如下:

tkprof tracefile outfile [explain=user/password] [options…]

几个选项

print=integer     只列出前几个SQL语句,integer    为指定的数量,例如print=10

sys=no                不列出以SYS用户运行的语句

sort=option         排序选项, 选项列表如下:

 

 

  • prscnt number of times parse was called
  • prscpu cpu time parsing
  • prsela elapsed time parsing
  • prsdsk number of disk reads during parse
  • prsqry number of buffers for consistent read during parse
  • prscu number of buffers for current read during parse
  • prsmis number of misses in library cache during parse
  • execnt number of execute was called
  • execpu cpu time spent executing
  • exeela elapsed time executing
  • exedsk number of disk reads during execute
  • exeqry number of buffers for consistent read during execute
  • execu number of buffers for current read during execute
  • exerow number of rows processed during execute
  • exemis number of library cache misses during execute
  • fchcnt number of times fetch was called
  • fchcpu cpu time spent fetching
  • fchela elapsed time fetching
  • fchdsk number of disk reads during fetch
  • fchqry number of buffers for consistent read during fetch
  • fchcu number of buffers for current read during fetch
  • fchrow number of rows fetched
  • userid userid of user that parsed the cursor

 

 

接下来看一个最简单的 TKPROF的例子:

 

 

 

 

drop table fullscan;

create table fullscan as select * from dba_objects;

exec dbms_stats.gather_table_stats(user,'FULLSCAN');

alter system flush shared_pool;
alter system flush buffer_cache;

alter session set events '10046 trace name context forever,level 12';

select count(*) from fullscan;

oradebug setmypid
oradebug tracefile_name;

/s01/admin/G10R25/udump/g10r25_ora_30334.trc

[oracle@vrh8 udump]$ tkprof /s01/admin/G10R25/udump/g10r25_ora_30334.trc 30334.tkf

TKPROF: Release 10.2.0.5.0 - Production on Sun Aug 25 02:21:27 2013   askmaclean.com

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

vi  30334.tkf

Trace file: /s01/admin/G10R25/udump/g10r25_ora_30334.trc
Sort options: default

********************************************************************************
count    = number of times OCI procedure was executed
cpu      = cpu time in seconds executing
elapsed  = elapsed time in seconds executing
disk     = number of physical reads of buffers from disk
query    = number of buffers gotten for consistent read
current  = number of buffers gotten in current mode (usually for update)
rows     = number of rows processed by the fetch or execute call
********************************************************************************

select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1,
  spare2
from
 obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null
  and linkname is null and subname is null

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      0.00       0.00          2          4          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.00       0.00          2          4          0           1

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS   (recursive depth: 1)

Rows     Row Source Operation
-------  ---------------------------------------------------
      1  TABLE ACCESS BY INDEX ROWID OBJ$ (cr=4 pr=2 pw=0 time=133 us)
      1   INDEX RANGE SCAN I_OBJ2 (cr=3 pr=1 pw=0 time=74 us)(object id 37)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1        0.01          0.01
  db file sequential read                         2        0.00          0.00
********************************************************************************

select count(*)
from
 fullscan

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          4         15          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.01       0.01       1139       1143          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.02       0.02       1143       1158          0           1

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Rows     Row Source Operation
-------  ---------------------------------------------------
      1  SORT AGGREGATE (cr=1143 pr=1139 pw=0 time=15759 us)
  77268   TABLE ACCESS FULL FULLSCAN (cr=1143 pr=1139 pw=0 time=463719 us)  

Elapsed times include waiting on following events:      
  Event waited on                             Times   Max. Wait  Total Waited  
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       2        0.00          0.00  
  db file sequential read                         1        0.00          0.00
  db file scattered read                         80        0.00          0.00
  SQL*Net message from client                     2        0.00          0.00

 

 

 

 

 

在上述例子中我们可以看到TKPROF将 一个SQL Statement 的运行 划分为几个部分的信息:

1. SQL 语句的parse 、execute 、fetch 阶段的耗时:

 

select count(*)
from
 fullscan

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          4         15          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.01       0.01       1139       1143          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.02       0.02       1143       1158          0           1

 

 

 

call: 每一个游标的行为被分成三个步骤:

  • Parse: 解析该游标并生成执行计划的统计信息
  • Execute: 执行该游标阶段的统计信息
  • Fetch : Fetch取得数据行阶段的统计信息

 

  • count   指的是该游标的相关操作 的次数,例如parse count : 2 ,即该游标解析了2次
  • CPU :   相关栏目 所消耗的CPU时间,单位为s
  • elapsed:  相关栏目所消耗的时间,单位为s
  • disk :     相关栏目所消耗的物理读
  • query :  相关栏目所消耗的一致性逻辑读 consistent logical read   ==>一般对于SELECT查询而言 只有query 没有current
  • current: 相关栏目当前逻辑读 current logical read
  • rows 该步骤取回的行数 ==》在本例中由于是 count(*) 所以只有一行
  • Misses in library cache during parse: 1   在解析阶段 library cache 发生了miss,则说明本次解析是硬解析

 

几点释疑:

 

1、对于PL/SQL而言 匿名块/存储过程 以及其中包含的SQL语句会同时体现在TKPROF中,即存在重叠;且SQL将以递归SQL的形式出现:

PARSING IN CURSOR #4 len=56 dep=1 uid=0 oct=6 lid=0 tim=1345130672819745 hv=3509762282 ad=’a7525f30′
UPDATE FULLSCAN SET OWNER=’MACLEAN’ WHERE OBJECT_ID=:B1

 

COMMIT也是这样:

PARSING IN CURSOR #2 len=6 dep=1 uid=0 oct=44 lid=0 tim=1345130672822889 hv=255718823 ad=’0′
COMMIT

 

我们来看一个实际的例子:

 

 

alter system flush shared_pool;
alter system flush buffer_cache;
set timing on;
alter session set events '10046 trace name context forever,level 12';
create index ind_objd on fullscan(object_id);

begin
for i in 1..10000 loop
update fullscan set owner='MACLEAN' where object_id=i;
commit;
end loop;
end;
/
PL/SQL procedure successfully completed.

Elapsed: 00:00:04.00

begin
for i in 1..10000 loop
update fullscan set owner='MACLEAN' where object_id=i;
commit;
end loop;
end;

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.62       0.68        178      20037          0           1
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.62       0.68        178      20037          0           1

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  log file sync                                   1        0.00          0.00
  SQL*Net message to client                       1        0.00          0.00

********************************************************************************

UPDATE FULLSCAN SET OWNER='MACLEAN'
WHERE
 OBJECT_ID=:B1

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute  10000      2.90       2.69        178      20037      19364        9564
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    10001      2.90       2.69        178      20037      19364        9564

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS   (recursive depth: 1)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                       177        0.00          0.00

COMMIT

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute  10000      0.43       0.52          0          0       9564           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    10001      0.43       0.52          0          0       9564           0

Misses in library cache during parse: 0
Parsing user id: SYS   (recursive depth: 1)

 

 

 

以上通过一个匿名块  循环执行了10000次的 “update fullscan set owner=’MACLEAN’ where object_id=i;” 以及commit  总的执行 Elapsed: 00:00:04.00 。

该匿名块总耗时为0.68s, 10000次循环update fullscan为2.69s,10000次commit总耗时0.52s ,  0.68+0.52+2.69=3.89s ,此外还有少量的递归SQL耗时也算在这个4.0s里。

 

 

2、 在以上例子中看到, 对于 PL/SQL匿名块、update、commit而言 有execute 阶段 ,而没有 fetch阶段,fetch的次数为0。   对于SELECT语句而言 ,有execute阶段,但是execute阶段的disk、query、current一般为零,统统算在Fetch阶段。

 

 

 

begin
for i in 1..10000 loop
update fullscan set owner='MACLEAN' where object_id=i;
commit;
end loop;
end;

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.62       0.68        178      20037          0           1
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.62       0.68        178      20037          0           1

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  log file sync                                   1        0.00          0.00
  SQL*Net message to client                       1        0.00          0.00

PARSING IN CURSOR #5 len=106 dep=0 uid=0 oct=47 lid=0 tim=1345130672819492 hv=3631473533 ad='a750b960'
begin
for i in 1..10000 loop
update fullscan set owner='MACLEAN' where object_id=i;
commit;
end loop;
end;
END OF STMT
PARSE #5:c=1000,e=891,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=1345130672819487
BINDS #5:

EXEC #5:c=3968396,e=3907489,p=178,cr=20037,cu=28928,mis=0,r=1,dep=0,og=1,tim=1345130676727033
WAIT #5: nam='log file sync' ela= 162 buffer#=8084 sync scn=14950441 p3=0 obj#=96606 tim=1345130676727293
WAIT #5: nam='SQL*Net message to client' ela= 5 driver id=1650815232 #bytes=1 p3=0 obj#=96606 tim=1345130676727343
*** 2013-08-25 03:00:52.748
WAIT #5: nam='SQL*Net message from client' ela= 234159641 driver id=1650815232 #bytes=1 p3=0 obj#=96606 tim=1345130910887016

 

 

 

3、实际在10046 中真实反映了 上述匿名块的执行时间为 3907489 μs = 3.9s 以及其总的cr=20037 cu=28928( update的19364+commit的9564),但在TKPROF中 匿名块等PL/SQL对象显示的信息并不全面,这可能是为了避免用户的误解。

 

 

TKPROF提供了多种排序的方法

 

Sort options: default

********************************************************************************
count    = number of times OCI procedure was executed
cpu      = cpu time in seconds executing
elapsed  = elapsed time in seconds executing
disk     = number of physical reads of buffers from disk
query    = number of buffers gotten for consistent read
current  = number of buffers gotten in current mode (usually for update)
rows     = number of rows processed by the fetch or execute call

 

一般我们对于查询的调优 常用的组合是 SYS=NO  fchela, fchela即按照fetch阶段的elapsed time按照从大到小排列

 

 

[oracle@vrh8 udump]$ tkprof g10r25_ora_30731.trc  30731.tkf sys=no sort=fchela    

TKPROF: Release 10.2.0.5.0 - Production on Sun Aug 25 03:39:46 2013

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

Sort options: fchela
********************************************************************************
count    = number of times OCI procedure was executed
cpu      = cpu time in seconds executing
elapsed  = elapsed time in seconds executing
disk     = number of physical reads of buffers from disk
query    = number of buffers gotten for consistent read
current  = number of buffers gotten in current mode (usually for update)
rows     = number of rows processed by the fetch or execute call
********************************************************************************

select count(*)
from
 fullscan

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.01       0.01       1140       1144          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.01       0.01       1140       1144          0           1

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 64

Rows     Row Source Operation
-------  ---------------------------------------------------
      1  SORT AGGREGATE (cr=1144 pr=1140 pw=0 time=14476 us)
  77270   TABLE ACCESS FULL FULLSCAN (cr=1144 pr=1140 pw=0 time=386457 us)

 

 

 

如上Sort options: fchela 后,trace中信息按照fetch elapsed time从长到短排列。

 

 

执行计划

Rows     Row Source Operation
-------  ---------------------------------------------------
      1  SORT AGGREGATE (cr=1144 pr=1140 pw=0 time=14476 us)
  77270   TABLE ACCESS FULL FULLSCAN (cr=1144 pr=1140 pw=0 time=386457 us)

 

 

TKPROF中的执行计划并不现实card、cost等CBO指标, 其所提供的每一个步骤的Rows 、CR、PR 信息对于诊断执行计划到底慢在哪一步有一定帮助, 但是其time耗时信息并不准确。

 

 

等待事件

 

 

  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       2        0.00          0.00
  db file sequential read                         1        0.00          0.00
  db file scattered read                         81        0.00          0.00
  SQL*Net message from client                     2        0.00          0.00

 

 

 

 

TKPROF中简要描述了 语句相关的等待事件, 包括遇到了 多少次该等待事件(Times Waited)、 最长的等待是多久 Max.Wait, 总的等待时间Total Waited ,单位均为 S。

 

10046 中的等待时间描述过于简单,仅为让阅读者简要把握等待问题, 针对等待时间的调优 强烈建议 基于AWR中的wait histogram和ASH去分析, 与他们对比TKPROF显然已经过时了。

 

 

示例解析

 

 

 

select count(1) from big1
where object_id between 10 and 100000
and data_object_id between 1 and 1000
and status like 'VALI%'
and object_type IN ('TABLE', 'INDEX')

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1     20.02 (c)  20.12 (b)      0          1          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      1.13       1.33          0       9087          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4     21.15      21.45 (a)      0       9088          0           1

Misses in library cache during parse: 1  <== 说明是硬解析
Optimizer mode: ALL_ROWS
Parsing user id: 54

 

 

 

  • (a)说明该语句总耗时 21.45s
  • (b) 说明该语句花在解析上的耗时20.12s
  • (c) 说明该语句花在解析上的CPU时间为20.02s
  • 语句解析等待时间= 语句解析耗时 – 语句解析CPU耗时 =  20.12 – 20.02 = 0.10 s

 

以上分析说明 该语句运行的绝大多数耗时花费在解析上, 而解析时 大多数时间是CPU运算, 一般有几种可能导致这么多的CPU运算:

  • 语句过于复杂,导致parse解析和optimize优化 消耗较多CPU
  • 主机CPU忙,进程分配不到足够的CPU时间片
  • 可能遇到resource manager 限制实现CPU

 

视乎实际情况,需要具体分析。

 

【11g新特性】sec_max_failed_login_attempts

【11g新特性】sec_max_failed_login_attempts (默认为10,范围为1到unlimited)这个参数以11g 新特性形式引入, 文档对它的描述是

SEC_MAX_FAILED_LOGIN_ATTEMPTS specifies the number of authentication attempts that can be made by a client on a connection to the server process. After the specified number of failure attempts, the connection will be automatically dropped by the server process.

 

但是有同学怎么测试都无法生效, 实际该参数只对使用了OCI 的特定程序生效,而使用SQLPLUS是无法生效的, 坑爹的新特性:

 

SEC_MAX_FAILED_LOGIN_ATTEMPTS only works application uses OCI Program.SEC_MAX_FAILED_LOGIN_ATTEMPTS not work in sqlplus.
OCI Program have the following ,it wil work.
1.You need to use OCI_THREADED mode.
2.You need to set the attribute ofserver, username, password attributes in the appropriate handles:
3.You need to useOCISessionBegin to connect to the database

 

Maclean教你读Oracle 10046 SQL TRACE

有同学一直向Maclean反应希望做一期10046 SQL trace的教程, 正好这几天有空 我们就理一理。

 

为什么我们要使用10046 trace?

 

10046 trace帮助我们解析 一条/多条SQL、PL/SQL语句的运行状态 ,这些状态包括 :Parse/Fetch/Execute三个阶段中遇到的等待事件、消耗的物理和逻辑读、CPU时间、执行计划等等。

即10046 为我们揭示了 一条/多条SQL 的运行情况, 对于  以点入手的 SQL调优是很好的辅助工具,特别是在 10g之前没有ASH的情况下。 但整体系统调优 不是10046 所擅长的,  10046 是 性能调优的起钉器 , AWR是性能调优 的锤子。

 

10046还能帮助我们分析 一些 DDL维护命令的内部工作原理, RMAN、Data Pump Expdp/Impdp等工具的缓慢问题等, 是研究 oracle 数据库原理的 居家旅行必备良品。

 

10046 和SQL TRACE的区别?

 

10046 比 SQL_TRACE参数提供更多的控制选项, 更详细的内容输出, 一般Maclean只用10046 而不用sql_trace

 

10046 和10053 的区别?

 

10053 是最常用的Oracle 优化器optimizer 跟踪trace, 10053 可以作为我们解析 优化器为什么选择某个执行计划,其中的理由的辅助工具,但并不告诉我们这个执行计划 到底运行地如何。

而10046 并不解释 optimizer优化器的工作, 但它同样说明了在SQL解析parse阶段所遇到的等待事件和所消耗的CPU等资源,以及Execute执行和Fetch阶段的各项指标。

 

简而言之10046 告诉我们SQL(执行计划)运行地如何, 10053告诉我们 优化器为什么为这个SQL选择某个执行计划。

 

 10046 TRACE的LEVEL:

 

不同的Level 对应不同的跟踪级别

  • 1  启用标准的SQL_TRACE功能 ( 默认)  包含了 SQL语句、响应时间、服务时间、处理的行数,物理读和写的数目、执行计划以及其他一些额外信息。   到版本10.2中 执行计划写入到 trace 的条件是仅当相关游标 已经关闭时, 且与之相关的执行统计信息是所有执行次数的总和数据。  到版本11.1中仅在每次游标的第一次执行后将执行计划写入到trace , 执行统计信息仅仅和这第一次执行相关
  • 4 比level 1时多出 绑定变量的 trace
  • 8  比level 1多出等待事件,特别对于9i中指出 latch free等待事件很有用,对于分析全表扫描和索引扫描也很有用
  • 12  比level 1 多出 绑定变量和 等待事件
  • 16  在11g中为每一次执行生成STAT信息,仅在11.1之后可用
  • 32  比level 1少执行计划
  •  64  和level 1 相比 在第一次执行后还可能生成执行计划信息 ; 条件是某个游标在前一次执行的前提下 运行耗时变长了一分钟。仅在 11.2.0.2中可用
  • Level 28 (4 + 8 + 16) 代表 同时启用 level 4 、level 8、level 16
  • level 68 ( 64 + 4 )  代表 同时启用 level 64、level 4

 

 

 

 

设置的方法如下:

 

 

session 级别: alter session set events ‘10046  trace name context forever,level X’;

system 级别 :      alter system  set events ‘10046  trace name context forever,level X’;

 

针对非本会话的 某一个进程设置,如果你知道他的SPID 操作系统进程号

oradebug setospid SPID;

oradebug event 10046 trace name context forever, level X;

 

例如:

 

[oracle@vrh8 ~]$ ps -ef|grep LOCAL  
oracle   12421 12420  0 Aug21 ?        00:00:00 oracleG10R25 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle   12522 12521  0 Aug21 ?        00:00:00 oracleG10R25 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle   12533     1  0 Aug21 ?        00:00:00 oracleG10R25 (LOCAL=NO)
oracle   15354 15353  0 Aug21 ?        00:00:08 oracleG10R25 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle   15419 15418  0 Aug21 ?        00:00:11 oracleG10R25 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle   16219 16218  0 Aug21 ?        00:00:00 oracleG10R25 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
oracle   17098 17097  0 03:12 ?        00:00:00 oracleG10R25 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))

要跟踪 17098  这个进程

SQL> oradebug event 10046 trace name context forever, level 28;
Statement processed.

从 sid 定位到 SPID 或者 ORAPID 的 查询如下:

SQL> select distinct sid from v$mystat;

       SID
----------
       141

SQL> select spid,pid from v$Process where addr=(select paddr from v$session where sid=141);

SPID                PID
------------ ----------
17196                24

select spid,pid from v$Process where addr=(select paddr from v$session where sid=&SID)

如果只知道 ORA的PID 那么也可以

oradebug setorapid 24;
oradebug event 10046 trace name context forever, level 28;

 

 

 

10046 trace 示例解析

 

 

 

这里我们引入一个全表扫描的10046例子 并解析该例子中的TRACE信息:

 

 


PARSING IN CURSOR #20 len=44 dep=0 uid=0 oct=3 lid=0 tim=1344883874047619 hv=2241892608 ad='a7902a08'
select count(*) from fullscan where owner=:v
END OF STMT
PARSE #20:c=2000,e=1087,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=1344883874047610

PARSING IN CURSOR #26 len=198 dep=1 uid=0 oct=3 lid=0 tim=1344883874048534 hv=4125641360 ad='a7ab9fc0'
select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, spare2 from obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null and linkna
me is null and subname is null
END OF STMT
PARSE #26:c=0,e=531,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=1344883874048501
BINDS #26:
kkscoacd
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=7f9ccfec6bd8  bln=22  avl=01  flg=05
  value=0
 Bind#1  
  oacdty=01 mxl=32(08) mxlc=00 mal=00 scl=00 pre=00
  oacflg=18 fl2=0001 frm=01 csi=873 siz=32 off=0
  kxsbbbfp=7f9ccfec6ba0  bln=32  avl=08  flg=05
  value="FULLSCAN"  askmaclean.com
 Bind#2
   oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=7f9ccfec6b70  bln=24  avl=02  flg=05
  value=1
EXEC #26:c=1998,e=1506,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=1344883874050177
WAIT #26: nam='db file sequential read' ela= 26 file#=1 block#=58007 blocks=1 obj#=37 tim=1344883874050345
WAIT #26: nam='db file sequential read' ela= 19 file#=1 block#=58966 blocks=1 obj#=18 tim=1344883874050452

PARSING IN CURSOR #25 len=493 dep=1 uid=0 oct=3 lid=0 tim=1344883874051980 hv=2584065658 ad='a7a9ef68'
select t.ts#,t.file#,t.block#,nvl(t.bobj#,0),nvl(t.tab#,0),t.intcols,nvl(t.clucols,0),t.audit$,t.flags,t.pctfree$,t.pctused$,t.initrans,t.maxtrans,t.rowcnt,t.blkcnt,t.e
mpcnt,t.avgspc,t.chncnt,t.avgrln,t.analyzetime,t.samplesize,t.cols,t.property,nvl(t.degree,1),nvl(t.instances,1),t.avgspc_flb,t.flbcnt,t.kernelcols,nvl(t.trigflag, 0),n
vl(t.spare1,0),nvl(t.spare2,0),t.spare4,t.spare6,ts.cachedblk,ts.cachehit,ts.logicalread from tab$ t, tab_stats$ ts where t.obj#= :1 and t.obj# = ts.obj# (+)
END OF STMT
PARSE #25:c=1000,e=585,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=1344883874051971
BINDS #25:
kkscoacd
 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 off=0
  kxsbbbfp=7f9ccfec6bd8  bln=22  avl=04  flg=05
  value=96551
EXEC #25:c=3000,e=2757,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,tim=1344883874054930
WAIT #25: nam='db file sequential read' ela= 21 file#=1 block#=48756 blocks=1 obj#=3 tim=1344883874055059
WAIT #25: nam='db file sequential read' ela= 18 file#=1 block#=51327 blocks=1 obj#=4 tim=1344883874055149
FETCH #25:c=0,e=538,p=2,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=1344883874055512
STAT #25 id=1 cnt=1 pid=0 pos=1 obj=0 op='MERGE JOIN OUTER (cr=5 pr=2 pw=0 time=565 us)'
STAT #25 id=2 cnt=1 pid=1 pos=1 obj=4 op='TABLE ACCESS CLUSTER TAB$ (cr=3 pr=2 pw=0 time=228 us)'
STAT #25 id=3 cnt=1 pid=2 pos=1 obj=3 op='INDEX UNIQUE SCAN I_OBJ# (cr=2 pr=1 pw=0 time=115 us)'
STAT #25 id=4 cnt=0 pid=1 pos=2 obj=0 op='BUFFER SORT (cr=2 pr=0 pw=0 time=251 us)'
STAT #25 id=5 cnt=0 pid=4 pos=1 obj=709 op='TABLE ACCESS BY INDEX ROWID TAB_STATS$ (cr=2 pr=0 pw=0 time=207 us)'
STAT #25 id=6 cnt=0 pid=5 pos=1 obj=710 op='INDEX UNIQUE SCAN I_TAB_STATS$_OBJ# (cr=2 pr=0 pw=0 time=33 us)'

................

BINDS #20:
kkscoacd
 Bind#0
  oacdty=96 mxl=2000(150) mxlc=00 mal=00 scl=00 pre=00
  oacflg=03 fl2=1000000 frm=01 csi=873 siz=2000 off=0
  kxsbbbfp=7f9ccfec6420  bln=2000  avl=50  flg=05
  value="MACLEAN                                           "
EXEC #20:c=20996,e=21249,p=7,cr=19,cu=0,mis=1,r=0,dep=0,og=1,tim=1344883874068951
WAIT #20: nam='SQL*Net message to client' ela= 6 driver id=1650815232 #bytes=1 p3=0 obj#=36 tim=1344883874069011
WAIT #20: nam='db file sequential read' ela= 23 file#=1 block#=80385 blocks=1 obj#=96551 tim=1344883874069159
WAIT #20: nam='db file scattered read' ela= 42 file#=1 block#=80386 blocks=7 obj#=96551 tim=1344883874069383
WAIT #20: nam='db file scattered read' ela= 41 file#=1 block#=82313 blocks=8 obj#=96551 tim=1344883874069543
WAIT #20: nam='db file scattered read' ela= 30 file#=1 block#=82321 blocks=8 obj#=96551 tim=1344883874069678
WAIT #20: nam='db file scattered read' ela= 38 file#=1 block#=82329 blocks=8 obj#=96551 tim=1344883874069949
WAIT #20: nam='db file scattered read' ela= 848 file#=1 block#=82337 blocks=8 obj#=96551 tim=1344883874070846
WAIT #20: nam='db file scattered read' ela= 63 file#=1 block#=82345 blocks=8 obj#=96551 tim=1344883874071042
WAIT #20: nam='db file scattered read' ela= 37 file#=1 block#=92593 blocks=8 obj#=96551 tim=1344883874071190
WAIT #20: nam='db file scattered read' ela= 73 file#=1 block#=92601 blocks=8 obj#=96551 tim=1344883874071393
FETCH #20:c=18997,e=18234,p=1139,cr=1143,cu=0,mis=0,r=1,dep=0,og=1,tim=1344883874087322
WAIT #20: nam='SQL*Net message from client' ela= 285 driver id=1650815232 #bytes=1 p3=0 obj#=96551 tim=1344883874087675
FETCH #20:c=0,e=3,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,tim=1344883874087715
WAIT #20: nam='SQL*Net message to client' ela= 3 driver id=1650815232 #bytes=1 p3=0 obj#=96551 tim=1344883874087744
*** 2013-08-22 04:44:59.527
WAIT #20: nam='SQL*Net message from client' ela= 12169104 driver id=1650815232 #bytes=1 p3=0 obj#=96551 tim=1344883886256887
STAT #20 id=1 cnt=1 pid=0 pos=1 obj=0 op='SORT AGGREGATE (cr=1143 pr=1139 pw=0 time=18243 us)'
STAT #20 id=2 cnt=0 pid=1 pos=1 obj=96551 op='TABLE ACCESS FULL FULLSCAN (cr=1143 pr=1139 pw=0 time=18200 us)'
WAIT #0: nam='SQL*Net message to client' ela= 8 driver id=1650815232 #bytes=1 p3=0 obj#=96551 tim=1344883886257193
WAIT #0: nam='SQL*Net message from client' ela= 455225 driver id=1650815232 #bytes=1 p3=0 obj#=96551 tim=1344883886712468
WAIT #0: nam='SQL*Net message to client' ela= 0 driver id=1650815232 #bytes=1 p3=0 obj#=96551 tim=1344883886712594

 

 

PARSING IN CURSOR #20 len=44 dep=0 uid=0 oct=3 lid=0 tim=1344883874047619 hv=2241892608 ad=’a7902a08′
select count(*) from fullscan where owner=:v
END OF STMT
PARSE #20:c=2000,e=1087,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=1344883874047610

 

PARSING IN CURSOR #20 ,这里的#20是游标号, 这个游标号非常重要, 后面的 FETCH 、WAIT、EXECUTE、PARSE 都通过这个游标号和前面的SQL联系起来。  

 

注意可以看到 在执行PARSING IN CURSOR #20 后 ,PARSE #20之后没有紧跟着 #20游标的运行 ,而是跟了 #25、#26游标的运行情况, 仔细看一下 #25和#26他们是 系统递归的recursive SQL  ,这些递归SQL由 用户的SQL触发,一般来说是查一些数据字典基表例如 obj$、tab$等,常规情况下 递归SQL运行消耗的资源和时间都非常少。

LEN=44  指SQL的长度

OCT=3    Oracle command type 指Oracle中命令分类的类型  可以通过 V$SQL.COMMAND_TYPE获得对应关系

11g中提供了 V$SQLCOMMAND 视图可以看到完整的对照列表, http://www.askmaclean.com/archives/vsqlcommand-sql-opcodes-and-names.html

 

LID=0 权限用户ID  Privilege user id.

 

TIM   timestamp 一个时间戳, 在9i之前 这个指标的单位是 1/100 s 即 10ms 。 到9i以后单位为 1/1000000  的microsecond 。 这个时间戳可以用来判断 trace中2个点的时间差。  这个 TIm的值来自于V$TIMER视图,这个视图是Oracle内部计时用的。

 

DEP=0  代表该SQL的递归深入(recursive depth),因为递归SQL可能再引发下一层的递归SQL, 如果DEP=0则说明不是递归SQL,如果DEP>0则说明是递归SQL。

 

 UID=0  UID即USERID 用以标明是谁在解析这个游标, 如果是0则说明是SYS 用户, 具体 用户名和UID对应可以通过如下查询获得:

select user#,name from user$;

 

OG=1  OG 代表optimizer_mode ,具体对应关系见下表

  • 0  游标不可见 或 优化器环境未合理创建
  • 1 –  ALL_ROWS
  • 2  – FIRST_ROWS
  • 3   – RULE
  • 4   – CHOOSE

 

 

mis=0   该指标说明library cache未发生miss,则本次解析 我们没有需要硬解析 而是采用软解析或者更好的方式。 硬解析在Oracle中成本是很高的。 注意由于在任何阶段包括PARSE/EXECUTE/FETCH阶段都可能发生游标被age out的现象,所以在这些阶段都会打印mis指标。如果mis>0则说明可能发生了硬解析。

 

HV     代表这个SQL 的hash value , 10g之前没有SQL_ID 时 主要靠HASH VALUE 来定位一个SQL

AD      代表SQLTEXT 的地址 来源于 V$SQLAREA.ADDRESS

err     代表 Oracle错误代码 例如ORA-1555

 

PARSE    是SQL运行的第一个阶段,解析SQL

EXEC       是SQL运行的第二个阶段,运行已经解析过的语句

FETCH   从游标中  fetch数据行

UNMAP   是当游标使用临时表时,若游标关闭则使用UNMAP释放临时表相关的资源,包括释放锁和释放临时段

 

C     比较重要的指标,代表本步操作消耗的CPU 时间片; 9i以后单位为microsecond

E      Elapsed Time ,代表本步操作消耗的自然时间,  9i以后单位为microsecond

 

 

这里存在一个问题例如 在我们的例子中PARSE #20:c=2000,e=1087   CPU_TIME> Elapsed time  ;

理论上 应当是  Elapsed Time = CPU TIME + WAIT TIME (等待事件的时间), 但是由于CPU TIME 和Elapsed time使用了不同 的clock时钟计时,所以在 2者都很短,或者 是CPU敏感的操作时 有可能 CPU TIME> Elapsed time。

相关的BUG 有:

  • Bug 4161114 : IN V$SQL, CPU_TIME > ELAPSED_TIME
  • Bug 7603849 : CPU_TIME > ELAPSED_TIME FOR CERTAIN SQL’S IN V$SQL
  • Bug 7580277 : ELAPSED_TIME SHOWING 0 FOR CERTAIN SQL’S IN V$SQL
  • Bug 8243074 : INCORRECT ELAPSED_TIME IN V$SQL

该问题可能 在12c中得到修复

 

 p   物理读的数目

CR  CR一致性读引起的buffer get  数目

CU  当前读current read 引起的buffer get 数目

r     处理的行数

 

CLOSE #[CURSOR]:c=%u e=%u dep=%d type=%u tim=%u   ==》一个游标关闭的例子

 CLOSE   游标关闭

type    关闭游标的操作类型

  • 0    该游标从未被缓存且执行次数小于3次,也叫hard close
  • 1      该游标从未被缓存但执行次数至少3次,若在session cached cursor中有free slot 则将该游标放入session cached cursor
  • 2     该游标从未被缓存但执行次数至少3次,该游标置入session cached cursor的条件是讲老的缓存age out掉
  • 3      该游标已经在缓存里,则还会去

 

 

STAT #[CURSOR] id=N cnt=0 [pid=0 pos=0 obj=0 op=’SORT AGGREGATE ‘]  

 

  • STAT   相关行反应解释执行计划的统计信息
  • [CURSOR]     游标号
  • id    执行计划的行数 从1开始
  • cnt    该数据源的行数
  • pid    该数据源的 父ID
  • pos    在执行计划中的位置
  • obj     对应数据源的  object id
  • op=    数据源的访问操作,例如 FULL SCAN

11g 以上还提供如下信息:

 

STAT #2 id=1 cnt=26 pid=0 pos=1 obj=0 op=’HASH GROUP BY (cr=1143 pr=1139 pw=0 time=61372 us)’
STAT #2 id=2 cnt=77276 pid=1 pos=1 obj=96551 op=’TABLE ACCESS FULL FULLSCAN (cr=1143 pr=1139 pw=0 time=927821 us)’

 

  • CR 代表一致性读的数量
  • PR  代表物理读的数量
  • pw  代表物理写的数量
  • time   单位为microsecond,本步骤的耗时
  • cost    本操作的优化器成本
  • size    评估的数据源大小,单位为字节
  • card       评估的优化器基数Cardinality.

 

 XCTEND rlbk=0, rd_only=1

  •  XCTEND  一个事务结束的标志
  • rlbk           如果是1代表 有回滚操作, 如果是0 代表不会滚 即 commit提交了
  • rd_only     如果是1代表 事务只读 , 如果是0 说明数据改变发生过

 

 

绑定变量  

BINDS #20:
kkscoacd
Bind#0
oacdty=96 mxl=2000(150) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1000000 frm=01 csi=873 siz=2000 off=0
kxsbbbfp=7f9ccfec6420 bln=2000 avl=50 flg=05
value=”MACLEAN

  • BINDS #20:  说明 绑定变量 是针对 20号游标的
  • kkscoacd  是绑定变量相关的描述符
  • Bind#0   说明是第0个变量
  • oacdty      data type   96 是 ANSI fixed char
  • oacflg      代表绑定选项的特殊标志位
  • size           为该内存chunk分配的内存大小
  • mxl       绑定变量的最大长度
  • pre      precision
  • scl      Scale
  • kxsbbbfp         buffer point
  • bln               bind buffer length
  • avl     实际的值的长度
  • flg          代表绑定状态
  • value=”MACLEAN    实际的绑定值

 

如果看到 “bind 6: (No oacdef for this bind)”类似的信息则说明在trace时 还没有定义绑定数据。 这可能是在trace时游标还没绑定变量。

 

WAIT #20: nam=’db file scattered read’ ela= 42 file#=1 block#=80386 blocks=7 obj#=96551 tim=1344883874069383

 

  • WAIT #20 等待 20号游标的相关等待事件
  • Nam      等待针对的事件名字,它的P1、P2、P3可以参考视图V$EVENT_NAME,也可以从V$SESSION、ASH中观察到等待事件
  • ela           本操作的耗时,单位为microsecond
  • p1,p2,p3       针对该事件的三个描述参数,见V$EVENT_NAME

 

在上例中针对 db file scattered read , P1为文件号, P2为 起始块号, p3为 读的块数,  即db file scattered read 是从 1号文件的第80386 个块开始一次读取了7个块。

注意在10046中 出现的WAIT 行信息 都是 已经结束的等待事件, 而当前等待则不会在trace中出现,直到这个当前等待结束。 你可以通过systemstate dump/errorstack等trace来获得当前等待信息。

 

 

 

 

你有多了解Oracle Enqueue lock队列锁机制?

你有多了解Oracle Enqueue lock队列锁机制?

 

概念

 

Enqueue 队列锁 是 oracle中 主要的 并发访问控制 和锁的机制。   我们耳熟能详的 TM table lock表锁 和 TX 事务锁都是 enqueue 。 enqueue 最多可以有6个模式 , enqueue lock被设计出来用于那些需要较长时间锁机制的场景。

enqueue 的 6个 锁模式分别为: X 、 SSX、 S、SX、SS、NULL。

以下是当一个进程以某种模式持有某个enqueue , 而另一个进程尝试以某种模式request 这个enqueue的兼容矩阵:

 

请求模式
持有模式 NULL SS SX S SSX X
NULL 成功 成功 成功 成功 成功 成功
SS 成功 成功 成功 成功 成功 失败
SX 成功 成功 成功 失败 失败 失败
S 成功 成功 失败 成功 失败 失败
SSX 成功 成功 失败 失败 失败 失败
X 成功 失败 失败 失败 失败 失败

 

 

再次比较 Enqueue 和Latch

 

latch是为了串行访问机制, 而enqueue 更多是为了并发访问控制

从设计出发 enqueue 可以被持有较长的一段时间 ; latch应当在极短的时间内(us级别)持有和释放,否则 latch将成为严重的性能瓶颈,乃至HANG

  • enqueue 的request 和release 要比latch 使用更多的CPU
  • enqueue 要比latch在结构上复杂地多
  • enqueue 有6种模式
  • enqueue 可能是LOCAL的 可能是cluster-wide global的
  • latch只对应一个process state object; 而enqueue 对应一个session state object和一个process state object

 

每一个 Enqueue Resource 都以2个 字母代表 例如  TX和TM ,并带有4个数字 例如 TM-00017927-00000000-00000000-00000000 称作 resource id 的4个部分,一般我们只用到前2个ID 。

在内部一个Enqueue Resource  对应一个  KSQRS  结构, 该KSQRS  结构  拥有三个列表:

  • owner list
  • waiter list
  • converter list

 

简单描绘一个enqueue resource的结构:

<TM resource>  [owner list的头部]     [waiter list的头部]     [converter list的头部]   [resource ID : ID1 ID2 ID3 ID4] [enqueue type]
                     |                     |                            |
                     S                     X                           S->X
                     |                     |
                     S                    SX 
                     |
                     S

Oracle Database 13c展望

Oracle Database 13c展望, 13能发展点啥 现在说为时尚早, 但显然如果当前热议的话题 cloud云计算 和大数据 不变的话,那么显然 Oracle Database还要往这2个方向发展, 或许在13中可能把Exadata 的Smart Scan 、Storage Index等特性释出, Exadata可能发展出更多 强壮的特性。 :lol:

全面解析9i以后Oracle Latch闩锁原理

Latch闩锁在Oracle中属于 KSL Kernel Services Latching, 而从顶层视图来说 KSL又属于VOS  Virtual Operating System。

 maclean-latch

 

 

Latches 是一种 低级别(low-level)的 锁机制, 初学IT的同学请注意 低级不代表简单, C语言对比java语言要 低级一些但C并不比java简单。

 

在一些文章著作中也将latch称为spin lock 自旋锁。  latch用来保护 共享内存(SGA)中的数据 以及关键的代码区域。   一般我们说有2种latch:

 

1)Test and Set 简称TAS  :

TAS是计算机科学中的专指, test-and-set instruction  指令 用以在一个 原子操作(atomic 例如非中断操作)中写入到一个内存位置 ,并返回其旧的值。 常见的是 值1被写入到该内存位置。 如果多个进程访问同一内存位置, 若有一个进程先开始了test-and-set操作,则其他进程直到第一个进程结束TAS才可以开始另一个TAS。 

关于TAS指令更多信息 可以参考wiki ,包括TAS的伪代码例子:    http://t.cn/zQgATRr        

askmaclean.com

在Oracle中Test-And-Set类型的latch使用原生的Test-And-Set指令。 在绝大多数平台上, 零值zero代表latch是 空闲或者可用的 , 而一个非零值代表 latch 正忙或者被持有。  但是仅在HP PA-RISC上 正相反。  TAS latch只有2种状态 : 空闲 或者 忙。

 

2) Compare-And-Swap 简称 CAS

Compare-And-Swap 也是计算机专有名词, Compare-And-Swap(CAS)是一个用在多线程环境中实现同步的 原子指令( atomic )。 该指令将在一个给定值(given value)和 指定内存位置的内容 之间比对,仅在一致的情况下 修改该内存位置的内容为一个 给定的 新值(不是前面那个值)。  这些行为都包含在一个 单独的原子操作中。 原子性保证了该新的值是基于最新的信息计算获得的; 如果该 内存位置的内容在同时被其他线程修改过,则本次写入失败。 该操作的结果必须说明其到底是否执行了 取代动作。 它要么返回一个 布尔类型的反馈, 要么返回从 指定内存地址读取到的值(而不是要写入的值)。

关于CAS的更多信息可以参考 http://t.cn/hcEqh

Oracle中的 Compare-And-Swap Latch也使用原生态的Compare-And-Swap指令。  和TAS Latch类似, 空值代表latch是free的,而一个非空值代表latch正忙。  但是一个CAS latch 可以有多种状态 : 空闲的、 以共享模式被持有 、 以排他模式被持有。 CAS latch可以在同一时间被 多个进程或线程以共享模式持有, 但还是仅有一个进程能以排他模式持有CAS latch。   典型的情况下, 共享持有CAS latch的进程以只读模式访问相关数据, 而一个排他的持有者 目的显然是要写入/修改 对应CAS latch保护的数据。

举例来说, CAS latch的共享持有者是为了扫描一个链表 linked list , 而相反排他的持有者是为了修改这个列表。 共享持有者的总数上线是0x0fffffff即10进制的 268435455。

 

注意几乎所有平台均支持CAS latch, 仅仅只有HP的PA-RISC平台不支持(惠普真奇葩)。 在PA-RISC上CAS latch实际是采用TAS latch。 所以虽然在HP  PA-RISC上代码仍会尝试以共享模式获得一个latch,但是抱歉最终会以 排他模式获得这个latch。

 

 

 

一般 一个latch会包含以下 信息:

  • Latch type 类型 , latch type定义了 是TAS 还是CAS latch, latch  class和 latch number
  • Latch的 level 级别
  • 持有该latch的代码位置where ,例如 使用kslgetl函数获得某个latch,则持有文职为kslgetl
  • 持有该latch的原因
  • nowait模式下获得该latch的次数  V$LATCH.IMMEDIATE_GETS
  • wait模式下第一个尝试失败的次数 V$LATCH .MISSES
  • nowait模式下尝试失败的次数 V$LATCH.IMMEDIATE_MISSES
  • 获取latch失败造成sleep的总时间 X$KSLLTR.KSLLTWSL, V$LATCH.SLEEPS
  • 首次spin成功获得latch的次数 X$KSLLTR.KSLLTHST0, V$LATCH.SPIN_GETS
  • latch wait list等等

 

子闩 child latch

 

当一个单一的latch要保护过多的资源时 会造成许多争用,  在此种场景中 child latch变得很有用。   为了使用child latch,  需要分割原latch保护的资源为多个分区, 最常见的例子是 放入到多个hash buckets里, 并将不同子集的资源分配给一个child latch。 比起每一个hash bucket都去实现一个单独的latch来说, 编程上 使用child latch要方便的多, 虽然这不是我们用户所需要考虑的。  为一个latch 定义多个child latch,则这个latch称为parent latch父闩。  child latch 可以继承 parent latch的一些属性,  这些属性包括 级别和清理程序。  换句话说, child latch就像是parent 父闩的拷贝一样。

经典情况下, 在SGA 初始化过程中child latch将被分配和初始化(startup nomount)。但在目前版本中(10/11g)中也允许在实例启动后 创建和删除latch。

 

child latch又可以分成2种:

  • 允许一个进程/线程在同一时刻持有2个兄弟child latch
  • 不允许一个进程/线程在同一时刻持有2个兄弟child latch

 

因为child latch从parent latch那里继承了属性,所以注意 child latch的 latch level和 parent 父闩是一样的。 因为 一个进程/线程 不能在同一时间  持有2个latch level一样的闩,所以正常情况下 一个进程/线程 也不能同一时间 持有2个兄弟child latch。

 

回到我们说的hash bucket的例子里来, 假设一个进程/线程有 将一个resource从一个hash bucket 移动到另一个hash bucket的需求,在此场景中就需要 同时持有2个兄弟child latch。  但是如果允许这种同时持有2个兄弟child latch的行为发生的话, 那么很容易造成死锁deadlock的麻烦。 oracle 不允许 进程/线程任意地同时获得2个兄弟child latch,由于此种操作很容易引起死锁。  由此引入了一些规则 :  兄弟child latch必须是相关的child number ,且进程/线程只能以特性的顺序来同时get 2个兄弟child latch,即child number 从大到小低贱的顺序。

 

此外需要注意的是仅有TAS latch可以同时get多个兄弟child latch,目前还不支持 CAS的latch。

 

Latch 清理恢复

 

Oracle中定义了一个latch, 就需要这个latch对应的清理函数cleanup function,这个函数在以下2个场景中生效:

  1. 当某个latch被持有,但是持有进程遇到了某一个错误                                      ==》主动
  2. 当持有latch的进程die掉,需要PMON进程前去恢复这个latch的状态        ==》被动

 

经典情况下, 执行清理函数的进程要么把正在执行过程中的操作回滚掉 ,要么前滚掉。 为了为 前滚(rolling forward)或者回滚(rolling back)提供必要的信息, oracle在latch结构中加入了recovery的结构,其中包含了这个正在执行过程中的操作的日志信息, 这些日志信息必须包含足以前滚或者回滚的数据。  如我们以前讲过的, 理论上oracle进程可能在运行任何指令的时候意外终止,所以清理恢复是常事。

 

清理恢复最恶心的bug是PMON 执行cleanup function时因为 代码bug ,把PMON自己给弄dead了, 由于PMON的关键的后台进程,所以这会引起实例终止。

 

 

 

Latch和 10.2.0.2后引入的KGX Mutex对比

 

和 latch一样, kgx mutex也是用来控制串行化访问SGA中数据的 ,但仍有一些重要区别:

  1. KGX mutex要比  CAS latch更轻量级, mutex 结构大约为16个字节, 而一个latch结构大约是100个字节。 因此 mutex嵌入到大量其他对象结构中是可行的, 因为他的struct 足够小
  2. 之所以mutex可以提供 更小的结构 很廉价的成本,其原因是 使用mutex有一个简单的前提假设: 对于mutex的争用是很小的。 因此没有为mutex那样提供一个优化过的wait  list , mutex做更多的 SPIN & WAIT 并消耗更多的CPU。   此外mutex也没有提供任何死锁检测和预防机制,这些都完全取决于Kgx mutex的用户自身的行为。
  3. Latch在 内部视图(例如X$KSLLT)中提供 全面的诊断信息。 KGX mutex在(x$mutex_sleep、x$mutex_sleep_history等内部视图)中提供部分信息, 同时也允许其用户在回调程序中用特定信息填充这些视图。
  4. 除了共享和排他模式之外, KGX mutex还提供一种examine 模式, 允许其在不以共享或排他模式持有mutex的情况下client检查一个mutex的状态以及其用户数据。 这种模式是latch所没有的

 

Latch 和Enqueue lock队列锁对比,以下是latch和enqueue的几个重大区别:

 

  1. 在典型情况下,latch被认为将仅仅被持有很短的一段时间(ms级别),而enqueue 将被持有 比之长得多的多的时间(秒=》分钟=》小时)。 例如TX 队列事务锁在整个事务的生命周期中被持有 。 latch被设计出来就是为了在 函数运行到某几十个乃至上百个指令过程中被持有,这是很短暂的过程
  2. latch是为了避免同一时间 有一个以上的进程运行相似的代码片段, 而enqueue是为了避免同一时间多于一个的进程访问相同的资源
  3. latch的使用较为简单, 而enqueue的使用则由于命名空间namespace和死锁检测 的问题而较为麻烦
  4. latch只有2个模式 共享和排他,  而enqueue 则支持6个模式
  5. RAC中 latch 总是本地存放在当前实例的SGA中, 而enqueue可以是Local的 也可能是Global的
  6.  9i以前latch不是FIFO的,是抢占式的; 从9i开始 大多数latch也是FIFO了; enqueue始终是FIFO的

 

有同学仍不理解 latch和enqueue的区别的话, 可以这样想一下, latch 保护的SGA中的数据 对用户来说几乎都是不可见的, 例如 cache buffer的hash bucket 对不研究内部原理的用户来说 等于不存在这个玩样,这些东西都是比较简单的数据结构struct ,如果你是开发oracle的人 你会用几百个字节的enqueue 来保护 几个字节的一个变量吗?

而队列锁 TX是针对事务的 , TM是针对 表的,US是针对 undo segment的,这些东西在实例里已经属于比较高级的对象了,也是用户常可见的对象, 维护这些对象 需要考虑 死锁检测、 并发多模式访问、RAC全局锁 等等问题,所以需要用更复杂的enqueue lock。

 

 死锁dead lock

 

为了使得latch使用足够轻量级 ,死锁预防机制十分简单。  由此Oracle开发人员 在构建一个latch时会定义 一个数字级别 level (从 0 到 16 ), 并且Oracle要求它们必须以level增序顺序获取。  若一个进程/线程在持有一个 latch的情况下,要求一个相同或者更低level的latch的话,KSL层会生成一个内部错误, 这种问题称为 “latch hierarchy violation”。

 

 

SQL> select distinct level# from v$latch order by 1;

    LEVEL#
----------
         0
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        14
        15
        16

 

仅有以nowait模式get latch时可以以级别(level) 非兼容的级别获得一个latch,但是这种情况非常少。

 

Latch Level 级别

 

Oracle在定义latch level的时候 取决于以下2个原则:

  • 那些latch是在被持有的情况下, 进程/线程还会去get其他的latch?
  • 当已经有latch被进程/线程持有的情况下, 那些latch还会被 get?

如上文dead lock的描述, latch level的一大作用是 帮助减少latch dead lock。

 

Latch Class

latch的类class定义了如下的内容:

  • spin count
  • yield count (number of times we yield cpu before sleeping)
  • wait time sample rate (0 implies it is not enabled)
  • sleep (in microseconds and repeated [see below])

 

对于post/wait 类而言 SLEEP_BUCKET和SLEEP_TIME 是被忽略的。

以下是几个latch class:

Class 0  Post/Wait Class ,绝大多数latch都是该类型

Class 1  Waiter List Latch。 该Latch保护对应latch的Waiter List,这种latch被假定总是只被持有非常短的时间(指令级别),  有充分的理由花费更多的spin count 消耗更多的CPU , 并尽可能减少sleep时间

Class 2   那些由于多种原因,不能使用post/wait机制的latch 。 例如process allocation latch  这个闩 是在一个新进程创建时所需要获取的,但是新进程还没加载post/wait的上下文,显然无法用post/wait , 所以这种 latch不能用post /wait机制

Class  3 非常短持有的latch, 特性与class 1类似。

CLASS_KSLLT字段代表了latch的类型

 

SQL> select CLASS_KSLLT,count(*) from x$kslltr group by CLASS_KSLLT;

CLASS_KSLLT   COUNT(*)
----------- ----------
          2          1
          0        702

SQL> select KSLLTNAM,CLASS_KSLLT from x$kslltr where CLASS_KSLLT=2;

KSLLTNAM                                                         CLASS_KSLLT
---------------------------------------------------------------- -----------
process allocation                                                         2

 

 

从9.0.2 开始 每个latch class的SPIN COUNT、YIELD COUNT 、WAITTIME_SAMPLING 、 SLEEP_TIME[1] ….   SLEEP_TIME[i] 均在参数_latch_class_X中定义 。

 

 

SQL> col name for a20
SQL> col avalue for a20
SQL> col sdesc for a20

SELECT x.ksppinm NAME,y.ksppstvl avalue,x.KSPPDESC sdesc
 FROM SYS.x$ksppi x, SYS.x$ksppcv y
 WHERE x.inst_id = USERENV ('Instance')
 AND y.inst_id = USERENV ('Instance')
 AND x.indx = y.indx
AND x.ksppinm like '%latch%class%';

NAME                 AVALUE               SDESC
-------------------- -------------------- --------------------
_latch_class_0                            latch class 0
_latch_class_1                            latch class 1
_latch_class_2                            latch class 2
_latch_class_3                            latch class 3
_latch_class_4                            latch class 4
_latch_class_5                            latch class 5
_latch_class_6                            latch class 6
_latch_class_7                            latch class 7
_latch_classes                            latch classes override

SQL> select INDX,SPIN,YIELD,WAITTIME,SLEEP0 from X$KSLLCLASS;

      INDX       SPIN      YIELD   WAITTIME     SLEEP0
---------- ---------- ---------- ---------- ----------
         0      20000          0          1       8000
         1      20000          0          1       1000
         2      20000          0          1       8000
         3      20000          0          1       1000
         4      20000          0          1       8000
         5      20000          0          1       8000
         6      20000          0          1       8000
         7      20000          0          1       8000

8 rows selected.

 

 

举例来说  _latch_class_1=”5000 2 0 1000 2000 4000 8000″    则

  • SPIN_COUNT=5000
  • YIELD_COUNT=2
  • wait time sampling: 0 (不收集,一般都是1即收集)
  • 增序的sleep time   1000  => 2000 => 4000 => 8000, 单位是microseconds,超过4次则保持在8000

 

每一个wait class 适应自己对应_latch_class_X中的SPIN_COUNT、YIELD_COUNT等参数 。 而实例参数_SPIN_COUNT只做为向后兼容,若对应的latch Class没有自己的SPIN_COUNT属性才会生效。

由此实际生效的SPIN_COUNT由由以下几个参数 按优先级从高到低生效:

  • 首先是 设置过的_latch_class_X  中的SPIN_COUNT
  • 设置够的_SPIN_COUNT
  • 内部函数

 

注意 除非是oracle support建议你去修改这些latch参数,否则在任何系统中都不该去尝试修改它们,如果你确实遇到了latch free的问题,那么你应当首先做 SQL 调优 和并发调整。

 

 

SPIN 

inception-top

 

 

还记得 电影《inception》盗梦空间里中旋转的陀螺吗, 旋转的陀螺 在英文里就是spinning top。 spin 自旋是 latch话题中一个频率很高的词,但是一直以来我们对自旋的理解都不够彻底 ,下面我们彻底解释 9i以后的自旋SPIN 和 Busy Latch原理。

SPIN 是指 当进程首先尝试获取latch失败后( 一般是别人持有了该latch), 有2种选择 要么是退让CPU(yield CPU) 休眠一段时间后再重新尝试获取latch , 要么是 本进程抱着希望在CPU 上空转,因为如果我不用CPU了 让给别人用了 就会造成context switch上下文切换 (vmstat 里看到的CS),而我在CPU上空转的话就可以等等看这个latch是否会在这段时间里被人家释放, 我的一次空转称为SPIN 一次, 而SPIN_COUNT定义了我在这次总的SPIN 操作里总共SPIN 空转多少次,例如SPIN_COUNT=2000(注意 见上文中对SPIN_COUNT的描述)就是说 我有机会空转 2000次, 空转一次后 我跑去查看一下latch是否被别人释放了,如果没有我继续下一次空转, 如果是释放了 那么我就获得这个latch了,也就是SPIN_GETS成功了。如果SPIN 2000次了还是没有等到释放latch,则SPIN_GETS没有成功, 之后该SLEEP就SLEEP( 9i前后 从9i开始有区别,具体见下文)。

 

如果上述SPIN GET的成功获得了latch,那么因为我没有退让CPU 也就没有上下文切换, 所以显然我获得latch的速度要比直接sleep并重试来的快。

 

另假设我提高了某个latch对应的 spin_count ,例如修改latch_class_1中的SPIN_COUNT为更高的值,则在上述情况下可能SPIN循环的次数更多,也就意味着有更高的概率在 SPIN阶段获得 latch, 而代价是SPIN消耗更高的 CPU时间片。 相反 若降低SPIN_COUNT,则意味着SPIN阶段获得latch的概率降低, SPIN消耗相对少的CPU。

 

在中古的硬件中 可能有仅有1个CPU的系统,虽然现在很少见了, 但是显然在仅有一个CPU的情况下SPIN是无意义的,因为如果你把唯一的一个CPU用来SPIN了,显然 真正持有对应latch的那个进程获取不到CPU,获取不到CPU的结果是它无法释放这个latch。在这种环境里代码自动把spin_count调整为1。

 

 

SPIN 与Latch Busy

 

9i之前的 spin与latch busy 运作伪代码可以点击这里(main for 8i)。

 

从9.0.2开始oracle 开始大量启用 post/wait和latch class机制 , 我们来描述一下 伪代码

 

SLEEPs                  //睡眠次数计数
yields                  //yield 计数  copyright askmaclean.com
on_wait_list = FALSE;

while (如果未获得latch)
{
  在对应的latch上SPIN ,循环次数为SPIN_COUNT,SPIN_COUNT 来源一般为 _latch_class_X
    if (获得latch)
	   break; 

  if(yields < YIELD_COUNT)                     // YIELD_COUNT来源为latch_class_X 
  {
    yields++;
	yield CPU ;                               
  }

   else

   {
     yield =0;

	 if (如果latch是post/wait机制的)
	  {
	    on_wait_list=TRUE ; 
		get wait list latch ;                  //获得wait list latch
		add current process to wait list;      //将被进程加入到wait list的尾部
        free wait list latch;                  //释放wait list latch
        wait to be posted;                     //等待被post
	  }
	 else 
	  {
	   wait for SLEEP_TIMES[sleeps] microseconds;   //等待SLEEP_TIME[sleeps]对应的时间 来源为latch_class_X 
	   if ( sleeps	 < SLEEP_BUCKETS)               //SLEEP_BUCKETS 一般为4
	   sleeps++;
	 }
 }
 }

//如果某一刻获得了一个post/wait latch,且本进程在wait list上,则需要从wait list 上把自己移走:

if( 如果我在wait list上)
{
get wait list latch ;                       //获得wait list latch
remove current process from wait list;      //从wait list 上把自己移走
free wait list latch;                       //释放wait list latch
}

 

 

从9i开始绝大多数 latch都是 post/wait class的, 出去少量非post/wait class的latch和PMON进程外, 进程都会进入非时控的sleep (sleep[1]..[sleep[i] i到4以后不再增加) 不会自己醒来, 仅在该latch的持有者 释放该latch 且  等待的进程在wait list的头部的情况下被post唤醒 (awake)。 Oracle 选择这种非时控的sleep的原因 为了避免在miss后引起反复的 上下文交换context switch 以便改善性能。

但是这种实现也存在一种风险, 即需要应对那些 持有latch进程意外终止 和 存在丢失 post的bug的情况。

【Oracle Database 12c】RMAN新特性

在12c中提出了不少RMAN备份恢复的新特性,这里我们先草草地过一下这些新特性。

sysbackup 管理角色覆盖了 备份backup和recovery恢复所需要的权限, 还包括连接到已关闭的 数据库。  系统管理员可以将sysbackup而非sysdba赋予给那些只操作备份和恢复的用户,由此减少了SYSDBA这个超级用户权限过重的问题。  与SYSDBA相反,SYSBACKUP不包含访问所有表的SELECT ANY TABLE权限。

 

 

使用SYSBACKUP登陆RMAN 
C:\Users\xiangbli>rman target "'/ as sysbackup'"

恢复管理器: Release 12.1.0.1.0 - Production on 星期一 8月 19 07:55:45 2013

Copyright (c) 1982, 2013, Oracle and/or its affiliates.  All rights reserved.

已连接到目标数据库: MACLEAN (DBID=1694338843)

现在RMAN增强了SQL接口可以通过RMAN做一些查询了。

RMAN> select user from dual;

使用目标数据库控制文件替代恢复目录
USER
------------------------------
SYSBACKUP

 

 

 

尝试在非归档模式下 热备份hot backup

 

 

 

RMAN> SELECT NAME, DBID, LOG_MODE FROM V$DATABASE;

NAME            DBID LOG_MODE
--------- ---------- ------------
MACLEAN   1694338843 NOARCHIVELOG

RMAN> backup database;

启动 backup 于 19-8月 -13
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: SID=365 设备类型=DISK
通道 ORA_DISK_1: 正在启动全部数据文件备份集
通道 ORA_DISK_1: 正在指定备份集内的数据文件
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03009: backup 命令 (ORA_DISK_1 通道上, 在 08/19/2013 08:06:10 上) 失败
ORA-19602: 无法按 NOARCHIVELOG 模式备份或复制活动文件

非归档模式是不能 在线 热备份的! 这一点没有变

 oerr ORA 19602
19602, 00000, "cannot backup or copy active file in NOARCHIVELOG mode"
// *Cause:  You tried to copy or backup a file that was not closed cleanly,
// and the database was in NOARCHIVELOG mode.  This is not allowed
// because when restored, the file will require redo application
// before it is usable, and redo is not currently being saved
// beyond the contents of the online redo logs.
// *Action: Take the tablespace offline clean or close the database and retry
// the copy or backup.
$

 

 

 

 

将数据库修改为归档模式后 再次备份

 

 

RMAN> shutdown immediate;

数据库已关闭
数据库已卸装
Oracle 实例已关闭

RMAN> startup mount;

已连接到目标数据库 (未启动)
Oracle 实例已启动
数据库已装载

系统全局区域总计    1737031680 字节

Fixed Size                     2403544 字节
Variable Size                536871720 字节
Database Buffers            1191182336 字节
Redo Buffers                   6574080 字节

RMAN> alter database archivelog;

已处理语句

RMAN> alter database open;

已处理语句

RMAN> show all;

db_unique_name 为 MACLEAN 的数据库的 RMAN 配置参数为:
CONFIGURE RETENTION POLICY TO REDUNDANCY 1; # default
CONFIGURE BACKUP OPTIMIZATION OFF; # default
CONFIGURE DEFAULT DEVICE TYPE TO DISK; # default
CONFIGURE CONTROLFILE AUTOBACKUP ON;
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '%F'; # default
CONFIGURE DEVICE TYPE DISK PARALLELISM 1 BACKUP TYPE TO BACKUPSET; # default
CONFIGURE DATAFILE BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE ARCHIVELOG BACKUP COPIES FOR DEVICE TYPE DISK TO 1; # default
CONFIGURE MAXSETSIZE TO UNLIMITED; # default
CONFIGURE ENCRYPTION FOR DATABASE OFF; # default
CONFIGURE ENCRYPTION ALGORITHM 'AES128'; # default
CONFIGURE COMPRESSION ALGORITHM 'BASIC' AS OF RELEASE 'DEFAULT' OPTIMIZE FOR LOAD TRUE ; # default
CONFIGURE RMAN OUTPUT TO KEEP FOR 7 DAYS; # default
CONFIGURE ARCHIVELOG DELETION POLICY TO NONE; # default
CONFIGURE SNAPSHOT CONTROLFILE NAME TO 'C:\APP\XIANGBLI\PRODUCT\12.1.0\DBHOME_2\DATABASE\SNCFMACLEAN.ORA'; # default

RMAN> backup database;

启动 backup 于 19-8月 -13
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: SID=373 设备类型=DISK
通道 ORA_DISK_1: 正在启动全部数据文件备份集
通道 ORA_DISK_1: 正在指定备份集内的数据文件
输入数据文件: 文件号=00006 名称=C:\APP\XIANGBLI\ORADATA\MACLEAN\USERS01.DBF
输入数据文件: 文件号=00003 名称=C:\APP\XIANGBLI\ORADATA\MACLEAN\SYSAUX01.DBF
输入数据文件: 文件号=00001 名称=C:\APP\XIANGBLI\ORADATA\MACLEAN\SYSTEM01.DBF
输入数据文件: 文件号=00005 名称=C:\APP\XIANGBLI\ORADATA\MACLEAN\UNDOTBS01.DBF
输入数据文件: 文件号=00002 名称=C:\APP\XIANGBLI\ORADATA\MACLEAN\EXAMPLE01.DBF
输入数据文件: 文件号=00009 名称=C:\APP\XIANGBLI\ORADATA\MACLEAN\LOW_COST_STORE.DBF
输入数据文件: 文件号=00007 名称=C:\APP\XIANGBLI\ORADATA\MACLEAN\ILM_PART1.DBF
输入数据文件: 文件号=00008 名称=C:\APP\XIANGBLI\ORADATA\MACLEAN\ILM_PART2.DBF
输入数据文件: 文件号=00004 名称=C:\APP\XIANGBLI\ORADATA\MACLEAN\MACLEAN1.DBF
输入数据文件: 文件号=00010 名称=C:\APP\XIANGBLI\ORADATA\MACLEAN\SOURCE_TBS.DBF
通道 ORA_DISK_1: 正在启动段 1 于 19-8月 -13
通道 ORA_DISK_1: 已完成段 1 于 19-8月 -13
段句柄=C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\BACKUPSET\2013_08_19\O1_MF_NNNDF_TAG20130819T081144_912RP1LP_.BKP 标记=TAG20130819T081144 注释=NONE
通道 ORA_DISK_1: 备份集已完成, 经过时间:00:02:40
完成 backup 于 19-8月 -13

启动 Control File and SPFILE Autobackup 于 19-8月 -13
段 handle=C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\AUTOBACKUP\2013_08_19\O1_MF_S_823853664_912RV130_.BKP comment=NONE
完成 Control File and SPFILE Autobackup 于 19-8月 -13

 

 

 

 

以上备份结束后列出了 备份用时。

之后我们列出之前的备份情况,并删除 对于备份策略而言无用的备份:

 

 

 

 

 

RMAN> list backup;

备份集列表
===================

BS 关键字  类型 LV 大小       设备类型 经过时间 完成时间
------- ---- -- ---------- ----------- ------------ ----------
1       Full    9.61M      DISK        00:00:02     31-7月 -13
        BP 关键字: 1   状态: AVAILABLE  已压缩: NO  标记: TAG20130731T135056
段名:C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\BACKUPSET\2013_07_31\O1_MF_NCNNF_TAG20130731T135056_8ZK9G27G_.BKP
  包括的控制文件: Ckp SCN: 2891741      Ckp 时间: 31-7月 -13

BS 关键字  类型 LV 大小       设备类型 经过时间 完成时间
------- ---- -- ---------- ----------- ------------ ----------
2       Full    9.64M      DISK        00:00:01     31-7月 -13
        BP 关键字: 2   状态: AVAILABLE  已压缩: NO  标记: TAG20130731T135059
段名:C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\AUTOBACKUP\2013_07_31\O1_MF_S_822232259_8ZK9G48J_.BKP
  包含的 SPFILE: 修改时间: 31-7月 -13
  SPFILE db_unique_name: MACLEAN
  包括的控制文件: Ckp SCN: 2891749      Ckp 时间: 31-7月 -13

BS 关键字  类型 LV 大小       设备类型 经过时间 完成时间
------- ---- -- ---------- ----------- ------------ ----------
3       Full    2.15G      DISK        00:02:35     19-8月 -13
        BP 关键字: 3   状态: AVAILABLE  已压缩: NO  标记: TAG20130819T081144
段名:C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\BACKUPSET\2013_08_19\O1_MF_NNNDF_TAG20130819T081144_912RP1LP_.BKP
  备份集 3 中的数据文件列表
  文件 LV 类型 Ckp SCN    Ckp 时间   名称
  ---- -- ---- ---------- ---------- ----
  1       Full 4736749    19-8月 -13 C:\APP\XIANGBLI\ORADATA\MACLEAN\SYSTEM01.DBF
  2       Full 4736749    19-8月 -13 C:\APP\XIANGBLI\ORADATA\MACLEAN\EXAMPLE01.DBF
  3       Full 4736749    19-8月 -13 C:\APP\XIANGBLI\ORADATA\MACLEAN\SYSAUX01.DBF
  4       Full 4736749    19-8月 -13 C:\APP\XIANGBLI\ORADATA\MACLEAN\MACLEAN1.DBF
  5       Full 4736749    19-8月 -13 C:\APP\XIANGBLI\ORADATA\MACLEAN\UNDOTBS01.DBF
  6       Full 4736749    19-8月 -13 C:\APP\XIANGBLI\ORADATA\MACLEAN\USERS01.DBF
  7       Full 4736749    19-8月 -13 C:\APP\XIANGBLI\ORADATA\MACLEAN\ILM_PART1.DBF
  8       Full 4736749    19-8月 -13 C:\APP\XIANGBLI\ORADATA\MACLEAN\ILM_PART2.DBF
  9       Full 4736749    19-8月 -13 C:\APP\XIANGBLI\ORADATA\MACLEAN\LOW_COST_STORE.DBF
  10      Full 4736749    19-8月 -13 C:\APP\XIANGBLI\ORADATA\MACLEAN\SOURCE_TBS.DBF

BS 关键字  类型 LV 大小       设备类型 经过时间 完成时间
------- ---- -- ---------- ----------- ------------ ----------
4       Full    9.64M      DISK        00:00:01     19-8月 -13
        BP 关键字: 4   状态: AVAILABLE  已压缩: NO  标记: TAG20130819T081424
段名:C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\AUTOBACKUP\2013_08_19\O1_MF_S_823853664_912RV130_.BKP
  包含的 SPFILE: 修改时间: 19-8月 -13
  SPFILE db_unique_name: MACLEAN
  包括的控制文件: Ckp SCN: 4736816      Ckp 时间: 19-8月 -13

RMAN> delete obsolete;

RMAN 保留策略将应用于该命令
将 RMAN 保留策略设置为冗余 1
使用通道 ORA_DISK_1
删除以下已废弃的备份和副本:
类型                 关键字 完成时间           文件名/句柄
-------------------- ------ ------------------ --------------------
备份集               1      31-7月 -13
备份片段       1      31-7月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\BACKUPSET\2013_07_31\O1_MF_NCNNF_TAG20130731T135056_8ZK9G27G_.BKP
存档日志          1      15-8月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_15\O1_MF_1_68_90SB5GVH_.ARC
备份集               2      31-7月 -13
备份片段       2      31-7月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\AUTOBACKUP\2013_07_31\O1_MF_S_822232259_8ZK9G48J_.BKP
存档日志          2      16-8月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_16\O1_MF_1_69_90TYSCY3_.ARC
存档日志          3      16-8月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_16\O1_MF_1_70_90TYX340_.ARC
存档日志          4      17-8月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_17\O1_MF_1_71_90Y7D6DP_.ARC

是否确定要删除以上对象 (输入 YES 或 NO)? no

RMAN>

RMAN> delete noprompt obsolete;

RMAN 保留策略将应用于该命令
将 RMAN 保留策略设置为冗余 1
使用通道 ORA_DISK_1
删除以下已废弃的备份和副本:
类型                 关键字 完成时间           文件名/句柄
-------------------- ------ ------------------ --------------------
备份集               1      31-7月 -13
备份片段       1      31-7月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\BACKUPSET\2013_07_31\O1_MF_NCNNF_TAG20130731T135056_8ZK9G27G_.BKP
存档日志          1      15-8月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_15\O1_MF_1_68_90SB5GVH_.ARC
备份集               2      31-7月 -13
备份片段       2      31-7月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\AUTOBACKUP\2013_07_31\O1_MF_S_822232259_8ZK9G48J_.BKP
存档日志          2      16-8月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_16\O1_MF_1_69_90TYSCY3_.ARC
存档日志          3      16-8月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_16\O1_MF_1_70_90TYX340_.ARC
存档日志          4      17-8月 -13         C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_17\O1_MF_1_71_90Y7D6DP_.ARC
已删除备份片段
备份片段句柄=C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\BACKUPSET\2013_07_31\O1_MF_NCNNF_TAG20130731T135056_8ZK9G27G_.BKP RECID=1 STAMP=822232258
已删除的归档日志
归档日志文件名=C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_15\O1_MF_1_68_90SB5GVH_.ARC RECID=1 STAMP=823543727
已删除备份片段
备份片段句柄=C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\AUTOBACKUP\2013_07_31\O1_MF_S_822232259_8ZK9G48J_.BKP RECID=2 STAMP=822232260
已删除的归档日志
归档日志文件名=C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_16\O1_MF_1_69_90TYSCY3_.ARC RECID=2 STAMP=823597614
已删除的归档日志
归档日志文件名=C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_16\O1_MF_1_70_90TYX340_.ARC RECID=3 STAMP=823597732
已删除的归档日志
归档日志文件名=C:\APP\XIANGBLI\FAST_RECOVERY_AREA\MACLEAN\ARCHIVELOG\2013_08_17\O1_MF_1_71_90Y7D6DP_.ARC RECID=4 STAMP=823704734
6 对象已删除

沪公网安备 31010802001379号

TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569