test's People
test's Issues
test
“
INSERT /*+ BYPASS_RECURSIVE_CHECK */ INTO "DWHES_DM"."MV_FCT_SUBS_BUNDLE_DAY" select
t.subscription_id,
t.bundle_id,
t.bundle_start_date,
t.bundle_end_date,
t.permanence,
t.origin ,
t.sale_date ,
t.cancel_date ,
t.sfid ,
t.penalty ,
t.permanence_months ,
t.sequence_number ,
t.bundle_sequence_number
from (select
temp.subscription_id ,
temp.bundle_id ,
temp.bundle_start_date ,
temp.bundle_end_date ,
temp.permanence ,
temp.origin ,
temp.sale_date ,
temp.cancel_date ,
temp.sfid ,
temp.penalty ,
temp.permanence_months ,
tem
Thread 1 advanced to log sequence 64458 (LGWR switch)”
ORA-4031一次数据库参数调整
ORA-4031一次数据库参数调整
环境:suse linux sp11,oracle RAC 11.2.0.3
背景:客户表示BI数据库部分存储过程运行出现ora-4031问题,导致后续大面积存储过程延后作业
原因分析:
ORA-04031: unable to allocate 4128 bytes of shared memory ("shared pool","T_E_PD_MAINPRODUCT
在执行存储过程中出现shared pool无法扩展情况,该问题在11gR2之前,由于部分bug影响,是比较普遍的问题。而问题环境已经是11gR2版本,故先不考虑bug问题。
非bug版本出现这种问题原因主要有两点:
1.所执行sql语句未使用绑定变量,导致sql硬解析过多,出现大量的内存碎片,无法完整使用大块shared_pool;
2.shared_pool太小,无法满足需求。
由于客户所在数据库为BI数据库,为OLAP数据仓库,语句中使用绑定变量反而会加剧性能问题。故优先考虑第二个原因。
根据生成的trc文件上传到oracle官网诊断工具【ORA-4031 Troubleshooting Tool (文档 ID 1521925.1)】,诊断工具给出以下结论:
** In your trace file, there is evidence of subpool imbalance:
free memory in subpool 0 has 201763488 bytes, while in subpool 4 it has 1137789568 bytes, which is 5 times larger.
ges resource in subpool 3 has 6223384 bytes, while in subpool 5 it has 187991376 bytes, which is 30 times larger.
建议:
Decrease the number of subpools in use, or increase SHARED_POOL_SIZE,depending on the current number of subpools.
大意为shared pool子池使用非常不均衡,建议减少子池数,或增大sga。
由于更改subpool需要修改隐含参数,会对服务器造成未知性能影响,因此考虑增大sga方式。
通过客户awr及系统参数显示,服务器有125G内存,数据库使用70g内存,其中shared pool使用13g,通过进一步show parameter查询,发现以下参数的值:
SQL> show parameter sga
NAME TYPE VALUE
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 70400M
sga_target big integer 56576M
SQL> show parameter memory
NAME TYPE VALUE
hi_shared_memory_address integer 0
memory_max_target big integer 70400M
memory_target big integer 70400M
shared_memory_address integer 0
以上数据包含两个信息:
1.sga实际上没有使用到70g;
2.数据库内存管理使用AMM模式
由于AMM管理内存会出现无法使用hugepage的情况,于是计划在增加sga的同时,禁用AMM。
客户数据库是RAC双节点,所以采用滚动关机方式修改参数。
注:建议有时间窗口下,停机修改参数,可避免高负载数据库在关闭节点后,另一节点产生大量gc时间,驱逐被关闭节点。
修改步骤可参看:
http://www.cnblogs.com/snake-hand/archive/2011/10/11/2452243.html
该步骤流程是正确的,但是在操作过程中犯了两个错误:
1.在增大sga的同时,将memory_target和memory_max_target使用以下命令置0:
ALTER SYSTEM SET memory_target=0 scope=spfile;
ALTER SYSTEM SET memory_max_target=0 scope=spfile;
ALTER SYSTEM SET sga_max_size=80G scope=spfile;
ALTER SYSTEM SET sga_target=80G scope=spfile;
此操作直接导致第一个节点修改完后,数据库无法启动:
SQL> startup
ORA-00843: Parameter not taking MEMORY_MAX_TARGET into account
ORA-00849: SGA_TARGET 2147483648 cannot be set to more than MEMORY_MAX_TARGET 0.
正确操作应该是通过spfile生成pfile,将pfile中memory_target和memory_max_target两项参数删除,再替换原spfile。
2.与第一个错误相关,数据库无法启动后,由于对rac操作不熟悉,导致恢复原来的spfile停滞了将近两小时。正确的恢复方式如下:
如果没有spfile备份,在正常节点下,查询该参数:
SQL> show parameter spfile
NAME TYPE VALUE
spfile string $ORACLE_HOME/dbs/spfilexxx.ora
切换至故障节点
$ cat initBI2.ora
SPFILE='+ORA_DG/BI/spfileBI.ora'
SQL> create pfile='/tmp/pfile.ora' from spfile='+ORA_DG/BI/spfileBI.ora';
移除刚才修改的memory_target和memory_max_target两项参数,重启数据库
SQL> startup pfile='/tmp/pfile.ora';
SQL> create spfile from pfile='/tmp/pfile.ora';
SQL> shutdown immediate
SQL> startup
至此,节点1参数修改完毕,切换到节点2修改,出现报错:
ORA-00849: write to SPFILE requested but SPFILE is not modifiable
该错误是独立错误,在该节点重启数据库即可修改。重复网址中的步骤即可。
至此,本次调整结束了,总结以下经过:
1.如果能申请停机时间,最好将rac全部停止后修改参数,避免节点驱逐风险;
2.禁用AMM,修改memory参数时,RAC集群需要将spfile复制出来后,重新create回ASM;
3.RAC集群修改单个节点后,其他节点需要重启后才能生效,也就是停机修改更稳妥的缘故。
行列转置示例
行列转置示例
有需求将行列完全转置,如下:
JOB | D10_SAL | D20_SAL | D30_SAL | D40_SAL |
---|---|---|---|---|
CLERK | 1300 | 1900 | 950 | |
SALESMAN | 5600 | |||
PRESIDENT | 5000 | |||
MANAGER | 2450 | 2975 | 2850 | |
ANALYST | 6000 |
转置成如下:
SALDESC | CLERK | SALESMAN | PRESIDENT | MANAGER | ANALYST |
---|---|---|---|---|---|
D10_SAL | 1300 | 5000 | 2450 | ||
D20_SAL | 1900 | 2975 | 6000 | ||
D30_SAL | 950 | 5600 | 2850 | ||
D40_SAL |
思路是将源表首先列转行,再行转列。(先后无要求,顺序反过来也行)
行转列有pivot,case when方式,列转行有unpivot,insert all...when方式
pivot/unpviot语句和维护简单,但适用场景不如后者多;
case when/insert语句略繁琐,但适用场景多。
首先列转行:
SELECT job,saldesc,deptsal
FROM pivoted_data UNPIVOT INCLUDE NULLS(deptsal FOR saldesc IN(d10_sal,
d20_sal,
d30_sal,
d40_sal));
得到结果:
CLERK | D10_SAL | 1300 |
---|---|---|
CLERK | D20_SAL | 1900 |
CLERK | D30_SAL | 950 |
CLERK | D40_SAL | |
SALESMAN | D10_SAL | |
SALESMAN | D20_SAL | |
SALESMAN | D30_SAL | 5600 |
SALESMAN | D40_SAL | |
PRESIDENT | D10_SAL | 5000 |
PRESIDENT | D20_SAL | |
PRESIDENT | D30_SAL | |
PRESIDENT | D40_SAL | |
MANAGER | D10_SAL | 2450 |
MANAGER | D20_SAL | 2975 |
MANAGER | D30_SAL | 2850 |
MANAGER | D40_SAL | |
ANALYST | D10_SAL | |
ANALYST | D20_SAL | 6000 |
ANALYST | D30_SAL | |
ANALYST | D40_SAL |
行转列【嵌套上个语句】:
select * from pivoted_data
unpivot include nulls(deptsal for saldesc in(d10_sal,
d20_sal,
d30_sal,
d40_sal))
pivot (sum(deptsal) for job in ('CLERK','SALESMAN','PRESIDENT','MANAGER','ANALYST')))
order by saldesc ;
SALDESC | CLERK | SALESMAN | PRESIDENT | MANAGER | ANALYST |
---|---|---|---|---|---|
D10_SAL | 1300 | 5000 | 2450 | ||
D20_SAL | 1900 | 2975 | 6000 | ||
D30_SAL | 950 | 5600 | 2850 | ||
D40_SAL |
附:
适用pivot对源表数据有要求,以下两例说明:
select * from scott.emp;
EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
---|---|---|---|---|---|---|---|
7369 | SMITH | CLERK | 7902 | 1980/12/17 0:00:00 | 800 | 20 | |
7499 | ALLEN | SALESMAN | 7698 | 1981/2/20 0:00:00 | 1600 | 300 | 30 |
7521 | WARD | SALESMAN | 7698 | 1981/2/22 0:00:00 | 1250 | 500 | 30 |
7566 | JONES | MANAGER | 7839 | 1981/4/2 0:00:00 | 2975 | 20 | |
7654 | MARTIN | SALESMAN | 7698 | 1981/9/28 0:00:00 | 1250 | 1400 | 30 |
7698 | BLAKE | MANAGER | 7839 | 1981/5/1 0:00:00 | 2850 | 30 | |
7782 | CLARK | MANAGER | 7839 | 1981/6/9 0:00:00 | 2450 | 10 | |
7788 | SCOTT | ANALYST | 7566 | 1987/4/19 0:00:00 | 3000 | 20 | |
7839 | KING | PRESIDENT | 1981/11/17 0:00:00 | 5000 | 10 | ||
7844 | TURNER | SALESMAN | 7698 | 1981/9/8 0:00:00 | 1500 | 0 | 30 |
7876 | ADAMS | CLERK | 7788 | 1987/5/23 0:00:00 | 1100 | 20 | |
7900 | JAMES | CLERK | 7698 | 1981/12/3 0:00:00 | 950 | 30 | |
7902 | FORD | ANALYST | 7566 | 1981/12/3 0:00:00 | 3000 | 20 | |
7934 | MILLER | CLERK | 7782 | 1982/1/23 0:00:00 | 1300 | 10 |
select job, d10_sal, d20_sal, d30_sal, d40_sal
from scott.emp
pivot(sum(sal) as sal for deptno in(10 as d10,
20 as d20,
30 as d30,
40 as d40));
JOB | SAL | DEPTNO |
---|---|---|
CLERK | 800 | 20 |
SALESMAN | 1600 | 30 |
SALESMAN | 1250 | 30 |
MANAGER | 2975 | 20 |
SALESMAN | 1250 | 30 |
MANAGER | 2850 | 30 |
MANAGER | 2450 | 10 |
ANALYST | 3000 | 20 |
PRESIDENT | 5000 | 10 |
SALESMAN | 1500 | 30 |
CLERK | 1100 | 20 |
CLERK | 950 | 30 |
ANALYST | 3000 | 20 |
CLERK | 1300 | 10 |
select * from sys.emp;
JOB | D10_SAL | D20_SAL | D30_SAL | D40_SAL |
---|---|---|---|---|
SALESMAN | 1250 | |||
MANAGER | 2850 | |||
CLERK | 1300 | |||
SALESMAN | 1250 | |||
MANAGER | 2975 | |||
SALESMAN | 1500 | |||
CLERK | 950 | |||
PRESIDENT | 5000 | |||
CLERK | 1100 | |||
ANALYST | 3000 | |||
ANALYST | 3000 | |||
MANAGER | 2450 | |||
CLERK | 800 | |||
SALESMAN | 1600 |
SELECT JOB, D10_SAL, D20_SAL, D30_SAL, D40_SAL
FROM sys.emp
PIVOT(SUM(sal) as sal FOR deptno IN(10 AS d10,
20 AS d20,
30 AS d30,
40 AS d40));
JOB | D10_SAL | D20_SAL | D30_SAL | D40_SAL |
---|---|---|---|---|
CLERK | 1300 | 1900 | 950 | |
SALESMAN | 5600 | |||
PRESIDENT | 5000 | |||
MANAGER | 2450 | 2975 | 2850 | |
ANALYST | 6000 |
可见如果scott.emp要达到sys.emp的pivot效果,需要在前面语句多加处理,反而不如case when灵活了。
parameter
NAME TYPE VALUE VALUE
fast_start_parallel_rollback string LOW LOW
parallel_adaptive_multi_user boolean TRUE TRUE
parallel_automatic_tuning boolean FALSE FALSE
parallel_degree_limit string CPU CPU
parallel_degree_policy string MANUAL MANUAL
parallel_execution_message_size integer 16384 16384
parallel_force_local boolean FALSE FALSE
parallel_instance_group string
parallel_io_cap_enabled boolean FALSE FALSE
parallel_max_servers integer 120 585
parallel_min_percent integer 0 0
parallel_min_servers integer 0 0
parallel_min_time_threshold string AUTO AUTO
parallel_server boolean FALSE FALSE
parallel_server_instances integer 1 1
parallel_servers_target integer 128 256
parallel_threads_per_cpu integer 2 2
recovery_parallelism integer 0 0
xml转换table
xml格式数据转换到table列
oracle从9i开始支持xml数据在数据库中的存储,通常存储在表中的clob字段。
使用xmltable的语法为:
xmltable('' passing xmltype()
cloumns
path '')
下面是一个范例
select t.data_day,t.tmpl_id,t.tmpl_type,t.tmpl_xml from hwcdm.t_e_ogg_im_tmpl_info_d t where rownum=1;
DATA_DAY TMPL_ID TMPL_TYPE TMPL_XML
20170401 10000200 1
此段中XML文本格式如下:
1--<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2--<InvTmplLifeCycleTemplateXMLVO remark="预置" status="1" lifeCycleTplName="SIM卡段生命周期模板" lifeCycleTplId="1000025">
3-- <invTmplClassFeature value="ENTITY" objType="LIFECYCLE" objId="1000025" classId="1" relaId="3300"/>
4-- <invTmplClassFeature value="PHYSICAL" objType="LIFECYCLE" objId="1000025" classId="2" relaId="3301"/>
5-- <invTmplStsOperMap open="false" origItemStatus="Init" operCode="StockIn" lifeCycleTplId="1000025" pathId="2300"/>
6-- <invTmplStsOperMap open="false" targItemStatus="" origItemStatus="Available" operCode="Transfer" lifeCycleTplId="1000025" pathId="2301"/>
7-- <invTmplStsOperMap open="false" targItemStatus="Wastrel" origItemStatus="Available" operCode="StockOut" lifeCycleTplId="1000025" pathId="2302"/>
8-- <invTmplStsOperMap open="false" targItemStatus="Wastrel" origItemStatus="Available" operCode="Dismount" lifeCycleTplId="1000025" pathId="2303">
9-- <invTmplStsChangeCndt ruleId="456" operCode="CZNXPriceCardExternalStockOut" pathId="2303" conditionId="39"/>
10-- <invTmplStsChangeCndt ruleId="33333" operCode="CZNXPriceCardExternalStockOut" pathId="2303" conditionId="18"/>
11-- </invTmplStsOperMap>
12-- <invTmplStsOperMap open="false" targItemStatus="Wastrel" origItemStatus="Available" operCode="" lifeCycleTplId="1000025" pathId="2304"/>
13-- <invTmplStsOperMap open="false" targItemStatus="Wastrel" origItemStatus="Available" operCode="Discarded" lifeCycleTplId="1000025" pathId="2305"/>
14-- <invTmplStsOperMap open="false" targItemStatus="OutOfPrint" origItemStatus="Available" operCode="ExternalStockOut" lifeCycleTplId="1000025" pathId="3000">
15-- <invTmplStsChangeCndt ruleId="123" operCode="CZNXPriceCardExternalStockOut" pathId="3000" conditionId="3"/>
16-- <invTmplStsChangeCndt ruleId="223" operCode="CZNXPriceCardExternalStockOut" pathId="3000" conditionId="1"/>
17-- </invTmplStsOperMap>
18-- <invTmplStsOperMap open="false" targItemStatus="Wastrel" origItemStatus="OutOfPrint" operCode="ExternalUnSaleGoodsUnbox" lifeCycleTplId="1000025" pathId="2307"/>
19-- <invTmplStsOperMap open="false" targItemStatus="OutOfPrint" origItemStatus="OutOfPrint" operCode="ExternalUnSaleGoodsStockIn" lifeCycleTplId="1000025" pathId="2308"/>
20-- <invTmplStsOperMap open="false" targItemStatus="Available" origItemStatus="OutOfPrint" operCode="ExternalReturnForResale" lifeCycleTplId="1000025" pathId="2309"/>
21-- <invTmplStsOperMap open="false" targItemStatus="Wastrel" origItemStatus="Available" operCode="ExternalUnboxing" lifeCycleTplId="1000025" pathId="2310"/>
22--</InvTmplLifeCycleTemplateXMLVO>
第1行是根节点,可以看做根目录
第2行开始作为子节点,位置为/InvTmplLifeCycleTemplateXMLVO,结束符在第22行。如果需要提取该行remark属性,表示为/InvTmplLifeCycleTemplateXMLVO/@remark。
第3行是第2行子节点,结束符第3行。第10行是第3行的子节点,位置为/InvTmplLifeCycleTemplateXMLVO/invTmplStsOperMap/invTmplStsChangeCndt
这段xml中没有包含值,都是属性。如果需要提取值,可看参考网址。
现在需要将不同节点中的属性提取到oracle表中,需要使用到xmltable函数分解xml文本。
select t1.TMPL_NAME as temp_name,
t1.REMARK as temp_info,
t1.STATUS as temp_status,
t2.relaId as tag_id,
t1.TMPL_TYPE as temp_type,
t2.relaId as rela_id,
t1.tmpl_id as temp_id,
t4.oper_name as oper_name,
t2.operCode as oper_code,
t2.origItemStatus as source_status,
t2.targItemStatus as dest_status,
t2.open as open_code,
t2.pathId as rest_id,
t3.conditionId as rule_id,
t3.ruleId as rest_id,
t1.be_id as be_id
from (select t.BE_ID,
t.REMARK,
t.STATUS,
t.TMPL_ID,
t.TMPL_NAME,
t.TMPL_TYPE,
t.TMPL_XML,
t.be_id as "be_id"
from dwhods.im_tmpl_info t where t.tmpl_type=3 )t1,
xmltable('for $i in /InvTmplLifeCycleTemplateXMLVO/invTmplClassFeature
let $a := $i/@relaId
for $j in /InvTmplLifeCycleTemplateXMLVO/invTmplStsOperMap
let $b := $j/@operCode
let $c := $j/@origItemStatus
let $d := $j/@targItemStatus
let $e := $j/@open
let $f := $j/@pathId
return <InvTmplLifeCycleTemplateXMLVO
relaId="{$a}"
operCode="{$b}"
origItemStatus="{$c}"
targItemStatus="{$d}"
open="{$e}"
pathId="{$f}"/>'
passing xmltype(t1.tmpl_xml)
columns
relaId varchar2(50) path '@relaId',
operCode varchar2(50) path '@operCode',
origItemStatus varchar2(50) path '@origItemStatus',
targItemStatus varchar2(50) path '@targItemStatus',
open varchar2(50) path '@open',
pathId varchar2(50) path '@pathId'
)t2
left join
xmltable('for $k in /InvTmplLifeCycleTemplateXMLVO/invTmplStsOperMap/invTmplStsChangeCndt
let $g := $k/@conditionId
let $h := $k/@ruleId
let $n := $k/@pathId
return <InvTmplLifeCycleTemplateXMLVO
conditionId="{$g}"
ruleId="{$h}"
pathId="{$n}"/>'
passing xmltype(t1.tmpl_xml)
columns
pathId varchar2(50) path '@pathId' ,
conditionId varchar2(50) path '@conditionId' ,
ruleId varchar2(50) path '@ruleId')t3
on t2.pathId=t3.pathId
left join dwhods.im_tmpl_item_oper t4
on t2.opercode=t4.oper_code;
以上sql语句中,t1.tmpl_xml是xml文本。使用for循环将节点中的元素提取到变量中再映射到xmltable的column。
由于暂未发现子节点的for循环的表达方式,所以使用了两次xmltable进行join,补全子节点rule_id,rest_id的属性。
转换后数据如下:
TAG_ID RELA_ID OPER_CODE SOURCE_STATUS DEST_STATUS OPEN_CODE REST_ID RULE_ID REST_ID BE_ID
3301 3301 Dismount Available Wastrel false 2303 18 33333 101
参考资料:
xml解析:http://blog.csdn.net/anddyhua/article/details/7931970?locationNum=1&fps=1
xmlquery语法:http://docs.oracle.com/cd/B19306_01/appdev.102/b14259/xdb_xquery.htm
锁诊断
--通过SQL语句检查表锁
select V$SESSION.sid,v$session.SERIAL#,v$process.spid,
rtrim(object_type) object_type,rtrim(owner) || '.' || object_name object_name,
decode(lmode, 0, 'None', 1, 'Null', 2, 'Row-S',3, 'Row-X',4, 'Share',5, 'S/Row-X', 6, 'Exclusive','Unknown') LockMode,
decode(request, 0, 'None', 1, 'Null', 2, 'Row-S', 3, 'Row-X',4, 'Share', 5, 'S/Row-X', 6, 'Exclusive', 'Unknown') RequestMode
,ctime, block b, v$session.username,MACHINE,MODULE,ACTION,A.type
from (SELECT * FROM V$LOCK) A, all_objects,V$SESSION,v$process
where A.sid > 6
and object_name<>'OBJ$'
and A.id1 = all_objects.object_id
and A.sid=v$session.sid
and v$process.addr=v$session.paddr and v$session.sid > 53
and rtrim(owner)<>'SYS'
--锁所在sql查询,勿用pl/sql
SELECT /*+ ORDERED */
sql_text
FROM v$sqltext a
WHERE (a.hash_value, a.address) IN
(SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),
DECODE(sql_hash_value, 0, prev_sql_addr, sql_address)
FROM v$session b
WHERE b.sid in (select session_id from v$locked_object))
ORDER BY piece ASC;
--锁所在对象,会话和锁类型
select b.owner,b.object_name,l.session_id,l.locked_mode
from v$locked_object l, dba_objects b
where b.object_id=l.object_id;
--锁所在sid,serial#和登录时间
select t2.username,t2.sid,t2.serial#,t2.logon_time
from v$locked_object t1,v$session t2
where t1.session_id=t2.sid order by t2.logon_time;
SQL> select sid,type,lmode,id1,id2,request,block from v$lock where type in ('TM','TX') order by 1,2;
SID TYPE LMODE ID1 ID2 REQUEST BLOCK
38 TM 3 87772 0 0 0
38 TX 0 196613 2916 6 0
63 TM 3 87772 0 0 0
63 TX 6 196613 2916 0 1
SQL> select sid,event from v$session_wait where sid in (63,38);
SID EVENT
38 enq: TX - row lock contention
63 SQL*Net message to client
SQL> select * from dba_objects where object_id=87772;
OWNER OBJECT_NAME SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE CREATED LAST_DDL_TIME TIMESTAMP STATUS TEMPORARY GENERATED SECONDARY NAMESPACE EDITION_NAME
ALEX T 87772 87772 TABLE 2015/6/28 1 2015/6/28 17: 2015-06-28:17:08:29 VALID N N N 1
--会话其他信息查询
select * from v$session where sid=63;
--kill会话
ALTER system KILL session 'SID,serial#';
HugePage配置说明
-
【问题描述】
在有大量并发会话数连接至数据库时,则PageTables占用的内存也越来越大,而这部分内存是无法被数据库使用。当达到一定量级致使主机物理内存资源不足时会导致SGA使用内存被换页从而导致数据库性能下降。 -
【原因/触发因素】
Linux虚拟内存管理过程中,会把物理内存映射为虚拟内存,维护这个映射关系的就是Page Table这个表,每个PTE(Page table)的大小为8字节,Linux会把内存映射为固定大小块,默认是4KB,这样每个连接会话所使使用的Page table表项占用内存为
pagetable size/per(MB)=(sga target size(GB)*1024*1024/4)*8/1024/1024
对于Linux,开启了大页内存,由于HugePages 大小为 2 MB,通过为 Oracle 数据库 SGA 选用更大的页面,可大大减少Page Tables size,即大大减少其占用的内存,进而提高系统内存资源使用率和性能。
每一个进程会有一个页表内存开销,用来寻址该进程要访问的内存区域,对于Oracle来说,每一个服务进程要访问的主要内存主要来自于SGA部分,因为当前数据库的内存配置普遍偏高,所以导致每个服务进程需要开销很大一部分页表内存。 -
【影响和风险】
如果业务的连接数增高,很容易导致物理内存被耗尽。 -
【注意事项】
-
【参数调整说明】
a. ORACLE参数调整的目标是关闭SGA自动调整功能,即将memory_target和memory_max_target设置为0. 对于memory_target和memory_max_target已经设置为0或者这两个参数未设置的环境,请忽略修改ORACLE参数部分。
b. 本指导中ORACLE参数是按照外购件发布的巡检标准设置的,仅供参考。对于数据库与产品合设的服务器,ORACLE参数的调整需要参考产品的内存调优指南。
c. 对于多实例合设的数据库服务器,计算vm.nr_hugepages时,需根据各实例设置的sga_target之合计算。 -
【解决方案】
启用Linux的hugepage功能,把默认的4K内存页面提升到2M,这样一来页表内存的开销就会下降512倍,从而大大降低内存的开销。 -
【实施步骤】
以下步骤以64G内存的主机为例(具体设置值以实际内存来计算,见下面具体计算公式(蓝色字体标注))。
7.1 RAC组网
步骤1 备份两个节点的oracle spfile ,sysctl.conf和 limits.conf。
以root用户执行以下命令:
#cp /etc/sysctl.conf /etc/sysctl_bak
#cp /etc/security/limits.conf /etc/security/limits.conf_bak
以oracle用户执行以下命令:
$sqlplus / as sysdba
SQL> create pfile='/home/oracle/pfile.txt' from spfile;
步骤2 修改节点1的操作系统内核参数
Step>1 login oracle node 1 as root user
Step>2 edit file “/etc/sysctl.conf”
Modify as below
kernel.shmall = 计算出来的值 (设置标准: 物理内存/4096)
物理内存,查询方法:(用root用户执行以下操作:)
grep –i MemTotal /proc/meminfo
查询出的值为KB,需转换为bytes(字节)再代入以上公式进行计算。
kernel.shmmax = xxx (设置标准:设置SHMMAX为物理内存的一半,单位是字节)
kernel.shmmni = 4096 (固定值)
vm.nr_hugepages = xxx (设置标准:ceil(ceil(SGA_TARGET/granule_size)*granule_size/Hugepagesize)+2
Hugepagesize查询方法:(用root用户执行以下操作:)
grep -i Hugepagesize /proc/meminfo
hugepages值计算方法:
1.手动计算;
以上计算公式中,进行计算时建议把SGA_TARGE、granule_size、Hugepagesize的单位统一用字节来带入计算。
2.工具计算:
或者,请利用工具(9.8章节)来自动计算hugepages值。(使用工具时,每一项值的单位可以不统一,具体请参考工具中的说明)。
步骤3 edit file “/etc/security/limits.conf”
Add parameter as below
* soft memlock xxxxxx (设置标准:物理内存的90%,单位是KB)
* hard memlock xxxxxx (设置标准:物理内存的90%,单位是KB)
步骤4 修改节点2的操作系统内核参数,方法和节点1一样
Step>1 login oracle node 1 as root user
Step>2 edit file “/etc/sysctl.conf”
Modify as below
kernel.shmall = xxxx
kernel.shmmax = xxxx
kernel.shmmni = 4096
vm.nr_hugepages = xxxx
Step>3 edit file “/etc/security/limits.conf”
Add parameter as below
* soft memlock xxxxxx
* hard memlock xxxxxx
步骤5 修改oracle参数
此步骤只适用现网环境中数据库实例参数 memory_max_target、memory_target为非0时需要进行配置。
如果现网环境中memory_max_target、memory_target为0或者未配置,跳过此步骤。
#su – oracle
$sqlplus / as sysdba
SQL> alter system set memory_max_target=0 scope = spfile;
SQL> alter system set memory_target=0 scope = spfile;
SQL> alter system reset memory_target scope = spfile;
SQL> alter system reset memory_max_target scope = spfile;
SQL> alter system set pga_aggregate_target = 3200M scope = spfile; (设置标准:物理内存的5%)
SQL> alter system set sga_target=32G scope = spfile; (设置标准:物理内存的45%)
SQL> alter system set sga_max_size=32G scope = spfile; (设置标准:大于等于sga_target)
SQL> alter system set db_cache_size=22900M scope = spfile; (设置标准:sga_target的65%)
SQL> alter system set shared_pool_size=4900M scope=spfile; (设置标准:sga_target的15%)
步骤6 重启oracle实例
stop oracle instance for two nodes
#su – oracle
#sqlplus / as sysdba
Sql> shutdown immediate
Sql> startup
SQL> show parameter memory;(检查参数修改是否生效,确保memory_target和memory_max_target为0,否则不得进行下面的OS重启)
Sql> shutdown immediate
步骤7 以root用户分别重启两个主机和双据库双机
#init 6 (或者执行reboot)
#/opt/oracrs/product/11gR2/grid/bin/crsctl start crs
步骤8 检查hugepage功能是否生效以及hugepage内存被oracle进程所使用。
#su – root
#grep HugePage /proc/meminfo
当以上查询结果显示HugePages_Total为非0时,则说明hugeapges功能已开启。
当以上查询结果显示HugePages_Total与HugePages_Free的值不一致时,则说明hugepage内存被oracle进程所使用。
#ls -l /dev/shm
(检查有没有ora_<DB_SID>开头的共享内存段,正常情况下没有ora_<DB_SID>开头的共享内存段。<DB_SID>为db的实例,不含asm实例“+ASM”。)
10.2 每个连接的物理内存计算方法
没有启用hugepage的情况:(总物理内存 - free - cache – 2G)/总连接数
启用hugepage的情况:(总物理内存 - free - cache – 2G – Oracle SGA)/总连接数
注:计算公式中的2G是操作系统内核和CRS等其他进程的估值。
10.3 主机可新支撑连接的计算方法
可新支撑连接数=free/附录一计算的结果
10.4 预警实施过程中的常见异常
1、 操作系统的内核参数都是小写的,现场多次出现由于参数的首字母是大写的原因导致hugepage不能启用成功。
2、 Oracle的参数修改完之后一定要先重启实例,确认参数是否修改成功,然后再重启主机,否则有可能因为疏漏导致Oracle参数没有修改成功,进而导致hugepage启用失败,而且还多浪费了一次主机的重启时间。
10.5 检查PageTables占用的内存大小计算方法
检查PageTables占用的内存大小:
#su - root
#grep -i pagetables /proc/meminfo
10.6 granule_size的计算方法
粒度值(granule_size)可通过如下SQL查询出来:
select v.CURRENT_SIZE,v.GRANULE_SIZE from v$memory_dynamic_components v where v.component='SGA Target';
10.7 常用sga_target值对应的Hugepages值列表(仅供参考)
SGA_TARGET (单位:MB) | GRANULE_SIZE(单位:字节) | Hugepages值 |
---|---|---|
8192(8G) | 16777216 | 4098 |
16384(16G) | 33554432 | 8194 |
24576(24G) | 67108864 | 12290 |
32768 (32G) | 67108864 | 16386 |
65536 (64G) | 134217728 | 32770 |
分享一下好东西.http://blog.tanelpoder.com/archives/
Oracle 如何修改列的数据类型
对字段操作 | 操作方法 |
---|---|
更新字段名 | alter table TABLE_NAME rename column column_old to column_new; |
添加字段 | alter table TABLE_NAME add COLUMN_NAME varchar(10); |
删除字段 | alter table TABLE_NAME drop column COLUMN_NAME; |
添加字段并附值 | alter table TABLE_NAME ADD COLUMN_NAME NUMBER(1) DEFAULT 1; |
修改字段值 | update TABLE_NAME set filedname=value where filedname=value; |
修改字段数据类型 | alter table tablename modify filedname varchar2(20); |
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
1.修改字段数据类型时,如果该列有数据则报ORA-01439: column to be modified must be empty to change datatype,此时需要通过另外一种方法修改:
SQL> alter table zyt add id_temp varchar2(10);
Table altered.
SQL> commit;
Commit complete.
SQL> select * from zyt;
NAME ID ID_TEMP
---------- ---------- ----------
zyt1 1
david 2
SQL> alter table zyt rename column id to id_bak;
Table altered.
SQL> select * from zyt;
NAME ID_BAK ID_TEMP
---------- ---------- ----------
zyt1 1
david 2
SQL> desc zyt;
Name Null? Type
----------------------------------------- -------- ----------------------------
NAME VARCHAR2(10)
ID_BAK NOT NULL NUMBER(2)
ID_TEMP VARCHAR2(10)
SQL> update zyt set ID_TEMP = cast(ID_BAK as varchar2(10));
2 rows updated.
SQL> commit;
Commit complete.
SQL> select * from zyt;
NAME ID_BAK ID_TEMP
---------- ---------- ----------
zyt1 1 1
david 2 2
SQL> alter table zyt drop column ID_BAK;
Table altered.
SQL> commit;
Commit complete.
SQL> select * from zyt;
NAME ID_TEMP
---------- ----------
zyt1 1
david 2
SQL> desc zyt;
Name Null? Type
----------------------------------------- -------- ----------------------------
NAME VARCHAR2(10)
ID_TEMP VARCHAR2(10)
备注:这种方法能满足需求,因新增字段默认添加到表末尾,有可能发生行迁移,对应用程序会产生影响,同时也涉及复杂数据,不算最好的方法
2.建立一个中间跳板,临时存储数据
SQL> desc zyt;
Name Null? Type
----------------------------------------- -------- ----------------------------
NAME VARCHAR2(10)
ID VARCHAR2(10)
SQL> select * from zyt;
NAME ID
---------- ----------
zyt1 1
david 2
SQL> alter table zyt add id_temp VARCHAR2(10)
Table altered.
SQL> select * from zyt;
NAME ID ID_TEMP
---------- ---------- ----------
zyt1 1
david 2
SQL> update zyt set ID_TEMP=id,id=null;
2 rows updated.
SQL> select * from zyt;
NAME ID ID_TEMP
---------- ---------- ----------
zyt1 1
david 2
SQL> alter table zyt modify id number(10);
Table altered.
SQL> desc zyt;
Name Null? Type
----------------------------------------- -------- ----------------------------
NAME VARCHAR2(10)
ID NUMBER(10)
ID_TEMP VARCHAR2(10)
SQL> update zyt set id=ID_TEMP,ID_TEMP=null;
2 rows updated.
SQL> select * from zyt;
NAME ID ID_TEMP
---------- ---------- ----------
zyt1 1
david 2
SQL> alter table zyt drop column ID_TEMP;
Table altered.
SQL> commit;
Commit complete.
SQL> select * from zyt;
NAME ID
---------- ----------
zyt1 1
david 2
SQL> desc zyt;
Name Null? Type
----------------------------------------- -------- ----------------------------
NAME VARCHAR2(10)
ID NUMBER(10)
备注:第二种方法,是增加一个与被修改的列类型一样的列,之后将要修改列的数据复制到新增的列并置空要修改的列,之后修改数据类型,再从新增列将数据拷贝回来,该过程涉及两次数据复制,如果是数据量很多,会比较慢同时也会产生很多undo和redo;优点是数据不会发生行迁移。
sql
Stat Name Statement Total Per Execution % Snap Total
Elapsed Time (ms) 6,052,830 6,052,830.09 3.25
CPU Time (ms) 1,632,590 1,632,590.00 4.36
Executions 1
Buffer Gets 31,268,262 31,268,262.00 1.23
Disk Reads 31,152,232 31,152,232.00 6.64
Parse Calls 1 1.00 0.00
Rows 23 23.00
User I/O Wait Time (ms) 2,430,889
Cluster Wait Time (ms) 734,239
Application Wait Time (ms) 0
Concurrency Wait Time (ms) 16
Invalidations 0
Version Count 2
Sharable Mem(KB) 140
Id Operation Name Rows Bytes TempSpc Cost (%CPU) Time Pstart Pstop
0 INSERT STATEMENT 15M(100)
1 LOAD TABLE CONVENTIONAL
2 HASH GROUP BY 355K 140M 89G 15M (1) 51:54:39
3 HASH JOIN 223M 86G 8598K (2) 28:39:44
4 PARTITION LIST SINGLE 16871 955K 156 (2) 00:00:02 90 90
5 TABLE ACCESS FULL T_S_CRM_AGENT 16871 955K 156 (2) 00:00:02 90 90
6 HASH JOIN 39774 13M 8597K (2) 28:39:25
7 TABLE ACCESS FULL T_S_CRM_INFDEALER 566 33960 822 (1) 00:00:10
8 HASH JOIN RIGHT OUTER 37574 10M 8596K (2) 28:39:15
9 TABLE ACCESS FULL T_M_DIM_RECHARGE_FACEVALUE 6 240 3 (0) 00:00:01
10 HASH JOIN RIGHT OUTER 37574 9430K 8596K (2) 28:39:15
11 TABLE ACCESS FULL T_E_CRM_DIC_RES_MODEL 11 154 5 (0) 00:00:01
12 HASH JOIN 37574 8916K 8596K (2) 28:39:15
13 PARTITION LIST ALL 37411 1315K 45505 (4) 00:09:07 1 61
14 TABLE ACCESS FULL T_E_UVC_USEDCARD 37411 1315K 45505 (4) 00:09:07 1 61
15 PARTITION LIST ALL 306K 60M 8550K (2) 28:30:09 1 62
16 TABLE ACCESS FULL T_E_DEALER_TRANS_DETL_D 306K 60M 8550K (2) 28:30:09 1 62
SQL Id SQL Text
2nxryhm0ndjqc insert into dwhls.t_l_rechge_card_stock_d_test( daycd , region_id , dist_dealer_id , dist_dealer_name , dist_master_sim , dealer_id , dealer_name , master_sim , sub_dealer_id , sub_dealer_name , sub_master_sim , dealer_type , dealer_level , tariff_type , rc_denom , rechge_cnt , trans_cnt , income_cnt , procs_time ) select /+parallel(6)/ '20170109' as daycd , to_char(t6.zone) as region_id , t2.dealer_id as dist_dealer_id , t2.dealer_name as dist_dealer_name , t2.dealer_msisdn as dist_master_sim , '' as dealer_id , '' as dealer_name , '' as master_sim , '' as sub_dealer_id , '' as sub_dealer_name , '' as sub_master_sim , t2.dealer_type as dealer_type , t2.dealer_level as dealer_level , '30' as tariff_type , ---as RC t4.uvc_face as rc_denom , 0 as rechge_cnt , case when t1.transfer_src_dept=t2.dealer_id then sum(t1.sale_amount) else 0 end as trans_cnt , 0 as income_cnt , sysdate as procs_time from dwhedm.t_e_dealer_trans_detl_d t1 inner join dwhstg.t_s_crm_infdealer t2 on t2.dealer_id = t1.dealer_id and lower(t2.dealer_type) = 'distributors' and t2.dealer_level = '1' and to_char(t1.dealdate, 'yyyymmdd')='20170109' left join dwhedm.t_e_crm_dic_res_model t3 on t3.model_id=t1.model_id and t3.res_type_id='30' left join dwhdm.t_m_dim_recharge_facevalue t4 on t4.crm_face=t3.model_id and t4.crm_face like 'RC%' left join dwhedm.t_e_uvc_usedcard t5 on t5.sequence_card=t1.res_code left join dwhstg.t_s_crm_agent t6 on t6.agentid=t1.dealer_id and t6.data_day=to_char(t1.dealdate, 'yyyymmdd') where t1.res_type='30' and to_char(t1.dealdate, 'yyyymmdd')='20170109' and to_char(t5.dealdate, 'yyyymmdd')='20170109' ---- Added by m84015915 to run query faster and t6.data_day = '20170109' ---- Added by m84015915 to run query faster group by t2.dealer_id, t2.dealer_name, t2.dealer_msisdn, t2.dealer_type, t2.dealer_level, t4.uvc_face, t1.transfer_src_dept, t6.zone
子程序示例
create or replace procedure prc_pay_date is
procedure prc_pay_date2 (date_pair number) is
v_rowid rowid;
v_rowid2 rowid;
CURSOR CUR_rowid IS
select rowid
from T_O_BANK_AMEX_SUM_D_BAK
where rowid > (select row_id from ( select rownum rn,rowid row_id
from T_O_BANK_AMEX_SUM_D_BAK t
where t.pay_date = 'Fecha de Pago')
where rn = date_pair)
and rowid < (select row_id from ( select rownum rn,rowid row_id
from T_O_BANK_AMEX_SUM_D_BAK t
where t.pay_date = 'Totales')
where rn = date_pair);
BEGIN
OPEN cur_rowid;
fetch cur_rowid into v_rowid2;
LOOP
fetch cur_rowid INTO V_ROWID;
UPDATE T_O_BANK_AMEX_SUM_D_BAK
set pay_date =
(select distinct pay_date
from T_O_BANK_AMEX_SUM_D_BAK t
where pay_date is not null
and rowid in v_rowid2)
WHERE ROWID = rowidtochar(v_rowid)
and pay_date is null;
COMMIT;
EXIT WHEN cur_rowid%NOTFOUND;
END LOOP;
CLOSE cur_rowid;
end prc_pay_date2;
procedure prc_pay_date3 is
pair_date number;
cursor cur_pair_date is select count(rowid) row_id
from T_O_BANK_AMEX_SUM_D_BAK t
where t.pay_date = 'Fecha de Pago';
begin
open cur_pair_date;
fetch cur_pair_date into pair_date;
for i in 1..pair_date loop
prc_pay_date2(i);
dbms_output.put_line(i||' pair updated!');
end loop;
close cur_pair_date;
end prc_pay_date3;
begin
prc_pay_date3;
exception
when others then
dbms_output.put_line(substr(sqlerrm, 1, 200));
end prc_pay_date;
性能优化案例3
2.5 复杂视图导致执行计划不稳定
2.5.1 视图BIF_ORDER_DETAIL_EN_V
问题描述:
环境:生产环境
程序:BIF_ORDER_DETAIL_EN_V
时间:2013-11-28
该问题对应W3电子流第D1675042号问题。
生产环境的一个视图BIF_ORDER_DETAIL_EN_V不限定合同号很快,限定合同号非常慢,如下图:
select /*+ parallel(8) */
*
from BIF_ORDER_DETAIL_EN_V t
where t.HW_CONTRACT_NUM='0001701209270C'
and t.REPORT_ITEM_L1_EN_NAME='Order'
and t.DAY_ID between 20130201 and 20131121
and t.REPOFFICE_EN_NAME='Colombia Rep.O'
and t.OFFICE_EN_NAME='Colombia'
and t.COUNTRY_EN_NAME='Colombia'
不限定合同号:33 S
限定合同号:7分钟还没出来
场景:1)查看单个或者多个合同号的交易记录,会计期可能是一个月也可能是几年
2)查看某个地区部在一个月或者多个月的交易记录
3)查看某个项目在一个月或者多个月的交易记录
4)查看某个产品在一个月或者多个月的交易记录
维度:合同维、区域维、项目维、产品维
会计期:不确定,可能一天的、半月、6个月、几年的
问题分析:
不限定合同号,查出来很快,因为仅仅是显示前面N条而已。检索出来的记录,大部分都符合条件,所以出来结果很快。限定合同号之后,因为返回的记录少了很多,所以要检索大量数据之后才能返回,所以更慢。
但如果要查出全量数据,估计都会很慢。所以归根结底还是要优化视图BIF_ORDER_DETAIL_EN_V。
视图BIF_ORDER_DETAIL_EN_V定义很复杂,有嵌套子查询,还有嵌套视图DWR_ORD_ACCEPTANCE_METHOD_V。
CREATE OR REPLACE VIEW BIF.BIF_ORDER_DETAIL_EN_V AS
SELECT /*+ leading(DWR_ORD_CONTRACT_DETAIL_F T1166 T37177) no_merge(T420055) no_merge(T812149) no_push_pred(T812149) use_hash(T120228,
T409840,
T417618 ,
T973 ,
T20170 ,
T30666 ,
T30737,
T30964 ,
T31139 ,
T31024 ,
T22417 ,
T22472,
T1166 ,
T41305 ,
T1105 ,
T391 ,
T22109 ,
T81543,
T85582,
T366 ,
T37177,
T52463,
T413630 ,
T409823 ,
T69098,
T812149,
T420029,
T420055) */
sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '考核报告' then
T413630.PROD_QUANTITY
end) as Measure_Prod_Quantity, --订货量_考核报告
sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '考核报告' then
case
when T69098.COL_RULE_CODE is null or
T69098.COL_RULE_CODE in ('ORDER_00001', 'ORDER_00003') then
T413630.RMB_FACT_EX_RATE_ORDER_AMT
else
0
end
end) + sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '考核报告' then
case
when T69098.COL_RULE_CODE in ('ORDER_00002', 'ORDER_00003') then
T413630.RMB_FACT_EX_RATE_VAT_AMT
else
0
end
end) as INCENTIVE_RMB_AAA_ORDER_AMT,
sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '考核报告' then
case
when T69098.COL_RULE_CODE is null or
T69098.COL_RULE_CODE in ('ORDER_00001', 'ORDER_00003') then
T413630.RMB_BUDGET_EX_RATE_ORDER_AMT
else
0
end
end) + sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '考核报告' then
case
when T69098.COL_RULE_CODE in ('ORDER_00002', 'ORDER_00003') then
T413630.RMB_BUDGET_EX_RATE_VAT_AMT
else
0
end
end) as INCENTIVE_RMB_AAP_ORDER_AMT,
sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '考核报告' then
case
when T69098.COL_RULE_CODE is null or
T69098.COL_RULE_CODE in ('ORDER_00001', 'ORDER_00003') then
T413630.USD_FACT_EX_RATE_ORDER_AMT
else
0
end
end) + sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '考核报告' then
case
when T69098.COL_RULE_CODE in ('ORDER_00002', 'ORDER_00003') then
T413630.USD_FACT_EX_RATE_VAT_AMT
else
0
end
end) as INCENTIVE_USD_AAA_ORDER_AMT,
sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '考核报告' then
case
when T69098.COL_RULE_CODE is null or
T69098.COL_RULE_CODE in ('ORDER_00001', 'ORDER_00003') then
T413630.USD_BUDGET_EX_RATE_ORDER_AMT
else
0
end
end) + sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '考核报告' then
case
when T69098.COL_RULE_CODE in ('ORDER_00002', 'ORDER_00003') then
T413630.USD_BUDGET_EX_RATE_VAT_AMT
else
0
end
end) as INCENTIVE_USD_AAP_ORDER_AMT,
sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '经营报告' then
T413630.PROD_QUANTITY
end) as Incentive_Prod_Quantity, --订货量_经营报告
sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '经营报告' then
case
when T69098.COL_RULE_CODE is null or
T69098.COL_RULE_CODE in ('ORDER_00001', 'ORDER_00003') then
T413630.RMB_FACT_EX_RATE_ORDER_AMT
else
0
end
end) + sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '经营报告' then
case
when T69098.COL_RULE_CODE in ('ORDER_00002', 'ORDER_00003') then
T413630.RMB_FACT_EX_RATE_VAT_AMT
else
0
end
end) as MEASURE_RMB_AAA_ORDER_AMT,
sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '经营报告' then
case
when T69098.COL_RULE_CODE is null or
T69098.COL_RULE_CODE in ('ORDER_00001', 'ORDER_00003') then
T413630.RMB_BUDGET_EX_RATE_ORDER_AMT
else
0
end
end) + sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '经营报告' then
case
when T69098.COL_RULE_CODE in ('ORDER_00002', 'ORDER_00003') then
T413630.RMB_BUDGET_EX_RATE_VAT_AMT
else
0
end
end) as MEASURE_RMB_AAP_ORDER_AMT,
sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '经营报告' then
case
when T69098.COL_RULE_CODE is null or
T69098.COL_RULE_CODE in ('ORDER_00001', 'ORDER_00003') then
T413630.USD_FACT_EX_RATE_ORDER_AMT
else
0
end
end) + sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '经营报告' then
case
when T69098.COL_RULE_CODE in ('ORDER_00002', 'ORDER_00003') then
T413630.USD_FACT_EX_RATE_VAT_AMT
else
0
end
end) as MEASURE_USD_AAA_ORDER_AMT,
sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '经营报告' then
case
when T69098.COL_RULE_CODE is null or
T69098.COL_RULE_CODE in ('ORDER_00001', 'ORDER_00003') then
T413630.USD_BUDGET_EX_RATE_ORDER_AMT
else
0
end
end) + sum(case
when T85582.REPORT_CATEGORY_CN_NAME = '经营报告' then
case
when T69098.COL_RULE_CODE in ('ORDER_00002', 'ORDER_00003') then
T413630.USD_BUDGET_EX_RATE_VAT_AMT
else
0
end
end) as MEASURE_USD_AAP_ORDER_AMT,
T413630.TC_CODE as TC_CODE, --交易币种
T413630.SERVICE_BEGIN_DATE as SERVICE_BEGIN_DATE, --服务交付启动日
T413630.PROD_GROUP_EN_NAME as PROD_GROUP_EN_NAME, --产品分组名称
T413630.PROD_GROUP_CODE as PROD_GROUP_CODE, --产品分组编码
case T413630.ORDER_TYPE_ID
when 1 then
'设备'
when 2 then
'服务'
else
NULL
end as ORDER_TYPE, --订货类型
T413630.MAINTAIN_END_DATE as MAINTAIN_END_DATE, --截止维保日
T413630.MAINTAIN_BEGIN_DATE as MAINTAIN_BEGIN_DATE, --起始维保日
T413630.DESCRIPTION as DESCRIPTION, --描述
T22472.TOP_CUST_CATEGORY_EN_NAME as TOP_CUST_CATEGORY_EN_NAME, --系统部
T22472.CUST_CREDIT_LEVEL_CODE as CUST_CREDIT_LEVEL_CODE, --系统部客户资信等级
T22472.LVL2_CUST_CLASS_EN_NAME as LVL2_CUST_CLASS_EN_NAME, --二级客户群名称
T22472.CUST_EN_NAME as CUST_EN_NAME, --系统部报告客户名称
T22472.CUST_CLASS_EN_NAME as CUST_CLASS_EN_NAME, --客户群
T22472.VALUE_SUBNET_FLAG as VALUE_SUBNET_FLAG, --价值子网标记
T31024.CUST_EN_NAME as AGENT_CUST_EN_NAME, --代理分销客户名称
T31024.INTER_CUST_ACCOUNT_CODE as AGENT_INTER_CUST_ACCOUNT_CODE, --代理分销客户编码
T41305.SALES_MODE_EN_NAME as SALES_MODE_EN_NAME, --销售模式/渠道
T366.COMPANY_CODE as COMPANY_CODE, --签约主体代码
T366.COMPANY_EN_NAME as COMPANY_EN_NAME, --签约主体名称
T413630.UTD_INCENTIVE_DYNAMIC_TYPE as UTD_OPERATING_DYNAMIC_TYPE, --订货_增量类型
T391.LOGIN_DATE as LOGIN_DATE, --合同登录日期
T391.SIGN_DATE as SIGN_DATE, --合同签定日期
T391.CTRCT_BUSINESS_TYPE_EN_NAME as CTRCT_BUSINESS_TYPE_EN_NAME, --业务类型标识
T391.CONTRACT_TEXT_AMT as CONTRACT_TEXT_AMT, --订货文本金额(交易币种)
T391.CONTRACT_TYPE_EN_NAME as CONTRACT_TYPE_EN_NAME, --合同类型名称
T391.HW_CONTRACT_NUM as HW_CONTRACT_NUM, --合同号
T391.CONTRACT_NAME AS CONTRACT_NAME,
T391.STOCK_INCREMENT_TYPE_EN_NAME as STOCK_INCREMENT_TYPE_EN_NAME, --增量/存量标识
T52463.EMPLOYEE_NAME as EMPLOYEE_NAME, --录入人员
T30964.CUST_EN_NAME as END_CUST_EN_NAME, --最终客户名称
T30964.INTER_CUST_ACCOUNT_CODE as END_INTER_CUST_ACCOUNT_CODE, --最终客户编码
T120228.JE_CATEGORY_CODE as JE_SOURCE_CODE, --数据来源标识
(case
when upper(T120228.CN_NAME) in ('MAINTAIN_DEFFER', 'MAINTAIN_STANDARD') then
'Y'
else
'N'
end) as Maintain_Flag, --保修标识
T409823.MILESTONE_EN_NAME as MILESTONE_EN_NAME, --验收时点
T20170.PROD_CODE as ASSIST_PROD_CODE, --辅产品编码
T20170.PROD_EN_NAME as ASSIST_PROD_EN_NAME, --辅产品名称
T812149.CODE as ACCEPT_CODE, --验收方式
T420055.CODE as PHASE_TYPE, --订货期次类型
T409840.EQUIPMENT_AMT as EQUIPMENT_AMT, --设备订货文本金额(交易币种)
T409840.PAYMENT_UNIT_NUM as PAYMENT_UNIT_NUM, --PU
T409840.SERVICE_AMT as SERVICE_AMT, --服务订货文本金额(交易币种)
T30666.PROD_CODE as PHY_PROD_CODE, --物理产品编码
T30666.PROD_EN_NAME as PHY_PROD_EN_NAME, --物理产品名称
T973.LV0_PROD_LIST_EN_NAME as LV0_PROD_LIST_EN_NAME, --BG
T973.LV1_PROD_LIST_EN_NAME as LV1_PROD_LIST_EN_NAME, --BU
T973.LV2_PROD_LIST_EN_NAME as LV2_PROD_LIST_EN_NAME, --产品Lv2
T973.LV3_PROD_LIST_EN_NAME as LV3_PROD_LIST_EN_NAME, --产品Lv3
T973.PROD_CODE as MAJOR_PROD_CODE, --主产品编码
T973.PROD_EN_NAME as MAJOR_PROD_EN_NAME, --主产品名称
T1166.OFFICE_EN_NAME as OFFICE_EN_NAME, --办事处
T1166.REGION_EN_NAME as REGION_EN_NAME, --地区部
T1166.REPOFFICE_EN_NAME as REPOFFICE_EN_NAME, --代表处
T1166.GEO_PC_CODE as GEO_PC_CODE, --Region编码
T1166.GEO_PC_EN_NAME as GEO_PC_EN_NAME, --Region名称
T1166.COUNTRY_EN_NAME as COUNTRY_EN_NAME, --国家
T37177.REPORT_ITEM_L1_EN_NAME as REPORT_ITEM_L1_EN_NAME, --指标1级
T37177.REPORT_ITEM_L2_EN_NAME as REPORT_ITEM_L2_EN_NAME, --指标2级
T37177.REPORT_ITEM_L3_EN_NAME as REPORT_ITEM_L3_EN_NAME, --指标3级
T37177.REPORT_ITEM_L4_EN_NAME as REPORT_ITEM_L4_EN_NAME, --指标4级
T37177.REPORT_ITEM_L5_EN_NAME as REPORT_ITEM_L5_EN_NAME, --指标5级
T69098.REPORT_ITEM_EN_ALIAS as REPORT_ITEM_EN_NAME, --报表项名称
T417618.PROJ_LEVEL_EN_NAME as SALES_PROJ_LEVEL_EN_NAME, --销售项目层级
T417618.PROJ_CN_NAME as SALES_PROJ_EN_NAME, --销售项目名称
T417618.PROJ_NUM as SALES_PROJ_NUM, --销售项目编码
T1105.PROJ_LEVEL_EN_NAME as DELIVERY_PROJ_LEVEL_EN_NAME, --交付项目等级
T1105.PROJ_NUM as DELIVERY_PROJ_NUM, --交付项目编码
T1105.PROJ_CN_NAME as DELIVERY_PROJ_EN_NAME, --交付项目名称
T22417.CUST_CREDIT_LEVEL_CODE as ENT_CUST_CREDIT_LEVEL_CODE, --企业网报告客户资信等级
T22417.CUST_EN_NAME as ENT_CUST_EN_NAME, --企业网报告客户名称
T22417.ENTERPRISE_CUST_CLASS_EN_NAME as ENTERPRISE_CUST_CLASS_EN_NAME, --企业业务客户群
T22417.INDUSTRY_CLASS_EN_NAME as INDUSTRY_CLASS_EN_NAME, --企业业务行业拓展部
T22417.DOMTC_ENTPS_INDU_CLASS_EN_NAME as DOMTC_ENTPS_INDU_CLASS_EN_NAME, --企业业务行业系统部
T30737.PROD_CODE as SERVICE_PROD_CODE, --服务产品编码
T30737.PROD_EN_NAME as SERVICE_PROD_EN_NAME, --服务产品名称
T30737.SERVICE_PROD_SPEL_FLAG as SERVICE_PROD_SPEL_FLAG, --服务分类
T31139.CUST_EN_NAME as SIGNED_CUST_EN_NAME, --签约客户名称
T31139.INTER_CUST_ACCOUNT_CODE as SIGNED_INTER_CUST_ACCOUNT_CODE, --签约客户编码
T413630.PERIOD_ID as DAY_ID,
sysdate as DAY_ID_FROM,
sysdate as DAY_ID_TO,
T1166.AREA_CODE, --add by wwx83766
T1166.REGION_CODE, --add by wwx83766
T1166.REPOFFICE_CODE, --add by wwx83766
T1166.OFFICE_CODE, --add by wwx83766
T1166.COUNTRY_CODE, --add by wwx83766
T973.LV0_PROD_LIST_CODE, --add by wwx83766
T973.LV1_PROD_LIST_CODE, --add by wwx83766
T973.LV2_PROD_LIST_CODE, --add by wwx83766
T973.LV3_PROD_LIST_CODE, --add by wwx83766
T973.LV4_PROD_LIST_CODE, --add by wwx83766
T22472.TOP_CUST_CATEGORY_CODE, --add by wwx83766
T22472.CUST_CLASS_CODE, --add by wwx83766
T41305.SALES_MODE_CODE --add by wwx83766
from DM_DIM_JOURNAL_CATEGORY_D T120228,
DM_DIM_PAYMENT_UNIT_D T409840,
DM_DIM_PROJECT_D T417618, /* DIM_GEO_PROJECT_SALES */
DM_DIM_PRODUCT_D T973,
DM_DIM_PRODUCT_D T20170, /* DM_DIM_MINOR_PRODUCT_D */
DM_DIM_PRODUCT_D T30666, /* DM_DIM_PHYS_PRODUCT_D */
DM_DIM_PRODUCT_D T30737, /* DM_DIM_SERVICE_PRODUCT_D */
DM_DIM_CUSTOMER_D T30964, /* DM_DIM_END_CUSTOMER_D */
DM_DIM_CUSTOMER_D T31139, /* DM_DIM_SIGN_CUSTOMER_D */
DM_DIM_CUSTOMER_D T31024, /* DM_DIM_AGENT_DISTRIBUTION_CUST_D */
DM_DIM_CUSTOMER_D T22417, /* DM_DIM_CUSTOMER_ENTERPRIZE_D */
DM_DIM_CUSTOMER_D T22472, /* DM_DIM_CUSTOMER_ACCOUNT_DEPT_D */
DM_DIM_REGION_RC_D T1166,
DM_DIM_SALES_MODE_D T41305,
DM_DIM_PROJECT_D T1105,
DM_DIM_CONTRACT_D T391,
DM_DIM_DATA_CATEGORY_D T22109,
DM_DIM_DATA_REP_CATEGORY_B T81543,
DM_DIM_REPORT_CATEGORY_D T85582,
DM_DIM_COMPANY_D T366,
DM_DIM_REPORT_ITEM_LEVEL_D T37177,
DM_DIM_EMPLOYEE_D T52463,
(SELECT F.ORDER_DETAIL_NUM,
F.DESCRIPTION,
RPT.PERIOD_ID,
NVL(F.JE_CATEGORY_ID, -999999) JE_CATEGORY_ID,
NVL(F.JE_SOURCE_ID, -999999) JE_SOURCE_ID,
NVL(F.CONTRACT_KEY, -999999) CONTRACT_KEY,
NVL(F.GEO_PC_KEY, -999999) GEO_PC_KEY,
NVL(F.SIGN_COMPANY_KEY, -999999) SIGN_COMPANY_KEY,
NVL(F.SIGN_CUST_KEY, -999999) SIGN_CUST_KEY,
NVL(F.END_CUST_KEY, -999999) END_CUST_KEY,
NVL(F.AGENT_DISTRIBUTION_CUST_KEY, -999999) AGENT_DISTRIBUTION_CUST_KEY,
NVL(F.ACCOUNT_DEPT_CUST_KEY, -999999) ACCOUNT_DEPT_CUST_KEY,
NVL(F.ENTERPRISE_CUST_KEY, -999999) ENTERPRISE_CUST_KEY,
NVL(F.ORDER_PHASE_TYPE_ID, -999999) ORDER_PHASE_TYPE_ID,
NVL(F.ORDER_TYPE_ID, -999999) ORDER_TYPE_ID,
NVL(F.DATA_CATEGORY_ID, -999999) DATA_CATEGORY_ID,
NVL(F.PHYS_PROD_KEY, -999999) PHYS_PROD_KEY,
NVL(F.SERVICE_PROD_KEY, -999999) SERVICE_PROD_KEY,
NVL(F.MAJOR_PROD_KEY, -999999) MAJOR_PROD_KEY,
NVL(F.MINOR_PROD_KEY, -999999) MINOR_PROD_KEY,
NVL(F.PU_KEY, -999999) PU_KEY,
F.CUST_CONTRACT_NO,
F.VERSION,
F.VOUCHER_NUMBER,
NVL(F.DELIVERY_PROJ_KEY, -999999) DELIVERY_PROJ_KEY,
F.PROD_QUANTITY,
F.PROD_GROUP_CODE,
F.PROD_GROUP_CN_NAME,
F.PROD_GROUP_EN_NAME,
NVL(F.ACCEPT_MILESTONE_ID, -999999) ACCEPT_MILESTONE_ID,
NVL(F.ACCEPT_METHOD_TYPE_ID, -999999) ACCEPT_METHOD_TYPE_ID,
F.MAINTAIN_BEGIN_DATE,
F.MAINTAIN_END_DATE,
F.SERVICE_BEGIN_DATE,
F.TC_CODE,
F.LC_CODE,
TC_ORDER_AMT AS TC_ORDER_AMT,
TC_VAT_AMT AS TC_VAT_AMT,
LC_ORDER_AMT AS LC_ORDER_AMT,
LC_VAT_AMT AS LC_VAT_AMT,
F.RMB_FACT_EX_RATE_ORDER_AMT,
F.RMB_FACT_EX_RATE_VAT_AMT,
F.RMB_BUDGET_EX_RATE_ORDER_AMT,
F.RMB_BUDGET_EX_RATE_VAT_AMT,
F.USD_FACT_EX_RATE_ORDER_AMT,
F.USD_FACT_EX_RATE_VAT_AMT,
F.USD_BUDGET_EX_RATE_ORDER_AMT,
F.USD_BUDGET_EX_RATE_VAT_AMT,
F.SALES_MODE_KEY,
NVL(F.INPUT_EMPLOYEE_KEY, -999999) INPUT_EMPLOYEE_KEY,
NVL(RPT.REPORT_ITEM_ID, -999999) REPORT_ITEM_ID,
TYP.OPERATING_DYNAMIC_TYPE,
TYP.INCENTIVE_DYNAMIC_TYPE,
TYP.UTD_OPERATING_DYNAMIC_TYPE,
TYP.UTD_INCENTIVE_DYNAMIC_TYPE,
F.SALES_PROJ_KEY,
NVL(F.PROD_CODE_UPDATE_FLAG, 0) PROD_CODE_UPDATE_FLAG,
F.APPLY_USER,
f.CONTRACT_ID
FROM (SELECT A.*
FROM DWR_ORD_CONTRACT_DETAIL_F A,
DWR_DIM_JOURNAL_SOURCE_D X
WHERE A.JE_SOURCE_ID = X.JE_SOURCE_ID
AND (X.JE_SOURCE_CODE <> 'POLICY CHANGE' OR
(X.JE_SOURCE_CODE = 'POLICY CHANGE' AND
A.PERIOD_ID <> 20130101))) F,
BIF.BIF_RPT_ITEM_ORD_DET_STD_T RPT,
DWR_CONTRACT_DYNAMIC_TYPE_D TYP
WHERE F.ORDER_DETAIL_NUM = RPT.FACT_KEY_ID
AND F.PERIOD_ID = RPT.PERIOD_ID
AND F.CONTRACT_ID = TYP.CONTRACT_ID(+)
AND TYP.SCD_ACTIVE_BEGIN_DATE(+) <=
TO_DATE(TO_CHAR(F.PERIOD_ID), 'YYYY-MM-DD')
AND NVL(TYP.SCD_ACTIVE_END_DATE(+),
TO_DATE('4712-12-31', 'YYYY-MM-DD')) >=
TO_DATE(TO_CHAR(F.PERIOD_ID), 'YYYY-MM-DD')
AND ABS(F.TC_ORDER_AMT) + ABS(F.TC_VAT_AMT) + ABS(F.LC_ORDER_AMT) +
ABS(F.LC_VAT_AMT) + ABS(F.USD_BUDGET_EX_RATE_VAT_AMT) +
ABS(F.USD_BUDGET_EX_RATE_ORDER_AMT) +
ABS(F.RMB_BUDGET_EX_RATE_VAT_AMT) +
ABS(F.USD_FACT_EX_RATE_ORDER_AMT) +
ABS(F.RMB_FACT_EX_RATE_VAT_AMT) +
ABS(F.RMB_FACT_EX_RATE_ORDER_AMT) +
ABS(F.USD_FACT_EX_RATE_VAT_AMT) +
ABS(F.RMB_BUDGET_EX_RATE_ORDER_AMT) > 1) T413630,
DM_DIM_MILESTONE_D T409823,
DM_DIM_REPORT_ITEM_EXT_D T69098,
DWR_ORD_ACCEPTANCE_METHOD_V T812149,
(SELECT T420055.CLASS_ID, T420055.CODE
FROM DWI_MD_CLASS_TYPE T420029,
DWI_MD_CLASS T420055
WHERE T420029.CLASS_TYPE_ID = T420055.CLASS_TYPE_ID
and T420029.NAME = '订货期次类型') T420055
WHERE T413630.SIGN_CUST_KEY = T31139.CUST_ACCOUNT_KEY
AND T413630.END_CUST_KEY = T30964.CUST_ACCOUNT_KEY
AND T413630.AGENT_DISTRIBUTION_CUST_KEY = T31024.CUST_ACCOUNT_KEY
AND T413630.ACCOUNT_DEPT_CUST_KEY = T22472.CUST_ACCOUNT_KEY
AND T413630.ENTERPRISE_CUST_KEY = T22417.CUST_ACCOUNT_KEY
AND T413630.GEO_PC_KEY = T1166.GEO_PC_KEY
AND T413630.PHYS_PROD_KEY = T30666.PROD_KEY
AND T413630.SERVICE_PROD_KEY = T30737.PROD_KEY
AND T413630.MAJOR_PROD_KEY = T973.PROD_KEY
AND T413630.MINOR_PROD_KEY = T20170.PROD_KEY
AND T413630.CONTRACT_KEY = T391.CONTRACT_KEY
AND T413630.DELIVERY_PROJ_KEY = T1105.PROJ_KEY
AND T413630.SALES_PROJ_KEY = T417618.PROJ_KEY
AND T413630.SIGN_COMPANY_KEY = T366.COMPANY_KEY
AND T413630.SALES_MODE_KEY = T41305.SALES_MODE_KEY
AND t413630.PU_KEY = T409840.Pu_Key
AND t413630.REPORT_ITEM_ID = T37177.REPORT_ITEM_L5_ID
AND T37177.USER_GROUP_ID = 2
AND T37177.REPORT_ITEM_L1_CODE IN ('STD_ORDER_11051','STD_ORDER_11005') --'订货',订货新增
AND t413630.REPORT_ITEM_ID = T69098.Report_Item_Id
AND T69098.Report_Item_Type = 'N'
AND T413630.INPUT_EMPLOYEE_KEY = T52463.EMPLOYEE_KEY
AND T413630.ACCEPT_MILESTONE_ID = T409823.MILESTONE_ID(+)
AND T413630.ORDER_PHASE_TYPE_ID = T420055.CLASS_ID
AND T413630.JE_CATEGORY_ID = T120228.JE_CATEGORY_ID
AND T413630.ACCEPT_METHOD_TYPE_ID = T812149.CLASS_ID(+)
AND T413630.ORDER_PHASE_TYPE_ID = T420055.CLASS_ID
AND T413630.DATA_CATEGORY_ID = T22109.DATA_CATEGORY_ID
AND T22109.DATA_CATEGORY_ID = T81543.DATA_CATEGORY_ID
AND T81543.REPORT_CATEGORY_ID = T85582.REPORT_CATEGORY_ID
AND T85582.REPORT_CATEGORY_CN_NAME in ('经营报告', '考核报告')
AND (T413630.USD_FACT_EX_RATE_ORDER_AMT <> 0 OR
T413630.RMB_FACT_EX_RATE_ORDER_AMT <> 0 OR
T413630.RMB_BUDGET_EX_RATE_ORDER_AMT <> 0 OR
T413630.USD_BUDGET_EX_RATE_ORDER_AMT <> 0 OR
T413630.USD_FACT_EX_RATE_VAT_AMT <> 0 OR
T413630.RMB_FACT_EX_RATE_VAT_AMT <> 0 OR
T413630.USD_BUDGET_EX_RATE_VAT_AMT <> 0 OR
T413630.RMB_BUDGET_EX_RATE_VAT_AMT <> 0)
group by T366.COMPANY_EN_NAME,
T366.COMPANY_CODE,
T391.CONTRACT_TEXT_AMT,
T391.CONTRACT_TYPE_EN_NAME,
T391.CTRCT_BUSINESS_TYPE_EN_NAME,
T391.HW_CONTRACT_NUM,
T391.CONTRACT_NAME,
T391.LOGIN_DATE,
T391.SIGN_DATE,
T391.STOCK_INCREMENT_TYPE_EN_NAME,
T973.LV0_PROD_LIST_EN_NAME,
T973.LV1_PROD_LIST_EN_NAME,
T973.LV2_PROD_LIST_EN_NAME,
T973.LV3_PROD_LIST_EN_NAME,
T973.PROD_EN_NAME,
T973.PROD_CODE,
T1105.PROJ_NUM,
T1105.PROJ_CN_NAME,
T1105.PROJ_LEVEL_EN_NAME,
T1166.COUNTRY_EN_NAME,
T1166.GEO_PC_EN_NAME,
T1166.GEO_PC_CODE,
T1166.OFFICE_EN_NAME,
T1166.REGION_EN_NAME,
T1166.REPOFFICE_EN_NAME,
T413630.PERIOD_ID,
T20170.PROD_EN_NAME,
T20170.PROD_CODE,
T22417.CUST_EN_NAME,
T22417.ENTERPRISE_CUST_CLASS_EN_NAME,
T22417.CUST_CREDIT_LEVEL_CODE,
T22417.INDUSTRY_CLASS_EN_NAME,
T22417.ENTERPRISE_CUST_CLASS_CODE,
T22417.DOMTC_ENTPS_INDU_CLASS_EN_NAME,
T22472.CUST_CLASS_EN_NAME,
T22472.CUST_EN_NAME,
T22472.LVL2_CUST_CLASS_EN_NAME,
T22472.TOP_CUST_CATEGORY_EN_NAME,
T22472.TOP_CUST_CATEGORY_CODE,
T22472.VALUE_SUBNET_FLAG,
T22472.CUST_CLASS_CODE,
T22472.LVL2_CUST_CLASS_CODE,
T22472.CUST_CREDIT_LEVEL_CODE,
T30666.PROD_EN_NAME,
T30666.PROD_CODE,
T30737.PROD_EN_NAME,
T30737.PROD_CODE,
T30737.SERVICE_PROD_SPEL_FLAG,
T30964.CUST_EN_NAME,
T30964.INTER_CUST_ACCOUNT_CODE,
T31024.INTER_CUST_ACCOUNT_CODE,
T31024.CUST_TYPE_EN_NAME,
T31139.CUST_EN_NAME,
T31139.INTER_CUST_ACCOUNT_CODE,
T37177.REPORT_ITEM_L1_EN_NAME,
T37177.REPORT_ITEM_L2_EN_NAME,
T37177.REPORT_ITEM_L3_EN_NAME,
T37177.REPORT_ITEM_L5_EN_NAME,
T37177.REPORT_ITEM_L4_EN_NAME,
T41305.SALES_MODE_EN_NAME,
T52463.EMPLOYEE_NAME,
T69098.REPORT_ITEM_EN_ALIAS,
T120228.JE_CATEGORY_CODE,
T409823.MILESTONE_EN_NAME,
T409840.EQUIPMENT_AMT,
T409840.PAYMENT_UNIT_NUM,
T409840.SERVICE_AMT,
T413630.DESCRIPTION,
T413630.MAINTAIN_BEGIN_DATE,
T413630.MAINTAIN_END_DATE,
T413630.PROD_GROUP_EN_NAME,
T413630.PROD_GROUP_CODE,
T413630.SERVICE_BEGIN_DATE,
T413630.TC_CODE,
T417618.PROJ_NUM,
T417618.PROJ_CN_NAME,
T417618.PROJ_LEVEL_EN_NAME,
T420055.CODE,
T413630.UTD_INCENTIVE_DYNAMIC_TYPE,
T812149.CODE,
T31024.CUST_EN_NAME,
case T413630.ORDER_TYPE_ID
when 1 then
'设备'
when 2 then
'服务'
else
NULL
end,
case
when upper(T120228.CN_NAME) in
('MAINTAIN_DEFFER', 'MAINTAIN_STANDARD') then
'Y'
else
'N'
end,
T1166.AREA_CODE, --add by wwx83766
T1166.REGION_CODE, --add by wwx83766
T1166.REPOFFICE_CODE, --add by wwx83766
T1166.OFFICE_CODE, --add by wwx83766
T1166.COUNTRY_CODE, --add by wwx83766
T973.LV0_PROD_LIST_CODE, --add by wwx83766
T973.LV1_PROD_LIST_CODE, --add by wwx83766
T973.LV2_PROD_LIST_CODE, --add by wwx83766
T973.LV3_PROD_LIST_CODE, --add by wwx83766
T973.LV4_PROD_LIST_CODE, --add by wwx83766
T22472.TOP_CUST_CATEGORY_CODE, --add by wwx83766
T22472.CUST_CLASS_CODE, --add by wwx83766
T41305.SALES_MODE_CODE;
复杂的视图,直接导致执行计划很复杂。以下面的SQL为例:
select /*+ parallel(8) */ count(0)
from BIF_ORDER_DETAIL_EN_V t
where t.HW_CONTRACT_NUM = '0001701209270C'
and t.REPORT_ITEM_L1_EN_NAME = 'Order'
and t.DAY_ID between 20130201 and 20131121
and t.REPOFFICE_EN_NAME = 'Colombia Rep.O'
and t.OFFICE_EN_NAME = 'Colombia'
and t.COUNTRY_EN_NAME = 'Colombia'
执行计划如下:
SQL Plan Monitoring Details (Plan Hash Value=3997002216)
==============================================================================================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs| Rows |Activ |
| | | |(Estim)| | | (Act) |ity(%)|
| 0 |SELECT STATEMENT | | | | 1| 1 | |
| 1 | SORT AGGREGATE | | 1 | | 1| 1 | |
| 2 | PX COORDINATOR | | | | 17| 8 | |
| 3 | PX SEND QC (RANDOM) |:TQ10037 | 1 | | 8| 8 | |
| 4 | SORT AGGREGATE | | 1 | | 8| 8 | |
| 5 | VIEW |BIF_ORDER_DETAIL_EN_V | 1 | 165K| 8| 2012 | |
| 6 | HASH GROUP BY | | 1 | 165K| 8| 2012 | |
| 7 | PX RECEIVE | | 1 | 165K| 8| 5752 | |
| 8 | PX SEND HASH |:TQ10036 | 1 | 165K| 8| 5752 | |
| 9 | NESTED LOOPS | | 1 | 165K| 8| 5752 | |
| 10 | HASH JOIN | | 1 | 165K| 8| 5752 | |
| 11 | PX RECEIVE | | 1 | 165K| 8| 46016 | |
| 12 | PX SEND BROADCAST |:TQ10035 | 1 | 165K| 8| 46016 | |
| 13 | HASH JOIN BUFFERED | | 1 | 165K| 8| 5752 | |
| 14 | JOIN FILTER CREATE |:BF0000 | 1 | 165K| 8| 13324 | |
| 15 | PX RECEIVE | | 1 | 165K| 8| 13324 | |
| 16 | PX SEND HASH |:TQ10033 | 1 | 165K| 8| 13324 | |
| 17 | HASH JOIN BUFFERED | | 1 | 165K| 8| 13324 | |
| 18 | HASH JOIN | | 1 | 165K| 8| 4368 | |
| 19 | PX RECEIVE | | 1 | 165K| 8| 4368 | 0.03 |
| 20 | PX SEND HASH |:TQ10030 | 1 | 165K| 8| 4368 | |
| 21 | NESTED LOOPS OUTER | | 1 | 165K| 8| 4368 | |
| 22 | HASH JOIN | | 1 | 165K| 8| 4368 | |
| 23 | PX RECEIVE | | 1 | 164K| 8| 34944 | |
| 24 | PX SEND BROADCAST |:TQ10029 | 1 | 164K| 8| 34944 | |
| 25 | HASH JOIN | | 1 | 164K| 8| 4368 | |
| 26 | PX RECEIVE | | 1 | 164K| 8| 34944 | |
| 27 | PX SEND BROADCAST |:TQ10028 | 1 | 164K| 8| 34944 | |
| 28 | HASH JOIN | | 1 | 164K| 8| 4368 | |
| 29 | PX RECEIVE | | 1 | 164K| 8| 34944 | |
| 30 | PX SEND BROADCAST |:TQ10027 | 1 | 164K| 8| 34944 | |
| 31 | HASH JOIN | | 1 | 164K| 8| 4368 | |
| 32 | PX RECEIVE | | 1 | 163K| 8| 34944 | |
| 33 | PX SEND BROADCAST |:TQ10026 | 1 | 163K| 8| 34944 | |
| 34 | HASH JOIN | | 1 | 163K| 8| 4368 | |
| 35 | PX RECEIVE | | 1 | 133K| 8| 34944 | |
| 36 | PX SEND BROADCAST |:TQ10025 | 1 | 133K| 8| 34944 | |
| 37 | HASH JOIN | | 1 | 133K| 8| 4368 | |
| 38 | PX RECEIVE | | 1 | 132K| 8| 34944 | |
| 39 | PX SEND BROADCAST |:TQ10024 | 1 | 132K| 8| 34944 | |
| 40 | HASH JOIN | | 1 | 132K| 8| 4368 | |
| 41 | PX RECEIVE | | 1 | 101K| 8| 34944 | |
| 42 | PX SEND BROADCAST |:TQ10023 | 1 | 101K| 8| 34944 | 0.03 |
| 43 | HASH JOIN BUFFERED | | 1 | 101K| 8| 4368 | |
| 44 | PX RECEIVE | | 1 | 101K| 8| 4368 | |
| 45 | PX SEND HASH |:TQ10021 | 1 | 101K| 8| 4368 | |
| 46 | HASH JOIN | | 1 | 101K| 8| 4368 | |
| 47 | PX RECEIVE | | 1 | 101K| 8| 34944 | |
| 48 | PX SEND BROADCAST |:TQ10019 | 1 | 101K| 8| 34944 | |
| 49 | HASH JOIN | | 1 | 101K| 8| 4368 | |
| 50 | PX RECEIVE | | 1 | 101K| 8| 34944 | |
| 51 | PX SEND BROADCAST |:TQ10018 | 1 | 101K| 8| 34944 | |
| 52 | HASH JOIN | | 1 | 101K| 8| 4368 | |
| 53 | PX RECEIVE | | 1 | 101K| 8| 34944 | |
| 54 | PX SEND BROADCAST |:TQ10017 | 1 | 101K| 8| 34944 | |
| 55 | HASH JOIN | | 1 | 101K| 8| 4368 | |
| 56 | PX RECEIVE | | 1 | 100K| 8| 34944 | |
| 57 | PX SEND BROADCAST |:TQ10016 | 1 | 100K| 8| 34944 | |
| 58 | HASH JOIN | | 1 | 100K| 8| 4368 | |
| 59 | PX RECEIVE | | 1 | 99180| 8| 34944 | |
| 60 | PX SEND BROADCAST |:TQ10015 | 1 | 99180| 8| 34944 | |
| 61 | HASH JOIN | | 1 | 99180| 8| 4368 | |
| 62 | PX RECEIVE | | 1 | 98059| 8| 34944 | |
| 63 | PX SEND BROADCAST |:TQ10014 | 1 | 98059| 8| 34944 | |
| 64 | HASH JOIN | | 1 | 98059| 8| 4368 | 0.03 |
| 65 | PX RECEIVE | | 1 | 96937| 8| 34944 | |
| 66 | PX SEND BROADCAST |:TQ10013 | 1 | 96937| 8| 34944 | 0.03 |
| 67 | HASH JOIN | | 1 | 96937| 8| 4368 | |
| 68 | PX RECEIVE | | 1 | 95815| 8| 34944 | |
| 69 | PX SEND BROADCAST |:TQ10012 | 1 | 95815| 8| 34944 | |
| 70 | HASH JOIN BUFFERED | | 1 | 95815| 8| 4368 | |
| 71 | PX RECEIVE | | 1 | 88566| 8| 4368 | |
| 72 | PX SEND HASH |:TQ10010 | 1 | 88566| 8| 4368 | |
| 73 | HASH JOIN OUTER BUFFERED | | 1 | 88566| 8| 4368 | |
| 74 | PX RECEIVE | | 1 | 88362| 8| 4368 | 0.03 |
| 75 | PX SEND HASH |:TQ10008 | 1 | 88362| 8| 4368 | |
| 76 | HASH JOIN OUTER BUFFERED | | 1 | 88362| 8| 4368 | 0.08 |
| 77 | PX RECEIVE | | 1 | 88360| 8| 4368 | |
| 78 | PX SEND HASH |:TQ10005 | 1 | 88360| 8| 4368 | |
| 79 | HASH JOIN BUFFERED | | 1 | 88360| 8| 4368 | |
| 80 | JOIN FILTER CREATE |:BF0001 | 1 | 88356| 8| 24928 | |
| 81 | PX RECEIVE | | 1 | 88356| 8| 24928 | |
| 82 | PX SEND HASH |:TQ10003 | 1 | 88356| 8| 24928 | |
| 83 | NESTED LOOPS | | 1 | 88356| 8| 24928 | |
| 84 | BUFFER SORT | | | | 8| 27056 | |
| 85 | PX RECEIVE | | | | 8| 27056 | |
| 86 | PX SEND BROADCAST |:TQ10002 | | | 8| 27056 | |
| 87 | HASH JOIN | | 1 | 85133| 8| 3382 | |
| 88 | HASH JOIN | | 19 | 85130| 8| 3382 | 0.05 |
| 89 | PX RECEIVE | | 3 | 77125| 8| 24 | |
| 90 | PX SEND BROADCAST |:TQ10000 | 3 | 77125| 8| 24 | |
| 91 | PX BLOCK ITERATOR | | 3 | 77125| 8| 3 | |
| 92 | TABLE ACCESS STORAGE FULL|DM_DIM_CONTRACT_D | 3 | 77125| 96| 3 | 2.49 |
| 93 | PX BLOCK ITERATOR | | 10M | 8001| 8| 13M | |
| 94 | TABLE ACCESS STORAGE FULL |DWR_ORD_CONTRACT_DETAIL_F | 10M | 8001| 158| 13M | 0.60 |
| 95 | BUFFER SORT | | | | 8| 16 | |
| 96 | PX RECEIVE | | 2 | 2| 8| 16 | |
| 97 | PX SEND BROADCAST |:TQ10001 | 2 | 2| 8| 16 | |
| 98 | PX BLOCK ITERATOR | | 2 | 2| 8| 2 | |
| 99 | TABLE ACCESS STORAGE FULL|DM_DIM_REGION_RC_D | 2 | 2| 24| 2 | |
|100 | PX BLOCK ITERATOR | | 1 | 23210|27056| 24928 | |
|101 | TABLE ACCESS STORAGE FULL |BIF_RPT_ITEM_ORD_DET_STD_T | 1 | 23210| 906K| 24928 |96.18 |
|102 | PX RECEIVE | | 9 | 3| 8| 7 | |
|103 | PX SEND HASH |:TQ10004 | 9 | 3| 8| 7 | |
|104 | JOIN FILTER USE |:BF0001 | 9 | 3| 8| 7 | |
|105 | PX BLOCK ITERATOR | | 9 | 3| 8| 7 | |
|106 | TABLE ACCESS STORAGE FULL |DM_DIM_REPORT_ITEM_LEVEL_D | 9 | 3| 47| 7 | |
|107 | PX RECEIVE | | 29 | 2| 8| 18 | |
|108 | PX SEND HASH |:TQ10006 | 29 | 2| 8| 29 | |
|109 | PX BLOCK ITERATOR | | 29 | 2| 8| 29 | |
|110 | TABLE ACCESS STORAGE FULL |DM_DIM_MILESTONE_D | 29 | 2| 5| 29 | |
|111 | PX RECEIVE | | 473 | 203| 8| 17 | |
|112 | PX SEND HASH |:TQ10009 | 473 | 203| 8| 23 | |
|113 | VIEW |DWR_ORD_ACCEPTANCE_METHOD_V | 473 | 203| 8| 23 | |
|114 | HASH JOIN | | 473 | 203| 8| 23 | |
|115 | PX RECEIVE | | 1 | 2| 8| 8 | |
|116 | PX SEND BROADCAST |:TQ10007 | 1 | 2| 8| 8 | |
|117 | PX BLOCK ITERATOR | | 1 | 2| 8| 1 | |
|118 | TABLE ACCESS STORAGE FULL |DWI_MD_CLASS_TYPE | 1 | 2| 9| 1 | |
|119 | PX BLOCK ITERATOR | | 250K | 200| 8| 471 | |
|120 | TABLE ACCESS STORAGE FULL |DWI_MD_CLASS | 250K | 200| 102| 471 | 0.03 |
|121 | PX RECEIVE | | 5M | 7248| 8| 621K | |
|122 | PX SEND HASH |:TQ10011 | 5M | 7248| 8| 5M | |
|123 | PX BLOCK ITERATOR | | 5M | 7248| 8| 5M | |
|124 | TABLE ACCESS STORAGE FULL |DM_DIM_PAYMENT_UNIT_D | 5M | 7248| 102| 5M | |
|125 | PX BLOCK ITERATOR | | 381K | 1121| 8| 382K | |
|126 | TABLE ACCESS STORAGE FULL |DM_DIM_CUSTOMER_D | 381K | 1121| 105| 382K | |
|127 | PX BLOCK ITERATOR | | 381K | 1121| 8| 382K | |
|128 | TABLE ACCESS STORAGE FULL |DM_DIM_CUSTOMER_D | 381K | 1121| 105| 382K | |
|129 | PX BLOCK ITERATOR | | 381K | 1121| 8| 382K | |
|130 | TABLE ACCESS STORAGE FULL |DM_DIM_CUSTOMER_D | 381K | 1121| 105| 382K | |
|131 | PX BLOCK ITERATOR | | 381K | 1121| 8| 382K | |
|132 | TABLE ACCESS STORAGE FULL |DM_DIM_CUSTOMER_D | 381K | 1121| 105| 382K | |
|133 | PX BLOCK ITERATOR | | 82567 | 343| 8| 82583 | |
|134 | TABLE ACCESS STORAGE FULL |DM_DIM_PRODUCT_D | 82567 | 343| 139| 82583 | |
|135 | PX BLOCK ITERATOR | | 82567 | 343| 8| 82583 | |
|136 | TABLE ACCESS STORAGE FULL |DM_DIM_PRODUCT_D | 82567 | 343| 139| 82583 | |
|137 | PX BLOCK ITERATOR | | 2335 | 7| 8| 2335 | |
|138 | TABLE ACCESS STORAGE FULL |DM_DIM_JOURNAL_CATEGORY_D | 2335 | 7| 89| 2335 | |
|139 | VIEW | | 473 | 203| 8| 4 | |
|140 | HASH JOIN | | 473 | 203| 8| 4 | |
|141 | PX RECEIVE | | 1 | 2| 8| 8 | |
|142 | PX SEND BROADCAST |:TQ10020 | 1 | 2| 8| 8 | |
|143 | PX BLOCK ITERATOR | | 1 | 2| 8| 1 | |
|144 | TABLE ACCESS STORAGE FULL |DWI_MD_CLASS_TYPE | 1 | 2| 9| 1 | |
|145 | PX BLOCK ITERATOR | | 250K | 200| 8| 1007 | |
|146 | TABLE ACCESS STORAGE FULL |DWI_MD_CLASS | 250K | 200| 102| 1007 | |
|147 | PX RECEIVE | | 26 | 2| 8| 2 | |
|148 | PX SEND HASH |:TQ10022 | 26 | 2| 8| 26 | |
|149 | PX BLOCK ITERATOR | | 26 | 2| 8| 26 | |
|150 | TABLE ACCESS STORAGE FULL |DM_DIM_SALES_MODE_D | 26 | 2| 5| 26 | |
|151 | PX BLOCK ITERATOR | | 7M | 30496| 8| 7M | |
|152 | TABLE ACCESS STORAGE FULL |DM_DIM_PROJECT_D | 7M | 30496| 98| 7M | 0.16 |
|153 | PX BLOCK ITERATOR | | 381K | 1121| 8| 382K | |
|154 | TABLE ACCESS STORAGE FULL |DM_DIM_CUSTOMER_D | 381K | 1121| 105| 382K | |
|155 | PX BLOCK ITERATOR | | 7M | 30496| 8| 7M | |
|156 | TABLE ACCESS STORAGE FULL |DM_DIM_PROJECT_D | 7M | 30496| 98| 7M | 0.19 |
|157 | PX BLOCK ITERATOR | | 82567 | 343| 8| 82583 | |
|158 | TABLE ACCESS STORAGE FULL |DM_DIM_PRODUCT_D | 82567 | 343| 139| 82583 | |
|159 | PX BLOCK ITERATOR | | 82567 | 343| 8| 82583 | |
|160 | TABLE ACCESS STORAGE FULL |DM_DIM_PRODUCT_D | 82567 | 343| 139| 82583 | |
|161 | PX BLOCK ITERATOR | | 2099 | 10| 8| 2105 | |
|162 | TABLE ACCESS STORAGE FULL |DM_DIM_COMPANY_D | 2099 | 10| 105| 2105 | |
|163 | PX BLOCK ITERATOR | | 937K | 1316| 8| 939K | |
|164 | TABLE ACCESS STORAGE FULL |DM_DIM_EMPLOYEE_D | 937K | 1316| 103| 939K | |
|165 | TABLE ACCESS BY INDEX ROWID |DWR_CONTRACT_DYNAMIC_TYPE_D | 1 | | 4368| 4368 | 0.05 |
|166 | INDEX RANGE SCAN |DWR_CONTRACT_DYNAMIC_TYPE_D_U1| 1 | | 4368| 16962 | |
|167 | PX RECEIVE | | 43 | 2| 8| 14 | |
|168 | PX SEND HASH |:TQ10031 | 43 | 2| 8| 43 | |
|169 | PX BLOCK ITERATOR | | 43 | 2| 8| 43 | |
|170 | TABLE ACCESS STORAGE FULL |DM_DIM_DATA_CATEGORY_D | 43 | 2| 5| 43 | |
|171 | PX RECEIVE | | 65 | 2| 8| 26 | |
|172 | PX SEND HASH |:TQ10032 | 65 | 2| 8| 65 | |
|173 | PX BLOCK ITERATOR | | 65 | 2| 8| 65 | |
|174 | TABLE ACCESS STORAGE FULL |DM_DIM_DATA_REP_CATEGORY_B | 65 | 2| 9| 65 | |
|175 | PX RECEIVE | | 2 | 2| 8| 2 | |
|176 | PX SEND HASH |:TQ10034 | 2 | 2| 8| 2 | |
|177 | JOIN FILTER USE |:BF0000 | 2 | 2| 8| 2 | |
|178 | PX BLOCK ITERATOR | | 2 | 2| 8| 2 | |
|179 | TABLE ACCESS STORAGE FULL |DM_DIM_REPORT_CATEGORY_D | 2 | 2| 5| 2 | |
|180 | PX BLOCK ITERATOR | | 1949 | 13| 8| 4266 | |
|181 | TABLE ACCESS STORAGE FULL |DM_DIM_REPORT_ITEM_EXT_D | 1949 | 13| 102| 4266 | |
|182 | TABLE ACCESS BY INDEX ROWID |DWR_DIM_JOURNAL_SOURCE_D | 1 | | 5752| 5752 | |
|183 | INDEX UNIQUE SCAN |XPKDWR_DIM_JOURNAL_SOURCE_D | 1 | | 5752| 5752 | |
==============================================================================================================================================================================================
可以看到,96%的时间都耗费在对BIF_RPT_ITEM_ORD_DET_STD_T的检索上。对该表做了906K次Nested Loops。这是一张大表,记录数很多,90万次Nested Loops的结果是,一共读取了4T的数据量。该SQL需要20分钟才能完成。
这个问题,首选是修改视图BIF_ORDER_DETAIL_EN_V定义,尽量不嵌套子查询,不嵌套视图,这样,执行计划会简单好控制一些。
在不修改视图的情况下,可以在外层查询加提示USE_HASH(T.T413630.RPT),强制让BIF_RPT_ITEM_ORD_DET_STD_T走Hash Join。
修改后的SQL如下:
select /*+ parallel(8) USE_HASH(T.T413630.RPT)*/ count(0)
from BIF_ORDER_DETAIL_EN_V t
where t.HW_CONTRACT_NUM = '0001701209270C'
and t.REPORT_ITEM_L1_EN_NAME = 'Order'
and t.DAY_ID between 20130201 and 20131121
and t.REPOFFICE_EN_NAME = 'Colombia Rep.O'
and t.OFFICE_EN_NAME = 'Colombia'
and t.COUNTRY_EN_NAME = 'Colombia'
执行计划如下:
SQL Plan Monitoring Details (Plan Hash Value=2066198206)
==============================================================================================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs| Rows |Activ |
| | | |(Estim)| | | (Act) |ity(%)|
==============================================================================================================================================================================================
| 0 |SELECT STATEMENT | | | | 1 | 1 | |
| 1 | SORT AGGREGATE | | 1 | | 1 | 1 | |
| 2 | PX COORDINATOR | | | | 17 | 8 | 0.52 |
| 3 | PX SEND QC (RANDOM) |:TQ10037 | 1 | | 8 | 8 | |
| 4 | SORT AGGREGATE | | 1 | | 8 | 8 | |
| 5 | VIEW |BIF_ORDER_DETAIL_EN_V | 1 | 198K | 8 | 2012 | |
| 6 | HASH GROUP BY | | 1 | 198K | 8 | 2012 | |
| 7 | PX RECEIVE | | 1 | 198K | 8 | 5752 | |
| 8 | PX SEND HASH |:TQ10036 | 1 | 198K | 8 | 5752 | |
| 9 | NESTED LOOPS | | 1 | 198K | 8 | 5752 | |
| 10 | HASH JOIN | | 1 | 198K | 8 | 5752 | |
| 11 | PX RECEIVE | | 1 | 198K | 8 | 46016 | |
| 12 | PX SEND BROADCAST |:TQ10035 | 1 | 198K | 8 | 46016 | |
| 13 | HASH JOIN BUFFERED | | 1 | 198K | 8 | 5752 | |
| 14 | JOIN FILTER CREATE |:BF0000 | 1 | 197K | 8 | 13324 | |
| 15 | PX RECEIVE | | 1 | 197K | 8 | 13324 | |
| 16 | PX SEND HASH |:TQ10033 | 1 | 197K | 8 | 13324 | |
| 17 | HASH JOIN BUFFERED | | 1 | 197K | 8 | 13324 | |
| 18 | HASH JOIN | | 1 | 197K | 8 | 4368 | |
| 19 | PX RECEIVE | | 1 | 197K | 8 | 4368 | |
| 20 | PX SEND HASH |:TQ10030 | 1 | 197K | 8 | 4368 | |
| 21 | NESTED LOOPS OUTER | | 1 | 197K | 8 | 4368 | |
| 22 | HASH JOIN | | 1 | 197K | 8 | 4368 | |
| 23 | PX RECEIVE | | 1 | 196K | 8 | 34944 | |
| 24 | PX SEND BROADCAST |:TQ10029 | 1 | 196K | 8 | 34944 | |
| 25 | HASH JOIN | | 1 | 196K | 8 | 4368 | |
| 26 | PX RECEIVE | | 1 | 196K | 8 | 34944 | |
| 27 | PX SEND BROADCAST |:TQ10028 | 1 | 196K | 8 | 34944 | |
| 28 | HASH JOIN | | 1 | 196K | 8 | 4368 | |
| 29 | PX RECEIVE | | 1 | 196K | 8 | 34944 | |
| 30 | PX SEND BROADCAST |:TQ10027 | 1 | 196K | 8 | 34944 | |
| 31 | HASH JOIN | | 1 | 196K | 8 | 4368 | |
| 32 | PX RECEIVE | | 1 | 195K | 8 | 34944 | |
| 33 | PX SEND BROADCAST |:TQ10026 | 1 | 195K | 8 | 34944 | |
| 34 | HASH JOIN | | 1 | 195K | 8 | 4368 | |
| 35 | PX RECEIVE | | 1 | 165K | 8 | 34944 | |
| 36 | PX SEND BROADCAST |:TQ10025 | 1 | 165K | 8 | 34944 | |
| 37 | HASH JOIN | | 1 | 165K | 8 | 4368 | |
| 38 | PX RECEIVE | | 1 | 164K | 8 | 34944 | |
| 39 | PX SEND BROADCAST |:TQ10024 | 1 | 164K | 8 | 34944 | |
| 40 | HASH JOIN | | 1 | 164K | 8 | 4368 | 0.52 |
| 41 | PX RECEIVE | | 1 | 133K | 8 | 34944 | |
| 42 | PX SEND BROADCAST |:TQ10023 | 1 | 133K | 8 | 34944 | |
| 43 | HASH JOIN BUFFERED | | 1 | 133K | 8 | 4368 | |
| 44 | PX RECEIVE | | 1 | 133K | 8 | 4368 | |
| 45 | PX SEND HASH |:TQ10021 | 1 | 133K | 8 | 4368 | |
| 46 | HASH JOIN | | 1 | 133K | 8 | 4368 | |
| 47 | PX RECEIVE | | 1 | 133K | 8 | 34944 | |
| 48 | PX SEND BROADCAST |:TQ10019 | 1 | 133K | 8 | 34944 | |
| 49 | HASH JOIN | | 1 | 133K | 8 | 4368 | |
| 50 | PX RECEIVE | | 1 | 133K | 8 | 34944 | |
| 51 | PX SEND BROADCAST |:TQ10018 | 1 | 133K | 8 | 34944 | |
| 52 | HASH JOIN | | 1 | 133K | 8 | 4368 | |
| 53 | PX RECEIVE | | 1 | 133K | 8 | 34944 | |
| 54 | PX SEND BROADCAST |:TQ10017 | 1 | 133K | 8 | 34944 | |
| 55 | HASH JOIN | | 1 | 133K | 8 | 4368 | |
| 56 | PX RECEIVE | | 1 | 132K | 8 | 34944 | |
| 57 | PX SEND BROADCAST |:TQ10016 | 1 | 132K | 8 | 34944 | |
| 58 | HASH JOIN | | 1 | 132K | 8 | 4368 | |
| 59 | PX RECEIVE | | 1 | 131K | 8 | 34944 | |
| 60 | PX SEND BROADCAST |:TQ10015 | 1 | 131K | 8 | 34944 | |
| 61 | HASH JOIN | | 1 | 131K | 8 | 4368 | |
| 62 | PX RECEIVE | | 1 | 130K | 8 | 34944 | |
| 63 | PX SEND BROADCAST |:TQ10014 | 1 | 130K | 8 | 34944 | |
| 64 | HASH JOIN | | 1 | 130K | 8 | 4368 | |
| 65 | PX RECEIVE | | 1 | 129K | 8 | 34944 | |
| 66 | PX SEND BROADCAST |:TQ10013 | 1 | 129K | 8 | 34944 | |
| 67 | HASH JOIN | | 1 | 129K | 8 | 4368 | |
| 68 | PX RECEIVE | | 1 | 128K | 8 | 34944 | |
| 69 | PX SEND BROADCAST |:TQ10012 | 1 | 128K | 8 | 34944 | |
| 70 | HASH JOIN BUFFERED | | 1 | 128K | 8 | 4368 | |
| 71 | PX RECEIVE | | 1 | 121K | 8 | 4368 | |
| 72 | PX SEND HASH |:TQ10010 | 1 | 121K | 8 | 4368 | |
| 73 | HASH JOIN OUTER BUFFERED | | 1 | 121K | 8 | 4368 | |
| 74 | PX RECEIVE | | 1 | 121K | 8 | 4368 | |
| 75 | PX SEND HASH |:TQ10008 | 1 | 121K | 8 | 4368 | |
| 76 | HASH JOIN OUTER BUFFERED | | 1 | 121K | 8 | 4368 | |
| 77 | PX RECEIVE | | 1 | 121K | 8 | 4368 | |
| 78 | PX SEND HASH |:TQ10005 | 1 | 121K | 8 | 4368 | |
| 79 | HASH JOIN BUFFERED | | 1 | 121K | 8 | 4368 | |
| 80 | JOIN FILTER CREATE |:BF0001 | 1 | 121K | 8 | 24928 | |
| 81 | PX RECEIVE | | 1 | 121K | 8 | 24928 | |
| 82 | PX SEND HASH |:TQ10003 | 1 | 121K | 8 | 24928 | |
| 83 | HASH JOIN | | 1 | 121K | 8 | 24928 | 6.28 |
| 84 | PX RECEIVE | | 1 |85133 | 8 | 27056 | |
| 85 | PX SEND BROADCAST |:TQ10002 | 1 |85133 | 8 | 27056 | |
| 86 | HASH JOIN | | 1 |85133 | 8 | 3382 | |
| 87 | HASH JOIN | | 19 |85130 | 8 | 3382 | |
| 88 | PX RECEIVE | | 3 |77125 | 8 | 24 | |
| 89 | PX SEND BROADCAST |:TQ10000 | 3 |77125 | 8 | 24 | |
| 90 | PX BLOCK ITERATOR | | 3 |77125 | 8 | 3 | |
| 91 | TABLE ACCESS STORAGE FULL |DM_DIM_CONTRACT_D | 3 |77125 | 96 | 3 |48.17 |
| 92 | PX BLOCK ITERATOR | | 10M | 8001 | 8 | 13M | |
| 93 | TABLE ACCESS STORAGE FULL |DWR_ORD_CONTRACT_DETAIL_F | 10M | 8001 | 158 | 13M |12.57 |
| 94 | BUFFER SORT | | | | 8 | 16 | |
| 95 | PX RECEIVE | | 2 | 2 | 8 | 16 | |
| 96 | PX SEND BROADCAST |:TQ10001 | 2 | 2 | 8 | 16 | |
| 97 | PX BLOCK ITERATOR | | 2 | 2 | 8 | 2 | |
| 98 | TABLE ACCESS STORAGE FULL |DM_DIM_REGION_RC_D | 2 | 2 | 24 | 2 | |
| 99 | PX BLOCK ITERATOR | | 34M |35371 | 8 | 109M | |
|100 | TABLE ACCESS STORAGE FULL |BIF_RPT_ITEM_ORD_DET_STD_T | 34M |35371 | 268 | 109M | 6.81 |
|101 | PX RECEIVE | | 9 | 3 | 8 | 6 | |
|102 | PX SEND HASH |:TQ10004 | 9 | 3 | 8 | 7 | |
|103 | JOIN FILTER USE |:BF0001 | 9 | 3 | 8 | 7 | |
|104 | PX BLOCK ITERATOR | | 9 | 3 | 8 | 7 | |
|105 | TABLE ACCESS STORAGE FULL |DM_DIM_REPORT_ITEM_LEVEL_D | 9 | 3 | 47 | 7 | |
|106 | PX RECEIVE | | 29 | 2 | 8 | 18 | |
|107 | PX SEND HASH |:TQ10006 | 29 | 2 | 8 | 29 | |
|108 | PX BLOCK ITERATOR | | 29 | 2 | 8 | 29 | |
|109 | TABLE ACCESS STORAGE FULL |DM_DIM_MILESTONE_D | 29 | 2 | 5 | 29 | |
|110 | PX RECEIVE | | 473 | 203 | 8 | 17 | |
|111 | PX SEND HASH |:TQ10009 | 473 | 203 | 8 | 23 | |
|112 | VIEW |DWR_ORD_ACCEPTANCE_METHOD_V | 473 | 203 | 8 | 23 | |
|113 | HASH JOIN | | 473 | 203 | 8 | 23 | |
|114 | PX RECEIVE | | 1 | 2 | 8 | 8 | |
|115 | PX SEND BROADCAST |:TQ10007 | 1 | 2 | 8 | 8 | |
|116 | PX BLOCK ITERATOR | | 1 | 2 | 8 | 1 | |
|117 | TABLE ACCESS STORAGE FULL |DWI_MD_CLASS_TYPE | 1 | 2 | 9 | 1 | |
|118 | PX BLOCK ITERATOR | | 250K | 200 | 8 | 877 | |
|119 | TABLE ACCESS STORAGE FULL |DWI_MD_CLASS | 250K | 200 | 102 | 877 | |
|120 | PX RECEIVE | | 5M | 7248 | 8 | 621K | |
|121 | PX SEND HASH |:TQ10011 | 5M | 7248 | 8 | 5M | 0.52 |
|122 | PX BLOCK ITERATOR | | 5M | 7248 | 8 | 5M | |
|123 | TABLE ACCESS STORAGE FULL |DM_DIM_PAYMENT_UNIT_D | 5M | 7248 | 102 | 5M | 3.66 |
|124 | PX BLOCK ITERATOR | | 381K | 1121 | 8 | 382K | |
|125 | TABLE ACCESS STORAGE FULL |DM_DIM_CUSTOMER_D | 381K | 1121 | 105 | 382K | |
|126 | PX BLOCK ITERATOR | | 381K | 1121 | 8 | 382K | |
|127 | TABLE ACCESS STORAGE FULL |DM_DIM_CUSTOMER_D | 381K | 1121 | 105 | 382K | |
|128 | PX BLOCK ITERATOR | | 381K | 1121 | 8 | 382K | |
|129 | TABLE ACCESS STORAGE FULL |DM_DIM_CUSTOMER_D | 381K | 1121 | 105 | 382K | 3.66 |
|130 | PX BLOCK ITERATOR | | 381K | 1121 | 8 | 382K | |
|131 | TABLE ACCESS STORAGE FULL |DM_DIM_CUSTOMER_D | 381K | 1121 | 105 | 382K | |
|132 | PX BLOCK ITERATOR | | 82567 | 343 | 8 | 82583 | |
|133 | TABLE ACCESS STORAGE FULL |DM_DIM_PRODUCT_D | 82567 | 343 | 139 | 82583 | |
|134 | PX BLOCK ITERATOR | | 82567 | 343 | 8 | 82583 | |
|135 | TABLE ACCESS STORAGE FULL |DM_DIM_PRODUCT_D | 82567 | 343 | 139 | 82583 | |
|136 | PX BLOCK ITERATOR | | 2335 | 7 | 8 | 2335 | |
|137 | TABLE ACCESS STORAGE FULL |DM_DIM_JOURNAL_CATEGORY_D | 2335 | 7 | 89 | 2335 | |
|138 | VIEW | | 473 | 203 | 8 | 4 | |
|139 | HASH JOIN | | 473 | 203 | 8 | 4 | |
|140 | PX RECEIVE | | 1 | 2 | 8 | 8 | |
|141 | PX SEND BROADCAST |:TQ10020 | 1 | 2 | 8 | 8 | |
|142 | PX BLOCK ITERATOR | | 1 | 2 | 8 | 1 | |
|143 | TABLE ACCESS STORAGE FULL |DWI_MD_CLASS_TYPE | 1 | 2 | 9 | 1 | |
|144 | PX BLOCK ITERATOR | | 250K | 200 | 8 | 900 | |
|145 | TABLE ACCESS STORAGE FULL |DWI_MD_CLASS | 250K | 200 | 102 | 900 | |
|146 | PX RECEIVE | | 26 | 2 | 8 | 2 | |
|147 | PX SEND HASH |:TQ10022 | 26 | 2 | 8 | 26 | |
|148 | PX BLOCK ITERATOR | | 26 | 2 | 8 | 26 | |
|149 | TABLE ACCESS STORAGE FULL |DM_DIM_SALES_MODE_D | 26 | 2 | 5 | 26 | |
|150 | PX BLOCK ITERATOR | | 7M |30496 | 8 | 7M | |
|151 | TABLE ACCESS STORAGE FULL |DM_DIM_PROJECT_D | 7M |30496 | 98 | 7M | 6.81 |
|152 | PX BLOCK ITERATOR | | 381K | 1121 | 8 | 382K | |
|153 | TABLE ACCESS STORAGE FULL |DM_DIM_CUSTOMER_D | 381K | 1121 | 105 | 382K | |
|154 | PX BLOCK ITERATOR | | 7M |30496 | 8 | 7M | |
|155 | TABLE ACCESS STORAGE FULL |DM_DIM_PROJECT_D | 7M |30496 | 98 | 7M | 7.85 |
|156 | PX BLOCK ITERATOR | | 82567 | 343 | 8 | 82583 | |
|157 | TABLE ACCESS STORAGE FULL |DM_DIM_PRODUCT_D | 82567 | 343 | 139 | 82583 | |
|158 | PX BLOCK ITERATOR | | 82567 | 343 | 8 | 82583 | |
|159 | TABLE ACCESS STORAGE FULL |DM_DIM_PRODUCT_D | 82567 | 343 | 139 | 82583 | |
|160 | PX BLOCK ITERATOR | | 2099 | 10 | 8 | 2105 | |
|161 | TABLE ACCESS STORAGE FULL |DM_DIM_COMPANY_D | 2099 | 10 | 105 | 2105 | |
|162 | PX BLOCK ITERATOR | | 937K | 1316 | 8 | 939K | |
|163 | TABLE ACCESS STORAGE FULL |DM_DIM_EMPLOYEE_D | 937K | 1316 | 103 | 939K | 2.62 |
|164 | TABLE ACCESS BY INDEX ROWID |DWR_CONTRACT_DYNAMIC_TYPE_D | 1 | |4368 | 4368 | |
|165 | INDEX RANGE SCAN |DWR_CONTRACT_DYNAMIC_TYPE_D_U1| 1 | |4368 | 16962 | |
|166 | PX RECEIVE | | 43 | 2 | 8 | 14 | |
|167 | PX SEND HASH |:TQ10031 | 43 | 2 | 8 | 43 | |
|168 | PX BLOCK ITERATOR | | 43 | 2 | 8 | 43 | |
|169 | TABLE ACCESS STORAGE FULL |DM_DIM_DATA_CATEGORY_D | 43 | 2 | 5 | 43 | |
|170 | PX RECEIVE | | 65 | 2 | 8 | 26 | |
|171 | PX SEND HASH |:TQ10032 | 65 | 2 | 8 | 65 | |
|172 | PX BLOCK ITERATOR | | 65 | 2 | 8 | 65 | |
|173 | TABLE ACCESS STORAGE FULL |DM_DIM_DATA_REP_CATEGORY_B | 65 | 2 | 9 | 65 | |
|174 | PX RECEIVE | | 2 | 2 | 8 | 2 | |
|175 | PX SEND HASH |:TQ10034 | 2 | 2 | 8 | 2 | |
|176 | JOIN FILTER USE |:BF0000 | 2 | 2 | 8 | 2 | |
|177 | PX BLOCK ITERATOR | | 2 | 2 | 8 | 2 | |
|178 | TABLE ACCESS STORAGE FULL |DM_DIM_REPORT_CATEGORY_D | 2 | 2 | 5 | 2 | |
|179 | PX BLOCK ITERATOR | | 1949 | 13 | 8 | 4266 | |
|180 | TABLE ACCESS STORAGE FULL |DM_DIM_REPORT_ITEM_EXT_D | 1949 | 13 | 102 | 4266 | |
|181 | TABLE ACCESS BY INDEX ROWID |DWR_DIM_JOURNAL_SOURCE_D | 1 | |5752 | 5752 | |
|182 | INDEX UNIQUE SCAN |XPKDWR_DIM_JOURNAL_SOURCE_D | 1 | |5752 | 5752 | |
==============================================================================================================================================================================================
修改后的SQL仅运行了30s就完成。从执行计划可以看到,对表BIF_RPT_ITEM_ORD_DET_STD_T仅做了268次检索,仅读取了10G数据。整个SQL也才读取105G数据。
加提示强制走Hash Join的做法,不一定对每一种查询场景都有效。要想彻底解决视图BIF_ORDER_DETAIL_EN_V的性能问题,还是要修改视图定义,去掉子查询,去掉嵌套视图。
解决方案:
建议:
- 修改视图BIF_ORDER_DETAIL_EN_V,去掉子查询,去掉嵌套视图。
- 在不修改视图的情况下,可以在外层查询加提示USE_HASH(T.T413630.RPT),强制让BIF_RPT_ITEM_ORD_DET_STD_T走Hash Join。
2.5.2 视图使用Union All导致无法被Merge
问题描述:
环境:FU6环境
程序:
时间:2014-02-25
从近几天对于FU6环境的报表运行情况的监控和分析,发现部分报表引用含有Union All的视图,性能问题明显。
问题分析:
下面是最近几天的报表Top SQL中有用到的带有Union All视图的列表。
SQL_ID RUN_TIME(M) SQL_EXEC_START SQL_EXEC_END Used Views
1 bsvy8kpu4w2vp 11.77 2014/2/19 2:47:03 2014/2/19 2:58:49 DM_GROUP_EXT_SUB_IFRS_SUM_FV
2 151rk06xjvjmd 34.8 2014/2/21 10:05:25 2014/2/21 10:40:13 DM_GROUP_AR_TRX_BASE_FV
DM_GROUP_AR_BAL_BASE_FV
3 05zma4qhfdg1n 33.1 2014/2/21 16:21:53 2014/2/21 16:54:59 DWR_AP_SLA_STAND_REPORT_ITEM_F
4 f2ad5844ab2sh 30.85 2014/2/25 9:12:12 2014/2/25 9:43:03 DM_GROUP_AR_TRX_BASE_FV
5 0usuqc8j98za4 32.05 2014/2/21 16:52:56 2014/2/21 17:24:59 DM_GROUP_AR_TRX_BASE_FV
DM_GROUP_AR_BAL_BASE_FV
6 147vjaxhdd3fy 31.55 2014/2/24 16:20:12 2014/2/24 16:51:45 DM_CAR_OSB_SUM_FV
DM_CAR_PL_SUM_FV
7 btaq717w3bhpb 14.6 2014/2/24 17:43:56 2014/2/24 17:58:32 DWR_GRP_AP_LBLTY_BAL_RPT_V
8 bc6cnuc00qzvx 14.22 2014/2/24 16:13:40 2014/2/24 16:27:53 DWR_DIM_RECEIPT_CLASS_V
DWR_DIM_RECEIPT_METHOD_V
DM_GROUP_AR_TRX_BASE_FV
9 dfqrfur2w9y6s 13.42 2014/2/24 16:00:07 2014/2/24 16:13:32 DM_GROUP_AR_TRX_BASE_FV
10 20pkhfj5yyam4 30.15 2014/2/21 17:49:44 2014/2/21 18:19:53 DM_GROUP_AR_BAL_BASE_FV
DM_GROUP_AR_TRX_BASE_FV
Oracle官方文档明确表示,如果视图里面带有Union或Union All,被引用时将不能被Merge。
Mergable Views
As stated above, when Oracle transforms a query on a view it can either merge or push predicates. Of the two techniques, merging provides better optimization opportunities, but is more restrictive in the situations where it can be used.
- Features that will disable view merging:
o Set operators (UNION, UNION ALL, INTERSECT, MINUS)
o A CONNECT BY clause
o A ROWNUM pseudocolumn
o Aggregate functions (AVG, COUNT, MAX, MIN, SUM) in the select list
If your query uses any of these features, read on below to see whether Push Predicates can help. One exception to this rule is views using the UNION ALL set operator that also satisfy the criteria for a Partition View.- Features that require Complex View Merging:
o DISTINCT / UNIQUE
o GROUP BY
If your view uses either DISTINCT or GROUP BY, then Complex View Merging may provide better performance. Check with the DBA to see whether either the OPTIMIZER_FEATURES_ENABLE or COMPLEX_VIEW_MERGING initialisation parameters are set. If not, you can enable complex view merging for just your query using theMERGE hint (not to be confused with the USE_MERGE hint which is used for Sort-Merge joins). Note that Complex View Merging will not help for queries that access columns in the view built from aggregate or analytic functions.- Features that will merge under special conditions
o The view is used as the outer table in an outer join.
If your view is joined as the outer table of an outer join, then it cannot be merged if the view has two or more base tables, however it can still Push Predicates (see below).
这就意味着,除了加在视图上的PERIOD_ID等过滤条件可能被Push进去之外,其他关联条件都没办法Push进去,更不能被Merge。视图不能Merge的情况下,视图里的事实表需要检索整个会计期甚至是多个会计期的数据,耗费时间长。如果视图能被Merge,则视图里的事实表会被有效的关联条件再次过滤,检索的数据量会大大降低。
比如DM_GROUP_AR_TRX_BASE_FV,按汇率+币种,将1条记录发散成4条。虽然PERIOD_ID条件可以Push进视图,但是其他条件如区域、产品等都是通过关联别的维表实现的,Push不进去。因为有Union All,视图也无法被Merge。所以即便是查询一个很小的区域或者很少的几个产品,视图内部也要全部检索一个会计期的数据。而事实表DM_GROUP_AR_TRX_BASE_F一个分区的数据就多达1-2亿条,检索时间很长。
对于这一类视图,目前建议是建立一个汇率+币种的小表,用事实表关联小表,这样可以避免在视图里使用Union All。当然,需要整改的视图不只是附件中列出的这些。
解决方案:
建议改写视图,不要在视图里使用Union All。而是建立一个汇率+币种的小表,用事实表关联小表。
2.6 并行进程工作不均衡
2.6.1 使用不支持并行的函数导致无法并行
问题描述:
环境:SIT环境(Exadata UAT)
程序:损益集团通调分摊模块,MCA_ALLOCATION_PKG.MCA_ALLOC_EXECUTE_P
时间:2014-01-16
现在SIT环境损益集团通调分摊模块多个作业出现性能问题,请帮忙看看,谢谢!
MOIA作业:
-
TASK_C_REPORT_PL_GROUP/BAT_C_REPORT_PL_GROUP/SEQ_FIN_MCA_PL_ALLOC_PCR:
-
TASK_C_REPORT_PL_GROUP/BAT_C_REPORT_PL_GROUP/SEQ_FIN_MCA_PL_ALLOC_EXP_RESEARCH\PJob_SP_PL_MCA_ALLOC_EXP1006
调用的SP都是: MCA_ALLOCATION_PKG.MCA_ALLOC_EXECUTE_P
主要参数: ALLOC_RULE = GRP_PCR0004
目前在跑的sql(sql_id为19tvb2g7pxphx)已经跑了一个多小时了。这个sql通过hint指定了并行,但是实际上没有走并行,查询到的session只有一个。见下图:
查询这个sql中的对象,发现有视图MCA.MCA_PROJ_PRD_TM_REL_BG_TAG_V,而这个视图下面又有物化视图MCA.MCA_PROJ_PROD_REL_MV。视图和物化视图都比较复杂。
sql如下:
INSERT /*+ parallel(4) */
INTO MCA_ALLOC_BASE_TMP
(BASE_ATTRIBUTE_VALUE,
RATIO,
DENOMINATOR_DIMENSION1,
DENOMINATOR_DIMENSION2,
DENOMINATOR_DIMENSION3,
DENOMINATOR_DIMENSION4,
DENOMINATOR_DIMENSION5,
TARGET_DIMENSION1,
TARGET_DIMENSION2,
TARGET_DIMENSION3,
TARGET_DIMENSION4,
TARGET_DIMENSION5,
TARGET_DIMENSION6,
TARGET_DIMENSION7,
TARGET_DIMENSION8,
TARGET_DIMENSION9,
TARGET_DIMENSION10,
TARGET_DIMENSION11,
TARGET_DIMENSION12,
TARGET_DIMENSION13,
TARGET_DIMENSION14,
TARGET_DIMENSION15,
TARGET_DIMENSION16,
TARGET_DIMENSION17,
TARGET_DIMENSION18,
TARGET_DIMENSION19,
TARGET_DIMENSION20,
TARGET_DIMENSION21,
TARGET_DIMENSION22,
TARGET_DIMENSION23,
TARGET_DIMENSION24,
TARGET_DIMENSION25,
TARGET_DIMENSION26,
TARGET_DIMENSION27,
TARGET_DIMENSION28,
TARGET_DIMENSION29,
TARGET_DIMENSION30)
SELECT /*+ parallel(4) */
SUM(TT.AMOUNT),
SUM(TT.RATIO),
TT.PROJ_KEY,
NULL,
NULL,
NULL,
NULL,
TT.BG_PROD_KEY,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
FROM MCA_PROJ_PRD_TM_REL_BG_TAG_V TT
WHERE '201311' <= TT.PERIOD
AND TT.PERIOD <= '201311'
AND (TT.PROJ_KEY IS NOT NULL AND TT.PROJ_KEY <> -999999)
GROUP BY TT.PROJ_KEY, TT.BG_PROD_KEY
HAVING SUM(TT.AMOUNT) > 0
问题分析:
加有并行提示的SQL,实际执行的Session只有一个,可能有如下原因:
- 节点并行度被占用,没拿到并行度。
- 脚本里用到不支持并行调用的Procedure或Function。
- 观察时正在执行的那一部分脚本不需要并行。比如一个Union All语句,第一部分没有并行,第二部分有并行。
- 其他原因。
从sql_id=19tvb2g7pxphx看,应该属于第2种情况,因为视图MCA.MCA_PROJ_PRD_TM_REL_BG_TAG_V引用了如下几个函数:
- MCA_ALLOCATION_PKG.GET_PERIOD_VERSION_F
- MCA_ALLOCATION_PKG.GET_CURRENT_PERIOD_LASTDAY_F
- MCA_ALLOCATION_PKG.GET_CURRENT_OPEN_PERIOD_F
而这几个函数都不支持并行调用。
视图MCA.MCA_PROJ_PRD_TM_REL_BG_TAG_V脚本如下:
CREATE OR REPLACE VIEW MCA.MCA_PROJ_PRD_TM_REL_BG_TAG_V AS
SELECT A.ACCOUNT_PERIOD_ID AS PERIOD, --会计期
C.PROJ_KEY AS PROJ_KEY, --项目KEY
C.PROJ_NUM AS PROJ_NUM, --项目CODE
CASE WHEN A.RND_TEAM_ID = -999999 THEN 1 WHEN A.PROD_ID = -999999 THEN 2 END AS REL_TYPE,--TYPE = 1,项目下产品的比例,TYPE = 2,项目下团队的比例。
CASE WHEN A.PROD_ID = -999999 THEN E.RND_TEAM_KEY ELSE D.PROD_KEY END AS PROD_OR_TEAM_KEY,--产品或团队KEY
CASE WHEN A.PROD_ID = -999999 THEN E.RND_TEAM_CODE ELSE D.PROD_CODE END AS PROD_OR_TEAM_CODE,--产品或团队CODE
CASE
WHEN A.PROD_ID = -999999 THEN
(SELECT BG_PROD_KEY
FROM (SELECT DISTINCT T.RND_TEAM_CODE,
T.RND_TEAM_KEY,
BU.DEFAULT_PROD_CODE AS BG_PROD_CODE,
P.PROD_KEY AS BG_PROD_KEY
FROM DWR_DIM_RND_TEAM_D T,
MCA_BU_BG_T BU,
MCA_PROD_BG_T P
WHERE T.L0_RND_TEAM_CN_NAME = BU.BU_CN_NAME
AND BU.DEFAULT_PROD_CODE = P.PROD_CODE
AND BU.BU_LEVEL='1'
AND P.VERSION =MCA_ALLOCATION_PKG.GET_PERIOD_VERSION_F
AND BU.VERSION = MCA_ALLOCATION_PKG.GET_PERIOD_VERSION_F
AND T.SCD_ACTIVE_BEGIN_DATE <=MCA_ALLOCATION_PKG.GET_CURRENT_PERIOD_LASTDAY_F
AND T.SCD_ACTIVE_END_DATE >MCA_ALLOCATION_PKG.GET_CURRENT_PERIOD_LASTDAY_F
) BG
WHERE E.RND_TEAM_KEY = BG.RND_TEAM_KEY)
ELSE
(SELECT BG.BG_PROD_KEY
FROM MCA_PROD_BG_T BG
WHERE D.PROD_KEY = BG.PROD_KEY
AND BG.VERSION = MCA_ALLOCATION_PKG.GET_PERIOD_VERSION_F)
END AS BG_PROD_KEY, --产品或团队BG KEY
CASE
WHEN A.PROD_ID = -999999 THEN
(SELECT BG.BG_PROD_CODE
FROM (SELECT DISTINCT T.RND_TEAM_CODE,
T.RND_TEAM_KEY,
BU.DEFAULT_PROD_CODE AS BG_PROD_CODE,
P.PROD_KEY AS BG_PROD_KEY
FROM DWR_DIM_RND_TEAM_D T,
MCA_BU_BG_T BU,
MCA_PROD_BG_T P
WHERE T.L0_RND_TEAM_CN_NAME = BU.BU_CN_NAME
AND BU.DEFAULT_PROD_CODE = P.PROD_CODE
AND BU.BU_LEVEL='1'
AND P.VERSION = MCA_ALLOCATION_PKG.GET_PERIOD_VERSION_F
AND BU.VERSION =MCA_ALLOCATION_PKG.GET_PERIOD_VERSION_F
AND T.SCD_ACTIVE_BEGIN_DATE <=MCA_ALLOCATION_PKG.GET_CURRENT_PERIOD_LASTDAY_F
AND T.SCD_ACTIVE_END_DATE >MCA_ALLOCATION_PKG.GET_CURRENT_PERIOD_LASTDAY_F
) BG
WHERE E.RND_TEAM_KEY = BG.RND_TEAM_KEY)
ELSE
(SELECT BG.BG_PROD_CODE
FROM MCA_PROD_BG_T BG
WHERE D.PROD_KEY = BG.PROD_KEY
AND BG.VERSION = MCA_ALLOCATION_PKG.GET_PERIOD_VERSION_F)
END AS BG_PROD_CODE, --产品或团队BG KEY
A.ALLOCATE_PROJ_RATE AS AMOUNT,
NULL AS RATIO
FROM MCA_PROJ_PROD_REL_MV A,
DWI_MD_CLASS B,
MCA_PROJECT_T_MV C,
MCA_PRODUCT_T D,
DWR_DIM_RND_TEAM_D E
WHERE A.PROJ_PROD_REL_TYPE_ID = B.CLASS_ID
AND B.DEL_FLAG = 'N'
AND A.PROJ_ID = C.PROJ_ID
AND A.PROD_ID = D.PROD_ID
AND D.VERSION =MCA_ALLOCATION_PKG.GET_PERIOD_VERSION_F
AND A.RND_TEAM_ID = E.RND_TEAM_ID
AND E.SCD_ACTIVE_BEGIN_DATE <=MCA_ALLOCATION_PKG.GET_CURRENT_PERIOD_LASTDAY_F
AND E.SCD_ACTIVE_END_DATE >MCA_ALLOCATION_PKG.GET_CURRENT_PERIOD_LASTDAY_F
AND A.ACCOUNT_PERIOD_ID = MCA_ALLOCATION_PKG.GET_CURRENT_OPEN_PERIOD_F --取当前打开会计期的数据
AND B.CODE = 'RND_PROJ_EDITION_BENEFIT' --取研发项目与产品版本的受益关联,不取研发项目与产品版本的交付关联
AND A.PROJ_ID IN (SELECT F.PROJ_ID --校验当前打开会计期的数据,研发项目与产品版本的受益比例是否在项目下汇总为1
FROM MCA_PROJ_PROD_REL_MV F, DWI_MD_CLASS G
WHERE F.PROJ_PROD_REL_TYPE_ID = G.CLASS_ID
AND G.DEL_FLAG = 'N'
--AND F.END_TIME = TO_DATE('47121231','YYYYMMDD') 3.0主数据会修改,无需加
AND F.ACCOUNT_PERIOD_ID =MCA_ALLOCATION_PKG.GET_CURRENT_OPEN_PERIOD_F
AND G.CODE = 'RND_PROJ_EDITION_BENEFIT'
GROUP BY F.PROJ_ID
HAVING SUM(F.ALLOCATE_PROJ_RATE) = 1);
解决方案:
解决办法:
- 尽量不要在SQL中调用自定义函数
- 如果需要在SQL中调用函数,又想启用并行的话,必须让函数支持并行调用,方法是在函数的定义部分加入PARALLEL_ENABLE。
2.6.2 插入分区表导致并行不均衡
问题描述:
环境:生产环境
程序:DWR_GRP_JE_RPT_ITEM_PKG.DWR_GRP_JE_RPT_ITEM_P
时间:2014-01-10
今天的损益通调,程序DWR_GRP_JE_RPT_ITEM_PKG.DWR_GRP_JE_RPT_ITEM_P运行很慢,今天运行了65分钟才完成。
问题分析:
检查程序,发现Top SQL是如下的插入语句(sql_id=a3dfpfu09b9yp):
INSERT /*+ append parallel(8)*/
INTO DWRFIN.DWR_GRP_JE_RPT_ITEM_PUBLIC_V T
(T.GRP_ACCOUNT_ENTRY_ID,
T.PERIOD_ID,
T.DATA_SOURCE_TABLE_ID,
T.JE_SOURCE_ID,
T.JE_CATEGORY_ID,
T.DATA_CATEGORY_ID,
T.GROUP_ACCOUNT_CODE,
T.SUB_ACCOUNT_CODE,
T.COMPANY_KEY,
T.IC_KEY,
T.BUY_FROM_IC_KEY,
T.DEPT_KEY,
T.GEO_PC_KEY,
T.COA_BU_KEY,
T.MAJOR_PROD_KEY,
T.MINOR_PROD_KEY,
T.BAS_SALES_TEAM_KEY,
T.END_CUST_KEY,
T.SIGN_CUST_KEY,
T.AGENT_DISTRIBUTION_CUST_KEY,
T.ACCOUNT_DEPT_CUST_KEY,
T.ENTERPRISE_CUST_KEY,
T.BU_KEY,
T.CONTRACT_KEY,
T.PROJ_KEY,
T.SUBPROJ_KEY,
T.SALES_MODE_KEY,
T.COUNTER_SIGN_CONTRACT_KEY,
T.CHILD_RPT_ITEM_ID,
T.PARENT_RPT_ITEM_ID,
T.RCM_KEY,
T.LC_CODE,
T.TC_CODE,
T.UCCID,
T.LC_DR_AMT,
T.LC_CR_AMT,
T.TC_DR_AMT,
T.TC_CR_AMT,
T.RMB_FACT_EX_RATE_DR_AMT,
T.RMB_FACT_EX_RATE_CR_AMT,
T.RMB_BUDGET_EX_RATE_DR_AMT,
T.RMB_BUDGET_EX_RATE_CR_AMT,
T.USD_FACT_EX_RATE_DR_AMT,
T.USD_FACT_EX_RATE_CR_AMT,
T.USD_BUDGET_EX_RATE_DR_AMT,
T.USD_BUDGET_EX_RATE_CR_AMT,
T.LC_PTD_AMT,
T.TC_PTD_AMT,
T.RMB_FACT_EX_RATE_PTD_AMT,
T.RMB_BUDGET_EX_RATE_PTD_AMT,
T.USD_FACT_EX_RATE_PTD_AMT,
T.USD_BUDGET_EX_RATE_PTD_AMT,
T.UPD_JOB_INSTANCE_ID,
T.CRT_JOB_INSTANCE_ID,
T.LAST_UPD_CYCLE_ID,
T.CRT_CYCLE_ID,
T.DEL_FLAG)
SELECT /*+ USE_HASH(RCM PUB) */
FACT.GRP_ACCOUNT_ENTRY_ID,
FACT.PERIOD_ID,
FACT.DATA_SOURCE_TABLE_ID,
FACT.JE_SOURCE_ID,
FACT.JE_CATEGORY_ID,
FACT.DATA_CATEGORY_ID,
FACT.GROUP_ACCOUNT_CODE,
FACT.SUB_ACCOUNT_CODE,
FACT.COMPANY_KEY,
FACT.IC_KEY,
FACT.BUY_FROM_IC_KEY,
FACT.DEPT_KEY,
FACT.GEO_PC_KEY,
FACT.COA_BU_KEY,
FACT.MAJOR_PROD_KEY,
FACT.MINOR_PROD_KEY,
FACT.BAS_SALES_TEAM_KEY,
FACT.END_CUST_KEY,
FACT.SIGN_CUST_KEY,
FACT.AGENT_DISTRIBUTION_CUST_KEY,
FACT.ACCOUNT_DEPT_CUST_KEY,
FACT.ENTERPRISE_CUST_KEY,
FACT.BU_KEY BU_KEY,
FACT.CONTRACT_KEY,
FACT.PROJ_KEY,
FACT.SUBPROJ_KEY,
FACT.SALES_MODE_KEY,
FACT.COUNTER_SIGN_CONTRACT_KEY,
PUB.REPORT_ITEM_ID CHILD_RPT_ITEM_ID,
RPT.PARENT_RPT_ITEM_ID,
NVL(RCM.RCM_KEY, -999999) RCM_KEY,
FACT.LC_CODE,
FACT.TC_CODE,
FACT.UCCID,
FACT.LC_DR_AMT,
FACT.LC_CR_AMT,
FACT.TC_DR_AMT,
FACT.TC_CR_AMT,
FACT.RMB_FACT_EX_RATE_DR_AMT,
FACT.RMB_FACT_EX_RATE_CR_AMT,
NVL(COALESCE(RR_D.LC_RMB_AAP_END_RATE, RR_D.LC_RMB_AAP_BEGIN_RATE) *
FACT.LC_DR_AMT,
FACT.RMB_FACT_EX_RATE_DR_AMT) RMB_BUDGET_EX_RATE_DR_AMT,
NVL(COALESCE(RR_D.LC_RMB_AAP_END_RATE, RR_D.LC_RMB_AAP_BEGIN_RATE) *
FACT.LC_CR_AMT,
FACT.RMB_FACT_EX_RATE_CR_AMT) RMB_BUDGET_EX_RATE_CR_AMT,
COALESCE(UF_M.AVG_RATE, UF_M.BEGIN_RATE, 0) * FACT.LC_DR_AMT USD_FACT_EX_RATE_DR_AMT,
COALESCE(UF_M.AVG_RATE, UF_M.BEGIN_RATE, 0) * FACT.LC_CR_AMT USD_FACT_EX_RATE_CR_AMT,
COALESCE(RR_D.LC_USD_AAP_END_RATE,
RR_D.LC_USD_AAP_BEGIN_RATE,
UF_M.AVG_RATE,
UF_M.BEGIN_RATE,
0) * FACT.LC_DR_AMT USD_BUDGET_EX_RATE_DR_AMT,
COALESCE(RR_D.LC_USD_AAP_END_RATE,
RR_D.LC_USD_AAP_BEGIN_RATE,
UF_M.AVG_RATE,
UF_M.BEGIN_RATE,
0) * FACT.LC_CR_AMT USD_BUDGET_EX_RATE_CR_AMT,
CASE
WHEN (UPPER(DWR_DIM_GRP_ACCT_CODE_D.ACCOUNT_TYPE_EN_NAME) IN
('ASSET', 'EXPENSE') AND
DWR_DIM_GRP_ACCT_CODE_D.LVL2_ACCOUNT_CODE <> '56212') THEN
(LC_DR_AMT - LC_CR_AMT) * NVL(RPT.CALCULATING_SIGN, 1)
ELSE
(LC_CR_AMT - LC_DR_AMT) * NVL(RPT.CALCULATING_SIGN, 1)
END LC_PTD_AMT,
CASE
WHEN (UPPER(DWR_DIM_GRP_ACCT_CODE_D.ACCOUNT_TYPE_EN_NAME) IN
('ASSET', 'EXPENSE') AND
DWR_DIM_GRP_ACCT_CODE_D.LVL2_ACCOUNT_CODE <> '56212') THEN
(TC_DR_AMT - TC_CR_AMT) * NVL(RPT.CALCULATING_SIGN, 1)
ELSE
(TC_CR_AMT - TC_DR_AMT) * NVL(RPT.CALCULATING_SIGN, 1)
END TC_PTD_AMT,
CASE
WHEN (UPPER(DWR_DIM_GRP_ACCT_CODE_D.ACCOUNT_TYPE_EN_NAME) IN
('ASSET', 'EXPENSE') AND
DWR_DIM_GRP_ACCT_CODE_D.LVL2_ACCOUNT_CODE <> '56212') THEN
(RMB_FACT_EX_RATE_DR_AMT - RMB_FACT_EX_RATE_CR_AMT) *
NVL(RPT.CALCULATING_SIGN, 1)
ELSE
(RMB_FACT_EX_RATE_CR_AMT - RMB_FACT_EX_RATE_DR_AMT) *
NVL(RPT.CALCULATING_SIGN, 1)
END RMB_FACT_EX_RATE_PTD_AMT,
CASE
WHEN (UPPER(DWR_DIM_GRP_ACCT_CODE_D.ACCOUNT_TYPE_EN_NAME) IN
('ASSET', 'EXPENSE') AND
DWR_DIM_GRP_ACCT_CODE_D.LVL2_ACCOUNT_CODE <> '56212') THEN
NVL(COALESCE(RR_D.LC_RMB_AAP_END_RATE, RR_D.LC_RMB_AAP_BEGIN_RATE) *
(FACT.LC_DR_AMT - FACT.LC_CR_AMT) * NVL(RPT.CALCULATING_SIGN, 1),
(RMB_FACT_EX_RATE_DR_AMT - RMB_FACT_EX_RATE_CR_AMT) *
NVL(RPT.CALCULATING_SIGN, 1))
ELSE
NVL(COALESCE(RR_D.LC_RMB_AAP_END_RATE, RR_D.LC_RMB_AAP_BEGIN_RATE) *
(FACT.LC_CR_AMT - FACT.LC_DR_AMT) * NVL(RPT.CALCULATING_SIGN, 1),
(RMB_FACT_EX_RATE_CR_AMT - RMB_FACT_EX_RATE_DR_AMT) *
NVL(RPT.CALCULATING_SIGN, 1))
END RMB_BUDGET_EX_RATE_PTD_AMT,
CASE
WHEN (UPPER(DWR_DIM_GRP_ACCT_CODE_D.ACCOUNT_TYPE_EN_NAME) IN
('ASSET', 'EXPENSE') AND
DWR_DIM_GRP_ACCT_CODE_D.LVL2_ACCOUNT_CODE <> '56212') THEN
COALESCE(UF_M.AVG_RATE, UF_M.BEGIN_RATE, 0) *
(FACT.LC_DR_AMT - FACT.LC_CR_AMT) * NVL(RPT.CALCULATING_SIGN, 1)
ELSE
COALESCE(UF_M.AVG_RATE, UF_M.BEGIN_RATE, 0) *
(FACT.LC_CR_AMT - FACT.LC_DR_AMT) * NVL(RPT.CALCULATING_SIGN, 1)
END USD_FACT_EX_RATE_PTD_AMT,
CASE
WHEN (UPPER(DWR_DIM_GRP_ACCT_CODE_D.ACCOUNT_TYPE_EN_NAME) IN
('ASSET', 'EXPENSE') AND
DWR_DIM_GRP_ACCT_CODE_D.LVL2_ACCOUNT_CODE <> '56212') THEN
COALESCE(RR_D.LC_USD_AAP_END_RATE,
RR_D.LC_USD_AAP_BEGIN_RATE,
UF_M.AVG_RATE,
UF_M.BEGIN_RATE,
0) * (FACT.LC_DR_AMT - FACT.LC_CR_AMT) *
NVL(RPT.CALCULATING_SIGN, 1)
ELSE
COALESCE(RR_D.LC_USD_AAP_END_RATE,
RR_D.LC_USD_AAP_BEGIN_RATE,
UF_M.AVG_RATE,
UF_M.BEGIN_RATE,
0) * (FACT.LC_CR_AMT - FACT.LC_DR_AMT) *
NVL(RPT.CALCULATING_SIGN, 1)
END USD_BUDGET_EX_RATE_PTD_AMT,
NVL(:B3, 0),
NVL(:B3, 0),
NVL(:B2, 0),
NVL(:B2, 0),
'N'
FROM (SELECT DWR_FIN_GROUP_JE_ALL_F.*,
COMP.COMPANY_CODE,
GEO_PC.GEO_PC_CODE
FROM DWRFIN.DWR_FIN_GROUP_JE_ALL_F,
DWRDIM.DWR_DIM_COMPANY_D COMP,
DWRDIM.DWR_DIM_REGION_RC_D GEO_PC
WHERE DWR_FIN_GROUP_JE_ALL_F.COMPANY_KEY = COMP.COMPANY_KEY
AND DWR_FIN_GROUP_JE_ALL_F.GEO_PC_KEY = GEO_PC.GEO_PC_KEY
AND DWR_FIN_GROUP_JE_ALL_F.PERIOD_ID = :B1) FACT,
BIF.BIF_RPT_ITEM_PL_PUB_T PUB,
DWRFIN.DWR_GRP_JE_RCM RCM,
BIF.BIF_RPT_ITEM_P_C_REL RPT,
DWRDIM.DWR_DIM_GRP_ACCT_CODE_D,
MCA.MCA_PERIOD_RATE_T UF_M,
MCA.MCA_BLENDED_EXCHANGE_RATE_T RR_D
WHERE FACT.PERIOD_ID = PUB.PERIOD_ID
AND PUB.PERIOD_ID = :B1
AND FACT.GRP_ACCOUNT_ENTRY_ID = PUB.FACT_KEY_ID
AND PUB.FACT_KEY_ID = RCM.GRP_ACCOUNT_ENTRY_ID(+)
AND PUB.PERIOD_ID = RCM.PERIOD_ID(+)
AND FACT.GROUP_ACCOUNT_CODE =
DWR_DIM_GRP_ACCT_CODE_D.GROUP_ACCOUNT_CODE
AND PUB.REPORT_ITEM_ID = RPT.CHILD_RPT_ITEM_ID
AND FACT.COMPANY_CODE = RR_D.COMPANY_CODE(+)
AND FACT.GEO_PC_CODE = RR_D.REGION_CODE(+)
AND FACT.PERIOD_ID = TO_NUMBER(RR_D.PERIOD_NUMBER(+))
AND FACT.LC_CODE = UF_M.FROM_CURRENCY_CODE(+)
AND FACT.PERIOD_ID = TO_NUMBER(UF_M.PERIOD_NUMBER(+))
AND UF_M.TO_CURRENCY_CODE(+) = 'USD'
以上语句一共插入577489080,耗时65分钟。因为是年结,插入的数据量比之前要大很多。
查看执行计划如下:
SQL Plan Monitoring Details (Plan Hash Value=3000473584)
==================================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | | (Estim) | | |(Actual) | (%) |
==================================================================================================================================
| 0 |INSERT STATEMENT | | | | 17 | | |
| 1 | PX COORDINATOR | | | | 17 | | |
| 2 | PX SEND QC (RANDOM) | :TQ10011 | 304M | 445K | 1 | 1 | |
| 3 | LOAD AS SELECT | | | | 1 | 1 | 0.05 |
| 4 | PX RECEIVE | | 304M | 445K | 1 | 577M | |
| 5 | PX SEND PARTITION (KEY) | :TQ10010 | 304M | 445K | 8 | 577M | 0.05 |
| 6 | HASH JOIN BUFFERED | | 304M | 445K | 8 | 577M | 10.81 |
| 7 | PX RECEIVE | | 8236 | 2 | 8 | 65888 | |
| 8 | PX SEND BROADCAST | :TQ10007 | 8236 | 2 | 8 | 65888 | |
| 9 | PX BLOCK ITERATOR | | 8236 | 2 | 8 | 8236 | |
| 10 | TABLE ACCESS STORAGE FULL | BIF_RPT_ITEM_P_C_REL | 8236 | 2 | 24 | 8236 | |
| 11 | HASH JOIN RIGHT OUTER | | 82M | 444K | 8 | 82M | 2.88 |
| 12 | PX RECEIVE | | 24M | 6578 | 8 | 25M | 0.05 |
| 13 | PX SEND HASH | :TQ10008 | 24M | 6578 | 8 | 25M | 0.20 |
| 14 | PX BLOCK ITERATOR | | 24M | 6578 | 8 | 25M | |
| 15 | TABLE ACCESS STORAGE FULL | DWR_GRP_JE_RCM | 24M | 6578 | 99 | 25M | |
| 16 | PX RECEIVE | | 82M | 438K | 8 | 82M | 3.62 |
| 17 | PX SEND HASH | :TQ10009 | 82M | 438K | 8 | 82M | 6.45 |
| 18 | HASH JOIN BUFFERED | | 82M | 438K | 8 | 82M | 24.50 |
| 19 | PX RECEIVE | | 6872 | 26 | 8 | 54976 | |
| 20 | PX SEND BROADCAST | :TQ10002 | 6872 | 26 | 8 | 54976 | |
| 21 | PX BLOCK ITERATOR | | 6872 | 26 | 8 | 6872 | |
| 22 | TABLE ACCESS STORAGE FULL | DWR_DIM_GRP_ACCT_CODE_D | 6872 | 26 | 98 | 6872 | |
| 23 | HASH JOIN RIGHT OUTER | | 82M | 438K | 8 | 82M | 1.98 |
| 24 | PX RECEIVE | | 884 | 13 | 8 | 9160 | |
| 25 | PX SEND BROADCAST | :TQ10003 | 884 | 13 | 8 | 9160 | |
| 26 | PX BLOCK ITERATOR | | 884 | 13 | 8 | 1145 | |
| 27 | TABLE ACCESS STORAGE FULL | MCA_BLENDED_EXCHANGE_RATE_T | 884 | 13 | 90 | 1145 | |
| 28 | HASH JOIN RIGHT OUTER | | 82M | 438K | 8 | 82M | 1.44 |
| 29 | PX RECEIVE | | 160 | 94 | 8 | 1312 | |
| 30 | PX SEND BROADCAST | :TQ10004 | 160 | 94 | 8 | 1312 | |
| 31 | PX BLOCK ITERATOR | | 160 | 94 | 8 | 164 | |
| 32 | TABLE ACCESS STORAGE FULL | MCA_PERIOD_RATE_T | 160 | 94 | 91 | 164 | |
| 33 | HASH JOIN | | 82M | 438K | 8 | 82M | 36.36 |
| 34 | PX RECEIVE | | 82M | 24487 | 8 | 82M | 0.05 |
| 35 | PX SEND HASH | :TQ10005 | 82M | 24487 | 8 | 82M | 0.15 |
| 36 | PX BLOCK ITERATOR | | 82M | 24487 | 8 | 82M | |
| 37 | TABLE ACCESS STORAGE FULL | BIF_RPT_ITEM_PL_PUB_T | 82M | 24487 | 354 | 82M | 0.55 |
| 38 | PX RECEIVE | | 98M | 96951 | 8 | 98M | 1.59 |
| 39 | PX SEND HASH | :TQ10006 | 98M | 96951 | 8 | 98M | 4.86 |
| 40 | VIEW | | 98M | 96951 | 8 | 98M | 0.50 |
| 41 | FILTER | | | | 8 | 98M | 0.05 |
| 42 | HASH JOIN | | 98M | 96951 | 8 | 98M | 0.99 |
| 43 | PX RECEIVE | | 2118 | 10 | 8 | 16952 | |
| 44 | PX SEND BROADCAST | :TQ10000 | 2118 | 10 | 8 | 16952 | |
| 45 | PX BLOCK ITERATOR | | 2118 | 10 | 8 | 2119 | |
| 46 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2118 | 10 | 183 | 2119 | |
| 47 | HASH JOIN | | 98M | 96911 | 8 | 98M | 0.99 |
| 48 | PX RECEIVE | | 658 | 2 | 8 | 5264 | |
| 49 | PX SEND BROADCAST | :TQ10001 | 658 | 2 | 8 | 5264 | |
| 50 | PX BLOCK ITERATOR | | 658 | 2 | 8 | 658 | |
| 51 | TABLE ACCESS STORAGE FULL| DWR_DIM_REGION_RC_D | 658 | 2 | 27 | 658 | |
| 52 | PX BLOCK ITERATOR | | 98M | 96879 | 8 | 98M | |
| 53 | TABLE ACCESS STORAGE FULL | DWR_FIN_GROUP_JE_ALL_F | 98M | 96879 | 464 | 98M | 1.88 |
==================================================================================================================================
以上的执行计划,因为最后是Done(Error)状态,所以最后的Activity一列是不准的。大部分的耗时,都是在最后的HASH JOIN BUFFERED和PX SEND PARTITION (KEY)。
因为并行分发方式是PX SEND PARTITION (KEY),但是实际上数据只插入到一个分区(P201312),所以造成最后只有一个Slave在做事,其他Slave都空闲的场景。看一下并行Session的执行情况:
Parallel Execution Details (DOP=8 , Servers Allocated=16)
=============================================================================================================
| Name | Type | Server# | Elapsed | Cpu | IO || Buffer | Read | Read | Write | Write |
| | | | Time(s) | Time(s) | Waits(s) || Gets | Reqs | Bytes | Reqs | Bytes |
=============================================================================================================
| PX Coordinator | QC | | 0.37 | 0.19 | 0.00 || 1606 | 24 | 384KB | | . |
| p000 | Set 1 | 1 | 179 | 88 | 91 || 16690 | 43918 | 6GB | 43490 | 6GB |
| p001 | Set 1 | 2 | 181 | 89 | 92 || 16802 | 44300 | 6GB | 43512 | 6GB |
| p002 | Set 1 | 3 | 180 | 89 | 92 || 17515 | 44318 | 6GB | 43494 | 6GB |
| p003 | Set 1 | 4 | 181 | 88 | 93 || 15718 | 43876 | 6GB | 43496 | 6GB |
| p004 | Set 1 | 5 | 3854 | 2145 | 1404 || 14M | 44357 | 6GB | 890K | 212GB |
| p005 | Set 1 | 6 | 180 | 88 | 92 || 16836 | 44303 | 6GB | 43509 | 6GB |
| p006 | Set 1 | 7 | 181 | 89 | 92 || 16771 | 44686 | 6GB | 43894 | 6GB |
| p007 | Set 1 | 8 | 181 | 89 | 92 || 16683 | 44378 | 6GB | 43898 | 6GB |
| p008 | Set 2 | 1 | 684 | 679 | 5.38 || 285K | 51770 | 8GB | 36786 | 4GB |
| p009 | Set 2 | 2 | 686 | 680 | 5.24 || 281K | 51560 | 8GB | 36793 | 4GB |
| p010 | Set 2 | 3 | 682 | 678 | 4.11 || 298K | 52382 | 8GB | 36794 | 4GB |
| p011 | Set 2 | 4 | 683 | 679 | 4.15 || 316K | 53246 | 9GB | 36787 | 4GB |
| p012 | Set 2 | 5 | 683 | 679 | 4.04 || 305K | 52976 | 9GB | 36812 | 4GB |
| p013 | Set 2 | 6 | 683 | 679 | 3.73 || 280K | 51573 | 8GB | 36813 | 4GB |
| p014 | Set 2 | 7 | 685 | 681 | 4.05 || 309K | 53047 | 9GB | 36820 | 4GB |
| p015 | Set 2 | 8 | 688 | 684 | 4.64 || 314K | 53055 | 8GB | 36801 | 4GB |
=============================================================================================================
绝大部分的工作都交给了p004,该Session耗时3854s,写入212G数据。而其他Session,写入数据均不超过6G。
为了解决这个问题,我们可以在Insert的时候带上分区名,将原来的:
INSERT /*+ append parallel(8)*/
INTO DWRFIN.DWR_GRP_JE_RPT_ITEM_PUBLIC_V T
改为:
INSERT /*+ append parallel(8)*/
INTO DWRFIN.DWR_GRP_JE_RPT_ITEM_PUBLIC_V PARTITION(P201312) T
修改后的SQL(sql_id=46hg4059pjw9n),运行986s即可完成,执行计划如下:
SQL Plan Monitoring Details (Plan Hash Value=783773654)
===================================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | | (Estim) | | | (Actual) | (%) |
===================================================================================================================================
| 0 | INSERT STATEMENT | | | | 17 | 8 | 0.08 |
| 1 | PX COORDINATOR | | | | 17 | 8 | |
| 2 | PX SEND QC (RANDOM) | :TQ10010 | 304M | 445K | 8 | 8 | |
| 3 | LOAD AS SELECT | | | | 8 | 16 | 70.15 |
| 4 | HASH JOIN | | 304M | 445K | 8 | 577M | 0.91 |
| 5 | PX RECEIVE | | 8236 | 2 | 8 | 65888 | |
| 6 | PX SEND BROADCAST | :TQ10007 | 8236 | 2 | 8 | 65888 | |
| 7 | PX BLOCK ITERATOR | | 8236 | 2 | 8 | 8236 | |
| 8 | TABLE ACCESS STORAGE FULL | BIF_RPT_ITEM_P_C_REL | 8236 | 2 | 24 | 8236 | |
| 9 | HASH JOIN RIGHT OUTER | | 82M | 444K | 8 | 82M | 1.01 |
| 10 | PX RECEIVE | | 24M | 6578 | 8 | 25M | |
| 11 | PX SEND HASH | :TQ10008 | 24M | 6578 | 8 | 25M | 0.05 |
| 12 | PX BLOCK ITERATOR | | 24M | 6578 | 8 | 25M | |
| 13 | TABLE ACCESS STORAGE FULL | DWR_GRP_JE_RCM | 24M | 6578 | 99 | 25M | 0.01 |
| 14 | PX RECEIVE | | 82M | 438K | 8 | 82M | 1.55 |
| 15 | PX SEND HASH | :TQ10009 | 82M | 438K | 8 | 82M | 1.70 |
| 16 | HASH JOIN BUFFERED | | 82M | 438K | 8 | 82M | 6.40 |
| 17 | PX RECEIVE | | 6872 | 26 | 8 | 54976 | |
| 18 | PX SEND BROADCAST | :TQ10002 | 6872 | 26 | 8 | 54976 | |
| 19 | PX BLOCK ITERATOR | | 6872 | 26 | 8 | 6872 | |
| 20 | TABLE ACCESS STORAGE FULL | DWR_DIM_GRP_ACCT_CODE_D | 6872 | 26 | 98 | 6872 | |
| 21 | HASH JOIN RIGHT OUTER | | 82M | 438K | 8 | 82M | 0.42 |
| 22 | PX RECEIVE | | 884 | 13 | 8 | 9160 | |
| 23 | PX SEND BROADCAST | :TQ10003 | 884 | 13 | 8 | 9160 | |
| 24 | PX BLOCK ITERATOR | | 884 | 13 | 8 | 1145 | |
| 25 | TABLE ACCESS STORAGE FULL | MCA_BLENDED_EXCHANGE_RATE_T | 884 | 13 | 90 | 1145 | |
| 26 | HASH JOIN RIGHT OUTER | | 82M | 438K | 8 | 82M | 0.32 |
| 27 | PX RECEIVE | | 160 | 94 | 8 | 1312 | |
| 28 | PX SEND BROADCAST | :TQ10004 | 160 | 94 | 8 | 1312 | |
| 29 | PX BLOCK ITERATOR | | 160 | 94 | 8 | 164 | |
| 30 | TABLE ACCESS STORAGE FULL | MCA_PERIOD_RATE_T | 160 | 94 | 91 | 164 | |
| 31 | HASH JOIN | | 82M | 438K | 8 | 82M | 13.91 |
| 32 | PX RECEIVE | | 82M | 24487 | 8 | 82M | 0.01 |
| 33 | PX SEND HASH | :TQ10005 | 82M | 24487 | 8 | 82M | 0.08 |
| 34 | PX BLOCK ITERATOR | | 82M | 24487 | 8 | 82M | |
| 35 | TABLE ACCESS STORAGE FULL | BIF_RPT_ITEM_PL_PUB_T | 82M | 24487 | 354 | 82M | 0.12 |
| 36 | PX RECEIVE | | 98M | 96951 | 8 | 98M | 0.58 |
| 37 | PX SEND HASH | :TQ10006 | 98M | 96951 | 8 | 98M | 1.13 |
| 38 | VIEW | | 98M | 96951 | 8 | 98M | 0.08 |
| 39 | HASH JOIN | | 98M | 96951 | 8 | 98M | 0.34 |
| 40 | PX RECEIVE | | 2118 | 10 | 8 | 16952 | |
| 41 | PX SEND BROADCAST | :TQ10000 | 2118 | 10 | 8 | 16952 | |
| 42 | PX BLOCK ITERATOR | | 2118 | 10 | 8 | 2119 | |
| 43 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2118 | 10 | 183 | 2119 | |
| 44 | HASH JOIN | | 98M | 96911 | 8 | 98M | 0.37 |
| 45 | PX RECEIVE | | 658 | 2 | 8 | 5264 | |
| 46 | PX SEND BROADCAST | :TQ10001 | 658 | 2 | 8 | 5264 | |
| 47 | PX BLOCK ITERATOR | | 658 | 2 | 8 | 658 | |
| 48 | TABLE ACCESS STORAGE FULL | DWR_DIM_REGION_RC_D | 658 | 2 | 27 | 658 | 0.01 |
| 49 | PX BLOCK ITERATOR | | 98M | 96879 | 8 | 98M | |
| 50 | TABLE ACCESS STORAGE FULL | DWR_FIN_GROUP_JE_ALL_F | 98M | 96879 | 464 | 98M | 0.74 |
===================================================================================================================================
再看一下并行Session的执行情况:
Parallel Execution Details (DOP=8 , Servers Allocated=16)
============================================================================================================
| Name | Type | Server# | Elapsed | Cpu | IO | Buffer | Read | Read | Write | Write |
| | | | Time(s) | Time(s) | Waits(s) | Gets | Reqs | Bytes | Reqs | Bytes |
============================================================================================================
| PX Coordinator | QC | | 0.15 | 0.09 | 0.02 | 154 | 4 | 112KB | | . |
| p000 | Set 1 | 1 | 735 | 602 | 126 | 2M | 15596 | 4GB | 24582 | 24GB |
| p001 | Set 1 | 2 | 739 | 606 | 125 | 2M | 16207 | 5GB | 24582 | 24GB |
| p002 | Set 1 | 3 | 732 | 603 | 122 | 2M | 16128 | 5GB | 24569 | 24GB |
| p003 | Set 1 | 4 | 736 | 602 | 126 | 2M | 16180 | 4GB | 24590 | 24GB |
| p004 | Set 1 | 5 | 737 | 607 | 123 | 2M | 15241 | 4GB | 24619 | 24GB |
| p005 | Set 1 | 6 | 733 | 602 | 124 | 2M | 14982 | 4GB | 24614 | 24GB |
| p006 | Set 1 | 7 | 738 | 605 | 124 | 2M | 15511 | 4GB | 24607 | 24GB |
| p007 | Set 1 | 8 | 736 | 602 | 127 | 2M | 15800 | 4GB | 24581 | 24GB |
| p008 | Set 2 | 1 | 232 | 96 | 136 | 16673 | 44279 | 6GB | 43490 | 6GB |
| p009 | Set 2 | 2 | 219 | 96 | 123 | 17317 | 44331 | 6GB | 43511 | 6GB |
| p010 | Set 2 | 3 | 222 | 96 | 126 | 16926 | 44294 | 6GB | 43494 | 6GB |
| p011 | Set 2 | 4 | 223 | 96 | 127 | 16803 | 44291 | 6GB | 43496 | 6GB |
| p012 | Set 2 | 5 | 233 | 96 | 137 | 16736 | 44291 | 6GB | 43499 | 6GB |
| p013 | Set 2 | 6 | 222 | 96 | 126 | 16659 | 44298 | 6GB | 43509 | 6GB |
| p014 | Set 2 | 7 | 225 | 96 | 129 | 16943 | 44695 | 6GB | 43894 | 6GB |
| p015 | Set 2 | 8 | 225 | 96 | 129 | 16917 | 44698 | 6GB | 43898 | 6GB |
============================================================================================================
8个Slave Session工作量分布相当平均,每个Session写入24G数据。
解决方案:
建议在对单个分区并行插入大量数据时,指定分区名称,以免并行进程分发不均衡。
2.6.3 没有启用PDML导致插入时并行不生效
问题描述:
环境:FU4 EDW环境
程序:CNBG_MCA数据送DWR
时间:2014-03-06
用下面语句查日志,可以看到往MCA_JOURNAL_TO_DW_O_PUB_T表插入46464329行数据时,花费了23分钟。正常应该是5到8分钟。
可以请DBA同事看看当时的trace,是否有锁等待或数据库物理问题。
SELECT DML_TYPE || ' ' || S1.DML_ROW_COUNT || ' ROWS' AS 影响数据行,
SUBSTR((S1.STEP_END_TIME - S1.STEP_START_TIME), 12, 2) AS HOUR,
SUBSTR((S1.STEP_END_TIME - S1.STEP_START_TIME), 15, 2) AS MINUTE,
SUBSTR((S1.STEP_END_TIME - S1.STEP_START_TIME), 18, 2) AS SECOND,
SUBSTR((S1.STEP_END_TIME - S1.STEP_START_TIME), 21, 6) AS MICROSECOND,
S1.SQL_TEXT,
REPLACE(S1.LOG_MESSAGE,'MCA_ALLOCATION_PKG.MCA_ALLOC_',''),
S1.DATA_COMPONENT_NAME,
S1.STEP_START_TIME,
S1.STEP_END_TIME,
S1.CYCLE_ID,
S1.STEP_TYPE,
S1.Process_Component_Id
FROM FND_PROCESS_STEP_LOG S1
WHERE S1.LOG_MESSAGE LIKE '%mca2->o2%'
AND S1.STEP_START_TIME >=TO_TIMESTAMP('2014-03-01 00:00:00.000', 'syyyy-mm-dd HH24:mi:ss.ff2')
AND S1.STEP_START_TIME <=TO_TIMESTAMP('2014-03-05 23:59:59.000', 'syyyy-mm-dd HH24:mi:ss.ff2')
ORDER BY STEP_END_TIME
抓到的问题SQL如下(sql_id=8m0srmwuks568):
INSERT INTO MCA_JOURNAL_TO_DW_O_PUB_T
(PERIOD_ID,
UCCID,
HIERARCHY_CODE,
DATA_SOURCE_TABLE_ID,
REPORT_ITEM_ID,
GRP_ACCOUNT_ENTRY_ID,
JE_SOURCE_ID,
JE_CATEGORY_ID,
DATA_CATEGORY_ID,
GROUP_ACCOUNT_CODE,
SUB_ACCOUNT_CODE,
COMPANY_KEY,
BUY_FROM_IC_KEY,
IC_KEY,
DEPT_KEY,
GEO_PC_KEY,
COA_BU_KEY,
MAJOR_PROD_KEY,
MINOR_PROD_KEY,
BAS_SALES_TEAM_KEY,
END_CUST_KEY,
SIGN_CUST_KEY,
AGENT_DISTRIBUTION_CUST_KEY,
ACCOUNT_DEPT_CUST_KEY,
ENTERPRISE_CUST_KEY,
BU_KEY,
CONTRACT_KEY,
PROJ_KEY,
SUBPROJ_KEY,
SALES_MODE_KEY,
COUNTER_SIGN_CONTRACT_KEY,
RCM_KEY,
TC_CODE,
LC_CODE,
TC_DR_AMT,
TC_CR_AMT,
LC_DR_AMT,
LC_CR_AMT,
RMB_FACT_EX_RATE_DR_AMT,
RMB_FACT_EX_RATE_CR_AMT,
RMB_BUDGET_EX_RATE_DR_AMT,
RMB_BUDGET_EX_RATE_CR_AMT,
USD_FACT_EX_RATE_DR_AMT,
USD_FACT_EX_RATE_CR_AMT,
USD_BUDGET_EX_RATE_DR_AMT,
USD_BUDGET_EX_RATE_CR_AMT,
TC_PTD_AMT,
LC_PTD_AMT,
RMB_FACT_EX_RATE_PTD_AMT,
RMB_BUDGET_EX_RATE_PTD_AMT,
USD_FACT_EX_RATE_PTD_AMT,
USD_BUDGET_EX_RATE_PTD_AMT,
UPD_JOB_INSTANCE_ID,
CRT_JOB_INSTANCE_ID,
LAST_UPD_CYCLE_ID,
CRT_CYCLE_ID,
DEL_FLAG,
CREATION_DATE,
SCHEDULE_TYPE_ID,
VOUCHER_ID,
LINE_NO)
SELECT /*+ PARALLEL(8) */
J.PERIOD,
J.UCCID,
J.HIERARCHY_CODE,
J.DATA_SOURCE_TABLE_ID,
J.REPORT_ITEM_ID,
DWRFIN.DWR_FIN_GROUP_JE_ALL_F_S.NEXTVAL,
J.JE_SOURCE_ID,
J.JE_CATEGORY_ID,
CASE
WHEN C.CODE IS NOT NULL AND D.CODE IS NOT NULL THEN
:B5
ELSE
J.DATA_CATEGORY_ID
END AS DATA_CATEGORY_ID,
J.GROUP_ACCOUNT_CODE,
J.SUB_ACCOUNT_CODE,
J.COMPANY_KEY,
J.BUY_FROM_IC_KEY,
J.SELL_TO_IC_KEY,
J.DEPT_KEY,
J.GEO_PC_KEY,
NVL(J.COA_BU_KEY, -999999),
J.MAJOR_PROD_KEY,
J.MINOR_PROD_KEY,
J.BAS_SALES_TEAM_KEY,
J.END_CUST_KEY,
J.SIGN_CUST_KEY,
J.AGENT_DISTRIBUTION_CUST_KEY,
J.ACCOUNT_DEPT_CUST_KEY,
J.ENTERPRISE_CUST_KEY,
J.BU_KEY,
J.CONTRACT_KEY,
J.PROJ_KEY,
J.SUBPROJ_KEY,
J.SALES_MODE_KEY,
J.COUNTER_SIGN_CONTRACT_KEY,
J.RCM_KEY,
J.TRANSACTION_CURRENCY,
J.LOCAL_CURRENCY,
NVL(J.DR_TC, 0),
NVL(J.CR_TC, 0),
NVL(J.DR_LC, 0),
NVL(J.CR_LC, 0),
NVL(J.DR_RMB_AAA, 0),
NVL(J.CR_RMB_AAA, 0),
NVL(J.RMB_BUDGET_EX_RATE_DR_AMT, 0),
NVL(J.RMB_BUDGET_EX_RATE_CR_AMT, 0),
NVL(J.USD_FACT_EX_RATE_DR_AMT, 0),
NVL(J.USD_FACT_EX_RATE_CR_AMT, 0),
NVL(J.USD_BUDGET_EX_RATE_DR_AMT, 0),
NVL(J.USD_BUDGET_EX_RATE_CR_AMT, 0),
CASE
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE <> '56212' THEN
NVL(J.DR_TC, 0) - NVL(J.CR_TC, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE = '56212' THEN
NVL(J.CR_TC, 0) - NVL(J.DR_TC, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('收入', '负债', '权益') THEN
NVL(J.CR_TC, 0) - NVL(J.DR_TC, 0)
END AS TC_PTD_AMT,
CASE
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE <> '56212' THEN
NVL(J.DR_LC, 0) - NVL(J.CR_LC, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE = '56212' THEN
NVL(J.CR_LC, 0) - NVL(J.DR_LC, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('收入', '负债', '权益') THEN
NVL(J.CR_LC, 0) - NVL(J.DR_LC, 0)
END AS LC_PTD_AMT,
CASE
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE <> '56212' THEN
NVL(J.DR_RMB_AAA, 0) - NVL(J.CR_RMB_AAA, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE = '56212' THEN
NVL(J.CR_RMB_AAA, 0) - NVL(J.DR_RMB_AAA, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('收入', '负债', '权益') THEN
NVL(J.CR_RMB_AAA, 0) - NVL(J.DR_RMB_AAA, 0)
END AS RMB_FACT_EX_RATE_PTD_AMT,
CASE
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE <> '56212' THEN
NVL(J.RMB_BUDGET_EX_RATE_DR_AMT, 0) -
NVL(J.RMB_BUDGET_EX_RATE_CR_AMT, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE = '56212' THEN
NVL(J.RMB_BUDGET_EX_RATE_CR_AMT, 0) -
NVL(J.RMB_BUDGET_EX_RATE_DR_AMT, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('收入', '负债', '权益') THEN
NVL(J.RMB_BUDGET_EX_RATE_CR_AMT, 0) -
NVL(J.RMB_BUDGET_EX_RATE_DR_AMT, 0)
END AS RMB_BUDGET_EX_RATE_PTD_AMT,
CASE
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE <> '56212' THEN
NVL(J.USD_FACT_EX_RATE_DR_AMT, 0) - NVL(J.USD_FACT_EX_RATE_CR_AMT, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE = '56212' THEN
NVL(J.USD_FACT_EX_RATE_CR_AMT, 0) - NVL(J.USD_FACT_EX_RATE_DR_AMT, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('收入', '负债', '权益') THEN
NVL(J.USD_FACT_EX_RATE_CR_AMT, 0) - NVL(J.USD_FACT_EX_RATE_DR_AMT, 0)
END AS USD_FACT_EX_RATE_PTD_AMT,
CASE
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE <> '56212' THEN
NVL(J.USD_BUDGET_EX_RATE_DR_AMT, 0) -
NVL(J.USD_BUDGET_EX_RATE_CR_AMT, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('费用', '资产') AND
A.LVL2_ACCOUNT_CODE = '56212' THEN
NVL(J.USD_BUDGET_EX_RATE_CR_AMT, 0) -
NVL(J.USD_BUDGET_EX_RATE_DR_AMT, 0)
WHEN A.ACCOUNT_TYPE_CN_NAME IN ('收入', '负债', '权益') THEN
NVL(J.USD_BUDGET_EX_RATE_CR_AMT, 0) -
NVL(J.USD_BUDGET_EX_RATE_DR_AMT, 0)
END AS USD_BUDGET_EX_RATE_PTD_AMT,
:B4,
:B4,
:B3,
:B3,
NVL(J.DEL_FLAG, 'N'),
SYSDATE,
J.SCHEDULE_TYPE_ID,
J.VOUCHER_ID,
J.LINE_NO
FROM MCA_JOURNALS_PUB_T J,
DWR_DIM_GRP_ACCT_CODE_D A,
DWR_DIM_JOURNAL_CATEGORY_D B,
DWR_DIM_DATA_CATEGORY_D F,
BIF_MD_CLASS_T C,
BIF_MD_CLASS_T D
WHERE J.PERIOD = :B2
AND J.HIERARCHY_CODE = :B1
AND J.GROUP_ACCOUNT_CODE = A.GROUP_ACCOUNT_CODE
AND J.JE_CATEGORY_ID = B.JE_CATEGORY_ID
AND B.JE_CATEGORY_CODE = C.CODE(+)
AND C.CLASS_TYPE_CODE(+) = 'MCA_INTERFACE_JE_CATEGORY_FAIR'
AND C.STATUS(+) = 1
AND J.DATA_CATEGORY_ID = F.DATA_CATEGORY_ID
AND F.DATA_CATEGORY_CODE = D.CODE(+)
AND D.CLASS_TYPE_CODE(+) = 'MCA_INTERFACE_DC_FAIR'
AND D.STATUS(+) = 1
AND NOT
(J.DR_TC = 0 AND J.CR_TC = 0 AND J.DR_LC = 0 AND J.CR_LC = 0 AND
J.RMB_BUDGET_EX_RATE_DR_AMT = 0 AND
J.RMB_BUDGET_EX_RATE_CR_AMT = 0 AND J.USD_FACT_EX_RATE_DR_AMT = 0 AND
J.USD_FACT_EX_RATE_CR_AMT = 0 AND J.USD_BUDGET_EX_RATE_DR_AMT = 0 AND
J.USD_BUDGET_EX_RATE_CR_AMT = 0 AND J.DR_RMB_AAA = 0 AND
J.CR_RMB_AAA = 0)
AND J.SCHEDULE_TYPE_ID NOT IN (3, 7201, 7202, 7203, 7204)
问题分析:
了解到,该程序最近做过变更,后面的几张表都是新加上去的。
SQL的执行计划如下:
Parallel Execution Details (DOP=8 , Servers Allocated=16)
==================================================================================================================
| Name | Type | Server# | Elapsed | Cpu | IO |Buffer | Read | Read | Wait Events |
| | | | Time(s) | Time(s) | Waits(s) | Gets | Reqs | Bytes | (sample #) |
==================================================================================================================
| PX Coordinator | QC | | 1129 | 1127 | | 10M | | . | os thread startup (1) |
| | | | | | | | | | row cache lock (1) |
| p064 | Set 1 | 1 | 21 | 19 | 1.65 | 156K | 2442 | 2GB | direct path read (2) |
| p065 | Set 1 | 2 | 22 | 20 | 2.33 | 171K | 2670 | 3GB | direct path read (3) |
| p066 | Set 1 | 3 | 21 | 20 | 0.69 | 162K | 2538 | 2GB | direct path read (1) |
| p067 | Set 1 | 4 | 21 | 19 | 1.23 | 158K | 2476 | 2GB | direct path read (3) |
| p068 | Set 1 | 5 | 21 | 20 | 0.76 | 165K | 2576 | 3GB | direct path read (1) |
| p069 | Set 1 | 6 | 21 | 20 | 1.28 | 164K | 2565 | 2GB | direct path read (1) |
| p070 | Set 1 | 7 | 22 | 20 | 1.40 | 173K | 2706 | 3GB | direct path read (1) |
| p071 | Set 1 | 8 | 21 | 20 | 1.46 | 164K | 2568 | 3GB | direct path read (2) |
| p160 | Set 2 | 1 | 0.19 | 0.06 | 0.11 | 778 | 34 | 7MB | |
| p161 | Set 2 | 2 | 0.19 | 0.05 | 0.12 | 668 | 39 | 6MB | |
| p162 | Set 2 | 3 | 0.18 | 0.05 | 0.11 | 623 | 30 | 6MB | |
| p163 | Set 2 | 4 | 0.19 | 0.05 | 0.12 | 600 | 39 | 5MB | |
| p164 | Set 2 | 5 | 0.20 | 0.05 | 0.12 | 634 | 34 | 6MB | |
| p165 | Set 2 | 6 | 0.19 | 0.05 | 0.12 | 594 | 33 | 6MB | |
| p166 | Set 2 | 7 | 0.19 | 0.06 | 0.11 | 790 | 34 | 8MB | |
| p167 | Set 2 | 8 | 0.18 | 0.05 | 0.11 | 550 | 37 | 5MB | |
==================================================================================================================
SQL Plan Monitoring Details (Plan Hash Value=2459263409)
============================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | | (Estim) | | | (Actual) | (%) |
============================================================================================================================
| 0 | INSERT STATEMENT | | | | 1 | 0 | 0.08 |
| 1 | LOAD TABLE CONVENTIONAL | | | | 1 | 0 | 34.56 |
| 2 | SEQUENCE | DWR_FIN_GROUP_JE_ALL_F_S | | | 1 | 46M | 46.83 |
| 3 | PX COORDINATOR | | | | 17 | 46M | 7.30 |
| 4 | PX SEND QC (RANDOM) | :TQ10004 | 41M | 53448 | 8 | 46M | 3.05 |
| 5 | HASH JOIN | | 41M | 53448 | 8 | 46M | 1.76 |
| 6 | PX RECEIVE | | 6970 | 20 | 8 | 55768 | |
| 7 | PX SEND BROADCAST | :TQ10000 | 6970 | 20 | 8 | 55768 | |
| 8 | PX BLOCK ITERATOR | | 6970 | 20 | 8 | 6971 | |
| 9 | TABLE ACCESS FULL | DWR_DIM_GRP_ACCT_CODE_D | 6970 | 20 | 86 | 6971 | |
| 10 | HASH JOIN RIGHT OUTER | | 41M | 53415 | 8 | 46M | 0.72 |
| 11 | PX RECEIVE | | 102 | 157 | 8 | 128 | |
| 12 | PX SEND BROADCAST | :TQ10001 | 102 | 157 | 8 | 128 | |
| 13 | PX BLOCK ITERATOR | | 102 | 157 | 8 | 16 | |
| 14 | TABLE ACCESS FULL | BIF_MD_CLASS_T | 102 | 157 | 107 | 16 | |
| 15 | HASH JOIN | | 41M | 53245 | 8 | 46M | 0.96 |
| 16 | PX RECEIVE | | 3141 | 7 | 8 | 25520 | |
| 17 | PX SEND BROADCAST | :TQ10002 | 3141 | 7 | 8 | 25520 | |
| 18 | PX BLOCK ITERATOR | | 3141 | 7 | 8 | 3190 | |
| 19 | TABLE ACCESS FULL | DWR_DIM_JOURNAL_CATEGORY_D | 3141 | 7 | 121 | 3190 | |
| 20 | HASH JOIN | | 41M | 53225 | 8 | 46M | 0.96 |
| 21 | PX RECEIVE | | 59 | 27 | 8 | 472 | |
| 22 | PX SEND BROADCAST | :TQ10003 | 59 | 27 | 8 | 472 | |
| 23 | NESTED LOOPS OUTER | | 59 | 27 | 8 | 59 | |
| 24 | PX BLOCK ITERATOR | | | | 8 | 59 | |
| 25 | TABLE ACCESS FULL | DWR_DIM_DATA_CATEGORY_D | 59 | 2 | 5 | 59 | |
| 26 | TABLE ACCESS BY INDEX ROWID | BIF_MD_CLASS_T | 1 | | 59 | 7 | |
| 27 | INDEX RANGE SCAN | BIF_MD_CLASS_T_U2 | 1 | | 59 | 62 | |
| 28 | PX BLOCK ITERATOR | | 41M | 53186 | 8 | 46M | |
| 29 | TABLE ACCESS FULL | MCA_JOURNALS_PUB_T | 41M | 53186 | 365 | 46M | 3.69 |
============================================================================================================================
可以看到,大部分时间都消耗在QC上,Slave Session基本上没有做事。出现这个情况是因为没有启用DML并行,只有Select部分有并行。以Serial方式插入4600万数据,耗费20多分钟属于正常。
启用DML并行后,运行193秒完成,执行计划如下:
Parallel Execution Details (DOP=8 , Servers Allocated=16)
================================================================================================================
| Name | Type | Server# | Elapsed | Cpu | IO |Buffer | Wait Events |
| | | | Time(s) | Time(s) | Waits(s) | Gets | (sample #) |
================================================================================================================
| PX Coordinator | QC | | 0.13 | 0.04 | | 181 | |
| p008 | Set 1 | 1 | 0.02 | 0.02 | | 705 | |
| p009 | Set 1 | 2 | 0.02 | 0.02 | | 629 | |
| p010 | Set 1 | 3 | 0.02 | 0.02 | | 715 | |
| p011 | Set 1 | 4 | 0.03 | 0.03 | 0.00 | 727 | enq: FB - contention (1) |
| p012 | Set 1 | 5 | 0.02 | 0.02 | | 670 | |
| p013 | Set 1 | 6 | 0.02 | 0.02 | | 585 | |
| p014 | Set 1 | 7 | 0.02 | 0.02 | | 646 | |
| p015 | Set 1 | 8 | 192 | 159 | 34 | 1M | gc current multi block request (1) |
| p016 | Set 2 | 1 | 41 | 40 | 0.94 | 172K | direct path read (1) |
| p017 | Set 2 | 2 | 41 | 40 | 0.84 | 169K | |
| p018 | Set 2 | 3 | 42 | 41 | 0.81 | 170K | direct path read (2) |
| p019 | Set 2 | 4 | 42 | 41 | 0.44 | 164K | direct path read (1) |
| p020 | Set 2 | 5 | 40 | 39 | 0.83 | 168K | direct path read (1) |
| p021 | Set 2 | 6 | 39 | 39 | 0.67 | 159K | direct path read (2) |
| p022 | Set 2 | 7 | 39 | 38 | 0.98 | 168K | direct path read (1) |
| p023 | Set 2 | 8 | 40 | 39 | 0.88 | 167K | |
================================================================================================================
SQL Plan Monitoring Details (Plan Hash Value=3331367624)
========================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity|
| | | | (Estim) | | |(Actual) | (%) |
========================================================================================================================
| 0 |INSERT STATEMENT | | | | 17 | 2 | |
| 1 | PX COORDINATOR | | | | 17 | 2 | |
| 2 | PX SEND QC (RANDOM) | :TQ10005 | 41M | 53448 | 8 | 2 | |
| 3 | LOAD AS SELECT | | | | 8 | 2 | 32.92 |
| 4 | PX RECEIVE | | 41M | 53448 | 8 | 46M | 6.42 |
| 5 | PX SEND PARTITION (KEY) | :TQ10004 | 41M | 53448 | 8 | 46M | 38.10 |
| 6 | SEQUENCE | DWR_FIN_GROUP_JE_ALL_F_S | | | 8 | 46M | 3.31 |
| 7 | HASH JOIN | | 41M | 53448 | 8 | 46M | 3.11 |
| 8 | PX RECEIVE | | 6970 | 20 | 8 | 55768 | |
| 9 | PX SEND BROADCAST | :TQ10000 | 6970 | 20 | 8 | 55768 | |
| 10 | PX BLOCK ITERATOR | | 6970 | 20 | 8 | 6971 | |
| 11 | TABLE ACCESS FULL | DWR_DIM_GRP_ACCT_CODE_D | 6970 | 20 | 86 | 6971 | |
| 12 | HASH JOIN RIGHT OUTER | | 41M | 53415 | 8 | 46M | 2.69 |
| 13 | PX RECEIVE | | 102 | 157 | 8 | 128 | |
| 14 | PX SEND BROADCAST | :TQ10001 | 102 | 157 | 8 | 128 | |
| 15 | PX BLOCK ITERATOR | | 102 | 157 | 8 | 16 | |
| 16 | TABLE ACCESS FULL | BIF_MD_CLASS_T | 102 | 157 | 107 | 16 | |
| 17 | HASH JOIN | | 41M | 53245 | 8 | 46M | 2.28 |
| 18 | PX RECEIVE | | 3141 | 7 | 8 | 25520 | |
| 19 | PX SEND BROADCAST | :TQ10002 | 3141 | 7 | 8 | 25520 | |
| 20 | PX BLOCK ITERATOR | | 3141 | 7 | 8 | 3190 | |
| 21 | TABLE ACCESS FULL | DWR_DIM_JOURNAL_CATEGORY_D| 3141 | 7 | 121 | 3190 | |
| 22 | HASH JOIN | | 41M | 53225 | 8 | 46M | 2.90 |
| 23 | PX RECEIVE | | 59 | 27 | 8 | 472 | |
| 24 | PX SEND BROADCAST | :TQ10003 | 59 | 27 | 8 | 472 | |
| 25 | NESTED LOOPS OUTER | | 59 | 27 | 8 | 59 | |
| 26 | PX BLOCK ITERATOR | | | | 8 | 59 | |
| 27 | TABLE ACCESS FULL | DWR_DIM_DATA_CATEGORY_D | 59 | 2 | 5 | 59 | |
| 28 | TABLE ACCESS BY INDEX ROWID| BIF_MD_CLASS_T | 1 | | 59 | 7 | |
| 29 | INDEX RANGE SCAN | BIF_MD_CLASS_T_U2 | 1 | | 59 | 62 | |
| 30 | PX BLOCK ITERATOR | | 41M | 53186 | 8 | 46M | |
| 31 | TABLE ACCESS FULL | MCA_JOURNALS_PUB_T | 41M | 53186 | 365 | 46M | 8.07 |
========================================================================================================================
速度明显加快,但是还是有一个Slave Session明显比其他的耗时多,也就是说还是有段时间只有一个Session在做事。这是因为目标表是分区表,如果不指定分区插入,就会给其他分区也分配Slave Session。但最后实际只插入到一个分区,也就只有一个Session真正做事了。
解决办法,是在表名后加分区名字,指定分区插入。比如,把:
INSERT INTO MCA_JOURNAL_TO_DW_O_PUB_T
改为:
INSERT INTO MCA_JOURNAL_TO_DW_O_PUB_T PARTITION(P201311)
在表名MCA_JOURNAL_TO_DW_O_PUB_T之后加上PARTITION(P201311),这一次只需要50秒即可完成。执行计划如下:
Parallel Execution Details (DOP=8 , Servers Allocated=16)
===========================================================================================================================
| Name | Type | Server# | Elapsed | Cpu | IO |Buffer | Read | Read | Wait Events |
| | | | Time(s) | Time(s) | Waits(s) | Gets | Reqs | Bytes | (sample #) |
===========================================================================================================================
| PX Coordinator | QC | | 0.08 | 0.04 | | 181 | | . | |
| p096 | Set 1 | 1 | 56 | 44 | 11 | 343K | 2681 | 3GB | enq: HV - contention (1) |
| p097 | Set 1 | 2 | 58 | 46 | 11 | 347K | 2604 | 3GB | row cache lock (1) |
| p098 | Set 1 | 3 | 53 | 43 | 10 | 322K | 2464 | 2GB | row cache lock (1) |
| p099 | Set 1 | 4 | 57 | 45 | 11 | 343K | 2584 | 3GB | enq: SQ - contention (1) |
| p100 | Set 1 | 5 | 57 | 45 | 11 | 343K | 2613 | 3GB | log file switch completion (1) |
| p101 | Set 1 | 6 | 56 | 45 | 11 | 336K | 2553 | 2GB | log file switch completion (1) |
| p102 | Set 1 | 7 | 55 | 43 | 11 | 325K | 2442 | 2GB | log file switch completion (1) |
| p103 | Set 1 | 8 | 55 | 44 | 11 | 337K | 2600 | 3GB | log file switch completion (1) |
| p104 | Set 2 | 1 | 0.04 | 0.01 | 0.02 | 757 | 18 | 768KB | |
| p105 | Set 2 | 2 | 0.03 | 0.01 | 0.02 | 705 | 14 | 576KB | |
| p106 | Set 2 | 3 | 0.03 | 0.01 | 0.02 | 694 | 16 | 608KB | |
| p107 | Set 2 | 4 | 0.03 | 0.01 | 0.02 | 654 | 16 | 656KB | |
| p108 | Set 2 | 5 | 0.04 | 0.01 | 0.02 | 651 | 18 | 720KB | |
| p109 | Set 2 | 6 | 0.03 | 0.01 | 0.02 | 620 | 17 | 672KB | |
| p110 | Set 2 | 7 | 0.04 | 0.01 | 0.02 | 562 | 21 | 544KB | |
| p111 | Set 2 | 8 | 0.03 | 0.01 | 0.01 | 594 | 12 | 480KB | |
===========================================================================================================================
SQL Plan Monitoring Details (Plan Hash Value=3311608656)
============================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | | (Estim) | | | (Actual) | (%) |
============================================================================================================================
| 0 | INSERT STATEMENT | | | | 17 | 10 | |
| 1 | PX COORDINATOR | | | | 17 | 10 | |
| 2 | PX SEND QC (RANDOM) | :TQ10004 | 41M | 53448 | 8 | 10 | |
| 3 | LOAD AS SELECT | | | | 8 | 18 | 71.56 |
| 4 | SEQUENCE | DWR_FIN_GROUP_JE_ALL_F_S | | | 8 | 46M | 4.51 |
| 5 | HASH JOIN | | 41M | 53448 | 8 | 46M | 3.16 |
| 6 | PX RECEIVE | | 6970 | 20 | 8 | 55768 | |
| 7 | PX SEND BROADCAST | :TQ10000 | 6970 | 20 | 8 | 55768 | |
| 8 | PX BLOCK ITERATOR | | 6970 | 20 | 8 | 6971 | |
| 9 | TABLE ACCESS FULL | DWR_DIM_GRP_ACCT_CODE_D | 6970 | 20 | 86 | 6971 | |
| 10 | HASH JOIN RIGHT OUTER | | 41M | 53415 | 8 | 46M | 2.03 |
| 11 | PX RECEIVE | | 102 | 157 | 8 | 128 | |
| 12 | PX SEND BROADCAST | :TQ10001 | 102 | 157 | 8 | 128 | |
| 13 | PX BLOCK ITERATOR | | 102 | 157 | 8 | 16 | |
| 14 | TABLE ACCESS FULL | BIF_MD_CLASS_T | 102 | 157 | 107 | 16 | |
| 15 | HASH JOIN | | 41M | 53245 | 8 | 46M | 2.93 |
| 16 | PX RECEIVE | | 3141 | 7 | 8 | 25520 | |
| 17 | PX SEND BROADCAST | :TQ10002 | 3141 | 7 | 8 | 25520 | |
| 18 | PX BLOCK ITERATOR | | 3141 | 7 | 8 | 3190 | |
| 19 | TABLE ACCESS FULL | DWR_DIM_JOURNAL_CATEGORY_D | 3141 | 7 | 121 | 3190 | |
| 20 | HASH JOIN | | 41M | 53225 | 8 | 46M | 3.84 |
| 21 | PX RECEIVE | | 59 | 27 | 8 | 472 | |
| 22 | PX SEND BROADCAST | :TQ10003 | 59 | 27 | 8 | 472 | |
| 23 | NESTED LOOPS OUTER | | 59 | 27 | 8 | 59 | |
| 24 | PX BLOCK ITERATOR | | | | 8 | 59 | |
| 25 | TABLE ACCESS FULL | DWR_DIM_DATA_CATEGORY_D | 59 | 2 | 5 | 59 | |
| 26 | TABLE ACCESS BY INDEX ROWID | BIF_MD_CLASS_T | 1 | | 59 | 7 | |
| 27 | INDEX RANGE SCAN | BIF_MD_CLASS_T_U2 | 1 | | 59 | 62 | |
| 28 | PX BLOCK ITERATOR | | 41M | 53186 | 8 | 46M | |
| 29 | TABLE ACCESS FULL | MCA_JOURNALS_PUB_T | 41M | 53186 | 365 | 46M | 11.51 |
| | | | | | | | |
============================================================================================================================
这一次,每个Slave Session的CPU时间平均分布。
解决方案:
建议:
- 因为插入数据量大,建议启用DML并行。
- 插入时指定分区。
2.7 回滚Undo导致不走 Smart Scan
2.7.1 回滚Undo导致不走 Smart Scan
问题描述:
环境:生产环境
程序:补录程序DWR_SA_APD_CAUSE_PKG.DWR_SA_CAUSE_SERVICE_CLOSING_P
时间:2014-04-17
生产环境(exadata)涉及补录的程序DWR_SA_APD_CAUSE_PKG.DWR_SA_CAUSE_SERVICE_CLOSING_P;目前定时间隔一小时运行(这个机制不合理,我已经问过他们,会7月版本修改)。但性能在0.12分钟到10分钟之间波动很大(偶尔甚至到60~100分钟,这种我看多半发生在凌晨日增量调度,应该是调度冲突导致,暂不关注)
我提取了运行时的执行计划(附件sql1),发现维表扫描没有走smart scan,所以性能较差需要5~6分钟。我把那段查询语句拿出来带入变量运行也就10秒跑完,正常走smart scan(附件sql2)。
问题是调度程序使用的HWDW账号,设置了用户级的触发器的强制dreact path read,为何会出现这种状况?
看下面日志,0.0X分钟的应该都是走了smart scan,几分钟的应该是没有。总共就处理几千条数据
问题分析:
检查sql_id=55xb88zkucctw的运行历史:
发现执行计划一直都是不变的,PHV= 1411237955。但是执行时间变化相当大,有时是几秒钟,有时是几分钟,而凌晨1点到3点这段时间,经常会也需要运行100多分钟才能完成。
检查dba_hist_active_sess_history中的记录,发现运行几分钟的时候,等待事件基本上是cell multiblock physical read。而运行100多分钟的时候,等待事件基本上是cell single block physical read。两种情况均伴有少量的gc cr multi block request,运行几秒钟时,ASH中基本没有记录。自己代入变量之后运行脚本测试,也是几秒即可完成。查看SQL Monitor报告,走的都是cell smart table scan。
出现这种差异的原因,是因为语句引用到的维表,尤其是合同维,均安排在凌晨1点到3点进行刷新。因为刷新维表时间比较长,所以语句55xb88zkucctw需要不停地回滚Undo。如果只是少量维表刷新,则回滚Undo时可以cell multiblock physical read。如果同时有合同维等几个大维表或者很多维表同时刷新,则回滚Undo是往往是cell single block physical read。而平时不刷新维表时,不需要回滚Undo,走cell smart table scan,所以就很快。
解决方案:
错开调度补录程序和维表刷新程序,或者维表刷新期间暂停调度补录程序。
01oracle11g.xml
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<root title="root1">
<folder title="ORACLE 11g" expand="1" title-en="ORACLE 11g">
<SQLString title="检查超长事务" title-en="check_longtime_transaction" status="1" rela1="==" rela2="<=" rela3=">" value1="0" value2="10" value3="10" sql-show="select b.sid,b.SERIAL#,a.USED_UBLK, c.SAMPLE_TIME,c.sql_id, d.sql_text from v$transaction a, v$session b, v$active_session_history c, v$sqlarea d where a.ses_addr=b.saddr and b.SID=c.SESSION_ID and b.SERIAL#=c.SESSION_SERIAL# and c.SQL_ID=d.SQL_ID(+) and c.SAMPLE_TIME>systimestamp-5/1440 and a.START_TIME< to_Char((sysdate - 5/1440),'mm/dd/yy hh24:mi:ss') order by c.SAMPLE_TIME desc " description="" description-en="" chart-mode="-1">
select count(*) from v$transaction where start_time< to_Char((sysdate - 5/1440),'mm/dd/yy hh24:mi:ss')
</SQLString>
<SQLString title="没有绑定变量的SQL" title-en="SQL without bind" status="1" rela1="==" rela2="<" rela3=">=" value1="0" value2="50" value3="50" sql-show=" select PARSING_SCHEMA_NAME,substr(sql_text,1,80), count(*) from v$sqlarea group by PARSING_SCHEMA_NAME,substr(sql_text,1,80) having count(*)>50 order by count(*) desc" description="" description-en="" chart-mode="-1">
select count(*) from ( select substr(sql_text,1,80), count(*) from v$sqlarea group by substr(sql_text,1,80) having count(*)>200 order by count(*) desc )
</SQLString>
<SQLString title="检查最近半小时内的结果集超大的sql" title-en="check big result SQL" status="1" rela1="==" rela2="" rela3=">" value1="0" value2="" value3="0" sql-show="select a.sql_id,EXECUTIONS_DELTA, trunc(ROWS_PROCESSED_DELTA/EXECUTIONS_DELTA) result_count,b.sql_text from DBA_HIST_SQLSTAT a, v$sqlarea b where ROWS_PROCESSED_DELTA/EXECUTIONS_DELTA>1000 and EXECUTIONS_DELTA>0 and SNAP_ID>=(select max(snap_id) from DBA_HIST_SQLSTAT) and a.sql_id=b.sql_id" description="" description-en="" chart-mode="-1">
select count(*) from DBA_HIST_SQLSTAT where ROWS_PROCESSED_DELTA/EXECUTIONS_DELTA>1000 and EXECUTIONS_DELTA>0 and SNAP_ID>=(select max(snap_id) from DBA_HIST_SQLSTAT)
</SQLString>
<SQLString title="[AWR] 长时间行锁情况(>100s)" title-en="Check Row Locks" status="1" rela1="<" rela2="<=" rela3=">" value1="50" value2="100" value3="100" description="出现了[:0]行锁,请检查" description-en="There are [:0] row locks, please check it." sql-show="select V$SESSION.sid,v$session.SERIAL#, v$session.BLOCKING_SESSION,v$session.sql_id,v$session.PREV_SQL_ID, v$process.spid, rtrim(object_type) object_type,rtrim(owner) || '.' || object_name object_name, decode(lmode, 0, 'None', 1, 'Null', 2, 'Row-S', 3, 'Row-X', 4, 'Share', 5, 'S/Row-X', 6, 'Exclusive', 'Unknown') LockMode, decode(request, 0, 'None', 1, 'Null', 2, 'Row-S', 3, 'Row-X', 4, 'Share', 5, 'S/Row-X', 6, 'Exclusive', 'Unknown') RequestMode ,ctime, block b, v$session.username,MACHINE,MODULE,ACTION, decode(A.type, 'MR', 'Media Recovery', 'RT','Redo Thread', 'UN','User Name', 'TX', 'Transaction', 'TM', 'DML', 'UL', 'PL/SQL User Lock', 'DX', 'Distributed Xaction', 'CF', 'Control File', 'IS', 'Instance State', 'FS', 'File Set', 'IR', 'Instance Recovery', 'ST', 'Disk Space Transaction', 'TS', 'Temp Segment', 'IV', 'Library Cache Invalida-tion', 'LS', 'Log Start or Switch', 'RW', 'Row Wait', 'SQ', 'Sequence Number', 'TE', 'Extend Table', 'TT', 'Temp Table', 'Unknown') LockType from (SELECT * FROM V$LOCK) A, all_objects,V$SESSION,v$process where A.sid > 6 and object_name<>'OBJ$' and A.id1 = all_objects.object_id and A.sid=v$session.sid and v$process.addr=v$session.paddr and v$session.sid > 53 and rtrim(owner)<>'SYS' " chart-mode="-1">
with query1 as (select V$SESSION.sid,v$session.SERIAL#, v$session.BLOCKING_SESSION,v$session.sql_id,v$session.PREV_SQL_ID, v$process.spid, rtrim(object_type) object_type,rtrim(owner) || '.' || object_name object_name, decode(lmode, 0, 'None', 1, 'Null', 2, 'Row-S', 3, 'Row-X', 4, 'Share', 5, 'S/Row-X', 6, 'Exclusive', 'Unknown') LockMode, decode(request, 0, 'None', 1, 'Null', 2, 'Row-S', 3, 'Row-X', 4, 'Share', 5, 'S/Row-X', 6, 'Exclusive', 'Unknown') RequestMode ,ctime, block b, v$session.username,MACHINE,MODULE,ACTION, decode(A.type, 'MR', 'Media Recovery', 'RT','Redo Thread', 'UN','User Name', 'TX', 'Transaction', 'TM', 'DML', 'UL', 'PL/SQL User Lock', 'DX', 'Distributed Xaction', 'CF', 'Control File', 'IS', 'Instance State', 'FS', 'File Set', 'IR', 'Instance Recovery', 'ST', 'Disk Space Transaction', 'TS', 'Temp Segment', 'IV', 'Library Cache Invalida-tion', 'LS', 'Log Start or Switch', 'RW', 'Row Wait', 'SQ', 'Sequence Number', 'TE', 'Extend Table', 'TT', 'Temp Table', 'Unknown') LockType from (SELECT * FROM V$LOCK) A, all_objects,V$SESSION,v$process where A.sid > 6 and object_name<>'OBJ$' and A.id1 = all_objects.object_id and A.sid=v$session.sid and v$process.addr=v$session.paddr and v$session.sid > 53 and rtrim(owner)<>'SYS' ) select count(*) from query1 where username is not null and ctime>100
</SQLString>
<SQLString title="[AWR]db file sequential read耗时(ms)" title-en="DB File Sequential Read Average Time" status="1" rela1="<" rela2="<" rela3=">=" value1="10" value2="20" value3="20" description="当前平均等待时间为[:0]ms,请检查磁盘性能" description-en="DB file sequential read average wait time is [:0]">
with query1 as ( select * from (select b.TIME_WAITED_MICRO-a.TIME_WAITED_MICRO as TIME_WAITED_MICRO1,b.TOTAL_WAITS-a.TOTAL_WAITS as TOTAL_WAITS1,b.* from (select * from DBA_HIST_SYSTEM_EVENT where SNAP_ID=:snap_id-1)a, (select * from DBA_HIST_SYSTEM_EVENT where SNAP_ID=:snap_id)b where a.INSTANCE_NUMBER=b.INSTANCE_NUMBER and a.instance_number=(select userenv('instance') from dual ) and a.EVENT_NAME=b.EVENT_NAME and a.EVENT_NAME='db file sequential read' )aa ) select round(TIME_WAITED_MICRO1/TOTAL_WAITS1/1000),to_char(EVENT_NAME), TIME_WAITED_MICRO1, TOTAL_WAITS1 from query1 where TOTAL_WAITS1<>0 and rownum<6
</SQLString>
<SQLString title="[AWR]log file sync等待时间(ms)" title-en="Log File Sync Average Time" status="1" rela1="<" rela2="<" rela3=">=" value1="7" value2="20" value3="20" description="当前平均等待时间为[:0]ms,请检查磁盘性能" description-en="Log file sync average time is [:0]">
with query1 as ( select * from (select b.TIME_WAITED_MICRO-a.TIME_WAITED_MICRO as TIME_WAITED_MICRO1,b.TOTAL_WAITS-a.TOTAL_WAITS as TOTAL_WAITS1,b.* from (select * from DBA_HIST_SYSTEM_EVENT where SNAP_ID=:snap_id-1)a, (select * from DBA_HIST_SYSTEM_EVENT where SNAP_ID=:snap_id)b where a.INSTANCE_NUMBER=b.INSTANCE_NUMBER and a.instance_number=(select userenv('instance') from dual ) and a.EVENT_NAME=b.EVENT_NAME and a.EVENT_NAME='log file sync' )aa ) select round(TIME_WAITED_MICRO1/TOTAL_WAITS1/1000),to_char(EVENT_NAME), TIME_WAITED_MICRO1, TOTAL_WAITS1 from query1 where TOTAL_WAITS1<>0 and rownum<6
</SQLString>
<SQLString title="[AWR]逻辑读TopSQL(%)" title-en="Top SQL Ordered by Buffer Get" status="1" rela1="<" rela2="<" rela3=">=" value1="15" value2="40" value3="40" description="SQL ([:1])当前逻辑读占总逻辑读[:0]%" description-en="Top 1 SQL [:1] Ordered by Buffer Get is [:0]%">
with query1 as ( select * from (select b.BUFFER_GETS_TOTAL-a.BUFFER_GETS_TOTAL as cur_buffer,b.* from (select * from dba_hist_sqlstat where SNAP_ID=(select max(snap_id)-1 from dba_hist_snapshot))a, (select * from dba_hist_sqlstat where SNAP_ID=(select max(snap_id) from dba_hist_snapshot))b where a.INSTANCE_NUMBER=b.INSTANCE_NUMBER and a.sql_id=b.sql_id and a.PLAN_HASH_VALUE=b.PLAN_HASH_VALUE order by b.BUFFER_GETS_TOTAL-a.BUFFER_GETS_TOTAL desc) aa where rownum<100 ) select round(cur_buffer*100/(select sum(cur_buffer) from query1 ),2),to_char(SQL_ID), cur_buffer as buffer_persent from query1 where cur_buffer<>0 and rownum<6
</SQLString>
<SQLString title="[AWR]物理读TopSQL(%)" title-en="Top SQL Ordered by Read" status="1" rela1="<" rela2="<=" rela3=">" value1="15" value2="40" value3="40" description="SQL([:1])当前物理读占总物理读[:0]%" description-en="Top 1 SQL [:1] ordered by read if [:0]%">
with query1 as ( select * from (select b.DISK_READS_TOTAL-a.DISK_READS_TOTAL as cur_reads,b.* from (select * from dba_hist_sqlstat where SNAP_ID=(select max(snap_id)-1 from dba_hist_snapshot))a, (select * from dba_hist_sqlstat where SNAP_ID=(select max(snap_id) from dba_hist_snapshot))b where a.INSTANCE_NUMBER=b.INSTANCE_NUMBER and a.sql_id=b.sql_id and a.PLAN_HASH_VALUE=b.PLAN_HASH_VALUE order by b.DISK_READS_TOTAL-a.DISK_READS_TOTAL desc) aa where rownum<100 ) select round(cur_reads*100/(select sum(cur_reads) from query1 ),2) as buffer_persent, to_char(SQL_ID), cur_reads from query1 where cur_reads<>0 and rownum<6
</SQLString>
<SQLString title="[AWR]耗时TopSQL(%)" title-en="Top SQL Ordered by Elapse Time" status="1" rela1="<" rela2="<=" rela3=">" value1="15" value2="40" value3="40" description="SQL ([:1])当前耗时占总耗时[:0]%" description-en="Top SQL [:1] Ordered by Elapse Time [:0]%">
with query1 as ( select * from ( select b.ELAPSED_TIME_TOTAL-a.ELAPSED_TIME_TOTAL as cost_time,b.* from (select * from dba_hist_sqlstat where SNAP_ID=(select max(snap_id)-1 from dba_hist_snapshot))a, (select * from dba_hist_sqlstat where SNAP_ID=(select max(snap_id) from dba_hist_snapshot))b where a.INSTANCE_NUMBER=b.INSTANCE_NUMBER and a.sql_id=b.sql_id and a.PLAN_HASH_VALUE=b.PLAN_HASH_VALUE order by b.ELAPSED_TIME_TOTAL-a.ELAPSED_TIME_TOTAL desc) aa where rownum<100 ) select round(cost_time*100/(select sum(cost_time) from query1 ),2) as buffer_persent, to_char(SQL_ID), cost_time from query1 where cost_time<>0 and rownum<6
</SQLString>
<SQLString title="[AWR]每秒重做日志产生速度(K)" title-en="Redo Log Pre Second" status="1" rela1="<" rela2="<" rela3=">=" value1="1000" value2="2000" value3="2000" description="" description-en="">
select round(AVERAGE/1024,3) from DBA_HIST_SYSMETRIC_SUMMARY where METRIC_NAME='Redo Generated Per Sec' and snap_id=:snap_id
</SQLString>
<SQLString title="[AWR]每秒硬解析次数" title-en="Pysical Read Pre Second" status="1" rela1="<" rela2="<" rela3=">=" value1="10" value2="40" value3="40" description="每秒硬解析次数[:0]次,请检查是否有过高的子游标,是否没有使用绑定变量" description-en="">
select round(AVERAGE,2) from DBA_HIST_SYSMETRIC_SUMMARY where METRIC_NAME='Hard Parse Count Per Sec' and snap_id=:snap_id
</SQLString>
<SQLString title="数据库设置的session数" title-en="Check Parameter sessions " status="1" rela1=">" rela2=">=" rela3="<" value1="800" value2="600" value3="600" description="" description-en="Parameter sessions should be more than 800">
select value from v$parameter where name='sessions'
</SQLString>
<SQLString title="检查表空间%" title-en="Check Tablespace Usage" status="1" rela1="<=" rela2="<=" rela3=">" value1="80" value2="90" value3="90" description="表空间[:1]占用比为[:0]%,剩余[:3]M,请处理。" description-en="Tablespace [:1] usage :[:0]%, balance [:3]M, Please check it." sql-show="select a.tablespace_name, b.bytes usedBytes, a.bytes freebytes from (select tablespace_name, sum(nvl(bytes,0)) bytes from dba_free_space group by tablespace_name) a, (select tablespace_name, sum(nvl(bytes,0)) bytes from dba_data_files group by tablespace_name) b where a.tablespace_name(+)=b.tablespace_name -- and 100* a.bytes/b.bytes < 50 order by b.bytes + a.bytes" chart-mode="1">
select 100*rOund(1- a.bytes/b.bytes,4),a.tablespace_name, b.bytes usedBytes, trunc(a.bytes/1024/1024) freebytes from (select tablespace_name, sum(nvl(bytes,0)) bytes from dba_free_space group by tablespace_name) a, (select tablespace_name, sum(nvl(bytes,0)) bytes from dba_data_files group by tablespace_name) b where a.tablespace_name(+)=b.tablespace_name and b.tablespace_name not like 'UNDO%' order by a.bytes/b.bytes
</SQLString>
<SQLString title="检查表锁blocker" title-en="Check dba_blockers" status="1" rela1="==" rela2="<" rela3=">=" value1="0" value2="2" value3="2" description="存在表锁的情况" description-en="There is some lock in the database, please check the view dba_blockers." sql-show="select * from dba_blockers" chart-mode="-1">select count(*) from dba_blockers</SQLString>
<SQLString title="检查session数(%)" title-en="Check DB Session Usage " status="1" rela1="<" rela2="<" rela3=">=" value1="60" value2="75" value3="75" description="" description-en="">
select 100*round(b.curvalue/a.sumvalue,4) PROCESS_RATE from (select to_number(VALUE)*0.8 sumvalue from v$parameter where name='sessions') a ,(select count(*) curvalue from v$session ) b
</SQLString>
<SQLString title="重做日志切换频率" title-en="Check Redo Log Switch Frequntcy" status="1" rela1="<" rela2="<" rela3=">=" value1="6" value2="12" value3="12" description="当前日志切换频率为[:0],请考虑调整redo大小" description-en="The switch of redo log is too frequntly, please check it.">
select count(*) COUNT_VAL from v$log_history where first_time>sysdate-1/24
</SQLString>
<SQLString title="重做日志大小(M)" title-en="Check Redo Log Size" status="1" rela1=">=" rela2="<" rela3="" value1="512" value2="512" value3="" description="" description-en="">select round(min(BYTES)/1024/1024) from v$log</SQLString>
<SQLString title="UNDO表空间大小(G)" title-en="Check Undo Tablespace Size" status="1" rela1=">=" rela2=">=" rela3="<" value1="8" value2="4" value3="4" description="" description-en="">
select sum(BYTES)/1024/1024/1024 from DBA_DATA_FILES where tablespace_name = (select value from V$PARAMETER where name='undo_tablespace')
</SQLString>
<SQLString title="无效存储过程(函数,包)" title-en="Invalid Procedures and Functions" status="1" rela1="==" rela2="<" rela3=">=" value1="0" value2="10" value3="10" description="出现了[:0]个无效的存储过程或函数,需要确认是否对系统有影响" description-en="[:0] invalid procedures or functions. please check it.">
select count(*) ROW_COUNT from ALL_OBJECTS where OBJECT_TYPE ='FUNCTION' and STATUS='INVALID'
</SQLString>
<SQLString title="无效全局索引" title-en="Invalid Indexes" status="1" rela1="==" rela2="<" rela3=">=" value1="0" value2="10" value3="10" description="存在无效索引,请马上确认重建" description-en="exists unusable index, please check it.">
select count(*) ROW_COUNT from dba_indexes where STATUS = 'UNUSABLE'
</SQLString>
<SQLString title="分区表到期" title-en="Check Table Partitions Close to Max Partition" status="1" rela1="==" rela2="<" rela3=">=" value1="0" value2="10" value3="10" description="当前有[:0]个分区表快到期,请检查dba_tab_partitions表" description-en="There are [:0] table partitions is close to MAX partition, please check it." sql-show=" select * from dba_tab_partitions a , (select table_owner, table_name, max(PARTITION_POSITION) pp from dba_tab_partitions group by table_owner, table_name) cc where a.table_name=cc.table_name and a.table_owner=cc.table_owner and a.PARTITION_POSITION= cc.pp-1 and (a.partition_name like 'P%2011%' or a.partition_name like 'P%2012%' or a.partition_name like 'P%2013%' or a.partition_name like 'P%2014%' or a.partition_name like 'P%2015%') and to_number( REGEXP_SUBSTR(SUBSTR(a.partition_name, INSTR(a.partition_name, 20, 1, 1), 4), '^\d+')) < 2015 order by a.table_owner, a.table_name" chart-mode="-1">
select count(*) from dba_tab_partitions a , (select table_owner, table_name, max(PARTITION_POSITION) pp from dba_tab_partitions group by table_owner, table_name) cc where a.table_name=cc.table_name and a.table_owner=cc.table_owner and a.PARTITION_POSITION= cc.pp-1 and (a.partition_name like 'P%2011%' or a.partition_name like 'P%2012%' or a.partition_name like 'P%2013%' or a.partition_name like 'P%2014%' or a.partition_name like 'P%2015%') and to_number( REGEXP_SUBSTR(SUBSTR(a.partition_name, INSTR(a.partition_name, 20, 1, 1), 4), '^\d+')) < 2015 order by a.table_owner, a.table_name
</SQLString>
<SQLString title="检查UNUSABLE分区索引" title-en="Unusable Indexe Partitions" status="1" rela1="==" rela2="<=" rela3=">" value1="0" value2="100" value3="100" description="请检查dba_ind_partitions status='UNUSABLE'的分区索引并修正" description-en="select * from dba_ind_partitions where status='UNUSABLE'">
select count(*) from dba_ind_partitions where status='UNUSABLE'
</SQLString>
<SQLString title="检查索引并行度" title-en="Check Degree of Indexes" status="1" rela1="==" rela2="<=" rela3=">" value1="0" value2="20" value3="20" description="" description-en="select * from dba_indexes where ltrim(rtrim(degree)) >'1'">
select count(*) from dba_indexes where ltrim(rtrim(degree)) >'1'
</SQLString>
<SQLString title="不允许同一个业务用户在两个实例上都有连接" title-en="Job can not exist in two Instance" status="1" rela1="==" rela2="==" rela3=">" value1="0" value2="0" value3="0" sql-show="select gv.INST_ID, gv.USERNAME, gv.MACHINE, gv.PROGRAM, count(*) from gv$session gv group by gv.INST_ID, gv.USERNAME, gv.MACHINE, gv.PROGRAM having count(*) > 2" description="不允许同一个业务用户在两个实例上都有连接" description-en="" chart-mode="-1">
with temp1 as (select count(distinct gv.INST_ID),gv.USERNAME, gv.MACHINE, gv.PROGRAM from gv$session gv group by gv.INST_ID, gv.USERNAME, gv.MACHINE, gv.PROGRAM having count(distinct gv.INST_ID) > 2 ) select count(*) from temp1
</SQLString>
<SQLString title="不允许业务用户的job的实例号为0" title-en="Job instance can not be 0" status="1" rela1="==" rela2="" rela3=">" value1="0" value2="" value3="0" sql-show="select j.LOG_USER, j.INSTANCE, count(*) from dba_jobs j group by j.LOG_USER, j.INSTANCE" description="不允许业务用户的job的实例号为0,或者同一个用户在两个节点上都有job,且要满足某个业务用户job所在的实例和上面第一条的结果一致。" description-en="" chart-mode="-1">
with temp1 as ( select j.LOG_USER, j.INSTANCE,upper(WHAT), count(*) countval from dba_jobs j group by j.LOG_USER, j.INSTANCE, upper(WHAT) ) select count(*) from temp1 where instance='0' or countval>1
</SQLString>
<SQLString title="索引比表大的检测" title-en="Index is Bigger than Table Size" status="1" rela1="==" rela2=">" rela3=">=" value1="0" value2="0" value3="5" sql-show="with query1 as (select OWNER,SEGMENT_NAME, decode(segment_type, 'INDEX','1','INDEX PARTITION','1', 'TABLE','2','TABLE PARTITION','2','3') SEG_TYPE,bytes from DBA_SEGMENTS where owner not in ('SYS','SYSTEM','SYSMAN') and BLOCKS>8 ) select aa.SEGMENT_NAME, bb.SEGMENT_NAME, bb.seg_size-aa.seg_size from (select a.OWNER,SEGMENT_NAME,SEG_TYPE, table_name, sum(bytes) seg_size from query1 a, DBA_INDEXES c where (a.owner=c.OWNER and a.SEGMENT_NAME=c.INDEX_NAME and a.SEG_TYPE='1') group by a.OWNER,SEGMENT_NAME,SEG_TYPE,table_name) aa, (select a.OWNER,SEGMENT_NAME,SEG_TYPE, table_name, sum(bytes) seg_size from query1 a, DBA_INDEXES b where (a.owner=b.OWNER and a.SEGMENT_NAME=b.TABLE_NAME and a.SEG_TYPE='2') group by a.OWNER,SEGMENT_NAME,SEG_TYPE,table_name)bb where aa.OWNER=bb.OWNER and aa.table_name = bb.table_name and bb.seg_size-aa.seg_size<0" description="索引比表大的检测" description-en="Index is Bigger than Table Size" chart-mode="-1">
with query1 as (select OWNER,SEGMENT_NAME, decode(segment_type, 'INDEX','1','INDEX PARTITION','1', 'TABLE','2','TABLE PARTITION','2','3') SEG_TYPE,bytes from DBA_SEGMENTS where owner not in ('SYS','SYSTEM','SYSMAN') and BLOCKS>8 ) select count(*) from (select a.OWNER,SEGMENT_NAME,SEG_TYPE, table_name, sum(bytes) seg_size from query1 a, DBA_INDEXES c where (a.owner=c.OWNER and a.SEGMENT_NAME=c.INDEX_NAME and a.SEG_TYPE='1') group by a.OWNER,SEGMENT_NAME,SEG_TYPE,table_name) aa, (select a.OWNER,SEGMENT_NAME,SEG_TYPE, table_name, sum(bytes) seg_size from query1 a, DBA_INDEXES b where (a.owner=b.OWNER and a.SEGMENT_NAME=b.TABLE_NAME and a.SEG_TYPE='2') group by a.OWNER,SEGMENT_NAME,SEG_TYPE,table_name)bb where aa.OWNER=bb.OWNER and aa.table_name = bb.table_name and bb.seg_size-aa.seg_size<0
</SQLString>
<SQLString title="检查最新的alert日志" title-en="Check Alert Log" status="1" rela1="==" rela2=">" rela3="" value1="0" value2="0" value3="" sql-show="with query1 as (select * from (select rownum n ,p.* from orpt_icheck_alert p) where n > ((select count(*) from orpt_icheck_alert p)-10000)) select * from query1 where log like 'ORA-%' and log not like 'ORA-609%' " description="1, 创建一个directory" description-en="Check Alert Log" chart-mode="-1">
with query1 as (select * from (select rownum n ,p.* from orpt_icheck_alert p) where n > ((select count(*) from orpt_icheck_alert p)-10000)) select count(*) from query1 where log like 'ORA-%' and log not like 'ORA-609%'
</SQLString>
<SQLString title="检查11g是否增量收集统计信息" title-en="Check statistics collect Incremental" status="1" rela1="==" rela2="!=" rela3="" value1="TRUE" value2="TRUE" value3="" sql-show="SELECT 'GLOBAL_INCREMENTAL : ' || DBMS_STATS.GET_PREFS('INCREMENTAL') FROM DUAL" description="检查11g是否增量收集统计信息begin dbms_stats.SET_GLOBAL_PREFS(pname => 'INCREMENTAL',pvalue => 'TRUE'); end;" description-en="Check statistics collect Incremental" chart-mode="-1">
SELECT DBMS_STATS.GET_PREFS('INCREMENTAL') FROM DUAL
</SQLString>
<SQLString title="检查数据库版本号" title-en="Check DB Server Version" status="1" rela1=">=" rela2="<" rela3="" value1="0" value2="0" value3="" sql-show="select * from dba_registry_history where NAMESPACE='SERVER'" description="检查数据库版本号,公司规定必须在11.2.0.3.4以上,当前[:2]" description-en="Check DB Server Version" chart-mode="-1">
select decode(substr(version,1,4),'11.1',id-5,'11.2',id-4,'0'), COMMENTS from dba_registry_history where NAMESPACE='SERVER' order by ACTION_TIME desc
</SQLString>
<SQLString title="检查diskgroup" title-en="Check Diskgroup usage" status="1" rela1="==" rela2="" rela3=">" value1="0" value2="" value3="0" sql-show="select * from V$ASM_DISKGROUP " description="磁盘组空间不足,请检查" description-en="Diskgroup balance is not enough, please check it." chart-mode="-1">
select count(*) from V$ASM_DISKGROUP where FREE_MB/total_mb<0.5 and FREE_MB<50000
</SQLString>
</folder>
</root>
OGG规范
目 录
1 目的 4
2 规范范围 4
3 OGG工作流程和名词解释 4
3.1 OGG工作流程 4
3.2 OGG相关名字解释 4
4 术语定义 4
5 架构部署 5
5.1 OGG 部署同步规范【May】 5
5.2 OGG的高可用性 6
6 源端数据库配置规范 6
7 数据同步场景 7
7.1 同步功能支持 7
7.2 同步场景 7
8 OGG关键技术约束【must】: 8
9 OGG 使用限制 8
9.1 目标端的Trigger限制 8
9.2 目标端的主外键限制 9
9.3 双向复制限制使用sequence 9
10 OGG同步表规范 9
10.1 表级要求 9
10.2 DML复制 10
10.2.1 DML复制范围【Must】 10
10.2.2 DML 操作类型限制【Should】 10
10.3 DDL复制【May】 10
10.4 其他限制要求 10
10.5 OGG 异常处理【Should】 11
11 部署规范 11
11.1 OGG安装规范【Should】 11
11.2 OGG实例及进程规范【Should】 11
11.3 OGG实例对应的OS用户规范【May】 12
12 命名规范 12
12.1 OGG DB用户名称及权限【Should】 12
12.2 OGG 抽取进程Extract命名【Should】 13
12.3 OGG 传输进程Data Pump命名【Should】 13
12.4 OGG复制进程Replicat命名【Should】 13
12.5 OGG表定义文件命名规范【May】 13
13 参数配置规范 13
13.1 参数文件明确指定要配置的表【Must】 13
13.2 OGG MGR进程参数设置规范【Should】 13
13.3 OGG 抽取进程Extract参数设置规范【Should】 14
13.4 OGG 传输进程Pump参数设置规范【Should】 14
13.5 OGG 交付进程Replicate参数设置规范【Should】 15
14 监控部署规范 15
14.1 邮件及短信通知【Should】 15
15 附录:OGG 复制数据类型限制 16
GoldenGate实施规范
1 目的
本规范规定GoldenGate的实施标准,指导项目组在使用GoldenGate 方面降低风险,增强GoldenGate 在生产环境运行的稳定性。
2 规范范围
仅适用于采用OGG工具在Oracle数据库之间,进行的业务数据同步,做为项目采用OGG进行数据同步的参考
3 OGG工作流程和名词解释
3.1 OGG工作流程
3.2 OGG相关名字解释
- Extract进程:从源端负责日志捕获的进程;
- Pump进程: 负责将源端extract进程捕获的数据队列文件传送到目标端;
- Replicate进程: 负责将OGG的数据写入到目标数据库;
- MGR进程: 负责OGG的管理,通讯端口配置,队列文件清理等。MGR进程停止后,无法接受pump进程传送过来的数据。
4 术语定义
- 完整说法 缩略说法
- GoldenGate OGG
- Extract GoldenGate软件的抽取进程,又叫Capture进程,一般用于抽取数据库日志抓取数据变化或将本地队列中数据传递到目标端,一般简称E进程。
- Replicat GoldenGate软件的投递进程,用于将队列文件中的数据变化转换为SQL应用到目标库,一般简称R进程。
- Data Pump 专指将本地队列中数据传递到目标端的Extract进程,区别于读取日志的主Extract进程,一- 般简称P进程。
- Trail GoldenGate的队列文件,存储增删改等数据变化,以其专有格式存放。
5 架构部署
5.1 OGG 部署同步规范【May】
? 尽量采用并行结构。将事务量分配到多个并发执行的OGG进程组上,以加快数据复制速度。一个进程组包含一个Extract(抽取)进程,一个或多个Datapump(传输)进程,一个或多个Replicat(加载)进程,以及专供它们使用的Trail(队列)文件。如图所示。
? 预先估计各个表上的事务量,尽量将事务平均分配到不同的进程组上。
? 对于目标端的每个Trail文件,如果有性能瓶颈,可以使用两个及以上Replicat进程并行加载。具有关联关系的表应该放到同一个Replicat进程,以保证事务完整性。
? 如果Extract进程抽取日志速度无法赶上日志产生速度的话,应该考虑对符合下列特征的表使用单独的进程组进行复制:
? 事务特别繁忙
? 事务处理时间特别长或特别大
? 存在大字段(如:LOB等)对复制效率有影响的表
5.2 OGG的高可用性
因OGG从数据库的角度看是数据库一个独立的应用,只有保证数据库的正常运行才能保证OGG实例的正常运行,因此OGG的高可用是与数据库保持一致的,先有数据库的高可用才有OGG的高可用。
一般Oracle数据库都是RAC架构,建议在RAC上部署一个NAS共享存储,将OGG部署在NAS共享存储上,RAC中每个节点都可以访问NAS,在当前OGG运行节点机器故障时,可以切换到另一个节点上继续运行。
对于比较重要的生产环境交易系统,因各节点的应用连接有规划,不建议部署OGG自动切换,需人工识别可以切换的节点。
6 源端Oracle数据库配置规范
对于部署OGG的源端数据库,必须遵循以下规范:
- 数据库必须开启归档,并且设置为强制归档【Must】;
- 数据库必须开启数据库级别的最小补充日志【Must】;
- 数据库的归档日志,必须保留3天,如果存储不足以保留3天,需扩容【Must】;
- 需保证数据库的长事务不得有超过1天的,如果有超过1天的超长事务,需要应用立即整改,或者部署自动清理超长事务的脚本【Must】。
7 源端MySQL数据库配置规范
- 数据库的日志,必须保留3天,如果存储不足以保留3天,需扩容【Must】;
- MySQL必须设置 binlog_format=row【Must】;
- MySQL不允许设置lower_case_table_name=0 参数,否则OGG无法识别正确的table def文件【Must】;
8 数据同步场景【Must】
目前OGG仅用于以下场景的数据复制,并遵循以下规范:
8.1 Oracle到Oracle的非全库的数据复制
8.2 Oracle到HANA的数据复制
9 OGG 源端使用限制【Must】
- 目前OGG只支持Oracle 11.2.0.3及以上版本,低于此版本OGG的复制准确性不能保证;
- 不支持IOT索引组织表复制
- 不支持Clustered Table复制
- 不支持物化视图复制
- 表没有主键或唯一索引,不能使用OGG同步;
- 当目标数据库与源数据库存在相同的trigger时,则应当禁止掉或者删除目标端的trigger;
- 目标端被复制的表禁止设置外键;
- 双向复制情况下,sequence 存在冲突问题。需在应用层面解决冲突问题;
- 要求源、目标数据库字符集为UTF8或者AL32UTF8
- 源端数据库归档日志必须能保留3天以上;
- 源端数据库不能有超过24小时的长事务,如果有,需要定时清理。
- 生产系统不支持DDL 同步
10 OGG目标端的使用限制【Must】
10.1 禁止目标端表的主外键关系
10.2 禁止目标端表的trigger【Should】
原因如下:
同Trigger类似,如果数据库中存在级联删除的外键,则GoldenGate复制数据变化到目标端后,目标端的cascade delete会自动触发删除对应子记录,但同时GoldenGate又能够把这些子记录的变化从源端复制过来,造成这些记录会被删除两次,OGG复制会报告错误并且停止复制。
10.3 双向复制限制使用sequence
在双向复制情况下,sequence 存在冲突问题。需在应用层面解决冲突问题。
对于源端DDL变更,源-目标数据库故障,导致OGG的异常停止,重启后OGG的恢复操作,以及故障处理的及时性,OGG的实时性会受到一定影响,下游需接受这种影响【Should】
10.4 OGG 异常处理【Should】
? 在OGG同步过程中,为避免由于OGG 异常原因导致故障时段数据差异或延迟,项目组必须有替代OGG 的应急同步方案。
? 由于数据异常导致OGG无法同步,对于数据的处理或者数据重新刷新操作,由项目组提交变更完成。
11 部署规范
必须遵守OGG变更实施规范,否则出现异常由产品组承担业务风险。
11.1 OGG安装规范【Should】
在有RAC的数据库生产环境,OGG必须部署在NAS上,并且考虑双活情况,NAS挂载目录为:/oggnas/[dbname]/goldengate
11.2 OGG实例及进程规范【Should】
各应用需遵循如下部署原则:
? 一个数据库实例一般只部署一个OGG实例;
? OGG实例采用OGG标准端口7809-7899中的某一个。并适当给10-80个连续端口备用,如果一个系统预计将来需要通过OGG集成的源很多,需分配更多的端口;
? 一个实例下不得超过6个Exatract进程,极端情况下不得超过9个。
? 如果部署集成模式抽取进程,一个抽取进程需要占用1.5G~2G的Stream Pool,需充分分配Stream Pool的大小。
? 一个Extract进程可以对应多个pump进程,但建议对一个目标不超过三个pump进程;
11.3 OGG实例对应的OS用户规范【Must】
OGG需要用具有DBA组权限的OS用户进行配置和运行,可用Oracle数据库实例用户或单独建一个OGG的OS用户,权限跟oracle用户一致,进行配置管理。
11.4 统一走EIP受理需求(EDW/HANA除外) 【Must】
EIP作为统一的集成平台,对OGG的集成点进行统一管控。
11.5 不允许做双向复制及多对一复制【Must】
双向复制是指源和目标的同一张表互相做复制,很容易导致数据冲突,造成运维负担,产品组需自行解决双向复制的问题;
多对一复制是指多个源端的表数据复制到同一个目标端的同一张表中,这样也容易造成数据冲突。
11.6 不允许做双向复制及多对一复制【Must】
11.7 禁止目标表有其他任何的写入,修改操作【Must】
OGG目标表只能通过OGG进行DML操作,否则一旦其他应用或人为修改目标数据,会造成OGG复制进程报错停止。
11.8 OGG部署变更时间窗必须给予足够初始化数据时间【Must】
OGG部署后可能需要进行数据初始化,目前已提供自动初始化功能,但是性能比数据泵导出导入方式效率要低,下游产品需给予足够的数据初始化时间;
11.9 关键业务系统,如要求数据延时724不得超过10分钟的,不建议使用OGG【Must】
OGG只能在单个节点运行,不具备集群功能,很难保证724小时不出现异常,而且OGG的延迟受源端的影响较大,如果下游产品只依赖通过OGG进行同步,并且无法接受延迟波动,建议不要使用OGG进行同步;
11.10 表大小超过10G,增量每天100万以上的表,不允许进行海外分布式部署【Must】
海外数据同步受网络带宽影响较大,OGG是按进程同步数据,一个进程下一般会同步较多的表,如果某一张表增量数据过大,会阻塞其他表的同步,并引起较大的OGG复制延迟;
11.11 当OGG出现故障或其他变更(如数据库升级,软硬件故障等),能承担偶尔8小时内的业务停止风险或下游产品有临时替代方案;
OGG只能在单个节点运行,不具备集群功能,并且受源端的DDL变更影响,容易出现故障告知进程停止,监控会有一定的延迟,遇到节假日的处理可能会出现较长时间的故障恢复;
11.12 OGG存在漏数的可能,能接受由于偶尔漏数导致的源目标数据不一致的风险。
OGG本身可能存在一些bug,导致数据复制遗漏,无法保证100%数据不丢失。下游产品需能接受数据偶尔丢失的风险。
12 命名规范
OGG进程命名有8位字符的限制,所以需要对命名进行规划,保持OGG系统的可读性和易于理解。OGG进程名称都应该采用全大写进行命名,参数文件名称采用全小写命名【Should】
12.1 OGG DB用户名称及权限【Should】
用于安装OGG时创建的用户,可以直接使用外部认证用户,或者创建一个GOLDENGATE的普通用户,用于连接DB,用户名称统一用GOLDENGATE。
为了保证OGG正常运行,需授予OGG数据库用户一定权限,权限如下:
其中红色标示的三个权限,如果只做OGG源端,可以不授予。
grant connect to GOLDENGATE;
grant resource to GOLDENGATE;
grant create session to GOLDENGATE;
grant alter session to GOLDENGATE;
grant select any table to GOLDENGATE;
grant flashback any table to GOLDENGATE;
grant select any dictionary to GOLDENGATE;
grant insert any table to GOLDENGATE;
grant update any table to GOLDENGATE;
grant delete any table to GOLDENGATE;
grant alter any table to GOLDENGATE;
grant SELECT ANY TRANSACTION to GOLDENGATE;
grant alter system to GOLDENGATE;
grant select on sys.dba_clusters to GOLDENGATE;
grant execute on sys.dbms_flashback to GOLDENGATE;
EXEC DBMS_GOLDENGATE_AUTH.GRANT_ADMIN_PRIVILEGE( grantee => ' GOLDENGATE ', privilege_type => 'capture', grant_select_privileges=> true, do_grants => TRUE);
12.2 OGG 抽取进程Extract命名【Should】
OGG一个实例抽取进程一般不超过6个,抽取进程命名可以用可以代表是Extract进程的标示,全部用大写,并加上数字顺序,例如:EFIN01,ESCM02
12.3 OGG 传输进程Data Pump命名【Should】
Data Pump进程的名称有限制8个字符,命名要能识别是Pump进程,并知道是传输到哪个目标系统,规则为P+目标系统的缩写+两位数据流水号,比如:PEDW01,PSCM01。
12.4 OGG复制进程Replicat命名【Should】
复制进程的名称有限制8个字符,命名要能识别是Replicat进程,并且数据源是哪个系统,规则为r+源端系统的缩写+两位流水号,比如:RHWERP01, RCEP01。
12.5 OGG表定义文件命名规范【May】
表定义文件是Replicat进程用到的,建议每个Replicat使用一个表定义文件,当源端表接口变化时,只需刷新该表所在的表定义文件,不会影响其他复制进程。表定义文件存放在./dirdef目标下。命名规则为source+_+Replicat进程名.def,如source_rhwerp01.def
13 参数配置规范
13.1 参数文件明确指定要配置的表【Must】
不允许在各类型参数文件中配置使用通配符来配置TABLE, 如TABLE Schema.*或 TABLE .。
13.2 OGG MGR进程参数设置规范【Should】
MGR进程需要配置自动清除队列文件,一般至少要保留3天以上队列文件。目标端可以保留5天以上。
purgeoldextracts /ogg/goldengate/dirdat*,usecheckpoints, minkeepdays 3, frequencyminutes 30
为了能使进程在停止后自动起来,可以在MGR参数文件中添加自动重启的参数:
autorestart er *, retries 3, waitminutes 5, resetminutes 30
13.3 OGG 抽取进程Extract参数设置规范【Should】
- 不允许在参数文件中使用明文的连接数据库的密码,必须使用加密的存储,或者使用OS认证用户。
- 对于单个数据库实例的环境中,需要在运行OGG的OS用户的环境变量中设置ORACLE_HOME和ORACLE_SID的环境变量,对于有多个数据库实例运行的服务器上,则需要在服务器中配置TNS NAME,例如:
CPP = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=cep-scan)(PORT=1526))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=asms.szxasm.huawei.com)))
并在参数文件中指定使用该TNS登录数据库,
USERID goldengate@CPP, PASSWORD XXXXXX - 必须在Extract参数文件中增加以下参数,以防止OGG对delete的数据进行压缩存储导致OGG报错【Must】:
NOCOMPRESSDELETES对于11.2.0.3以上数据库版本,如果是用经典模式读取数据库日志,要使用DBLOGREADER方式读取,需增加此以下参数【Should】:
TRANLOGOPTIONS DBLOGREADER, DBLOGREADERBUFSIZE 4096000
AIX平台DBLOGREADERBUFSIZE最大只能设置为1048576 - 对于存在分布式事务的源数据库,经典模式可能会丢失数据,需用集成模式进行抽取【May】
13.4 OGG 传输进程Pump参数设置规范【Should】
对于数据量比较大的复制场景,可以增加 compress提高性能【May】
如:rmthost szxtsv7813rhl, mgrport 7809, compress
13.5 OGG 交付进程Replicate参数设置规范【Should】
- 不允许在参数文件中使用明文的连接数据库的密码,必须使用加密的存储,或者使用外部用户。
- 对于单个数据库实例的环境中,需要在运行OGG的OS用户的环境变量中设置ORACLE_HOME和ORACLE_SID的环境变量,对于有多个数据库实例运行的服务器上,则需要在服务器中配置TNS NAME,例如:
CPP = (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=cep-scan)(PORT=1526))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=asms.szxasm.huawei.com)))
并在参数文件中指定使用该TNS登录数据库,
USERID goldengate@CPP, PASSWORD XXXXXX - 必须要配置discard文件,以备问题定位;
- HANDLECOLLISIONS参数的作用是打开GG的自动冲突解决机制。使用GG来自动解决数据复制过程中的冲突。如更新一条不存在的记录/删除不存在的记录等。主要用于数据同步出错后的数据修复,不用于正常复制。
14 监控部署规范
14.1 邮件及短信通知【Should】
在OGG日常运行过程中,源或目标由于系统,网络,资源等影响,可能会导致复制出现异常,需部署监控,出现异常自动发送邮件的方式进行异常提醒,以便能够较方便的发现问题。
应通过部署脚本,监控OGG进程状态,延时时间,配置监控邮件及短信发送名单,进行监控报警。监控至少包括如下:
? OGG 进程状态监控
? OGG lag 时间监控
15 附录:OGG 复制数据类型限制
? 支持Numeric(数字类型),包括NUMBER、BINARY FLOAT、BINARY DOUBLE。暂不支持BINARY_INTEGER和PLS_INTEGER。
? 支持所有Character(字符类型),包括CHAR、VARCHAR2、LONG、NCHAR、NVARCHAR2。
? 支持大对象,包括CLOB、NCLOB、BLOB。但不支持BFILE
? 支持Binary(二进制类型),包括RAW和LONG RAW。
? 支持Date及timestamp类型。除了TIMEZONE_REGION和TIMEZONE_ABBR类型
? 不支持多字节的XML类型。
? 支持用户自定义类型(UDT),源端的UDT与目标端的UDT的必须相同。
? 其它支持的数据类型,包括ROWID、VARRAY、INTERVAL DAY、INTERVAL YEAR。
? OGG不支持如下数据类型:
ANYDATA and ANYDATASET
ANYTYPE
MLSLABEL
URITYPE
UROWID
05icheck_12C.xml
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<root title="root1">
<folder title="数据库参数检查,巡检和上线之前需要关注" expand="1" title-en="[Check Database Parameters]">
<SQLString title="检查参数 [db_block_size]" title-en="Check Parameter [db_block_size]" status="1" rela1="==" rela2="!=" rela3="" value1="8192" value2="8192" value3="" description="数据块大小,创建数据库的时候指定" description-en="">
select value from v$parameter where name='db_block_size'
</SQLString>
<SQLString title="检查参数[Control_files]" title-en="Check Parameter [Control_files]" status="1" rela1=">=" rela2="<" rela3="" value1="3" value2="3" value3="" description="控制文件必须是3个" description-en="">
select count(*) RST from v$parameter2 where name = 'control_files'
</SQLString>
<SQLString title="检查参数 [sga_target]" title-en="Check Parameter [sga_target]" status="1" rela1=">=" rela2="<" rela3="" value1="45" value2="45" value3="" description="alter system set sga_target=[:1] scope=both sid='*'" description-en="alter system set sga_target=[:1] scope=both sid='*'" sql-show="" chart-mode="-1">
select round(100*a.value/b.value,2), case when b.value>10000000000 then trunc((b.value*0.45)/1024/1024/1024)||'G' else trunc((b.value*0.45)/1024/1024)||'M' end from (select value from v$parameter where name = 'sga_target') a, (select value from V$OSSTAT where STAT_NAME='PHYSICAL_MEMORY_BYTES')b
</SQLString>
<SQLString title="检查参数 [db_cache_size]" title-en="Check Parameter [db_cache_size]" status="1" rela1=">=" rela2="<" rela3="" value1="30" value2="30" value3="" description="alter system set db_cache_size=[:1] scope=both sid='*'" description-en="alter system set db_cache_size=[:1] scope=both sid='*'" sql-show="" chart-mode="-1">
select round(100*a.value/b.value,2) , case when b.value>10000000000 then trunc((b.value*0.35)/1024/1024/1024)||'G' else trunc((b.value*0.35)/1024/1024)||'M' end from (select value from v$parameter where name = 'db_cache_size') a, (select value from V$OSSTAT where STAT_NAME='PHYSICAL_MEMORY_BYTES')b
</SQLString>
<SQLString title="检查参数 [shared_pool_size]" title-en="Check Parameter [shared_pool_size]" status="1" rela1=">=" rela2="<" rela3="" value1="4" value2="4" value3="" description="alter system set shared_pool_size=[:1] scope=both sid='*'" description-en="alter system set shared_pool_size=[:1] scope=both sid='*'" sql-show="" chart-mode="-1">
select round(100*a.value/b.value,2) , case when b.value>40000000000 then trunc((b.value*0.05)/1024/1024/1024)||'G' else trunc((b.value*0.05)/1024/1024)||'M' end from (select value from v$parameter where name = 'shared_pool_size') a, (select value from V$OSSTAT where STAT_NAME='PHYSICAL_MEMORY_BYTES')b
</SQLString>
<SQLString title="重做日志数量" title-en="Check the oracle Redo LogFile Quantity" status="1" rela1=">=" rela2="<" rela3="" value1="5" value2="5" value3="" description="重做日志文件须要在5组以上" description-en="">
select min( group_count) from (select thread#,count(distinct group#) group_count from V$LOG group by thread#) cc
</SQLString>
<SQLString title="检查参数 [pre_page_sga]" title-en="Check Parameter [pre_page_sga]" status="1" rela1="==" rela2="!=" rela3="" value1="FALSE" value2="FALSE" value3="" description="alter system set pre_page_sga=FALSE scope=spfile sid='*'" description-en="alter system set pre_page_sga=FALSE scope=spfile sid='*'" sql-show="" chart-mode="-1">
select upper(value) RST from v$parameter where name = 'pre_page_sga'
</SQLString>
<SQLString title="检查参数 [spfile]" title-en="Check Parameter [spfile]" status="1" rela1="!=" rela2="==" rela3="" value1="" value2="" value3="" description="spfile启动参数文件,启动数据库的时候指定" description-en="" sql-show="" chart-mode="-1">select value from v$parameter where name='spfile'</SQLString>
<SQLString title="检查参数 [sec_case_sensitive_logon]" title-en="Check Parameter [sec_case_sensitive_logon]" status="1" rela1="!=" rela2="==" rela3="" value1="" value2="" value3="" description="sec_case_sensitive_logon启动参数文件,启动数据库的时候指定" description-en="" sql-show="" chart-mode="-1">
select value from v$parameter where name='sec_case_sensitive_logon'
</SQLString>
<SQLString title="检查参数 [undo_management]" title-en="Check Parameter [undo_management]" status="1" rela1="==" rela2="!=" rela3="" value1="AUTO" value2="AUTO" value3="" description="alter system set open_cursors=AUTO scope=spfile sid='*'" description-en="alter system set open_cursors=AUTO scope=spfile sid='*'" sql-show="" chart-mode="-1">
select upper(value) from v$parameter where name='undo_management'
</SQLString>
<SQLString title="检查参数 [open_cursors]" title-en="Check Parameter [open_cursors]" status="1" rela1="==" rela2="!=" rela3="" value1="1000" value2="1000" value3="" description="alter system set open_cursors=1000 scope=both sid='*'" description-en="alter system set open_cursors=1000 scope=both sid='*'" sql-show="" chart-mode="-1">
select value from v$parameter where name = 'open_cursors'
</SQLString>
<SQLString title="检查参数 [db_file_multiblock_read_count]" title-en="Check Parameter [db_file_multiblock_read_count]" status="1" rela1="<=" rela2=">" rela3="" value1="16" value2="16" value3="" description="alter system set db_file_multiblock_read_count=16 scope=both sid='*'" description-en="alter system set db_file_multiblock_read_count=16 scope=both sid='*'" sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'db_file_multiblock_read_count'
</SQLString>
<SQLString title="检查参数 [log_checkpoint_interval]" title-en="Check Parameter [log_checkpoint_interval]" status="1" rela1="<=" rela2=">" rela3="" value1="0" value2="0" value3="" description="alter system set log_checkpoint_interval=0 scope=both sid='*'" description-en="alter system set log_checkpoint_interval=0 scope=both sid='*'" sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'log_checkpoint_interval'
</SQLString>
<SQLString title="检查参数 [remote_login_passwordfile]" title-en="Check Parameter [remote_login_passwordfile]" status="1" rela1="==" rela2="!=" rela3="" value1="EXCLUSIVE" value2="EXCLUSIVE" value3="" description="alter system set remote_login_passwordfile=EXCLUSIVE scope=spfile sid='*'" description-en="alter system set remote_login_passwordfile=EXCLUSIVE scope=spfile sid='*'" sql-show="" chart-mode="-1">
select upper(value) from v$parameter where name = 'remote_login_passwordfile'
</SQLString>
<SQLString title="检查参数 [log_checkpoint_timeout]" title-en="Check Parameter [log_checkpoint_timeout]" status="1" rela1="==" rela2="!=" rela3="" value1="1800" value2="1800" value3="" description="alter system set log_checkpoint_timeout=1800 scope=both sid='*'" description-en="alter system set log_checkpoint_timeout=1800 scope=both sid='*'" sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'log_checkpoint_timeout'
</SQLString>
<SQLString title="检查参数 [timed_statistics]" title-en="Check Parameter [timed_statistics]" status="1" rela1="==" rela2="!=" rela3="" value1="TRUE" value2="TRUE" value3="" description="alter system set timed_statistics=TRUE scope=both sid='*'" description-en="alter system set timed_statistics=TRUE scope=both sid='*'" sql-show="" chart-mode="-1">
select upper(value) from v$parameter where name = 'timed_statistics'
</SQLString>
<SQLString title="检查参数 [lock_sga]" title-en="Check Parameter [lock_sga]" status="1" rela1="==" rela2="!=" rela3="" value1="FALSE" value2="FALSE" value3="" description="alter system set lock_sga=FALSE scope=spfile sid='*'" description-en="alter system set lock_sga=FALSE scope=spfile sid='*'" sql-show="" chart-mode="-1">
select upper(value) from v$parameter where name = 'lock_sga'
</SQLString>
<SQLString title="检查参数 [global_names]" title-en="Check Parameter [global_names]" status="1" rela1="==" rela2="!=" rela3="" value1="FALSE" value2="FALSE" value3="" description="alter system set global_names=FALSE scope=both sid='*'" description-en="alter system set global_names=FALSE scope=both sid='*'" sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'global_names'
</SQLString>
<SQLString title="检查参数 [cursor_sharing]" title-en="Check Parameter [cursor_sharing]" status="1" rela1="==" rela2="!=" rela3="" value1="FORCE" value2="FORCE" value3="" description="alter system set cursor_sharing=FORCE scope=both sid='*'" description-en="alter system set cursor_sharing=FORCE scope=both sid='*'" sql-show="" chart-mode="-1">
select upper(value) from v$parameter where name = 'cursor_sharing'
</SQLString>
<SQLString title="检查参数 [filesystemio_options]" title-en="Check Parameter [filesystemio_options]" status="1" rela1="==" rela2="!=" rela3="" value1="ASYNCH" value2="ASYNCH" value3="" description="alter system set filesystemio_options=ASYNCH scope=both sid='*'" description-en="alter system set filesystemio_options=ASYNCH scope=both sid='*'" sql-show="" chart-mode="-1">
select upper(value) RST from v$parameter where name = 'filesystemio_options'
</SQLString>
<SQLString title="检查参数 [statistics_level]" title-en="Check Parameter [statistics_level]" status="1" rela1="==" rela2="!=" rela3="" value1="TYPICAL" value2="TYPICAL" value3="" description="alter system set statistics_level=typical scope=both sid='*'" description-en="alter system set statistics_level=typical scope=both sid='*'" sql-show="" chart-mode="-1">
select upper(value) RST from v$parameter where name = 'statistics_level'
</SQLString>
<SQLString title="检查参数 [session_cached_cursors]" title-en="Check Parameter [session_cached_cursors]" status="1" rela1="<=" rela2=">" rela3="" value1="50" value2="50" value3="" description="alter system set session_cached_cursors=16 scope=both sid='*'" description-en="alter system set session_cached_cursors=16 scope=both sid='*'" sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'session_cached_cursors'
</SQLString>
<SQLString title="检查参数 [job_queue_processes]" title-en="Check Parameter [job_queue_processes]" status="1" rela1="<=" rela2=">" rela3="" value1="20" value2="20" value3="" description="alter system set job_queue_processes=16 scope=both sid='*'" description-en="alter system set job_queue_processes=16 scope=both sid='*'" sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'job_queue_processes'
</SQLString>
<SQLString title="检查参数 disk_asynch_io" title-en="Check Parameter [disk_asynch_io]" status="1" rela1="==" rela2="!=" rela3="" value1="TRUE" value2="TRUE" value3="" description="alter system set disk_asynch_io=TRUE scope=spfile sid='*' --启停异步IO" description-en="alter system set disk_asynch_io=TRUE scope=spfile sid='*' " sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'disk_asynch_io'
</SQLString>
<SQLString title="检查参数 [_undo_autotune]" title-en="Check Parameter [_undo_autotune]" status="1" rela1="<=" rela2=">" rela3="" value1="FALSE" value2="FALSE" value3="" description="alter system set "_undo_autotune"=FALSE scope=both sid='*' --UNDO自动调优控制" description-en="alter system set "_undo_autotune"=FALSE scope=both sid='*' " sql-show="" chart-mode="-1">
select y.ksppstvl value, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_undo_autotune' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
<SQLString title="检查参数 [control_management_pack_access]" title-en="Check Parameter [control_management_pack_access]" status="1" rela1="==" rela2="!=" rela3="" value1="DIAGNOSTIC+TUNING" value2="DIAGNOSTIC+TUNING" value3="" description="alter system set control_management_pack_access=DIAGNOSTIC+TUNING scope=both sid='*' --控制oracle自动诊断特性" description-en="alter system set control_management_pack_access=DIAGNOSTIC+TUNING scope=both sid='*' " sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'control_management_pack_access'
</SQLString>
<SQLString title="检查参数 [parallel_execution_message_size]" title-en="Check Parameter [parallel_execution_message_size]" status="1" rela1="<=" rela2=">" rela3="" value1="4096" value2="4096" value3="" description="alter system set parallel_execution_message_size=4096 scope=spfile sid='*'" description-en="alter system set parallel_execution_message_size=4096 scope=spfile sid='*'" sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'parallel_execution_message_size'
</SQLString>
<SQLString title="检查参数 [optimizer_dynamic_sampling]" title-en="Check Parameter [optimizer_dynamic_sampling]" status="1" rela1="==" rela2="!=" rela3="" value1="2" value2="2" value3="" description="optimizer_dynamic_sampling启动参数文件,启动数据库的时候指定" description-en="" sql-show="" chart-mode="-1">
select value from v$parameter where name='optimizer_dynamic_sampling'
</SQLString>
<SQLString title="检查参数 [audit_trail]" title-en="Check Parameter [audit_trail]" status="1" rela1="==" rela2="!=" rela3="" value1="NONE" value2="NONE" value3="" description="alter system set audit_trail=NONE scope=spfile sid='*'" description-en="alter system set audit_trail=NONE scope=spfile sid='*'" sql-show="" chart-mode="-1">
select upper(value) from v$parameter where name = 'audit_trail'
</SQLString>
<SQLString title="检查参数 [_b_tree_bitmap_plans]" title-en="Check Parameter [_b_tree_bitmap_plans]" status="1" rela1="==" rela2="!=" rela3="" value1="FALSE" value2="FALSE" value3="" description="alter system set "_b_tree_bitmap_plans"=false scope=both sid='*'" description-en="alter system set "_b_tree_bitmap_plans"=false scope=both sid='*'" sql-show="" chart-mode="-1">
select y.ksppstvl value, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_b_tree_bitmap_plans' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
<SQLString title="检查参数[_lm_rcvr_hang_allow_time]" title-en="Check Parameter [_lm_rcvr_hang_allow_time]" status="1" rela1="==" rela2="!=" rela3="" value1="300" value2="300" value3="" description="alter system set "_lm_rcvr_hang_allow_time"=300 scope=both sid='*'" description-en="alter system set "_lm_rcvr_hang_allow_time"=300 scope=both sid='*'" sql-show="" chart-mode="-1">
select y.ksppstvl value, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_lm_rcvr_hang_allow_time' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
<SQLString title="检查参数 [PASSWORD_LIFE_TIME]" title-en="Check Parameter [PASSWORD_LIFE_TIME]" status="1" rela1="==" rela2="!=" rela3="" value1="UNLIMITED" value2="UNLIMITED" value3="" description="" description-en="">
SELECT LIMIT RST FROM dba_profiles s WHERE s.profile='DEFAULT' AND resource_name='PASSWORD_LIFE_TIME'
</SQLString>
<SQLString title="检查参数 [FAILED_LOGIN_ATTEMPTS]" title-en="Check Parameter [FAILED_LOGIN_ATTEMPTS]" status="1" rela1="==" rela2="!=" rela3="" value1="UNLIMITED" value2="UNLIMITED" value3="" description="" description-en="">
SELECT LIMIT RST FROM dba_profiles s WHERE s.profile='DEFAULT' AND resource_name='FAILED_LOGIN_ATTEMPTS'
</SQLString>
<SQLString title="检查参数 [_clusterwide_global_transactions]" title-en="Check Parameter [_clusterwide_global_transactions]" status="1" rela1="<=" rela2=">" rela3="" value1="FALSE" value2="FALSE" value3="" description="alter system set "_clusterwide_global_transactions"=false scope=spfile sid='*'" description-en="alter system set "_clusterwide_global_transactions"=false scope=spfile sid='*'" sql-show="" chart-mode="-1">
select y.ksppstvl value, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_clusterwide_global_transactions' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
<SQLString title="检查参数 [recyclebin]" title-en="Check Parameter [recyclebin]" status="1" rela1="==" rela2="!=" rela3="" value1="OFF" value2="OFF" value3="" description="alter system set recyclebin=OFF scope=spfile sid='*'" description-en="alter system set recyclebin=OFF scope=spfile sid='*'" sql-show="" chart-mode="-1">
select upper(value) from v$parameter where name = 'recyclebin'
</SQLString>
<SQLString title="检查参数 optimizer_index_caching" title-en="Check the oracle parameter optimizer_index_caching" status="1" rela1="==" rela2="!=" rela3="" value1="90" value2="90" value3="" description="alter system set optimizer_index_caching=90 scope=both sid='*'" description-en="alter system set optimizer_index_caching=90 scope=both sid='*'" sql-show="" chart-mode="-1">
select value from v$parameter where name = 'optimizer_index_caching'
</SQLString>
<SQLString title="检查参数 [optimizer_index_cost_adj]" title-en="Check Parameter [optimizer_index_cost_adj]" status="1" rela1="<=" rela2=">" rela3="" value1="30" value2="30" value3="" description="alter system set optimizer_index_cost_adj=10 scope=both sid='*'" description-en="alter system set optimizer_index_cost_adj=10 scope=both sid='*'" sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'optimizer_index_cost_adj'
</SQLString>
<SQLString title="检查参数 [undo_retention]" title-en="Check Parameter [undo_retention]" status="1" rela1="<=" rela2=">" rela3="" value1="10800" value2="10800" value3="" description="alter system set undo_retention=10800 scope=both sid='*'" description-en="alter system set undo_retention=10800 scope=both sid='*'" sql-show="" chart-mode="-1">
select value RST from v$parameter where name = 'undo_retention'
</SQLString>
<SQLString title="检查参数[_optim_peek_user_binds]" title-en="Check Parameter [_optim_peek_user_binds]" status="1" rela1="==" rela2="!=" rela3="" value1="TRUE" value2="TRUE" value3="" sql-show="" description=" alter system set "_optim_peek_user_binds"=true scope=both sid='*'" description-en=" alter system set "_optim_peek_user_binds"=true scope=both sid='*'" chart-mode="-1">
select y.ksppstvl value, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_optim_peek_user_binds' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
</folder>
<folder title="ORACLE 特性开关" expand="1" title-en="ORACLE 11g new feature">
<SQLString title="检查参数[deferred_segment_creation]" title-en="Check Parameter [deferred_segment_creation]" status="1" rela1="==" rela2="!=" rela3="" value1="FALSE" value2="FALSE" value3="" sql-show="" description=" alter system set "deferred_segment_creation"=false scope=both sid='*'" description-en=" alter system set "deferred_segment_creation"=false scope=both sid='*'" chart-mode="-1">
select value from v$parameter where name='deferred_segment_creation'
</SQLString>
<SQLString title="检查参数[_gc_policy_time]" title-en="Check Parameter [_gc_policy_time]" status="1" rela1="==" rela2="!=" rela3="" value1="0" value2="0" value3="" sql-show="" description=" alter system set "_gc_policy_time"=0 scope=spfile sid='*'" description-en=" alter system set "_gc_policy_time"=0 scope=spfile sid='*'" chart-mode="-1">
select y.ksppstvl value, x.ksppinm name, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_gc_policy_time' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
<SQLString title="检查参数[_gc_undo_affinity]" title-en="Check Parameter [_gc_undo_affinity]" status="1" rela1="==" rela2="!=" rela3="" value1="FALSE" value2="FALSE" value3="" sql-show="" description=" alter system set "_gc_undo_affinity"=false scope=spfile sid='*'" description-en=" alter system set "_gc_undo_affinity"=false scope=spfile sid='*'" chart-mode="-1">
select y.ksppstvl value, x.ksppinm name, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_gc_undo_affinity' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
<SQLString title="检查参数[parallel_force_local]" title-en="Check Parameter [parallel_force_local]" status="1" rela1="==" rela2="!=" rela3="" value1="TRUE" value2="TRUE" value3="" sql-show="" description=" alter system set "parallel_force_local"=TRUE scope=both sid='*'" description-en=" alter system set "parallel_force_local"=TRUE scope=both sid='*'" chart-mode="-1">
select value from v$parameter where name='parallel_force_local'
</SQLString>
<SQLString title="检查参数[_memory_broker_stat_interval]" title-en="Check Parameter [_memory_broker_stat_interval]" status="1" rela1="==" rela2="!=" rela3="" value1="999" value2="999" value3="" sql-show="" description=" alter system set "_memory_broker_stat_interval"=999 scope=both sid='*'" description-en=" alter system set "_memory_broker_stat_interval"=999 scope=both sid='*'" chart-mode="-1">
select y.ksppstvl value, x.ksppinm name, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_memory_broker_stat_interval' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
<SQLString title="检查参数[_use_adaptive_log_file_sync]" title-en="Check Parameter [_use_adaptive_log_file_sync]" status="1" rela1="==" rela2="!=" rela3="" value1="FALSE" value2="FALSE" value3="" sql-show="" description=" alter system set "_use_adaptive_log_file_sync"=false scope=both sid='*'" description-en=" alter system set "_use_adaptive_log_file_sync"=false scope=both sid='*'" chart-mode="-1">
select y.ksppstvl value, x.ksppinm name, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_use_adaptive_log_file_sync' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
<SQLString title="检查参数 [_use_single_log_writer]" title-en="Check Parameter [_use_single_log_writer]" status="1" rela1="==" rela2="!=" rela3="" value1="TRUE" value2="TRUE" value3="" sql-show="" description=" alter system set "_use_single_log_writer"=true scope=spfile sid='*'" description-en=" alter system set "_use_single_log_writer"=true scope=spfile sid='*'" chart-mode="-1">
select y.ksppstvl value, x.ksppinm name, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_use_single_log_writer' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
</folder>
<folder title="ORACLE 配置及空间检查" expand="1" title-en="ORACLE 12C configruation and space check">
<SQLString title="检查自动维护任务配置" title-en="Check Auto table state collect" status="1" rela1="==" rela2="<" rela3="" value1="3" value2="3" value3="" sql-show="select t.client_name, t.status from dba_autotask_client t union all select window_name,autotask_status from dba_autotask_window_clients" description="要求:关闭auto space advisor和sql tuning advisor,打开auto optimizer stats collection" description-en="" chart-mode="-1">
--三个项满足要求的需要count=3 select count(*) from dba_autotask_client t where t.client_name='auto optimizer stats collection' and STATUS='ENABLED' or t.client_name='auto space advisor' and STATUS='DISABLED' or t.client_name='sql tuning advisor' and STATUS='DISABLED'
</SQLString>
<SQLString title="检查是否开启用户登录触发器" title-en="Check User Logon Trigger" status="1" rela1="==" rela2="!=" rela3="" value1="0" value2="0" value3="" sql-show="select * from dba_triggers a where trim(a.triggering_event) = 'LOGON' and status ='ENABLED'" description="" description-en="" chart-mode="-1">
select count(*) from dba_triggers a where trim(a.triggering_event) = 'LOGON' and status ='ENABLED'
</SQLString>
<SQLString title="检查数据库专有连接方式" title-en="Check DB connection DEDICATED" status="1" rela1="==" rela2="!=" rela3="" value1="0" value2="0" value3="" sql-show="" description="" description-en="" chart-mode="-1">
select count(*) from v$session where SERVER<>'DEDICATED'
</SQLString>
<SQLString title="检查7天内Oracle进程数是否达上线80%" title-en="Check Processes catch 80% in last week" status="1" rela1="==" rela2="!=" rela3="" value1="0" value2="0" value3="" sql-show="select * from dba_hist_resource_limit a, dba_hist_snapshot b where a.snap_id = b.snap_id and a.resource_name in('processes', 'session') and b.begin_interval_time >= sysdate - 7 and a.max_utilization / a.limit_value >= 0.8" description="" description-en="" chart-mode="-1">
select count(*) from dba_hist_resource_limit a, dba_hist_snapshot b where a.snap_id = b.snap_id and a.resource_name in('processes', 'session') and b.begin_interval_time >= sysdate - 7 and a.max_utilization / a.limit_value >= 0.8
</SQLString>
</folder>
<folder title="RAC中SGA超过100G最佳实践" expand="1" title-en="Best Practices and Recommendations for RAC databases with SGA size over 100GB">
<SQLString title="检查参数[shared_pool_size >15%SGA]" title-en="Check Parameter [shared_pool_size]" status="1" rela1=">=" rela2="<" rela3="" value1="15" value2="15" value3="" description="shared_pool_size启动参数文件,启动数据库的时候指定" description-en="" sql-show="" chart-mode="-1">
select round(100*a.value/b.value,2) from (select value from v$parameter where name='shared_pool_size') a, (select value from (select value from v$parameter where name='sga_target' union all select value from v$parameter where name='sga_max_size' union all select value from v$parameter where name='memory_max_target') d where value>'0' and rownum<2) b
</SQLString>
<SQLString title="检查参数 [_lm_sync_timeout]" title-en="Check Parameter [_lm_sync_timeout]" status="1" rela1="==" rela2="!=" rela3="" value1="1200" value2="1200" value3="" sql-show="" description=" alter system set "_lm_sync_timeout"=1200 scope=spfile sid='*'" description-en=" alter system set "_lm_sync_timeout"=1200 scope=spfile sid='*'" chart-mode="-1">
select y.ksppstvl value, x.ksppinm name, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_lm_sync_timeout' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
<SQLString title="检查参数 [_lm_tickets]" title-en="Check Parameter [_lm_tickets]" status="1" rela1="==" rela2="!=" rela3="" value1="5000" value2="5000" value3="" sql-show="" description=" alter system set "_lm_tickets"=5000 scope=spfile sid='*'" description-en=" alter system set "_lm_tickets"=5000 scope=spfile sid='*'" chart-mode="-1">
select y.ksppstvl value, x.ksppinm name, y.ksppstdf isdefault, decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod, decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj 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 = '_lm_tickets' order by translate(x.ksppinm, ' _', ' ')
</SQLString>
</folder>
</root>
ceph论文中英文摘要
Ceph是一款具有卓越性能、高可靠和高扩展性的分布式文件系统,其使用的伪随机分配算法(CRUSH),高度分离了数据和元数据的存放,并将本来不可靠的数据节点(OSD)设计成跨平台版本和动态集群。
Ceph以PB级的容量规模的文件系统为设计单位,提供了高性能的IO、高可用、高吞吐、高扩展性和动态的元数据处理能力,以及强大而安全的数据分布、复制、故障处理和容错特性,在读写性能和延迟方面表现也异常出色。元数据节点(MDS)和数据节点(OSD)扩张简便,元数据和数据自动均衡数据的功能强大而高效。
以上的这些特性,基本上可以满足当前对分布式文件文件系统高性能、高可靠性和高扩展性的要求,胜于市面上一些已有的分布式文件系统产品。
在后续的版本中,ceph会加强元数据节点的高可用性,以及一些沟通协议和架构的安全性。同时,Ceph正努力提供服务质量体系结构,以允许基于聚合类的流量优先级和基于OSD管理的预留带宽和延迟保障。
Ceph, a distributed file system that provides excellent performance, reliability, and scalability. Ceph maximizes the separation between data and metadata management by replacing allocation tables with a pseudo-random data distribution function (CRUSH) designed for heterogeneous and dynamic clusters of unreliable object storage devices (OSDs).
Ceph is designed of a large file system which provides petabytes of highly performance I/O computing ability, highly reliable storage, huge throughout extended, highly scalability and dynamic metadata processing capacity, which also combines robust and safe rebalance , replication, failure handling and fault-tolerance ability , provides extraordinary read/write I/O performance and low latency. Metadata server(MDS) and data server(OSD) offers flexible scalability for adding nodes, with efficient and powerful auto-rebalance function among nodes.
According to characteristic mentioned above, Ceph almost satisfies main quests about high performance, reliability and scalability for distribution file system product in the market, which performs better than the same existing products.
In the following development version, Ceph aims to enhance the high availability of MDS server, part of communication protocol and security of architecture. In addition, Ceph is working for offer a quality of service architecture to allow both aggregate class-based traffic prioritization and OSD-managed reserva-tion based bandwidth and latency guarantees.
rman备份
2.2. RMAN备份
2.2.1. 控制文件自动备份
语法:
CONFIGURE CONTROLFILE AUTOBACKUP ON;
如果CONFIGURE CONTROLFILE AUTOBACKUP 设置为ON,则在以下情况下,RMAN自动执行控制文件的自动备份:
- 在RMAN 提示符下执行每个BACKUP 或COPY 命令后
- 当RUN 命令块中BACKUP 或COPY 命令后跟的既不是BACKUP 也不是COPY 时
- 当每个RUN 命令块结尾处的最后一条命令既不是BACKUP 也不是COPY 时在执行这些命令过程中,除了执行当前控制文件的备份或复制外,还进行控制文件的自动备份。
- 当数据库结构发生改变时,比如新增加了数据文件
缺省情况下,CONFIGURE CONTROLFILE AUTOBACKUP 设置为OFF。
2.2.2. RMAN备份脚本(0级全备)
备份顺序:
- database:主要备份所有的数据文件,临时文件不备份
- 归档当前redo:因为在备份database过程中,数据也会发生变化,这样会导致数据文件SCN号不一致,而正常情况下要open数据库,所有数据文件中所有数据块和文件头本身的SCN都必须要一样数据库才能open。这时在恢复数据库时,就需要使用备份database中的生成的所有归档,所以备份database完成之后需要归档当前redo,这样后面备份归档时才能将备份database过程中的所有归档备份下来。
- 归档日志:将归档目录下的所有归档文件备份。
- 控制文件自动备份:备份控制文件。因为恢复数据库时,不适用恢复目录(catalog)数据库的情况下,备份信息都在控制文件中,所以需要在最后备份控制文件,这样才能看到之前所有的备份信息。
run {
# Hot database level 0 whole backup
allocate channel t1 type disk;
backup
incremental level 0
skip inaccessible
filesperset 6
# recommended format
format '/backup/bk_%s_%p_%T'
(database);
sql 'alter system archive log current';
# backup all archive logs
backup
skip inaccessible
filesperset 10
format '/backup/db/bk_%s_%p_%t'
(archivelog all -->delete input表示备份完归档以后删除归档文件,这样可以释放归档目录的空间
delete input);
}
正常在除了每天定时做一次全库备份以外,一般还要定时(半小时)备份一次归档日志,防止归档路径满了。
run {
allocate channel t1 type disk;
sql 'alter system archive log current';
# backup all archive logs
backup
skip inaccessible
filesperset 10
format '/backup/db/bk_%s_%p_%t'
(archivelog all
delete input);
}
第3课:RMAN恢复
一般在运行RMAN前,建议设一下ORACLE客户端的时间格式,这样看的时间更精确一些,否则默认只能显示到年月日
su - oracle
export NLS_DATE_FORMAT=”YYYY-MM-DD HH24:MI:SS”
3.1. 灾难恢复
3.1.1. dummy instance
Dummy parameter file:使用rman启动数据库时,如果spfile和pfile都已经丢失的话,数据库会自动使用一个默认的初始化参数文件来启动数据库,我们把这种情况叫使用Dumy parameter file启动数据库。使用dumy parameter file启动数据库就是为了恢复spfile,恢复完spfile以后,我们需要重新用spfile正常启动数据库。
使用dumy parameter file启动数据库的过程如下
RMAN> startup nomount
connected to target database (not started)
startup failed: ORA-01078: failure in processing system parameters
LRM-00109: could not open parameter file '/oracle/app/oracle/product/11.1.0/db_1/dbs/initora11g.ora'
-->提示找不到pfile启动数据库,数据库先找spfile,再找pfile,pfile都找不到就表示spfile也没有了。
starting Oracle instance without parameter file for retrieval of spfile --> 出现这个提示时表示使用了dummy parameter file
Oracle instance started
Total System Global Area 158662656 bytes
Fixed Size 2119304 bytes
Variable Size 79694200 bytes
Database Buffers 71303168 bytes
Redo Buffers 5545984 bytes
alert日志中也可以看到明显的标志
Sat Feb 16 11:14:13 2013
Starting ORACLE instance (restrict)
LICENSE_MAX_SESSION = 0
LICENSE_SESSIONS_WARNING = 0
Picked latch-free SCN scheme 3
Using LOG_ARCHIVE_DEST_1 parameter default value as /oracle/app/oracle/product/11.1.0/db_1/dbs/arch
Autotune of undo retention is turned on.
IMODE=BR
ILAT =12
LICENSE_MAX_USERS = 0
SYS auditing is disabled
Starting up ORACLE RDBMS Version: 11.1.0.7.0.
Using parameter settings in client-side pfile /var/tmp/ora_tfil003820 on machine rx6600a
System parameters with non-default values:
sga_target = 152M
compatible = "11.1.0.7.0"
_dummy_instance = TRUE
remote_login_passwordfile= "EXCLUSIVE"
db_name = "ORA11G"
3.1.2. Set dbid
执行rman target / [nocatalog]表示不使用恢复目录(catalog recovery),这时候恢复控制文件时需要指定DB ID,RMAN需要根据DBID和autobackup的路径和格式来找到控制文件的自动备份。但是实际上我们测试不指定DB ID时也可以找到正确的控制文件的自动备份。
If you are not using a recovery catalog, then you must restore your control file from an
autobackup. To restore the control file from autobackup, the database must be in a
NOMOUNT state. As shown in Example 19–2, you must first set the DBID for your
database, and then use the RESTORE CONTROLFILE FROM AUTOBACKUP command.
Example 19–2 Setting the DBID and Restoring the Control File from Autobackup
SET DBID 320066378;
RUN
{
SET CONTROLFILE AUTOBACKUP FORMAT
FOR DEVICE TYPE DISK TO 'autobackup_format';
RESTORE CONTROLFILE FROM AUTOBACKUP;
}
RMAN uses the autobackup format and DBID to determine where to hunt for the
control file autobackup. If one is found, RMAN restores the control file to
3.1.3. open resetlogs
Open resetlogs表示打开数据库时将current redo的sequence号重置到1。以下情况下必须指定resetlogs
1)不完全恢复或者使用控制文件备份恢复了控制文件
2)上次open resetlogs没有成功。这里的没有成功指的是open时还没有到重置current redo的阶段,如果open resetlogs失败了,但是alert日志中显示redo已经被重置以后失败,下次open时是不需要指定resetlogs的。
3)做了flashback database以后
alert日志如下
Sun Feb 17 10:59:22 2013
alter database open resetlogs --> open resetlogs开始执行
Sun Feb 17 10:59:38 2013
Archived Log entry 39 added for thread 1 sequence 189 ID 0xfa3558b8 dest 1: --> 在重置redo之前需要先归档一下
Sun Feb 17 10:59:54 2013
Archived Log entry 40 added for thread 1 sequence 190 ID 0xfa3558b8 dest 1:
Sun Feb 17 11:00:06 2013
Archived Log entry 41 added for thread 1 sequence 191 ID 0xfa3558b8 dest 1:
RESETLOGS after incomplete recovery UNTIL CHANGE 3789999 --> 提示是不完全恢复以后resetlogs
Resetting resetlogs activation ID 4197800120 (0xfa3558b8)
Sun Feb 17 11:00:37 2013
Online log /oracle/app/oradata/ora11g/redo006.log: Thread 2 Group 3 was previously cleared --> reselogs之前redo是unused状态,sequence号是0
Sun Feb 17 11:00:52 2013
Online log /oracle/app/oradata/ora11g/redo003.log: Thread 2 Group 5 was previously cleared
Online log /oracle/app/oradata/ora11g/redo004.log: Thread 2 Group 6 was previously cleared
Sun Feb 17 11:00:54 2013
Setting recovery target incarnation to 2 -->更改场景号
Sun Feb 17 11:00:54 2013
Assigning activation ID 4203807790 (0xfa91042e)
LGWR: STARTING ARCH PROCESSES
Sun Feb 17 11:00:54 2013
ARC0 started with pid=22, OS id=28750
Sun Feb 17 11:00:54 2013
ARC1 started with pid=23, OS id=28752
Sun Feb 17 11:00:54 2013
ARC2 started with pid=24, OS id=28754
ARC0: Archival started
Sun Feb 17 11:00:54 2013
ARC3 started with pid=25, OS id=28756
LGWR: STARTING ARCH PROCESSES COMPLETE
Thread 1 opened at log sequence 1 --> redo的sequence重置到1了,如果在这个之后报错,下次open数据库时就不需要指定resetlogs了
Current log# 1 seq# 1 mem# 0: /oracle/app/oradata/ora11g/redo001.log
Successful open of redo thread 1
ARC1: Becoming the 'no FAL' ARCH
ARC1: Becoming the 'no SRL' ARCH
ARC3: Becoming the heartbeat ARCH
MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set
...
后面的就和一般open一样了
3.2. 跨场景恢复
3.2.1. 场景(incarnation)
每执行一次RESETLOGS时都会产生一个新的incarnation,因为每次resetlogs时redo都会重置,但是SCN号不会重置,这样就存在不同的redo中有相同的SCN号,这样如果我们下次再做恢复时,数据库就不知道用哪一个redo了(不管是until time, until sequence, until scn,数据库内部都是用SCN),所以数据库定义了场景号来区分。
关联视图:V$DATABASE_INCARNATION
RMAN命令:LIST INCARNATION
场景号迁移图如下:可以看到场景1和场景2都有SCN 2000,场景2和场景3都有SCN 3000
3.2.2. RESET DATABASE TO INCARNATION
如果恢复到之前的场景号里面的某一个时间点,就需要重置场景号,这样数据库恢复时才会用正确的归档。
如果RMAN没有使用恢复目录(rman target /时),必须mount数据库以后才能RESET DATABASE TO INCARNATION x。
如果RMAN使用了恢复目录时,nomount和mount状态都可以执行RESET DATABASE TO INCARNATION x。
第4课:RMAN详细介绍
RMAN调用存在于内核中的DBMS_BACKUP_RESTORE,所以不需要打开数据库,NOMOUNT状态下就可以使用。
RMAN必须使用dedicated server模式进行连接。
4.1. RMAN主要组件
Auxliary DB:辅助DB,用于不完全恢复。
Standby DB:A copy of the primary database that is updated using archived logs created by the primary database. RMAN can create or back up a standby database. You can fail over to the standby database if the primary database goes down.
Duplicate DB:A copy of the primary database that you can use for testing purposes.
轮询进程(POLLING PROCESS):监视和报告备份或还原操作的进展。
存储仓库(REPOSITORY):存储了与目标数据库及其备份相关的元数据,并包含目标数据库物理结果的详细信息:
1)数据文件的位置
2)已完成所有备份的细节
3)RMAN的永久配置设置。
一般控制文件里面就是RMAN的REPOSITORY,还有一种是恢复目录(recover catalog)
Snapshot control file:need only when resynchronizing with the recovery catalog or when making a backup of the current conrol file.
恢复目录(recover catalog):恢复目录是另外一个数据库,专门用来保存一个或多个数据库的元信息(metadata,如文件,备份等信息)
4.2. RMAN基本概念
4.2.1 RMAN执行模式
单语句模式,JOB模式(RUN块),BATCH(文件)模式,管道接口四种模式。
4.2.2. 通道分配
CHANNEL名称:ORA_devicetype_n
ORA_MAINT_devicetype_n
4.2.3. 备份分类
执行一次BACKUP命令以后就会生成一个备份集(backup set),一个备份集可能包括多个备份片(backup piece)
一个datafile不能保存在两个备份集中,所以要保证MAXSETSIZE>备份对象datafile的大小。
No. | 备份 | 定义 | 说明 |
---|---|---|---|
1 | full backup | 包含所有的数据块 | 不适用在增量备份中 |
2 | level 0 backup | 包含所有的数据块 | 可使用在增量备份中 |
3 | level 1 backup | Differential backup | after level 1 or 0 |
4 | level 1 backup | cumulative backup(default) | after level 0 |
以下情况会进行自动备份
After every BACKUP or CREATE CATALOG command issued at the RMAN prompt.
■ Whenever a BACKUP command within a RUN block is followed by a command that is not BACKUP.
■ At the end of every RUN block if the last command in the block was BACKUP.
■ After structural changes for databases in ARCHIVELOG mode.
The autobackup after structural changes does not occur for databases in NOARCHIVELOG mode. Structural changes include adding tablespaces, altering the state of a tablespace or datafile (for example, bringing it online), adding a new online redo log, renaming a file, adding a new redo thread, enabling or disabling Flashback Database, and so on. This type of autobackup, unlike autobackups that occur in the preceding circumstances, is only to disk. You can run CONFIGURE ONTROLFILE AUTOBACKUP FOR DEVICE TYPE DISK to set a nondefault disk location.
list backup举例:
BS Key Type LV Size Device Type Elapsed Time Completion Time --> BS key:备份集key值,TYPE full表示全备
------- ---- -- ---------- ----------- ------------ ---------------
2 Full 670.02M DISK 00:02:43 05-FEB-13
BP Key: 2 Status: AVAILABLE Compressed: NO Tag: TAG20130205T105316
Piece Name: /oracle/backup/dbbackup_03o16uss_1_1 -->备份片,这个备份集只有一个备份片
List of Datafiles in backup set 2
File LV Type Ckp SCN Ckp Time Name
---- -- ---- ---------- --------- ----
1 Full 3788999 04-FEB-13 /oracle/app/oradata/ora11g/system01.dbf -->备份的内容,本例是数据文件的备份
2 Full 3788999 04-FEB-13 /oracle/app/oradata/ora11g/sysaux01.dbf
3 Full 3788999 04-FEB-13 /oracle/app/oradata/ora11g/undotbs01.dbf
4 Full 3788999 04-FEB-13 /oracle/app/oradata/ora11g/users01.dbf
5 Full 1481460 30-DEC-12 /oracle/app/oradata/ora11g/test1.dbf
6 Full 1481460 30-DEC-12 /oracle/app/oradata/ora11g/test2.dbf
BS Key Type LV Size Device Type Elapsed Time Completion Time
------- ---- -- ---------- ----------- ------------ ---------------
3 Full 9.36M DISK 00:00:04 05-FEB-13
BP Key: 3 Status: AVAILABLE Compressed: NO Tag: TAG20130205T105602
Piece Name: /oracle/app/oracle/product/11.1.0/db_1/dbs/c-4197782200-20130205-00
SPFILE Included: Modification time: 05-FEB-13 -->看到备份集中有spfile和控制文件的备份时,表示是autobackup
SPFILE db_unique_name: ORA11G
Control File Included: Ckp SCN: 3788999 Ckp time: 04-FEB-13
4.2.4. Retention Policy和Flash Recovery Area: disk quota Rules
① 备份状态
OBSOLETE:NOT NEEDED,表示过旧的备份,主要受保存策略控制
EXPIRED:NOT FOUND,表示找不到了,在RMAN中可以看到,但是实际上已经没有了(如在操作系统中被删掉了)
命令:REPORT OBSOLETE
DELETE OBSOLETE
② 保存策略(Retention Policy)
1)Redundancy:基于数量
2)Recover Window:基于时间
必须保证窗口区域内的时间点都可以恢复,因此会出现比窗口区域更早的备份处于not obsolete状态。
例外:通过以下方法可以使得备份不会变成obsolete状态
USING KEEP
LOGS:save archive log
UNTIL keeptime
③ Flash Recovery Area
如果配置了Flash Recovery Area,则数据库会使用一个内部算法来删掉那些已经变为obsolete(Retention Policy不在需要)的文件,从而满足Flash Recovery Area的disk quota rules。如果archive log已经备份到磁带,根据Retention Policy判断还没有变为obsolete,但是这时disk quota rules认为该文件已经备份,所以可以删除。也就是说disk quota rules会违反Retention Policy,但是Retention Policy不会违反disk quota rules。
所以retention policy 不要和disk quota rules相矛盾。
Flash recovery area中的文件不能被设为unavaliable或者keep。
4.2.5. Block Corruption
MAXCORRUPT:最大容错个数,超过该错误后备份出错并停止。
视图:V$DATABASE_BLOCK_CORRUPTION
Check corruption:
BACKUP … VALIDATE;
执行以后会将corruption info写入到V$DATABASE_BLOCK_CORRUPTION中
4.2.6. split mirror
分裂镜像,可以用来作为备份。
4.3. RMAN命令相关
format:%d:生成数据库名
%u:保证唯一性
%t:four bytes time stamp
%s:backup set number
%p:backup piece number
PROXY COPY:如果Media Manager支持PROXY COPY 的话,RMAN将数据控制交给Media Manager。只适用于Media Manager,Disk不适用。
BACKUP DEVICE TYPE sbt PROXY DATAFILE 3;
如果Media Manager不支持PROXY COPY,则RMAN备份该文件。
BACKUP DEVICE TYPE sbt PROXY ONLY DATABASE;
如果Media Manager不支持PROXY COPY,则该语句执行失败。
注意:control files不适用PROXY,会自动忽略。
Backup of Archive log
LOCATION=USE_DB_RECOVERY_FILE_DES:指定archive log备份备份到flash recovery area中。
SET ARCHIVELOG DESTINATION:直接指定archive log的restore位置。
SBT_LIBRARY :RMAN参数,指定Media Management Library。
DUPLEX:只适用于backup sets,不能用于image copies。
Norepository:不能使用configure命令,只能使用allocate。
DBID:需要恢复control file时,需要使用SET DBID指定DBID。
DBID可以从自动备份control file文件名得到,也可以在执行rman target / 从提示信息里得到。
CROSSCHEK:交叉检查
No. | STATUS | 说明 |
---|---|---|
1 | AVALIABLE | |
2 | EXPIRED | DELETE EXPIRED删除 |
3 | UNAVALIABLE | DELETE不会删除,但也不能用来restore和recover |
REPORT:
No. | 命令 | 说明 |
---|---|---|
1 | REPORT NEED BACKUP | 列出需要备份的文件(基于Retention Policy) |
2 | REPORT UNRECOVERABLE | 如果进行了一些unrecoverable的操作,则datafile会变为unrecoverable |
3 | REPORT OBSOLETE |
DELETE:
No. | 命令 | 说明 |
---|---|---|
1 | DELETE NOPROMPT | 删除过程中不提示确认 |
2 | DELETE EXPIRED | 删除过期失效的文件 |
3 | DELETE OBSOLETE | 删除过期无用的文件 |
4 | DELETE FORCE | 不管文件是否存在,强制删除repository中的记录。 |
RECOVER … TEST:trouble shoot
RESETLOGS:reset log sequence number to 1. 用于不完全恢复时。
FORMAT可使用在下列命令中
No. | 命令 |
---|---|
1 | BACKUP |
2 | CONFIGURE CHANNEL |
3 | ALLOCATE CHANNEL |
CATALOG
No. | 命令 |
---|---|
1 | CATALOG DATAFILE COPY |
2 | CATALOG ARCHIVELOG |
3 | CATALOG BACKUP PIECE |
4 | CATALOG START WITH ‘directory_prefix’ or ‘directory/’ |
DG_phy_stby_diag.sql
-- NAME: DG_phy_stby_diag.sql
-- ------------------------------------------------------------------------
-- AUTHOR:
-- Michael Smith - Oracle Support Services - DataServer Group
-- Copyright 2002, Oracle Corporation
-- ------------------------------------------------------------------------
-- PURPOSE:
-- This script is to be used to assist in collection information to help
-- troubeshoot Data Guard issues.
-- ------------------------------------------------------------------------
-- DISCLAIMER:
-- This script is provided for educational purposes only. It is NOT
-- supported by Oracle World Wide Technical Support.
-- The script has been tested and appears to work as intended.
-- You should always run new scripts on a test instance initially.
-- ------------------------------------------------------------------------
-- Script output is as follows:
set echo off
set feedback off
column timecol new_value timestamp
column spool_extension new_value suffix
select to_char(sysdate,'Mondd_hhmi') timecol,
'.out' spool_extension from sys.dual;
column output new_value dbname
select value || '_' output
from v$parameter where name = 'db_name';
spool dgdiag_phystby_&&dbname&×tamp&&suffix
set lines 200
set pagesize 35
set trim on
set trims on
alter session set nls_date_format = 'MON-DD-YYYY HH24:MI:SS';
set feedback on
select to_char(sysdate) time from dual;
set echo on
--
-- ARCHIVER can be (STOPPED | STARTED | FAILED) FAILED means that the archiver failed
-- to archive a -- log last time, but will try again within 5 minutes. LOG_SWITCH_WAIT
-- The ARCHIVE LOG/CLEAR LOG/CHECKPOINT event log switching is waiting for. Note that
-- if ALTER SYSTEM SWITCH LOGFILE is hung, but there is room in the current online
-- redo log, then value is NULL
column host_name format a20 tru
column version format a9 tru
select instance_name,host_name,version,archiver,log_switch_wait from v$instance;
-- The following select will give us the generic information about how this standby is
-- setup. The database_role should be standby as that is what this script is intended
-- to be ran on. If protection_level is different than protection_mode then for some
-- reason the mode listed in protection_mode experienced a need to downgrade. Once the
-- error condition has been corrected the protection_level should match the protection_mode
-- after the next log switch.
column ROLE format a7 tru
select name,platform_id,database_role role,log_mode,
flashback_on flashback,protection_mode,protection_level
from v$database;
-- Force logging is not mandatory but is recommended. Supplemental logging should be enabled
-- on the standby if a logical standby is in the configuration. During normal
-- operations it is acceptable for SWITCHOVER_STATUS to be SESSIONS ACTIVE or NOT ALLOWED.
column force_logging format a13 tru
column remote_archive format a14 tru
column dataguard_broker format a16 tru
select force_logging,remote_archive,supplemental_log_data_pk,supplemental_log_data_ui,
switchover_status,dataguard_broker from v$database;
-- This query produces a list of all archive destinations and shows if they are enabled,
-- what process is servicing that destination, if the destination is local or remote,
-- and if remote what the current mount ID is. For a physical standby we should have at
-- least one remote destination that points the primary set but it should be deferred.
COLUMN destination FORMAT A35 WRAP
column process format a7
column archiver format a8
column ID format 99
select dest_id "ID",destination,status,target,
archiver,schedule,process,mountid
from v$archive_dest;
-- If the protection mode of the standby is set to anything higher than max performance
-- then we need to make sure the remote destination that points to the primary is set
-- with the correct options else we will have issues during switchover.
select dest_id,process,transmit_mode,async_blocks,
net_timeout,delay_mins,reopen_secs,register,binding
from v$archive_dest;
-- The following select will show any errors that occured the last time an attempt to
-- archive to the destination was attempted. If ERROR is blank and status is VALID then
-- the archive completed correctly.
column error format a55 tru
select dest_id,status,error from v$archive_dest;
-- Determine if any error conditions have been reached by querying thev$dataguard_status
-- view (view only available in 9.2.0 and above):
column message format a80
select message, timestamp
from v$dataguard_status
where severity in ('Error','Fatal')
order by timestamp;
-- The following query is ran to get the status of the SRL's on the standby. If the
-- primary is archiving with the LGWR process and SRL's are present (in the correct
-- number and size) then we should see a group# active.
select group#,sequence#,bytes,used,archived,status from v$standby_log;
-- The above SRL's should match in number and in size with the ORL's returned below:
select group#,thread#,sequence#,bytes,archived,status from v$log;
-- Query v$managed_standby to see the status of processes involved in the
-- configuration.
select process,status,client_process,sequence#,block#,active_agents,known_agents
from v$managed_standby;
-- Verify that the last sequence# received and the last sequence# applied to standby
-- database.
select al.thrd "Thread", almax "Last Seq Received", lhmax "Last Seq Applied"
from (select thread# thrd, max(sequence#) almax
from v$archived_log
where resetlogs_change#=(select resetlogs_change# from v$database)
group by thread#) al,
(select thread# thrd, max(sequence#) lhmax
from v$log_history
where first_time=(select max(first_time) from v$log_history)
group by thread#) lh
where al.thrd = lh.thrd;
-- The V$ARCHIVE_GAP fixed view on a physical standby database only returns the next
-- gap that is currently blocking redo apply from continuing. After resolving the
-- identified gap and starting redo apply, query the V$ARCHIVE_GAP fixed view again
-- on the physical standby database to determine the next gap sequence, if there is
-- one.
select * from v$archive_gap;
-- Non-default init parameters.
set numwidth 5
column name format a30 tru
column value format a50 wra
select name, value
from v$parameter
where isdefault = 'FALSE';
spool off
性能优化案例分析2
- 性能优化典型案例
本节为性能问题典型案例及优化方案。
2.1 统计信息估算值不准
2.1.1 关联后结果集估计值不对
问题描述:
环境:SIT环境(Exadata UAT)
程序:MCA公共余额计算性能
时间:2014-01-21
如下脚本执行了6个多小时才完成:
SELECT /*+ PARALLEL(2) */
1106003,
MPLC.PERIOD,
MPLC.RESTATEMENT,
MPLC.COMPANY_KEY,
MPLC.COA_BU_KEY,
MPLC.BU_KEY,
MPLC.DEPT_KEY,
MPLC.GEO_PC_KEY,
MPLC.GROUP_ACCOUNT_CODE,
MPLC.SUB_ACCOUNT_CODE,
MPLC.COA_PROD_KEY,
MPLC.MAJOR_PROD_KEY,
MPLC.MINOR_PROD_KEY,
MPLC.CONTRACT_KEY,
MPLC.BAS_SALES_TEAM_KEY,
MPLC.SIGN_CUST_KEY,
MPLC.PROJ_KEY,
MPLC.SALES_MODE_KEY,
MPLC.COMPANY_ACCOUNT_CODE,
MPLC.SUBPROJ_KEY,
MPLC.COUNTER_SIGN_CONTRACT_KEY,
MPLC.BUY_FROM_IC_KEY,
MPLC.SELL_TO_IC_KEY,
MPLC.SIGN_COMPANY_KEY,
MPLC.FULFIL_COMPANY_KEY,
MPLC.SIGNING_CONTRACT_KEY,
MPLC.PRICE_MODEL,
MPLC.DELIVERY_GEO_PC_KEY,
MPLC.JE_SOURCE_ID,
MPLC.JE_CATEGORY_ID,
MPLC.DATA_CATEGORY_ID,
MPLC.INTERGEO_BALANCE_REQUIRED,
MPLC.TRANSACTION_CURRENCY,
MPLC.LOCAL_CURRENCY,
MPLC.DR_TC,
MPLC.CR_TC,
MPLC.DR_LC,
MPLC.CR_LC,
MPLC.DR_RMB_AAA,
MPLC.CR_RMB_AAA
FROM MCA_JOURNALS_T MPLC
INNER JOIN MCA_JOURNAL_SOURCE_T MCA_JESOURCE_T ON MPLC.JE_SOURCE_ID =
MCA_JESOURCE_T.JE_SOURCE_ID
and MCA_JESOURCE_T.VERSION =
'201311'
INNER JOIN MCA_JOURNAL_CATEGORY_T MCA_JECATEGORY_T ON MPLC.JE_CATEGORY_ID =
MCA_JECATEGORY_T.JE_CATEGORY_ID
and MCA_JECATEGORY_T.VERSION =
'201311'
INNER JOIN MCA_DATA_SOURCE_CONFIG_T MCA_DATASOURCECONF_T ON MCA_DATASOURCECONF_T.S_SOURCE_CODE =
MCA_JESOURCE_T.JE_SOURCE_CODE
AND MCA_DATASOURCECONF_T.S_CATEGORY_CODE =
MCA_JECATEGORY_T.JE_CATEGORY_CODE
AND MCA_DATASOURCECONF_T.S_HIERARCHY_CODE =
MPLC.HIERARCHY_CODE
AND MCA_DATASOURCECONF_T.CATEGORY_CODE =
'Alloc_GRP_PCR0008'
AND MCA_DATASOURCECONF_T.SOURCE_CODE =
'MCA-Allocation'
AND MCA_DATASOURCECONF_T.ALLOCATE_TYPE = 'O'
LEFT JOIN MCA_GROUP_ACCOUNT_T GROUP_ACCOUNT ON MPLC.GROUP_ACCOUNT_CODE =
GROUP_ACCOUNT.GROUP_ACCOUNT_CODE
AND GROUP_ACCOUNT.VERSION =
'201311'
LEFT JOIN MCA_DEPARTMENT_T DEPARTMENT ON MPLC.DEPT_KEY =
DEPARTMENT.DEPT_KEY
AND DEPARTMENT.VERSION = '201311'
LEFT JOIN MCA_GEO_RC_T GEO_RC ON MPLC.GEO_PC_KEY = GEO_RC.GEO_PC_KEY
AND GEO_RC.VERSION = '201311'
LEFT JOIN MCA_PRODUCT_T MAJOR_PRODUCT ON MPLC.MAJOR_PROD_KEY =
MAJOR_PRODUCT.PROD_KEY
AND MAJOR_PRODUCT.VERSION = '201311'
LEFT JOIN MCA_PROJECT_T PROJECT ON MPLC.PROJ_KEY = PROJECT.PROJ_KEY
LEFT JOIN MCA_CONTRACT_T CONTRACT ON MPLC.CONTRACT_KEY =
CONTRACT.CONTRACT_KEY
LEFT JOIN MCA_DATA_CATEGORY_T DATA_CATEGORY ON MPLC.DATA_CATEGORY_ID =
DATA_CATEGORY.DATA_CATEGORY_ID
AND DATA_CATEGORY.VERSION =
'201311'
WHERE '201311' <= MPLC.PERIOD
AND MPLC.PERIOD <= '201311'
AND ((MAJOR_PRODUCT.LV0_PROD_LIST_CODE <> 'PDCG901161' OR
(MAJOR_PRODUCT.LV0_PROD_LIST_CODE = 'PDCG901161' AND
GEO_RC.GEO_PC_CODE IN ('6001', '7001', '3602', '3613'))) AND
(DEPARTMENT.DEPT_EXPENSE_TYPE_CODE = 'Z7' AND
GROUP_ACCOUNT.ACCOUNT_EXPENSE_CATG_CODE IN
('E01', 'E03', 'E05', 'E06', 'E08', 'E09', 'E10', 'E11', 'E02',
'E04', 'E07', 'E12')) AND DEPARTMENT.DEPT_TAG_CODE = '09' AND
CONTRACT.HW_CONTRACT_NUM IN ('SNULL', '未知合同') AND
DATA_CATEGORY.DATA_CATEGORY_CLASS <> '10' AND
PROJECT.PROJ_NUM IN ('SNULL', '0000000') AND
GEO_RC.GEO_PC_CN_NAME NOT LIKE '%总部%')
AND PERIOD >= '201311'
AND PERIOD <= '201311'
AND RESTATEMENT = 'N';
如果去掉并行提示,一分多钟就可以执行出来。
问题分析:
加并行提示时,执行计划如下(没执行完):
SQL Plan Monitoring Details (Plan Hash Value=3773552578)
====================================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | | (Estim) | | | (Actual) | (%) |
====================================================================================================================================
| 0 | SELECT STATEMENT | | | | 1 | | |
| 1 | SORT AGGREGATE | | 1 | | 1 | | |
| 2 | PX COORDINATOR | | | | 5 | 0 | 0.61 |
| 3 | PX SEND QC (RANDOM) | :TQ10006 | 1 | | | | |
| 4 | SORT AGGREGATE | | 1 | | | | |
| 5 | HASH JOIN | | 1 | 70074 | | | |
| 6 | PX RECEIVE | | 1 | 69914 | | | |
| 7 | PX SEND BROADCAST | :TQ10005 | 1 | 69914 | | | |
| 8 | HASH JOIN | | 1 | 69914 | | | |
| 9 | PX RECEIVE | | 1 | 69857 | | | |
| 10 | PX SEND BROADCAST | :TQ10004 | 1 | 69857 | | | |
| 11 | HASH JOIN | | 1 | 69857 | | | |
| 12 | PX RECEIVE | | 1 | 69844 | | | |
| 13 | PX SEND BROADCAST | :TQ10003 | 1 | 69844 | 2 | | |
| 14 | HASH JOIN | | 1 | 69844 | 2 | 0 | |
| 15 | PX RECEIVE | | | | 2 | 140M | |
| 16 | PX SEND BROADCAST | :TQ10002 | | | 2 | 140M | |
| 17 | NESTED LOOPS | | | | 2 | 70M | |
| 18 | NESTED LOOPS | | 1 | 68856 | 2 | 571M | |
| 19 | HASH JOIN | | 1 | 68850 | 2 | 114M | |
| 20 | HASH JOIN | | 1 | 68730 | 2 | 2M | 0.61 |
| 21 | PX RECEIVE | | 1 | 2 | 2 | 2 | |
| 22 | PX SEND BROADCAST | :TQ10000 | 1 | 2 | 2 | 2 | |
| 23 | PX BLOCK ITERATOR | | 1 | 2 | 2 | 1 | |
| 24 | TABLE ACCESS STORAGE FULL | MCA_CONTRACT_T | 1 | 2 | 34 | 1 | 79.27 |
| 25 | PX BLOCK ITERATOR | | 2M | 68725 | 2 | 2M | |
| 26 | TABLE ACCESS STORAGE FULL | MCA_JOURNALS_T | 2M | 68725 | 34 | 2M | 0.61 |
| 27 | BUFFER SORT | | | | 2 | 136 | |
| 28 | PX RECEIVE | | 1 | 120 | 2 | 302 | |
| 29 | PX SEND BROADCAST | :TQ10001 | 1 | 120 | 2 | 302 | |
| 30 | PX BLOCK ITERATOR | | 1 | 120 | 2 | 151 | |
| 31 | TABLE ACCESS STORAGE FULL | MCA_DATA_SOURCE_CONFIG_T | 1 | 120 | 25 | 151 | 14.02 |
| 32 | INLIST ITERATOR | | | | 114M | 571M | |
| 33 | INDEX RANGE SCAN | MCA_PROJECT_N1 | 7 | 2 | 228M | 571M | 1.22 |
| 34 | TABLE ACCESS BY INDEX ROWID | MCA_PROJECT_T | 1 | 6 | 571M | 70M | 1.22 |
| 35 | PX BLOCK ITERATOR | | 13 | 987 | | | |
| 36 | TABLE ACCESS STORAGE FULL | MCA_GROUP_ACCOUNT_T | 13 | 987 | | | |
| 37 | PX BLOCK ITERATOR | | 27 | 12 | | | |
| 38 | TABLE ACCESS STORAGE FULL | MCA_DATA_CATEGORY_T | 27 | 12 | | | |
| 39 | PX BLOCK ITERATOR | | 342 | 57 | | | |
| 40 | TABLE ACCESS STORAGE FULL | MCA_JOURNAL_SOURCE_T | 342 | 57 | | | |
| 41 | PX BLOCK ITERATOR | | 2240 | 159 | | | |
| 42 | TABLE ACCESS STORAGE FULL | MCA_JOURNAL_CATEGORY_T | 2240 | 159 | | | |
====================================================================================================================================
没有并行提示时,执行计划如下:
SQL Plan Monitoring Details (Plan Hash Value=1065085828)
======================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | | (Estim) | | | (Actual) | (%) |
======================================================================================================================
| 0 | SELECT STATEMENT | | | | 1 | 1 | |
| 1 | SORT AGGREGATE | | 1 | | 1 | 1 | |
| 2 | HASH JOIN | | 1 | 293K | 1 | | |
| 3 | NESTED LOOPS | | | | 1 | | |
| 4 | NESTED LOOPS | | 1 | 293K | 1 | | |
| 5 | HASH JOIN | | 1 | 293K | 1 | | |
| 6 | HASH JOIN | | 37 | 293K | 1 | 0 | |
| 7 | HASH JOIN | | 47 | 291K | 1 | 152K | |
| 8 | HASH JOIN | | 149 | 291K | 1 | 2M | |
| 9 | HASH JOIN | | 105 | 291K | 1 | 2M | |
| 10 | TABLE ACCESS STORAGE FULL | MCA_CONTRACT_T | 3 | 274K | 1 | 2 | 12.82 |
| 11 | PARTITION LIST SINGLE | | 2M | 17272 | 1 | 2M | |
| 12 | TABLE ACCESS STORAGE FULL | MCA_JOURNALS_T | 2M | 17272 | 1 | 2M | 2.56 |
| 13 | TABLE ACCESS STORAGE FULL | MCA_JOURNAL_CATEGORY_T | 2240 | 287 | 1 | 2836 | 23.08 |
| 14 | TABLE ACCESS STORAGE FULL | MCA_DATA_SOURCE_CONFIG_T | 125 | 217 | 1 | 151 | 5.13 |
| 15 | TABLE ACCESS STORAGE FULL | MCA_GROUP_ACCOUNT_T | 218 | 1779 | 1 | 2 | 56.41 |
| 16 | TABLE ACCESS STORAGE FULL | MCA_JOURNAL_SOURCE_T | 342 | 102 | | | |
| 17 | INLIST ITERATOR | | | | | | |
| 18 | INDEX RANGE SCAN | MCA_PROJECT_N1 | 7 | 3 | | | |
| 19 | TABLE ACCESS BY INDEX ROWID | MCA_PROJECT_T | 1 | 11 | | | |
| 20 | TABLE ACCESS STORAGE FULL | MCA_DATA_CATEGORY_T | 12 | 22 | | | |
======================================================================================================================
加并行的时候,MCA_JOURNALS_T和MCA_CONTRACT_T关联之后,直接与MCA_DATA_SOURCE_CONFIG_T关联了,就是这个关联,产生了庞大的中间结果集。
解决办法是将提示改成/*+ PARALLEL(2) leading(MPLC,CONTRACT,MCA_JECATEGORY_T) */,修改后41s完成,执行计划如下:
SQL Plan Monitoring Details (Plan Hash Value=2901514415)
====================================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | | (Estim) | | | (Actual) | (%) |
====================================================================================================================================
| 0 | SELECT STATEMENT | | | | 1 | 1 | |
| 1 | SORT AGGREGATE | | 1 | | 1 | 1 | |
| 2 | PX COORDINATOR | | | | 5 | 2 | |
| 3 | PX SEND QC (RANDOM) | :TQ10006 | 1 | | 2 | 2 | |
| 4 | SORT AGGREGATE | | 1 | | 2 | 2 | |
| 5 | HASH JOIN | | 1 | 163K | 2 | | |
| 6 | PX RECEIVE | | 1 | 163K | 2 | | |
| 7 | PX SEND BROADCAST | :TQ10005 | 1 | 163K | 2 | | |
| 8 | HASH JOIN | | 1 | 163K | 2 | | |
| 9 | PX RECEIVE | | 1 | 163K | 2 | | |
| 10 | PX SEND BROADCAST | :TQ10004 | 1 | 163K | 2 | | |
| 11 | HASH JOIN | | 1 | 163K | 2 | 0 | |
| 12 | PX RECEIVE | | | | 2 | 111K | |
| 13 | PX SEND BROADCAST | :TQ10003 | | | 2 | 111K | |
| 14 | NESTED LOOPS | | | | 2 | 55384 | |
| 15 | NESTED LOOPS | | 1 | 162K | 2 | 760K | |
| 16 | HASH JOIN | | 1 | 162K | 2 | 152K | |
| 17 | HASH JOIN | | 75 | 162K | 2 | 2M | 1.54 |
| 18 | PX RECEIVE | | 53 | 161K | 2 | 3M | |
| 19 | PX SEND BROADCAST | :TQ10001 | 53 | 161K | 2 | 3M | |
| 20 | HASH JOIN | | 53 | 161K | 2 | 2M | 3.08 |
| 21 | PX BLOCK ITERATOR | | 2M | 9590 | 2 | 2M | |
| 22 | TABLE ACCESS STORAGE FULL | MCA_JOURNALS_T | 2M | 9590 | 34 | 2M | |
| 23 | BUFFER SORT | | | | 2 | 2 | |
| 24 | PX RECEIVE | | 1 | 152K | 2 | 2 | |
| 25 | PX SEND BROADCAST | :TQ10000 | 1 | 152K | 2 | 2 | |
| 26 | PX BLOCK ITERATOR | | 1 | 152K | 2 | 1 | |
| 27 | TABLE ACCESS STORAGE FULL | MCA_CONTRACT_T | 1 | 152K | 34 | 1 | 83.08 |
| 28 | PX BLOCK ITERATOR | | 2240 | 159 | 2 | 2836 | |
| 29 | TABLE ACCESS STORAGE FULL | MCA_JOURNAL_CATEGORY_T | 2240 | 159 | 27 | 2836 | 9.23 |
| 30 | BUFFER SORT | | | | 2 | 302 | |
| 31 | PX RECEIVE | | 2 | 120 | 2 | 302 | |
| 32 | PX SEND BROADCAST | :TQ10002 | 2 | 120 | 2 | 302 | |
| 33 | PX BLOCK ITERATOR | | 2 | 120 | 2 | 151 | |
| 34 | TABLE ACCESS STORAGE FULL | MCA_DATA_SOURCE_CONFIG_T | 2 | 120 | 25 | 151 | |
| 35 | INLIST ITERATOR | | | | 152K | 760K | |
| 36 | INDEX RANGE SCAN | MCA_PROJECT_N1 | 7 | 2 | 304K | 760K | |
| 37 | TABLE ACCESS BY INDEX ROWID | MCA_PROJECT_T | 1 | 6 | 760K | 55384 | 3.08 |
| 38 | PX BLOCK ITERATOR | | 13 | 987 | 2 | 2 | |
| 39 | TABLE ACCESS STORAGE FULL | MCA_GROUP_ACCOUNT_T | 13 | 987 | 37 | 2 | |
| 40 | PX BLOCK ITERATOR | | 27 | 12 | | | |
| 41 | TABLE ACCESS STORAGE FULL | MCA_DATA_CATEGORY_T | 27 | 12 | | | |
| 42 | PX BLOCK ITERATOR | | 342 | 57 | | | |
| 43 | TABLE ACCESS STORAGE FULL | MCA_JOURNAL_SOURCE_T | 342 | 57 | | | |
====================================================================================================================================
为什么加并行会走错关联顺序呢?关键在于如下的几个过滤条件:
AND ((GROUP_ACCOUNT.ACCOUNT_EXPENSE_CATG_CODE = '20' AND
CONTRACT.HW_CONTRACT_NUM IN ('SNULL') AND
(DATA_CATEGORY.DATA_CATEGORY_CLASS <> '10' ) AND
PROJECT.PROJ_NUM IN ('SNULL', '0000000')))
经过过滤条件CONTRACT.HW_CONTRACT_NUM IN ('SNULL'),合同维表MCA_CONTRACT_T被认为只有1条记录。跟MCA_JOURNAL_T关联后,估计的结果集也是1,而实际结果集却有160多万。由于中间结果集估计值是1,CBO会认为这个结果集与别的表关联后,结果集不会超过1,所以就不再考虑后续表的关联顺序。但实际情况却不是这样,所以导致了中间结果集笛卡尔积的出现。加入Leading提示后,纠正了错误关联顺序,从而避免笛卡尔积。
进一步研究的话,还是因为表MCA_JOURNAL_T的CONTRACT_KEY分布不均匀,-999999的值太多。201311会计期一共187.7万记录,-999999的值就有166.7万,占了将近90%。如此分布不均匀,要CBO判断准是很难的。
SELECT count(*) FROM MCA_JOURNALS_T where PERIOD = 201311;
--1877413
SELECT count(*) FROM MCA_JOURNALS_T where PERIOD = 201311 AND CONTRACT_KEY = -999999;
--1666975
解决方案:
建议:
- 保证统计信息的正确性。
- 去掉并行提示或者增加提示leading(MPLC,CONTRACT,MCA_JECATEGORY_T)。
2.1.2 表统计信息估算值太小
问题描述:
环境:SIT环境(Exadata UAT)
程序:历史累计程序,DWAPP.DWR_IS_PROJ_ACCUM_PKG.DWR_IS_PROJ_ACCUM_P
时间:2014-01-22
SIT环境历史累计的SP调度时间非常长,重新收集过各表的统计信息后,一个会计期还是要5-7个小时。
Select的话2-30秒能出来,count的话166秒就能出来,但跑不出数。
查session脚本:
--1.识别调度引擎Session,并获取杀Session脚本:
SELECT s.STATe,s.INST_ID,s.SQL_EXEC_START,S.OSUSER,S.USERNAME,
Q.SQL_TEXT,Q.SQL_FULLTEXT,S.SID,S.SERIAL#,
'EXEC SP_FIN_SCHEDULE_KILL_SESSION('||S.SID||','||S.SERIAL#||','||S.INST_ID||');',
S.PROGRAM,S.MODULE,S.STATUS,
S.MACHINE,S.SERVICE_NAME,S.CLIENT_INFO,S.SQL_HASH_VALUE,
'alter system kill session '||''''||s.sid||', '||s.serial#||', @'||s.inst_id||''''||';',
S.*
FROM GV$SESSION S,
GV$SQLAREA Q
WHERE S.INST_ID = Q.INST_ID
AND S.SQL_ID = Q.SQL_ID
AND S.USERNAME = 'DWAPP'
AND S.OSUSER = 'dsadm'
AND s.MODULE LIKE 'SP:DWR_IS_PROJ_ACCUM_PKG.DWR_IS_PROJ_ACCUM_P%'
ORDER BY S.SQL_EXEC_START, S.SID ;
有性能问题的脚本如下(已代入变量):
INSERT /*+ APPEND PARALLEL(8)*/
INTO DWR_IS_PROJ_ACCUM_TMP1 --DWAPP.DWR_FIN_GRP_JE_ACCUM_F_TMP
(PERIOD_ID,
JE_SOURCE_ID,
JE_CATEGORY_ID,
DATA_SOURCE_TABLE_ID,
DATA_CATEGORY_ID,
GROUP_ACCOUNT_CODE,
SUB_ACCOUNT_CODE,
COMPANY_CODE,
IC_CODE,
DEPT_CODE,
GEO_PC_CODE,
COA_BU_CODE,
BUY_FROM_IC_CODE,
MAJOR_PROD_CODE,
MINOR_PROD_CODE,
BAS_SALES_TEAM_CODE,
END_CUST_CODE,
SIGN_CUST_CODE,
AGENT_DISTRIBUTION_CUST_CODE,
ACCOUNT_DEPT_CUST_CODE,
ENTERPRISE_CUST_CODE,
BU_CODE,
CONTRACT_CODE,
PROJ_CODE,
SUBPROJ_CODE,
SALES_MODE_CODE,
--COUNTER_SIGN_CONTRACT_CODE,
RESTATEMENT_CODE,
LC_CODE,
TC_CODE,
TC_YTD_AMT,
TC_CTD_AMT,
LC_YTD_AMT,
LC_CTD_AMT,
RMB_FACT_EX_RATE_YTD_AMT,
RMB_FACT_EX_RATE_ITD_AMT,
RMB_BUDGET_EX_RATE_YTD_AMT,
RMB_BUDGET_EX_RATE_ITD_AMT,
USD_FACT_EX_RATE_YTD_AMT,
USD_FACT_EX_RATE_ITD_AMT,
USD_BUDGET_EX_RATE_YTD_AMT,
USD_BUDGET_EX_RATE_ITD_AMT,
TC_YTD_DR_AMT,
TC_YTD_CR_AMT,
TC_CTD_DR_AMT,
TC_CTD_CR_AMT,
LC_YTD_DR_AMT,
LC_YTD_CR_AMT,
LC_CTD_DR_AMT,
LC_CTD_CR_AMT,
RMB_FACT_EX_RATE_YTD_DR_AMT,
RMB_FACT_EX_RATE_YTD_CR_AMT,
RMB_FACT_EX_RATE_CTD_DR_AMT,
RMB_FACT_EX_RATE_CTD_CR_AMT,
RMB_BUDGET_EX_RATE_YTD_DR_AMT,
RMB_BUDGET_EX_RATE_YTD_CR_AMT,
RMB_BUDGET_EX_RATE_CTD_DR_AMT,
RMB_BUDGET_EX_RATE_CTD_CR_AMT,
USD_FACT_EX_RATE_YTD_DR_AMT,
USD_FACT_EX_RATE_YTD_CR_AMT,
USD_FACT_EX_RATE_CTD_DR_AMT,
USD_FACT_EX_RATE_CTD_CR_AMT,
USD_BUDGET_EX_RATE_YTD_DR_AMT,
USD_BUDGET_EX_RATE_YTD_CR_AMT,
USD_BUDGET_EX_RATE_CTD_DR_AMT,
USD_BUDGET_EX_RATE_CTD_CR_AMT,
XCHARGE_PROJ_CODE)
SELECT /*+ PARALLEL(8) */
201400 PERIOD_ID, --201400 201500 ....
Z.JE_SOURCE_ID JE_SOURCE_ID,
Z.JE_CATEGORY_ID JE_CATEGORY_ID,
Z.DATA_SOURCE_TABLE_ID DATA_SOURCE_TABLE_ID,
Z.DATA_CATEGORY_ID DATA_CATEGORY_ID,
Z.GROUP_ACCOUNT_CODE GROUP_ACCOUNT_CODE,
Z.SUB_ACCOUNT_CODE SUB_ACCOUNT_CODE,
COM_D.COMPANY_CODE COMPANY_CODE,
IC_D.COMPANY_CODE IC_CODE,
DEPT_D.DEPT_CODE DEPT_CODE,
REG_D.GEO_PC_CODE GEO_PC_CODE,
COA_BU_D.BU_CODE COA_BU_CODE,
BUY_FROM_IC_D.COMPANY_CODE BUY_FROM_IC_CODE,
MAJOR_PROD_D.PROD_CODE MAJOR_PROD_CODE,
MINOR_PROD_D.PROD_CODE MINOR_PROD_CODE,
BAS_SALES_TEAM_D.BAS_SALES_TEAM_CODE BAS_SALES_TEAM_CODE,
END_CUST_D.CUST_ACCOUNT_NUM END_CUST_CODE,
SIGN_CUST_D.CUST_ACCOUNT_NUM SIGN_CUST_CODE,
AGENT_CUST_D.CUST_ACCOUNT_NUM AGENT_DISTRIBUTION_CUST_CODE,
DEPT_CUST_D.CUST_ACCOUNT_NUM ACCOUNT_DEPT_CUST_CODE,
ENTERPRISE_CUST_D.CUST_ACCOUNT_NUM ENTERPRISE_CUST_CODE,
BU_D.BU_CODE BU_CODE,
CON_D.HW_CONTRACT_NUM CONTRACT_CODE,
PROJ_D.PROJ_NUM PROJ_CODE,
SUBPROJ_D.PROJ_NUM SUBPROJ_CODE,
SALES_MODE_D.SALES_MODE_CODE SALES_MODE_CODE,
--SIGN_CON_D.HW_CONTRACT_NUM COUNTER_SIGN_CONTRACT_CODE,
Z.RESTATEMENT_CODE RESTATEMENT_CODE,
Z.LC_CODE LC_CODE,
Z.TC_CODE TC_CODE,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.TC_DR_AMT - Z.TC_CR_AMT
ELSE
Z.TC_CR_AMT - Z.TC_DR_AMT
END TC_YTD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.TC_DR_AMT - Z.TC_CR_AMT
ELSE
Z.TC_CR_AMT - Z.TC_DR_AMT
END TC_CTD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.LC_DR_AMT - Z.LC_CR_AMT
ELSE
Z.LC_CR_AMT - Z.LC_DR_AMT
END LC_YTD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.LC_DR_AMT - Z.LC_CR_AMT
ELSE
Z.LC_CR_AMT - Z.LC_DR_AMT
END LC_CTD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.RMB_FACT_EX_RATE_DR_AMT - Z.RMB_FACT_EX_RATE_CR_AMT
ELSE
Z.RMB_FACT_EX_RATE_CR_AMT - Z.RMB_FACT_EX_RATE_DR_AMT
END RMB_FACT_EX_RATE_YTD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.RMB_FACT_EX_RATE_DR_AMT - Z.RMB_FACT_EX_RATE_CR_AMT
ELSE
Z.RMB_FACT_EX_RATE_CR_AMT - Z.RMB_FACT_EX_RATE_DR_AMT
END RMB_FACT_EX_RATE_ITD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.LC_DR_AMT - Z.LC_CR_AMT
ELSE
Z.LC_CR_AMT - Z.LC_DR_AMT
END * COALESCE(BUDGET_RATE.LC_RMB_AAP_END_RATE,
BUDGET_RATE.LC_RMB_AAP_BEGIN_RATE,
FACT_RATE_RMB.AVG_RATE,
FACT_RATE_RMB.BEGIN_RATE,
0) RMB_BUDGET_EX_RATE_YTD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.LC_DR_AMT - Z.LC_CR_AMT
ELSE
Z.LC_CR_AMT - Z.LC_DR_AMT
END * COALESCE(BUDGET_RATE.LC_RMB_AAP_END_RATE,
BUDGET_RATE.LC_RMB_AAP_BEGIN_RATE,
FACT_RATE_RMB.AVG_RATE,
FACT_RATE_RMB.BEGIN_RATE,
0) RMB_BUDGET_EX_RATE_ITD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.LC_DR_AMT - Z.LC_CR_AMT
ELSE
Z.LC_CR_AMT - Z.LC_DR_AMT
END *
COALESCE(FACT_RATE_USD.AVG_RATE, FACT_RATE_USD.BEGIN_RATE, 0) USD_FACT_EX_RATE_YTD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.LC_DR_AMT - Z.LC_CR_AMT
ELSE
Z.LC_CR_AMT - Z.LC_DR_AMT
END *
COALESCE(FACT_RATE_USD.AVG_RATE, FACT_RATE_USD.BEGIN_RATE, 0) USD_FACT_EX_RATE_ITD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.LC_DR_AMT - Z.LC_CR_AMT
ELSE
Z.LC_CR_AMT - Z.LC_DR_AMT
END * COALESCE(BUDGET_RATE.LC_USD_AAP_END_RATE,
BUDGET_RATE.LC_USD_AAP_BEGIN_RATE,
FACT_RATE_USD.AVG_RATE,
FACT_RATE_USD.BEGIN_RATE,
0) USD_BUDGET_EX_RATE_YTD_AMT,
CASE
WHEN UPPER(GRP_D.ACCOUNT_TYPE_EN_NAME) IN ('ASSET', 'EXPENSE') AND
GRP_D.LVL2_ACCOUNT_CODE <> '56212' THEN
Z.LC_DR_AMT - Z.LC_CR_AMT
ELSE
Z.LC_CR_AMT - Z.LC_DR_AMT
END * COALESCE(BUDGET_RATE.LC_USD_AAP_END_RATE,
BUDGET_RATE.LC_USD_AAP_BEGIN_RATE,
FACT_RATE_USD.AVG_RATE,
FACT_RATE_USD.BEGIN_RATE,
0) USD_BUDGET_EX_RATE_ITD_AMT,
Z.TC_DR_AMT TC_YTD_DR_AMT,
Z.TC_CR_AMT TC_YTD_CR_AMT,
Z.TC_DR_AMT TC_CTD_DR_AMT,
Z.TC_CR_AMT TC_CTD_CR_AMT,
Z.LC_DR_AMT LC_YTD_DR_AMT,
Z.LC_CR_AMT LC_YTD_CR_AMT,
Z.LC_DR_AMT LC_CTD_DR_AMT,
Z.LC_CR_AMT LC_CTD_CR_AMT,
Z.RMB_FACT_EX_RATE_DR_AMT RMB_FACT_EX_RATE_YTD_DR_AMT,
Z.RMB_FACT_EX_RATE_CR_AMT RMB_FACT_EX_RATE_YTD_CR_AMT,
Z.RMB_FACT_EX_RATE_DR_AMT RMB_FACT_EX_RATE_CTD_DR_AMT,
Z.RMB_FACT_EX_RATE_CR_AMT RMB_FACT_EX_RATE_CTD_CR_AMT,
Z.LC_DR_AMT * COALESCE(BUDGET_RATE.LC_RMB_AAP_END_RATE,
BUDGET_RATE.LC_RMB_AAP_BEGIN_RATE,
FACT_RATE_RMB.AVG_RATE,
FACT_RATE_RMB.BEGIN_RATE,
0) RMB_BUDGET_EX_RATE_YTD_DR_AMT,
Z.LC_CR_AMT * COALESCE(BUDGET_RATE.LC_RMB_AAP_END_RATE,
BUDGET_RATE.LC_RMB_AAP_BEGIN_RATE,
FACT_RATE_RMB.AVG_RATE,
FACT_RATE_RMB.BEGIN_RATE,
0) RMB_BUDGET_EX_RATE_YTD_CR_AMT,
Z.LC_DR_AMT * COALESCE(BUDGET_RATE.LC_RMB_AAP_END_RATE,
BUDGET_RATE.LC_RMB_AAP_BEGIN_RATE,
FACT_RATE_RMB.AVG_RATE,
FACT_RATE_RMB.BEGIN_RATE,
0) RMB_BUDGET_EX_RATE_CTD_DR_AMT,
Z.LC_CR_AMT * COALESCE(BUDGET_RATE.LC_RMB_AAP_END_RATE,
BUDGET_RATE.LC_RMB_AAP_BEGIN_RATE,
FACT_RATE_RMB.AVG_RATE,
FACT_RATE_RMB.BEGIN_RATE,
0) RMB_BUDGET_EX_RATE_CTD_CR_AMT,
Z.LC_DR_AMT *
COALESCE(FACT_RATE_USD.AVG_RATE, FACT_RATE_USD.BEGIN_RATE, 0) USD_FACT_EX_RATE_YTD_DR_AMT,
Z.LC_CR_AMT *
COALESCE(FACT_RATE_USD.AVG_RATE, FACT_RATE_USD.BEGIN_RATE, 0) USD_FACT_EX_RATE_YTD_CR_AMT,
Z.LC_DR_AMT *
COALESCE(FACT_RATE_USD.AVG_RATE, FACT_RATE_USD.BEGIN_RATE, 0) USD_FACT_EX_RATE_CTD_DR_AMT,
Z.LC_CR_AMT *
COALESCE(FACT_RATE_USD.AVG_RATE, FACT_RATE_USD.BEGIN_RATE, 0) USD_FACT_EX_RATE_CTD_CR_AMT,
Z.LC_DR_AMT * COALESCE(BUDGET_RATE.LC_USD_AAP_END_RATE,
BUDGET_RATE.LC_USD_AAP_BEGIN_RATE,
FACT_RATE_USD.AVG_RATE,
FACT_RATE_USD.BEGIN_RATE,
0) USD_BUDGET_EX_RATE_YTD_DR_AMT,
Z.LC_CR_AMT * COALESCE(BUDGET_RATE.LC_USD_AAP_END_RATE,
BUDGET_RATE.LC_USD_AAP_BEGIN_RATE,
FACT_RATE_USD.AVG_RATE,
FACT_RATE_USD.BEGIN_RATE,
0) USD_BUDGET_EX_RATE_YTD_CR_AMT,
Z.LC_DR_AMT * COALESCE(BUDGET_RATE.LC_USD_AAP_END_RATE,
BUDGET_RATE.LC_USD_AAP_BEGIN_RATE,
FACT_RATE_USD.AVG_RATE,
FACT_RATE_USD.BEGIN_RATE,
0) USD_BUDGET_EX_RATE_CTD_DR_AMT,
Z.LC_CR_AMT * COALESCE(BUDGET_RATE.LC_USD_AAP_END_RATE,
BUDGET_RATE.LC_USD_AAP_BEGIN_RATE,
FACT_RATE_USD.AVG_RATE,
FACT_RATE_USD.BEGIN_RATE,
0) USD_BUDGET_EX_RATE_CTD_CR_AMT,
'SNULL' XCHARGE_PROJ_CODE --结算项目编码
FROM DWRFIN.DWR_FIN_GROUP_JE_ALL_F Z,
DWR_DIM_COMPANY_D COM_D,
DWR_DIM_COMPANY_D IC_D,
DWR_DIM_DEPARTMENT_D DEPT_D,
DWR_DIM_REGION_RC_D REG_D,
DWR_DIM_BU_D COA_BU_D,
DWR_DIM_COMPANY_D BUY_FROM_IC_D,
DWR_DIM_PRODUCT_D MAJOR_PROD_D,
DWR_DIM_PRODUCT_D MINOR_PROD_D,
DWR_DIM_CONTRACT_D CON_D,
--DWR_DIM_CONTRACT_D SIGN_CON_D,
DWR_DIM_BU_D BU_D,
DWR_DIM_CUSTOMER_D END_CUST_D,
DWR_DIM_CUSTOMER_D SIGN_CUST_D,
DWR_DIM_CUSTOMER_D AGENT_CUST_D,
DWR_DIM_CUSTOMER_D DEPT_CUST_D,
DWR_DIM_CUSTOMER_D ENTERPRISE_CUST_D,
DWR_DIM_PROJECT_D PROJ_D,
DWR_DIM_PROJECT_D SUBPROJ_D,
DWR_DIM_BAS_SALES_TEAM_D BAS_SALES_TEAM_D,
DWR_DIM_SALES_MODE_D SALES_MODE_D,
DWR_DIM_GRP_ACCT_CODE_D GRP_D,
MCA_PERIOD_RATE_T FACT_RATE_RMB,
MCA_PERIOD_RATE_T FACT_RATE_USD,
DWR_DIM_PROJECT_D PROJ_DEBAR, ----排除项目
(SELECT RR_D.LC_RMB_AAP_BEGIN_RATE,
RR_D.LC_RMB_AAP_END_RATE,
RR_D.LC_USD_AAP_BEGIN_RATE,
RR_D.LC_USD_AAP_END_RATE,
RR_D.PERIOD_NUMBER,
COMP.COMPANY_KEY,
GEO_PC.GEO_PC_KEY
FROM MCA_BLENDED_EXCHANGE_RATE_T RR_D,
DWR_DIM_COMPANY_D COMP,
DWR_DIM_REGION_RC_D GEO_PC
WHERE COMP.COMPANY_CODE = RR_D.COMPANY_CODE
AND GEO_PC.GEO_PC_CODE = RR_D.REGION_CODE) BUDGET_RATE
WHERE 1 = 1
AND 201301 = FACT_RATE_RMB.PERIOD_NUMBER(+)
AND Z.LC_CODE = FACT_RATE_RMB.FROM_CURRENCY_CODE(+)
AND 'RMB' = FACT_RATE_RMB.TO_CURRENCY_CODE(+)
AND 201301 = FACT_RATE_USD.PERIOD_NUMBER(+)
AND Z.LC_CODE = FACT_RATE_USD.FROM_CURRENCY_CODE(+)
AND 'USD' = FACT_RATE_USD.TO_CURRENCY_CODE(+)
AND 201301 = BUDGET_RATE.PERIOD_NUMBER(+)
AND Z.COMPANY_KEY = BUDGET_RATE.COMPANY_KEY(+)
AND Z.GEO_PC_KEY = BUDGET_RATE.GEO_PC_KEY(+)
AND Z.COMPANY_KEY = COM_D.COMPANY_KEY
AND Z.IC_KEY = IC_D.COMPANY_KEY
AND Z.DEPT_KEY = DEPT_D.DEPT_KEY
AND Z.GEO_PC_KEY = REG_D.GEO_PC_KEY
AND Z.COA_BU_KEY = COA_BU_D.BU_KEY
AND Z.BU_KEY = BU_D.BU_KEY
AND Z.BUY_FROM_IC_KEY = BUY_FROM_IC_D.COMPANY_KEY
AND Z.MAJOR_PROD_KEY = MAJOR_PROD_D.PROD_KEY
AND Z.MINOR_PROD_KEY = MINOR_PROD_D.PROD_KEY
AND Z.CONTRACT_KEY = CON_D.CONTRACT_KEY
--AND Z.COUNTER_SIGN_CONTRACT_KEY = SIGN_CON_D.CONTRACT_KEY
AND Z.END_CUST_KEY = END_CUST_D.CUST_ACCOUNT_KEY
AND Z.SIGN_CUST_KEY = SIGN_CUST_D.CUST_ACCOUNT_KEY
AND Z.AGENT_DISTRIBUTION_CUST_KEY =
AGENT_CUST_D.CUST_ACCOUNT_KEY
AND Z.ACCOUNT_DEPT_CUST_KEY = DEPT_CUST_D.CUST_ACCOUNT_KEY
AND Z.ENTERPRISE_CUST_KEY = ENTERPRISE_CUST_D.CUST_ACCOUNT_KEY
AND Z.PROJ_KEY = PROJ_D.PROJ_KEY
AND Z.SUBPROJ_KEY = SUBPROJ_D.PROJ_KEY
AND Z.BAS_SALES_TEAM_KEY = BAS_SALES_TEAM_D.BAS_SALES_TEAM_KEY
AND Z.SALES_MODE_KEY = SALES_MODE_D.SALES_MODE_KEY
AND Z.GROUP_ACCOUNT_CODE = GRP_D.GROUP_ACCOUNT_CODE(+)
AND NVL(Z.RESTATEMENT_CODE, 'N') = 'N'
AND Z.DATA_SOURCE_TABLE_ID NOT IN (10027, 10300, 10301) ---排除XCHARGE,BIS来源的数据
AND Z.PERIOD_ID = 201301 --取数用游标会计期
AND Z.PROJ_KEY <> -999999
----排除部分项目
AND PROJ_D.PROJ_ID = PROJ_DEBAR.PROJ_ID
AND DATE '2013-12-31' >= PROJ_DEBAR.SCD_ACTIVE_BEGIN_DATE
AND DATE '2013-12-31' < PROJ_DEBAR.SCD_ACTIVE_END_DATE
AND ((UPPER(PROJ_DEBAR.PROJ_STATUS_CODE) = 'CLOSED' AND
NVL(TO_NUMBER(TO_CHAR(ADD_MONTHS(PROJ_DEBAR.PROJ_END_DATE,
12),
'YYYYMM')),
471212) >= 201312) OR
UPPER(PROJ_DEBAR.PROJ_STATUS_CODE) <> 'CLOSED');
问题分析:
Top SQL的执行计划如下(sql_id=fgu2dhf847r3q,201301会计期,未完成):
SQL Plan Monitoring Details (Plan Hash Value=3324406220)
=============================================================================================================================================================
| Id | Operation | Name | Rows | Cost | Rows |Activ |
| | | |(Est) | |(Act) |ity(%)|
=============================================================================================================================================================
| 0 |INSERT STATEMENT | | | | 0 | 0.34 |
| 1 | PX COORDINATOR | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10033 | 5203 | 148K | | |
| 3 | LOAD AS SELECT | | | | | |
| 4 | HASH JOIN RIGHT OUTER | | 5203 | 148K | | |
| 5 | PX RECEIVE | | 187 | 98 | | |
| 6 | PX SEND BROADCAST | :TQ10030 | 187 | 98 | | |
| 7 | PX BLOCK ITERATOR | | 187 | 98 | | |
| 8 | TABLE ACCESS STORAGE FULL | MCA_PERIOD_RATE_T | 187 | 98 | | |
| 9 | HASH JOIN RIGHT OUTER | | 3308 | 148K | | |
| 10 | PX RECEIVE | | 187 | 98 | | |
| 11 | PX SEND BROADCAST | :TQ10031 | 187 | 98 | | |
| 12 | PX BLOCK ITERATOR | | 187 | 98 | | |
| 13 | TABLE ACCESS STORAGE FULL | MCA_PERIOD_RATE_T | 187 | 98 | | |
| 14 | HASH JOIN | | 2103 | 148K | | |
| 15 | PX RECEIVE | | 2102 | 121K | | |
| 16 | PX SEND BROADCAST | :TQ10032 | 2102 | 121K | | |
| 17 | HASH JOIN RIGHT OUTER BUFFERED | | 2102 | 121K | | |
| 18 | PX RECEIVE | | 4074 | 33 | | |
| 19 | PX SEND HASH | :TQ10028 | 4074 | 33 | | |
| 20 | VIEW | | 4074 | 33 | | |
| 21 | HASH JOIN BUFFERED | | 4074 | 33 | | |
| 22 | PX RECEIVE | | 1375 | 22 | | |
| 23 | PX SEND HASH | :TQ10025 | 1375 | 22 | | |
| 24 | HASH JOIN BUFFERED | | 1375 | 22 | | |
| 25 | PX RECEIVE | | 657 | 2 | | |
| 26 | PX SEND HASH | :TQ10021 | 657 | 2 | | |
| 27 | PX BLOCK ITERATOR | | 657 | 2 | | |
| 28 | TABLE ACCESS STORAGE FULL | DWR_DIM_REGION_RC_D | 657 | 2 | | |
| 29 | PX RECEIVE | | 871 | 20 | | |
| 30 | PX SEND HASH | :TQ10022 | 871 | 20 | | |
| 31 | PX BLOCK ITERATOR | | 871 | 20 | | |
| 32 | TABLE ACCESS STORAGE FULL | MCA_BLENDED_EXCHANGE_RATE_T| 871 | 20 | | |
| 33 | PX RECEIVE | | 2110 | 10 | | |
| 34 | PX SEND HASH | :TQ10026 | 2110 | 10 | | |
| 35 | PX BLOCK ITERATOR | | 2110 | 10 | | |
| 36 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2110 | 10 | | |
| 37 | PX RECEIVE | | 2102 | 121K | | |
| 38 | PX SEND HASH | :TQ10029 | 2102 | 121K | | |
| 39 | HASH JOIN | | 2102 | 121K | | |
| 40 | PX RECEIVE | | 2102 | 120K | | |
| 41 | PX SEND BROADCAST | :TQ10027 | 2102 | 120K | | |
| 42 | HASH JOIN BUFFERED | | 2102 | 120K | | |
| 43 | PX RECEIVE | | 2110 | 10 | | |
| 44 | PX SEND HASH | :TQ10023 | 2110 | 10 | | |
| 45 | PX BLOCK ITERATOR | | 2110 | 10 | | |
| 46 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2110 | 10 | | |
| 47 | PX RECEIVE | | 2102 | 120K | | |
| 48 | PX SEND HASH | :TQ10024 | 2102 | 120K | | |
| 49 | HASH JOIN | | 2102 | 120K | | |
| 50 | PX RECEIVE | | 2102 | 118K | | |
| 51 | PX SEND BROADCAST | :TQ10020 | 2102 | 118K | | |
| 52 | HASH JOIN BUFFERED | | 2102 | 118K | | |
| 53 | PX RECEIVE | | 2110 | 10 | | |
| 54 | PX SEND HASH | :TQ10018 | 2110 | 10 | | |
| 55 | PX BLOCK ITERATOR | | 2110 | 10 | | |
| 56 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2110 | 10 | | |
| 57 | PX RECEIVE | | 2102 | 118K | | |
| 58 | PX SEND HASH | :TQ10019 | 2102 | 118K | | |
| 59 | HASH JOIN BUFFERED | | 2102 | 118K | | |
| 60 | PX RECEIVE | | 2110 | 10 | | |
| 61 | PX SEND HASH | :TQ10016 | 2110 | 10 | | |
| 62 | PX BLOCK ITERATOR | | 2110 | 10 | | |
| 63 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2110 | 10 | | |
| 64 | PX RECEIVE | | 2102 | 118K | | |
| 65 | PX SEND HASH | :TQ10017 | 2102 | 118K | | |
| 66 | HASH JOIN | | 2102 | 118K | | |
| 67 | PX RECEIVE | | 2102 |78218 | | |
| 68 | PX SEND BROADCAST | :TQ10015 | 2102 |78218 | | |
| 69 | HASH JOIN | | 2102 |78218 | | |
| 70 | PX RECEIVE | | 2102 |51038 | | |
| 71 | PX SEND BROADCAST | :TQ10014 | 2102 |51038 | | |
| 72 | HASH JOIN | | 2102 |51038 | | |
| 73 | PX RECEIVE | | 657 | 2 | | |
| 74 | PX SEND BROADCAST | :TQ10012 | 657 | 2 | | |
| 75 | PX BLOCK ITERATOR | | 657 | 2 | | |
| 76 | TABLE ACCESS STORAGE FULL | DWR_DIM_REGION_RC_D | 657 | 2 | | |
| 77 | HASH JOIN | | 2102 |51035 | | |
| 78 | PX RECEIVE | | 2102 |50088 | | |
| 79 | PX SEND BROADCAST | :TQ10013 | 2102 |50088 | | |
| 80 | HASH JOIN | | 2102 |50088 | | |
| 81 | PX RECEIVE | | 2102 |49140 | | |
| 82 | PX SEND BROADCAST | :TQ10011 | 2102 |49140 | | |
| 83 | HASH JOIN | | 2102 |49140 | | |
| 84 | PX RECEIVE | | 2102 |48193 | | |
| 85 | PX SEND BROADCAST | :TQ10010 | 2102 |48193 | | |
| 86 | HASH JOIN | | 2102 |48193 | | |
| 87 | PX RECEIVE | | 2102 |47245 | | |
| 88 | PX SEND BROADCAST | :TQ10009 | 2102 |47245 | | |
| 89 | HASH JOIN RIGHT OUTER BUFFERED | | 2102 |47245 | | |
| 90 | PX RECEIVE | | 6858 | 16 | | |
| 91 | PX SEND HASH | :TQ10007 | 6858 | 16 | | |
| 92 | PX BLOCK ITERATOR | | 6858 | 16 | | |
| 93 | TABLE ACCESS STORAGE FULL | DWR_DIM_GRP_ACCT_CODE_D | 6858 | 16 | | |
| 94 | PX RECEIVE | | 2102 |47228 | | |
| 95 | PX SEND HASH | :TQ10008 | 2102 |47228 | | |
| 96 | HASH JOIN | | 2102 |47228 | | |
| 97 | PX RECEIVE | | 2102 |20048 | | |
| 98 | PX SEND BROADCAST | :TQ10006 | 2102 |20048 | | |
| 99 | HASH JOIN | | 2102 |20048 | 0 | |
| 100 | PX BLOCK ITERATOR | |82681 | 303 |82681 | |
| 101 | TABLE ACCESS STORAGE FULL | DWR_DIM_PRODUCT_D |82681 | 303 |82681 | |
|>102 | BUFFER SORT | | | | 0 |10.78 |
|>103 | PX RECEIVE | | 2102 |19745 | 109M | 0.44 |
| 104 | PX SEND BROADCAST | :TQ10005 | 2102 |19745 | 109M | 0.49 |
| 105 | HASH JOIN | | 2102 |19745 | 14M | 0.09 |
| 106 | PX BLOCK ITERATOR | |82681 | 303 |82681 | |
| 107 | TABLE ACCESS STORAGE FULL | DWR_DIM_PRODUCT_D |82681 | 303 |82681 | |
| 108 | BUFFER SORT | | | | 110M |84.02 |
| 109 | PX RECEIVE | | 2102 |19441 | 230M | 1.28 |
| 110 | PX SEND BROADCAST | :TQ10004 | 2102 |19441 | 230M | 1.51 |
| 111 | HASH JOIN | | 2102 |19441 | 29M | 0.07 |
| 112 | PX RECEIVE | | 400 | 2 | 3200 | |
| 113 | PX SEND BROADCAST | :TQ10000 | 400 | 2 | 3200 | |
| 114 | PX BLOCK ITERATOR | | 400 | 2 | 400 | |
| 115 | TABLE ACCESS STORAGE FULL | DWR_DIM_BU_D | 400 | 2 | 400 | |
| 116 | HASH JOIN | | 2102 |19439 | 29M | 0.06 |
| 117 | PX RECEIVE | | 400 | 2 | 3200 | |
| 118 | PX SEND BROADCAST | :TQ10001 | 400 | 2 | 3200 | |
| 119 | PX BLOCK ITERATOR | | 400 | 2 | 400 | |
| 120 | TABLE ACCESS STORAGE FULL | DWR_DIM_BU_D | 400 | 2 | 400 | |
| 121 | HASH JOIN | | 2102 |19436 | 29M | 0.08 |
| 122 | PX RECEIVE | | 39 | 2 | 312 | |
| 123 | PX SEND BROADCAST | :TQ10002 | 39 | 2 | 312 | |
| 124 | PX BLOCK ITERATOR | | 39 | 2 | 39 | |
| 125 | TABLE ACCESS STORAGE FULL | DWR_DIM_SALES_MODE_D | 39 | 2 | 39 | |
| 126 | HASH JOIN | | 2102 |19434 | 29M | 0.05 |
| 127 | PX RECEIVE | | 1 | 2 | 8 | |
| 128 | PX SEND BROADCAST | :TQ10003 | 1 | 2 | 8 | |
| 129 | PX BLOCK ITERATOR | | 1 | 2 | 1 | |
| 130 | TABLE ACCESS STORAGE FULL| DWR_DIM_BAS_SALES_TEAM_D | 1 | 2 | 1 | |
| 131 | PX BLOCK ITERATOR | | 2102 |19431 | 29M | |
| 132 | TABLE ACCESS STORAGE FULL | DWR_FIN_GROUP_JE_ALL_F | 2102 |19431 | 29M | 0.79 |
| 133 | PX BLOCK ITERATOR | | 6M |27178 | | |
| 134 | TABLE ACCESS STORAGE FULL | DWR_DIM_PROJECT_D | 6M |27178 | | |
| 135 | PX BLOCK ITERATOR | | 313K | 947 | | |
| 136 | TABLE ACCESS STORAGE FULL | DWR_DIM_CUSTOMER_D | 313K | 947 | | |
| 137 | PX BLOCK ITERATOR | | 313K | 947 | | |
| 138 | TABLE ACCESS STORAGE FULL | DWR_DIM_CUSTOMER_D | 313K | 947 | | |
| 139 | PX BLOCK ITERATOR | | 313K | 947 | | |
| 140 | TABLE ACCESS STORAGE FULL | DWR_DIM_CUSTOMER_D | 313K | 947 | | |
| 141 | PX BLOCK ITERATOR | | 313K | 947 | | |
| 142 | TABLE ACCESS STORAGE FULL | DWR_DIM_CUSTOMER_D | 313K | 947 | | |
| 143 | PX BLOCK ITERATOR | | 6M |27178 | | |
| 144 | TABLE ACCESS STORAGE FULL | DWR_DIM_PROJECT_D | 6M |27178 | | |
| 145 | PX BLOCK ITERATOR | | 7M |39431 | | |
| 146 | TABLE ACCESS STORAGE FULL | DWR_DIM_CONTRACT_D | 7M |39431 | | |
| 147 | PX BLOCK ITERATOR | | 346K | 1990 | | |
| 148 | TABLE ACCESS STORAGE FULL | DWR_DIM_DEPARTMENT_EDW_D | 346K | 1990 | | |
| 149 | PX BLOCK ITERATOR | | 313K | 947 | | |
| 150 | TABLE ACCESS STORAGE FULL | DWR_DIM_CUSTOMER_D | 313K | 947 | | |
| 151 | PX BLOCK ITERATOR | | 2M |27210 | | |
| 152 | TABLE ACCESS STORAGE FULL | DWR_DIM_PROJECT_D | 2M |27210 | | |
=============================================================================================================================================================
从执行计划来看,表DWR_FIN_GROUP_JE_ALL_F的估计值是不对的,本来有29M左右,但是估计值只有2102。检查表的统计信息值没有问题,但是我们没有收集直方图。表上有将近30个关联条件,这对估计值的影响很大。
因为源表估计值比较小,导致跟维表关联后的中间结果集估计值偏小。跟大维表关联时,认为中间结果集比维表小,使用中间结果集作为驱动,用了PX SEND BROADCAST,最终导致性能问题。
在后台加大表DWR_FIN_GROUP_JE_ALL_F的统计信息值到10000000000000000:
exec dbms_stats.set_table_stats(ownname=>'DWRFIN',tabname=>'DWR_FIN_GROUP_JE_ALL_F',numrows=>10000000000000000);
执行计划改变,估计值有22M,接近实际值。新的执行计划如下(201303会计期,6.9分钟完成):
SQL Plan Monitoring Details (Plan Hash Value=1691128212)
===================================================================================================================================
| Id | Operation | Name | Rows | Cost |Exec | Rows |Activ |
| | | |(Est) | | | (Act) |ity(%)|
===================================================================================================================================
| 0 |INSERT STATEMENT | | | | 17 | 8 | |
| 1 | PX COORDINATOR | | | | 17 | 8 | 0.17 |
| 2 | PX SEND QC (RANDOM) | :TQ10030 | 21M | 148K | 8 | 8 | |
| 3 | LOAD AS SELECT | | | | 8 | 16 |48.02 |
| 4 | HASH JOIN | | 21M | 148K | 8 | 32M | 1.07 |
| 5 | PX RECEIVE | | 313K | 947 | 8 | 3M | |
| 6 | PX SEND BROADCAST | :TQ10006 | 313K | 947 | 8 | 3M | |
| 7 | PX BLOCK ITERATOR | | 313K | 947 | 8 | 313K | |
| 8 | TABLE ACCESS STORAGE FULL | DWR_DIM_CUSTOMER_D | 313K | 947 | 114 | 313K | |
| 9 | HASH JOIN | | 21M | 147K | 8 | 32M | 0.99 |
| 10 | PX RECEIVE | | 313K | 947 | 8 | 3M | |
| 11 | PX SEND BROADCAST | :TQ10007 | 313K | 947 | 8 | 3M | |
| 12 | PX BLOCK ITERATOR | | 313K | 947 | 8 | 313K | |
| 13 | TABLE ACCESS STORAGE FULL | DWR_DIM_CUSTOMER_D | 313K | 947 | 114 | 313K | |
| 14 | HASH JOIN | | 21M | 146K | 8 | 32M | 0.91 |
| 15 | PX RECEIVE | | 313K | 947 | 8 | 3M | |
| 16 | PX SEND BROADCAST | :TQ10008 | 313K | 947 | 8 | 3M | |
| 17 | PX BLOCK ITERATOR | | 313K | 947 | 8 | 313K | |
| 18 | TABLE ACCESS STORAGE FULL | DWR_DIM_CUSTOMER_D | 313K | 947 | 114 | 313K | |
| 19 | HASH JOIN | | 21M | 145K | 8 | 32M | 1.90 |
| 20 | PX RECEIVE | | 313K | 947 | 8 | 3M | 0.08 |
| 21 | PX SEND BROADCAST | :TQ10009 | 313K | 947 | 8 | 3M | 0.17 |
| 22 | PX BLOCK ITERATOR | | 313K | 947 | 8 | 313K | |
| 23 | TABLE ACCESS STORAGE FULL | DWR_DIM_CUSTOMER_D | 313K | 947 | 114 | 313K | 0.41 |
| 24 | HASH JOIN | | 21M | 144K | 8 | 32M | 1.24 |
| 25 | PX RECEIVE | | 313K | 947 | 8 | 3M | |
| 26 | PX SEND BROADCAST | :TQ10010 | 313K | 947 | 8 | 3M | |
| 27 | PX BLOCK ITERATOR | | 313K | 947 | 8 | 313K | |
| 28 | TABLE ACCESS STORAGE FULL | DWR_DIM_CUSTOMER_D | 313K | 947 | 114 | 313K | |
| 29 | HASH JOIN | | 21M | 143K | 8 | 32M | 3.63 |
| 30 | PX RECEIVE | | 7M | 39431 | 8 | 57M | 0.17 |
| 31 | PX SEND BROADCAST | :TQ10011 | 7M | 39431 | 8 | 57M | 0.41 |
| 32 | PX BLOCK ITERATOR | | 7M | 39431 | 8 | 7M | |
| 33 | TABLE ACCESS STORAGE FULL | DWR_DIM_CONTRACT_D | 7M | 39431 | 104 | 7M | |
| 34 | HASH JOIN | | 21M | 104K | 8 | 32M | 2.89 |
| 35 | PX RECEIVE | | 6M | 27178 | 8 | 45M | 0.25 |
| 36 | PX SEND BROADCAST | :TQ10012 | 6M | 27178 | 8 | 45M | 0.08 |
| 37 | PX BLOCK ITERATOR | | 6M | 27178 | 8 | 6M | |
| 38 | TABLE ACCESS STORAGE FULL | DWR_DIM_PROJECT_D | 6M | 27178 | 106 | 6M | |
| 39 | HASH JOIN | | 21M | 76815 | 8 | 32M | 1.32 |
| 40 | PX RECEIVE | | 346K | 1990 | 8 | 3M | |
| 41 | PX SEND BROADCAST | :TQ10013 | 346K | 1990 | 8 | 3M | |
| 42 | PX BLOCK ITERATOR | | 346K | 1990 | 8 | 346K | |
| 43 | TABLE ACCESS STORAGE FULL | DWR_DIM_DEPARTMENT_EDW_D | 346K | 1990 | 104 | 346K | |
| 44 | HASH JOIN | | 21M | 74818 | 8 | 32M | 1.82 |
| 45 | PX RECEIVE | |82681 | 303 | 8 | 661K | |
| 46 | PX SEND BROADCAST | :TQ10014 |82681 | 303 | 8 | 661K | |
| 47 | PX BLOCK ITERATOR | |82681 | 303 | 8 | 82681 | |
| 48 | TABLE ACCESS STORAGE FULL | DWR_DIM_PRODUCT_D |82681 | 303 | 104 | 82681 | |
| 49 | HASH JOIN | | 21M | 74508 | 8 | 32M | 0.91 |
| 50 | PX RECEIVE | |82681 | 303 | 8 | 661K | |
| 51 | PX SEND BROADCAST | :TQ10015 |82681 | 303 | 8 | 661K | |
| 52 | PX BLOCK ITERATOR | |82681 | 303 | 8 | 82681 | |
| 53 | TABLE ACCESS STORAGE FULL | DWR_DIM_PRODUCT_D |82681 | 303 | 104 | 82681 | |
| 54 | HASH JOIN RIGHT OUTER | | 21M | 74199 | 8 | 32M | 1.90 |
| 55 | PX RECEIVE | | 6858 | 16 | 8 | 54864 | |
| 56 | PX SEND BROADCAST | :TQ10016 | 6858 | 16 | 8 | 54864 | |
| 57 | PX BLOCK ITERATOR | | 6858 | 16 | 8 | 6858 | |
| 58 | TABLE ACCESS STORAGE FULL | DWR_DIM_GRP_ACCT_CODE_D | 6858 | 16 | 155 | 6858 | |
| 59 | HASH JOIN RIGHT OUTER | | 21M | 74175 | 8 | 32M | 1.73 |
| 60 | PX RECEIVE | | 4074 | 33 | 8 | 17816 | |
| 61 | PX SEND BROADCAST | :TQ10017 | 4074 | 33 | 8 | 17816 | |
| 62 | VIEW | | 4074 | 33 | 8 | 2227 | |
| 63 | HASH JOIN BUFFERED | | 4074 | 33 | 8 | 2227 | |
| 64 | PX RECEIVE | | 1375 | 22 | 8 | 713 | |
| 65 | PX SEND HASH | :TQ10002 | 1375 | 22 | 8 | 713 | |
| 66 | HASH JOIN BUFFERED | | 1375 | 22 | 8 | 713 | |
| 67 | PX RECEIVE | | 657 | 2 | 8 | 657 | |
| 68 | PX SEND HASH | :TQ10000 | 657 | 2 | 8 | 657 | |
| 69 | PX BLOCK ITERATOR | | 657 | 2 | 8 | 657 | |
| 70 | TABLE ACCESS STORAGE FULL | DWR_DIM_REGION_RC_D | 657 | 2 | 23 | 657 | |
| 71 | PX RECEIVE | | 871 | 20 | 8 | 472 | |
| 72 | PX SEND HASH | :TQ10001 | 871 | 20 | 8 | 472 | |
| 73 | PX BLOCK ITERATOR | | 871 | 20 | 8 | 472 | |
| 74 | TABLE ACCESS STORAGE FULL | MCA_BLENDED_EXCHANGE_RATE_T| 871 | 20 | 122 | 472 | |
| 75 | PX RECEIVE | | 2110 | 10 | 8 | 2110 | |
| 76 | PX SEND HASH | :TQ10003 | 2110 | 10 | 8 | 2110 | |
| 77 | PX BLOCK ITERATOR | | 2110 | 10 | 8 | 2110 | |
| 78 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2110 | 10 | 167 | 2110 | |
| 79 | HASH JOIN | | 21M | 74136 | 8 | 32M | 0.58 |
| 80 | PX RECEIVE | | 2110 | 10 | 8 | 16880 | |
| 81 | PX SEND BROADCAST | :TQ10018 | 2110 | 10 | 8 | 16880 | |
| 82 | PX BLOCK ITERATOR | | 2110 | 10 | 8 | 2110 | |
| 83 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2110 | 10 | 167 | 2110 | |
| 84 | HASH JOIN | | 21M | 74119 | 8 | 32M | 0.41 |
| 85 | PX RECEIVE | | 2110 | 10 | 8 | 16880 | |
| 86 | PX SEND BROADCAST | :TQ10019 | 2110 | 10 | 8 | 16880 | |
| 87 | PX BLOCK ITERATOR | | 2110 | 10 | 8 | 2110 | |
| 88 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2110 | 10 | 167 | 2110 | |
| 89 | HASH JOIN | | 21M | 74102 | 8 | 32M | 1.65 |
| 90 | PX RECEIVE | | 2110 | 10 | 8 | 16880 | |
| 91 | PX SEND BROADCAST | :TQ10020 | 2110 | 10 | 8 | 16880 | |
| 92 | PX BLOCK ITERATOR | | 2110 | 10 | 8 | 2110 | |
| 93 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2110 | 10 | 167 | 2110 | |
| 94 | HASH JOIN | | 21M | 74085 | 8 | 32M | 1.24 |
| 95 | PX RECEIVE | | 657 | 2 | 8 | 5256 | |
| 96 | PX SEND BROADCAST | :TQ10021 | 657 | 2 | 8 | 5256 | |
| 97 | PX BLOCK ITERATOR | | 657 | 2 | 8 | 657 | |
| 98 | TABLE ACCESS STORAGE FULL | DWR_DIM_REGION_RC_D | 657 | 2 | 23 | 657 | |
| 99 | HASH JOIN | | 21M | 74077 | 8 | 32M | 0.74 |
| 100 | PX RECEIVE | | 400 | 2 | 8 | 3200 | |
| 101 | PX SEND BROADCAST | :TQ10022 | 400 | 2 | 8 | 3200 | |
| 102 | PX BLOCK ITERATOR | | 400 | 2 | 8 | 400 | |
| 103 | TABLE ACCESS STORAGE FULL | DWR_DIM_BU_D | 400 | 2 | 12 | 400 | |
| 104 | HASH JOIN | | 21M | 74068 | 8 | 32M | 0.25 |
| 105 | PX RECEIVE | | 400 | 2 | 8 | 3200 | |
| 106 | PX SEND BROADCAST | :TQ10023 | 400 | 2 | 8 | 3200 | |
| 107 | PX BLOCK ITERATOR | | 400 | 2 | 8 | 400 | |
| 108 | TABLE ACCESS STORAGE FULL | DWR_DIM_BU_D | 400 | 2 | 12 | 400 | |
| 109 | HASH JOIN RIGHT OUTER | | 21M | 74059 | 8 | 32M | 0.91 |
| 110 | PX RECEIVE | | 103 | 98 | 8 | 1312 | |
| 111 | PX SEND BROADCAST | :TQ10024 | 103 | 98 | 8 | 1312 | |
| 112 | PX BLOCK ITERATOR | | 103 | 98 | 8 | 164 | |
| 113 | TABLE ACCESS STORAGE FULL | MCA_PERIOD_RATE_T | 103 | 98 | 97 | 164 | |
| 114 | HASH JOIN RIGHT OUTER | | 21M | 73954 | 8 | 32M | 1.57 |
| 115 | PX RECEIVE | | 69 | 98 | 8 | 1312 | |
| 116 | PX SEND BROADCAST | :TQ10025 | 69 | 98 | 8 | 1312 | |
| 117 | PX BLOCK ITERATOR | | 69 | 98 | 8 | 164 | |
| 118 | TABLE ACCESS STORAGE FULL | MCA_PERIOD_RATE_T | 69 | 98 | 97 | 164 | |
| 119 | HASH JOIN | | 21M | 73849 | 8 | 32M | 0.58 |
| 120 | PX RECEIVE | | 39 | 2 | 8 | 312 | |
| 121 | PX SEND BROADCAST | :TQ10026 | 39 | 2 | 8 | 312 | |
| 122 | PX BLOCK ITERATOR | | 39 | 2 | 8 | 39 | |
| 123 | TABLE ACCESS STORAGE FULL | DWR_DIM_SALES_MODE_D | 39 | 2 | 5 | 39 | |
| 124 | HASH JOIN | | 21M | 73841 | 8 | 32M | 0.58 |
| 125 | PX RECEIVE | | 1 | 2 | 8 | 8 | |
| 126 | PX SEND BROADCAST | :TQ10027 | 1 | 2 | 8 | 8 | |
| 127 | PX BLOCK ITERATOR | | 1 | 2 | 8 | 1 | |
| 128 | TABLE ACCESS STORAGE FULL | DWR_DIM_BAS_SALES_TEAM_D | 1 | 2 | 1 | 1 | |
| 129 | HASH JOIN | | 21M | 73832 | 8 | 32M | 2.39 |
| 130 | PX RECEIVE | | 5M | 54391 | 8 | 6M | |
| 131 | PX SEND HASH | :TQ10028 | 5M | 54391 | 8 | 6M | 0.08 |
| 132 | HASH JOIN BUFFERED | | 5M | 54391 | 8 | 6M | 3.14 |
| 133 | PX RECEIVE | | 2M | 27210 | 8 | 2M | |
| 134 | PX SEND HASH | :TQ10004 | 2M | 27210 | 8 | 2M | 0.08 |
| 135 | PX BLOCK ITERATOR | | 2M | 27210 | 8 | 2M | |
| 136 | TABLE ACCESS STORAGE FULL| DWR_DIM_PROJECT_D | 2M | 27210 | 106 | 2M | 0.58 |
| 137 | PX RECEIVE | | 6M | 27178 | 8 | 6M | |
| 138 | PX SEND HASH | :TQ10005 | 6M | 27178 | 8 | 6M | 0.08 |
| 139 | PX BLOCK ITERATOR | | 6M | 27178 | 8 | 6M | |
| 140 | TABLE ACCESS STORAGE FULL| DWR_DIM_PROJECT_D | 6M | 27178 | 106 | 6M | 0.74 |
| 141 | PX RECEIVE | | 22M | 19431 | 8 | 33M | 2.31 |
| 142 | PX SEND HASH | :TQ10029 | 22M | 19431 | 8 | 33M | 2.48 |
| 143 | PX BLOCK ITERATOR | | 22M | 19431 | 8 | 33M | |
| 144 | TABLE ACCESS STORAGE FULL | DWR_FIN_GROUP_JE_ALL_F | 22M | 19431 | 159 | 33M | 9.57 |
===================================================================================================================================
加大统计信息值后,201301期间4.8分钟完成,201302期间20.68分钟完成,201303期间6.9分钟完成。
因为加大统计信息值只是临时做法,收集统计信息后又会覆盖该值。为稳妥起见,又通过SPM对fgu2dhf847r3q做了执行计划固定,固定到了Plan Hash Value=1691128212。
固定之后,201304期间7.98分钟完成,201305期间10.1分钟完成。
会计期之间的时间差异,跟当时系统IO资源是否紧张有关系。因为现在SIT环境IO资源不是很好,很容易受其他程序影响。
解决方案:
建议:
- 后台加大表DWR_FIN_GROUP_JE_ALL_F的统计信息值。
- 通过SPM固定执行计划。
2.2 Select子句和Where子句的子查询
2.2.1 Select子查询
问题描述:
环境:生产环境
程序:CES视图ISS_DN_SPU_PO_V
时间:2013-11-18
有个通个create table创建远程备份表的方式拉数据有1.5亿记录,在后台创建了很久都没有结果,应该是远程接口视图存在性能问题造成,建议和CES数据库DBA看下原因。
抽数脚本如下:
Sql_id 135manmh27kyc 118mins
/*发货需求统计*/
CREATE TABLE DMTEMP.ISS_DN_SPU_PO_V_4000_TMP1 TABLESPACE DMTEMPDAT NOLOGGING PARALLEL 16 AS
SELECT /*+ PARALLEL(16)*/ T.REQUEST_HEADER_ID,
T.REQUEST_LINE_ID,
T.ONHAND_ID,
T.REQUEST_QTY,
T.TRANSACTION_QTY,
T.BOX_NO,
T.MBOX_NO,
T.SPU_BARCODE,
T.ITEM_CODE,
T.ENTITY_ID,
T.SUBINVENTORY_CODE,
T.LOCATOR_CODE,
T.LSP_LOCATOR_CODE,
T.MBOX_NAME,
T.MBOX_TYPE,
T.SITE_TYPE,
T.PACKINSTRUCTION_TYPE,
T.PACK_VERSION,
T.SITE_DESC,
T.DESCRIPTION,
T.UNIT,
T.LAST_UPDATE_DATE,
4000 AS SS_ID,
19000101000000 AS CYCLE_ID,
-1 AS CRT_JOB_INSTANCE_ID,
-1 AS UPD_JOB_INSTANCE_ID
FROM RLS_CUTOVER.ISS_DN_SPU_PO_V@CES T
源系统视图脚本如下:
CREATE OR REPLACE FORCE VIEW rls_cutover.iss_dn_spu_po_v (request_header_id,
request_line_id,
onhand_id,
request_qty,
transaction_qty,
box_no,
mbox_no,
spu_barcode,
item_code,
entity_id,
subinventory_code,
locator_code,
lsp_locator_code,
mbox_name,
mbox_type,
site_type,
packinstruction_type,
pack_version,
site_desc,
description,
unit,
last_update_date
)
AS
SELECT isrl.request_header_id, isrl.request_line_id, isrl.onhand_id,
isrl.request_qty, isrl.transaction_qty,
(SELECT iouv.box_no
FROM inv_onhand_union_v iouv
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND ROWNUM = 1) box_no,
(SELECT iouv.mbox_no
FROM inv_onhand_union_v iouv
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND ROWNUM = 1) mbox_no,
(SELECT iouv.spu_barcode
FROM inv_onhand_union_v iouv
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND ROWNUM = 1) spu_barcode,
(SELECT iouv.item_code
FROM inv_onhand_union_v iouv
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND ROWNUM = 1) item_code,
isrl.entity_id,
(SELECT iouv.subinventory_code
FROM inv_onhand_union_v iouv
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND ROWNUM = 1) subinventory_code,
(SELECT iouv.locator_code
FROM inv_onhand_union_v iouv
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND ROWNUM = 1) locator_code,
(SELECT iouv.lsp_locator_code
FROM inv_onhand_union_v iouv
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND ROWNUM = 1) lsp_locator_code,
(SELECT oss.mbox_name
FROM inv_onhand_union_v iouv, om_spu_status oss
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND iouv.spu_barcode = oss.spu_barcode
AND iouv.entity_id = oss.entity_id
AND ROWNUM = 1) mbox_name,
(SELECT oss.mbox_type
FROM inv_onhand_union_v iouv, om_spu_status oss
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND iouv.spu_barcode = oss.spu_barcode
AND iouv.entity_id = oss.entity_id
AND ROWNUM = 1) mbox_type,
(SELECT oo.site_type || ' ' || op.pack_version
FROM inv_onhand_union_v iouv,
om_packinfo op,
om_spu_status oss,
om_orders oo
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND iouv.spu_barcode = oss.spu_barcode
AND iouv.entity_id = oss.entity_id
AND op.pack_no = oss.pack_no
AND op.entity_id = oss.entity_id
AND oo.pack_no = oss.pack_no
AND oo.entity_id = oss.entity_id
AND ROWNUM = 1) site_type,
(SELECT oo.site_type
FROM inv_onhand_union_v iouv,
om_spu_status oss,
om_orders oo
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND iouv.spu_barcode = oss.spu_barcode
AND iouv.entity_id = oss.entity_id
AND oo.pack_no = oss.pack_no
AND oo.entity_id = oss.entity_id
AND ROWNUM = 1) packinstruction_type,
(SELECT op.pack_version
FROM inv_onhand_union_v iouv,
om_packinfo op,
om_spu_status oss
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND iouv.spu_barcode = oss.spu_barcode
AND iouv.entity_id = oss.entity_id
AND op.pack_no = oss.pack_no
AND op.entity_id = oss.entity_id
AND ROWNUM = 1) pack_version,
(SELECT oo.site_description
FROM inv_onhand_union_v iouv,
om_spu_status oss,
om_orders oo
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND iouv.spu_barcode = oss.spu_barcode
AND iouv.entity_id = oss.entity_id
AND oo.pack_no = oss.pack_no
AND oo.entity_id = oss.entity_id
AND ROWNUM = 1) site_desc,
(SELECT bi.description
FROM inv_onhand_union_v iouv, bas_items bi
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND iouv.inventory_item_id = bi.inventory_item_id
AND ROWNUM = 1) description,
(SELECT bi.unit
FROM inv_onhand_union_v iouv, bas_items bi
WHERE iouv.entity_id = isrl.entity_id
AND iouv.inventory_id = isrl.onhand_id
AND iouv.inventory_item_id = bi.inventory_item_id
AND ROWNUM = 1) unit,
isrl.last_update_date
FROM iss_shipping_request_line isrl;
用户反馈,这个视图本身并不慢,不到1s就出结果了
Count也不慢,结果集1.5亿条。
用户在sqlplus里,一敲回车,立马就出结果了,然后我再ctrl C终止掉,这是快还是慢。也有PLSQL Developer里只显示N行的东西在吗?
问题分析:
视图rls_cutover.iss_dn_spu_po_v的抽数性能比较差,关键在于源系统视图的Select子句有15个子查询。
这种写法,结果集的每条记录都会要检索15个子查询。结果集有1.5亿条,则子查询一共要运行1.5亿15=22.5亿次。不管这些子查询有多快,22.5亿次也是一个天文数字。哪怕是0.1毫秒1次,也需要22500000000.1/1000/3600=62.5小时。
这里有个误区,就是认为Count(1)很快,或者在客户端Select * 很快,就没有性能问题。
但事实并不是这样子的,Count(1)很快,并不能说明就没有性能问题。因为Count的时候并不会关注Select子句有多少个字段,是否有子查询或者函数。
在PLSQL Developer或者Sqlplus里Select 很快,也不能说明就没有性能问题,因为只会显示前 N条记录,而不是所有记录。
就客户抓图里显示的1.57s检索190行为例,190行耗时1.57s,即每条记录耗时1.57s/190=0.008s。1.5亿条需耗时1.5亿0.008s/3600=333小时。
实际上,Insert的效率应该比在客户端select * 还要快一些。但是就本例来说,Insert也还是需要20个小时以上。
Select子句不允许有子查询和自定义函数,这在RA开发规范是有明确规定的。
建议把Select子查询改为关联查询,然后再对关联查询做调优。
解决方案:
建议:
- 修改源系统视图,将Select子句里的子查询改写为关联查询。
- 如果源系统该视图仅提供给RA使用,则建议在原视图上加/+Parallel(8)/的提示,同时将RA端取数时的并行提示改为/+Parallel(8)/。
2.2.2 Where子查询
问题描述:
环境:生产环境
程序:HFM分公司调度YTD程序DWR_HFM_PKG.HFM_TRAIL_BAL_YTD_P
时间:2013-04-26
分公司调度中YTD今天已经跑了25分钟,但是昨晚的日增量跑了2分钟左右,请各位帮忙分析一下,谢谢!
Pkg的位置:Dwr_hfm_pkg. HFM_TRAIL_BAL_YTD_P
SELECT D.STEP_TYPE,
D.STEP_START_TIME,
D.STEP_END_TIME,
D.DATA_COMPONENT_NAME,
D.LOG_MESSAGE,
D.DML_ROW_COUNT
FROM FND_PROCESS_LOG M, FND_PROCESS_STEP_LOG D
WHERE /*M.CYCLE_ID = '20120201000002'
AND TRUNC(D.STEP_START_TIME) = TRUNC(SYSDATE)
AND*/
M.CYCLE_ID = D.CYCLE_ID
AND M.LOG_JOB_ID = D.LOG_JOB_ID
AND M.PROCESS_COMPONENT_ID = D.PROCESS_COMPONENT_ID
AND M.PROCESS_TIMEKEY = D.PROCESS_TIMEKEY
AND M.PROCESS_COMPONENT_NAME LIKE '%HFM_TRAIL_BAL_YTD_P%'
AND D.STEP_START_TIMe >= date '2013-04-27'
ORDER BY D.STEP_END_TIME DESC;
-
用日增量全量跑的时候就耗时3分钟左右。
-
分公司跑超过了20分钟。
问题分析:
代码中的Exists子查询执行次数太多导致性能问题。
- 建议给DWR_SUBSIDIARY_SCHEDULE_R_TMP加索引,走索引扫描。
- 对P_SCHEDULE_TASK_ID进行判断
如果是P_SCHEDULE_TASK_ID日常执行:
AND ((NVL(&P_SCHEDULE_TASK_ID, 0) = 0)
如果是分公司走如下代码:
(NVL(&P_SCHEDULE_TASK_ID, 0) <> 0 AND EXISTS -- 分公司调度
(SELECT 1
FROM DWR_SUBSIDIARY_SCHEDULE_R_TMP SCHEDULE --modify by liuhongfang 2013/4/15
WHERE COMPANY.COMPANY_KEY = SCHEDULE.COMPANY_KEY))
如果希望程序改动最小,则给DWR_SUBSIDIARY_SCHEDULE_R_TMP加索引,以便Exists子查询能走索引。但是因为子查询要执行上百万次,数据量大时还是会有性能问题。而且,Exists和索引我们都不推荐使用,所以这是短期解决办法。
最好的办法,是修改程序,日增量调度和分公司调度分开代码。这样,日增量调度时,不需要Exist子查询。而分公司调度时,则可以将Exists子查询改为关联查询,大大提高效率。
在对YTD程序的EXISTS进行优化以后,现在400多万的数据9分钟左右完成,瓶颈在删除数据。
代码如下:
-- 日常调度清理正式表数据,如果是日常调度可以TRUNCATE,
IF P_SCHEDULE_TYPE = 1 THEN --日增量调度
EXECUTE IMMEDIATE 'ALTER TABLE DWINTFC.HFM_TRAIL_BAL_YTD TRUNCATE PARTITION ' || 'P_' ||
V_PERIOD_ID; --ADD BY LIUHONGFANG 2013/4/15
ELSE
--分公司调度,调度任务关联的公司 ,不能TRUNCATE
DELETE /*+ PARALLEL(8) */
FROM HFM_TRAIL_BAL_YTD T --目标表
WHERE T.PERIOD_ID = V_PERIOD_ID
AND EXISTS (SELECT 1
FROM DWR_DIM_COMPANY_D_HFM_TMP C
WHERE T.COMPANY_KEY = C.COMPANY_KEY
AND C.FILTER_FLAG = 0);
END IF;
说明一下:HFM_TRAIL_BAL_YTD有建本地唯一索引,但是分公司的调度不能TRUNCATE。
DWR_DIM_COMPANY_D_HFM_TMP是一个Session级别的临时表,总共有2000多记录。COMPANY_KEY字段是主键。
HFM_TRAIL_BAL_YTD表按会计期分区,记录数量3560多万。
select a.period_id, count(*) from HFM_TRAIL_BAL_YTD a group by a.period_id;
注意到,表HFM_TRAIL_BAL_YTD上有一个局部唯一性索引DWINTFC.HFM_TRAIL_BAL_YTD_P_U1,多达14个字段。
create unique index DWINTFC.HFM_TRAIL_BAL_YTD_P_U1 on DWINTFC.HFM_TRAIL_BAL_YTD (PERIOD_ID, GROUP_ACCOUNT_CODE, ACCOUNT_TYPE_CODE, COMPANY_KEY, IC_KEY, DEPT_KEY, PROD_KEY, GEO_PC_KEY, LC_CODE, SOB_TYPE_ID, SOB_CLASS_FLAG, DATA_CLASS_FLAG, DATA_PRODUCE_TYPE_FLAG, DATA_SOURCE_TABLE_ID)
local;
根据经验,去掉索引的话,不用维护索引,则Insert和Delete语句都会快一倍以上。
既然是通过ETL调度,完全可以通过ETL程序来保证数据的唯一性,而不是依赖索引。建议从性能角度出发,删除类似的不合理索引。
测试了一下,删除一个会计期837万条记录,有索引时花了2142秒,没索引时仅用了39秒,有索引耗时是没索引时的55倍。
测试脚本如下:
Alter Session Enable Parallel DML;
DELETE /*+ PARALLEL(8) */
FROM DWINTFC.HFM_TRAIL_BAL_YTD_BB T --目标表
WHERE T.PERIOD_ID = 201304
AND EXISTS (SELECT 1
FROM DWAPP.DWR_DIM_COMPANY_D_HFM_TMP C
WHERE T.COMPANY_KEY = C.COMPANY_KEY
AND C.FILTER_FLAG = 0);
Commit;
Alter Session Disable Parallel DML;
无论如何,14个字段的唯一索引,在哪个系统都不是一个理想的设计。
解决方案:
- 去掉表DWINTFC.HFM_TRAIL_BAL_YTD上的索引。
- 尽量改Delete为Truncate
- 尽量去掉Exists子查询
2.3 索引问题
2.3.1 合同维表索引导致不能用Smart Scan
问题描述:
环境:生产环境
程序:CSO源控件抽数_合同
时间:2014-03-13
请帮忙优化一这个sql, 该语句运行了近7小时, 生产环境edw库
Sql id: 1trfptg33hmm5
SELECT NVL(OCCU.HW_CONTRACT_NUM, 'NULL') CONTRACT_NUMBER, --华为合同号
OCCU.CONTRACT_MAIN_TYPE_ID CONTRACT_TYPE, --合同主类型
OCCU.CONTRACT_SUB_TYPE_ID CONTRACT_CLASS, --合同子类型
OCCU.CONTRACT_STATUS_ID STATUS, -- 状态
OCCU.ISSUE_DATE AS ISSUE_DATE, --客户界面下发日期
OCCU.RECEIVED_DATE AS RECEIVED_DATE, --接收日期
OCCU.REGISTRATION_DATE AS REGISTER_DATE, --发布日期
OCCU.LAST_UPDATE_DATE AS LAST_UPDATE_DATE,
TO_CHAR(CHG.CHANGE_REASON) CHANGE_REASON, --合同变更原因
OCCU.SIGN_DATE SIGNED_DATE, --合同签订日期
'CIR' AS CONTRACT_SOURCE_TYPE,
OCCU.ENGINEERING_SERVICE_FLAG AS PROJ_DELIVER_FLAG, -- 工程交付标识
OCCU.DELIVERY_PROJ_ID AS DELIVERY_PROJECT_ID, -- 取项目KEY
OCCU.CONTRACT_MAIN_PROD_TYPE_ID MAIN_PRODUCT_TYPE, --产品主类型
'N' AS SPECIAL_COUNTRY_FLAG, --特殊国家合同标识--特殊国家合同标识--DWI_CM_THIRD_CHAIN_BUSINESS_T仅有两条记录不集成,所以给'N'
A.REGISTER_DATE REGISTRATION_DATE_V1, --注册日期(1.0版本)
TO_NUMBER(DECODE(CL_SCT.CODE,'SNULL','',CL_SCT.CODE)) AS DISTRIBUTED_STATUS, --合同拆分状态
OCCU.VERSION, --版本
NVL(OCCU.VERSION, 'SNULL') AS VERSION_JOIN, --版本关联使用
CASE
WHEN OCCU.PURE_SERVICE_CONTRACT_FLAG = 'N' THEN
'N'
WHEN OCCU.PURE_SERVICE_CONTRACT_FLAG = 'Y' THEN
'Y'
ELSE
NULL
END PURE_SERVICE_FLAG, --纯服务合同标识
OCCU.S3_PILOT_FLAG AS S3_PILOT_FLAG, --S3试点合同标识
NVL(OCCU.TERMINAL_CONTRACT_FLAG, 'N') AS TERMINAL_CONTRACT_FLAG,
OCCU.CONTRACT_BUSINESS_TYPE_ID BUSINESS_TYPE,
BU_D.BU_KEY BG_TYPE,
NULL CONTRACT_TOTAL_AMT_USD,
REVIEW_CMPLT.CTRCT_REVIEW_CMPLT_DATE
FROM DWI_MD_CONTRACT_VERSION_MV OCCU,
DWR_DIM_BU_D BU_D,
DWI_MD_CONTRACT MD,
DWI_MD_CLASS CL,
-- DWRLTC.DWR_CONTRACT_HISINFO_F_TMP TMP,
(SELECT TH.CONTRACT_ID, TH.VERSION, TH.REGISTRATION_DATE AS REGISTER_DATE
FROM DWI_MD_CONTRACT_VERSION_MV TH--, DWRLTC.DWR_CONTRACT_HISINFO_F_TMP TMP
WHERE TH.VERSION = 'V001.000'
-- AND TH.CONTRACT_ID = TMP.CONTRACT_ID
-- AND TH.VERSION = TMP.VERSION
) A,
(SELECT CONTRACT_ID, VERSION, CHANGE_REASON
FROM (SELECT T.CONTRACT_ID,
T.VERSION,
T.CHANGE_REASON_DESCR CHANGE_REASON,
ROW_NUMBER() OVER(PARTITION BY T.CONTRACT_ID, T.VERSION ORDER BY T.CONTRACT_CHANGE_TYPE_ID,T.CHANGE_REASON_DESCR) RN
FROM DWI_MD_CONTRACT_CHANGE T --,
-- DWRLTC.DWR_CONTRACT_HISINFO_F_TMP TMP
WHERE T.DEL_FLAG = 'N'
-- AND T.CONTRACT_ID=TMP.CONTRACT_ID
AND T.SS_ID = 2600
-- AND T.VERSION=TMP.VERSION
)
WHERE RN = 1) CHG,
DWI_MD_CONTRACT_SPLIT_STATUS SCT,
DWI_MD_CLASS CL_SCT,
((SELECT CONTRACT_NUMBER,
NVL(DATE_APPROVED, TO_DATE('47121231', 'YYYYMMDD')) AS CTRCT_REVIEW_CMPLT_DATE
FROM (SELECT T.CONTRACT_NUMBER,
T.DATE_APPROVED,
ROW_NUMBER() OVER(PARTITION BY T.CONTRACT_NUMBER ORDER BY T.DATE_APPROVED DESC NULLS LAST) RN
FROM (SELECT T.HW_CONTRACT_NUM AS CONTRACT_NUMBER, T.CTRCT_REVIEW_CMPLT_DATE AS DATE_APPROVED
FROM DWI_MD_CONTRACT_VERSION_MV T,
DWRLTC.DWR_CONTRACT_KEY_INFO_TMP CON/*,
DWRLTC.DWR_CONTRACT_HISINFO_F_TMP TMP*/
WHERE /*CON.CONTRACT_ID=TMP.CONTRACT_ID
AND*/ T.HW_CONTRACT_NUM=CON.CONTRACT_NUMBER
) T)
WHERE RN = 1)) REVIEW_CMPLT
WHERE OCCU.CONTRACT_ID = CHG.CONTRACT_ID(+)
AND OCCU.VERSION = CHG.VERSION(+)
/* AND OCCU.CONTRACT_ID = TMP.CONTRACT_ID
AND OCCU.VERSION = TMP.VERSION*/
AND OCCU.CONTRACT_ID = A.CONTRACT_ID(+)
AND OCCU.CONTRACT_ID = SCT.CONTRACT_ID(+)
AND OCCU.VERSION = SCT.RAS_SPLIT_VERSION(+)
AND OCCU.HW_CONTRACT_NUM = REVIEW_CMPLT.CONTRACT_NUMBER(+)
AND OCCU.CONTRACT_STATUS_ID = CL.CLASS_ID
AND UPPER(CL.CODE) IN ('PUBLISHED', 'CLOSED', 'PRE-CLOSED')--9:PUBLISHED 13:CLOSED 14:PRE-CLOSED
AND SCT.DEL_FLAG(+) ='N'
AND OCCU.CONTRACT_ID = MD.CONTRACT_ID
AND SCT.RAS_SPLIT_STATUS_ID = CL_SCT.CLASS_ID(+)
AND OCCU.BG_ID = BU_D.BU_ID
AND BU_D.SCD_ACTIVE_IND = 1
AND MD.SS_ID = 2600
AND MD.END_TIME = DATE'4712-12-31'
AND SCT.END_TIME(+) = DATE'4712-12-31'
AND NVL(OCCU.HW_CONTRACT_NUM, 'NULL') not like 'EMS%'
AND NVL(OCCU.HW_CONTRACT_NUM, 'NULL') not like 'EMK%'
AND NVL(OCCU.HW_CONTRACT_NUM, 'NULL') not like 'BS%'
UNION ALL
--CPP
----CPP
SELECT NVL(OCCU.HW_CONTRACT_NUM, 'NULL') CONTRACT_NUMBER, --华为合同号
NULL CONTRACT_TYPE, --合同主类型
OCCU.CONTRACT_SUB_TYPE_ID CONTRACT_CLASS, --合同子类型
OCCU.CONTRACT_STATUS_ID STATUS, -- 状态
NULL ISSUE_DATE, --客户界面下发日期
NULL RECEIVED_DATE, --接收日期
OCCU.REGISTRATION_DATE AS REGISTER_DATE, --发布日期
OCCU.LAST_UPDATE_DATE AS LAST_UPDATE_DATE,
NULL CHANGE_REASON, --合同变更原因
NULL SIGNED_DATE, --合同签订日期
'CPP' AS CONTRACT_SOURCE_TYPE,
OCCU.ENGINEERING_SERVICE_FLAG AS PROJ_DELIVER_FLAG, -- 工程交付标识
NULL DELIVERY_PROJECT_ID, -- 取项目KEY
NULL MAIN_PRODUCT_TYPE, --产品主类型
NULL SPECIAL_COUNTRY_FLAG, --特殊国家合同标识
OCCU.REGISTRATION_DATE AS REGISTRATION_DATE_V1, --注册日期(1.0版本)
TO_NUMBER(DECODE(CL_SCT.CODE,'SNULL','',CL_SCT.CODE)) AS DISTRIBUTED_STATUS, --合同拆分状态
OCCU.VERSION, --版本
NVL(OCCU.VERSION, 'SNULL') AS VERSION_JOIN, --版本关联使用
NVL(PURE_SRV_CON.PURE_SERVICE_FLAG, 'N') PURE_SERVICE_FLAG, --纯服务合同标识
NULL S3_PILOT_FLAG, --S3试点合同标识
'N' AS TERMINAL_CONTRACT_FLAG,
NULL BUSINESS_TYPE,
NULL BG_TYPE,
NULL CONTRACT_TOTAL_AMT_USD,
NULL CTRCT_REVIEW_CMPLT_DATE
FROM DWI_MD_CONTRACT_VERSION_MV OCCU,
DWI_MD_CONTRACT MD,
DWI_MD_CLASS CL,
-- DWRLTC.DWR_CONTRACT_HISINFO_F_TMP TMP,
(SELECT DISTINCT T1.HW_CONTRACT_NUM AS HTH, 'Y' PURE_SERVICE_FLAG
FROM DWI_MD_CONTRACT_PU T1,
DWI_MD_CLASS CL,
(SELECT T.HW_CONTRACT_NUM , COUNT(DISTINCT T.SALES_PROD_TYPE_ID)
FROM DWI_MD_CONTRACT_PU T,
DWRLTC.DWR_CONTRACT_KEY_INFO_TMP CON/*,
DWRLTC.DWR_CONTRACT_HISINFO_F_TMP TMP*/
WHERE T.DEL_FLAG ='N'
AND T.HW_CONTRACT_NUM=CON.CONTRACT_NUMBER
-- AND CON.CONTRACT_ID=TMP.CONTRACT_ID
AND T.SS_ID = 2800
AND T.END_TIME = DATE'4712-12-31'
GROUP BY T.HW_CONTRACT_NUM
HAVING COUNT(DISTINCT T.SALES_PROD_TYPE_ID) = 1) T2
WHERE T1.HW_CONTRACT_NUM = T2.HW_CONTRACT_NUM
AND T1.SALES_PROD_TYPE_ID = CL.CLASS_ID
AND CL.CODE = '服务'
AND T1.DEL_FLAG ='N'
AND T1.END_TIME = DATE'4712-12-31') PURE_SRV_CON,
DWI_MD_CONTRACT_SPLIT_STATUS SCT,
DWI_MD_CLASS CL_SCT,
DWI_MD_CONTRACT_EXE_ATTR ATTR
WHERE OCCU.CONTRACT_ID = SCT.CONTRACT_ID(+)
AND OCCU.VERSION = SCT.RAS_SPLIT_VERSION(+)
/* AND OCCU.CONTRACT_ID=TMP.CONTRACT_ID
AND OCCU.VERSION=TMP.VERSION*/
AND OCCU.HW_CONTRACT_NUM = PURE_SRV_CON.HTH(+)
AND NVL(OCCU.HW_CONTRACT_NUM, 'NULL') not like 'EMS%'
AND NVL(OCCU.HW_CONTRACT_NUM, 'NULL') not like 'EMK%'
AND NVL(OCCU.HW_CONTRACT_NUM, 'NULL') not like 'BS%'
AND OCCU.CONTRACT_STATUS_ID = CL.CLASS_ID
AND CL.CODE = '2'
AND OCCU.CONTRACT_ID = ATTR.CONTRACT_ID
AND NVL(ATTR.EMS_TYPE, 'UNKNOWN') <> 'EMS'
AND SCT.DEL_FLAG(+) ='N'
AND SCT.END_TIME(+) = DATE'4712-12-31'
AND MD.END_TIME = DATE'4712-12-31'
AND OCCU.CONTRACT_ID = MD.CONTRACT_ID
AND SCT.RAS_SPLIT_STATUS_ID = CL_SCT.CLASS_ID(+)
AND MD.SS_ID = 2800
问题分析:
为方便测试,我在SQL外面包了一层Count,即:
SELECT COUNT(0) FROM (…);
原来的Count语句1899s完成,执行计划如下:
SQL Plan Monitoring Details (Plan Hash Value=3583332453)
==============================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | |(Estim) | | | (Actual) | (%) |
==============================================================================================================================
| 0 |SELECT STATEMENT | | | | 1 | 1 | |
| 1 | SORT AGGREGATE | | 1 | | 1 | 1 | |
| 2 | NESTED LOOPS OUTER | | 1062 | 665K | 1 | 2M | |
| 3 | VIEW | VW_JF_SET$84B1CF17 | 1062 | 661K | 1 | 2M | |
| 4 | UNION-ALL | | | | 1 | 2M | |
| 5 | HASH JOIN | | 1047 | 427K | 1 | 2M | 0.05 |
| 6 | TABLE ACCESS STORAGE FULL | DWR_DIM_BU_D | 226 | 7 | 1 | 278 | |
| 7 | HASH JOIN OUTER | | 871 | 427K | 1 | 2M | 0.11 |
| 8 | HASH JOIN OUTER | | 769 | 261K | 1 | 2M | 0.21 |
| 9 | NESTED LOOPS | | | | 1 | 2M | 0.21 |
| 10 | NESTED LOOPS | | 769 | 138K | 1 | 71M | 0.27 |
| 11 | NESTED LOOPS OUTER | | 769 | 128K | 1 | 2M | |
| 12 | NESTED LOOPS | | 769 | 123K | 1 | 2M | |
| 13 | MAT_VIEW ACCESS STORAGE FULL | DWI_MD_CONTRACT_VERSION_MV | 769 | 123K | 1 | 6M | 1.17 |
| 14 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CLASS | 1 | 1 | 6M | 2M | 0.32 |
| 15 | INDEX UNIQUE SCAN | DWI_MD_CLASS_U1 | 1 | | 6M | 6M | 0.11 |
| 16 | VIEW PUSHED PREDICATE | | 1 | 6 | 2M | 670K | 0.05 |
| 17 | WINDOW SORT PUSHED RANK | | 1 | 6 | 2M | 671K | 0.48 |
| 18 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CONTRACT_CHANGE | 1 | 5 | 2M | 671K | 1.39 |
| 19 | INDEX RANGE SCAN | DWI_MD_CONTRACT_CHANGE_U1 | 1 | 3 | 2M | 2M | 0.75 |
| 20 | INDEX RANGE SCAN | DWI_MD_CONTRACT_U1 | 11 | 2 | 3M | 71M | 5.49 |
| 21 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CONTRACT | 1 | 13 | 87M | 2M | 73.93 |
| 22 | MAT_VIEW ACCESS STORAGE FULL | DWI_MD_CONTRACT_VERSION_MV | 8191 | 122K | 1 | 1M | 0.21 |
| 23 | VIEW | | 6M | 167K | 1 | 5M | |
| 24 | VIEW | | 6M | 167K | 1 | 5M | 0.05 |
| 25 | WINDOW SORT PUSHED RANK | | 6M | 167K | 1 | 6M | 0.75 |
| 26 | NESTED LOOPS | | 6M | 123K | 1 | 6M | 0.05 |
| 27 | MAT_VIEW ACCESS STORAGE FULL | DWI_MD_CONTRACT_VERSION_MV | 6M | 123K | 1 | 6M | 0.48 |
| 28 | INDEX UNIQUE SCAN | DWR_CONTRACT_KEY_INFO_TMP_U1 | 1 | | 6M | 6M | 0.59 |
| 29 | NESTED LOOPS | | | | 1 | 609K | 0.05 |
| 30 | NESTED LOOPS | | 15 | 234K | 1 | 609K | |
| 31 | NESTED LOOPS | | 15 | 234K | 1 | 609K | |
| 32 | HASH JOIN OUTER | | 15 | 234K | 1 | 610K | 0.11 |
| 33 | HASH JOIN | | 15 | 123K | 1 | 610K | 0.05 |
| 34 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CLASS | 1 | 4 | 1 | 123 | |
| 35 | INDEX RANGE SCAN | DWI_MD_CLASS_U2 | 1 | 2 | 1 | 123 | |
| 36 | MAT_VIEW ACCESS STORAGE FULL | DWI_MD_CONTRACT_VERSION_MV | 769 | 123K | 1 | 6M | 0.37 |
| 37 | VIEW | | 1 | 111K | 1 | 420K | |
| 38 | HASH UNIQUE | | 1 | 111K | 1 | 420K | 0.05 |
| 39 | NESTED LOOPS | | | | 1 | 514K | |
| 40 | NESTED LOOPS | | 1 | 111K | 1 | 4M | |
| 41 | HASH JOIN | | 1 | 111K | 1 | 4M | 0.16 |
| 42 | VIEW | | 1 | 55629 | 1 | 2M | |
| 43 | FILTER | | | | 1 | 2M | |
| 44 | SORT GROUP BY | | 1 | 55629 | 1 | 2M | 0.32 |
| 45 | NESTED LOOPS | | 1674 | 55628 | 1 | 3M | |
| 46 | TABLE ACCESS STORAGE FULL | DWI_MD_CONTRACT_PU | 1674 | 55628 | 1 | 3M | 0.05 |
| 47 | INDEX UNIQUE SCAN | DWR_CONTRACT_KEY_INFO_TMP_U1 | 1 | | 3M | 3M | 0.11 |
| 48 | TABLE ACCESS STORAGE FULL | DWI_MD_CONTRACT_PU | 10042 | 55628 | 1 | 7M | 0.05 |
| 49 | INDEX UNIQUE SCAN | DWI_MD_CLASS_U1 | 1 | | 4M | 4M | 0.21 |
| 50 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CLASS | 1 | 1 | 4M | 514K | |
| 51 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CONTRACT | 1 | 13 | 610K | 609K | 7.89 |
| 52 | INDEX RANGE SCAN | DWI_MD_CONTRACT_U1 | 11 | 2 | 610K | 3M | 0.69 |
| 53 | INDEX UNIQUE SCAN | DWI_MD_CONTRACT_EXE_ATTR_U1 | 1 | 1 | 609K | 609K | 0.21 |
| 54 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CONTRACT_EXE_ATTR | 1 | 2 | 609K | 609K | 0.69 |
| 55 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CONTRACT_SPLIT_STATUS | 1 | 3 | 2M | 676K | 1.49 |
| 56 | INDEX RANGE SCAN | MD_CONTRACT_SPLIT_STATUS_U1 | 1 | 2 | 2M | 4M | 0.80 |
==============================================================================================================================
这个SQL性能比较差还是因为DWI_MD_CONTRACT走了索引的缘故。
解决办法是在Union All连接的两段SQL的Select处,均加入提示/+FULL(MD)/,强制表DWI_MD_CONTRACT走全表扫描,修改后的SQL,Count出全部240多万数据,仅需要165s。
新的执行计划如下:
SQL Plan Monitoring Details (Plan Hash Value=3898737674)
==============================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | |(Estim) | | | (Actual) | (%) |
==============================================================================================================================
| 0 |SELECT STATEMENT | | | | 1 | 1 | |
| 1 | SORT AGGREGATE | | 1 | | 1 | 1 | |
| 2 | VIEW | | 1068 | 2M | 1 | 2M | |
| 3 | UNION-ALL | | | | 1 | 2M | |
| 4 | HASH JOIN OUTER | | 1053 | 977K | 1 | 2M | 1.22 |
| 5 | NESTED LOOPS OUTER | | 929 | 811K | 1 | 2M | |
| 6 | HASH JOIN OUTER | | 924 | 808K | 1 | 2M | 1.22 |
| 7 | NESTED LOOPS | | | | 1 | 2M | |
| 8 | NESTED LOOPS | | 924 | 686K | 1 | 2M | |
| 9 | HASH JOIN | | 924 | 685K | 1 | 2M | 0.61 |
| 10 | TABLE ACCESS STORAGE FULL | DWR_DIM_BU_D | 226 | 7 | 1 | 278 | |
| 11 | NESTED LOOPS OUTER | | 769 | 685K | 1 | 2M | |
| 12 | HASH JOIN | | 769 | 680K | 1 | 2M | 0.61 |
| 13 | TABLE ACCESS STORAGE FULL | DWI_MD_CONTRACT | 1220 | 558K | 1 | 1M | 1.22 |
| 14 | MAT_VIEW ACCESS STORAGE FULL | DWI_MD_CONTRACT_VERSION_MV | 769 | 123K | 1 | 6M | 4.88 |
| 15 | VIEW PUSHED PREDICATE | | 1 | 6 | 2M | 693K | 1.22 |
| 16 | WINDOW SORT PUSHED RANK | | 1 | 6 | 2M | 694K | 8.54 |
| 17 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CONTRACT_CHANGE | 1 | 5 | 2M | 694K | 3.05 |
| 18 | INDEX RANGE SCAN | DWI_MD_CONTRACT_CHANGE_U1 | 1 | 3 | 2M | 2M | 6.10 |
| 19 | INDEX UNIQUE SCAN | DWI_MD_CLASS_U1 | 1 | | 2M | 2M | 1.22 |
| 20 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CLASS | 1 | 1 | 2M | 2M | 0.61 |
| 21 | MAT_VIEW ACCESS STORAGE FULL | DWI_MD_CONTRACT_VERSION_MV | 8191 | 122K | 1 | 1M | 2.44 |
| 22 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CONTRACT_SPLIT_STATUS | 1 | 3 | 2M | 676K | 11.59 |
| 23 | INDEX RANGE SCAN | MD_CONTRACT_SPLIT_STATUS_U1 | 1 | 2 | 2M | 3M | 9.76 |
| 24 | VIEW | | 6M | 167K | 1 | 5M | |
| 25 | VIEW | | 6M | 167K | 1 | 5M | |
| 26 | WINDOW SORT PUSHED RANK | | 6M | 167K | 1 | 6M | 7.93 |
| 27 | NESTED LOOPS | | 6M | 123K | 1 | 6M | |
| 28 | MAT_VIEW ACCESS STORAGE FULL | DWI_MD_CONTRACT_VERSION_MV | 6M | 123K | 1 | 6M | 7.32 |
| 29 | INDEX UNIQUE SCAN | DWR_CONTRACT_KEY_INFO_TMP_U1 | 1 | | 6M | 6M | 4.88 |
| 30 | NESTED LOOPS | | | | 1 | 609K | |
| 31 | NESTED LOOPS | | 15 | 792K | 1 | 609K | |
| 32 | NESTED LOOPS OUTER | | 15 | 792K | 1 | 609K | |
| 33 | HASH JOIN | | 15 | 792K | 1 | 609K | 0.61 |
| 34 | HASH JOIN OUTER | | 15 | 234K | 1 | 610K | 0.61 |
| 35 | HASH JOIN | | 15 | 123K | 1 | 610K | |
| 36 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CLASS | 1 | 4 | 1 | 123 | |
| 37 | INDEX RANGE SCAN | DWI_MD_CLASS_U2 | 1 | 2 | 1 | 123 | |
| 38 | MAT_VIEW ACCESS STORAGE FULL | DWI_MD_CONTRACT_VERSION_MV | 769 | 123K | 1 | 6M | 4.88 |
| 39 | VIEW | | 1 | 111K | 1 | 420K | |
| 40 | HASH UNIQUE | | 1 | 111K | 1 | 420K | 0.61 |
| 41 | NESTED LOOPS | | | | 1 | 514K | |
| 42 | NESTED LOOPS | | 1 | 111K | 1 | 4M | |
| 43 | HASH JOIN | | 1 | 111K | 1 | 4M | 1.22 |
| 44 | VIEW | | 1 | 55629 | 1 | 2M | |
| 45 | FILTER | | | | 1 | 2M | |
| 46 | SORT GROUP BY | | 1 | 55629 | 1 | 2M | 6.10 |
| 47 | NESTED LOOPS | | 1674 | 55628 | 1 | 3M | |
| 48 | TABLE ACCESS STORAGE FULL | DWI_MD_CONTRACT_PU | 1674 | 55628 | 1 | 3M | |
| 49 | INDEX UNIQUE SCAN | DWR_CONTRACT_KEY_INFO_TMP_U1 | 1 | | 3M | 3M | |
| 50 | TABLE ACCESS STORAGE FULL | DWI_MD_CONTRACT_PU | 10042 | 55628 | 1 | 7M | |
| 51 | INDEX UNIQUE SCAN | DWI_MD_CLASS_U1 | 1 | | 4M | 4M | 1.83 |
| 52 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CLASS | 1 | 1 | 4M | 514K | 1.22 |
| 53 | TABLE ACCESS STORAGE FULL | DWI_MD_CONTRACT | 1220 | 558K | 1 | 873K | |
| 54 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CONTRACT_SPLIT_STATUS | 1 | 3 | 609K | 0 | 4.27 |
| 55 | INDEX RANGE SCAN | MD_CONTRACT_SPLIT_STATUS_U1 | 1 | 2 | 609K | 628K | 0.61 |
| 56 | INDEX UNIQUE SCAN | DWI_MD_CONTRACT_EXE_ATTR_U1 | 1 | 1 | 614K | 609K | 1.22 |
| 57 | TABLE ACCESS BY INDEX ROWID | DWI_MD_CONTRACT_EXE_ATTR | 1 | 2 | 635K | 609K | 1.83 |
==============================================================================================================================
如果能启用并行,则效果更佳。
表DWI_MD_CONTRACT上的索引,已经导致很多程序出现性能问题,请讨论一下该索引存在的必要性。
如果一定要保留,可否Invisible?如果不能Invisible,则必须要在有性能问题的SQL上加入Full提示。
具体到这个SQL,从11月版本上线,随着表DWI_MD_CONTRACT数据不断增加,性能问题日益明显。
早在12月下旬时,耗时就已经超过2小时了。
解决方案:
加Full提示,强制表DWI_MD_CONTRACT走全表扫描。或者Invisible表DWI_MD_CONTRACT上的索引。
2.3.2 DS的Update语句没有走索引
问题描述:
环境:生产环境
程序:DWETL的Update语句
时间:2013-11-19
监控发现,好些DWETL调度的Update语句,有很明显的性能问题。
下面两个SQL在生产环境跑了好几个小时了。这些Update在目标表条件字段上没有索引,如果更新次数多的话, 会消耗大量IO资源。
UPDATE DWILTC.DWI_PO_LINE_CACULATION_ALL SET DEL_FLAG='Y',LAST_UPD_CYCLE_ID=20131116000000,LAST_MODIFIED_DATE=SYSDATE WHERE PO_CALCULATION_ID=:PO_CALCULATION_ID
AND DEL_FLAG='N';
UPDATE DWI_INV_SERIES_SPU_ITEM_DETAIL
SET OVS_PACK_ID = :OVS_PACK_ID,
MBOX_NO = :MBOX_NO,
ITEM_ID = :ITEM_ID,
MEASURE_UNIT = :MEASURE_UNIT,
SUM_QTY = :SUM_QTY,
MANAGING_ORG_ID = :MANAGING_ORG_ID,
PACKED_LINE_ID = :PACKED_LINE_ID,
SERIES_NUM = :SERIES_NUM,
ITEM_EDITION = :ITEM_EDITION,
CREATE_OP_ID = :CREATE_OP_ID,
CREATE_DATE = :CREATE_DATE,
LAST_UPDATED_BY_OP_ID = :LAST_UPDATED_BY_OP_ID,
SS_ID = :SS_ID,
DEL_FLAG = :DEL_FLAG,
DQ_IMPROVE_FLAG = :DQ_IMPROVE_FLAG,
LAST_UPDATE_DATE = :LAST_UPDATE_DATE,
DW_LAST_UPDATE_DATE = :DW_LAST_UPDATE_DATE,
LAST_UPD_CYCLE_ID = :LAST_UPD_CYCLE_ID,
UPD_JOB_INSTANCE_ID = :UPD_JOB_INSTANCE_ID
WHERE DWI_INV_SERIES_SPU_ITEM_DETAIL.SPU_NUM = :SPU_NUM
AND DWI_INV_SERIES_SPU_ITEM_DETAIL.ITEM_BARCODE =
:ITEM_BARCODE RETURNING COUNT(ROWID) INTO :22
问题分析:
就sql_id=c7m4h75w502k9来说,执行了11146次,超过7个小时,仅仅更新了11157条记录。
因为没有索引,所以每次都是全表扫描,一共读取的字节数多达81TB。
而整个生产环境才90 T左右的有效数据(去掉TEMP、Undo等),也就是说,这个SQL,差不多将整个生产环境的数据读了一遍。而这样的SQL,几乎每天都有发现,昨天发现的ga58y78ssfwd5,也是更新同样的表,执行了超过14个小时,读取数据超过76T。
执行计划如下:
SQL Monitoring Report
SQL Text
------------------------------
UPDATE DWILTC.DWI_PO_LINE_CACULATION_ALL SET DEL_FLAG='Y',LAST_UPD_CYCLE_ID=20131118000000,LAST_MODIFIED_DATE=SYSDATE WHERE PO_CALCULATION_ID=:PO_CALCULATION_ID AND DEL_FLAG='N'
Global Information
------------------------------
Status : DONE
Instance ID : 4
Session : DWETL (31662:65217)
SQL ID : c7m4h75w502k9
SQL Execution ID : 67108864
Execution Started : 11/19/2013 01:34:47
First Refresh Time : 11/19/2013 01:34:51
Last Refresh Time : 11/19/2013 09:02:46
Duration : 26879s
Module/Action : osh@szxete25-bi (TNS V1-V3)/-
Service : etl
Program : osh@szxete25-bi (TNS V1-V3)
Binds
================================================================================
| Name | Position | Type | Value |
================================================================================
| :PO_CALCULATION_ID | 1 | VARCHAR2(2000) | 1411720701 |
================================================================================
Global Stats
====================================================================================================================
| Elapsed | Cpu | IO | Application | Concurrency | Cluster | Other | Buffer | Read | Read | Cell |
| Time(s) | Time(s) | Waits(s) | Waits(s) | Waits(s) | Waits(s) | Waits(s) | Gets | Reqs | Bytes | Offload |
====================================================================================================================
| 26878 | 22595 | 4036 | 80 | 1.55 | 3.48 | 162 | 7G | 266M | 81TB | 83.22% |
====================================================================================================================
SQL Plan Monitoring Details (Plan Hash Value=107578415)
================================================================================================================
| Id | Operation | Name | Rows | Cost | Execs | Rows |Activity |
| | | | (Estim) | | | (Actual) | (%) |
================================================================================================================
| 0 | UPDATE STATEMENT | | | | 11146 | | |
| 1 | UPDATE | DWI_PO_LINE_CACULATION_ALL | | | 11146 | 0 | 0.04 |
| 2 | TABLE ACCESS STORAGE FULL | DWI_PO_LINE_CACULATION_ALL | 1 | 185K | 11146 | 11157 | 99.96 |
================================================================================================================
解决办法相当简单,就是给表DWI_PO_LINE_CACULATION_ALL创建一个基于字段PO_CALCULATION_ID的索引。
这里要解释一下,为什么Onepass调度的事实表建议少用索引,而DS调度的标却建议使用索引。
对于Onepass调度过程中使用的事实表、中间表,包括部分维表,建议尽量少用索引,因为:
- Exadata平台有Smart Scan特性,在大数据量处理时,全表扫描会比走索引更快。
- 索引维护对装载数据的性能影响很大,会极大地降低并行插入的性能。
但是,DS 程序不一样,大部分通过DS程序更新数据的表,往往需要添加索引。这是因为:
- 通过DS更新数据时,一般每次仅更新极少数据量,但是运行次数却很多。这时,走索引会比走全表扫描更快。
- DS程序基本不存在并行插入,索引维护的代价对插入和更新的性能影响很小。
解决方案:
通过DS程序更新数据的表,如果每次仅更新少量数据,但是运行次数多,一定要添加索引。
2.4 PX SEND HASH & PX SEND BROADCAST
2.4.1 中间结果集估计值太小导致PX SEND BROADCAST大数据量
问题描述:
环境:生产环境
程序:DWR_AP_SLA_STD_REP_ITEM_F_PKG.DWR_AP_SLA_STD_REP_ITEM_F_P
时间:2013-12-02
DWR_AP_SLA_STD_REP_ITEM_F_PKG.DWR_AP_SLA_STD_REP_ITEM_F_P执行计划不对,运行时间偏长。
问题分析:
SQL语句如下(SQL_ID=1rmjgwcqsdhtx):
INSERT /*+ APPEND PARALLEL(8)*/
INTO DWR_AP_SLA_STAND_REPORT_ITEM_F
(SUB_LEDGER_ID,
SOURCE_APPLICATION_ID,
REF_AE_HEADER_ID,
TEMP_LINE_NO,
SPLIT_ALLOCATE_ID,
BID_ATTRIBUTION_TYPE_ID,
REPORT_ITEM_ID,
SET_OF_BOOKS_ID,
UNIQUE_INDEX_NUM,
SUB_LEDGER_ENTRY_ID,
SUB_MODULE_ENTRY_ID,
UCCID,
DATA_SOURCE_TABLE_ID,
DESCRIPTION,
PERIOD_ID,
ERP_PERIOD_ID,
POST_DATE,
JE_CATEGORY_ID,
JE_SOURCE_ID,
DATA_CATEGORY_ID,
SOB_CLASS_FLAG,
COA_COMPANY_KEY,
COA_IC_KEY,
ADJUST_IC_KEY,
COA_BU_KEY,
COA_DEPT_KEY,
COA_GEO_PC_KEY,
COA_PROD_KEY,
COMPANY_ACCOUNT_CODE,
GROUP_ACCOUNT_CODE,
SUB_ACCOUNT_CODE,
BU_KEY,
PO_ID,
PO_NUM,
PO_LINE_ID,
PO_DISTRIBUTION_ID,
RESP_GEO_PC_KEY,
BENEFIT_GEO_PC_KEY,
AP_INVOICE_ID,
AP_INVOICE_NUM,
AP_INVOICE_TYPE_ID,
AP_INVOICE_DISTR_LINE_ID,
AP_INVOICE_DISTR_LINE_TYPE_ID,
PAYMENT_CHECK_ID,
PAYMENT_ORDER_NUM,
PAYMENT_RECORD_ID,
PROJ_KEY,
CONTRACT_KEY,
CONTRACT_ID,
PURCHASE_BUSINESS_TYPE_ID,
BEGIN_DATE,
CREATE_DATE,
CHECK_DATE,
OVERDUE_DATE,
PAYMENT_DATE,
FAR_DUE_DATE,
ACTUAL_PAYMENT_DATE,
PAYMENT_GROUP_ID,
ITEM_KEY,
ITEM_ID,
ITEM_CATEGORY_KEY,
BUY_SELL_TYPE_ID,
PAYMENT_TERM_TYPE_ID,
PAYMENT_TYPE_ID,
SUPPLIER_KEY,
INV_MODE,
WEEKLY_PAYMENT_FLAG,
CEG_KEY,
BACK_TO_BACK_FLAG,
IC_FLAG,
TC_CODE,
LC_CODE,
TC_DR_AMT,
TC_CR_AMT,
LC_DR_AMT,
LC_CR_AMT,
RMB_FACT_EX_RATE_DR_AMT,
RMB_FACT_EX_RATE_CR_AMT,
RMB_BUDGET_EX_RATE_DR_AMT,
RMB_BUDGET_EX_RATE_CR_AMT,
USD_FACT_EX_RATE_DR_AMT,
USD_FACT_EX_RATE_CR_AMT,
USD_BUDGET_EX_RATE_DR_AMT,
USD_BUDGET_EX_RATE_CR_AMT,
PAYMENT_ACCOUNT_CODE,
JOURNAL_ENTRY_LINE_TYPE_ID,
ACCOUNT_CLASS_ID,
RMB_FACT_PAY_TERMS_MUL_PTD,
RMB_FACT_PUR_TERMS_MUL_PTD,
RMB_FACT_AHEAD_PAY_MUL_PTD,
RMB_FACT_DELAY_PAY_MUL_PTD,
RMB_FACT_WEEKLY_PAY_MUL_PTD,
RMB_FACT_COD_DELAY_PAY_MUL_PTD,
RMB_FACT_ACCT_DLY_PAY_MUL_PTD,
RMB_FACT_OTHR_DLY_PAY_MUL_PTD,
RMB_FACT_PROJECT_TERMS_MUL_PTD,
RMB_FACT_ADMIN_TERMS_MUL_PTD,
RMB_FACT_PRODUCE_TERMS_MUL_PTD,
RMB_FACT_NON_AGT_TERMS_MUL_PTD,
RMB_FACT_AGT_TERMS_MUL_PTD,
RMB_FACT_BILL_TERMS_MUL_PTD,
RMB_FACT_PURCHASE_CONTRACT_PTD,
BEFORE_ACCEPTANCE_PAYMENT_RATE,
BEFORE_ACCEPT_PAYMENT_MUL_PTD,
CRT_CYCLE_ID,
LAST_UPD_CYCLE_ID,
CRT_JOB_INSTANCE_ID,
UPD_JOB_INSTANCE_ID,
DEL_FLAG,
APT_ACCOUNTING_FLAG,
RMB_FACT_KPI_ADJ_TERMS_MUL_PTD,
SUPPLIER_SITE_ID,
TRACE_ACCOUNT_CODE,
DW_LAST_UPDATE_DATE,
INVOICE_RECEIPT_CREATOR,
VERSION_ID,
BILL_TYPE_ID,
PAYMENT_FLAG,
BILL_FLAG)
SELECT /*+ PARALLEL(8)*/
APV.SUB_LEDGER_ID,
APV.SOURCE_APPLICATION_ID,
APV.REF_AE_HEADER_ID,
APV.TEMP_LINE_NO,
APV.SPLIT_ALLOCATE_ID,
APV.BID_ATTRIBUTION_TYPE_ID,
APV.REPORT_ITEM_ID,
APV.SET_OF_BOOKS_ID,
APV.UNIQUE_INDEX_NUM,
APV.SUB_LEDGER_ENTRY_ID,
APV.SUB_MODULE_ENTRY_ID,
APV.UCCID,
APV.DATA_SOURCE_TABLE_ID,
APV.DESCRIPTION,
APV.PERIOD_ID,
APV.ERP_PERIOD_ID,
APV.POST_DATE,
APV.JE_CATEGORY_ID,
APV.JE_SOURCE_ID,
APV.DATA_CATEGORY_ID,
APV.SOB_CLASS_FLAG,
APV.COA_COMPANY_KEY,
APV.COA_IC_KEY,
APV.ADJUST_IC_KEY,
APV.COA_BU_KEY,
APV.COA_DEPT_KEY,
APV.COA_GEO_PC_KEY,
APV.COA_PROD_KEY,
APV.COMPANY_ACCOUNT_CODE,
APV.GROUP_ACCOUNT_CODE,
APV.SUB_ACCOUNT_CODE,
APV.BU_KEY,
APV.PO_ID,
APV.PO_NUM,
APV.PO_LINE_ID,
APV.PO_DISTRIBUTION_ID,
APV.RESP_GEO_PC_KEY,
APV.BENEFIT_GEO_PC_KEY,
APV.AP_INVOICE_ID,
APV.AP_INVOICE_NUM,
APV.AP_INVOICE_TYPE_ID,
APV.AP_INVOICE_DISTR_LINE_ID,
APV.AP_INVOICE_DISTR_LINE_TYPE_ID,
APV.PAYMENT_CHECK_ID,
APV.PAYMENT_ORDER_NUM,
APV.PAYMENT_RECORD_ID,
APV.PROJ_KEY,
APV.CONTRACT_KEY,
APV.CONTRACT_ID,
APV.PURCHASE_BUSINESS_TYPE_ID,
APV.BEGIN_DATE,
APV.CREATE_DATE,
APV.CHECK_DATE,
APV.OVERDUE_DATE,
APV.PAYMENT_DATE,
APV.FAR_DUE_DATE,
APV.ACTUAL_PAYMENT_DATE,
APV.PAYMENT_GROUP_ID,
APV.ITEM_KEY,
APV.ITEM_ID,
APV.ITEM_CATEGORY_KEY,
APV.BUY_SELL_TYPE_ID,
APV.PAYMENT_TERM_TYPE_ID,
APV.PAYMENT_TYPE_ID,
APV.SUPPLIER_KEY,
APV.INV_MODE,
APV.WEEKLY_PAYMENT_FLAG,
APV.CEG_KEY,
NVL(NVL(BB.BACK_TO_BACK_FLAG, BB1.BACK_TO_BACK_FLAG), 'N') BACK_TO_BACK_FLAG,
APV.IC_FLAG,
APV.TC_CODE,
APV.LC_CODE,
APV.TC_DR_AMT,
APV.TC_CR_AMT,
APV.LC_DR_AMT,
APV.LC_CR_AMT,
APV.RMB_FACT_EX_RATE_DR_AMT,
APV.RMB_FACT_EX_RATE_CR_AMT,
APV.RMB_BUDGET_EX_RATE_DR_AMT,
APV.RMB_BUDGET_EX_RATE_CR_AMT,
APV.USD_FACT_EX_RATE_DR_AMT,
APV.USD_FACT_EX_RATE_CR_AMT,
APV.USD_BUDGET_EX_RATE_DR_AMT,
APV.USD_BUDGET_EX_RATE_CR_AMT,
APV.PAYMENT_ACCOUNT_CODE,
APV.JOURNAL_ENTRY_LINE_TYPE_ID,
APV.ACCOUNT_CLASS_ID,
APV.RMB_FACT_PAY_TERMS_MUL_PTD,
APV.RMB_FACT_PUR_TERMS_MUL_PTD,
APV.RMB_FACT_AHEAD_PAY_MUL_PTD,
APV.RMB_FACT_DELAY_PAY_MUL_PTD,
APV.RMB_FACT_WEEKLY_PAY_MUL_PTD,
APV.RMB_FACT_COD_DELAY_PAY_MUL_PTD,
APV.RMB_FACT_AHEAD_PAY_MUL_PTD AS RMB_FACT_ACCT_DLY_PAY_MUL_PTD,
(APV.RMB_FACT_PAY_TERMS_MUL_PTD - APV.RMB_FACT_PUR_TERMS_MUL_PTD -
APV.RMB_FACT_PUR_TERMS_MUL_PTD - APV.RMB_FACT_AHEAD_PAY_MUL_PTD -
APV.RMB_FACT_DELAY_PAY_MUL_PTD - APV.RMB_FACT_WEEKLY_PAY_MUL_PTD -
APV.RMB_FACT_COD_DELAY_PAY_MUL_PTD - APV.RMB_FACT_AHEAD_PAY_MUL_PTD) AS RMB_FACT_OTHR_DLY_PAY_MUL_PTD,
APV.RMB_FACT_PAY_TERMS_MUL_PTD AS RMB_FACT_PROJECT_TERMS_MUL_PTD,
APV.RMB_FACT_PAY_TERMS_MUL_PTD AS RMB_FACT_ADMIN_TERMS_MUL_PTD,
APV.RMB_FACT_PAY_TERMS_MUL_PTD AS RMB_FACT_PRODUCE_TERMS_MUL_PTD,
APV.RMB_FACT_PUR_TERMS_MUL_PTD AS RMB_FACT_NON_AGT_TERMS_MUL_PTD,
APV.RMB_FACT_PUR_TERMS_MUL_PTD AS RMB_FACT_AGT_TERMS_MUL_PTD,
APV.RMB_FACT_BILL_TERMS_MUL_PTD,
APV.RMB_FACT_PURCHASE_CONTRACT_PTD,
APV.BEFORE_ACCEPTANCE_PAYMENT_RATE,
(NVL(APV.RMB_FACT_EX_RATE_DR_AMT, 0) -
NVL(APV.RMB_FACT_EX_RATE_CR_AMT, 0)) *
APV.BEFORE_ACCEPTANCE_PAYMENT_RATE AS BEFORE_ACCEPT_PAYMENT_MUL_PTD,
:B4,
:B4,
:B3,
:B3,
APV.DEL_FLAG,
APV.APT_ACCOUNTING_FLAG,
APV.RMB_FACT_KPI_ADJ_TERMS_MUL_PTD,
APV.SUPPLIER_SITE_ID,
APV.TRACE_ACCOUNT_CODE,
SYSDATE AS DW_LAST_UPDATE_DATE,
APV.INVOICE_RECEIPT_CREATOR,
APV.VERSION_ID,
APV.BILL_TYPE_ID,
APV.PAYMENT_FLAG,
APV.BILL_FLAG
FROM (SELECT /*+ PARALLEL(8)*/
AP.SUB_LEDGER_ID,
AP.SOURCE_APPLICATION_ID,
AP.REF_AE_HEADER_ID,
AP.TEMP_LINE_NO,
AP.SUB_LEDGER_ENTRY_ID,
AP.SUB_MODULE_ENTRY_ID,
AP.UCCID,
AP.DATA_SOURCE_TABLE_ID,
AP.DESCRIPTION,
BIF.PERIOD_ID,
AP.ERP_PERIOD_ID,
AP.POST_DATE,
AP.JE_CATEGORY_ID,
AP.JE_SOURCE_ID,
AP.DATA_CATEGORY_ID,
AP.SET_OF_BOOKS_ID,
AP.SOB_CLASS_FLAG,
AP.COA_COMPANY_KEY,
AP.COA_IC_KEY,
AP.ADJUST_IC_KEY,
AP.COA_BU_KEY,
AP.COA_DEPT_KEY,
AP.COA_GEO_PC_KEY,
AP.COA_PROD_KEY,
AP.GROUP_ACCOUNT_CODE,
AP.COMPANY_ACCOUNT_CODE,
AP.SUB_ACCOUNT_CODE,
AP.BU_KEY,
AP.PO_ID,
AP.PO_NUM,
AP.PO_LINE_ID,
AP.PO_DISTRIBUTION_ID,
AP.RESP_GEO_PC_KEY,
AP.BENEFIT_GEO_PC_KEY,
AP.AP_INVOICE_ID,
AP.AP_INVOICE_NUM,
AP.AP_INVOICE_TYPE_ID,
AP.AP_INVOICE_DISTR_LINE_ID,
AP.PAYMENT_CHECK_ID,
AP.PAYMENT_ORDER_NUM,
AP.PAYMENT_RECORD_ID,
AP.PROJ_KEY,
AP.CONTRACT_KEY,
AP.CONTRACT_ID,
AP.PURCHASE_BUSINESS_TYPE_ID,
AP.BEGIN_DATE,
AP.CREATE_DATE,
AP.CHECK_DATE,
AP.OVERDUE_DATE,
AP.PAYMENT_DATE,
AP.FAR_DUE_DATE,
AP.ACTUAL_PAYMENT_DATE,
AP.PAYMENT_GROUP_ID,
AP.ITEM_KEY,
AP.ITEM_ID,
AP.SUPPLIER_KEY,
AP.TC_CODE,
AP.LC_CODE,
AP.TC_DR_AMT,
AP.TC_CR_AMT,
AP.LC_DR_AMT,
AP.LC_CR_AMT,
AP.RMB_FACT_EX_RATE_DR_AMT,
AP.RMB_FACT_EX_RATE_CR_AMT,
AP.ITEM_CATEGORY_KEY,
AP.BUY_SELL_TYPE_ID,
AP.PAYMENT_TERM_TYPE_ID,
AP.PAYMENT_TYPE_ID,
AP.PAYMENT_ACCOUNT_CODE,
AP.INV_MODE,
AP.WEEKLY_PAYMENT_FLAG,
AP.RMB_BUDGET_EX_RATE_DR_AMT,
AP.RMB_BUDGET_EX_RATE_CR_AMT,
AP.USD_FACT_EX_RATE_DR_AMT,
AP.USD_FACT_EX_RATE_CR_AMT,
AP.USD_BUDGET_EX_RATE_DR_AMT,
AP.USD_BUDGET_EX_RATE_CR_AMT,
AP.CEG_KEY,
AP.IC_FLAG,
BIF.REPORT_ITEM_ID,
DC.COMPANY_ID,
DS.SUPPLIER_ID,
AP.SPLIT_ALLOCATE_ID,
AP.JOURNAL_ENTRY_LINE_TYPE_ID,
AP.ACCOUNT_CLASS_ID,
AP.AP_INVOICE_DISTR_LINE_TYPE_ID,
(NVL(AP.RMB_FACT_EX_RATE_DR_AMT, 0) -
NVL(AP.RMB_FACT_EX_RATE_CR_AMT, 0)) *
NVL((TRUNC(AP.ACTUAL_PAYMENT_DATE) - TRUNC(AP.BEGIN_DATE)), 0) AS RMB_FACT_PAY_TERMS_MUL_PTD,
(NVL(AP.RMB_FACT_EX_RATE_DR_AMT, 0) -
NVL(AP.RMB_FACT_EX_RATE_CR_AMT, 0)) *
NVL((TRUNC(AP.OVERDUE_DATE) - TRUNC(AP.BEGIN_DATE)), 0) AS RMB_FACT_PUR_TERMS_MUL_PTD,
(NVL(AP.RMB_FACT_EX_RATE_DR_AMT, 0) -
NVL(AP.RMB_FACT_EX_RATE_CR_AMT, 0)) *
NVL((TRUNC(AP.ACTUAL_PAYMENT_DATE) - TRUNC(AP.OVERDUE_DATE)), 0) AS RMB_FACT_AHEAD_PAY_MUL_PTD,
(NVL(AP.RMB_FACT_EX_RATE_DR_AMT, 0) -
NVL(AP.RMB_FACT_EX_RATE_CR_AMT, 0)) *
NVL((TRUNC(AP.CHECK_DATE) - TRUNC(AP.OVERDUE_DATE)), 0) AS RMB_FACT_DELAY_PAY_MUL_PTD,
(CASE
WHEN TRUNC(AP.CREATE_DATE) > TRUNC(AP.OVERDUE_DATE) THEN
(NVL(AP.RMB_FACT_EX_RATE_DR_AMT, 0) -
NVL(AP.RMB_FACT_EX_RATE_CR_AMT, 0)) *
NVL((TRUNC(AP.ACTUAL_PAYMENT_DATE) - TRUNC(AP.CHECK_DATE)), 0)
ELSE
(NVL(AP.RMB_FACT_EX_RATE_DR_AMT, 0) -
NVL(AP.RMB_FACT_EX_RATE_CR_AMT, 0)) *
NVL((TRUNC(AP.ACTUAL_PAYMENT_DATE) - TRUNC(AP.OVERDUE_DATE)), 0)
END) AS RMB_FACT_WEEKLY_PAY_MUL_PTD,
(NVL(AP.RMB_FACT_EX_RATE_DR_AMT, 0) -
NVL(AP.RMB_FACT_EX_RATE_CR_AMT, 0)) *
(NVL((TRUNC(AP.ACTUAL_PAYMENT_DATE) - TRUNC(AP.CREATE_DATE)), 0) + 5) AS RMB_FACT_COD_DELAY_PAY_MUL_PTD,
(NVL(AP.RMB_FACT_EX_RATE_DR_AMT, 0) -
NVL(AP.RMB_FACT_EX_RATE_CR_AMT, 0)) *
NVL((TRUNC(AP.FAR_DUE_DATE) - TRUNC(AP.CHECK_DATE)), 0) AS RMB_FACT_BILL_TERMS_MUL_PTD,
(CASE
WHEN UPPER(PTT.PAYMENT_TERM_TYPE_CODE) NOT IN
('COD', 'IMMEDIATE') OR
(UPPER(PTT.PAYMENT_TERM_TYPE_CODE) IN ('COD', 'IMMEDIATE') AND
(AP.LC_DR_AMT - AP.LC_CR_AMT) < 0) THEN
(AP.RMB_FACT_EX_RATE_DR_AMT - AP.RMB_FACT_EX_RATE_CR_AMT)
ELSE
0
END) AS RMB_FACT_PURCHASE_CONTRACT_PTD,
NVL(PTT.BEFORE_ACCEPTANCE_PAYMENT_RATE, 0) AS BEFORE_ACCEPTANCE_PAYMENT_RATE,
AP.UNIQUE_INDEX_NUM,
AP.DEL_FLAG,
AP.BID_ATTRIBUTION_TYPE_ID,
AP.APT_ACCOUNTING_FLAG,
16 * (AP.RMB_FACT_EX_RATE_DR_AMT - AP.RMB_FACT_EX_RATE_CR_AMT) AS RMB_FACT_KPI_ADJ_TERMS_MUL_PTD,
AP.SUPPLIER_SITE_ID,
AP.TRACE_ACCOUNT_CODE,
AP.INVOICE_RECEIPT_CREATOR,
'R00' AS VERSION_ID,
AP.BILL_TYPE_ID,
AP.PAYMENT_FLAG,
AP.BILL_FLAG
FROM DWR_AP_SLA_DETAIL_F AP,
BIF_RPT_ITEM_AP_DET_STD_T BIF,
DWR_DIM_COMPANY_D DC,
DWR_DIM_SUPPLIER_D DS,
DWR_DIM_PAYMENT_TERM_TYPE_L PTT
WHERE AP.PERIOD_ID = BIF.PERIOD_ID
AND AP.UNIQUE_INDEX_NUM = BIF.FACT_KEY_ID
AND AP.JOURNAL_ENTRY_LINE_TYPE_ID IN (22, 23)
AND AP.COA_COMPANY_KEY = DC.COMPANY_KEY
AND AP.SUPPLIER_KEY = DS.SUPPLIER_KEY
AND AP.PAYMENT_TERM_TYPE_ID = PTT.PAYMENT_TERM_TYPE_ID(+)
AND AP.PERIOD_ID = :B2
AND BIF.PERIOD_ID = :B2) APV,
(SELECT BTB.COMPANY_ID,
BTB.SUPPLIER_ID,
BTB.BEGIN_ACCOUNT_PERIOD_ID,
BTB.END_ACCOUNT_PERIOD_ID,
BTB.CONTRACT_ID,
BTB.BACK_TO_BACK_FLAG,
ROW_NUMBER() OVER(PARTITION BY BTB.COMPANY_ID, BTB.SUPPLIER_ID, BTB.CONTRACT_ID ORDER BY BTB.COMPANY_ID) AS ROW_NUM
FROM DWI_MD_AP_BACK_TO_BACK_REL BTB
WHERE :B2 >= BTB.BEGIN_ACCOUNT_PERIOD_ID
AND :B2 <= NVL(BTB.END_ACCOUNT_PERIOD_ID, 471212)
AND BTB.COMPANY_ID <> :B1) BB,
(SELECT BTB1.COMPANY_ID,
BTB1.SUPPLIER_ID,
BTB1.BEGIN_ACCOUNT_PERIOD_ID,
BTB1.END_ACCOUNT_PERIOD_ID,
BTB1.CONTRACT_ID,
BTB1.BACK_TO_BACK_FLAG,
ROW_NUMBER() OVER(PARTITION BY BTB1.COMPANY_ID, BTB1.SUPPLIER_ID ORDER BY BTB1.COMPANY_ID) AS ROW_NUM
FROM DWI_MD_AP_BACK_TO_BACK_REL BTB1
WHERE :B2 >= BTB1.BEGIN_ACCOUNT_PERIOD_ID
AND :B2 <= NVL(BTB1.END_ACCOUNT_PERIOD_ID, 471212)
AND BTB1.CONTRACT_ID = :B1) BB1
WHERE APV.COMPANY_ID = BB.COMPANY_ID(+)
AND APV.SUPPLIER_ID = BB.SUPPLIER_ID(+)
AND APV.CONTRACT_ID = BB.CONTRACT_ID(+)
AND BB.ROW_NUM(+) = 1
AND APV.COMPANY_ID = BB1.COMPANY_ID(+)
AND APV.SUPPLIER_ID = BB1.SUPPLIER_ID(+)
AND BB1.ROW_NUM(+) = 1
执行计划如下:
SQL Plan Monitoring Details (Plan Hash Value=235362529)
================================================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | | (Estim) | | | (Actual) | (%) |
================================================================================================================================================
| 0 | INSERT STATEMENT | | | | 17 | 2 | 0.08 |
| 1 | PX COORDINATOR | | | | 17 | 2 | 0.02 |
| 2 | PX SEND QC (RANDOM) | :TQ10016 | 1 | 40864 | 8 | 2 | |
| 3 | INDEX MAINTENANCE | DWR_AP_SLA_STAND_REPORT_ITEM_F | | | 8 | 2 | |
| 4 | PX RECEIVE | | 1 | 40864 | 8 | 2 | |
| 5 | PX SEND RANGE | :TQ10015 | 1 | 40864 | 8 | 2 | |
| 6 | LOAD AS SELECT | | | | 8 | 10 | 8.78 |
| 7 | PX RECEIVE | | 1 | 40864 | 8 | 26M | 0.96 |
| 8 | PX SEND PARTITION (KEY) | :TQ10014 | 1 | 40864 | 8 | 26M | 1.81 |
| 9 | HASH JOIN OUTER BUFFERED | | 1 | 40864 | 8 | 26M | 3.99 |
| 10 | PX RECEIVE | | 1 | 40860 | 8 | 26M | 0.71 |
| 11 | PX SEND HASH | :TQ10012 | 1 | 40860 | 8 | 26M | 0.90 |
| 12 | HASH JOIN OUTER BUFFERED | | 1 | 40860 | 8 | 26M | 5.43 |
| 13 | PX RECEIVE | | 1 | 40856 | 8 | 26M | 0.61 |
| 14 | PX SEND HASH | :TQ10009 | 1 | 40856 | 8 | 26M | 1.12 |
| 15 | VIEW | | 1 | 40856 | 8 | 26M | 4.09 |
| 16 | FILTER | | | | 8 | 26M | 0.02 |
| 17 | HASH JOIN BUFFERED | | 1 | 40856 | 8 | 26M | 4.44 |
| 18 | PX RECEIVE | | 1 | 39256 | 8 | 26M | 0.50 |
| 19 | PX SEND HASH | :TQ10006 | 1 | 39256 | 8 | 26M | 0.88 |
| 20 | HASH JOIN OUTER BUFFERED | | 1 | 39256 | 8 | 26M | 5.14 |
| 21 | PX RECEIVE | | 1 | 39056 | 8 | 26M | 0.58 |
| 22 | PX SEND HASH | :TQ10004 | 1 | 39056 | 8 | 26M | 1.20 |
| 23 | HASH JOIN | | 1 | 39056 | 8 | 26M | 46.22 |
| 24 | PX RECEIVE | | 1 | 39046 | 8 | 207M | 4.30 |
| 25 | PX SEND BROADCAST | :TQ10002 | 1 | 39046 | 8 | 207M | 5.49 |
| 26 | HASH JOIN BUFFERED | | 1 | 39046 | 8 | 26M | 1.64 |
| 27 | PX RECEIVE | | 11M | 3100 | 8 | 26M | 0.02 |
| 28 | PX SEND HASH | :TQ10000 | 11M | 3100 | 8 | 26M | 0.05 |
| 29 | PX BLOCK ITERATOR | | 11M | 3100 | 8 | 26M | |
| 30 | TABLE ACCESS STORAGE FULL | BIF_RPT_ITEM_AP_DET_STD_T | 11M | 3100 | 187 | 26M | 0.11 |
| 31 | PX RECEIVE | | 11M | 35936 | 8 | 11M | 0.20 |
| 32 | PX SEND HASH | :TQ10001 | 11M | 35936 | 8 | 11M | 0.42 |
| 33 | PX BLOCK ITERATOR | | 11M | 35936 | 8 | 11M | |
| 34 | TABLE ACCESS STORAGE FULL | DWR_AP_SLA_DETAIL_F | 11M | 35936 | 115 | 11M | 0.19 |
| 35 | PX BLOCK ITERATOR | | 2106 | 10 | 8 | 2110 | |
| 36 | TABLE ACCESS STORAGE FULL | DWR_DIM_COMPANY_D | 2106 | 10 | 167 | 2110 | |
| 37 | PX RECEIVE | | 61411 | 199 | 8 | 63657 | |
| 38 | PX SEND HASH | :TQ10005 | 61411 | 199 | 8 | 63657 | |
| 39 | VIEW | DWR_DIM_PAYMENT_TERM_TYPE_L | 61411 | 199 | 8 | 63657 | |
| 40 | HASH JOIN RIGHT OUTER | | 61411 | 199 | 8 | 63657 | |
| 41 | PX RECEIVE | | 88 | 2 | 8 | 10744 | |
| 42 | PX SEND BROADCAST | :TQ10003 | 88 | 2 | 8 | 10744 | |
| 43 | PX BLOCK ITERATOR | | 88 | 2 | 8 | 1343 | |
| 44 | TABLE ACCESS STORAGE FULL | DWI_PAYMENT_TERMS_LINES | 88 | 2 | 13 | 1343 | |
| 45 | PX BLOCK ITERATOR | | 61411 | 197 | 8 | 63657 | |
| 46 | TABLE ACCESS STORAGE FULL | DWI_MD_CLASS | 61411 | 197 | 104 | 63657 | |
| 47 | PX RECEIVE | | 1M | 1599 | 8 | 1M | |
| 48 | PX SEND HASH | :TQ10007 | 1M | 1599 | 8 | 1M | |
| 49 | PX BLOCK ITERATOR | | 1M | 1599 | 8 | 1M | |
| 50 | TABLE ACCESS STORAGE FULL | DWR_DIM_SUPPLIER_D | 1M | 1599 | 107 | 1M | 0.11 |
| 51 | PX RECEIVE | | 87 | 3 | 8 | 87 | |
| 52 | PX SEND HASH | :TQ10010 | 87 | 3 | 8 | 87 | |
| 53 | VIEW | | 87 | 3 | 8 | 87 | |
| 54 | WINDOW SORT PUSHED RANK | | 87 | 3 | 8 | 87 | |
| 55 | PX RECEIVE | | 87 | 3 | 8 | 87 | |
| 56 | PX SEND HASH | :TQ10008 | 87 | 3 | 8 | 87 | |
| 57 | WINDOW CHILD PUSHED RANK | | 87 | 3 | 8 | 87 | |
| 58 | PX BLOCK ITERATOR | | 87 | 2 | 8 | 87 | |
| 59 | TABLE ACCESS STORAGE FULL | DWI_MD_AP_BACK_TO_BACK_REL | 87 | 2 | 9 | 87 | |
| 60 | PX RECEIVE | | 89 | 3 | 8 | 89 | |
| 61 | PX SEND HASH | :TQ10013 | 89 | 3 | 8 | 89 | |
| 62 | VIEW | | 89 | 3 | 8 | 89 | |
| 63 | WINDOW SORT PUSHED RANK | | 89 | 3 | 8 | 89 | |
| 64 | PX RECEIVE | | 89 | 3 | 8 | 89 | |
| 65 | PX SEND HASH | :TQ10011 | 89 | 3 | 8 | 89 | |
| 66 | WINDOW CHILD PUSHED RANK | | 89 | 3 | 8 | 89 | |
| 67 | PX BLOCK ITERATOR | | 89 | 2 | 8 | 89 | |
| 68 | TABLE ACCESS STORAGE FULL | DWI_MD_AP_BACK_TO_BACK_REL | 89 | 2 | 9 | 89 | |
================================================================================================================================================
性能关键是表BIF_RPT_ITEM_AP_DET_STD_T和DWR_AP_SLA_DETAIL_F关联后,估计值变为1,导致结果集PX SEND BROADCAST。而实际上关联结果有26M,PX SEND BROADCAST后有207M,浪费很多资源。
经查,两张表的201311分区的统计信息均已失效。进一步了解到,11月29日的统计信息收集,在进行到一半之后被异常终止。
解决方案:
收集统计信息,或者加提示固定执行计划。
2.4.2 PX SEND HASH导致并行不均衡(1)
问题描述:
环境:生产环境
程序:试调度性能
时间:2013-11-25
2013-11-25进行的损益试调度,性能状况不是很好。
看了一下SQL Monitor报告,发现一个共同点,那就是虽然都启用了8个并行,但看起来只有1、2个Session在真正做事。同时查看了9月30日调度时候抓取的SQL Monitor报告,发现那时的并行情况良好,基本上都是8个Session平均在做事。
问题分析:
这里拿a7auhxhkfvcb3 为例,我们只使用后面的select语句。
对比9/30和11/25的执行计划,很明显其执行计划有很大的改变。最大的不同是11/25的使用了HASH JOIN RIGHT OUTER BUFFERED,而9/30的没有。
而且在HASH JOIN RIGHT OUTER BUFFERED处的时间消耗是非常高的。其为什么使用HASH JOIN RIGHT OUTER BUFFERED,是由于评估结果集的原因。
先看下9/30的执行计划:
现在运行其执行计划为,这里只取前面会使用outer buffered的地方。
由于只有一个salve在执行outer buffered,因此我们会看到有一个salve有大量的temp write(P047有5G,其他的只有几百M),远远高于其他slave。
在上面7,14行的结果集评估是10M/5M如果我们把其修改和9/30日评估的结果集。
其执行计划没有outer buffered
其并行slave的统计信息也均衡
从以上分析可以看出,提供的SQL都是由于执行计划改变,而导致性能发生改变,其根因是由于结果集发生变化而导致执行计划改变。
下面进一步分析结果集改变原因和对策。
这个问题的原因,主要还是合同维(DM_DIM_CON_KEY_M)和项目维(DM_DIM_PROJ_KEY_M)在11月11日变更后出现了异常增加。
还是拿a7auhxhkfvcb3 为例,从9月30日的SQL Monitor报告,可以看到合同维实际行数为2M,项目维实际行数为4M。
SQL Plan Monitoring Details (Plan Hash Value=3188624414)
==============================================================================================================================
| Id | Operation | Name | Rows | Cost |Execs | Rows |Activity |
| | | | (Estim) | | | (Actual) | (%) |
==============================================================================================================================
| 0 | INSERT STATEMENT | | | | 17 | 8 | 0.27 |
| 1 | PX COORDINATOR | | | | 17 | 8 | |
| 2 | PX SEND QC (RANDOM) | :TQ10014 | 337M | 491K | 8 | 8 | |
| 3 | LOAD AS SELECT | | | | 8 | 16 | 76.09 |
| 4 | HASH JOIN RIGHT OUTER | | 337M | 491K | 8 | 475M | 1.31 |
| 5 | PX RECEIVE | | 70886 | 7 | 8 | 567K | |
| 6 | PX SEND BROADCAST | :TQ10000 | 70886 | 7 | 8 | 567K | |
| 7 | PX BLOCK ITERATOR | | 70886 | 7 | 8 | 70886 | |
| 8 | TABLE ACCESS STORAGE FULL | DM_DIM_PROD_KEY_M | 70886 | 7 | 121 | 70886 | |
| 9 | HASH JOIN RIGHT OUTER | | 336M | 491K | 8 | 475M | 1.38 |
| 10 | PX RECEIVE | | 70886 | 7 | 8 | 567K | |
| 11 | PX SEND BROADCAST | :TQ10001 | 70886 | 7 | 8 | 567K | |
| 12 | PX BLOCK ITERATOR | | 70886 | 7 | 8 | 70886 | |
| 13 | TABLE ACCESS STORAGE FULL | DM_DIM_PROD_KEY_M | 70886 | 7 | 121 | 70886 | |
| 14 | HASH JOIN RIGHT OUTER | | 336M | 491K | 8 | 475M | 1.00 |
| 15 | PX RECEIVE | | 143 | 2 | 8 | 1144 | |
| 16 | PX SEND BROADCAST | :TQ10002 | 143 | 2 | 8 | 1144 | |
| 17 | PX BLOCK ITERATOR | | 143 | 2 | 8 | 143 | |
| 18 | TABLE ACCESS STORAGE FULL | DM_DIM_BU_KEY_M | 143 | 2 | 5 | 143 | |
| 19 | HASH JOIN RIGHT OUTER | | 336M | 491K | 8 | 475M | 0.95 |
| 20 | PX RECEIVE | | 167 | 2 | 8 | 1336 | |
| 21 | PX SEND BROADCAST | :TQ10003 | 167 | 2 | 8 | 1336 | |
| 22 | PX BLOCK ITERATOR | | 167 | 2 | 8 | 167 | |
| 23 | TABLE ACCESS STORAGE FULL | DM_DIM_REG_KEY_M | 167 | 2 | 5 | 167 | |
| 24 | HASH JOIN RIGHT OUTER | | 336M | 491K | 8 | 475M | 1.08 |
| 25 | PX RECEIVE | | 230K | 17 | 8 | 2M | |
| 26 | PX SEND BROADCAST | :TQ10004 | 230K | 17 | 8 | 2M | |
| 27 | PX BLOCK ITERATOR | | 230K | 17 | 8 | 230K | |
| 28 | TABLE ACCESS STORAGE FULL | DM_DIM_CUS_KEY_M | 230K | 17 | 114 | 230K | |
| 29 | HASH JOIN RIGHT OUTER | | 336M | 491K | 8 | 475M | 1.05 |
| 30 | PX RECEIVE | | 230K | 17 | 8 | 2M | |
| 31 | PX SEND BROADCAST | :TQ10005 | 230K | 17 | 8 | 2M | |
| 32 | PX BLOCK ITERATOR | | 230K | 17 | 8 | 230K | |
| 33 | TABLE ACCESS STORAGE FULL | DM_DIM_CUS_KEY_M | 230K | 17 | 114 | 230K | |
| 34 | HASH JOIN RIGHT OUTER | | 336M | 491K | 8 | 475M | 1.27 |
| 35 | PX RECEIVE | | 230K | 17 | 8 | 2M | 0.01 |
| 36 | PX SEND BROADCAST | :TQ10006 | 230K | 17 | 8 | 2M | 0.01 |
| 37 | PX BLOCK ITERATOR | | 230K | 17 | 8 | 230K | |
| 38 | TABLE ACCESS STORAGE FULL | DM_DIM_CUS_KEY_M | 230K | 17 | 114 | 230K | |
| 39 | HASH JOIN RIGHT OUTER | | 336M | 490K | 8 | 475M | 0.84 |
| 40 | PX RECEIVE | | 230K | 17 | 8 | 2M | |
| 41 | PX SEND BROADCAST | :TQ10007 | 230K | 17 | 8 | 2M | |
| 42 | PX BLOCK ITERATOR | | 230K | 17 | 8 | 230K | |
| 43 | TABLE ACCESS STORAGE FULL | DM_DIM_CUS_KEY_M | 230K | 17 | 114 | 230K | |
| 44 | HASH JOIN RIGHT OUTER | | 336M | 490K | 8 | 475M | 1.22 |
| 45 | PX RECEIVE | | 2M | 103 | 8 | 12M | |
| 46 | PX SEND BROADCAST | :TQ10008 | 2M | 103 | 8 | 12M | |
| 47 | PX BLOCK ITERATOR | | 2M | 103 | 8 | 2M | |
| 48 | TABLE ACCESS STORAGE FULL | DM_DIM_CON_KEY_M | 2M | 103 | 125 | 2M | |
| 49 | HASH JOIN RIGHT OUTER | | 336M | 490K | 8 | 475M | 6.42 |
| 50 | PX RECEIVE | | 4M | 239 | 8 | 30M | |
| 51 | PX SEND BROADCAST | :TQ10009 | 4M | 239 | 8 | 30M | 0.01 |
| 52 | PX BLOCK ITERATOR | | 4M | 239 | 8 | 4M | |
| 53 | TABLE ACCESS STORAGE FULL | DM_DIM_PROJ_KEY_M | 4M | 239 | 206 | 4M | |
| 54 | HASH JOIN RIGHT OUTER | | 336M | 490K | 8 | 475M | 0.89 |
| 55 | PX RECEIVE | | 7 | 2 | 8 | 56 | |
| 56 | PX SEND BROADCAST | :TQ10010 | 7 | 2 | 8 | 56 | |
| 57 | PX BLOCK ITERATOR | | 7 | 2 | 8 | 7 | |
| 58 | TABLE ACCESS STORAGE FULL | DM_DIM_SAL_KEY_M | 7 | 2 | 5 | 7 | |
| 59 | HASH JOIN RIGHT OUTER | | 336M | 490K | 8 | 475M | 1.18 |
| 60 | PX RECEIVE | | 181K | 13 | 8 | 1M | |
| 61 | PX SEND BROADCAST | :TQ10011 | 181K | 13 | 8 | 1M | |
| 62 | PX BLOCK ITERATOR | | 181K | 13 | 8 | 181K | |
| 63 | TABLE ACCESS STORAGE FULL | DM_DIM_DEP_KEY_M | 181K | 13 | 98 | 181K | |
| 64 | HASH JOIN RIGHT OUTER | | 336M | 490K | 8 | 475M | 0.77 |
| 65 | PX RECEIVE | | 186 | 2 | 8 | 1488 | |
| 66 | PX SEND BROADCAST | :TQ10012 | 186 | 2 | 8 | 1488 | |
| 67 | PX BLOCK ITERATOR | | 186 | 2 | 8 | 186 | |
| 68 | TABLE ACCESS STORAGE FULL | DM_DIM_RCM_KEY_M | 186 | 2 | 5 | 186 | |
| 69 | HASH JOIN RIGHT OUTER | | 336M | 489K | 8 | 475M | 1.17 |
| 70 | PX RECEIVE | | 1021 | 2 | 8 | 8168 | |
| 71 | PX SEND BROADCAST | :TQ10013 | 1021 | 2 | 8 | 8168 | |
| 72 | PX BLOCK ITERATOR | | 1021 | 2 | 8 | 1021 | |
| 73 | TABLE ACCESS STORAGE FULL | DM_DIM_REP_KEY_M | 1021 | 2 | 5 | 1021 | |
| 74 | PX BLOCK ITERATOR | | 336M | 489K | 8 | 475M | |
| 75 | TABLE ACCESS STORAGE FULL | DM_CAR_PL_PP_T1_PPT_TMP | 336M | 489K | 174 | 475M | 3.04 |
==============================================================================================================================
而到了11月25日,合同维激增到了10M,项目维也增加到了5M。
SQL Plan Monitoring Details (Plan Hash Value=2562085901)
==============================================================================================================================
| Id | Operation | Name | Rows | Cost | Rows |Activity |
| | | | (Estim) | |(Actual) | (%) |
==============================================================================================================================
| 0 | INSERT STATEMENT | | | | 0 | 0.18 |
| 1 | PX COORDINATOR | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10016 | 508M | 470K | | |
| -> 3 | LOAD AS SELECT | | | | 0 | 14.65 |
| -> 4 | HASH JOIN RIGHT OUTER | | 508M | 470K | 164M | 0.67 |
| 5 | PX RECEIVE | | 10M | 660 | 10M | |
| 6 | PX SEND HASH | :TQ10014 | 10M | 660 | 10M | |
| 7 | PX BLOCK ITERATOR | | 10M | 660 | 10M | |
| 8 | TABLE ACCESS STORAGE FULL | DM_DIM_CON_KEY_M | 10M | 660 | 10M | |
| -> 9 | PX RECEIVE | | 504M | 469K | 164M | 2.79 |
| -> 10 | PX SEND HASH | :TQ10015 | 504M | 469K | 164M | 2.90 |
| -> 11 | HASH JOIN RIGHT OUTER BUFFERED | | 504M | 469K | 164M | 43.12 |
| 12 | PX RECEIVE | | 5M | 346 | 5M | 0.01 |
| 13 | PX SEND HASH | :TQ10012 | 5M | 346 | 5M | 0.01 |
| 14 | PX BLOCK ITERATOR | | 5M | 346 | 5M | |
| 15 | TABLE ACCESS STORAGE FULL | DM_DIM_PROJ_KEY_M | 5M | 346 | 5M | 0.16 |
| 16 | PX RECEIVE | | 500M | 469K | 455M | 8.07 |
| 17 | PX SEND HASH | :TQ10013 | 500M | 469K | 455M | 12.49 |
| 18 | HASH JOIN RIGHT OUTER | | 500M | 469K | 455M | 1.02 |
| 19 | PX RECEIVE | | 71221 | 7 | 570K | |
| 20 | PX SEND BROADCAST | :TQ10000 | 71221 | 7 | 570K | |
| 21 | PX BLOCK ITERATOR | | 71221 | 7 | 71221 | |
| 22 | TABLE ACCESS STORAGE FULL | DM_DIM_PROD_KEY_M | 71221 | 7 | 71221 | |
| 23 | HASH JOIN RIGHT OUTER | | 500M | 469K | 455M | 1.10 |
| 24 | PX RECEIVE | | 71221 | 7 | 570K | |
| 25 | PX SEND BROADCAST | :TQ10001 | 71221 | 7 | 570K | |
| 26 | PX BLOCK ITERATOR | | 71221 | 7 | 71221 | |
| 27 | TABLE ACCESS STORAGE FULL | DM_DIM_PROD_KEY_M | 71221 | 7 | 71221 | |
| 28 | HASH JOIN RIGHT OUTER | | 499M | 469K | 455M | 0.84 |
| 29 | PX RECEIVE | | 145 | 2 | 1160 | |
| 30 | PX SEND BROADCAST | :TQ10002 | 145 | 2 | 1160 | |
| 31 | PX BLOCK ITERATOR | | 145 | 2 | 145 | |
| 32 | TABLE ACCESS STORAGE FULL | DM_DIM_BU_KEY_M | 145 | 2 | 145 | |
| 33 | HASH JOIN RIGHT OUTER | | 499M | 468K | 455M | 0.84 |
| 34 | PX RECEIVE | | 186 | 2 | 1488 | |
| 35 | PX SEND BROADCAST | :TQ10003 | 186 | 2 | 1488 | |
| 36 | PX BLOCK ITERATOR | | 186 | 2 | 186 | |
| 37 | TABLE ACCESS STORAGE FULL | DM_DIM_RCM_KEY_M | 186 | 2 | 186 | |
| 38 | HASH JOIN RIGHT OUTER | | 499M | 468K | 455M | 0.99 |
| 39 | PX RECEIVE | | 1158 | 2 | 9264 | |
| 40 | PX SEND BROADCAST | :TQ10004 | 1158 | 2 | 9264 | |
| 41 | PX BLOCK ITERATOR | | 1158 | 2 | 1158 | |
| 42 | TABLE ACCESS STORAGE FULL | DM_DIM_REP_KEY_M | 1158 | 2 | 1158 | 0.02 |
| 43 | HASH JOIN RIGHT OUTER | | 499M | 468K | 455M | 0.99 |
| 44 | PX RECEIVE | | 226K | 17 | 2M | |
| 45 | PX SEND BROADCAST | :TQ10005 | 226K | 17 | 2M | |
| 46 | PX BLOCK ITERATOR | | 226K | 17 | 226K | |
| 47 | TABLE ACCESS STORAGE FULL | DM_DIM_DEP_KEY_M | 226K | 17 | 226K | |
| 48 | HASH JOIN RIGHT OUTER | | 499M | 468K | 455M | 0.88 |
| 49 | PX RECEIVE | | 303K | 20 | 2M | 0.02 |
| 50 | PX SEND BROADCAST | :TQ10006 | 303K | 20 | 2M | 0.03 |
| 51 | PX BLOCK ITERATOR | | 303K | 20 | 303K | |
| 52 | TABLE ACCESS STORAGE FULL | DM_DIM_CUS_KEY_M | 303K | 20 | 303K | |
| 53 | HASH JOIN RIGHT OUTER | | 499M | 468K | 455M | 1.05 |
| 54 | PX RECEIVE | | 303K | 20 | 2M | 0.01 |
| 55 | PX SEND BROADCAST | :TQ10007 | 303K | 20 | 2M | 0.02 |
| 56 | PX BLOCK ITERATOR | | 303K | 20 | 303K | |
| 57 | TABLE ACCESS STORAGE FULL | DM_DIM_CUS_KEY_M | 303K | 20 | 303K | |
| 58 | HASH JOIN RIGHT OUTER | | 499M | 468K | 455M | 1.42 |
| 59 | PX RECEIVE | | 303K | 20 | 2M | |
| 60 | PX SEND BROADCAST | :TQ10008 | 303K | 20 | 2M | |
| 61 | PX BLOCK ITERATOR | | 303K | 20 | 303K | |
| 62 | TABLE ACCESS STORAGE FULL | DM_DIM_CUS_KEY_M | 303K | 20 | 303K | |
| 63 | HASH JOIN RIGHT OUTER | | 499M | 467K | 455M | 1.23 |
| 64 | PX RECEIVE | | 303K | 20 | 2M | 0.01 |
| 65 | PX SEND BROADCAST | :TQ10009 | 303K | 20 | 2M | |
| 66 | PX BLOCK ITERATOR | | 303K | 20 | 303K | |
| 67 | TABLE ACCESS STORAGE FULL | DM_DIM_CUS_KEY_M | 303K | 20 | 303K | |
| 68 | HASH JOIN RIGHT OUTER | | 499M | 467K | 455M | 0.85 |
| 69 | PX RECEIVE | | 210 | 2 | 1680 | |
| 70 | PX SEND BROADCAST | :TQ10010 | 210 | 2 | 1680 | |
| 71 | PX BLOCK ITERATOR | | 210 | 2 | 210 | |
| 72 | TABLE ACCESS STORAGE FULL | DM_DIM_REG_KEY_M | 210 | 2 | 210 | |
| 73 | HASH JOIN RIGHT OUTER | | 499M | 467K | 455M | 1.01 |
| 74 | PX RECEIVE | | 7 | 2 | 56 | |
| 75 | PX SEND BROADCAST | :TQ10011 | 7 | 2 | 56 | |
| 76 | PX BLOCK ITERATOR | | 7 | 2 | 7 | |
| 77 | TABLE ACCESS STORAGE FULL | DM_DIM_SAL_KEY_M | 7 | 2 | 7 | |
| 78 | PX BLOCK ITERATOR | | 499M | 467K | 455M | |
| 79 | TABLE ACCESS STORAGE FULL | DM_CAR_PL_PP_T1_PPT_TMP | 499M | 467K | 455M | 2.60 |
==============================================================================================================================
维表数据增加的结果,直接导致这两张表由原来的PX SEND BROADCAST变成了PX SEND HASH(测试得出的临界值在4M-5M之间)。
PX SEND BROADCAST时,每个并行Slave会取得一份全表数据,所以每个并行Slave都能全力工作。PX SEND HASH时却出现了异常,可能是由于KEY值分布不均衡,结果是1、2个并行Slave分担了绝大部分工作。因为大部分Slave不做事,导致总的运行时间大幅度拉长。
知道了原因,我们再进行测试。通过提示修改统计信息值,将两张维表的统计值全部改为4M。
修改前,SQL运行了2339s完成(修改后SQL_ID=81x3hwcfd0kkv)。修改后运行了1016s完成(修改后SQL_ID=bdbt8tcuv80sr)。结果集完全一样,均为455M。
同样,将前几次运行最长的4n88ta23h9196加提示修改估计值后,运行2142s完成(修改后SQL_ID=8vqcj478310jb)。而4n88ta23h9196在21日运行了297分钟,25日运行了189分钟。
解决方案:
建议:
- 确认维表数据的正确性,如果是维表数据异常,请重刷维表。
- 如果维表数据确实超过4M,则需要修改估计值,使其小于临界值,走PX SEND BROADCAST。
- 因为有多个程序使用两张维表,建议直接修改统计信息值,而不是通过提示修改。
dbms_stats.set_table_stats(ownname=>'DMDIM',tabname=>'DM_DIM_CON_KEY_M',numrows=>4000000);
dbms_stats.set_table_stats(ownname=>'DMDIM',tabname=>'DM_DIM_PROJ_KEY_M',numrows=>4000000);
注意:这是因为两个维表均比较小才可以这么处理,否则,大数据量的PX SEND BROADCAST也会有性能问题。
2.4.3 PX SEND HASH导致并行不均衡(2)
问题描述:
环境:生产环境
程序:AR月结PFM程序,DM_PFM_GROUP_INTO_PFM_PKG.DM_PFM_GROUP_AR_BAL_P、DM_PFM_GROUP_INTO_PFM_PKG.DM_PFM_GROUP_AR_TRX_P
时间:2013-12-09
生产环境AR月结任务PFM的两个SP还是很慢,请帮忙看看如何优化?
DM_PFM_GROUP_INTO_PFM_PKG.DM_PFM_GROUP_AR_BAL_P—-36mins
DM_PFM_GROUP_INTO_PFM_PKG.DM_PFM_GROUP_AR_TRX_P—-37mins
DM_PFM_GROUP_AR_BAL_P的Top SQL如下:
INSERT /*+APPEND PARALLEL(8)*/
INTO DM_PFM_GROUP_AR_BAL_TMP
(REPORT_ITEM_ID, --报表项ID
SUBJECT_AREA_ID, --主题ID
PERIOD_ID, --时间维键
VERSION_ID, --版本ID
SCENARIO_ID, --场景ID
DATA_CATEGORY_ID, --数据口径ID
BU_KEY, --BU KEY
COMPANY_KEY, --公司KEY
GEO_PC_KEY, --区域责任中心KEY
ACCOUNT_DEPT_CUST_KEY, --客户KEY
CONTRACT_KEY, --合同KEY
PROJ_KEY, --B层项目KEY
ENTERPRISE_CUST_KEY,
END_CUST_KEY,
SIGN_CUST_KEY,
SALES_MODE_KEY, --渠道KEY
AGING_DAYS,--账龄天数
LAST_PERIOD_AGING_DAYS,--上期 账龄天数
TC_CODE, --交易币币种
SCHEDULE_TYPE_ID, --增量调度类型ID
RMB_AAA_PTD_AMT, --人民币实际汇率本期金额
RMB_AAP_PTD_AMT, --人民币预算汇率本期金额
USD_AAA_PTD_AMT, --美元实际汇率本期金额
USD_AAP_PTD_AMT, --美元预算汇率本期金额
RMB_AAA_QTD_AMT, --人民币实际汇率本季度累计金额
RMB_AAP_QTD_AMT, --人民币预算汇率本季度累计金额
USD_AAA_QTD_AMT, --美元实际汇率本季度累计金额
USD_AAP_QTD_AMT, --美元预算汇率本季度累计金额
RMB_AAA_YTD_AMT, --人民币实际汇率本年累计金额
RMB_AAP_YTD_AMT, --人民币预算汇率本年累计金额
USD_AAA_YTD_AMT, --美元实际汇率本年累计金额
USD_AAP_YTD_AMT, --美元预算汇率本年累计金额
RMB_AAA_PY_QTD_AMT, --人民币实际汇率去年同期季累计金额
RMB_AAP_PY_QTD_AMT, --人民币预算汇率去年同期季累计金额
USD_AAA_PY_QTD_AMT, --美元实际汇率去年同期季累计金额
USD_AAP_PY_QTD_AMT, --美元预算汇率去年同期季累计金额
RMB_AAA_PY_YTD_AMT, --人民币实际汇率去年同期年累计金额
RMB_AAP_PY_YTD_AMT, --人民币预算汇率去年同期年累计金额
USD_AAA_PY_YTD_AMT, --美元实际汇率去年同期年累计金额
USD_AAP_PY_YTD_AMT, --美元预算汇率去年同期年累计金额
RMB_AAA_PY_ALL_YTD_AMT, --人民币实际汇率去年全年累计金额
RMB_AAP_PY_ALL_YTD_AMT, --人民币预算汇率去年全年累计金额
USD_AAA_PY_ALL_YTD_AMT, --美元实际汇率去年全年累计金额
USD_AAP_PY_ALL_YTD_AMT, --美元预算汇率去年全年累计金额
RMB_AAA_CY_OPEN_BAL_AMT, --人民币实际汇率年初余额
RMB_AAP_CY_OPEN_BAL_AMT, --人民币预算汇率年初余额
USD_AAA_CY_OPEN_BAL_AMT, --美元实际汇率年初余额
USD_AAP_CY_OPEN_BAL_AMT, --美元预算汇率年初余额
RMB_AAA_END_BAL_AMT, --人民币实际汇率期末余额
RMB_AAP_END_BAL_AMT, --人民币预算汇率期末余额
USD_AAA_END_BAL_AMT, --美元实际汇率期末余额
USD_AAP_END_BAL_AMT, --美元预算汇率期末余额
RMB_AAA_PY_END_BAL_AMT, --人民币实际汇率去年同期期末余额
RMB_AAP_PY_END_BAL_AMT, --人民币预算汇率去年同期期末余额
USD_AAA_PY_END_BAL_AMT, --美元实际汇率去年同期期末余额
USD_AAP_PY_END_BAL_AMT, --美元预算汇率去年同期期末余额
RMB_AAA_PQ_END_BAL_AMT, --人民币实际汇率上季期末余额
RMB_AAP_PQ_END_BAL_AMT, --人民币预算汇率上季期末余额
USD_AAA_PQ_END_BAL_AMT, --美元实际汇率上季期末余额
USD_AAP_PQ_END_BAL_AMT --美元预算汇率上季期末余额
)
SELECT S.REPORT_ITEM_ID AS REPORT_ITEM_ID, --报表项ID
S.SUBJECT_AREA_ID AS SUBJECT_AREA_ID, --主题ID
201311 AS PERIOD_ID, --时间维键
'R01' AS VERSION_ID, --版本ID
S.SCENARIO_ID AS SCENARIO_ID, --场景ID
S.DATA_CATEGORY_ID AS DATA_CATEGORY_ID, --数据口径ID
S.BU_KEY AS BU_KEY, --BU KEY
S.COMPANY_KEY AS COMPANY_KEY, --公司KEY
S.GEO_PC_KEY AS GEO_PC_KEY, --区域责任中心KEY
S.ACCOUNT_DEPT_CUST_KEY AS ACCOUNT_DEPT_CUST_KEY, --客户KEY
S.CONTRACT_KEY AS CONTRACT_KEY, --合同KEY
S.PROJ_KEY AS PROJ_KEY, --B层项目KEY
S.ENTERPRISE_CUST_KEY AS ENTERPRISE_CUST_KEY,
S.END_CUST_KEY AS END_CUST_KEY,
S.SIGN_CUST_KEY AS SIGN_CUST_KEY,
S.SALES_MODE_KEY AS SALES_MODE_KEY, --渠道KEY
S.AGING_DAYS AS AGING_DAYS,--账龄天数
S.LAST_PERIOD_AGING_DAYS AS LAST_PERIOD_AGING_DAYS,--上期 账龄天数
S.TC_CODE AS TC_CODE, --交易币币种
S.SCHEDULE_TYPE_ID AS SCHEDULE_TYPE_ID, --增量调度类型ID
SUM(S.RMB_AAA_PTD_AMT ) AS RMB_AAA_PTD_AMT, --人民币实际汇率本期金额
SUM(S.RMB_AAP_PTD_AMT ) AS RMB_AAP_PTD_AMT, --人民币预算汇率本期金额
SUM(S.USD_AAA_PTD_AMT ) AS USD_AAA_PTD_AMT, --美元实际汇率本期金额
SUM(S.USD_AAP_PTD_AMT ) AS USD_AAP_PTD_AMT, --美元预算汇率本期金额
SUM(S.RMB_AAA_QTD_AMT ) AS RMB_AAA_QTD_AMT, --人民币实际汇率本季度累计金额
SUM(S.RMB_AAP_QTD_AMT ) AS RMB_AAP_QTD_AMT, --人民币预算汇率本季度累计金额
SUM(S.USD_AAA_QTD_AMT ) AS USD_AAA_QTD_AMT, --美元实际汇率本季度累计金额
SUM(S.USD_AAP_QTD_AMT ) AS USD_AAP_QTD_AMT, --美元预算汇率本季度累计金额
SUM(S.RMB_AAA_YTD_AMT ) AS RMB_AAA_YTD_AMT, --人民币实际汇率本年累计金额
SUM(S.RMB_AAP_YTD_AMT ) AS RMB_AAP_YTD_AMT, --人民币预算汇率本年累计金额
SUM(S.USD_AAA_YTD_AMT ) AS USD_AAA_YTD_AMT, --美元实际汇率本年累计金额
SUM(S.USD_AAP_YTD_AMT ) AS USD_AAP_YTD_AMT, --美元预算汇率本年累计金额
SUM(S.RMB_AAA_PY_QTD_AMT ) AS RMB_AAA_PY_QTD_AMT, --人民币实际汇率去年同期季累计金额
SUM(S.RMB_AAP_PY_QTD_AMT ) AS RMB_AAP_PY_QTD_AMT, --人民币预算汇率去年同期季累计金额
SUM(S.USD_AAA_PY_QTD_AMT ) AS USD_AAA_PY_QTD_AMT, --美元实际汇率去年同期季累计金额
SUM(S.USD_AAP_PY_QTD_AMT ) AS USD_AAP_PY_QTD_AMT, --美元预算汇率去年同期季累计金额
SUM(S.RMB_AAA_PY_YTD_AMT ) AS RMB_AAA_PY_YTD_AMT, --人民币实际汇率去年同期年累计金额
SUM(S.RMB_AAP_PY_YTD_AMT ) AS RMB_AAP_PY_YTD_AMT, --人民币预算汇率去年同期年累计金额
SUM(S.USD_AAA_PY_YTD_AMT ) AS USD_AAA_PY_YTD_AMT, --美元实际汇率去年同期年累计金额
SUM(S.USD_AAP_PY_YTD_AMT ) AS USD_AAP_PY_YTD_AMT, --美元预算汇率去年同期年累计金额
SUM(S.RMB_AAA_PY_ALL_YTD_AMT ) AS RMB_AAA_PY_ALL_YTD_AMT, --人民币实际汇率去年全年累计金额
SUM(S.RMB_AAP_PY_ALL_YTD_AMT ) AS RMB_AAP_PY_ALL_YTD_AMT, --人民币预算汇率去年全年累计金额
SUM(S.USD_AAA_PY_ALL_YTD_AMT ) AS USD_AAA_PY_ALL_YTD_AMT, --美元实际汇率去年全年累计金额
SUM(S.USD_AAP_PY_ALL_YTD_AMT ) AS USD_AAP_PY_ALL_YTD_AMT, --美元预算汇率去年全年累计金额
SUM(S.RMB_AAA_CY_OPEN_BAL_AMT ) AS RMB_AAA_CY_OPEN_BAL_AMT, --人民币实际汇率年初余额
SUM(S.RMB_AAP_CY_OPEN_BAL_AMT ) AS RMB_AAP_CY_OPEN_BAL_AMT, --人民币预算汇率年初余额
SUM(S.USD_AAA_CY_OPEN_BAL_AMT ) AS USD_AAA_CY_OPEN_BAL_AMT, --美元实际汇率年初余额
SUM(S.USD_AAP_CY_OPEN_BAL_AMT ) AS USD_AAP_CY_OPEN_BAL_AMT, --美元预算汇率年初余额
SUM(S.RMB_AAA_END_BAL_AMT ) AS RMB_AAA_END_BAL_AMT, --人民币实际汇率期末余额
SUM(S.RMB_AAP_END_BAL_AMT ) AS RMB_AAP_END_BAL_AMT, --人民币预算汇率期末余额
SUM(S.USD_AAA_END_BAL_AMT ) AS USD_AAA_END_BAL_AMT, --美元实际汇率期末余额
SUM(S.USD_AAP_END_BAL_AMT ) AS USD_AAP_END_BAL_AMT, --美元预算汇率期末余额
SUM(S.RMB_AAA_PY_END_BAL_AMT ) AS RMB_AAA_PY_END_BAL_AMT, --人民币实际汇率去年同期期末余额
SUM(S.RMB_AAP_PY_END_BAL_AMT ) AS RMB_AAP_PY_END_BAL_AMT, --人民币预算汇率去年同期期末余额
SUM(S.USD_AAA_PY_END_BAL_AMT ) AS USD_AAA_PY_END_BAL_AMT, --美元实际汇率去年同期期末余额
SUM(S.USD_AAP_PY_END_BAL_AMT ) AS USD_AAP_PY_END_BAL_AMT, --美元预算汇率去年同期期末余额
SUM(S.RMB_AAA_PQ_END_BAL_AMT ) AS RMB_AAA_PQ_END_BAL_AMT, --人民币实际汇率上季期末余额
SUM(S.RMB_AAP_PQ_END_BAL_AMT ) AS RMB_AAP_PQ_END_BAL_AMT, --人民币预算汇率上季期末余额
SUM(S.USD_AAA_PQ_END_BAL_AMT ) AS USD_AAA_PQ_END_BAL_AMT, --美元实际汇率上季期末余额
SUM(S.USD_AAP_PQ_END_BAL_AMT ) AS USD_AAP_PQ_END_BAL_AMT --美元预算汇率上季期末余额
FROM DM_GROUP_AR_BAL_BASE_PP_V S,
(SELECT DIM.PROJ_KEY AS PROJ_KEY,
NVL(TO_NUMBER(TO_CHAR(DIM.PROJ_END_DATE,'YYYYMM')),471212) AS PROJ_END_DATE
FROM DM_DIM_PROJECT_D DIM) D
WHERE 1=1 AND ( ( 1=1) )
AND S.PROJ_KEY = D.PROJ_KEY
AND D.PROJ_END_DATE >= 201307
AND S.PERIOD_ID = 201311
AND S.VERSION_ID IN ('R01','PPV')
GROUP BY S.REPORT_ITEM_ID,
S.SUBJECT_AREA_ID,
S.SCENARIO_ID,
S.DATA_CATEGORY_ID,
S.BU_KEY,
S.COMPANY_KEY,
S.GEO_PC_KEY,
S.ACCOUNT_DEPT_CUST_KEY,
S.CONTRACT_KEY,
S.PROJ_KEY,
S.ENTERPRISE_CUST_KEY,
S.END_CUST_KEY,
S.SIGN_CUST_KEY,
S.SALES_MODE_KEY,
S.AGING_DAYS,
S.LAST_PERIOD_AGING_DAYS,
S.TC_CODE,
S.SCHEDULE_TYPE_ID
DM_PFM_GROUP_AR_TRX_P的Top SQL如下:
INSERT /*+APPEND PARALLEL(8)*/
INTO DM_PFM_GROUP_AR_TRX_TMP
(REPORT_ITEM_ID, --报表项ID
SUBJECT_AREA_ID, --主题ID
PERIOD_ID, --时间维键
VERSION_ID, --版本ID
SCENARIO_ID, --场景ID
DATA_CATEGORY_ID, --数据口径ID
BU_KEY, --BU KEY
COMPANY_KEY, --公司KEY
GEO_PC_KEY, --区域责任中心KEY
ACCOUNT_DEPT_CUST_KEY, --客户KEY
CONTRACT_KEY, --合同KEY
PROJ_KEY, --B层项目KEY
MILESTONE_ID, -- 里程碑ID
TC_CODE, --交易币币种
SCHEDULE_TYPE_ID, --增量调度类型ID
RECEIPT_METHOD_ID,--收款方式ID
ENTERPRISE_CUST_KEY,
SALES_MODE_KEY, --销售渠道KEY
AGING_DAYS, --账龄天数
SIGN_CUST_KEY,
END_CUST_KEY,
SOURCE_TABLE,
RMB_AAA_PTD_AMT, --人民币实际汇率本期金额
RMB_AAP_PTD_AMT, --人民币预算汇率本期金额
USD_AAA_PTD_AMT, --美元实际汇率本期金额
USD_AAP_PTD_AMT, --美元预算汇率本期金额
RMB_AAA_QTD_AMT, --人民币实际汇率本季度累计金额
RMB_AAP_QTD_AMT, --人民币预算汇率本季度累计金额
USD_AAA_QTD_AMT, --美元实际汇率本季度累计金额
USD_AAP_QTD_AMT, --美元预算汇率本季度累计金额
RMB_AAA_YTD_AMT, --人民币实际汇率本年累计金额
RMB_AAP_YTD_AMT, --人民币预算汇率本年累计金额
USD_AAA_YTD_AMT, --美元实际汇率本年累计金额
USD_AAP_YTD_AMT, --美元预算汇率本年累计金额
RMB_AAA_ITD_AMT, --人民币实际汇率历史累计金额
RMB_AAP_ITD_AMT, --人民币预算汇率历史累计金额
USD_AAA_ITD_AMT, --美元实际汇率历史累计金额
USD_AAP_ITD_AMT, --美元预算汇率历史累计金额
RMB_AAA_PY_PTD_AMT, --人民币实际汇率去年同期月金额
RMB_AAP_PY_PTD_AMT, --人民币预算汇率去年同期月金额
USD_AAA_PY_PTD_AMT, --美元实际汇率去年同期月金额
USD_AAP_PY_PTD_AMT, --美元预算汇率去年同期月金额
RMB_AAA_PY_QTD_AMT, --人民币实际汇率去年同期季累计金额
RMB_AAP_PY_QTD_AMT, --人民币预算汇率去年同期季累计金额
USD_AAA_PY_QTD_AMT, --美元实际汇率去年同期季累计金额
USD_AAP_PY_QTD_AMT, --美元预算汇率去年同期季累计金额
RMB_AAA_PY_YTD_AMT, --人民币实际汇率去年同期年累计金额
RMB_AAP_PY_YTD_AMT, --人民币预算汇率去年同期年累计金额
USD_AAA_PY_YTD_AMT, --美元实际汇率去年同期年累计金额
USD_AAP_PY_YTD_AMT, --美元预算汇率去年同期年累计金额
RMB_AAA_PY_ALL_QTD_AMT, --人民币实际汇率去年全季累计金额
RMB_AAP_PY_ALL_QTD_AMT, --人民币预算汇率去年全季累计金额
USD_AAA_PY_ALL_QTD_AMT, --美元实际汇率去年全季累计金额
USD_AAP_PY_ALL_QTD_AMT, --美元预算汇率去年全季累计金额
RMB_AAA_PY_ALL_YTD_AMT, --人民币实际汇率去年全年累计金额
RMB_AAP_PY_ALL_YTD_AMT, --人民币预算汇率去年全年累计金额
USD_AAA_PY_ALL_YTD_AMT, --美元实际汇率去年全年累计金额
USD_AAP_PY_ALL_YTD_AMT, --美元预算汇率去年全年累计金额
RMB_AAA_PP_PTD_AMT, --人民币实际汇率上月同期月金额
RMB_AAP_PP_PTD_AMT, --人民币预算汇率上月同期月金额
USD_AAA_PP_PTD_AMT, --美元实际汇率上月同期月金额
USD_AAP_PP_PTD_AMT, --美元预算汇率上月同期月金额
RMB_AAA_PP_QTD_AMT, --人民币实际汇率上季同期季累计金额
RMB_AAP_PP_QTD_AMT, --人民币预算汇率上季同期季累计金额
USD_AAA_PP_QTD_AMT, --美元实际汇率上季同期季累计金额
USD_AAP_PP_QTD_AMT, --美元预算汇率上季同期季累计金额
RMB_AAA_PY_ITD_AMT, --人民币 实际汇率 去年同期 历史累计金额
RMB_AAP_PY_ITD_AMT, --人民币 预算汇率 去年同期 历史累计金额
USD_AAA_PY_ITD_AMT, --美元 实际汇率 去年同期 历史累计金额
USD_AAP_PY_ITD_AMT --美元 预算汇率 去年同期 历史累计金额
)
SELECT S.REPORT_ITEM_ID AS REPORT_ITEM_ID, --报表项ID
S.SUBJECT_AREA_ID AS SUBJECT_AREA_ID, --主题ID
201311 AS PERIOD_ID, --时间维键
'R01' AS VERSION_ID, --版本ID
S.SCENARIO_ID AS SCENARIO_ID, --场景ID
S.DATA_CATEGORY_ID AS DATA_CATEGORY_ID, --数据口径ID
S.BU_KEY AS BU_KEY, --BU KEY
S.COMPANY_KEY AS COMPANY_KEY, --公司KEY
S.GEO_PC_KEY AS GEO_PC_KEY, --区域责任中心KEY
S.ACCOUNT_DEPT_CUST_KEY AS ACCOUNT_DEPT_CUST_KEY, --客户KEY
S.CONTRACT_KEY AS CONTRACT_KEY, --合同KEY
S.PROJ_KEY AS PROJ_KEY, --B层项目KEY
S.MILESTONE_ID AS MILESTONE_ID, -- 里程碑ID
S.TC_CODE AS TC_CODE, --交易币币种
S.SCHEDULE_TYPE_ID AS SCHEDULE_TYPE_ID, --增量调度类型ID
S.RECEIPT_METHOD_ID AS RECEIPT_METHOD_ID,--收款方式ID
S.ENTERPRISE_CUST_KEY AS ENTERPRISE_CUST_KEY,
S.SALES_MODE_KEY AS SALES_MODE_KEY, --销售渠道KEY
S.AGING_DAYS AS AGING_DAYS, --账龄天数
S.SIGN_CUST_KEY AS SIGN_CUST_KEY,
S.END_CUST_KEY AS END_CUST_KEY,
'DM_GROUP_AR_TRX_BASE_F' AS SOURCE_TABLE,
SUM(S.RMB_AAA_PTD_AMT) AS RMB_AAA_PTD_AMT, --人民币实际汇率本期金额
SUM(S.RMB_AAP_PTD_AMT) AS RMB_AAP_PTD_AMT, --人民币预算汇率本期金额
SUM(S.USD_AAA_PTD_AMT) AS USD_AAA_PTD_AMT, --美元实际汇率本期金额
SUM(S.USD_AAP_PTD_AMT) AS USD_AAP_PTD_AMT, --美元预算汇率本期金额
SUM(S.RMB_AAA_QTD_AMT) AS RMB_AAA_QTD_AMT, --人民币实际汇率本季度累计金额
SUM(S.RMB_AAP_QTD_AMT) AS RMB_AAP_QTD_AMT, --人民币预算汇率本季度累计金额
SUM(S.USD_AAA_QTD_AMT) AS USD_AAA_QTD_AMT, --美元实际汇率本季度累计金额
SUM(S.USD_AAP_QTD_AMT) AS USD_AAP_QTD_AMT, --美元预算汇率本季度累计金额
SUM(S.RMB_AAA_YTD_AMT) AS RMB_AAA_YTD_AMT, --人民币实际汇率本年累计金额
SUM(S.RMB_AAP_YTD_AMT) AS RMB_AAP_YTD_AMT, --人民币预算汇率本年累计金额
SUM(S.USD_AAA_YTD_AMT) AS USD_AAA_YTD_AMT, --美元实际汇率本年累计金额
SUM(S.USD_AAP_YTD_AMT) AS USD_AAP_YTD_AMT, --美元预算汇率本年累计金额
0 AS RMB_AAA_ITD_AMT, --人民币实际汇率历史累计金额
0 AS RMB_AAP_ITD_AMT, --人民币预算汇率历史累计金额
0 AS USD_AAA_ITD_AMT, --美元实际汇率历史累计金额
0 AS USD_AAP_ITD_AMT, --美元预算汇率历史累计金额
SUM(S.RMB_AAA_PY_PTD_AMT) AS RMB_AAA_PY_PTD_AMT, --人民币实际汇率去年同期月金额
SUM(S.RMB_AAP_PY_PTD_AMT) AS RMB_AAP_PY_PTD_AMT, --人民币预算汇率去年同期月金额
SUM(S.USD_AAA_PY_PTD_AMT) AS USD_AAA_PY_PTD_AMT, --美元实际汇率去年同期月金额
SUM(S.USD_AAP_PY_PTD_AMT) AS USD_AAP_PY_PTD_AMT, --美元预算汇率去年同期月金额
SUM(S.RMB_AAA_PY_QTD_AMT) AS RMB_AAA_PY_QTD_AMT, --人民币实际汇率去年同期季累计金额
SUM(S.RMB_AAP_PY_QTD_AMT) AS RMB_AAP_PY_QTD_AMT, --人民币预算汇率去年同期季累计金额
SUM(S.USD_AAA_PY_QTD_AMT) AS USD_AAA_PY_QTD_AMT, --美元实际汇率去年同期季累计金额
SUM(S.USD_AAP_PY_QTD_AMT) AS USD_AAP_PY_QTD_AMT, --美元预算汇率去年同期季累计金额
SUM(S.RMB_AAA_PY_YTD_AMT) AS RMB_AAA_PY_YTD_AMT, --人民币实际汇率去年同期年累计金额
SUM(S.RMB_AAP_PY_YTD_AMT) AS RMB_AAP_PY_YTD_AMT, --人民币预算汇率去年同期年累计金额
SUM(S.USD_AAA_PY_YTD_AMT) AS USD_AAA_PY_YTD_AMT, --美元实际汇率去年同期年累计金额
SUM(S.USD_AAP_PY_YTD_AMT) AS USD_AAP_PY_YTD_AMT, --美元预算汇率去年同期年累计金额
SUM(S.RMB_AAA_PY_ALL_QTD_AMT) AS RMB_AAA_PY_ALL_QTD_AMT, --人民币实际汇率去年全季累计金额
SUM(S.RMB_AAP_PY_ALL_QTD_AMT) AS RMB_AAP_PY_ALL_QTD_AMT, --人民币预算汇率去年全季累计金额
SUM(S.USD_AAA_PY_ALL_QTD_AMT) AS USD_AAA_PY_ALL_QTD_AMT, --美元实际汇率去年全季累计金额
SUM(S.USD_AAP_PY_ALL_QTD_AMT) AS USD_AAP_PY_ALL_QTD_AMT, --美元预算汇率去年全季累计金额
SUM(S.RMB_AAA_PY_ALL_YTD_AMT) AS RMB_AAA_PY_ALL_YTD_AMT, --人民币实际汇率去年全年累计金额
SUM(S.RMB_AAP_PY_ALL_YTD_AMT) AS RMB_AAP_PY_ALL_YTD_AMT, --人民币预算汇率去年全年累计金额
SUM(S.USD_AAA_PY_ALL_YTD_AMT) AS USD_AAA_PY_ALL_YTD_AMT, --美元实际汇率去年全年累计金额
SUM(S.USD_AAP_PY_ALL_YTD_AMT) AS USD_AAP_PY_ALL_YTD_AMT, --美元预算汇率去年全年累计金额
SUM(S.RMB_AAA_PP_PTD_AMT) AS RMB_AAA_PP_PTD_AMT, --人民币实际汇率上月同期月金额
SUM(S.RMB_AAP_PP_PTD_AMT) AS RMB_AAP_PP_PTD_AMT, --人民币预算汇率上月同期月金额
SUM(S.USD_AAA_PP_PTD_AMT) AS USD_AAA_PP_PTD_AMT, --美元实际汇率上月同期月金额
SUM(S.USD_AAP_PP_PTD_AMT) AS USD_AAP_PP_PTD_AMT, --美元预算汇率上月同期月金额
SUM(S.RMB_AAA_PP_QTD_AMT) AS RMB_AAA_PP_QTD_AMT, --人民币实际汇率上季同期季累计金额
SUM(S.RMB_AAP_PP_QTD_AMT) AS RMB_AAP_PP_QTD_AMT, --人民币预算汇率上季同期季累计金额
SUM(S.USD_AAA_PP_QTD_AMT) AS USD_AAA_PP_QTD_AMT, --美元实际汇率上季同期季累计金额
SUM(S.USD_AAP_PP_QTD_AMT) AS USD_AAP_PP_QTD_AMT, --美元预算汇率上季同期季累计金额
0 AS RMB_AAA_PY_ITD_AMT, --人民币 实际汇率 去年同期 历史累计金额
0 AS RMB_AAP_PY_ITD_AMT, --人民币 预算汇率 去年同期 历史累计金额
0 AS USD_AAA_PY_ITD_AMT, --美元 实际汇率 去年同期 历史累计金额
0 AS USD_AAP_PY_ITD_AMT --美元 预算汇率 去年同期 历史累计金额
FROM DM_GROUP_AR_TRX_BASE_F S,
(SELECT DIM.PROJ_KEY AS PROJ_KEY,
NVL(TO_NUMBER(TO_CHAR(DIM.PROJ_END_DATE,'YYYYMM')),471212) AS PROJ_END_DATE
FROM DM_DIM_PROJECT_D DIM) D
WHERE 1=1 AND ( ( 1=1) )
AND S.PROJ_KEY = D.PROJ_KEY
AND D.PROJ_END_DATE >= 201307
AND S.PERIOD_ID = 201311
AND S.VERSION_ID ='R01'
GROUP BY S.REPORT_ITEM_ID,
S.SUBJECT_AREA_ID,
S.SCENARIO_ID,
S.DATA_CATEGORY_ID,
S.BU_KEY,
S.COMPANY_KEY,
S.GEO_PC_KEY,
S.ACCOUNT_DEPT_CUST_KEY,
S.CONTRACT_KEY,
S.PROJ_KEY,
S.MILESTONE_ID,
S.TC_CODE,
S.SCHEDULE_TYPE_ID,
S.RECEIPT_METHOD_ID,
S.ENTERPRISE_CUST_KEY,
S.SALES_MODE_KEY,
S.AGING_DAYS,
S.SIGN_CUST_KEY,
S.END_CUST_KEY
问题分析:
我们拿DM_PFM_GROUP_AR_TRX_P中的Select部分做Count测试。SQL如下:
(sql_id=7gbwxfsjt2p98)
select /*+PARALLEL(8)*/ count(0)
from (SELECT S.REPORT_ITEM_ID AS REPORT_ITEM_ID,
S.SUBJECT_AREA_ID AS SUBJECT_AREA_ID,
201311 AS PERIOD_ID,
'R01' AS VERSION_ID,
S.SCENARIO_ID AS SCENARIO_ID,
S.DATA_CATEGORY_ID AS DATA_CATEGORY_ID,
S.BU_KEY AS BU_KEY,
S.COMPANY_KEY AS COMPANY_KEY,
S.GEO_PC_KEY AS GEO_PC_KEY,
S.ACCOUNT_DEPT_CUST_KEY AS ACCOUNT_DEPT_CUST_KEY,
S.CONTRACT_KEY AS CONTRACT_KEY,
S.PROJ_KEY AS PROJ_KEY,
S.MILESTONE_ID AS MILESTONE_ID,
S.TC_CODE AS TC_CODE,
S.SCHEDULE_TYPE_ID AS SCHEDULE_TYPE_ID,
S.RECEIPT_METHOD_ID AS RECEIPT_METHOD_ID,
S.ENTERPRISE_CUST_KEY AS ENTERPRISE_CUST_KEY,
S.SALES_MODE_KEY AS SALES_MODE_KEY,
S.AGING_DAYS AS AGING_DAYS,
S.SIGN_CUST_KEY AS SIGN_CUST_KEY,
S.END_CUST_KEY AS END_CUST_KEY,
'DM_GROUP_AR_TRX_BASE_F' AS SOURCE_TABLE,
SUM(S.RMB_AAA_PTD_AMT) AS RMB_AAA_PTD_AMT,
SUM(S.RMB_AAP_PTD_AMT) AS RMB_AAP_PTD_AMT,
SUM(S.USD_AAA_PTD_AMT) AS USD_AAA_PTD_AMT,
SUM(S.USD_AAP_PTD_AMT) AS USD_AAP_PTD_AMT,
SUM(S.RMB_AAA_QTD_AMT) AS RMB_AAA_QTD_AMT,
SUM(S.RMB_AAP_QTD_AMT) AS RMB_AAP_QTD_AMT,
SUM(S.USD_AAA_QTD_AMT) AS USD_AAA_QTD_AMT,
SUM(S.USD_AAP_QTD_AMT) AS USD_AAP_QTD_AMT,
SUM(S.RMB_AAA_YTD_AMT) AS RMB_AAA_YTD_AMT,
SUM(S.RMB_AAP_YTD_AMT) AS RMB_AAP_YTD_AMT,
SUM(S.USD_AAA_YTD_AMT) AS USD_AAA_YTD_AMT,
SUM(S.USD_AAP_YTD_AMT) AS USD_AAP_YTD_AMT,
0 AS RMB_AAA_ITD_AMT,
0 AS RMB_AAP_ITD_AMT,
0 AS USD_AAA_ITD_AMT,
0 AS USD_AAP_ITD_AMT,
SUM(S.RMB_AAA_PY_PTD_AMT) AS RMB_AAA_PY_PTD_AMT,
SUM(S.RMB_AAP_PY_PTD_AMT) AS RMB_AAP_PY_PTD_AMT,
SUM(S.USD_AAA_PY_PTD_AMT) AS USD_AAA_PY_PTD_AMT,
SUM(S.USD_AAP_PY_PTD_AMT) AS USD_AAP_PY_PTD_AMT,
SUM(S.RMB_AAA_PY_QTD_AMT) AS RMB_AAA_PY_QTD_AMT,
SUM(S.RMB_AAP_PY_QTD_AMT) AS RMB_AAP_PY_QTD_AMT,
SUM(S.USD_AAA_PY_QTD_AMT) AS USD_AAA_PY_QTD_AMT,
SUM(S.USD_AAP_PY_QTD_AMT) AS USD_AAP_PY_QTD_AMT,
SUM(S.RMB_AAA_PY_YTD_AMT) AS RMB_AAA_PY_YTD_AMT,
SUM(S.RMB_AAP_PY_YTD_AMT) AS RMB_AAP_PY_YTD_AMT,
SUM(S.USD_AAA_PY_YTD_AMT) AS USD_AAA_PY_YTD_AMT,
SUM(S.USD_AAP_PY_YTD_AMT) AS USD_AAP_PY_YTD_AMT,
SUM(S.RMB_AAA_PY_ALL_QTD_AMT) AS RMB_AAA_PY_ALL_QTD_AMT,
SUM(S.RMB_AAP_PY_ALL_QTD_AMT) AS RMB_AAP_PY_ALL_QTD_AMT,
SUM(S.USD_AAA_PY_ALL_QTD_AMT) AS USD_AAA_PY_ALL_QTD_AMT,
SUM(S.USD_AAP_PY_ALL_QTD_AMT) AS USD_AAP_PY_ALL_QTD_AMT,
SUM(S.RMB_AAA_PY_ALL_YTD_AMT) AS RMB_AAA_PY_ALL_YTD_AMT,
SUM(S.RMB_AAP_PY_ALL_YTD_AMT) AS RMB_AAP_PY_ALL_YTD_AMT,
SUM(S.USD_AAA_PY_ALL_YTD_AMT) AS USD_AAA_PY_ALL_YTD_AMT,
SUM(S.USD_AAP_PY_ALL_YTD_AMT) AS USD_AAP_PY_ALL_YTD_AMT,
SUM(S.RMB_AAA_PP_PTD_AMT) AS RMB_AAA_PP_PTD_AMT,
SUM(S.RMB_AAP_PP_PTD_AMT) AS RMB_AAP_PP_PTD_AMT,
SUM(S.USD_AAA_PP_PTD_AMT) AS USD_AAA_PP_PTD_AMT,
SUM(S.USD_AAP_PP_PTD_AMT) AS USD_AAP_PP_PTD_AMT,
SUM(S.RMB_AAA_PP_QTD_AMT) AS RMB_AAA_PP_QTD_AMT,
SUM(S.RMB_AAP_PP_QTD_AMT) AS RMB_AAP_PP_QTD_AMT,
SUM(S.USD_AAA_PP_QTD_AMT) AS USD_AAA_PP_QTD_AMT,
SUM(S.USD_AAP_PP_QTD_AMT) AS USD_AAP_PP_QTD_AMT,
0 AS RMB_AAA_PY_ITD_AMT,
0 AS RMB_AAP_PY_ITD_AMT,
0 AS USD_AAA_PY_ITD_AMT,
0 AS USD_AAP_PY_ITD_AMT
FROM DM_GROUP_AR_TRX_BASE_F S,
(SELECT DIM.PROJ_KEY AS PROJ_KEY,
NVL(TO_NUMBER(TO_CHAR(DIM.PROJ_END_DATE, 'YYYYMM')),
471212) AS PROJ_END_DATE
FROM DM_DIM_PROJECT_D DIM) D
WHERE 1 = 1 AND ((1 = 1))
AND S.PROJ_KEY = D.PROJ_KEY
AND D.PROJ_END_DATE >= 201307
AND S.PERIOD_ID = 201311
AND S.VERSION_ID = 'R01'
GROUP BY S.REPORT_ITEM_ID,
S.SUBJECT_AREA_ID,
S.SCENARIO_ID,
S.DATA_CATEGORY_ID,
S.BU_KEY,
S.COMPANY_KEY,
S.GEO_PC_KEY,
S.ACCOUNT_DEPT_CUST_KEY,
S.CONTRACT_KEY,
S.PROJ_KEY,
S.MILESTONE_ID,
S.TC_CODE,
S.SCHEDULE_TYPE_ID,
S.RECEIPT_METHOD_ID,
S.ENTERPRISE_CUST_KEY,
S.SALES_MODE_KEY,
S.AGING_DAYS,
S.SIGN_CUST_KEY,
S.END_CUST_KEY);
执行计划如下:
Plan hash value: 496602727
----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | 944K(100)| |
| 1 | SORT AGGREGATE | | 1 | | | | |
| 2 | PX COORDINATOR | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10002 | 1 | | | | |
| 4 | SORT AGGREGATE | | 1 | | | | |
| 5 | VIEW | | 167M| | | 944K (1)| 03:40:21 |
| 6 | HASH GROUP BY | | 167M| 39G| 60G| 944K (1)| 03:40:21 |
| 7 | HASH JOIN | | 167M| 39G| | 223K (1)| 00:52:07 |
| 8 | JOIN FILTER CREATE | :BF0000 | 5265K| 70M| | 25577 (1)| 00:05:59 |
| 9 | PX RECEIVE | | 5265K| 70M| | 25577 (1)| 00:05:59 |
| 10 | PX SEND HASH | :TQ10000 | 5265K| 70M| | 25577 (1)| 00:05:59 |
| 11 | PX BLOCK ITERATOR | | 5265K| 70M| | 25577 (1)| 00:05:59 |
| 12 | TABLE ACCESS STORAGE FULL| DM_DIM_PROJECT_D | 5265K| 70M| | 25577 (1)| 00:05:59 |
| 13 | PX RECEIVE | | 167M| 37G| | 197K (1)| 00:46:08 |
| 14 | PX SEND HASH | :TQ10001 | 167M| 37G| | 197K (1)| 00:46:08 |
| 15 | JOIN FILTER USE | :BF0000 | 167M| 37G| | 197K (1)| 00:46:08 |
| 16 | PX BLOCK ITERATOR | | 167M| 37G| | 197K (1)| 00:46:08 |
| 17 | TABLE ACCESS STORAGE FULL| DM_GROUP_AR_TRX_BASE_F | 167M| 37G| | 197K (1)| 00:46:08 |
----------------------------------------------------------------------------------------------------------------------
性能关键在于对表DM_DIM_PROJECT_D做了PX SEND HASH,但是SEND不均匀,导致大部分并行Slave没有工作,接下来的Hash Join浪费了大量时间。
考虑到表DM_DIM_PROJECT_D并不太大,只有5.5M记录,占用7.6G。与其不均匀PX SEND HASH,还不如PX SEND BROADCAST,使每个并行Slave都能正常工作,虽然分发时会多消耗一点时间,但整体应该快很多。
在子查询D加提示/+Cardinality(DIM,3000000)/,修改SQL如下:
(sql_id=abysrc7mf2jd4)
select /*+PARALLEL(8)*/ count(0)
from (SELECT S.REPORT_ITEM_ID AS REPORT_ITEM_ID,
S.SUBJECT_AREA_ID AS SUBJECT_AREA_ID,
201311 AS PERIOD_ID,
'R01' AS VERSION_ID,
S.SCENARIO_ID AS SCENARIO_ID,
S.DATA_CATEGORY_ID AS DATA_CATEGORY_ID,
S.BU_KEY AS BU_KEY,
S.COMPANY_KEY AS COMPANY_KEY,
S.GEO_PC_KEY AS GEO_PC_KEY,
S.ACCOUNT_DEPT_CUST_KEY AS ACCOUNT_DEPT_CUST_KEY,
S.CONTRACT_KEY AS CONTRACT_KEY,
S.PROJ_KEY AS PROJ_KEY,
S.MILESTONE_ID AS MILESTONE_ID,
S.TC_CODE AS TC_CODE,
S.SCHEDULE_TYPE_ID AS SCHEDULE_TYPE_ID,
S.RECEIPT_METHOD_ID AS RECEIPT_METHOD_ID,
S.ENTERPRISE_CUST_KEY AS ENTERPRISE_CUST_KEY,
S.SALES_MODE_KEY AS SALES_MODE_KEY,
S.AGING_DAYS AS AGING_DAYS,
S.SIGN_CUST_KEY AS SIGN_CUST_KEY,
S.END_CUST_KEY AS END_CUST_KEY,
'DM_GROUP_AR_TRX_BASE_F' AS SOURCE_TABLE,
SUM(S.RMB_AAA_PTD_AMT) AS RMB_AAA_PTD_AMT,
SUM(S.RMB_AAP_PTD_AMT) AS RMB_AAP_PTD_AMT,
SUM(S.USD_AAA_PTD_AMT) AS USD_AAA_PTD_AMT,
SUM(S.USD_AAP_PTD_AMT) AS USD_AAP_PTD_AMT,
SUM(S.RMB_AAA_QTD_AMT) AS RMB_AAA_QTD_AMT,
SUM(S.RMB_AAP_QTD_AMT) AS RMB_AAP_QTD_AMT,
SUM(S.USD_AAA_QTD_AMT) AS USD_AAA_QTD_AMT,
SUM(S.USD_AAP_QTD_AMT) AS USD_AAP_QTD_AMT,
SUM(S.RMB_AAA_YTD_AMT) AS RMB_AAA_YTD_AMT,
SUM(S.RMB_AAP_YTD_AMT) AS RMB_AAP_YTD_AMT,
SUM(S.USD_AAA_YTD_AMT) AS USD_AAA_YTD_AMT,
SUM(S.USD_AAP_YTD_AMT) AS USD_AAP_YTD_AMT,
0 AS RMB_AAA_ITD_AMT,
0 AS RMB_AAP_ITD_AMT,
0 AS USD_AAA_ITD_AMT,
0 AS USD_AAP_ITD_AMT,
SUM(S.RMB_AAA_PY_PTD_AMT) AS RMB_AAA_PY_PTD_AMT,
SUM(S.RMB_AAP_PY_PTD_AMT) AS RMB_AAP_PY_PTD_AMT,
SUM(S.USD_AAA_PY_PTD_AMT) AS USD_AAA_PY_PTD_AMT,
SUM(S.USD_AAP_PY_PTD_AMT) AS USD_AAP_PY_PTD_AMT,
SUM(S.RMB_AAA_PY_QTD_AMT) AS RMB_AAA_PY_QTD_AMT,
SUM(S.RMB_AAP_PY_QTD_AMT) AS RMB_AAP_PY_QTD_AMT,
SUM(S.USD_AAA_PY_QTD_AMT) AS USD_AAA_PY_QTD_AMT,
SUM(S.USD_AAP_PY_QTD_AMT) AS USD_AAP_PY_QTD_AMT,
SUM(S.RMB_AAA_PY_YTD_AMT) AS RMB_AAA_PY_YTD_AMT,
SUM(S.RMB_AAP_PY_YTD_AMT) AS RMB_AAP_PY_YTD_AMT,
SUM(S.USD_AAA_PY_YTD_AMT) AS USD_AAA_PY_YTD_AMT,
SUM(S.USD_AAP_PY_YTD_AMT) AS USD_AAP_PY_YTD_AMT,
SUM(S.RMB_AAA_PY_ALL_QTD_AMT) AS RMB_AAA_PY_ALL_QTD_AMT,
SUM(S.RMB_AAP_PY_ALL_QTD_AMT) AS RMB_AAP_PY_ALL_QTD_AMT,
SUM(S.USD_AAA_PY_ALL_QTD_AMT) AS USD_AAA_PY_ALL_QTD_AMT,
SUM(S.USD_AAP_PY_ALL_QTD_AMT) AS USD_AAP_PY_ALL_QTD_AMT,
SUM(S.RMB_AAA_PY_ALL_YTD_AMT) AS RMB_AAA_PY_ALL_YTD_AMT,
SUM(S.RMB_AAP_PY_ALL_YTD_AMT) AS RMB_AAP_PY_ALL_YTD_AMT,
SUM(S.USD_AAA_PY_ALL_YTD_AMT) AS USD_AAA_PY_ALL_YTD_AMT,
SUM(S.USD_AAP_PY_ALL_YTD_AMT) AS USD_AAP_PY_ALL_YTD_AMT,
SUM(S.RMB_AAA_PP_PTD_AMT) AS RMB_AAA_PP_PTD_AMT,
SUM(S.RMB_AAP_PP_PTD_AMT) AS RMB_AAP_PP_PTD_AMT,
SUM(S.USD_AAA_PP_PTD_AMT) AS USD_AAA_PP_PTD_AMT,
SUM(S.USD_AAP_PP_PTD_AMT) AS USD_AAP_PP_PTD_AMT,
SUM(S.RMB_AAA_PP_QTD_AMT) AS RMB_AAA_PP_QTD_AMT,
SUM(S.RMB_AAP_PP_QTD_AMT) AS RMB_AAP_PP_QTD_AMT,
SUM(S.USD_AAA_PP_QTD_AMT) AS USD_AAA_PP_QTD_AMT,
SUM(S.USD_AAP_PP_QTD_AMT) AS USD_AAP_PP_QTD_AMT,
0 AS RMB_AAA_PY_ITD_AMT,
0 AS RMB_AAP_PY_ITD_AMT,
0 AS USD_AAA_PY_ITD_AMT,
0 AS USD_AAP_PY_ITD_AMT
FROM DM_GROUP_AR_TRX_BASE_F S,
(SELECT /*+Cardinality(DIM,3000000)*/DIM.PROJ_KEY AS PROJ_KEY,
NVL(TO_NUMBER(TO_CHAR(DIM.PROJ_END_DATE, 'YYYYMM')),
471212) AS PROJ_END_DATE
FROM DM_DIM_PROJECT_D DIM) D
WHERE 1 = 1 AND ((1 = 1))
AND S.PROJ_KEY = D.PROJ_KEY
AND D.PROJ_END_DATE >= 201307
AND S.PERIOD_ID = 201311
AND S.VERSION_ID = 'R01'
GROUP BY S.REPORT_ITEM_ID,
S.SUBJECT_AREA_ID,
S.SCENARIO_ID,
S.DATA_CATEGORY_ID,
S.BU_KEY,
S.COMPANY_KEY,
S.GEO_PC_KEY,
S.ACCOUNT_DEPT_CUST_KEY,
S.CONTRACT_KEY,
S.PROJ_KEY,
S.MILESTONE_ID,
S.TC_CODE,
S.SCHEDULE_TYPE_ID,
S.RECEIPT_METHOD_ID,
S.ENTERPRISE_CUST_KEY,
S.SALES_MODE_KEY,
S.AGING_DAYS,
S.SIGN_CUST_KEY,
S.END_CUST_KEY);
执行计划如下:
Plan hash value: 3426232867
----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | 944K(100)| |
| 1 | SORT AGGREGATE | | 1 | | | | |
| 2 | PX COORDINATOR | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10002 | 1 | | | | |
| 4 | SORT AGGREGATE | | 1 | | | | |
| 5 | VIEW | | 167M| | | 944K (1)| 03:40:21 |
| 6 | HASH GROUP BY | | 167M| 39G| 60G| 944K (1)| 03:40:21 |
| 7 | PX RECEIVE | | 167M| 39G| | 223K (1)| 00:52:07 |
| 8 | PX SEND HASH | :TQ10001 | 167M| 39G| | 223K (1)| 00:52:07 |
| 9 | HASH JOIN | | 167M| 39G| | 223K (1)| 00:52:07 |
| 10 | PX RECEIVE | | 3000K| 40M| | 25577 (1)| 00:05:59 |
| 11 | PX SEND BROADCAST | :TQ10000 | 3000K| 40M| | 25577 (1)| 00:05:59 |
| 12 | PX BLOCK ITERATOR | | 3000K| 40M| | 25577 (1)| 00:05:59 |
| 13 | TABLE ACCESS STORAGE FULL| DM_DIM_PROJECT_D | 3000K| 40M| | 25577 (1)| 00:05:59 |
| 14 | PX BLOCK ITERATOR | | 167M| 37G| | 197K (1)| 00:46:08 |
| 15 | TABLE ACCESS STORAGE FULL | DM_GROUP_AR_TRX_BASE_F | 167M| 37G| | 197K (1)| 00:46:08 |
----------------------------------------------------------------------------------------------------------------------
实际测试的结果,修改前的SQL,运行1589s完成,修改后的SQL,运行459s完成,结果集均为155942011。
对DM_PFM_GROUP_AR_BAL_P做同样的Count测试。修改前的SQL(sql_id=42wj65qmhmmdu),运行328s完成,修改后的SQL(sql_id= 9kh9bsv1r0mur),运行280s完成,结果集均为40163246。因为结果集较小,修改前后的差别不是很大。
解决方案:
建议:
在子查询D加提示/+Cardinality(DIM,3000000)/,使对表DM_DIM_PROJECT_D做PX SEND BROADCAST。
注意:在表DM_DIM_PROJECT_D数据量大幅增加后,因为PX SEND BROADCAST成本增加,需要考虑别的优化措施。
test
INSERT INTO T_M_FV_FREEBIE_CHG_D ( DATA_DAY, CLASS_TYPE, OFFER_ID, FREEBIE_TYPE, SERV_TYPE, FREE_AMT, TRANS_NUM, PROCS_TIME ) SELECT DATA_DAY, CLASS_TYPE, OFFER_ID, FREEBIE_TYPE, SERV_TYPE, SUM(FREE_AMT) AS FREE_AMT, SUM(TRANS_NUM) AS TRANS_NUM, SYSDATE AS PROCS_TIME FROM (SELECT /+parallel(4)/ :B1 AS DATA_DAY, CASE WHEN T1.SERV_TYPE=1 THEN '13' ELSE '14' END AS CLASS_TYPE, T1.OFFER_ID AS OFFER_ID, T1.ACCT_TYPE AS FREEBIE_TYPE, CASE WHEN T1.SERV_TYPE=1 THEN '13' ELSE '14' END AS SERV_TYPE, T2.MVNO_CODE AS MVNO_CODE, SUM(T1.CHRG_AMT) AS FREE_AMT, SUM(T1.GRANT_NUM) AS TRANS_NUM FROM T_L_FV_GFT_DTL_D T1 LEFT JOIN T_L_FV_SUBS_BASE_INFO_D T2 ON T1.SUBS_KEY = T2.SUBS_KEY AND T2.DATA_DAY = :B1 WHERE T1.DATA_DAY=:B1 AND T1.USER_TYPE = '0' AND T1.OFFER_ID NOT IN(SELECT OFFER_KEY FROM T_D_DIM_FV_SMARTPLAN_CFG) AND INSTR(:B2 , T1.ACCT_TYPE)>0 GROUP BY T1.OFFER_ID, T1.ACCT_TYPE, T2.MVNO_CODE, CASE WHEN T1.SERV_TYPE=1 THEN '13' ELSE '14' END UNION ALL SELECT /+parallel (4)/ :B1 AS DATA_DAY, '13' AS CLASS_TYPE, T1.OFFER_ID AS OFFER_ID, T1.ACCT_TYPE AS FREEBIE_TYPE, '13' AS SERV_TYPE, T2.MVNO_CODE AS MVNO_CODE, SUM(T1.CHRG_AMT) AS FREE_AMT, SUM(T1.GRANT_NUM) AS TRANS_NUM FROM T_L_FV_GFT_DTL_D T1 LEFT JOIN T_L_FV_SUBS_BASE_INFO_D T2 ON T1.SUBS_KEY = T2.SUBS_KEY AND T2.DATA_DAY = :B1 WHERE T1.DATA_DAY=:B1 AND T1.USER_TYPE = '0' AND T1.SERV_TYPE=1 AND T1.OFFER_ID IN (SELECT OFFER_KEY FROM T_D_DIM_FV_SMARTPLAN_CFG) AND INSTR(:B2 , T1.ACCT_TYPE)>0 GROUP BY T1.OFFER_ID, T1.ACCT_TYPE, T2.MVNO_CODE) T3 JOIN T_D_DIM_FV_MVNO_CFG T5 ON T3.MVNO_CODE=T5.MVNO_CODE AND T5.FLAG_2GL='1' GROUP BY DATA_DAY, CLASS_TYPE, OFFER_ID, FREEBIE_TYPE, SERV_TYPE
o
项目名称:CBS/CRM系统表OGG实时同步至数据仓库
项目简介:有业务需求将来自5个CRM/CBS数据库130张表实时同步到数据仓库,要求实现次日凌晨1:00之前完成。
项目难点:
1.逻辑关系复杂,为5个业务数据库汇聚到数据仓库,配置和后续维护繁琐;
2.实时数据量大,兼有大事物和长事物,对源端和目标端数据库性能负载较大;
3.
ogg 12.2.0.1 installation
OGG 12.2安装步骤
-
使用oracle用户,上传介质到服务器并解压,得到文件夹fbo_ggs_Linux_x64_shiphome
[oracle@host2 oraadm]:oggtgt> unzip fbo_ggs_Linux_x64_shiphome.zip
如果db版本是11.2.0.4,并且ogg使用Integrated Capture模式,需要打补丁17030189,注意该补丁与20299013冲突。12c无需理会。 -
使用rsp文件安装ogg
--创建rsp文件,输入以下命令,第234行为可更改部分
[oracle@host1 Disk1]:oggsrc> vi oggcore.rsp
oracle.install.responseFileVersion=/oracle/install/rspfmt_ogginstall_response_schema_v12_1_2
INSTALL_OPTION=ORA11g
SOFTWARE_LOCATION=/opt/oraadm/test
START_MANAGER=fasle
--安装命令,rsp文件写绝对路径
[oracle@host1 Disk1]:oggsrc> ./runInstaller -silent -nowait -responseFile /opt/oraadm/fbo_ggs_Linux_x64_shiphome/Disk1/oggcore.rsp
- 完成安装,回到命令行页面。查询之前的安装目录,查看安装组件,并登陆ggsci
[oracle@host2 Disk1]:oggtgt> cd /opt/goldengate/
[oracle@host2 goldengate]:oggtgt> ls
[oracle@host2 goldengate]:oggtgt> ./ggsci
Oracle GoldenGate Command Interpreter for Oracle
Version 12.2.0.1.1 OGGCORE_12.2.0.1.0_PLATFORMS_151211.1401_FBO
Linux, x64, 64bit (optimized), Oracle 11g on Dec 12 2015 00:54:38
Operating system character set identified as UTF-8.Copyright (C) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
GGSCI (host2) 1>
- 进入数据库,打开supplementary log,开启OGG模式
select force_logging,supplemental_log_data_min from v$database;
alter database force logging;
alter database add supplemental log data;
SQL> select force_logging,supplemental_log_data_min from v$database;
FOR SUPPLEME
--- --------
YES YES
SQL> alter system set ENABLE_GOLDENGATE_REPLICATION=true;
SQL> ALTER SYSTEM SWITCH LOGFILE;
- 创建表空间,建用户
CREATE TABLESPACE DBADATATBS DATAFILE
'/******/dbadatatbs01.dbf' SIZE 2048M AUTOEXTEND OFF
LOGGING
ONLINE
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
BLOCKSIZE 8K
SEGMENT SPACE MANAGEMENT AUTO
FLASHBACK ON;
--(如果用户已存在,则变更权限即可)
CREATE USER GGSYNC
IDENTIFIED BY ggsync
DEFAULT TABLESPACE DBADATATBS
TEMPORARY TABLESPACE TEMP
PROFILE DEFAULT
ACCOUNT UNLOCK;
-- 2 Roles for GGSYNC
GRANT CONNECT TO GGSYNC;
GRANT RESOURCE TO GGSYNC;
ALTER USER GGSYNC DEFAULT ROLE ALL;
-- 11 System Privileges for GGSYNC
GRANT ALTER SESSION TO GGSYNC;
GRANT CREATE SESSION TO GGSYNC;
GRANT SELECT ANY TABLE TO GGSYNC;
GRANT SELECT ANY DICTIONARY TO GGSYNC;
GRANT CREATE TABLE TO GGSYNC;
GRANT UNLIMITED TABLESPACE TO GGSYNC;
GRANT FLASHBACK ANY TABLE TO GGSYNC;
GRANT INSERT ANY TABLE TO GGSYNC;
GRANT DELETE ANY TABLE TO GGSYNC;
GRANT UPDATE ANY TABLE TO GGSYNC;
GRANT ALTER ANY TABLE TO GGSYNC;
grant create view to ggsync;
grant create job to ggsync;
grant select any dictionary to ggsync;
grant dba to ggsync;
grant execute on dbms_capture_adm to ggsync;
grant SELECT on dba_clusters to ggsync;
grant SELECT on V_$DATABASE to ggsync;
grant select on sys.logmnr_buildlog to ggsync;
grant EXECUTE on DBMS_FLASHBACK to ggsync;
grant execute on DBMS_CAPTURE_ADM to ggsync;
grant execute on DBMS_STREAMS to ggsync;
grant EXECUTE_CATALOG_ROLE to ggsync;
- 增加心跳表,创建GLOBALS文件
GGSCI (host1 as ggsync@oggsrc) 21> edit param ./GLOBALS
--输入以下两行内容
CHECKPOINTTABLE ggsync.gg_checkpoint_tab
GGSCHEMA ggsync
GGSCI (host1 as ggsync@oggsrc) 21> exit
[oracle@host2 goldengate]:oggtgt> ./ggsci
GGSCI (host2) 8> dblogin userid ggsync,password ggsync
GGSCI (host2 as ggsync@oggtgt) 10> add HEARTBEATTABLE
GGSCI (host2 as ggsync@oggtgt) 11> ADD CHECKPOINTTABLE ggsync.gg_checkpoint_tab
- 创建 MGR参数文件并启动 MGR进程
./ggsci
create subdirs
edit param mgr
--输入如下内容:
port 7809
DYNAMICPORTLIST 7810-7909
PURGEOLDEXTRACTS ./dirdat/*/*,usecheckpoints,minkeepdays 3
autostart er *
autorestart er *,retries 5,waitminutes 7,resetminutes 60
lagreporthours 1
laginfominutes 5
lagcriticalminutes 5
GGSCI (host1) 5> stop mgr
Manager process is required by other GGS processes.
Are you sure you want to stop it (y/n)?y
Sending STOP request to MANAGER ...
Request processed.
Manager stopped.
GGSCI (host1) 6> start mgr
Manager started.GGSCI (oggtest) 3> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
- 创建抽取进程
创建目录
[oracle@host1 goldengate]:oggsrc> mkdir dirdat/e_oggsrc
GGSCI (host1) 7> add extract e_oggsrc, {intergrated} tranlog, begin now --【大括号部分可选,启用integrated capture模式】
GGSCI (host1) 8> add exttrail ./dirdat/e_oggsrc/ea, extract e_oggsrc, megabytes 500
{GGSCI (host1) 9> REGISTER EXTRACT e_oggsrc,database} --【大括号部分可选,注册integrated capture抽取进程】
GGSCI (host1) 10> edit param e_oggsrc
EXTRACT e_oggsrc
SETENV (ORACLE_HOME = /app/oracle/ora11g)
SETENV (ORACLE_SID=oggsrc)
SETENV (NLS_LANG="AMERICAN_AMERICA.ZHS16GBK")
userid ggsync, password ggsync
EXTTRAIL ./dirdat/e_oggsrc/ea
DISCARDFILE ./dirrpt/e_oggsrc.dsc,append,megabytes 2000
-- gg sync
table scott.*;
7.1添加附加日志
cd $OGG_HOME
./ggsci
dblogin userid ggsync,password ****
add trandata ggsync.gg_sync_testdb
add trandata scott.t1
add trandata scott.t2
add trandata scott.t1
- 配置传输进程
首先在目标库位置创建接受目录
[oracle@host2 goldengate]:oggtgt> mkdir dirdat/r_oggsrc
GGSCI (host1 as ggsync@oggsrc) 19> add extract t_oggtgt,exttrailsource ./dirdat/e_oggsrc/ea,begin now
GGSCI (host1 as ggsync@oggsrc) 20> add rmttrail ./dirdat/r_oggsrc/ra,extract t_oggtgt,megabytes 500
GGSCI (host1 as ggsync@oggsrc) 21> edit param t_oggtgt
EXTRACT t_oggtgt
SETENV (ORACLE_HOME = /app/oracle/ora11g)
SETENV (ORACLE_SID=oggsrc)
SETENV (NLS_LANG="AMERICAN_AMERICA.ZHS16GBK")
userid ggsync, password ggsync
passthru
RMTHOST 10.120.89.205, MGRPORT 7809, compress
RMTTRAIL ./dirdat/r_oggsrc/ra
DISCARDFILE ./dirrpt/t_oggtgt.dsc,append,megabytes 2000
REPORTCOUNT EVERY 10 MINUTES, RATE
-- gg sync
table scott.*;
- 配置目标复制进程(目标库)
mkdir ./dirdata/r_oggsrc
./ggsci
GGSCI (host2 as ggsync@oggtgt) 5> add replicat r_oggsrc, EXTTRAIL ./dirdat/r_oggsrc/ra
GGSCI (host2 as ggsync@oggtgt) 5> edit param r_oggsrc
replicat r_oggsrc
SETENV (ORACLE_HOME = /app/oracle/ora11g )
SETENV (ORACLE_SID=oggtgt)
SETENV (NLS_LANG="AMERICAN_AMERICA.ZHS16GBK")
userid ggsync, password ggsync
--HANDLECOLLISIONS
REPERROR DEFAULT,ABEND
DISCARDFILE ./dirrpt/r_oggsrc.dsc,append,megabytes 2000
map scott.*,target scott.*;
- 初始化数据
1.初始化所有表数据
从源库复制需要同步的表至目标库
2.启用参数 HANDLECOLLISIONS
去掉 HANDLECOLLISIONS 前的,”--”
(如果是重新同步个别表,则在 map 后面添加 HANDLECOLLISIONS,
例如:map test1.t1, target test.t1 HANDLECOLLISIONS;)
3.启动恢复进程 r_testdb
4.等待恢复进程同步完成之后,停止恢复进程 r_testdb
5.禁用 HANDLECOLLISIONS
6.启动恢复进程
转换OGG模式
http://docs.oracle.com/middleware/12212/odi/develop-connectivity-km/ogg.htm#ODIKM1695
Docs:
Administration guide: http://docs.oracle.com/goldengate/c1221/gg-winux/GWUAD/toc.htm
Knowledge guide: http://docs.oracle.com/goldengate/c1221/gg-winux/GIORA/toc.htm
SQL ID: f1uuzchp17xwy
WORKLOAD REPOSITORY SQL Report
Snapshot Period Summary
DB Name | DB Id | Instance | Inst num | Startup Time | Release | RAC |
---|---|---|---|---|---|---|
ETLDB | 1820230817 | etldb1 | 1 | 25-Jul-16 22:07 | 11.2.0.3.0 | YES |
Snap Id | Snap Time | Sessions | Cursors/Session | |
---|---|---|---|---|
Begin Snap: | 19780 | 03-Jun-17 03:30:04 | 181 | 1.5 |
End Snap: | 19790 | 03-Jun-17 08:30:04 | 158 | 1.7 |
Elapsed: | 300.00 (mins) | |||
DB Time: | 2,029.83 (mins) |
SQL Summary
SQL Id | Elapsed Time (ms) | Module | Action | SQL Text |
---|---|---|---|---|
f1uuzchp17xwy | 2,948,651 | JDBC Thin Client | INSERT /*+ append */ INTO HWCDM.T_L_CUST_SUBS_INFO_D( DATA_DAY , SUBS_... |
SQL ID: f1uuzchp17xwy
- 1st Capture and Last Capture Snap IDs refer to Snapshot IDs witin the snapshot range
- INSERT /*+ append */ INTO HWCDM.T_L_CUST_SUBS_INFO_D( DATA_DAY , SUBS_...
# | Plan Hash Value | Total Elapsed Time(ms) | Executions | 1st Capture Snap ID | Last Capture Snap ID |
---|---|---|---|---|---|
1 | 1584396146 | 2,948,651 | 1 | 19781 | 19782 |
Plan 1(PHV: 1584396146)
Back to TopPlan Statistics
- % Total DB Time is the Elapsed Time of the SQL statement divided into the Total Database Time multiplied by 100
Stat Name | Statement Total | Per Execution | % Snap Total |
---|---|---|---|
Elapsed Time (ms) | 2,948,651 | 2,948,651.44 | 2.42 |
CPU Time (ms) | 1,532,856 | 1,532,855.80 | 3.30 |
Executions | 1 | ||
Buffer Gets | 11,320,124 | 11,320,124.00 | 0.51 |
Disk Reads | 13,664,654 | 13,664,654.00 | 3.22 |
Parse Calls | 9 | 9.00 | 0.00 |
Rows | 33,018,999 | 33,018,999.00 | |
User I/O Wait Time (ms) | 1,526,193 | ||
Cluster Wait Time (ms) | 3,058 | ||
Application Wait Time (ms) | 16 | ||
Concurrency Wait Time (ms) | 53 | ||
Invalidations | 0 | ||
Version Count | 4 | ||
Sharable Mem(KB) | 654 |
Back to Plan 1(PHV: 1584396146)
Back to Top
Execution Plan
Id | Operation | Name | Rows | Bytes | TempSpc | Cost (%CPU) | Time | Pstart | Pstop | TQ | IN-OUT | PQ Distrib |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | INSERT STATEMENT | 706K(100) | ||||||||||
1 | LOAD AS SELECT | |||||||||||
2 | PX COORDINATOR | |||||||||||
3 | PX SEND QC (RANDOM) | :TQ10005 | 8 | 10760 | 706K (1) | 02:21:22 | Q1,05 | P->S | QC (RAND) | |||
4 | HASH JOIN OUTER BUFFERED | 8 | 10760 | 706K (1) | 02:21:22 | Q1,05 | PCWP | |||||
5 | PX RECEIVE | 8 | 8264 | 660K (1) | 02:12:05 | Q1,05 | PCWP | |||||
6 | PX SEND HASH | :TQ10003 | 8 | 8264 | 660K (1) | 02:12:05 | Q1,03 | P->P | HASH | |||
7 | HASH JOIN | 8 | 8264 | 660K (1) | 02:12:05 | Q1,03 | PCWP | |||||
8 | PX RECEIVE | 1 | 152 | 6105 (1) | 00:01:14 | Q1,03 | PCWP | |||||
9 | PX SEND BROADCAST | :TQ10000 | 1 | 152 | 6105 (1) | 00:01:14 | Q1,00 | P->P | BROADCAST | |||
10 | PX BLOCK ITERATOR | 1 | 152 | 6105 (1) | 00:01:14 | KEY | KEY | Q1,00 | PCWC | |||
11 | TABLE ACCESS FULL | T_E_CUST_INFO_D | 1 | 152 | 6105 (1) | 00:01:14 | KEY | KEY | Q1,00 | PCWP | ||
12 | VIEW | 26M | 21G | 654K (1) | 02:10:52 | Q1,03 | PCWP | |||||
13 | WINDOW SORT PUSHED RANK | 26M | 9315M | 11G | 654K (1) | 02:10:52 | Q1,03 | PCWP | ||||
14 | PX RECEIVE | 26M | 9315M | 654K (1) | 02:10:52 | Q1,03 | PCWP | |||||
15 | PX SEND HASH | :TQ10001 | 26M | 9315M | 654K (1) | 02:10:52 | Q1,01 | P->P | HASH | |||
16 | WINDOW CHILD PUSHED RANK | 26M | 9315M | 654K (1) | 02:10:52 | Q1,01 | PCWP | |||||
17 | PX BLOCK ITERATOR | 26M | 9315M | 75918 (1) | 00:15:12 | KEY | KEY | Q1,01 | PCWC | |||
18 | TABLE ACCESS FULL | T_E_CUST_SUBS_INFO_D | 26M | 9315M | 75918 (1) | 00:15:12 | KEY | KEY | Q1,01 | PCWP | ||
19 | PX RECEIVE | 1 | 312 | 46415 (1) | 00:09:17 | Q1,05 | PCWP | |||||
20 | PX SEND HASH | :TQ10004 | 1 | 312 | 46415 (1) | 00:09:17 | Q1,04 | P->P | HASH | |||
21 | VIEW | 1 | 312 | 46415 (1) | 00:09:17 | Q1,04 | PCWP | |||||
22 | WINDOW SORT PUSHED RANK | 1 | 112 | 46415 (1) | 00:09:17 | Q1,04 | PCWP | |||||
23 | PX RECEIVE | 1 | 112 | 46415 (1) | 00:09:17 | Q1,04 | PCWP | |||||
24 | PX SEND HASH | :TQ10002 | 1 | 112 | 46415 (1) | 00:09:17 | Q1,02 | P->P | HASH | |||
25 | WINDOW CHILD PUSHED RANK | 1 | 112 | 46415 (1) | 00:09:17 | Q1,02 | PCWP | |||||
26 | PX BLOCK ITERATOR | 1 | 112 | 46414 (1) | 00:09:17 | KEY | KEY | Q1,02 | PCWC | |||
27 | TABLE ACCESS FULL | T_E_ACCT_INFO_D | 1 | 112 | 46414 (1) | 00:09:17 | KEY | KEY | Q1,02 | PCWP |
- automatic DOP: Computed Degree of Parallelism is 4
Back to Plan 1(PHV: 1584396146)
Back to Top
Full SQL Text
case when in select
select 'alter table '||b.owner||'.'||b.table_name||' move tablespace '||
case when b.table_name like 'T_SYS_%' then 'TBS_DWH_DEFT'
when b.table_name like 'T_D_DIM_%' THEN 'TBS_DWH_DIM'
when b.table_name like 'T_E_%' then 'TBS_DWH_EDM'
when b.table_name like 'T_L_%' then 'TBS_DWH_LS'
when b.table_name like 'T_L_%' then 'TBS_DWH_LS'
when b.table_name like 'T_M_%' then 'TBS_DWH_DM'
else 'USERS' end
||';' as SQL from all_objects a,all_tables b where
a.OBJECT_TYPE='TABLE'
and b.tablespace_name='USERS'
and b.owner in ('HWCDM','DWHODS')
and a.CREATED>to_date('2016-11-21 00:00:00','YYYY-MM-DD HH24:MI:SS')
and a.OBJECT_NAME=b.TABLE_NAME
系统诊断
--查看udump文件
select p.value || '/' || i.instance_name || 'ora' || spid || '.trc' as "trace_file_name" from v$parameter p, v$process pro,v$session s,(select sid from v$mystat where rownum = 1) m, v$instance i where lower(p.name) = 'user_dump_dest' and pro.addr = s.paddr and m.sid = s.sid;
--被锁对象
select object_name as 对象名称,s.sid,s.serial#,p.spid as 系统进程号,s.last_call_et
from v$locked_object l , dba_objects o , v$session s , v$process p
where l.object_id=o.object_id and l.session_id=s.sid and s.paddr=p.addr;
select * from dba_dml_locks;
--1.查看系统等待
select sid,username,sql_id,osuser,serial#,event,p1,p2,p3,last_call_et,sql_id,username,blocking_session
from gv$session a --where sid=903;
where username is not null
and event not like '%mess%'-- and username LIKE 'FIN%'; --sid=977; and username ='PUBDATA';
--选取sql_text
select sql_text from v$sql where sql_id='0g2cqt0d9x8k2'; 2rpvkhm9ckfgh 2dx3ds16tghf6
--查看历史sql_plan
select t.id,t.operation||' '||t.options operation,t.object_name,t.cost,t.cardinality,t.bytes,t.cardinality from v$sql_plan t
where sql_id='cn6d6z2pqd76w' order by id
--2.查看有无阻塞
select sid,serial#,sql_id,event,osuser,username,program,last_call_et,blocking_session
from gv$session --where sid in(1392,1149,591)
where blocking_session>0;
--查看10分钟内数据库中所有锁的信息
select to_char(ash.sample_time, 'HH24:MI:SS') TIME,
ash.session_id,
decode(ash.session_state, 'WATING', ash.event, ash.session_state) STATE,
ash.sql_id,
ash.blocking_session BLOCKER
from v$active_session_history ash, dba_users du
where du.user_id = ash.user_id
and ash.sample_time > systimestamp - (10 / 1440);
--查看某个会话过去一段时间的等待时间及sql_id
select sample_time,event,wait_time,sql_id from v$active_session_history where session_id=&sid and session_serial=&serial;
--查看正在执行的sql情况
select sid,serial#,sql_id,event,osuser,username,program,last_call_et,blocking_session,P1,P2,P3
from Gv$session
where osuser='zhiming.li1' and username='DEPLOYOP';
--根据块号查表名[热点数据块的读取等待]
select p1 "file#",p2 "block#",p3 "class#"
from v$session_wait where event='read by other session';
SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, TABLESPACE_NAME, A.PARTITION_NAME
FROM DBA_EXTENTS A
WHERE FILE_ID = &FILE_ID
AND &BLOCK_ID BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS - 1;
--根据rowid查询记录存在哪个分区中
select dbms_rowid.rowid_relative_fno(&rowid) "FileNo", dbms_rowid.rowid_block_number(&rowid) "BlockNo"from dual;
--查出file_id和block_id使用上面语句匹配
--争夺数据块的数据对象查询
select owner,object_name,subobject_name,object_type
from dba_objects where data_object_id in (select row_wait_obj# from v$session where event='buffer_busy_waits');
--kill阻塞会话
select 'alter system kill session '||''''||sid||','||ss||''''||' immediate;' from
(select sid,SERIAL# ss,event,blocking_session,last_call_et,sql_id,prev_sql_id,status
from v$session where sid in(
select blocking_session
from gv$session
where blocking_session>0) ) and blocking_session is null;
select * from V$SESSION_LONGOPS WHERE USERNAME='UMINTF'
select xid from v$transaction where ses_addr=v$session.saddr;
select sql_id
from dba_hist_active_sess_history a
where a.xid in(
select xid,status from v$transaction where ses_addr in(
select saddr
from v$session where sid in(
select blocking_session
from gv$session
where blocking_session>0)))
select /*+ rule */ * from gv$lock where type='TX';
--查看语句
select sid,sql_id
from v$session
where sid=;
--3.查看正在执行的job
select * from dba_jobs_running;
--暂停止job
exec dbms_job.broken(jobid,false)
commit;
--停其他用户的job
exec sys.dbms_ijob.broken(98,true);
select count(*) from gv$session
select inst_id,count(*) from gv$session group by inst_id;
commit;
--重开始job
exec dbms_job.broken(1,false)
commit;
--占用资源的语句信息
SELECT b.username username,
a.SQL_TEXT,
a.DISK_READS reads,
a.executions exec,
a.disk_reads / DECODE (a.executions, 0, 1, a.executions)
rds_exec_ratio,
a.sql_text Statement
FROM v$sqlarea a, dba_users b
WHERE a.parsing_user_id = b.user_id AND a.disk_reads > 100000
ORDER BY a.disk_reads DESC;
--用buffer_gets列来替换disk_reads列可以得到占用最多内存的sql语句的相关信
--使用CPU多的用户session
--12是cpu used by this session
select a.sid,spid,status,substr(a.program,1,40) prog,a.terminal,osuser,value/60/100 value
from v$session a,v$process b,v$sesstat c
where c.statistic#=12 and c.sid=a.sid and a.paddr=b.addr order by value desc;
--RAC数据库查询SESSION中消耗CPU时间的相关SQL语句及进程
SELECT a.SID,a.SERIAL#,b.sql_text,b.CPU_TIME, b.parsing_schEma_name
FROM GV$SESSION a LEFT OUTER JOIN Gv$sqlarea b ON a.sql_address=b.address
where cpu_time >0
ORDER BY b.CPU_TIME DESC ;
--列出使用频率最高的5个查询:
select sql_text,executions
from (
select
sql_text,executions, rank() over (order by executions desc) exec_rank
from v$sql)
where exec_rank <=5;
--消耗磁盘读取最多的sql top5:
select disk_reads,sql_text
from (select sql_text,disk_reads, dense_rank() over (order by disk_reads desc) disk_reads_rank from v$sql)
where disk_reads_rank <=5;
--需要大量缓冲读取(逻辑读)操作的查询:
select buffer_gets,sql_text
from (select sql_text,buffer_gets, dense_rank() over (order by buffer_gets desc) buffer_gets_rank from v$sql)
where buffer_gets_rank<=5;
-- 执行次数多的SQL
SELECT sql_text, executions
FROM (SELECT sql_text, executions
FROM v$sqlarea
ORDER BY executions DESC)
WHERE ROWNUM < 10;
---逻辑读最多的SQL
SELECT *
FROM (SELECT buffer_gets, sql_text
FROM v$sqlarea
WHERE buffer_gets > 500000
ORDER BY buffer_gets DESC)
WHERE ROWNUM <= 10;
select * from v$process where spid=4438
addr
select * from v$session where paddr='addr'
select sql_id,event from v$session where sid=
select sql_text from v$sqltext where sql_id='' order by piece;
--查看运行长的语句
select a.inst_id,a.sid,a.serial#,a.username,a.machine,a.event,a.SQL_id,a.sql_child_number,a.last_call_et,b.spid
from gv$session a,gv$process b
where a.status='ACTIVE'
and a.type<>'BACKGROUND'
and a.paddr=b.addr
and a.inst_id=b.inst_id
order by last_call_et desc;
--查看语句内容
select sql_text from v$sqltext
where sql_id='dfvt1axmvj6qz'
order by piece;
select wm_concat(sql_text) from
(
select sql_text from v$sqltext
where sql_id='a8dkbv3nw81r0'
order by piece
)
--查看执行计划:
select * from gv$sql_plan
where sql_id='cr7jnm26mv0kp'
and child_number=0;
select * from table(dbms_xplan.display_awr('sql_id'));
select * from table(dbms_xplan.display_cursor('sql_id',null,'ADVANCED ALLSTATS LAST PEEKED_BINDS'));
select * from table(dbms_xplan.display_cursor('83ph8nr7xmq3x',9));
--查看绑定变量:
SELECT child_number,
name,
datatype_string,
character_sid,
last_captured,
value_string,
ANYDATA.accesstimestamp (value_anydata)
FROM V$SQL_BIND_CAPTURE
WHERE sql_id= '0ddtac23d8yf2'
SELECT snap_id,
NAME,
position,
value_string,
last_captured,
WAS_CAPTURED
FROM dba_hist_sqlbind
WHERE sql_id = 'c1j018vt5ajdu';
SELECT
dbms_sqltune.extract_bind(bind_data, 1).value_string AS a,
dbms_sqltune.extract_bind(bind_data, 2).value_string AS b
FROM wrh$_sqlstat
WHERE sql_id = 'c1j018vt5ajdu';
select sql_id,prev_sql_id from v$session
where paddr in
(
select addr from v$process
where spid=1782216
)
林建新 15:47:37
/* Formatted on 2015/4/27 15:42:31 (QP5 v5.185.11230.41888) */
SELECT *
FROM ( SELECT r.reportorphonenumber, r.reportorname, rp.companycode
FROM sinocore.gcregistmain r
INNER JOIN
sinocore.GCREGISTPOLICY rp
ON r.registno = rp.registno
WHERE rp.startdate <= SYSDATE AND rp.enddate > SYSDATE
ORDER BY r.reportdate DESC)
WHERE ROWNUM <= :1
select a.sid,a.serial#,a.machine,b.event,a.SQL_ADDRESS,a.last_call_et,c.spid
from v$session a,v$session_wait b,v$process c
where a.sid=b.sid
and a.status='ACTIVE'
and a.type<>'BACKGROUND'
and a.paddr=c.addr
order by last_call_et desc
select * from v$sql_plan
where address='0000000259596460';
select /*+ rule */ * from gv$lock where ;
select * from dba_jobs where last_date between to_date('20150925173000','yyyymmddhh24miss')
and to_date('20150925181000','yyyymmddhh24miss')
select * from dba_jobs_running;
1 264 1136390 2015-10-14 4:30:20 04:30:20 0
select what from dba_jobs where job=1136390
select count(*) from atpintf.fin_atp_bank_info;
select * from dba_jobs where last_date between to_date('20150928120000','yyyymmddhh24miss')
and to_date('20150928130000','yyyymmddhh24miss');
select * from appdata.job_schedule_table where job_name in(select replace ( replace(what,'slis_jobs_package.',''),';','')
from dba_jobs where last_date between to_date('20150928120000','yyyymmddhh24miss')
and to_date('20150928130000','yyyymmddhh24miss'));
revoke insert on atpintf.fin_atp_bank_info from dbmon;
select object_name,object_type,owner,created from dba_objects where status='INVALID';
select * from v$process where spid=4438
select * from v$session where paddr='addr'
select sql_id,event from v$session where sid=
select sql_text from v$sqltext where sql_id='' order by piece;
--查看运行长的语句
select a.inst_id,a.sid,a.serial#,a.username,a.machine,a.event,a.SQL_id,a.sql_child_number,a.last_call_et,b.spid
from gv$session a,gv$process b
where a.status='ACTIVE'
and a.type<>'BACKGROUND'
and a.paddr=b.addr
and a.inst_id=b.inst_id
order by last_call_et desc;
select wm_concat(sql_text) from
(
select sql_text from v$sqltext
where sql_id='a8dkbv3nw81r0'
order by piece
)
--查看执行计划:
select * from gv$sql_plan
where sql_id='cr7jnm26mv0kp'
and child_number=0;
select * from table(dbms_xplan.display_awr('sql_id'));
select * from table(dbms_xplan.display_cursor('sql_id',null,'ADVANCED ALLSTATS LAST PEEKED_BINDS'));
select * from table(dbms_xplan.display_cursor('83ph8nr7xmq3x',9));
--查看绑定变量:
SELECT child_number,
name,
datatype_string,
character_sid,
last_captured,
value_string,
ANYDATA.accesstimestamp (value_anydata)
FROM V$SQL_BIND_CAPTURE
WHERE sql_id= '0ddtac23d8yf2'
SELECT snap_id,
NAME,
position,
value_string,
last_captured,
WAS_CAPTURED
FROM dba_hist_sqlbind
WHERE sql_id = 'c1j018vt5ajdu';
SELECT
dbms_sqltune.extract_bind(bind_data, 1).value_string AS a,
dbms_sqltune.extract_bind(bind_data, 2).value_string AS b
FROM wrh$_sqlstat
WHERE sql_id = 'c1j018vt5ajdu';
select sql_id,prev_sql_id from v$session
where paddr in
(
select addr from v$process
where spid=1782216
)
林建新 15:47:37
/* Formatted on 2015/4/27 15:42:31 (QP5 v5.185.11230.41888) */
SELECT *
FROM ( SELECT r.reportorphonenumber, r.reportorname, rp.companycode
FROM sinocore.gcregistmain r
INNER JOIN
sinocore.GCREGISTPOLICY rp
ON r.registno = rp.registno
WHERE rp.startdate <= SYSDATE AND rp.enddate > SYSDATE
ORDER BY r.reportdate DESC)
WHERE ROWNUM <= :1
--Oracle10g提供的脚本
@?/rdbms/admin/addmrpt.sql --获取ADDM报告
@?/rdbms/admin/addmrpti.sql --获取RAC下的ADDM报告
@?/rdbms/admin/awrrpt.sql --获取AWR报告
@?/rdbms/admin/awrrpti.sql --获取RAC下的AWR报告
@?/rdbms/admin/sqltrpt.sql --获取指定的sql的详细的信息和优化建议
@?/rdbms/admin/ashrpt.sql --等待事件以及top sql报告
@?/rdbms/admin/ashrpti.sql --RAC下的等待事件以及top sql报告
@?/rdbms/admin/dbfusrpt.sql --数据库特性使用情况汇总统计
@?/rdbms/admin/awrsqrpt.sql --获取指定的sql在指定的snapshot时间段内的详细执行信息
@?/rdbms/admin/awrddrpt.sql --两份awr报告之间的差异。
表数据分析
begin
dbms_stats.gather_table_stats(
ownname => 'comm',
tabname => 'PRODUCT_OFFER',
degree=> 8,
estimate_percent => 5,
cascade => TRUE,
no_invalidate => FALSE,
FORCE => TRUE ) ;
end ;
/
estimate_percent => 10, -- 默认:'DBMS_STATS.AUTO_SAMPLE_SIZE'
method_opt => 'FOR ALL COLUMNS SIZE AUTO' ); --默认:'FOR ALL COLUMNS SIZE AUTO'
no_invalidate => FALSE --表示执行计划立即采用新分析的数据,清空子游标
查找被kill掉的session的spid信息
select spid, program from v$process
where program!= 'PSEUDO'
and addr not in (select paddr from v$session)
and addr not in (select paddr from v$bgprocess);
select addr,spid,program from v$process where addr in
(
select p.addr from v$process p where pid <> 1 minus select s.paddr from v$session s
);
--找到这种状态为'KILLED'的操作系统进程号(SPID)呢
SELECT s.username,s.status,
x.ADDR,x.KSLLAPSC,x.KSLLAPSN,x.KSLLASPO,x.KSLLID1R,x.KSLLRTYP,
decode(bitand (x.ksuprflg,2),0,null,1)
FROM x$ksupr x,v$session s
WHERE s.paddr(+)=x.addr
and bitand(ksspaflg,1)!=0
and s.sid=37 ;
x$ksupr.ADDR列的值对应了V$PROCESS 中的ADDR的值,知道了这个SPID的地址:
select spid,pid from v$process where addr='C000000109C831E0';
--查询已经分配的系统权限
select * from dba_sys_privs where grantee='XIGUA';
--查询已经分配的对象权限
select * from dba_tab_privs where grantee='XIGUA';
select * from dba_col_privs where grantee='XIGUA';
--查询已经分配的角色
select * from dba_role_privs where grantee='XIGUA';
清理一条SQL执行计划
SQL> SELECT 'exec dbms_shared_pool.purge('''||ADDRESS||','||HASH_VALUE||''',''C'');' ,SQL_TEXT FROM V$SQLAREA WHERE SQL_ID = '3q5b552c4v7dg';
ADDRESS HASH_VALUE SQL_TEXT
1EFB91B8 3642190903 select count(*) from xff
SQL> exec dbms_shared_pool.purge('1EFB91B8, 3642190903','C');
PL/SQL 过程已成功完成。
SQL> SELECT ADDRESS,HASH_VALUE,SQL_TEXT FROM V$SQLAREA WHERE SQL_ID = '2hjuwpdamsxb5';
未选定行
清理二阶段事务锁
select * from DBA_2PC_PENDING;存在未决事务的时候有可能发生资源的锁等待ORA-01591的错误,可以按如下方式处理。
ALTER SYSTEM DISABLE DISTRIBUTED RECOVERY;
begin
rollback force '224.4.256'; commit;
end;
ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY;
begin
DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('224.4.256'); commit;
end;
重启RAC 11gR2
步骤 1 以root用户登录操作系统。
步骤 2 进入grid安装目录下的bin目录。
cd /opt/oracrs/product/11gR2/grid/bin
步骤 3 停止RAC数据库。
./crsctl stop crs
步骤 4 启动RAC数据库。
./crsctl start crs
步骤 5 检查CRS资源。
./crsctl check crs
系统返回类似如下信息:
CRS-4638: Oracle High Availability Services is online
CRS-4537: Cluster Ready Services is online
CRS-4529: Cluster Synchronization Services is online
CRS-4533: Event Manager is online
plan
Plan Hash Value : 2280399827
| Id | Operation | Name | Rows | Bytes | Cost | Time |
| 0 | INSERT STATEMENT | | 1 | 594 | 20 | 00:00:01 |
| 1 | LOAD TABLE CONVENTIONAL | T_L_SIM_CARD_STOCK_D | | | | |
| 2 | HASH GROUP BY | | 1 | 594 | 20 | 00:00:01 |
| * 3 | HASH JOIN OUTER | | 1 | 594 | 19 | 00:00:01 |
| * 4 | HASH JOIN OUTER | | 1 | 482 | 16 | 00:00:01 |
| * 5 | HASH JOIN | | 1 | 468 | 12 | 00:00:01 |
| 6 | MERGE JOIN CARTESIAN | | 1 | 144 | 4 | 00:00:01 |
| 7 | PARTITION LIST EMPTY | | 1 | 86 | 2 | 00:00:01 |
| * 8 | TABLE ACCESS FULL | T_L_CU_SUBSCRIBERBASEINFO_D | 1 | 86 | 2 | 00:00:01 |
| 9 | BUFFER SORT | | 1 | 58 | 2 | 00:00:01 |
| 10 | PARTITION LIST EMPTY | | 1 | 58 | 2 | 00:00:01 |
| * 11 | TABLE ACCESS FULL | T_S_CRM_AGENT | 1 | 58 | 2 | 00:00:01 |
| 12 | VIEW | | 1 | 324 | 8 | 00:00:01 |
| 13 | NESTED LOOPS OUTER | | 1 | 410 | 8 | 00:00:01 |
| * 14 | HASH JOIN | | 1 | 355 | 8 | 00:00:01 |
| 15 | PARTITION LIST ALL | | 1 | 165 | 3 | 00:00:01 |
| * 16 | TABLE ACCESS FULL | T_E_DEALER_TRANS_DETL_D2 | 1 | 165 | 3 | 00:00:01 |
| * 17 | TABLE ACCESS FULL | T_S_CRM_INFDEALER | 1 | 190 | 4 | 00:00:01 |
| 18 | TABLE ACCESS BY INDEX ROWID | T_S_CRM_RES_MSISDN | 1 | 55 | 0 | 00:00:01 |
| * 19 | INDEX RANGE SCAN | INDEX_MSISDN_CODE | 1 | | 0 | 00:00:01 |
| * 20 | TABLE ACCESS FULL | T_E_CRM_DIC_RES_MODEL | 1 | 14 | 3 | 00:00:01 |
| 21 | TABLE ACCESS FULL | T_M_DIM_TARIFFPLAN | 136 | 15232 | 3 | 00:00:01 |
Predicate Information (identified by operation id):
- 3 - access("T4"."TARIFFPLAN"="T7"."ID"(+))
- 4 - access("T6"."RES_TYPE_ID"(+)="from$_subquery$_006"."RES_TYPE" AND "T6"."MODEL_ID"(+)="from$_subquery$_006"."QCSJ_C000000000600003")
- 5 - access("T5"."DATA_DAY"=TO_CHAR(INTERNAL_FUNCTION("from$_subquery$_006"."QCSJ_C000000000400002"),'yyyymmdd') AND "T5"."AGENTID"="from$_subquery$_006"."QCSJ_C000000000400000" AND
"T4"."DAYCD"=TO_CHAR(INTERNAL_FUNCTION("T1"."DEALDATE"),'yyyymmdd') AND "T3"."MSISDN"="T4"."MSISDN") - 8 - filter("T4"."DAYCD"='20161218')
- 11 - filter("T5"."DATA_DAY"='20161218')
- 14 - access("T2"."DEALER_ID"="T1"."DEALER_ID")
- 16 - filter(("T1"."RES_TYPE"='60' OR "T1"."RES_TYPE"='61' OR "T1"."RES_TYPE"='65') AND TO_CHAR(INTERNAL_FUNCTION("T1"."DEALDATE"),'yyyymmdd')='20161218')
- 17 - filter("T2"."DEALER_LEVEL"='1' AND LOWER("T2"."DEALER_TYPE")='distributors')
- 19 - access("T3"."RES_CODE"(+)="T1"."RES_CODE")
- 20 - filter("T6"."RES_TYPE_ID"(+)='60' OR "T6"."RES_TYPE_ID"(+)='61' OR "T6"."RES_TYPE_ID"(+)='65')
Note
- dynamic sampling used for this statement
分布式事物处理方式
分布式事物处理方式
背景:创建一个对象,报错
ORA-01591: 此一鎖定目前是由有問題的分散式交易 3.0.1728 所持有
原因:该对象以前存在,drop之后重新创建,其他会话同时占用了该对象,导致创建失败
解决步骤:
常规办法
select * from dba_2pc_pending;
rollback force '3.0.1728';
提示找不到该分布式事物(具体代号已经删除),得知同事直接kill session了,导致该事物无法找到,而状态仍然保留。
网上找到如下办法,涉及基表修改,生产库需谨慎:
alter system disable distributed recovery;
insert into pending_trans$ (
LOCAL_TRAN_ID,
GLOBAL_TRAN_FMT,
GLOBAL_ORACLE_ID,
STATE,
STATUS,
SESSION_VECTOR,
RECO_VECTOR,
TYPE#,
FAIL_TIME,
RECO_TIME)
values( '3.0.1728', /* <== Replace this with your local tran id */
306206, /* */
'XXXXXXX.12345.1.2.3', /* These values can be used without any */
'prepared','P', /* modification. Most of the values are */
hextoraw( '00000001' ), /* constant. */
hextoraw( '00000000' ), /* */
0, sysdate, sysdate );
insert into pending_sessions$
values( '3.0.1728',/* <==Replace only this with your local tran id */
1, hextoraw('05004F003A1500000104'),
'C', 0, 30258592, '',
146
);
commit;
rollback force '3.0.1728';
然而仍然存在问题,最后将目标对象更名后重新创建,解决问题。
参考:
http://www.itpub.net/thread-1587520-1-1.html
https://forums.oracle.com/forums/thread.jspa?threadID=415195
bi
insert into dwhls.T_L_SIM_CARD_STOCK_D(
daycd ,
region_id ,
dist_dealer_id ,
dist_dealer_name ,
dist_master_sim ,
dealer_id ,
dealer_name ,
master_sim ,
sub_dealer_id ,
sub_dealer_name ,
sub_master_sim ,
dealer_type ,
dealer_level ,
tariff_type ,
tariff_plan ,
act_cnt ,
trans_cnt ,
income_cnt ,
procs_time
)
select/* +parallel(*,6) */
'20161218' as daycd ,
to_char(t5.zone) as region_id ,
t2.dealer_id as dist_dealer_id ,
t2.dealer_name as dist_dealer_name ,
t2.dealer_msisdn as dist_master_sim ,
'' as dealer_id ,
'' as dealer_name ,
'' as master_sim ,
'' as sub_dealer_id ,
'' as sub_dealer_name ,
'' as sub_master_sim ,
t2.dealer_type as dealer_type ,
t2.dealer_level as dealer_level ,
t1.res_type as tariff_type ,
t7.name as tariff_plan ,
count(case when to_char(t4.activedate,'yyyymmdd')='20161218'
then t4.subscriberid
else null end) as act_cnt ,
case when t1.transfer_src_dept=t2.dealer_id
and upper(t4.subsstatuscd)='B06'
then sum(t1.sale_amount)
else 0 end as trans_cnt ,
0 as income_cnt ,
sysdate as procs_time
from dwhedm.t_e_dealer_trans_detl_d2 t1
inner join dwhstg.t_s_crm_infdealer t2
on t2.dealer_id = t1.dealer_id
and lower(t2.dealer_type) = 'distributors'
and t2.dealer_level = '1'
and to_char(t1.dealdate,'yyyymmdd')='20161218'
left join dwhstg.t_s_crm_res_msisdn t3
on t3.res_code=t1.res_code
left join dwhls.t_l_cu_subscriberbaseinfo_d t4
on t3.msisdn=t4.msisdn
and to_char(t1.dealdate,'yyyymmdd')=t4.daycd
left join dwhstg.t_s_crm_agent t5
on t5.agentid=t1.dealer_id
and t5.data_day=to_char(t1.dealdate,'yyyymmdd')
left join dwhedm.t_e_crm_dic_res_model t6
on t6.model_id=t3.model_id
and t6.res_type_id in ('60','61','65')
and t6.res_type_id=t1.res_type
left join dwhdm.t_m_dim_tariffplan t7
on t4.tariffplan=t7.id
where t1.res_type in ('60','61','65')
and to_char(t1.dealdate,'yyyymmdd')='20161218'
and t4.daycd = '20161218' --- Added by mukesh to run query faster
and t5.data_day = '20161218' -- Added by mukesh to run query faster
group by t2.dealer_id,
t2.dealer_name,
t2.dealer_msisdn,
t2.dealer_type,
t2.dealer_level,
t7.name,
t4.subsstatuscd,
to_char(t4.activedate,'yyyymmdd'),
t1.transfer_src_dept,
t5.zone,
t1.res_type;
状态语句
--查询阻塞的依赖关系
with ash as (select /+ materialize/* from gv$active_session_history t
where sample_time between timestamp '2017-01-28 16:00:00' and timestamp '2017-01-28 16:30:00'),
chains as (
select session_id, level lvl,
sys_connect_by_path(sql_id || ' '||event, ' -> ') path,
connect_by_isleaf isleaf
from ash
start with event in ('enq: TM - contention','enq: TX - row lock contention' )
connect by nocycle (prior blocking_session = session_id and prior blocking_session_serial# = session_serial# and prior sample_id = sample_id))
select lpad(round(ratio_to_report(count()) over () * 100)||'%',5,' ') "%This",
count() samples,
path
from chains
where isleaf = 1
group by path
order by samples
--查看实际和理想的Undo size及undo_retention,用于解决ORA-01555
col "undo retention" format a20
select d.undo_size/(1024*1024) "Current Undo Size",
substr(e.value,1,25) "undo retention",
(to_number(e.value)*to_number(f.value)g.undo_block_per_sec)/(10241024) "necessary undo size",
d.undo_size/(g.undo_block_per_sec * to_number(f.value)) "ideal_undo_retention"
from (
select sum(a.bytes) undo_size from v$datafile a, v$tablespace b, dba_tablespaces c
where c.contents='UNDO'
and c.status='ONLINE'
and b.name=c.tablespace_name
and a.ts#=b.ts# ) d,
v$parameter e,
v$parameter f,
( select max(undoblks/((end_time-begin_time)360024)) undo_block_per_sec from v$undostat) g
where e.name='undo_retention'
and f.name='db_block_size';
--检查UNDO空间使用率
select a.tablespace_name,
used_undo,
total_undo,
trunc(used_undo / total_undo * 100, 2) || '%' used_rag
from (select nvl(sum(bytes / 1024 / 1024), 0) used_undo, tablespace_name
from dba_undo_extents
where status = 'ACTIVE'
group by tablespace_name) a,
(select tablespace_name, sum(bytes / 1024 / 1024) total_undo
from dba_data_files
where tablespace_name in
(select value
from v$spparameter
where name = 'undo_tablespace'
and (sid = (select instance_name from v$instance) or
sid = '*'))
group by tablespace_name) b
where a.tablespace_name = b.tablespace_name
--过去一段时间内的ash
select *
from dba_hist_active_sess_history t
where t.sample_time between
to_date('2017/03/06 15:10', 'yyyy/mm/dd hh24:mi') and
to_date('2017/03/06 15:14', 'yyyy/mm/dd hh24:mi');
--30分钟内按等待时间排序的语句
select ash.user_id,u.username,s.sql_text,sum(ash.wait_time+ash.time_waited) ttl_wait_time
from v$active_session_history ash,
v$sqlarea s,
dba_users u
where ash.sample_time between sysdate - 60/2880 and sysdate
and ash.sql_id=s.sql_id
and ash.user_id=u.user_id
group by ash.user_id,s.sql_text,u.username
order by ttl_wait_time
--等待和实际时间百分比
select metric_name, value from v$sysmetric
where metric_name in ('Database CPU Time Ratio','Database Wait Time Ratio')
and intsize_csec=(select max(intsize_csec) from v$sysmetric);
--连接用户【查询数据库以用户分组连接数】
select inst_id,username,count(*) from gv$session group by inst_id,username;
--参数检查【查询给定参数的设定值,中等规模设置1000】
select value from v$parameter where name='open_cursors';
--会话信息【实例当前会话数和启动最高连接会话数量】
select sessions_current,sessions_highwater from v$license;
--参数修改【修改初始化参数,RAC需要注意SID参数】
alter system set undo_retention=3600 comment='default 900' SID='*' scope=both;
--trace文件检查【获取会话或全局转储位置】
select value from v$diag_info where name='Default Trace File';
--归档维护
SQL> archive log list;
SQL> alter database archivelog;
--执行归档
alter system switch logfile;
--切换日志组,开始写入下一个日志组
alter system archive log current;
--对当前日志组进行归档,切换到下一个日志组,在RAC会对所有实例进行归档,thread参数指定归档实例。
--查询表空间使用情况
SELECT UPPER(F.TABLESPACE_NAME) "表空间名",
D.TOT_GROOTTE_MB "表空间大小(M)",
D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空间(M)",
TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') || '%' "使用比",
F.TOTAL_BYTES "空闲空间(M)",
F.MAX_BYTES "最大块(M)"
FROM (SELECT TABLESPACE_NAME,
ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES,
ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES
FROM SYS.DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME) F,
(SELECT DD.TABLESPACE_NAME,
ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB
FROM SYS.DBA_DATA_FILES DD
GROUP BY DD.TABLESPACE_NAME) D
WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME
ORDER BY 1
--查询回滚时间
SELECT KTUXEUSN, KTUXESLT, KTUXESQN,/* Transaction ID */
KTUXESTA Status, KTUXECFL Flags ,KTUXESIZ
FROM x$ktuxe
WHERE ktuxesta!='INACTIVE';
declare
l_start number;
l_end number;
begin
select ktuxesiz into l_start from x$ktuxe where KTUXEUSN=8 and KTUXESLT=31;
dbms_lock.sleep(60);
select ktuxesiz into l_end from x$ktuxe where KTUXEUSN=8 and KTUXESLT=31;
dbms_output.put_line('time est hour:'||round(l_end/(l_start - l_end)/60,2));
end;
参考:http://www.cnblogs.com/zfyouxi/p/3893217.html
http://www.cnblogs.com/macleanoracle/archive/2013/03/19/2967782.html
--300s以上长事物
select * from v$transaction_enqueue t where t.CTIME>301
--检查dds存在跨节点连接
select inst_id,username,substr(module,1,5),count() from gv$session
where substr(module,1,5) ='ddsse'
group by inst_id,username,substr(module,1,5)
order by count() desc
--redo切换频率
select * from
( select
substr(to_char(first_time, 'mm/dd/rr hh:mi:ss'),1,5) day
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'00',1,0)) h00
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'01',1,0)) h01
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'02',1,0)) h02
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'03',1,0)) h03
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'04',1,0)) h04
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'05',1,0)) h05
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'06',1,0)) h06
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'07',1,0)) h07
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'08',1,0)) h08
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'09',1,0)) h09
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'10',1,0)) h10
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'11',1,0)) h11
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'12',1,0)) h12
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'13',1,0)) h13
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'14',1,0)) h14
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'15',1,0)) h15
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'16',1,0)) h16
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'17',1,0)) h17
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'18',1,0)) h18
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'19',1,0)) h19
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'20',1,0)) h20
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'21',1,0)) h21
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'22',1,0)) h22
, sum(decode(substr(to_char(first_time, 'mm/dd/rr hh24:mi:ss'),10,2),'23',1,0)) h23
, count(*) total
from
v$log_history a where THREAD#=1
group by substr(to_char(first_time, 'mm/dd/rr hh:mi:ss'),1,5)
order by substr(to_char(first_time, 'mm/dd/rr hh:mi:ss'),1,5)
);
--按等待时间统计session
select event, count() from v$session
where status='ACTIVE' and wait_class<>'Idle'
group by event order by count() desc;
select * from v$session where event=:event;
--查看全部等待事件
Select count(), event
from v$session_wait
where event not in ('smon timer', 'pmon timer', 'rdbms ipc message',
'SQLNet message from client')
group by event
order by 1 desc;
select * from v$session where event=:event;
--查看session占用undo
SELECT s.username,
s.sid,
s.serial#,
t.used_ublk,
t.used_urec,
rs.segment_name,
r.rssize,
r.status
FROM v$transaction t,
v$session s,
v$rollstat r,
dba_rollback_segs rs
WHERE s.saddr = t.ses_addr
AND t.xidusn = r.usn
AND rs.segment_id = t.xidusn
ORDER BY t.used_ublk DESC;
select * from v$session where sid=:sid;
--session 使用redo情况
select ss.sid,ss.serial#,ss.username,t.redosize redosize_bytes,t.name
from v$session ss,
(
select ss.sid ,sn.name,ss.value redosize
from v$sesstat ss,v$statname sn
where ss.statistic#=sn.statistic# and sn.name='redo size'
and ss.value<>0
) t
where ss.username is not null
and ss.sid=t.sid
order by 4 desc;
select * from v$session where sid=:sid;
--session cpu 使用情况
select ss.sid,se.command,ss.value CPU ,se.username,se.program
from v$sesstat ss, v$session se
where ss.statistic# in
(select statistic# from v$statname
where name = 'CPU used by this session')
and se.sid=ss.sid and ss.sid>6 order by ss.value desc;
select * from v$session where sid=:sid;
--单个session占用CPU情况
select s.sid, w.event, w.wait_time, w.seq#, q.sql_text
from v$session_wait w, v$session s, v$process p, v$sqlarea q
where s.paddr = p.addr
and s.sid = :sid
and s.sql_address = q.address
--查看sql绑定变量
select name,position, t.datatype_string, value_string
from DBA_HIST_SQLBIND t
where t.sql_id = :sqlId
-- and snap_id = :snapId
order by position
--查看sql执行计划
SELECT * FROM TABLE(dbms_xplan.display_cursor(:sql_id, null, 'advanced allstats last peeked_binds'))
--查看sql awr执行计划
SELECT * FROM TABLE(dbms_xplan.display_awr(:sql_id))
/*
--当前session
SELECT USERENV('SID') FROM DUAL;
--执行计划
explain plan for :SQL;
select * from table(DBMS_XPLAN.display);
SELECT * FROM TABLE(dbms_xplan.display_awr(:sid, :plan_hash_value));
select * from DBA_HIST_SQLBIND where sql_id = '5dckzxzkp84s7'
*/
--获取删除一条sql执行计划的脚本
SELECT 'exec dbms_shared_pool.purge('''||ADDRESS||','||HASH_VALUE||''',''C'');'
,SQL_TEXT
FROM V$SQLAREA WHERE SQL_ID = :sql_id
--估算sql执行速度
select sid, SERIAL#, sql_id, ELAPSED_SECONDS, TIME_REMAINING, START_TIME
from V$SESSION_LONGOPS
where sql_id = :sql_id
order by START_TIME desc;
--查看所有sql全表扫描的
select ltrim(sql_text) from V$SQLAREA WHERE SQL_ID IN ( select distinct sql_id
from V$SQL_PLAN where OPERATION='TABLE ACCESS' and OPTIONS='FULL'
AND OBJECT_OWNER NOT IN ('SYS','SYSMAN','SYSTEM','MDSYS','WKSYS','DBSNMP'))
AND SQL_FULLTEXT NOT LIKE '/*%'
and MODULE like '%dds%'
--当前性能最差sql语句(SYS用户)
select /+ ordered / distinct sw.event, sw.sid,
s.KSUUDNAM username, s.KSUSEPNM program,
-- sw.state, sw.seconds_in_wait seconds,
sw.state, sw.wait_time seconds,
sw.p1, sw.p2, sw.p3, sa.kglnaobj last_sql
from sys.v$session_wait sw, sys.x$ksuse s, sys.x$kglob sa
where sw.event not in ('rdbms ipc message','smon timer','pmon timer',
'SQLNet message from client','SQLNet message to client',
'lock manager wait for remote message',
'ges remote message', 'client message', 'SQL*Net more data from client',
'pipe get', 'Null event', 'PX Idle Wait', 'single-task message',
'wakeup time manager')
and s.KSUUDNAM<>'SYS'
and (sw.sid = s.KSUSENUM)
and (s.KSUSESQH = sa.KGLNAHSH)
order by sw.event,sw.sid;
--单次大结果集sql
select a.sql_id,EXECUTIONS_DELTA, trunc(ROWS_PROCESSED_DELTA/EXECUTIONS_DELTA) result_count,b.sql_text from DBA_HIST_SQLSTAT a, v$sqlarea b
where ROWS_PROCESSED_DELTA/EXECUTIONS_DELTA>1000 and EXECUTIONS_DELTA>0 and SNAP_ID>=(select max(snap_id) from DBA_HIST_SQLSTAT)
and a.sql_id=b.sql_id;
--总计大结果集sql
select ROWS_PROCESSED_DELTA,EXECUTIONS_DELTA,a.* from DBA_HIST_SQLSTAT a where ROWS_PROCESSED_DELTA>10000 and EXECUTIONS_DELTA>0 and SNAP_ID=:snap_id order by 1 desc;
--3日IOPS总计
with query1 as(select to_char(es.BEGIN_INTERVAL_TIME,'YYYYMMDD HH24:MI') TIME1,b.instance_number,b.stat_name stat_name,
(e.value - b.value) TOTAL_VALUE,
(e.value - b.value)/((to_date(to_char(es.END_INTERVAL_TIME,'YYYYMMDD HH24:MI:SS'),'YYYYMMDD HH24:MI:SS')-to_date(to_char(bs.END_INTERVAL_TIME,'YYYYMMDD HH24:MI:SS'),'YYYYMMDD HH24:MI:SS'))243600) AVG_VALUE
from dba_hist_sysstat b,
dba_hist_sysstat e,
dba_hist_snapshot bs,
dba_hist_snapshot es
where b.snap_id = e.snap_id-1
and b.dbid = e.dbid
and b.instance_number = e.instance_number
and b.stat_id = e.stat_id
and e.value >= b.value
and e.value > 0
and b.stat_name in ('physical read total IO requests','physical write total IO requests')
and bs.snap_id=b.snap_id and es.snap_id=e.snap_id
and bs.dbid=b.dbid and es.dbid=e.dbid
and bs.instance_number = b.instance_number and es.dbid=e.dbid
-- and bs.snap_id=es.snap_id-1
and bs.instance_number=es.instance_number
and (b.instance_Number=:instance_no or :instance_no is null)
order by b.snap_id,b.instance_number)
select substr(time1,10,5),
sum(decode(substr(time1,1,8),to_char(trunc(sysdate),'YYYYMMDD'), round(avg_value,2),null)) today,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-1),'YYYYMMDD'), round(avg_value,2),null)) yesterday,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-2),'YYYYMMDD'), round(avg_value,2),null)) TBY
from query1
where time1>to_char(trunc(sysdate-2),'YYYYMMDD HH24:MI')
group by substr(time1,10,5);
--having substr(time1,10,5) between '08:00' and '18:00'
--三日dbtime
with query1 as(select to_char(es.BEGIN_INTERVAL_TIME,'YYYYMMDD HH24:MI') TIME1,b.instance_number,b.stat_name stat_name,
(e.value - b.value) TOTAL_VALUE,
(e.value - b.value)/((to_date(to_char(es.END_INTERVAL_TIME,'YYYYMMDD HH24:MI:SS'),'YYYYMMDD HH24:MI:SS')-to_date(to_char(bs.END_INTERVAL_TIME,'YYYYMMDD HH24:MI:SS'),'YYYYMMDD HH24:MI:SS'))243600) AVG_VALUE
from dba_hist_sysstat b,
dba_hist_sysstat e,
dba_hist_snapshot bs,
dba_hist_snapshot es
where b.snap_id = e.snap_id-1
and b.dbid = e.dbid
and b.instance_number = e.instance_number
and b.stat_id = e.stat_id
and e.value >= b.value
and e.value > 0
and b.stat_name in ('DB time')
and bs.snap_id=b.snap_id and es.snap_id=e.snap_id
and bs.dbid=b.dbid and es.dbid=e.dbid
and bs.instance_number = b.instance_number and es.dbid=e.dbid
and bs.snap_id=es.snap_id-1
and bs.instance_number=es.instance_number
and (b.instance_Number=:instance_no or :instance_no is null)
order by b.snap_id,b.instance_number)
select substr(time1,10,5),
sum(decode(substr(time1,1,8),to_char(trunc(sysdate),'YYYYMMDD'), round(avg_value,2),null)) today,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-1),'YYYYMMDD'), round(avg_value,2),null)) yesterday,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-2),'YYYYMMDD'), round(avg_value,2),null)) TBY
from query1
where time1>to_char(trunc(sysdate-2),'YYYYMMDD HH24:MI')
group by substr(time1,10,5)
--having substr(time1,10,5) between '08:00' and '18:00'
--3日CLOB sql
with query1 as
(select to_char(b.END_INTERVAL_TIME,'yyyymmdd hh24:mi') time1, sum(EXECUTIONS_TOTAL) countval from DBA_HIST_SQLSTAT a, dba_hist_snapshot b where SQL_ID in ('a0jrv3szpcp4n','3yxk2fgrknh3y')
and a.SNAP_ID=b.snap_id group by to_char(b.END_INTERVAL_TIME,'yyyymmdd hh24:mi')
)
select substr(time1,10,5),
sum(decode(substr(time1,1,8),to_char(trunc(sysdate),'YYYYMMDD'), countval,null)) today,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-1),'YYYYMMDD'), countval,null)) yesterday,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-2),'YYYYMMDD'), countval,null)) TBY
from query1
where time1>to_char(trunc(sysdate-2),'YYYYMMDD HH24:MI')
group by substr(time1,10,5)
--3日物理读写(block)
with query1 as(select to_char(bs.BEGIN_INTERVAL_TIME,'YYYYMMDD HH24:MI') TIME1,b.instance_number,b.stat_name stat_name,
(e.value - b.value) TOTAL_VALUE,
(e.value - b.value)/((to_date(to_char(es.END_INTERVAL_TIME,'YYYYMMDD HH24:MI:SS'),'YYYYMMDD HH24:MI:SS')-to_date(to_char(bs.END_INTERVAL_TIME,'YYYYMMDD HH24:MI:SS'),'YYYYMMDD HH24:MI:SS'))243600) AVG_VALUE
from dba_hist_sysstat b,
dba_hist_sysstat e,
dba_hist_snapshot bs,
dba_hist_snapshot es
where b.snap_id = e.snap_id-1
and b.dbid = e.dbid
and b.instance_number = e.instance_number
and b.stat_id = e.stat_id
and e.value >= b.value
and e.value > 0
and b.stat_name in ('physical reads','physical writes')
and bs.snap_id=b.snap_id and es.snap_id=e.snap_id
and bs.dbid=b.dbid and es.dbid=e.dbid
and bs.instance_number = b.instance_number and es.dbid=e.dbid
and bs.snap_id=es.snap_id-1
and bs.instance_number=es.instance_number
order by b.snap_id,b.instance_number)
select substr(time1,10,5),
sum(decode(substr(time1,1,8),to_char(trunc(sysdate),'YYYYMMDD'), round(avg_value,2),null)) today,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-1),'YYYYMMDD'), round(avg_value,2),null)) yesterday,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-2),'YYYYMMDD'), round(avg_value,2),null)) TBY
from query1
where time1>to_char(trunc(sysdate-2),'YYYYMMDD HH24:MI')
group by substr(time1,10,5)
having substr(time1,10,5) between '08:00' and '18:00'
--3日redo stats
with query1 as(select to_char(es.BEGIN_INTERVAL_TIME,'YYYYMMDD HH24:MI') TIME1,b.instance_number,b.stat_name stat_name,
(e.value - b.value) TOTAL_VALUE,
(e.value - b.value)/((to_date(to_char(es.END_INTERVAL_TIME,'YYYYMMDD HH24:MI:SS'),'YYYYMMDD HH24:MI:SS')-to_date(to_char(bs.END_INTERVAL_TIME,'YYYYMMDD HH24:MI:SS'),'YYYYMMDD HH24:MI:SS'))243600) AVG_VALUE
from dba_hist_sysstat b,
dba_hist_sysstat e,
dba_hist_snapshot bs,
dba_hist_snapshot es
where b.snap_id = e.snap_id-1
and b.dbid = e.dbid
and b.instance_number = e.instance_number
and b.stat_id = e.stat_id
and e.value >= b.value
and e.value > 0
and b.stat_name in ('redo size')
and bs.snap_id=b.snap_id and es.snap_id=e.snap_id
and bs.dbid=b.dbid and es.dbid=e.dbid
and bs.instance_number = b.instance_number and es.dbid=e.dbid
and bs.snap_id=es.snap_id-1
and bs.instance_number=es.instance_number
and (b.instance_Number=:instance_no or :Instance_no is null)
order by b.snap_id,b.instance_number)
select substr(time1,10,5),
sum(decode(substr(time1,1,8),to_char(trunc(sysdate),'YYYYMMDD'), round(avg_value,2),null)) today,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-1),'YYYYMMDD'), round(avg_value,2),null)) yesterday,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-2),'YYYYMMDD'), round(avg_value,2),null)) TBY
from query1
where time1>to_char(trunc(sysdate-2),'YYYYMMDD HH24:MI')
group by substr(time1,10,5)
having substr(time1,10,5) between '08:00' and '18:00'
--3日execute count
with query1 as(select to_char(es.BEGIN_INTERVAL_TIME,'YYYYMMDD HH24:MI') TIME1,b.instance_number,b.stat_name stat_name,
(e.value - b.value) TOTAL_VALUE,
(e.value - b.value)/((to_date(to_char(es.END_INTERVAL_TIME,'YYYYMMDD HH24:MI:SS'),'YYYYMMDD HH24:MI:SS')-to_date(to_char(bs.END_INTERVAL_TIME,'YYYYMMDD HH24:MI:SS'),'YYYYMMDD HH24:MI:SS'))243600) AVG_VALUE
from dba_hist_sysstat b,
dba_hist_sysstat e,
dba_hist_snapshot bs,
dba_hist_snapshot es
where b.snap_id = e.snap_id-1
and b.dbid = e.dbid
and b.instance_number = e.instance_number
and b.stat_id = e.stat_id
and e.value >= b.value
and e.value > 0
and b.stat_name in ('execute count')
and bs.snap_id=b.snap_id and es.snap_id=e.snap_id
and bs.dbid=b.dbid and es.dbid=e.dbid
and bs.instance_number = b.instance_number and es.dbid=e.dbid
and bs.snap_id=es.snap_id-1
and bs.instance_number=es.instance_number
and (b.instance_Number=:instance_no or :instance_no is null)
order by b.snap_id,b.instance_number)
select substr(time1,10,5),
sum(decode(substr(time1,1,8),to_char(trunc(sysdate),'YYYYMMDD'), round(avg_value,2),null)) today,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-1),'YYYYMMDD'), round(avg_value,2),null)) yesterday,
sum(decode(substr(time1,1,8),to_char(trunc(sysdate-2),'YYYYMMDD'), round(avg_value,2),null)) TBY
from query1
where time1>to_char(trunc(sysdate-2),'YYYYMMDD HH24:MI')
group by substr(time1,10,5)
--having substr(time1,10,5) between '08:00' and '18:00'
ORACLE数据库DATAGUARD案例集锦
目 录
ORACLE数据库DATAGUARD案例集锦 1
1 基础知识 5
1.1 Dataguard 概念介绍 5
1.1.1 Data Guard类型 5
1.1.2 保护模式 5
1.1.3 ADG(Active DataGuard) 5
1.1.4 Apply Service与Redo Apply、Real-Time Apply 6
1.2 Dataguard主要参数解释 6
1.2.1 参数db_unique_name 6
1.2.2 log_archive_config 6
1.2.3 log_archive_dest_n 7
1.2.4 log_archive_max_processes 10
1.2.5 FAST_START_PARALLEL_ROLLBACK 10
1.2.6 LOG_ARCHIVE_MIN_SUCCEED_DEST 10
1.2.7 LOG_ARCHIVE_DEST_STATE_n 10
1.2.8 STANDBY_FILE_MANAGEMENT 10
1.3 Dataguard安装配置 11
1.3.1 系统规划 11
1.3.2 配置手工切换的DG 11
1.4 Dataguard后台进程 11
1.5 Dataguard监控 12
1.5.1 监控 physical standby 12
1.5.2 监控 primary 13
1.6 Dataguard切换 14
1.6.1 概念描述 14
1.6.2 SWITCHOVER 14
1.6.3 FAILOVER 15
1.6.4 Failover后重建容灾端 17
1.7 Dataguard配置信息收集 19
2 ORACLE数据库Dataguard案例分析 20
2.1 DataGuard容灾ORA-01274 ORA-01119错误解决办法 20
2.2 关于Oracle10g Dataguard数据同步后无法打开Standby database 21
2.3 因存储异常导致数据库Data Guard容灾异常 23
2.4 参数设置错误导致dataguard灾备数据库日志应用异常 24
2.5 Dataguard备库手工同步方法之一 26
2.6 ASM dataguard 容灾重做 27
2.7 设置log_archive_dest_2时提示db_unique_name不存在 29
2.8 权限不足 29
2.9 基线后容灾端DB不能mount 30
2.10 基线时错误RMAN-11003 31
2.11 基线时错误RMAN600 32
2.12 基线时错误ORA-17628 32
2.13 生产端Lost_Write问题的处理方法 34
2.14 生产端关闭时错误信息1089 35
2.15 容灾端RFS发生600错误 35
2.16 基线错误ORA-12577 36
2.17 错误ORA-01122 38
2.18 MRP占用很高CPU 39
1 基础知识
1.1 Dataguard 概念介绍
1.1.1 Data Guard类型
有三种standby模式:逻辑standby、物理standby、Snapshot。
物理std与主节点的完全一致,通过传输redo日志或arch日志达到主备节点的完全一致。 逻辑std建立之初与主节点完全一致,之后可以被修改,如增加表、用户等。通过将主节点的SQL语句传输到备节点上并执行来达到局部逻辑上的同步。Snapshot:可与物理std互相转换。在Snapshot模式下,只接受并归档redo日志,但不apply,直到再切换回物理std模式。
- 物理standby:容灾端是生产端的一个完全的copy,与生产端拥有相同的物理结构,生产端通过传输redo信息到容灾端并在容灾端获得apply,以保持两端的同步。容灾端最多可以read only的方式打开,可以查询,但不能read write。
- 逻辑stnadby:容灾端与生产端的物理结构不同,表结构都可以不同,可以read write,容灾端通过执行从生产端传递过来的redo中的sql语句以保持生产端做的sql在容灾端都执行到了。容灾端上依赖于生产端的那些表是read only,其他表可以是read write。
逻辑standby还有一个好处是,可以滚动升级,而不需要关闭DB; - 快照snapshot standby:snapshot standby是从物理standby转换过来的,它也接受从生产端传输来的redo日志,但是不apply。只有当需要将snapshot standby转换为physical standby时才去apply所有的日志。
1.1.2 保护模式
有三种保护模式:Max Availability、Max Performance、Max Protection,分别如下:
1. 最大性能模式:只要生产库的REDO数据写入到了REDO日志中,那么commit语句就可返回成功提示,而无需考虑REDO是否传输到了容灾端。REDO日志异步地传送到容灾端,因此生产端的性能几乎没有受到影响。这个DG的默认模式
2. 最大保护模式:此模式可确保0数据丢失,在commit返回成功提示前,REDO数据不仅要写入REDO LOG文件中,而且必须至少传输到一个同步的容灾端。如果任何一个同步的容灾端都无法传输到,生产库将被关闭。
3. 最大可用模式:正常情况下他以最大保护模式工作,但是如果日志无法传递到任何一个同步的容灾端时,他自动转换为最大性能模式,以确保生产端不会被关闭。
1.1.3 ADG(Active DataGuard)
ADG是容灾DB在open read only状态下仍可接受并apply日志的模式。
只要容灾端接受到的日志都已经做了apply动作,那么就可以alter database open read only,例如生产端最新的日志是199,容灾端接受到180并且apply到180,那么此时容灾DB是可以open red only的,只不过容灾DB的状态位于180号日志的状态。
1.1.4 Apply Service与Redo Apply、Real-Time Apply
Apply service是指将生产端的日志应用到容灾端。对于物理stanby,apply service就是redo apply,对于逻辑standby,apply service就是sql apply。
物理standby是通过传输redo文件到容灾端的standby redo log来实现同步。一般情况下,只有等当前的standby redo log归档后,其中的内容才可被MRP进程获取并应用。这就是所谓的redo apply。
如果启用了real-teim apply功能,那么每当有新的内容写入standby redo log中,MRP进程即刻(与参数log_archive_dest_2中的delay设定无关)将他们应用到容灾库中,而不需要等到它归档后。
1.2 Dataguard主要参数解释
1.2.1 参数db_unique_name
DB_UNIQUE_NAME属性是为某个数据库指定唯一的数据库名称,这就使得动态添加standby到包含RAC结构的primary数据库的dg配置成为可能,并且对于log_archive_dest_n中的service属性,其值对应的也必然是db_unique_name,也正因有了db_unique_name,redo数据在传输过程中才能确认传输到希望被传输到的数据库上。
如果两个库拥有相同的db_uniqeu_name值,他们是不能互相通信的。
在视图v$database中有字段primary_db_unique_name,生产端这个字段的值为容灾端的db_unique_name(表示容灾切换后的关系,而非现在的关系),容灾端这个字段的值为它所对应的生产端的db_uniqeu_name。
1.2.2 log_archive_config
要保障传输redo数据到指定服务器,除了db_unique_name,log_archive_dest_n之外,还有一个初始化参数:log_archive_config。
参数log_archive_config包括几个属性,可以用过控制数据库的传输和接收,SEND, NOSEND, RECEIVE, NORECEIVE。SEND允许数据库发送数据到远端,RECEIVE则允许standby接收来自其它数据库的数据,NOSEND,NORECEIVE自然就是禁止。 例如,设置primary数据库不接收任何归档数据,可以做如下的设置: LOG_ARCHIVE_CONFIG='NORECEIVE,DG_CONFIG=(jssweb,jsspdg)' 。注意,一旦做了如上的设置,那么假设该服务器发生了角色切换,那它仍然也没有接收redo数据的能力。
这个参数不可以动态修改。
该参数的配置可以从视图V$DATAGUARD_CONFIG中查询到。
1.2.3 log_archive_dest_n
对于data guard而言,核心是是LOG_ARCHIVE_DEST_n。它不仅控制着传输redo数据到其它数据库,同时还管理着由于网络中断造成的归档文件未接收的过程。
定义log_archive_dest_n中有很多子句,如果是dest_1那么,一般就是location=/path,如果是dataguard中,那么会多valid_for。对于归档失败的处理,LOG_ARCHIVE_DEST_1参数有几个属性可以用来控制一旦向归档过程中出现故障时应该采取什么措施。
_dest_1的子句:
- LOCATION:表示本地归档路径。对于log_archive_dest_n参数,要么指定LOCATION表示归档到本地,要么指定SERVICE归档到远程容灾端目录。如果本地归档到flashback area中,则设置LOCATION= USE_DB_RECOVERY_FILE_DEST
- REOPEN 指定时间后再次尝试归档。使用REOPEN=seconds(默认=300)属性,在指定时间重复尝试向归档目的地进行归档操作,如果该参数值设置为0,则一旦失败就不会再尝试重新连接并发送,直到下次redo数据再被归档时会重新尝试,不过并不会归档到已经失败的归档目的地,而是向替补的归档目的地发送。
- ALTERNATE 指定替补的归档目的地
alternate属性定义一个替补的归档目的地,所谓替补就是一旦主归档目的地因各种原因无法使用,则临时向alternate属性中指定的路径写。
需要注意一点,reopen的属性会比alternate属性优先级要高,如果你指定reopen属性的值>0,则lgwr/arch会首先尝试向主归档目的地写入,直到达到最大重试次数,如果仍然写入失败,才会向alternate属性指定的路径写。 - MAX_FAILURE 控制失败尝试次数
max_failure属性指定一个最大失败尝试次数,一般它与reopen配合使用,reopen指定失败后重新尝试的时间周期,max_failure则控制失败尝试的次数,如例: LOG_ARCHIVE_DEST_1='LOCATION=E:\jsspdg\ REOPEN=60 MAX_FAILURE=3'.
_dest_2的子句:
_dest_2的子句会复杂很多。下面分别介绍: - SERVICE:指定日志传送到的目标节点的参数service的值。一般等于对方的db_unique_name。是必须在参数的开头部分定义的子句。每个log_archive_dest_n中都必须以location或service开头。
- DB_UNIQUE_NAME:指定日志归档目的地的DB_UNIQUE_NAME的值,此值必须包含在参数log_archive_config参数的值中,否则会报错。如果log_archive_dest_1归档到本地,那么这个参数可以不指定,默认为生产端的参数db_unique_name的值。如果log_archive_dest_2归档到容灾端,那么这个子句必须设置为容灾端的参数db_unique_name的值。
- ARCH、LGWR:指定是在ARCH进程工作时传输归档日志到备机,还是在LGWR工作时传输REDO日志到备机。默认为ARCH。
- ASYNC、SYNC:当使用LGWR进程去传递日志的时候,网络IO同步还是异步的。默认(或没有设置)是异步的。
SYNC含义就是网络IO与目的地是同步的。也就是说每当启动一个IO时,LGWR会等待该IO完成才能继续处理。当需要建立无数据损失的环境的时候,需要指定Sync属性,因为该属性可以保证日志信息准确的传输到了备库节点。
当使用LGWR传输日志的时候,如果有多个备库节点,当设置SYNC=NOPARALLE,那么LGWR必须等待一个目的地址的IO完成才能写下一个IO地址,也就是每个地址是顺序写的。如果指定SYNC=PARALLE,其实IO就是异步的,也就是多个目的地址可以同时进行IO操作,但是同样,LGWR也需要等待每个目的地的IO完成后才能继续处理。ASYNC[=blocks] (默认值是2048,块的个数),指定为每个地址异步执行IO。LGWR不检查本次IO操作是否完成,直接可以继续处理下一个IO请求。使用异步IO可以使备库的环境对主库性能影响最小。2048是指在SGA中网络缓冲的大小。 - Delay:指定物理standby上(非real time apply模式),当standby rede log的日志归档后,是立即应用到备用数据库还是等待一段时间后(lap)才应用该归档日志。在最大保护模式,该参数设置无效。延迟日志应用可以防止主库的错误操作立即应用到备库中去。单位为分钟。如果写了delay但没有继续指定值,那么默认为30。如果没有写delay子句,那么默认为0,无延时。如果启用了real time apply,那么此参数的设置就被忽略。设置此参数后,容灾端做failover需要的时间会变长。
执行以下命令可以临时取消延时:
SQL>alter database recover managed standby database nodelay; - REOPEN:设置自动重新企图连接到归档目的地前的最小时间间隔(秒)。它应与max_failure搭配使用。不要为LOCATION的dest设置reopen,否则生产库可能会挂住。
- MAX_FAILURE:主节点向备节点传递日志的请求次数
- NOAFFIRM,AFFIRM:如果是NOAFFIRM,那么只要容灾端RFS接受到生产端传递来的日志,生产端即可获得到回音。但如果是AFFIRM,则必须将RFS进程所接受到的日志写入到容灾端的standby redo log文件中,生产端才能有回音。
如果设置为AFFIRM,则可能生产端启动时都需要检查容灾端的状态。
如果不指定,那么如果设置了ASYNC则默认为NOAFFIRM,如果设置了SYNC则默认为AFFIRM。
设置了ASYNC,建议不要设置AFFIRM,以后逐渐的不支持这样做。 - OPTIONAL、MANDATORY:如果为OPTIONAL则表示生产端不需要确定dest_2归档成功即可将这个redo文件重用。如果设置为MANDATORY则表示这个路径下归档失败时,生产端相应的redo就不能被重用覆盖。如果不指定,则默认为OPTIONAL。如果参数LOG_ARCHIVE_MIN_SUCCEED_DEST设置为3,而属性为mandatory的有5个,还有一个location的dest,那么当location和2个mandatory的dest归档成功时,redo就可被重用。LOG_ARCHIVE_MIN_SUCCEED_DEST的值不能大于mandatory的dest个数与location的dest个数的和。
- VALID_FOR=(redo_log_type, database_role):
配合其redo_log_type,database_role属性,为指定角色设置日志文件的归档路径,主要目的是为了辅助一旦发生角色切换操作后数据库的正常运转。 redo_log_type可设置为ONLINE_LOGFILE,STANDBY_LOGFILE,ALL_LOGFILES,分别表示这个归档dest可以接受online redo文件归的档、standby redo log文件归的档、所有归档文件;database_role可设置为PRIMARY_ROLE,STANDBY_ROLE,ALL_ROLES,分别表示此归档dest可以接受生产库的归档、容灾库的归档、不论数据库是什么角色的归档。注意valid_for参数是有默认值的,如果不设置的话,其默认值等同于:valid_for=(ALL_LOGFILES,ALL_ROLES) 。
推荐主动设置该参数而不要使用默认值,某些情况下默认的参数值不一定合适,比如逻辑standby就不像物理standby,逻辑standby处于open模式,不仅有redo数据而且还包含多种日志文件(online redologs,archived redologs以及standby redologs)。多数情况下,逻辑standby生成的online redologs与standby redologs生成在相同的目录内。因此,推荐你对每个*dest设置合适的valid_for属性。 - VERIFY:指定ARCn进程是否去扫描并检查归档日志的完整性。默认为不检查。
- NET_TIMEOUT:设置主机上LGWR等待LNSn进程相应的秒数,如在此时间内没有响应,则报错。默认是180秒。仅对同步LGWR模式有效。视图v$redo_dest_resp_histogram记录了SYNC模式下,传输redo信息到目的地的响应时间的历史值,可根据此视图调整此参数的设置。
- COMPRESSION:在往容灾端传输redo gap前先将要传输的内容压缩,以减少对网络带宽的压力。正常传输时,此参数无效。
- MAX_CONNECTIONS:用于指定传输redo gap时应开启几个session并行进行。
三中不同的模式,配置要求如下:
issue | 最大保护 | 最大可用 | 最大性能 |
---|---|---|---|
REDO写进程 | LGWR | LGWR | LGWR或ARCH |
网络传输模式 | SYNC | SYNC | LGWR进程时SYNC或ASYNC,ARCH进程时SYNC |
磁盘写操作 | AFFIRM | AFFIRM | AFFIRM或NOAFFIRM |
是否需要standby redologs | YES | YES | 可没有但推荐有 |
各个参数适用的场景:
子句 | 最大保护 | 最大可用 | 最大性能 |
---|---|---|---|
ASYNC / SYNC | SYNC | SYNC/ASYNC | ASYNC |
DELAY | / | / | Real time redo apply时无效 |
MAX_FAILURE | Y | Y | / |
NET_TIMEOUT | Y | Y | / |
NOAFFIRM / AFFIRM | AFFIRM | AFFIRM | NOAFFIRM |
OPTIONAL/MANDATORY | MANDATORY | MANDATORY | OPTIONAL |
VERIFY | Y | Y | Y |
SERVICE | 必须 | 必须 | 必须 |
DB_UNIQUE_NAME | 必须 | 必须 | 必须 |
VALID_FOR | 必须 | 必须 | 必须 |
COMPRESSION | 仅对redo gap有效 | 仅对redo gap有效 | 仅对redo gap有效 |
MAX_CONNECTIONS | 仅对redo gap有效 | 仅对redo gap有效 | 仅对redo gap有效 |
1.2.4 log_archive_max_processes
此参数指定ARCH进程的个数。可以动态修改。DG中此参数至少应大于4。
1.2.5 FAST_START_PARALLEL_ROLLBACK
设置对于一个事务做recover时的并行度。可以设置为FALSE,表示完全没有并行。LOW(默认设置)表示低度并行,并行度为2 * CPU_COUNT。也可以设置为HIGH,并行度为4 * CPU_COUNT。
1.2.6 LOG_ARCHIVE_MIN_SUCCEED_DEST
此参数说明至少有几个归档路径归档成功后才能覆写联机日志文件,此参数和归档路径参数联用。
如果使用最大性能模式,则此参数应设置为1,而不是2,否则必须要dest_2也成功才行,这与最大性能模式有冲突。
1.2.7 LOG_ARCHIVE_DEST_STATE_n
此参数与log_archive_dest_n配置使用,表示归档路径的状态。默认值为ENABLE,表示可以归档,如果要使归档路径失效,那么应设置对应的state参数为DEFER。
此参数的另外一个值为ALTERNATE,表示当主归档路径失败时,就启动此参数指定的归档路径。
此参数被修改后,当前REDO的sequence还是不受影响的,只有等日志发生切换后对新的序列才能生效。
1.2.8 STANDBY_FILE_MANAGEMENT
这个参数在容灾端设置,用于控制当生产库的数据文件发生的变化(如新增、drop或大小改变),能否自动传送并应用到容灾库中。可选值有AUTO、MANUAL。
如果设置为AUTO,那么如果要新增加表空间或数据文件,应在生产和容灾端分别做好DG或要使用的LV,然后在生产端执行SQL语句。如果要删除表空间,那么可以在生产端直接执行drop tablespace *** including contents and datafiles,这样可以将两边的表空间及数据文件都删除掉。如果仅仅执行drop tablespace ***,那么必须等REDO在容灾端应用后(表空间被删除了),先将容灾端的数据文件rm掉,然后确认没有问题后,再将生产的这个数据文件rm掉。
特别注意:如果是以LVM、ASM或文件系统管理存储,那么在生产端做数据文件管理前必须确保容灾端有相应的LV或DG或文件目录。否则REDO APPLY时会因设备不存在而失败。
如果已经因设备不存在而失败,则补救措施如下:
- 建立LV或DG或目录,并设置好权限。这里例如为/dev/raw/raw101
- 在容灾端执行以下查询,找出生产端传到容灾端在$ORACLE_HOME/dbs目录下生成的临时的数据文件名,这里例如为/oracle/dbs/u007.dbf:
SQL> select name from v$datafile;
- 执行以下命令修改数据库为手工管理standby的文件:
SQL> alter system set STANDBY_FILE_MANAGEMENT=MANUAL;
- 重新定义数据文件:
SQL> alter database create datafile ‘/oracle/dbs/u007.dbf’ as ‘/dev/raw/raw101’;
- 执行以下命令:
SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;
SQL> RECOVER MANAGED STANDBY DATABASE DISCONNECT;
1.3 Dataguard安装配置
详细安装过程,参考产品线发布的Dataguard 安装配置指导。主要包容如下几个要素:
1.3.1 系统规划
包括主备节点的要求、网络规划、数据库参数规划。
1.3.2 配置手工切换的DG
包括配置生产端的归档模式、将重要文件拷贝到容灾端、在容灾端建立实例需要的目录、NET配置、参数文件配置、在容灾端创建standby redo log、对容灾端做基线、打开DG、打开ADG。
1.4 Dataguard后台进程
RFS:remote file server. On the standby system, the remote file server (RFS) receives redo data over the network from the LGWR process and writes the redo data to the standby redo log files.
Fetch archive log (FAL) process (physical standby databases only): FAL提供一个client/server的机制来检测主备机上的归档是否有间断。由standby上的FAL client和和primary上FAL server来实现此工作。由FAL_CLIENT和FAL_SERVER参数决定primary database和standby database。
On the standby location,log transport services使用下面的进程:
LNSn:On the primary database, the LGWR process submits the redo data to one or more network server (LNSn) processes, which then initiate the network I/O in parallel to multiple remote destinations.
MRP: managed recovery process. The managed recovery process (MRP) applies archived redo log files to the physical standby database,and automatically determines the optimal number of parallel recovery processes at the time it starts. The number of parallel recovery slaves spawned is based on the number of CPUs available on the standby server.
LSP:logical standby process. The logical standby process (LSP) uses parallel execution (Pnnn) processes to apply archived redo log files to the logical standby database, using SQL interfaces.
1.5 Dataguard监控
1.5.1 监控 physical standby
SQL> select open_mode from v$database;
SQL> select sequence#,applied from v$archived_log order by sequence#;
SQL>select process,status,thread#,sequence#,block#,blocks from v$managed_standby;
SQL> select process,status from v$managed_standby;
一、NON-RAC
1、计算在physical standby中有多少日志没有进行介质恢复
(1)连接standby库,返回最后一个apply的归档日志的sequence#,记为laseq
SELECT MAX(SEQUENCE#) FROM V$ARCHIVED_LOG WHERE APPLIED = 'YES';
(2)获得最后一个完成的归档日志的sequence#,记为lrseq
SELECT MIN(SEQUENCE#)
FROM V$ARCHIVED_LOG
WHERE ((SEQUENCE# + 1) NOT IN (SELECT SEQUENCE# FROM V$ARCHIVED_LOG))
AND (SEQUENCE# >= &LASEQ);
(3)(lrseq - laseq)就表示还没apply到standby库的归档日志的数量
2、潜在的数据丢失窗口
(1)连接到主库,获得当前日志的sequence#,记为curseq
SELECT SEQUENCE# FROM V$LOG WHERE STATUS = 'CURRENT';
(2)(curseq - lrseq)就表示standby库需要介质恢复的归档日志数
备注:
1、curseq-lrseq=1表示没有数据丢失
2、查询v$archive_dest_status的PROTECTION_MODE 字段,返回值是RESYNCHRONIZATION
表示有数据丢失。
二、RAC
SELECT MAX(SEQUENCE#), THREAD# FROM V$ARCHIVED_LOG GROUP BY THREAD#;
三、Physical Standby Database Queries
1、三个小时前应用的archive
SELECT TO_CHAR(FIRST_TIME, ' dd-mon-yyyy HH:MI:SS') FIRST_TIME,
TO_CHAR(SYSDATE, 'dd-mon-yyyy HH:MI:SS') CURRENT_TIME,
SEQUENCE#,
THREAD#
FROM V$LOG_HISTORY
WHERE FIRST_TIME > (SYSDATE - 1 / 8);
2、检查数据文件
SELECT *
FROM V$DATAFILE_HEADER
WHERE STATUS = 'OFFLINE'
OR ERROR IS NOT NULL;
3、Media Recovery Process是否运行
SELECT * FROM V$MANAGED_STANDBY WHERE PROCESS LIKE 'MRP%';
4、查询昨天发生的event
SELECT *
FROM V$DATAGUARD_STATUS
WHERE SEVERITY IN ('Error', 'Fatal')
AND TIMESTAMP > (SYSDATE - 1);
1.5.2 监控 primary
1、检查远程(standby)的归档目录
SELECT DEST_ID, STATUS, TARGET, DESTINATION, ERROR
FROM GV$ARCHIVE_DEST
WHERE TARGET = 'STANDBY'
AND STATUS != 'VALID'
OR ERROR IS NOT NULL;
2、前一天是否有nologging操作
SELECT FILE#, NAME, UNRECOVERABLE_CHANGE#, UNRECOVERABLE_TIME
FROM V$DATAFILE
WHERE UNRECOVERABLE_TIME > (SYSDATE - 1);
3、检测gap
SELECT LOCAL.THREAD#, LOCAL.SEQUENCE#
FROM (SELECT THREAD#, SEQUENCE# FROM GV$ARCHIVED_LOG WHERE DEST_ID = 1) LOCAL
WHERE LOCAL.SEQUENCE# NOT IN
(SELECT SEQUENCE#
FROM GV$ARCHIVED_LOG
WHERE DEST_ID = 2
AND THREAD# = LOCAL.THREAD#);
4、检查前一天的event
SELECT *
FROM V$DATAGUARD_STATUS
WHERE SEVERITY IN ('Error', 'Fatal')
AND TIMESTAMP > (SYSDATE - 1);
SELECT DEST_ID "ID",
STATUS "DB_status",
DESTINATION "Archive_dest",
ERROR "Error"
FROM V$ARCHIVE_DEST
WHERE DEST_ID <= 5;
1.6 Dataguard切换
1.6.1 概念描述
Dataguard中的role transition有两类:switchover和failover。区别在于:switchover将一个physical 库平稳成为primary,将primary切换为standby角色,这个过程可以保证无数据丢失,在完成后原生产端变成容灾端,原容灾端变成新的生产端。
Failover是当主库无法正常工作时,强制将容灾端failover成primary角色,如果在primary库在出故障之前不是处于最大保护模式的话,将会有一些数据丢失,因为当前在写的redo或者已存在的gap不能再传送到standby库。如果primary库都打开了flashback的话,可以将原来的主库重新设为新primary role数据库的standby库。
在进行role transition要检查:primary,standby是否处于archvielog模式,归档的相关参数以及原生产端是否配置standby redo log文件;Standby库的临时文件(临时表空间的数据文件)要和primary匹配;是rac的话:在容灾端只有一个实例mount,其它都要关闭。
1.6.2 SWITCHOVER
- 切换步骤
1). 将主节点A切换为standby模式:
在A上执行select switchover_status from v$database,如果返回为SESSIONS ACTIVE,说明有进程在进行,可以通过如下命令将其停止:
SQL> alter database commit to switchover to physical standby with session shutdown;
如果返回值为to standby,则执行:
SQL> alter database commit to switchover to physical standby;
此时,会将数据库从primary转换为standby角色,同时在转换动作执行前,oracle会先将控制文件backup到相应的trace文件中。
2). 原主节点A的DB启动到mount状态:
3). 将原备节点B切换为primary模式:
此时,在B上执行:
SQL> select switchover_status from v$database;
如果返回值为to primary,那么执行:
SQL> alter database commit to switchover to primary;
如果返回为session active,那么在执行:
SQL> alter database commit to switchover to primary with session shutdown;
注意,开始切换前,正常情况下,生产端的switchover_status为to primay和session active。容灾端的状态为not allowed,只有当生产端做切换动作后,容灾端的状态才会变成to standby。
4). 启动节点B到open状态
5). 设置A为Recover Managed Standby:
此时A上的switchover_status变成RECOVERY NEEDED。 在A上打开real time apply功能:
SQL> alter database recover managed standby database using current logfile disconnect from session;
- 切换失败的回退方法
在做switchover过程中,如果碰到错误而无法正常完成切换,那么此时可以回退到切换前的状态。方法如下:
将原生产端A回退为新的生产端:
SQL> alter database commit to switchover to primary with session shutdown;
如果这个语句执行成功,那么关闭并重启数据库,使DB运行在read write的primary模式下。以后的步骤就不需要执行了。
这个语句执行时会在trace文件中记录重建原生产端控制文件的sql语句。
在B上创建一个新的standby控制文件。在A上执行以下语句并将生产的文件拷贝到B并在B的nomount状态下执行:
SQL> alter database create standby controlfile as ‘/…/std.ctl’
启动B的数据库,打开redo apply功能。
如果需要,可以重新做switchover。
1.6.3 FAILOVER
当主节点全部当机后,手工启动B,并且在B作为主节点运行期间,A一直未能修复,此时需要将B转换为primary角色。一段时间后,当A修复并且要重新做为主节点,那么可以先将A配置为新的standby,然后再做switchover。
- 无gap的FAILOVER
1). 检查日志gap:
在B上看看是否有归档日志文件的gap:
SQL> select thread#, low_sequence#, high_sequence# from v$archive_gap;
这个视图在11.1.0.7中并不准确,可以比对生产端和容灾端各自的v$managed_standby的LNS和RFS进程各自的log sequence,也可以直接去检查生产端和容灾端各自的归档目录下已有的归档文件。
如果有gap,则必须从相应的节点(thread)中拷贝相应的归档日志文件到B的相应目录下,并注册他们:
SQL> alter database register physical logfile 'filespec1';
如果可以确保生产端的所有归档日志及redo日志都已经传送或拷贝注册到容灾端,那么容灾端做failover后不会有数据丢失。如果有些归档日志无法获得或者最后的redo数据没有传送到容灾端,那么会有部分数据丢失。
2). 关闭A的数据库实例
3). 在B上取消recover managed状态:
执行如下语句:
SQL> alter database recover managed standby database cancel;
SQL> alter database recover managed standby database finish;
4). 转换B作为Primary:
SQL> alter database commit to switchover to primary [with session shutdown];
5). 重新启动B数据库:
SQL> alter database open;
6). 后续处理:
如果A的数据库无法再启动,在B做生产端期间A无法承担容灾端的角色,那么当A修复好以后,将备份的tnsnames.ora、listener.ora、sqlnet.ora文件从备份文件中恢复出来,然后从B对A做基线,然后打开redo apply功能,使A与B同步。然后再做一次switchover将A恢复为生产环境。
2. 有gap的FAILOVER
如果容灾端存在日志的gap,那么用正常的切换方法做finish时会报错:
SQL> alter database recover managed standby database finish;
Media Recovery failed with error 16171
ORA-283 signalled during: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH FORCE
...
Thu May 07 12:16:35 2009
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH FORCE
Attempt to do a Terminal Recovery (drcbpdb2)
Media Recovery Start: Managed Standby Recovery (drcbpdb2)
Fast Parallel Media Recovery enabled
Managed Standby Recovery not using Real Time Apply
parallel recovery started with 3 processes
Media Recovery Waiting for thread 1 sequence 20
Fetching gap sequence in thread 1, gap sequence 20-20
Thu May 07 12:19:44 2009
***********************************************************************
这样的场景下,做failover切换的方法是在容灾端执行以下命令,忽略gap,丢失部分数据,打开数据库:
SQL> alter database recover managed standby database cancel;
SQL> alter database activate physical standby database;
SQL> alter database open;
1.6.4 Failover后重建容灾端
- 使用flashback功能
方法描述:
如果原生产端打开了flashback database特性,那么可以将原生产DB回退到原容灾转生产的SCN,并转为standby模式,步骤如下:
确定容灾DB转为生产角色时的SCN,例如516759,在容灾DB上执行:
SQL> select STANDBY_BECAME_PRIMARY_SCN from v$database;
将原生产DB回退到516759:
SQL> startup mount;
SQL> flashback database orawch2 to scn 516759;
将原生产DB转变为physical standby模式,此时由于控制文件类型变化,数据库模式变为了nomount状态,需要重启新容灾DB,使日志可以通过RFS进程开始传送:
SQL> alter database convert to physical standby;
SQL> shutdown immediate;
SQL> startup mount;
在新容灾端打开redo apply功能:
SQL> alter database recover managed standby database using current logfile disconnect from session;
缺点描述:
打开flashback database特性需要预备一个磁盘空间来存放相关日志以供DB回退,并且对DB性能会有较明显的影响。
2. 使用新生产端的备份集去做恢复
方法描述:
在新的生产端全库备份,可以plus arcivelog,也可以不plus。然后将备份集传输到容灾端,进行恢复。具体步骤如下:
在新生产端做备份,然后将备份集传输到容灾端
将容灾DB使用自己的参数文件启动到nomount状态
使用传输来的备份集中的控制文件为容灾端做恢复:
RMAN> restore standby controlfile from ‘/备份集路径/包含控制文件的名称’;
RMAN> alter database mount;
RMAN> restore database;
确保生产端和容灾端的容灾复制监听都已开启,并且可tnsping通双方的容灾复制网络别名,生产端的log_archive_dest_state_2必须是ENABLE
在容灾端执行以下命令打开real time apply,并且处理备份集到当前时间之间新产生的日志:
RMAN> alter database recover managed standby database using current logfile disconnect from session;
缺点描述:
操作麻烦。并且需要为备份集准备一个磁盘空间。
优点描述:
仅对使用了的块进行备份,例如数据库表空间共1000G,但仅有1G的块上有数据,那么备份集仅1G左右,而且还可以采用压缩备份,备份集做多可降到十分之一,大大减少了数据传输量,加快了速度。适用于大数据库场景。
3. 使用旧生产端的备份集去做恢复
方法描述:
原生产端定义为A,原容灾端定义为B。
容灾切换前,A存在全备份文件,例如10点有备份。Failover切换(例如发生在12点)时可能丢失了部分A的日志(例如11点到12点之间的日志都丢失了),但B上10点钟的状态与A在10点的备份集是一致的,只要B保留了10点之后自己的所有日志,那么可以将B的这些日志传输到A并apply。具体步骤如下:
使用A上10点钟的备份文件,做到restore database步骤。这里controlfile类型不是standby的。
找到B转换为read write时的SCN号,例如556976:
SQL> SELECT TO_CHAR(STANDBY_BECAME_PRIMARY_SCN) FROM V$DATABASE;
将A恢复到这个SCN号+1:
run
{set until scn 556977;
recover database;}
将A转换为standby模式:
SQL> ALTER DATABASE CONVERT TO PHYSICAL STANDBY;
这个命令执行完以后,控制文件被修改为standby模式,同时数据库处于nomount状态;继续执行下面的命令重新将它启动到mount状态:
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
确保A和B上各自的监听都已启动,并且B的log_archive_dest_state_2的值为ENABLE
在A上打开real time apply功能,A会自动应用旧restelog的日志,以及新resetlog的日志:
Media Recovery Log /ora_arch/1_20_694981578.dbf
Media Recovery Waiting for thread 1 sequence 1
Fetching gap sequence in thread 1, gap sequence 1-2
Mon Aug 24 13:54:54 2009
缺点描述:
操作麻烦。并且需要A为备份集准备一个磁盘空间。
优点描述:
仅需要保留A的一个备份,以及B需要保留A备份之后的所有的日志。
使用duplicate功能
方法描述:
可以从新生产端往原生产端做duplicate复制。具体方法如下:
在生产端执行以下脚本将生产端的数据库传输复制到容灾端:
# rman target / auxiliary sys/oracle@@S_TNS@
RMAN> run {
allocate channel prmy1 type disk;
allocate auxiliary channel stby2 type disk;
duplicate target database for standby from active database nofilenamecheck;
}
缺点描述:
使用duplicate会较高地消耗生产端的CPU。并且它是全块的复制,例如生产DB有10000G,那么就需要复制10000G的大小,非常耗时,不适合较大数据库。
优点描述:
命令简单容易操作。数据在两个节点上直接传输,不需要中间磁盘空间。
1.7 Dataguard配置信息收集
This script is intended to be run via sqlplus as the SYS or Internal user.
NAME: dg_prim_diag.sql (Run on PRIMARY with a LOGICAL or PHYSICAL STANDBY):
NAME: DG_phy_stby_diag.sql:
2 ORACLE数据库Dataguard案例分析
2.1 DataGuard容灾ORA-01274 ORA-01119错误解决办法
现象描述
某客服局点数据库采用DATAGUARD容灾方案,局方维护人员在生产库扩表空间时增加了一个在灾备库没有的裸设备,导致STANDBY数据库异常MRP进程SHUTDOWN。
组网方案:
1、生产库由两台IBM P570+DS4700构成ORACLE RAC双机。
2、灾备库同样由两台IBM P570+DS4700构成ORACLE RAC双机。
3、ORACLE版本为 9.2.0.8。
告警信息
stangby数据库的ALERT告警日志如下:
Successfully added datafile 280 to media recovery
Datafile #280: '/dev/rlv_data2vg84'
Media Recovery Log /archive1/standby/uidb2_10376.log
WARNING: File being created with same name as in Primary
Existing file may be overwritten
File #281 added to control file as 'UNNAMED00281'. Originally created as:
'/dev/rlv_index1vg100'
Recovery was unable to create the file as:
'/dev/rlv_index1vg100'
Wed Dec 3 16:19:53 2008
MRP0: Background Media Recovery terminated with error 1274
Wed Dec 3 16:19:53 2008
Errors in file /home/oracle/app/oracle/admin/uidb/bdump/uidb1_mrp0_360682.trc:
ORA-01274: cannot add datafile '/dev/rlv_index1vg100' - file could not be created
ORA-01119: error in creating database file '/dev/rlv_index1vg100'
ORA-27040: skgfrcre: create error, unable to create file
IBM AIX RISC System/6000 Error: 13: Permission denied
Some recovered datafiles maybe left media fuzzy
Media recovery may continue but open resetlogs may fail
MRP0: Background Media Recovery process shutdown
原因分析
由于在生产库增加了一个灾备库没有的LV('/dev/rlv_index1vg100'),导致灾备库在应用归档日志文件时报错,进而导致MRP进程shutdown。处理过程:
在备库执行下列操作:
(1)把备库的文件管理方式改为手动管理
SQL> alter system set standby_file_management='manual' scope=both;
System altered.
(2)生成数据文件(如果数据文件是裸设备,要提前创建裸设备)
SQL> alter database create datafile '/u01/ora9i/database/9.2.0/dbs/UNNAMED00008' as '/dev/vg00/rlv_tbs02';
Database altered.
说明:"/home/oracle/app/product/9.2.0/dbs/UNNAMED00008"是通过在灾备库上查看V$DATAFILE视图根据ID号查出来的。
,该ID和灾备库alert日志中的File #281 added to control file as 'UNNAMED00281'. Originally created as:中的281对应。
(3)把备库的文件管理方式改为自动管理
SQL> alter system set standby_file_management='auto';
System altered.
(4)置备库为恢复管理模式
SQL> recover managed standby database disconnect;
Media recovery complete.
建议与总结
该问题首先要及时发现,保证生产和灾备库上的归档日志文件系统不能被写满,或者即将满。其次,绝对不可以随便删除归档日志文件,否则就无法采用上述恢复办法恢复,只能重建灾备库。
2.2 关于Oracle10g Dataguard数据同步后无法打开Standby database
现象描述
Oracle10g中DD数据同步后,容灾库(Standby)无法正常打开,数据文件不可用,DataGuard环境搭建失败。
告警信息
无。
原因分析
Oracle10g 中创建Vg类型时必须是Big,Scalable VG否则会导致Oracle10g偏移量告警,而在进行Oracle DataGuard DD数据同步时必须确保主数据库(Primary)和容灾数据(Standby)Vg类型一致,否则容灾数据库将无法正常打开。所以在用DD数据同步之前先检查当前Vg类型。
处理过程
将容灾库Vg类型重新划分与主数据Vg类型保持一致,也可通过RMAN方式创建容灾数据库。
方法一
kfjddb02:/u01/oracle>$lsvg vg28
VOLUME GROUP:vg28 VG IDENTIFIER: 00cd92d100004c000000011a4ca6e15c
VG STATE: active PP SIZE: 512 megabyte(s)
VG PERMISSION: read/write TOTAL PPs: 1020 (522240 megabytes)
MAX LVs: 512 FREE PPs: 4 (2048 megabytes)
LVs: 127 USED PPs: 1016 (520192 megabytes)
OPEN LVs: 7 QUORUM: 3
TOTAL PVs: 4 VG DESCRIPTORS: 4
STALE PVs: 0 STALE PPs: 0
ACTIVE PVs: 4 AUTO ON: no
Concurrent: Enhanced-Capable Auto-Concurrent: Disabled
VG Mode: Concurrent
Node ID: 2 Active Nodes:
MAX PPs per VG: 130048
MAX PPs per PV: 1016 MAX PVs: 128
LTG size (Dynamic): 1024 kilobyte(s) AUTO SYNC: no
HOT SPARE: no BB POLICY: relocatable
lqueryvg -At -g 00cd92d100004c000000011a4ca6e15c
......
Total PPs: 1020
LTG size: 128
HOT SPARE: 0
AUTO SYNC: 0
VG PERMISSION: 0
SNAPSHOT VG: 0
IS_PRIMARY VG: 0
PSNFSTPP: 16128
VARYON MODE: 0
VG Type: 1
Max PPs: 130048
说明,VG Type 0是普通VG,1是Big VG,VG Type 2就是Scalable VG
方法二
VG 类型的配置限制有差异,用户可定义 LV 的最大数目等于每个 VG 的 LV 最大数目减 1,因为将保留一个 LV 给系统使用。因此,系统管理员可以在常规 VG、大容量 VG 和可扩展 VG 中分别配置 255、511 和 4095 个 LV。下表是VG配置限制
VG 的配置限制
VG类型 | PV最大数目 | LV最大数目 | 每个VG的PP最大数目 | PP最大容量 |
---|---|---|---|---|
常规VG | 32 | 256 | 32512 | 1GB |
大容量VG | 128 | 512 | 130048 | 1GB |
可扩展VG | 1024 | 4096 | 2097152 | 128GB |
根据前面vg28的Max PPs为130048,从上表可得知vg28为Big Vg.
建议与总结
无。
2.3 因存储异常导致数据库Data Guard容灾异常
现象描述
ORACLE数据库Data Guard容灾系统,归档日志无法从主库传输到容灾库。
告警信息
主库alert日志:
Fri Apr 24 09:07:19 2009
ARC1: Attempting destination LOG_ARCHIVE_DEST_2 network reconnect (270)
ARC1: Destination LOG_ARCHIVE_DEST_2 network reconnect abandoned
Fri Apr 24 09:07:19 2009
Errors in file /u01/oracle/app/oracle/admin/kfdb/bdump/kfdb1_arc1_5677984.trc:
ORA-00270: error creating archive log
FAL[server, ARC1]: Error 270 creating remote archivelog file 'standby1'
FAL[server, ARC1]: FAL archive failed, see trace file.
Fri Apr 24 09:07:19 2009
Errors in file /u01/oracle/app/oracle/admin/kfdb/bdump/kfdb1_arc1_5677984.trc:
ORA-16055: FAL request rejected
ARCH: FAL archive failed. Archiver continuing
Fri Apr 24 09:07:19 2009
ORACLE Instance kfdb1 - Archival Error. Archiver continuing.
容灾库alert日志:
Fri Apr 24 09:07:19 2009
Errors in file /u01/oracle/app/oracle/admin/kfdb/udump/kfdb1_rfs_1052750.trc:
ORA-00270: error creating archive log /kfarch1/arch_2_16435_656527165.arc
ORA-19504: failed to create file "/kfarch1/arch_2_16435_656527165.arc"
ORA-27040: file create error, unable to create file
IBM AIX RISC System/6000 Error: 89: Invalid file system control data detected
原因分析
1、检查网络通信:
ping、tnsping、rlogin等操作均正常,主备节点网络可通;
2、检查主备节点存储:
在归档目录下测试文件的创建、编辑、删除等操作,主库归档目录正常,容灾库归档目录无法完成文件的创建、编辑和删除。
报错:Invalid file system control data detected.
此报错与alert日志中报错相同。
3、检查容灾节点存储:
$errpt|more
C1348779 0424090709 I O SYSJ2 LOG I/O ERROR
E86653C3 0424090709 P H LVDD I/O ERROR DETECTED BY LVM
DA1477B1 0424090709 P H hdisk36 REQUESTED OPERATION CANNOT BE PERFORMED
C1348779 0424090709 I O SYSJ2 LOG I/O ERROR
E86653C3 0424090709 P H LVDD I/O ERROR DETECTED BY LVM
DA1477B1 0424090709 P H hdisk36 REQUESTED OPERATION CANNOT BE PERFORMED
由此可推断存储出现异常。
处理过程
1、因容灾库存储异常,需停容灾库:
$sqlplus “/as sysdba”
SQL> alter database recover managed standby database cancel;
SQL> shutdown immediate;
2、检查存储,排除故障:
fsck检查,接着unmount /kfarch1,再mount /kfarch1。
在容灾节点的归档目录下测试文件的创建、编辑、删除等操作,均恢复正常。
3、重新启动容灾库,置为恢复管理模式:
$sqlplus “/as sysdba”
SQL> startup nomount;
SQL> alter database mount standby database;
SQL> alter database recover managed standby database disconnect;
4、观察主备库,检查alert日志与日志应用情况:
Data Guard系统恢复正常,日志正常传输并应用。
建议与总结
无。
2.4 参数设置错误导致dataguard灾备数据库日志应用异常
现象描述
数据库版本:oracle10g及以上
操作系统: 全部版本
故障现象: 灾备数据库长时间没有成功应用归档日志
现场工程师报说容灾节点的日志从2011.7.21之后就没有再应用,v$manage_standby动态性能视图中查询返回结果不再包含MRP0后台进程。
期望结果:
SQL> select process,status,thread#,sequence#,block#,blocks
from v$managed_standby;
PROCESS STATUS THREAD# SEQUENCE# BLOCK# BLOCKS
--------- ------------ ---------- ---------- ---------- ----------
MRP0 WAIT_FOR_LOG 1 102205 0 0
RFS RECEIVING 1 102128 1023998 1023998
RFS WRITING 1 102205 52170 1024000
Describe of process:
RFS: 负责接收主库端传输过来的redo log file
MRP0:负责应用接收到的redo log file
告警信息
Errors in file /opt/oracle/app/oracle/admin/smoradb/bdump/smorastd_mrp0_103784.trc:
ORA-01670: new datafile 17 needed for standby database recovery
ORA-01122: database file 17 failed verification check
ORA-01110: data file 17: '/dev/rsmora_index04'
ORA-01251: Unknown File Header Version read for file number 17
Some recovered datafiles maybe left media fuzzy
Media recovery may continue but open resetlogs may fail
MRP0: Background Media Recovery process shutdown.
原因分析
在这之前曾经出过两次相关的现网操作。
首先是存储曾经掉过一次电,所以当时怀疑存储导致的一个操作系统bug。让现场兄弟修复该bug后,问题依旧。
后现场工程师反映说,这个问题是从之前一次为tablespace增加datafile之后开始的。
远程登录现网环境,检查发现灾备端的参数standby_file_management被设置为了manual。设置这个参数值之后,主节点新增的数据文件需要到灾备端手工执行创建,之后归档日志才能再次顺利应用。
处理过程
由于检测到现网的参数standby_file_management被设置为MANUAL,所以首先尝试将该参数修改为AUTO,这样之后在主节点新增数据文件时,灾备节点可以顺利执行数据文件的创建动作。
Alter system set standby_file_management=’AUTO’;
修改该参数后检查v$datafile,发现已经存在对应的数据文件/dev/rsmora_index04,但是日志的应用依旧出现错误提示。
尝试手工执行数据文件的创建动作。
这时执行
alter database create datafile ‘/dev/rsmora_index04’ as ‘/dev/rsmora_index04’
出现错误提示,说将参数修改为自动之后无法手工创建文件。
于是再次将参数修改为MANUAL,创建文件之后再修改回来即可。
Alter system set standby_file_management=’MANUAL’;
alter database create datafile ‘/dev/rsmora_index04’ as ‘/dev/rsmora_index04’;
Alter system set standby_file_management=’AUTO’;
完成动作后,将数据库重新设置为日志应用状态。
alter database recover managed standby database disconnect;
建议与总结
无。
2.5 Dataguard备库手工同步方法之一
现象描述
某局oracle 9i dataguard主备库环境下,发现备库存在GAP,且手工从主库拷贝缺少归档至备库后,仍无法同步。
The alert log show failed in the standby:
Sun Oct 9 15:19:14 2011
Failed to request gap sequence. Thread #: 1, gap sequence: 224-224
All FAL server has been attempted.
告警信息
无。
原因分析
检查同步情况:
SQL> select open_mode from v$database;
SQL> select sequence#,applied from v$archived_log order by sequence#;
SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;
SQL> select process,status from v$managed_standby;
从v$archived_log中发现存在224,225,226,227的applied为NO,且从v$managed_standby中也看到存在MRP0(WAIT_FOR_GAP)和FAL(WAITING)。此处是FAL无法自动获取224,可考虑手工同步未同步的归档。
处理过程
- 首先将224,225,226,227手工从主库传送至备库,注意备库归档目录大小,修改传送过来的属主和权限;
- 在备库执行如下来恢复:
$ sqlplus '/ as sysdba'
SQL> recover managed standby database cancel;
--- 这时 MRP0 进程将结束
SQL> recover automatic standby database;
--- 此时备库将依次对224,225,226,227进行恢复,如果缺少某个文件,可暂不理会,立即手工重传归档文件至备库,比如225,然后在该命令提示符下输入225的绝对路径和该文件名:
/opt/oracle/oradata/archivelog/1_225.dbf
回车即可。 到最后报缺失主库当前的228时,可以在该命令提示符下输入AUTO,结束这手工RECOVER. 然后可以启用MRP0,如下:
SQL> alter database recover managed standby database disconnect from session;
建议与总结
- 备库有可能缺少大量的归档,在手工传送的时候,请务必注意文件目录大小和文件的属主权限。
- 也可以尝试先恢复224,然后启用MRP0:
SQL> alter database recover managed standby database disconnect from session;
2.6 ASM dataguard 容灾重做
现象描述
一线升级备库时,只在备库做了switchover,然后把备库open resetlogs,让后编译数据字典后把备库又切到standby 状态,主库没有做任何操作。
这样导致主备库不再是一套data guard,变成了两套独立的库。
告警信息
备库日志中发生了switchover,但是主库中没有switchover日志
wed oct 26 01:53:07 2011
alter database commit to switchover to primary with session shutdown
alter database switchover to primary (boss2)
maximum wait for role transition is 15 minutes.
all dispatchers and shared servers shutdown
close: killing server sessions.
close: all sessions shutdown successfully.
wed oct 26 01:53:07 2011
smon: disabling cache recovery
backup controlfile written to trace file /opt/oracle/app/oracle/diag/rdbms/boss/boss2/trace/boss2_ora_340976.trc
standby terminal recovery start scn: 100688092178
resetlogs after incomplete recovery until change 100688092179
...
wed oct 26 01:53:09 2011
arc3: becoming the 'no srl' arch
completed: alter database commit to switchover to primary with session shutdown
备库resetlogs之后,有启动到managed standby模式,这样备库在等待之前备库resetlogs之后产生的归档,这样就表现为了无法同步(自己无法同步自己的归档)
fal[client, mrp0]: error 12545 connecting to (description = (load_balance = on)(address = (protocol = tcp)(host = scan)(port = 1521))(connect_data = (service_name = bossmain))) for fetching gap sequence errors in file /opt/oracle/app/oracle/diag/rdbms/boss/boss1/trace/boss1_mrp0_356970.trc:
ora-12545: connect failed because target host or object does not exist errors in file /opt/oracle/app/oracle/diag/rdbms/boss/boss1/trace/boss1_mrp0_356970.trc:
ora-12545: connect failed because target host or object does not exist sat oct 29 00:25:38 2011
fal[client]: failed to request gap sequence gap - thread 2 sequence 7-106 dbid 3468682850 branch 765510788 à sequence已经重置了
fal[client]: all defined fal servers have been attempted.
原因分析
主备库不再是一套data guard,变成了两套独立的库。需要重做备库。
处理过程
详细过程见附件
因为容灾库各个配置已经配好,不需要重新配置,只用做恢复就可以了。
1)创建standby controlfile
rman target /
backup current controlfile for standby format '/rman01/prima_control.bkp';
主库每天会自动全库备份,备份目录为/rman01,/rman02,/rman03和/rman04
2)把主库的rman备份拷贝到备库的/rman04目录
备份日期:2011/10/31
大小:1t左右
传输方式:移动硬盘+ftp(因为业务已经上线,各个网卡都在一个交换机上,为了不增加网络负担,采用移动硬盘拷贝)
传过去以后需要检查一下文件数量和大小是否一致,否则后面catalog和restore时会报错
3)恢复备库
(1)恢复standby controlfile
login p570db1
su - oracle
sqlplus / as sysdba
shutdown immediate
startup nomount
exit
rman target /
restore standby controlfile from '/rman04/prima_control.bkp';
(2)因为主库的备份文件全部都放到了备库的/rman04下,所以需要把备份catalog到备库的控制文件中,否则restore时会提示找不到备份文件
rman target /
alter database mount;
catalog backuppiece '/rman04/ bossmain_s_xxx';
(3)恢复备库(不用recover,后面mrp会自己recover)
rman target /
restore database;
4)创建standby redo,应用归档日志
sqlplus / as sysdba
alter database add standby logfile thread 1 group 10 '+data_dg' size 500m;
alter database add standby logfile thread 1 group 11 '+data_dg' size 500m;
alter database add standby logfile thread 2 group 12 '+data_dg' size 500m;
alter database add standby logfile thread 2 group 13 '+data_dg' size 500m;
recover managed standby database using current logfile disconnect from session;
有缺少的归档日志时,及时从主库拷贝到备库
5)恢复备库到管理模式
sqlplus / as sysdba
alter database open read only;
建议与总结
1)对于容灾库的升级,opatch apply在主备库都执行,编译数据字典和无效对象只在主库执行,不要在备库执行。
2)对于使用ASM的容灾库。
2.7 设置log_archive_dest_2时提示db_unique_name不存在
错误描述:
配置主节点或备用节点的log_archive_dest_2参数为'service=orcl valid_for=(online_logfiles,primary_role) db_unique_name=orcl',此时收到如下错误:
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-16053: DB_UNIQUE_NAME orcl is not in the Data Guard onfiguration
原因分析:
在参数log_archive_config中未定义db_unique_name为orcl的值。
解决方法:
执行如下语句:
SQL> alter system set log_archive_config='dg_config=(hwrac,orcl)';
然后重新设置参数log_archive_dest_2的值。
2.8 权限不足
问题描述:
容灾端发现日志gap,缺少323,FAL失败。检查日志文件发现:
Mon Mar 09 17:08:07 2009
Error 1031 received logging on to the standby
FAL[client, MRP0]: Error 1031 connecting to oradg01 for fetching gap sequence
Errors in file /opt/oracle/app/diag/rdbms/drora01/drora011/trace/drora011_mrp0_18621.trc:
ORA-01031: insufficient privileges
再检查trc文件,发现如下信息:
*** 2009-03-09 17:07:36.799
Media Recovery add redo thread 1
*** 2009-03-09 17:07:36.809 1359 krsm.c
Managed Recovery: Active posted.
*** 2009-03-09 17:07:36.970 1117 krsh.c
Media Recovery Waiting for thread 2 sequence 323
*** 2009-03-09 17:07:36.971 1117 krsh.c
Fetching gap sequence in thread 2, gap sequence 323-323
Redo shipping client performing standby login
OCISessionBegin failed -1
.. Detailed OCI error val is 1017 and errmsg is 'ORA-01017: invalid username/password; logon denied'
OCISessionBegin failed. Error -1
.. Detailed OCI error val is 1031 and errmsg is 'ORA-01031: insufficient privileges'
OCISessionBegin failed. Error -1
.. Detailed OCI error val is 1031 and errmsg is 'ORA-01031: insufficient privileges'
*** 2009-03-09 17:07:37.132 1117 krsh.c
Error 1031 received logging on to the standby
*** 2009-03-09 17:07:37.132 1117 krsh.c
FAL[client, MRP0]: Error 1031 connecting to oradg01 for fetching gap sequence
ORA-01031: insufficient privileges
原因分析:
检查dest_2中的service,执行tnsping,成功。执行sqlplus sys/password@net_name as sysdba,成功。问题肯定是出在密码文件上。
解决方法:
将所有节点上原来的密码文件删除,然后在一个节点上新建,再拷贝到其他节点上并更名。
2.9 基线后容灾端DB不能mount
问题描述:
第一次复制基线失败(不是因为REDO方面),然后又重新做了一次复制,复制成功完成,但发现容灾端DB不能mount,提示redo2不能归档,trace文件中内容如下:
*** 2008-09-24 12:23:10.117 11266 kcrr.c
DDE rules only execution for: ORA 312
----- START Event Driven Actions Dump ----
---- END Event Driven Actions Dump ----
----- START DDE Actions Dump -----
Executing SYNC actions
----- START DDE Action: 'DB_STRUCTURE_INTEGRITY_CHECK' (Async) -----
Successfully dispatched
----- END DDE Action: 'DB_STRUCTURE_INTEGRITY_CHECK' (SUCCESS, 0 csec) -----
Executing ASYNC actions
----- END DDE Actions Dump (total 0 csec) -----
ORA-00316: log 2 of thread 1, type 12336 in header is not log file
ORA-00312: online log 2 thread 1: '/dev/vgdrora/rlv_redo2'
ORA-00316: log 2 of thread 1, type 12336 in header is not log file
ORA-00312: online log 2 thread 1: '/dev/vgdrora/rlv_redo2'
logfile 2 header verification failed:316
DDE: Problem Key 'ORA 312' was flood controlled (0x1) (no incident)
ORA-00312: online log 2 thread 1: '/dev/vgdrora/rlv_redo2'
*** 2008-09-24 12:23:10.128 11633 kcrr.c
ORA-16038: log 2 sequence# 2 cannot be archived
ORA-00312: online log 2 thread 1: '/dev/vgdrora/rlv_redo2'
*** 2008-09-24 12:38:31.036 11266 kcrr.c
解决方法:
这是由于REDO中遗留了正确复制之前的状态。将容灾端的数据库删除后重新做复制。
2.10 基线时错误RMAN-11003
问题描述:
一次做基线时,遇到错误,内容如下:
sql statement: alter database mount standby database
released channel: prmy1
released channel: prmy2
released channel: stby1
released channel: stby2
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate Db command at 03/28/2009 16:11:18
RMAN-03015: error occurred in stored script Memory Script
RMAN-03009: failure of sql command on clone_default channel at 03/28/2009 16:11:18
RMAN-11003: failure during parse/execution of SQL statement: alter database mount standby database
ORA-01167: two files are the same file/group number or the same file
ORA-00202: control file: '/dev/drvgora/rlv_ctl02'
检查容灾端的控制文件参数设置发现rlv_ctl02出现了两次:
SQL> show parameter control
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
control_file_record_keep_time integer 7
control_files string /dev/drvgora/rlv_ctl02, /dev/d
rvgora/rlv_ctl02, /dev/drvgora
/rlv_ctl03
control_management_pack_access string DIAGNOSTIC+TUNING
解决方法:
修改容灾端的control_files参数,然后重新基线。
2.11 基线时错误RMAN600
问题描述:
做基线时发生RMAN600的错误,停顿在backup as copy reuse
解决方法:
将生产端的密码文件传送到容灾端并更名。然后重新做基线。
2.12 基线时错误ORA-17628
问题描述:
一次做基线时,遇到错误,内容如下:
Starting backup at 14-MAR-08
channel prmy1: starting datafile copy
input datafile file number=00005 name=/dev/vg_ora/rora_test
RMAN-03009: failure of backup command on prmy1 channel at 03/14/2008 16:18:17
ORA-17628: Oracle error 19505 returned by remote Oracle server
continuing other job steps, job failed will not be re-run
channel prmy1: starting datafile copy
input datafile file number=00001 name=/dev/vg_ora/rora_system
RMAN-03009: failure of backup command on prmy1 channel at 03/14/2008 16:18:21
ORA-17628: Oracle error 19505 returned by remote Oracle server
continuing other job steps, job failed will not be re-run
channel prmy1: starting datafile copy
input datafile file number=00003 name=/dev/vg_ora/rora_undo
RMAN-03009: failure of backup command on prmy1 channel at 03/14/2008 16:18:22
ORA-17628: Oracle error 19505 returned by remote Oracle server
continuing other job steps, job failed will not be re-run
channel prmy1: starting datafile copy
input datafile file number=00002 name=/dev/vg_ora/rora_sysaux
RMAN-03009: failure of backup command on prmy1 channel at 03/14/2008 16:18:23
ORA-17628: Oracle error 19505 returned by remote Oracle server
continuing other job steps, job failed will not be re-run
channel prmy1: starting datafile copy
input datafile file number=00004 name=/dev/vg_ora/rora_data
released channel: prmy1
released channel: stby2
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate Db command at 03/14/2008 16:18:24
RMAN-03015: error occurred in stored script Memory Script
RMAN-03009: failure of backup command on prmy1 channel at 03/14/2008 16:18:24
ORA-17628: Oracle error 19505 returned by remote Oracle server
原因分析:
此文件的原因需要检查容灾端的告警日志,检查发现如下内容:
Physical Standby Database mounted.
Lost write protection disabled
Fri Mar 14 16:18:44 2008
Completed: alter database mount standby database
Fri Mar 14 16:18:45 2008
Errors in file /oracle/db/diag/rdbms/stb/wch/trace/wch_ora_20726.trc:
ORA-19505: failed to identify file "/dev/vg_ora/rora_test"
ORA-27040: file create error, unable to create file
HPUX-ia64 Error: 2: No such file or directory
Fri Mar 14 16:18:49 2008
Using STANDBY_ARCHIVE_DEST parameter default value as /arch
Fri Mar 14 16:18:49 2008
Errors in file /oracle/db/diag/rdbms/stb/wch/trace/wch_ora_20817.trc:
ORA-19505: failed to identify file "/dev/vg_ora/rora_system"
ORA-27040: file create error, unable to create file
HPUX-ia64 Error: 2: No such file or directory
Fri Mar 14 16:18:50 2008
Errors in file /oracle/db/diag/rdbms/stb/wch/trace/wch_ora_20821.trc:
ORA-19505: failed to identify file "/dev/vg_ora/rora_undo"
ORA-27040: file create error, unable to create file
HPUX-ia64 Error: 2: No such file or directory
Fri Mar 14 16:18:51 2008
Errors in file /oracle/db/diag/rdbms/stb/wch/trace/wch_ora_20823.trc:
ORA-19505: failed to identify file "/dev/vg_ora/rora_sysaux"
ORA-27040: file create error, unable to create file
HPUX-ia64 Error: 2: No such file or directory
Fri Mar 14 16:18:52 2008
Errors in file /oracle/db/diag/rdbms/stb/wch/trace/wch_ora_20825.trc:
ORA-19505: failed to identify file "/dev/vg_ora/rora_data"
ORA-27040: file create error, unable to create file
HPUX-ia64 Error: 2: No such file or directory
因此,这个问题的原因是由于容灾端的db_file_name_convert和log_file_name_convert要么没有设置,要么设置错误。
解决方法:
为容灾端设置参数db_file_name_convert和log_file_name_convert。注意,此参数的值应是:生产端的路径,容灾端的路径。切记不能弄错了先后次序。
2.13 生产端Lost_Write问题的处理方法
问题描述:
生产库Lost_Write现象是LGWR通知oracle已经写入物理文件中了而事实上并未写入,而这部分redo信息实际已经传送到了容灾端。当容灾端进行media recovery时,通过比较容灾端与生产端的redo文件中的块的scn,如果发现容灾端的scn要高于生产端,那么就认为生产端出席Lost_Write现象了。也就是说,生产端的lost_write现象是由容灾端监测到的。此时,容灾端的告警日志中有类似如下的错误提示:
Tue Dec 12 19:09:48 2006
STANDBY REDO APPLICATION HAS DETECTED THAT THE PRIMARY DATABASE LOST A DISK WRITE OF BLOCK 26, FILE 7 NO REDO AT OR AFTER SCN 389667 CAN BE USED FOR RECOVERY.
……………
……………
Slave exiting with ORA-752 exception
Errors in file /oracle/log/diag/rdbms/dgstwrite2/stwrite2/trace/stwrite2_pr00_23532.trc:
ORA-00752: recovery detected a lost write of a data block
ORA-10567: Redo is inconsistent with data block (file# 7, block# 26)
ORA-10564: tablespace TBS_2
ORA-01110: data file 7: '/oracle/dbs/btbs_21.f'
ORA-10561: block type 'TRANSACTION MANAGED DATA BLOCK', data object# 57503
生产端出现lost_write以后,容灾端仍可以正常地apply日志并将容灾库调整到一致状态,只是后续容灾告警日志中可能会出现如下信息:
Recovery interrupted!
Recovered data files to a consistent state at change 389569
生产端出现lost_write以后,生产端的数据文件可能已经corrupted,但是生产端的告警日志中却没有任何相关的异常信息。
解决方法:
解决方法是将容灾库做failover切换,步骤如下:
- 关闭生产端数据库,发生lost write的SCN以后的数据都将丢失;
- 在容灾端执行以下命令切换为primary角色:
SQL> ALTER DATABASE ACTIVATE STANDBY DATABASE;
执行过程如下:
Database altered.
Tue Dec 12 19:15:23 2006
alter database activate standby database
ALTER DATABASE ACTIVATE [PHYSICAL] STANDBY DATABASE (stwrite2)
RESETLOGS after incomplete recovery UNTIL CHANGE 389569
Resetting resetlogs activation ID 612657558 (0x24846996)
Online log /oracle/dbs/bt_log1.f: Thread 1 Group 1 was previously cleared
Online log /oracle/dbs/bt_log2.f: Thread 1 Group 2 was previously cleared
Standby became primary SCN: 389567
Tue Dec 12 19:15:23 2006
Setting recovery target incarnation to 3
Converting standby mount to primary mount.
ACTIVATE STANDBY: Complete - Database mounted as primary (stwrite2)
Completed: alter database activate standby database
- 在新的生产库(原容灾端)做好全备份【推荐而非必须】
- 将新的生产库打开:SQL> alter database open;
- 如果希望将原生产端配置为新的容灾端,那么可以使用步骤3的备份集来恢复,具体步骤请参考。
2.14 生产端关闭时错误信息1089
问题描述:
生产库数据库关闭时,告警日志中出现1089的错误如下:
Completed: ALTER DATABASE DISMOUNT
ARCH: Archival disabled due to shutdown: 1089
Shutting down archive processes
Archiving is disabled
Archive process shutdown avoided: 0 active
ARCH: Archival disabled due to shutdown: 1089
Shutting down archive processes
Archiving is disabled
Archive process shutdown avoided: 0 active
Fri May 15 11:50:40 2009
Stopping background process VKTM:
Fri May 15 11:50:42 2009
Instance shutdown complete
Fri May 15 12:09:10 2009
Starting ORACLE instance (normal)
解决方法:
这是一个已知的问题,并不影响系统的功能和性能,将在11.1.0.8中解决。
2.15 容灾端RFS发生600错误
问题描述:
生产端正常进行业务运行,产生归档日志需要传输到容灾端,发现容灾端的一个rfs中出现错误,信息如下:
Mon Jun 01 20:34:28 2009
Errors in file /oracle/db/diag/rdbms/drabc1/drabc1/trace/drabc1_rfs_25487.trc (incident=84207):
ORA-00600: internal error code, arguments: [krsb_stream_receive.2], [], [], [], [], [], [], []
Incident details in: /oracle/db/diag/rdbms/drabc1/drabc1/incident/incdir_84207/drabc1_rfs_25487_i84207.trc
Errors in file /oracle/db/diag/rdbms/drabc1/drabc1/trace/drabc1_rfs_25487.trc (incident=84208):
ORA-00600: internal error code, arguments: [], [], [], [], [], [], [], []
ORA-00600: internal error code, arguments: [krsb_stream_receive.2], [], [], [], [], [], [], []
Incident details in: /oracle/db/diag/rdbms/drabc1/drabc1/incident/incdir_84208/drabc1_rfs_25487_i84208.trc
此时生产端LNS进程被关闭重启,不过容灾端仅这个RFS被关闭和新开一个RFS进程,其他进程并未受到影响。
原因分析:
这是11.1.0.6上的bug,号码是6598142,在11.1.0.7中解决。
2.16 基线错误ORA-12577
问题描述:
生产端向容灾端做基线时,通过下面语句发现其中一个通道进行到99.99%时一直停顿:
SELECT sid, serial#, context, sofar, totalwork,round(sofar/totalwork*100,2) "% Complete"
FROM v$session_longops
WHERE opname LIKE 'RMAN%'
AND opname NOT LIKE '%aggregate%'
AND totalwork != 0
AND sofar <> totalwork;
此时复制过程提示如下信息:
Starting backup at 15-JUN-09
channel prmy1: starting datafile copy
input datafile file number=00005 name=/dev/vgdata/rlvworkdbs1
channel prmy2: starting datafile copy
input datafile file number=00006 name=/dev/vgdata/rlvworkdbs2
channel prmy3: starting datafile copy
input datafile file number=00007 name=/dev/vgdata/rlvworkdbs3
channel prmy4: starting datafile copy
input datafile file number=00008 name=/dev/vgdata/rlvworkdbs4
channel prmy5: starting datafile copy
input datafile file number=00009 name=/dev/vgdata/rlvworkdbs5
channel prmy6: starting datafile copy
input datafile file number=00010 name=/dev/vgdata/rlvworkdbs6
RMAN-03009: failure of backup command on prmy1 channel at 06/15/2009 01:40:56
ORA-17627: ORA-12577: Message 12577 not found; product=RDBMS; facility=ORA
continuing other job steps, job failed will not be re-run
channel prmy1: starting datafile copy
input datafile file number=00011 name=/dev/vgdata/rlvworkdbs7
重试一次仍失败,检查复制过程中网络并无丢包现象。继续观测上面SQL语句的结果发现,当第一批通道的复制工作都完成时,这个通道也达到100并释放。
当复制结束时仍收到错误,信息如下:
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate Db command at 06/15/2009 01:56:13
RMAN-03015: error occurred in stored script Memory Script
RMAN-03009: failure of backup command on prmy1 channel at 06/15/2009 01:40:56
ORA-17627: ORA-12577: Message 12577 not found; product=RDBMS; facility=ORA
Recovery Manager complete.
在容灾端启动redo apply,告警日志中报错如下:
Managed Standby Recovery starting Real Time Apply
Sun Jun 14 18:03:54 2009
Errors in file /oracle/db/diag/rdbms/drora01/drora01/trace/drora01_dbw0_14543.trc:
ORA-01157: cannot identify/lock data file 5 - see DBWR trace file
ORA-01110: data file 5: '/dev/vgdrdata/rlvworkdbs1'
ORA-27037: unable to obtain file status
HPUX-ia64 Error: 2: No such file or directory
Additional information: 3
MRP0: Background Media Recovery terminated with error 1110
Errors in file /oracle/db/diag/rdbms/drora01/drora01/trace/drora01_mrp0_15130.trc:
ORA-01110: data file 5: '/dev/vgdrdata/rlvworkdbs1'
ORA-01157: cannot identify/lock data file 5 - see DBWR trace file
ORA-01110: data file 5: '/dev/vgdrdata/rlvworkdbs1'
Managed Standby Recovery not using Real Time Apply
Errors in file /oracle/db/diag/rdbms/drora01/drora01/trace/drora01_mrp0_15130.trc:
ORA-01110: data file 5: '/dev/vgdrdata/rlvworkdbs1'
ORA-01157: cannot identify/lock data file 5 - see DBWR trace file
ORA-01110: data file 5: '/dev/vgdrdata/rlvworkdbs1'
MRP0: Background Media Recovery process shutdown (drora01)
Completed: alter database recover managed standby database using current logfile disconnect from session
Sun Jun 14 18:04:37 2009
RFS[7]: Assigned to RFS process 15472
RFS[7]: Identified database type as 'physical standby': Client is ARCH pid 16444
原因分析:
检查发现,容灾端刚好没有文件/dev/vgdrdata/rlvworkdbs1。划分好LV后重新基线即可。
2.17 错误ORA-01122
问题描述:
DataGuard配置完成后,打开redo apply正常,启动容灾DB到open read only时也成功,但是发现容灾告警日志中有如下错误信息:
ALTER DATABASE OPEN
Hex dump of (file 201, block 1) in trace file /oracle/db/diag/rdbms/drora01/drora01/trace/drora01_dbw0_12388.trc
Corrupt block relative dba: 0x00400001 (file 201, block 1)
Completely zero block found during data file header read
Reread of rdba: 0x00400001 (file 201, block 1) found same corrupted data
Errors in file /oracle/db/diag/rdbms/drora01/drora01/trace/drora01_dbw0_12388.trc:
ORA-01186: file 201 failed verification tests
ORA-01122: database file 201 failed verification check
ORA-01110: data file 201: '/dev/vgdrora/rlv_temp'
ORA-01210: data file header is media corrupt
File 201 not verified due to error ORA-01122
SMON: enabling cache recovery
Dictionary check beginning
Hex dump of (file 201, block 1) in trace file /oracle/db/diag/rdbms/drora01/drora01/trace/drora01_dbw0_12388.trc
Corrupt block relative dba: 0x00400001 (file 201, block 1)
Completely zero block found during data file header read
Reread of rdba: 0x00400001 (file 201, block 1) found same corrupted data
Errors in file /oracle/db/diag/rdbms/drora01/drora01/trace/drora01_dbw0_12388.trc:
ORA-01186: file 201 failed verification tests
ORA-01122: database file 201 failed verification check
ORA-01110: data file 201: '/dev/vgdrora/rlv_temp'
ORA-01210: data file header is media corrupt
File 201 not verified due to error ORA-01122
Dictionary check complete
Cannot re-create tempfile /dev/vgdrora/rlv_temp, the same name file exists
Database Characterset is AL32UTF8
Opening with internal Resource Manager plan
replication_dependency_tracking turned off (no async multimaster replication found)
Physical standby database opened for read only access.
Completed: ALTER DATABASE OPEN
这个现象并不是因为lv_temp上有坏块,可以看到oracle企图重建临时表空间,这个动作是正常的,但是它建立失败了。
原因分析:
容灾DB复制完后第一次启动时由于tempfile没有参与复制,因此SCN与datafiles不同,因此需要重建tempfile,但是这里它认为/dev/vgdrora/rlv_temp是个文件系统而非裸设备,但是这个文件已经存在,因此重建失败。
规避措施:
先实现容灾DB与生产DB的完全同步
将容灾DB启动到read only状态
在容灾DB执行以下命令重建tempfile:
alter database tempfile '/dev/vgdrora/rlv_temp' drop;
alter tablespace temp add tempfile '/dev/vgdrora/rlv_temp' size 4000M reuse;
2.18 MRP占用很高CPU
问题描述:
MRP进程在进行日志apply时占用了很高的CPU。
原因分析:
这是因为MRP进程在做日志apply时要计算checksum,这是BUG(6641036),补丁通过disbable部分操作的checksum计算来降低CPU使用率,提高MRP进程的速度。
解决方法:
该问题是11.1.0.6上的bug,在1107中解决。也可单独打补丁6641036。
ddl获取
zhi.peng 21:46:12
获取单表DDL
set heading off;
set echo off;
Set pages 999;
set long 90000;
spool getddl.sql
--获取各种对象
SELECT DBMS_METADATA.GET_DDL(U.OBJECT_TYPE, u.object_name)
FROM user_OBJECTS u
where U.OBJECT_TYPE IN ('TABLE','INDEX','PROCEDURE','FUNCTION');
--取建表语句
select dbms_metadata.get_ddl('TABLE',upper('&TABLENAME'),upper('&SCHEMA')) from dual;
--取建索引语句
select dbms_metadata.get_ddl('INDEX',upper('&INDEXNAME'),upper('&SCHEMA')) from dual;
spool off;
获取DBLINK的语句:
1 确定compatible参数为10.2.0.2并重启数据库.
2 select dbms_metadata.get_ddl('DB_LINK',db_link,owner,'10.2.0.1') from dba_db_links where owner <> 'SYS';
获取建表空间语句
select dbms_metadata.get_ddl('TABLESPACE','&TABLESPACENAME') from dual;
获取外键语句
SELECT dbms_metadata.get_ddl('REF_CONSTRAINT', CONSTRAINT_NAME) FROM user_constraints WHERE CONSTRAINT_TYPE = 'R';
zhi.peng 21:47:15
之前写的存储过程,你可以在上面修改一下然后执行就可以了.
create or replace procedure indexddl
as
LV_RESULTFILE UTL_FILE.FILE_TYPE;
ls_indexname dba_indexes.index_name%type;
ls_str varchar2(1000);
ls_owner varchar2(40);
ls_out varchar2(1000);
cursor cur01 is
select index_name from dba_indexes where owner='ICMSDATA';
begin
LV_RESULTFILE := UTL_FILE.FOPEN ('PZDIR', 'indexddl.txt', 'w');
ls_owner :='ICMSDATA';
open cur01;
loop
fetch cur01 into ls_indexname;
exit when cur01%notfound;
ls_str := 'select dbms_metadata.get_ddl(''INDEX'',upper('''||ls_indexname||'''),upper('''||ls_owner||''')) from dual';
EXECUTE IMMEDIATE ls_str INTO ls_out;
UTL_FILE.PUT_LINE (LV_RESULTFILE,ls_out);
ls_out := null;
end loop;
close cur01;
UTL_FILE.FCLOSE (LV_RESULTFILE);
end;
常见错误
SQL> select dbms_metadata.get_ddl('TABLE','PC','SCOTT') from dual;
ERROR:
ORA-19206: Invalid value for query or REF CURSOR parameter
ORA-06512: at "SYS.DBMS_XMLGEN", line 83
ORA-06512: at "SYS.DBMS_METADATA", line 345
ORA-06512: at "SYS.DBMS_METADATA", line 410
ORA-06512: at "SYS.DBMS_METADATA", line 449
ORA-06512: at "SYS.DBMS_METADATA", line 615
ORA-06512: at "SYS.DBMS_METADATA", line 1221
ORA-06512: at line 1
no rows selected
解决办法:运行$ORACLE_HOME/rdbms/admin/catmeta.sql
参考资料:http://blog.csdn.net/cunxiyuan108/article/details/12280965
wm_concat function in 12c
CREATE OR REPLACE TYPE WM_CONCAT_IMPL AS OBJECT
-- AUTHID CURRENT_USER AS OBJECT
(
CURR_STR VARCHAR2(32767),
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL)
RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
P1 IN VARCHAR2) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN WM_CONCAT_IMPL,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER)
RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT WM_CONCAT_IMPL,
SCTX2 IN WM_CONCAT_IMPL) RETURN NUMBER
)
;
/
CREATE OR REPLACE TYPE BODY WM_CONCAT_IMPL IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL)
RETURN NUMBER IS
BEGIN
SCTX := WM_CONCAT_IMPL(NULL);
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
P1 IN VARCHAR2) RETURN NUMBER IS
BEGIN
IF (CURR_STR IS NOT NULL) THEN
CURR_STR := CURR_STR || ',' || P1;
ELSE
CURR_STR := P1;
END IF;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN WM_CONCAT_IMPL,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER) RETURN NUMBER IS
BEGIN
RETURNVALUE := CURR_STR;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT WM_CONCAT_IMPL,
SCTX2 IN WM_CONCAT_IMPL) RETURN NUMBER IS
BEGIN
IF (SCTX2.CURR_STR IS NOT NULL) THEN
SELF.CURR_STR := SELF.CURR_STR || ',' || SCTX2.CURR_STR;
END IF;
RETURN ODCICONST.SUCCESS;
END;
END;
/
CREATE OR REPLACE FUNCTION wm_concat(P1 VARCHAR2) RETURN VARCHAR2 AGGREGATE USING WM_CONCAT_IMPL;
/
grant execute on WM_CONCAT_IMPL to public;
grant execute on wm_concat to public;
oracle mail proc
CREATE OR REPLACE PROCEDURE PROCSENDEMAIL(P_TXT VARCHAR2,
P_SUB VARCHAR2,
P_SENDOR VARCHAR2,
P_RECEIVER VARCHAR2,
P_SERVER VARCHAR2,
P_PORT NUMBER DEFAULT 25,
P_NEED_SMTP INT DEFAULT 0,
P_USER VARCHAR2 DEFAULT NULL,
P_PASS VARCHAR2 DEFAULT NULL,
P_FILENAME VARCHAR2 DEFAULT NULL,
P_ENCODE VARCHAR2 DEFAULT 'bit 7')
AUTHID CURRENT_USER IS
/*
作用:用oracle发送邮件
主要功能:1、支持多收件人。
2、支持中文
3、支持抄送人
4、支持大于32K的附件
5、支持多行正文
6、支持多附件
7、支持文本附件和二进制附件
8、支持HTML格式
8、支持
作者:suk
参数说明:
p_txt :邮件正文
p_sub: 邮件标题
p_SendorAddress : 发送人邮件地址
p_ReceiverAddress : 接收地址,可以同时发送到多个地址上,地址之间用","或者";"隔开
p_EmailServer : 邮件服务器地址,可以是域名或者IP
p_Port :邮件服务器端口
p_need_smtp:是否需要smtp认证,0表示不需要,1表示需要
p_user:smtp验证需要的用户名
p_pass:smtp验证需要的密码
p_filename:附件名称,必须包含完整的路径,如"d:tempa.txt"。
可以有多个附件,附件名称只见用逗号或者分号分隔
p_encode:附件编码转换格式,其中 p_encode='bit 7' 表示文本类型附件
p_encode='base64' 表示二进制类型附件
注意:
1、对于文本类型的附件,不能用base64的方式发送,否则出错
2、对于多个附件只能用同一种格式发送
/
L_CRLF VARCHAR2(2) := UTL_TCP.CRLF;
L_SENDORADDRESS VARCHAR2(4000);
L_SPLITE VARCHAR2(10) := '++';
BOUNDARY CONSTANT VARCHAR2(256) := '-----BYSUK';
FIRST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || L_CRLF;
LAST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || '--' ||
L_CRLF;
MULTIPART_MIME_TYPE CONSTANT VARCHAR2(256) := 'multipart/mixed; boundary="' ||
BOUNDARY || '"';
/ 以下部分是发送大二进制附件时用到的变量 /
L_FIL BFILE;
L_FILE_LEN NUMBER;
L_MODULO NUMBER;
L_PIECES NUMBER;
L_FILE_HANDLE UTL_FILE.FILE_TYPE;
L_AMT BINARY_INTEGER := 672 * 3; / ensures proper format; 2016 /
L_FILEPOS PLS_INTEGER := 1; / pointer for the file /
L_CHUNKS NUMBER;
L_BUF RAW(2100);
L_DATA RAW(2100);
L_MAX_LINE_WIDTH NUMBER := 54;
L_DIRECTORY_BASE_NAME VARCHAR2(100) := 'DIR_FOR_SEND_MAIL';
L_LINE VARCHAR2(1000);
L_MESG VARCHAR2(32767);
/ 以上部分是发送大二进制附件时用到的变量 /
TYPE ADDRESS_LIST IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
MY_ADDRESS_LIST ADDRESS_LIST;
TYPE ACCT_LIST IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
MY_ACCT_LIST ACCT_LIST;
-------------------------------------返回附件源文件所在目录或者名称--------------------------------------
FUNCTION GET_FILE(P_FILE VARCHAR2, P_GET INT) RETURN VARCHAR2 IS
--p_get=1 表示返回目录
--p_get=2 表示返回文件名
L_FILE VARCHAR2(1000);
BEGIN
IF INSTR(P_FILE, '') > 0 THEN
--windows
IF P_GET = 1 THEN
L_FILE := SUBSTR(P_FILE, 1, INSTR(P_FILE, '', -1) - 1);
ELSIF P_GET = 2 THEN
L_FILE := SUBSTR(P_FILE, - (LENGTH(P_FILE) - INSTR(P_FILE, '', -1)));
END IF;
ELSIF INSTR(P_FILE, '/') > 0 THEN
--linux/unix
IF P_GET = 1 THEN
L_FILE := SUBSTR(P_FILE, 1, INSTR(P_FILE, '/', -1) - 1);
ELSIF P_GET = 2 THEN
L_FILE := SUBSTR(P_FILE,
- (LENGTH(P_FILE) - INSTR(P_FILE, '/', -1)));
END IF;
END IF;
RETURN L_FILE;
END;
---------------------------------------------删除directory------------------------------------
PROCEDURE DROP_DIRECTORY(P_DIRECTORY_NAME VARCHAR2) IS
BEGIN
EXECUTE IMMEDIATE 'drop directory ' || P_DIRECTORY_NAME;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
--------------------------------------------------创建directory-----------------------------------------
PROCEDURE CREATE_DIRECTORY(P_DIRECTORY_NAME VARCHAR2, P_DIR VARCHAR2) IS
BEGIN
EXECUTE IMMEDIATE 'create directory ' || P_DIRECTORY_NAME || ' as ''' ||
P_DIR || '''';
EXECUTE IMMEDIATE 'grant read,write on directory ' || P_DIRECTORY_NAME ||
' to public';
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
--------------------------------------------分割邮件地址或者附件地址-----------------------------------
PROCEDURE P_SPLITE_STR(P_STR VARCHAR2, P_SPLITE_FLAG INT DEFAULT 1) IS
L_ADDR VARCHAR2(254) := '';
L_LEN INT;
L_STR VARCHAR2(4000);
J INT := 0; --表示邮件地址或者附件的个数
BEGIN
/处理接收邮件地址列表,包括去空格、将;转换为,等/
L_STR := TRIM(RTRIM(REPLACE(REPLACE(P_STR, ';', ','), ' ', ''), ','));
L_LEN := LENGTH(L_STR);
FOR I IN 1 .. L_LEN LOOP
IF SUBSTR(L_STR, I, 1) <> ',' THEN
L_ADDR := L_ADDR || SUBSTR(L_STR, I, 1);
ELSE
J := J + 1;
IF P_SPLITE_FLAG = 1 THEN
--表示处理邮件地址
--前后需要加上'<>',否则很多邮箱将不能发送邮件
L_ADDR := '<' || L_ADDR || '>';
--调用邮件发送过程
MY_ADDRESS_LIST(J) := L_ADDR;
ELSIF P_SPLITE_FLAG = 2 THEN
--表示处理附件名称
MY_ACCT_LIST(J) := L_ADDR;
END IF;
L_ADDR := '';
END IF;
IF I = L_LEN THEN
J := J + 1;
IF P_SPLITE_FLAG = 1 THEN
--调用邮件发送过程
L_ADDR := '<' || L_ADDR || '>';
MY_ADDRESS_LIST(J) := L_ADDR;
ELSIF P_SPLITE_FLAG = 2 THEN
MY_ACCT_LIST(J) := L_ADDR;
END IF;
END IF;
END LOOP;
END;
------------------------------------------------写邮件头和邮件内容------------------------------------------
PROCEDURE WRITE_DATA(P_CONN IN OUT NOCOPY UTL_SMTP.CONNECTION,
P_NAME IN VARCHAR2,
P_VALUE IN VARCHAR2,
P_SPLITE VARCHAR2 DEFAULT ':',
P_CRLF VARCHAR2 DEFAULT L_CRLF) IS
BEGIN
/ utl_raw.cast_to_raw 对解决中文乱码问题很重要*/
UTL_SMTP.WRITE_RAW_DATA(P_CONN,
UTL_RAW.CAST_TO_RAW(CONVERT(P_NAME || P_SPLITE ||
P_VALUE || P_CRLF,
'ZHS16GBK')));
END;
----------------------------------------写MIME邮件尾部-----------------------------------------------------
PROCEDURE END_BOUNDARY(CONN IN OUT NOCOPY UTL_SMTP.CONNECTION,
LAST IN BOOLEAN DEFAULT FALSE) IS
BEGIN
UTL_SMTP.WRITE_DATA(CONN, UTL_TCP.CRLF);
IF (LAST) THEN
UTL_SMTP.WRITE_DATA(CONN, LAST_BOUNDARY);
END IF;
END;
----------------------------------------------发送附件----------------------------------------------------
PROCEDURE ATTACHMENT(CONN IN OUT NOCOPY UTL_SMTP.CONNECTION,
MIME_TYPE IN VARCHAR2 DEFAULT 'text/plain',
INLINE IN BOOLEAN DEFAULT TRUE,
FILENAME IN VARCHAR2 DEFAULT 't.txt',
TRANSFER_ENC IN VARCHAR2 DEFAULT '7 bit',
DT_NAME IN VARCHAR2 DEFAULT '0') IS
L_FILENAME VARCHAR2(1000);
BEGIN
--写附件头
UTL_SMTP.WRITE_DATA(CONN, FIRST_BOUNDARY);
--设置附件格式
WRITE_DATA(CONN, 'Content-Type', MIME_TYPE);
--如果文件名称非空,表示有附件
DROP_DIRECTORY(DT_NAME);
--创建directory
CREATE_DIRECTORY(DT_NAME, GET_FILE(FILENAME, 1));
--得到附件文件名称
L_FILENAME := GET_FILE(FILENAME, 2);
IF (INLINE) THEN
WRITE_DATA(CONN,
'Content-Disposition',
'inline; filename="' || L_FILENAME || '"');
ELSE
WRITE_DATA(CONN,
'Content-Disposition',
'attachment; filename="' || L_FILENAME || '"');
END IF;
--设置附件的转换格式
IF (TRANSFER_ENC IS NOT NULL) THEN
WRITE_DATA(CONN, 'Content-Transfer-Encoding', TRANSFER_ENC);
END IF;
UTL_SMTP.WRITE_DATA(CONN, UTL_TCP.CRLF);
--begin 贴附件内容
IF TRANSFER_ENC = 'bit 7' THEN
--如果是文本类型的附件
BEGIN
L_FILE_HANDLE := UTL_FILE.FOPEN(DT_NAME, L_FILENAME, 'r'); --打开文件
--把附件分成多份,这样可以发送超过32K的附件
LOOP
UTL_FILE.GET_LINE(L_FILE_HANDLE, L_LINE);
L_MESG := L_LINE || L_CRLF;
WRITE_DATA(CONN, '', L_MESG, '', '');
END LOOP;
UTL_FILE.FCLOSE(L_FILE_HANDLE);
END_BOUNDARY(CONN);
EXCEPTION
WHEN OTHERS THEN
UTL_FILE.FCLOSE(L_FILE_HANDLE);
END_BOUNDARY(CONN);
NULL;
END; --结束文本类型附件的处理
ELSIF TRANSFER_ENC = 'base64' THEN
--如果是二进制类型的附件
BEGIN
--把附件分成多份,这样可以发送超过32K的附件
L_FILEPOS := 1; --重置offset,在发送多个附件时,必须重置
L_FIL := BFILENAME(DT_NAME, L_FILENAME);
L_FILE_LEN := DBMS_LOB.GETLENGTH(L_FIL);
L_MODULO := MOD(L_FILE_LEN, L_AMT);
L_PIECES := TRUNC(L_FILE_LEN / L_AMT);
IF (L_MODULO <> 0) THEN
L_PIECES := L_PIECES + 1;
END IF;
DBMS_LOB.FILEOPEN(L_FIL, DBMS_LOB.FILE_READONLY);
DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF);
L_DATA := NULL;
FOR I IN 1 .. L_PIECES LOOP
L_FILEPOS := I * L_AMT + 1;
L_FILE_LEN := L_FILE_LEN - L_AMT;
L_DATA := UTL_RAW.CONCAT(L_DATA, L_BUF);
L_CHUNKS := TRUNC(UTL_RAW.LENGTH(L_DATA) / L_MAX_LINE_WIDTH);
IF (I <> L_PIECES) THEN
L_CHUNKS := L_CHUNKS - 1;
END IF;
UTL_SMTP.WRITE_RAW_DATA(CONN, UTL_ENCODE.BASE64_ENCODE(L_DATA));
L_DATA := NULL;
IF (L_FILE_LEN < L_AMT AND L_FILE_LEN > 0) THEN
L_AMT := L_FILE_LEN;
END IF;
DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF);
END LOOP;
DBMS_LOB.FILECLOSE(L_FIL);
END_BOUNDARY(CONN);
EXCEPTION
WHEN OTHERS THEN
DBMS_LOB.FILECLOSE(L_FIL);
END_BOUNDARY(CONN);
RAISE;
END; --结束处理二进制附件
END IF; --结束处理附件内容
DROP_DIRECTORY(DT_NAME);
END; --结束过程ATTACHMENT
---------------------------------------------真正发送邮件的过程--------------------------------------------
PROCEDURE P_EMAIL(P_SENDORADDRESS2 VARCHAR2, --发送地址
P_RECEIVERADDRESS2 VARCHAR2) --接受地址
IS
L_CONN UTL_SMTP.CONNECTION; --定义连接
BEGIN
/初始化邮件服务器信息,连接邮件服务器/
L_CONN := UTL_SMTP.OPEN_CONNECTION(P_SERVER, P_PORT);
UTL_SMTP.HELO(L_CONN, P_SERVER);
/* smtp服务器登录校验 */
IF P_NEED_SMTP = 1 THEN
UTL_SMTP.COMMAND(L_CONN, 'AUTH LOGIN', '');
UTL_SMTP.COMMAND(L_CONN,
UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_USER))));
UTL_SMTP.COMMAND(L_CONN,
UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_PASS))));
END IF;
/*设置发送地址和接收地址*/
UTL_SMTP.MAIL(L_CONN, P_SENDORADDRESS2);
UTL_SMTP.RCPT(L_CONN, P_RECEIVERADDRESS2);
/*设置邮件头*/
UTL_SMTP.OPEN_DATA(L_CONN);
WRITE_DATA(L_CONN, 'Date', TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));
/*设置发送人*/
WRITE_DATA(L_CONN, 'From', P_SENDOR);
/*设置接收人*/
WRITE_DATA(L_CONN, 'To', P_RECEIVER);
/*设置邮件主题*/
WRITE_DATA(L_CONN, 'Subject', P_SUB);
WRITE_DATA(L_CONN, 'Content-Type', MULTIPART_MIME_TYPE);
UTL_SMTP.WRITE_DATA(L_CONN, UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(L_CONN, FIRST_BOUNDARY);
WRITE_DATA(L_CONN, 'Content-Type', 'text/plain;charset=gb2312');
--单独空一行,否则,正文内容不显示
UTL_SMTP.WRITE_DATA(L_CONN, UTL_TCP.CRLF);
/* 设置邮件正文
把分隔符还原成chr(10)。这主要是为了shell中调用该过程,如果有多行,则先把多行的内容合并成一行,并用 l_splite分隔
然后用 l_crlf替换chr(10)。这一步是必须的,否则将不能发送邮件正文有多行的邮件
*/
WRITE_DATA(L_CONN,
'',
REPLACE(REPLACE(P_TXT, L_SPLITE, CHR(10)), CHR(10), L_CRLF),
'',
'');
END_BOUNDARY(L_CONN);
--如果文件名称不为空,则发送附件
IF (P_FILENAME IS NOT NULL) THEN
--根据逗号或者分号拆分附件地址
P_SPLITE_STR(P_FILENAME, 2);
--循环发送附件(在同一个邮件中)
FOR K IN 1 .. MY_ACCT_LIST.COUNT LOOP
ATTACHMENT(CONN => L_CONN,
FILENAME => MY_ACCT_LIST(K),
TRANSFER_ENC => P_ENCODE,
DT_NAME => L_DIRECTORY_BASE_NAME || TO_CHAR(K));
END LOOP;
END IF;
/*关闭数据写入*/
UTL_SMTP.CLOSE_DATA(L_CONN);
/*关闭连接*/
UTL_SMTP.QUIT(L_CONN);
/*异常处理*/
EXCEPTION
WHEN OTHERS THEN
NULL;
RAISE;
END;
---------------------------------------------------主过程-----------------------------------------------------
BEGIN
L_SENDORADDRESS := '<' || P_SENDOR || '>';
P_SPLITE_STR(P_RECEIVER); --处理邮件地址
FOR K IN 1 .. MY_ADDRESS_LIST.COUNT LOOP
P_EMAIL(L_SENDORADDRESS, MY_ADDRESS_LIST(K));
END LOOP;
/处理邮件地址,根据逗号分割邮件/
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
PROCSENDEMAIL('邮件内容','邮件主题','发件人','收件人','邮件服务器ip地址',25,1,'用户名','密码','','base64');
dg_prim_diag.sql
-- NAME: dg_prim_diag.sql (Run on PRIMARY with a LOGICAL or PHYSICAL STANDBY)
-- ------------------------------------------------------------------------
-- Copyright 2002, Oracle Corporation
-- LAST UPDATED: 2/23/04
--
-- Usage: @dg_prim_diag
-- ------------------------------------------------------------------------
-- PURPOSE:
-- This script is to be used to assist in collection information to help
-- troubeshoot Data Guard issues with an emphasis on Logical Standby.
-- ------------------------------------------------------------------------
-- DISCLAIMER:
-- This script is provided for educational purposes only. It is NOT
-- supported by Oracle World Wide Technical Support.
-- The script has been tested and appears to work as intended.
-- You should always run new scripts on a test instance initially.
-- ------------------------------------------------------------------------
-- Script output is as follows:
set echo off
set feedback off
column timecol new_value timestamp
column spool_extension new_value suffix
select to_char(sysdate,'Mondd_hhmi') timecol,
'.out' spool_extension from sys.dual;
column output new_value dbname
select value || '_' output
from v$parameter where name = 'db_name';
spool dg_prim_diag_&&dbname&×tamp&&suffix
set linesize 79
set pagesize 35
set trim on
set trims on
alter session set nls_date_format = 'MON-DD-YYYY HH24:MI:SS';
set feedback on
select to_char(sysdate) time from dual;
set echo on
-- In the following the database_role should be primary as that is what
-- this script is intended to be run on. If protection_level is different
-- than protection_mode then for some reason the mode listed in
-- protection_mode experienced a need to downgrade. Once the error
-- condition has been corrected the protection_level should match the
-- protection_mode after the next log switch.
column role format a7 tru
column name format a10 wrap
select name,platform_id,database_role role,log_mode,
flashback_on flashback,protection_mode,protection_level
from v$database;
-- ARCHIVER can be (STOPPED | STARTED | FAILED). FAILED means that the
-- archiver failed to archive a log last time, but will try again within 5
-- minutes. LOG_SWITCH_WAIT The ARCHIVE LOG/CLEAR LOG/CHECKPOINT event log
-- switching is waiting for. Note that if ALTER SYSTEM SWITCH LOGFILE is
-- hung, but there is room in the current online redo log, then value is
-- NULL
column host_name format a20 tru
column version format a9 tru
select instance_name,host_name,version,archiver,log_switch_wait
from v$instance;
-- The following query give us information about catpatch.
-- This way we can tell if the procedure doesn't match the image.
select version, modified, status from dba_registry
where comp_id = 'CATPROC';
-- Force logging is not mandatory but is recommended. Supplemental
-- logging must be enabled if the standby associated with this primary is
-- a logical standby. During normal operations it is acceptable for
-- SWITCHOVER_STATUS to be SESSIONS ACTIVE or TO STANDBY.
column force_logging format a13 tru
column remote_archive format a14 tru
column dataguard_broker format a16 tru
select force_logging,remote_archive,
supplemental_log_data_pk,supplemental_log_data_ui,
switchover_status,dataguard_broker
from v$database;
-- This query produces a list of all archive destinations. It shows if
-- they are enabled, what process is servicing that destination, if the
-- destination is local or remote, and if remote what the current mount ID
-- is.
column destination format a35 wrap
column process format a7
column archiver format a8
column ID format 99
column mid format 99
select dest_id "ID",destination,status,target,
schedule,process,mountid mid
from v$archive_dest order by dest_id;
-- This select will give further detail on the destinations as to what
-- options have been set. Register indicates whether or not the archived
-- redo log is registered in the remote destination control file.
set numwidth 8
column ID format 99
select dest_id "ID",archiver,transmit_mode,affirm,async_blocks async,
net_timeout net_time,delay_mins delay,reopen_secs reopen,
register,binding
from v$archive_dest order by dest_id;
-- The following select will show any errors that occured the last time
-- an attempt to archive to the destination was attempted. If ERROR is
-- blank and status is VALID then the archive completed correctly.
column error format a55 wrap
select dest_id,status,error from v$archive_dest;
-- The query below will determine if any error conditions have been
-- reached by querying the v$dataguard_status view (view only available in
-- 9.2.0 and above):
column message format a80
select message, timestamp
from v$dataguard_status
where severity in ('Error','Fatal')
order by timestamp;
-- The following query will determine the current sequence number
-- and the last sequence archived. If you are remotely archiving
-- using the LGWR process then the archived sequence should be one
-- higher than the current sequence. If remotely archiving using the
-- ARCH process then the archived sequence should be equal to the
-- current sequence. The applied sequence information is updated at
-- log switch time.
select ads.dest_id,max(sequence#) "Current Sequence",
max(log_sequence) "Last Archived"
from v$archived_log al, v$archive_dest ad, v$archive_dest_status ads
where ad.dest_id=al.dest_id
and al.dest_id=ads.dest_id
and al.resetlogs_change#=(select max(resetlogs_change#) from v$archived_log )
group by ads.dest_id;
-- The following select will attempt to gather as much information as
-- possible from the standby. SRLs are not supported with Logical Standby
-- until Version 10.1.
set numwidth 8
column ID format 99
column "SRLs" format 99
column Active format 99
select dest_id id,database_mode db_mode,recovery_mode,
protection_mode,standby_logfile_count "SRLs",
standby_logfile_active ACTIVE,
archived_seq#
from v$archive_dest_status;
-- Query v$managed_standby to see the status of processes involved in
-- the shipping redo on this system. Does not include processes needed to
-- apply redo.
select process,status,client_process,sequence#
from v$managed_standby;
-- The following query is run on the primary to see if SRL's have been
-- created in preparation for switchover.
select group#,sequence#,bytes from v$standby_log;
-- The above SRL's should match in number and in size with the ORL's
-- returned below:
select group#,thread#,sequence#,bytes,archived,status from v$log;
-- Non-default init parameters.
set numwidth 5
column name format a30 tru
column value format a48 wra
select name, value
from v$parameter
where isdefault = 'FALSE';
spool off
通过隐含参数强制打开数据库
通过隐含参数强制打开数据库
rman恢复完成后,有可能出现数据文件SCN不一致。
正常情况:FUZZY=YES或FUZZY=NO + 所有SCN一致
SQL> select hxfil FILENUMBER, fhsta STATUS,fhscn SCN,fhrba_Seq SEQUENCE,
FHAFS "absolute fuzzy scn", decode(hxifz, 0,'NO', 1,'YES', NULL) FUZZY
from x$kcvfh order by FILENUMBER;
FILENUMBER STATUS SCN SEQUENCE absolute fuzzy s FUZ
---------- ---------- ---------------- ---------- ---------------- ---
1 8196 9468541326647 2710 0 YES
2 4 9468541326647 2710 0 YES
3 4 9468541326647 2710 0 YES
4 4 9468541326647 2710 0 YES
5 4 9468541326647 2710 0 YES
6 4 9468541326647 2710 0 YES
7 4 9468541326647 2710 0 YES
异常情况:
select hxfil FILENUMBER, fhsta STATUS,fhscn SCN,fhrba_Seq SEQUENCE,
FHAFS "absolute fuzzy scn", decode(hxifz, 0,'NO', 1,'YES', NULL) FUZZY
from x$kcvfh order by FILENUMBER;
FILENUMBER STATUS SCN SEQUENCE absolute fuzzy scn FUZZY
---------- ---------- -------------------------------- ---------- -------------------------------- ------
1 8192 9468541325983 2708 0 NO
2 0 9468541325983 2708 0 NO
3 0 9468541325984 2708 0 NO
4 0 9468541325985 2708 0 NO
5 0 9468541325985 2708 0 NO
6 0 9468541325982 2708 0 NO
7 0 9468541325984 2708 0 NO
原理:
FUZZY就是指执行过检查点以后,data file中的有些block又发生了更改,这时data file中的有些block的SCN号就比data file header中的checkpoint_change#大。
所以当恢复data file时,至少要恢复到data file中block中的最大SCN号以后才能open。
另外,在数据库open时,data file随时有可能会更新,所以一般open状态下FUZZY都是yes
查询恢复开始的SCN
After restore is completed, run below query. This will show the SCN from where recovery will START:
SQL> select min(fhscn) from x$kcvfh where hxfil in (select file# from v$datafile where enabled='READ WRITE');
MIN(FHSCN)
--------------------------------
9468541325982
应该恢复到的SCN
Below query will show the SCN up to which you MUST recover to clear the fuzziness of the restored datafiles:
SQL> select max(greatest(FHAFS,FHSCN)) from x$kcvfh where hxfil in (select file# from v$datafile where enabled='READ WRITE');
MAX(GREATEST(FHAFS,FHSCN))
--------------------------------
9468541325985
根据FUZZY SCN找到至少要恢复到的redo sequence
select thread#,sequence#,first_change#,next_change#, 'Archive log' TYPE from v$archived_log a,v$database d
where &FUZZY_SCN between first_change# and next_change#
and d.RESETLOGS_CHANGE#=a.RESETLOGS_CHANGE#
union all
select thread#,sequence#,first_change#,null next_change#,'Redo log' TYPE from v$log
where &FUZZY_SCN > first_change# and ARCHIVED='NO'
/
Enter value for fuzzy_scn: 9468541325985
old 2: where &FUZZY_SCN between first_change# and next_change#
new 2: where 9468541325985 between first_change# and next_change#
Enter value for fuzzy_scn: 9468541325985
old 6: where &FUZZY_SCN > first_change# and ARCHIVED='NO'
new 6: where 9468541325985 > first_change# and ARCHIVED='NO'
THREAD# SEQUENCE# FIRST_CHANGE# NEXT_CHANGE# TYPE
---------- ---------- ------------- ------------ ----------------------
1 2708 9.4685E+12 9.4685E+12 Archive log
1 2708 9.4685E+12 9.4685E+12 Archive log
打开数据库
SQL> alter database open resetlogs;
alter database open resetlogs
*
ERROR at line 1:
ORA-01152: file 3 was not restored from a sufficiently old backup
ORA-01110: data file 3: '/oradata/greta2/sysaux01.dbf'
如果没有该序列的日志,无法清除FUZZY,就需要使用_allow_resetlogs_corruption=true来强制打开数据库
alter system set "_allow_resetlogs_corruption"=true scope=spfile sid='*';
查询状态
SQL> select
2 x.ksppinm name,
3 y.ksppstvl value,
4 y.ksppstdf isdefault,
5 decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod,
6 decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj
7 from
8 sys.x$ksppi x,
9 sys.x$ksppcv y
10 where
11 x.inst_id = userenv('Instance') and
12 y.inst_id = userenv('Instance') and
13 x.indx = y.indx and x.ksppinm ='_allow_resetlogs_corruption';
NAME VALUE ISDEFAULT ISMOD ISADJ
------------------------------ ---------- ------------------ -------------------- ----------
_allow_resetlogs_corruption TRUE FALSE FALSE FALSE
SQL> alter database open resetlogs;
Database altered.
再次查询FUZZY和SCN状态,已经保持一致
SQL> select hxfil FILENUMBER, fhsta STATUS,fhscn SCN,fhrba_Seq SEQUENCE,
2 FHAFS "absolute fuzzy scn", decode(hxifz, 0,'NO', 1,'YES', NULL) FUZZY
3 from x$kcvfh order by FILENUMBER;
FILENUMBER STATUS SCN SEQUENCE absolute fuzzy scn FUZZY
---------- ---------- -------------------------------- ---------- -------------------------------- ------
1 8196 9468541325986 1 0 YES
2 4 9468541325986 1 0 YES
3 4 9468541325986 1 0 YES
4 4 9468541325986 1 0 YES
5 4 9468541325986 1 0 YES
6 4 9468541325986 1 0 YES
7 4 9468541325986 1 0 YES
电子书
Cost Based Oracle Fundamentals
http://www.itpub.net/forum.php?mod=viewthread&tid=520706
Linux内存管理介绍及典型案例
Linux内存管理介绍及典型案例
目录
1 基本概念
1.1 虚拟内存空间管理示意图(重点理解)
1.2 虚拟内存(重点理解)
1.3 SWAP
1.4 页表(重点理解)
1.5 Translation Lookaside Buffer (TLB)与缺页中断(初学了解即可)
1.6 进程的内存结构
1.7 共享内存(重点理解)
1.1 程序段与lib(初学了解即可)
1.2 内存碎片(初学了解即可)
1.3 Slab内存(初学了解即可)
1.4 大页(重点理解)
1.5 内存黑洞 (初学了解即可)
1.6 AnonPages(初学了解即可)
2 基本命令与文件
2.1 free(重点理解)
2.2 pmap(初学了解即可)
2.3 Vmstat(初学了解即可)
2.4 ps
2.5 atop(重点理解)
2.6 /proc
2.6.1 /proc/meminfo(重点理解)
2.6.2 /proc/slabinfo
2.6.3 /proc/buddyinfo
2.6.4 /proc/vmallocinfo
2.6.5 /proc/sys/vm/drop_caches(强制释放内存,慎用)
2.6.6 /proc/swaps
2.6.7 /proc//status(重点理解)
2.6.8 /proc//statm
2.6.9 /proc//smaps(重点理解)
2.6.10 /proc//maps
3 典型故障
3.1 Free不足发生SWAP交换(未确认根因)
3.2 Oracle进程未启用大页导致页表过大
3.3 /dev/shm中残留文件导致内存不足
3.4 NBU备份操作系统时导致内存不足
1 基本概念
1.1 虚拟内存空间管理示意图(重点理解)
1.2 虚拟内存(重点理解)
为了使程序、数据、堆栈的总大小可以超过可用物理内存的大小,操作系统把程序当前使用的那些部分加载到物理内存里,而不使用的部分则暂不加载。应用分配内存时,系统只是分配一个虚拟的地址空间,并不直接分配物理内存;当有实际的内存访问时,系统才会将虚拟地址映射到物理内存的一个地址上。
整个系统的虚拟内存大小可以通过/proc/meminfo中的VmallocTotal来查看,每个进程的虚拟内存大小可以通过ps aux中的SZ来查看,pmap也可以查看。
1.3 SWAP
使用的物理内存会保存到磁盘中,这一部分被称作SWAP。虚拟内存地址空间:物理内存+SWAP+未分配空间。
1.4 页表(重点理解)
Linux虚拟内存管理过程中,会把物理内存映射为虚拟内存,维护这个映射关系的就是Page Table这个表,每个PTE(Page table entry)的大小为8字节。每个进程都有一个页表,页表负责将虚拟内存地址转换成物理内存地址,所以虚拟内存中未分配部分是没有页表项的。因为SWAP是从物理内存交换到磁盘上的,所以SWAP也有对应的页表项。在页表中,在物理内存的页表项标记为valid(1),在SWAP中的页表项标记为invalid(0)
每个页(4k)需要使用一个页表项(PTE)来管理,所以一个进程对应的页表大小为
(物理内存+SWAP)/4k*8字节
整个系统的页表可以通过查询/proc/meminfo来查询,每个进程的页表大小可以查看/proc//status中的VmPTE大小
1.5 Translation Lookaside Buffer (TLB)与缺页中断(初学了解即可)
CPU的内存管理单元(memory management unit MMU,也称为存储器管理单元,是硬件设备,它被保存在主存main memory的两级页表控制)会缓存最近用过的页表,这个页表的缓存叫做Translation Lookaside Buffer (TLB)。如果没有TLB,每次访问内存需要访问页表内存和数据内存,会产生两次读内存操作。
大概过程如下(不包含异常场景,如内存访问越界或者无法分配)
1)当CPU将需要将虚拟内存地址映射成物理地址时,会先检查TLB,如果找到对应的记录(TLB hit),返回物理内存地址。(TLB中缓存的页表对应的页都在物理内存中,没有在swap中对应的页表项)TLB hit以后还会检查数据是否在CPU的cache中,如果没有在cache中,需要从内存中将数据读到CPU的cache中,然后再使用;
2)如果TLB中没有记录(TLB miss),会在page table中查找;
3)如果page table中有记录且未在swap中,更新TLB以后访问物理内存;
4)如果page table中无记录或者内存在SWAP中,此时会产生缺页中断;
5)如果page table中无记录,则调用do_no_page()新申请内存,并建立映射;
6)如果page table中有记录但是内存在swap中,则调用do_swap_page(),从交换设备换入此页面。
“tlb miss page fault”的图片搜索结果 https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Page_table_actions.svg/625px-Page_table_actions.svg.png
https://www.cs.auckland.ac.nz/~jmor159/363/html/fig/mem_op.gif
缺页中断可分为主缺页中断(Major Page Fault)和次缺页中断(Minor Page Fault),要从磁盘读取数据而产生的中断是主缺页中断;数据已经被读入内存并被缓存起来,从内存缓存区中而不是直接从硬盘中读取数据而产生的中断是次缺页中断。
1.6 进程的内存结构
注意:操作系统版本不一样,可能分布不一样
http://img.blog.csdn.net/20140904215636015?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmd6aGVianV0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码。
初始化过的数据(Data):在程序运行初已经对变量进行初始化的数据。
未初始化过的数据(BSS):在程序运行初未对变量进行初始化的数据。
栈 (Stack):存储局部、临时变量,函数调用时,存储函数的返回指针,用于控制函数的调用和返回。在程序块开始时自动分配内存,结束时自动释放内存,其操作方式类似于数据结构中的栈。
堆 (Heap):存储动态内存分配,需要程序员手工分配,手工释放.注意它与数据结构中的堆是两回事,分配方式类似于链表。
1.7 共享内存(重点理解)
程序可以申请共享内存(shared memory),共享内存多个进程都可以访问。
除了共享内存,程序使用的动态链接库(library)及程序自己的程序段也是可以共享的。
共享情况下,每个进程使用这些共享的内存,都会生成页表项
共享内存:
[oracle@host2 ~]:ora11g> ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 196611 oracle 640 16777216 24
0x00000000 229380 oracle 640 1660944384 24
0x8945ce40 262149 oracle 640 2097152 24
0x00000000 589830 oracle 640 16777216 40
0x00000000 622599 oracle 640 1660944384 40
0x15dd8db4 655368 oracle 640 2097152 40
/proc/meminfo中的Shmem统计的内容包括:shared memory和tmpfs。
shared memory又包括:
SysV shared memory [shmget etc.]
POSIX shared memory [shm_open etc.]
shared anonymous mmap [ mmap(…MAP_ANONYMOUS|MAP_SHARED…)]
因为shared memory在内核中都是基于tmpfs实现的,参见:
https://www.kernel.org/doc/Documentation/filesystems/tmpfs.txt
也就是说它们被视为基于tmpfs文件系统的内存页,既然基于文件系统,就不算匿名页,所以不被计入/proc/meminfo中的AnonPages,而是被统计进了:
1)Cached (i.e. page cache)
2)Mapped (当shmem被attached时候)
然而它们背后并不存在真正的硬盘文件,一旦内存不足的时候,它们是需要交换区才能swap-out的,所以在LRU lists里,它们被放在:
1)Inactive(anon) 或 Active(anon)
注:虽然它们在LRU中被放进了anon list,但是不会被计入 AnonPages。这是shared memory & tmpfs比较拧巴的一个地方,需要特别注意。
2)unevictable (如果被locked的话)
注意:
当shmget/shm_open/mmap创建共享内存时,物理内存尚未分配,要直到真正访问时才分配。/proc/meminfo中的 Shmem 统计的是已经分配的大小,而不是创建时申请的大小。
1.1 程序段与lib(初学了解即可)
进程共享library
https://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/images/Chapter9/9_03_SharedLibrary.jpg
1.2 内存碎片(初学了解即可)
/proc/buddyinfo是linuxbuddy系统管理物理内存的debug信息。在Linux中使用buddy算法解决物理内存的外碎片问题,其把所有空闲的内存,以2的幂次方的形式,分成11个块链表,分别对应为1、2、4、8、16、32、64、128、256、512、1024个页块。而Linux支持NUMA技术,对于NUMA设备,NUMA系统的结点通常是由一组CPU和本地内存组成,每一个节点都有相应的本地内存,因此buddyinfo 中的Node0表示节点ID;而每一个节点下的内存设备,又可以划分为多个内存区域(zone),因此下面的显示中,对于Node0的内存,又划分类DMA、Normal、HighMem区域。而后面则是表示空闲的区域。
此处以Normal区域进行分析,第二列值为100,表示当前系统中normal区域,可用的连续两页的内存大小为1002PAGE_SIZE;第三列值为52,表示当前系统中normal区域,可用的连续四页的内存大小为522^2PAGE_SIZE
[oracle@host2 ~]:ora11g> cat /proc/buddyinfo
Node 0, zone DMA 0 1 0 1 2 1 1 0 1 1 3
Node 0, zone DMA32 9 6 4 6 7 6 2 4 6 4 836
Node 0, zone Normal 1613 303 328 300 400 27 19 11 4 3 342
小的内存页越多,说明碎片越多。
1.3 Slab内存(初学了解即可)
以页为最小单位分配内存对于内核管理系统物理内存来说的确比较方便,但内核自身最常使用 的内存却往往是很小(远远小于一页)的内存块——比如存放文件描述符、进程描述符、虚拟内存区域描述符等行为所需的内存都不足一页。这些用来存放描述符的 内存相比页面而言,就好比是面包屑与面包。一个整页中可以聚集多个这种这些小块内存;而且这些小块内存块也和面包屑一样频繁地生成/销毁。
为了满足内核对这种小内存块的需要,Linux系统采用了一种被称为slab分配器的技术。Slab分配器的实现相当复杂,但原理不难,其核心**就是“存储池”的运用。内存片段(小块内存)被看作对象,当被使用完后,并不直接释放而是被缓存到“存储池”里,留做下次使用,这无疑避免了频繁创建与销毁对象所带来的额外负载。SLAB分配器使得一个页面内众多小块内存可独立被分配使用,避免了内部分片,节约了空闲内存 。
Linux内存管理层次关系图:
1.4 大页(重点理解)
4KB 大小的页面在“分页机制”提出的时候是合理的,因为当时的内存大小不过几十兆字节,然而当物理内存容量增长到几 G 甚至几十 G 的时候,操作系统仍然以 4KB 大小为页面的基本单位,是否依然合理呢?
在 Linux 操作系统上运行内存需求量较大的应用程序时,由于其采用的默认页面大小为 4KB,因而将会产生较多 TLB Miss 和缺页中断,从而大大影响应用程序的性能。当操作系统以 2MB 甚至更大作为分页的单位时,将会大大减少 TLB Miss 和缺页中断的数量,显著提高应用程序的性能。这也正是 Linux 内核引入大页面支持的直接原因。好处是很明显的,假设应用程序需要 2MB 的内存,如果操作系统以 4KB 作为分页的单位,则需要 512 个页面,进而在 TLB 中需要 512 个表项,同时也需要 512 个页表项,操作系统需要经历至少 512 次 TLB Miss 和 512 次缺页中断才能将 2MB 应用程序空间全部映射到物理内存;然而,当操作系统采用 2MB 作为分页的基本单位时,只需要一次 TLB Miss 和一次缺页中断,就可以为 2MB 的应用程序空间建立虚实映射,并在运行过程中无需再经历 TLB Miss 和缺页中断(假设未发生 TLB 项替换和 Swap)。
另外对于Oracle等使用共享内存的应用,如果共享内存很大,并发进程又很多的时候,会产生放大效应,如Oracle共享内存大小为10G,每个进程都已经映射了所有的共享内存,这时一个Oracle进程**享内存对应的页表大小为
10G/4k8字节=20M
如果有500个进程,这500个进程共享内存对应的页表则为20M500=10G,一般Oracle进程共享内存设置为物理内存的40%~60%。10G共享内存+10G页表=20G,对于一个24G物理内存的服务器,此时内存基本上就用光了,所以对于Oracle数据库,对于24G以上的服务器,如果页表过大,需要使用大页。
在linux操作系统中,大页通过设置内核参数vm.nr_hugepages(大页个数,默认大页单位是2M,如果要分配2048M大页,则vm.nr_hugepages设置为1000)启用,一旦启用,不管是否有进程使用,系统都已经分配出去,查看大页可以看/proc/meminfo中hugepage。
关于Oracle启用大页整改,参考如下,有详细的设置大页方法
A&S235-20170413关于Linux平台运行Oracle需要开启hugepage的整改公告
http://support.huawei.com/carrier/docview!docview?nid=SC2000006918&path=PBI1-7275733/PBI1-8132342/PBI1-8132344/PBI1-68785
1.5 内存黑洞 (初学了解即可)
追踪Linux系统的内存使用一直是个难题,很多人试着把能想到的各种内存消耗都加在一起,kernel text、kernel modules、buffer、cache、slab、page table、process RSS…等等,却总是与物理内存的大小对不上,这是为什么呢?因为Linux kernel并没有滴水不漏地统计所有的内存分配,kernel动态分配的内存中就有一部分没有计入/proc/meminfo中。
我们知道,Kernel的动态内存分配通过以下几种接口:
alloc_pages/__get_free_page: 以页为单位分配
vmalloc: 以字节为单位分配虚拟地址连续的内存块
slab allocator
kmalloc: 以字节为单位分配物理地址连续的内存块,它是以slab为基础的,使用slab层的general caches — 大小为2^n,名称是kmalloc-32、kmalloc-64等(在老kernel上的名称是size-32、size-64等)。
通过slab层分配的内存会被精确统计,可以参见/proc/meminfo中的slab/SReclaimable/SUnreclaim;
通过vmalloc分配的内存也有统计,参见/proc/meminfo中的VmallocUsed 和 /proc/vmallocinfo(下节中还有详述);
而通过alloc_pages分配的内存不会自动统计,除非调用alloc_pages的内核模块或驱动程序主动进行统计,否则我们只能看到free memory减少了,但从/proc/meminfo中看不出它们具体用到哪里去了。比如在VMware guest上有一个常见问题,就是VMWare ESX宿主机会通过guest上的Balloon driver(vmware_balloon module)占用guest的内存,有时占用得太多会导致guest无内存可用,这时去检查guest的/proc/meminfo只看见MemFree很少、但看不出内存的去向,原因就是Balloon driver通过alloc_pages分配内存,没有在/proc/meminfo中留下统计值,所以很难追踪。
1.6 AnonPages(初学了解即可)
用户进程的内存页分为两种:file-backed pages(与文件对应的内存页),和anonymous pages(匿名页)。Anonymous pages(匿名页)的数量统计在/proc/meminfo的AnonPages中。
以下是几个事实,有助于了解Anonymous Pages:
1)所有page cache里的页面(Cached)都是file-backed pages,不是Anonymous Pages。
注:shared memory 不属于 AnonPages,而是属于Cached,因为shared memory基于tmpfs,所以被视为file-backed、在page cache里,上一节解释过。
2)mmap private anonymous pages属于AnonPages(Anonymous Pages),而mmap shared anonymous pages属于Cached(file-backed pages),因为shared anonymous mmap也是基于tmpfs的
3)Anonymous Pages是与用户进程共存的,一旦进程退出,则Anonymous pages也释放,不像page cache即使文件与进程不关联了还可以缓存。
AnonPages统计值中包含了Transparent HugePages (THP)对应的 AnonHugePages 。
2 基本命令与文件
2.1 free(重点理解)
如下显示free是显示的当前内存的使用,-m的意思是MB来显示内容.我们来一起看看.
[oracle@host2 ~]:ora11g> free -m
total used free shared buffers cached
Mem: 32089 27277 4811 0 171 25507
-/+ buffers/cache: 1599 30489
Swap: 4093 0 4093
第一部分Mem行:
total 内存总数: 23641M (表示物理内存24G)
used 已经使用的内存数: 9942M
free 空闲的内存数: 13698M
shared 当前已经废弃不用,总是0
buffers Buffer 设备数据缓存内存数: 491M
cached Page 文件数据的缓存内存数:3007M
关系:total(23641M) = used(9942M) + free(13698M)
第二部分(-/+ buffers/cache):
(-buffers/cache) used内存数:286M (指的第一部分Mem行中的used - buffers - cached)
(+buffers/cache) free内存数: 715M (指的第一部分Mem行中的free + buffers + cached)
Linux为了提高磁盘和内存存取效率, 除了对dentry进行缓存(用于VFS,加速文件路 径名到inode的转换), 还采取了两种主要Cache方式:Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache能有效缩短了 I/O系统调用(比如read,write,getdents)的时间。
page cache和buffer cache最大的差别在于:page cache是对文件数据的缓存;buffer cache是对设备数据的缓存。两者在实现上差别不是很大,都是采用radix树进行管理。
2.2 pmap(初学了解即可)
查看进程的内存分布情况
名称:
pmap - report memory map of a process(查看进程的内存映像信息)
用法
pmap [ -x | -d ] [ -q ] pids...
pmap -V
选项含义
-x extended Show the extended format. 显示扩展格式,suse linux无此参数
-d device Show the device format. 显示设备格式
-q quiet Do not display some header/footer lines. 不显示头尾行
-V show version Displays version of program. 显示版本
VSS- Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS- Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS- Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存),计算Oracle数据库使用的实际物理内存建议使用这列
USS- Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存),suse linux无此列
一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS
Dirty: 脏页的字节数(包括共享和私有的)(KB)
SWAP:swap使用情况
PERM:权限,r = read w = write x = execute s = shared p = private (copy on write)
VSS (reported as VSZ from ps) is the total accessible address space of a process.This size also includes memory that may not be resident in RAM like mallocs that have been allocated but not written to. VSS is of very little use for determing real memory usage of a process.
RSS is the total memory actually held in RAM for a process. RSS can be misleading, because it reports the total all of the shared libraries that the process uses, even though a shared library is only loaded into memory once regardless of how many processes use it. RSS is not an accurate representation of the memory usage for a single process.
PSS differs from RSS in that it reports the proportional size of its shared libraries, i.e. if three processes all use a shared library that has 30 pages, that library will only contribute 10 pages to the PSS that is reported for each of the three processes. PSS is a very useful number because when the PSS for all processes in the system are summed together, that is a good representation for the total memory usage in the system. When a process is killed, the shared libraries that contributed to its PSS will be proportionally distributed to the PSS totals for the remaining processes still using that library. In this way PSS can be slightly misleading, because when a process is killed, PSS does not accurately represent the memory returned to the overall system.
USS is the total private memory for a process, i.e. that memory that is completely unique to that process.USS is an extremely useful number because it indicates the true incremental cost of running a particular process. When a process is killed, the USS is the total memory that is actually returned to the system. USS is the best number to watch when initially suspicious of memory leaksin a process.
http://www.software-architect.net/fileadmin/user_upload/blog/pmap.png
2.3 Vmstat(初学了解即可)
Vmstat 2 10
每隔2s取一次数据,重复10次
[oracle@host2 ~]:ora11g> vmstat 2 10
procs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 4925428 175108 26120388 0 0 0 3 1 0 0 0 100 0 0
1 0 0 4925428 175108 26120408 0 0 0 0 2094 4114 0 0 100 0 0
0 0 0 4930752 175108 26120420 0 0 0 32 2109 4123 0 0 100 0 0
0 0 0 4931188 175108 26120420 0 0 0 65 2201 4194 0 0 100 0 0
0 0 0 4931220 175108 26120388 0 0 0 0 2064 4101 0 0 100 0 0
0 0 0 4931220 175108 26120388 0 0 0 40 2096 4131 0 0 100 0 0
1 0 0 4931252 175108 26120352 0 0 0 32 2174 4115 0 0 100 0 0
0 0 0 4931220 175108 26120348 0 0 0 0 2056 4095 0 0 100 0 0
0 0 0 4931904 175108 26120304 0 0 0 32 2293 4175 0 0 100 0 0
0 0 0 4931912 175108 26120304 0 0 0 33 2086 4128 0 0 100 0 0
r 表示运行队列(就是说多少个进程真的分配到CPU),我测试的服务器目前CPU比较空闲,没什么程序在跑,当这个值超过了CPU数目,就会出现CPU瓶颈了。这个也和top的负载有关系,一般负载超过了3就比较高,超过了5就高,超过了10就不正常了,服务器的状态很危险。top的负载类似每秒的运行队列。如果运行队列过大,表示你的CPU很繁忙,一般会造成CPU使用率很高。
b 表示阻塞的进程。如果长时间出现b>0,说明系统runq过高,CPU过忙。此字段对应的就是RUNQ,非常重要的概念。
swpd 虚拟内存已使用的大小,如果大于0,表示你的机器物理内存不足了,如果不是程序内存泄露的原因,那么你该升级内存了或者把耗内存的任务迁移到其他机器。
free 同free命令
buff 同free命令
cache 同free命令
si 每秒从磁盘读入虚拟内存的大小,如果这个值大于0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉。我的机器内存充裕,一切正常。
so 每秒虚拟内存写入磁盘的大小,如果这个值大于0,同上。
bi 块设备每秒接收的块数量,这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是1024byte,我本机上没什么IO操作,所以一直是0,但是我曾在处理拷贝大量数据(2-3T)的机器上看过可以达到140000/s,磁盘写入速度差不多140M每秒
bo 块设备每秒发送的块数量,例如我们读取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO过于频繁,需要调整。
in 每秒CPU的中断次数,包括时间中断
cs 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。
us 用户CPU时间。
sy 系统CPU时间,如果太高,表示系统调用时间长,例如是IO操作频繁。
id 空闲 CPU时间,一般来说,id + us + sy = 100,一般我认为id是空闲CPU使用率,us是用户CPU使用率,sy是系统CPU使用率。
wa 等待IO CPU时间。
2.4 ps
[oracle@host2 ~]:ora11g> ps aux|head -5
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 25280 1204 ? Ss Apr04 1:46 init [5]
root 2 0.0 0.0 0 0 ? S Apr04 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S Apr04 8:09 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S Apr04 0:00 [kworker/u:0]
sz:进程映像所占用的物理页面数量,也就是以物理页面为单位表示的虚拟内存大小;
rss:进程当前所占用的物理内存大小,单位为kB;
vsz:进程的虚拟内存大小,单位为kB
2.5 atop(重点理解)
MEM行:同free输出的第一行
SWAP:同free输出的第三行
Vmcom:已经提交的虚拟内存空间大小
Vmlim:提交虚拟内存空间的最大限制,默认为swap分区大小乘以一半的内存大小
PAG:
Scan: scanned pages (`scan') due to the fact that free memory drops below a particular threshold
Stall:The number times that the kernel tries to reclaim pages due to an urgent need
swin、swout:换入和换出内存页数
进程信息:(按m以后会按内存排序)
MINFLT:次缺页中断
MAJFLT:主缺页中断
VGROW:进程自上一采样周期到当前虚拟内存增长大小,此字段一般用来看找内存突然上涨的进程
RGROW:进程自上一采样周期到当前物理内存增长大小,此字段一般用来看找内存突然上涨的进程
2.6 /proc
/proc下面记录了各个进程和整个系统的各种运行信息,可以通过man proc来查看具体信息(注意选5)
[oracle@host2 ~]:ora11g> man proc
Man: find all matching manual pages
- proc (n)
proc (5)
Man: What manual page do you want?
Man: 5
内存相关的主要文件如下
2.6.1 /proc/meminfo(重点理解)
# cat meminfo
MemTotal: 49354936 kB 物理内存大小
MemFree: 32365572 kB 空闲内存大小
Buffers: 428204 kB buffer内存
Cached: 1822192 kB cache内存
SwapCached: 0 kB 被高速缓冲存储器(cache memory)用的交换空间的大小 已经被交换出来的内存,但仍然被存放在swapfile中。用来在需要的时候很快的被替换而不需要再次打开I/O端口。
Active: 8021940 kB The total amount of buffer or page cache memory, that is in active use. This is memory that has been recently used and is usually not reclaimed for other purposes. This value is the sum of memory claimed by anonymous pages (listed as Active(anon)) and file-backed pages (listed as Active(file))
Inactive: 1324228 kB The total amount of buffer or page cache memory, that are free and available. This is memory that has not been recently used and can be reclaimed for other purposes. This value is the sum of memory claimed by anonymous pages (listed as Inactive(anon)) and file-backed pages (listed as Inactive(file)).
Active(anon): 7099616 kB
Inactive(anon): 3684 kB
Active(file): 922324 kB
Inactive(file): 1320544 kB
Unevictable: 6421728 kB The amount of memory discovered by the pageout code, that is not evictable because it is locked into memory by user programs.
Mlocked: 54668 kB The total amount of memory that is not evictable because it is locked into memory by user programs.
SwapTotal: 0 kB SWAP内存大小
SwapFree: 0 kB SWAP空闲大小
Dirty: 604 kB Amount of memory that will be written to disk
Writeback: 0 kB Amount of memory that currently is written to disk
AnonPages: 13530664 kB The total amount of memory used by pages that are not backed by files and are mapped into userspace page tables.
Mapped: 63372 kB Memory claimed with the mmap system call
Shmem: 1896 kB 共享内存大小
Slab: 548208 kB Kernel data structure cache
SReclaimable: 447044 kB Reclaimable slab caches (inode, dentry, etc.)
SUnreclaim: 101164 kB The part of Slab that cannot be reclaimed even when lacking memory.
KernelStack: 14328 kB The amount of memory used by the kernel stack allocations done for each task in the system.
PageTables: 90788 kB 页表大小
NFS_Unstable: 0 kB The amount of NFS pages sent to the server but not yet committed to the stable storage.
Bounce: 0 kB The amount of memory used for the block device "bounce buffers".
WritebackTmp: 0 kB The amount of memory used by FUSE for temporary writeback buffers.
CommitLimit: 24677468 kB The total amount of memory currently available to be allocated on the system based on the overcommit ratio (vm.overcommit_ratio). This limit is only adhered to if strict overcommit accounting is enabled (mode 2 in vm.overcommit_memory).
Committed_AS: 18677832 kB An approximation of the total amount of memory (RAM plus swap) the current workload needs in the worst case
VmallocTotal: 34359738367 kB The total amount of memory of total allocated virtual address space.
VmallocUsed: 394832 kB The total amount of memory of used virtual address space.
VmallocChunk: 34334126736 kB The largest contiguous block of memory, in kilobytes, of available virtual address space.
HardwareCorrupted: 0 kB 当系统检测到内存的硬件故障时,会把有问题的页面删除掉,不再使用
AnonHugePages: 8577024 kB The total amount of memory used by huge pages that are not backed by files and are mapped into userspace page tables.
HugePages_Total: 0 大页总数
HugePages_Free: 0
HugePages_Rsvd: 0 The number of unused huge pages reserved for hugetlbfs.
HugePages_Surp: 0 The number of surplus huge pages.
Hugepagesize: 2048 kB 大页单位
DirectMap4k: 159296 kB The amount of memory mapped into kernel address space with 4 kB page mappings.
DirectMap2M: 6123520 kB The amount of memory mapped into kernel address space with 2 MB page mappings.
DirectMap1G: 44040192 kB
其他suse linux中没有的:
MemAvailable
有些应用程序会根据系统的可用内存大小自动调整内存申请的多少,所以需要一个记录当前可用内存数量的统计值,MemFree并不适用,因为MemFree不能代表全部可用的内存,系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以这部分可回收的内存加上MemFree才是系统可用的内存,即MemAvailable。/proc/meminfo中的MemAvailable是内核使用特定的算法估算出来的,要注意这是一个估计值,并不精确。
更详细参考:
/PROC/MEMINFO之谜
http://linuxperf.com/?p=142
2.6.2 /proc/slabinfo
Slab内存
[oracle@host2 ~]:ora11g> cat /proc/slabinfo |more
slabinfo - version: 2.1
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : sl
abdata <active_slabs> <num_slabs> <sharedavail>
fuse_request 0 0 608 6 1 : tunables 54 27 8 : slabdata 0 0 0
fuse_inode 0 0 768 5 1 : tunables 54 27 8 : slabdata 0 0 0
xfs_buf 1571 1590 384 10 1 : tunables 54 27 8 : slabdata 159 159 0
fstrm_item 0 0 24 144 1 : tunables 120 60 8 : slabdata 0 0 0
xfs_mru_cache_elem 0 0 32 112 1 : tunables 120 60 8 : slabdata 0 0 0
xfs_ili 2321 2340 216 18 1 : tunables 120 60 8 : slabdata 130 130 0
xfs_inode 21561 21568 1024 4 1 : tunables 54 27 8 : slabdata 5392 5392 0
xfs_efi_item 0 0 400 10 1 : tunables 54 27 8 : slabdata 0 0 0
xfs_efd_item 0 0 400 10 1 : tunables 54 27 8 : slabdata 0 0 0
xfs_buf_item 0 0 224 17 1 : tunables 120 60 8 : slabdata 0 0 0
xfs_log_item_desc 1 112 32 112 1 : tunables 120 60 8 : slabdata 1 1 0
xfs_trans 0 0 280 14 1 : tunables 54 27 8 : slabdata 0 0 0
xfs_ifork 0 0 64 59 1 : tunables 120 60 8 : slabdata 0 0 0
xfs_dabuf 0 0 24 144 1 : tunables 120 60 8 : slabdata 0 0 0
xfs_da_state 0 0 488 8 1 : tunables 54 27 8 : slabdata 0 0 0
2.6.3 /proc/buddyinfo
查看内存分布,主要用来检查是否碎片过多
[oracle@host2 ~]:ora11g> cat /proc/buddyinfo
Node 0, zone DMA 0 1 0 1 2 1 1 0 1 1 3
Node 0, zone DMA32 9 6 4 6 7 6 2 4 6 4 836
Node 0, zone Normal 1497 200 328 267 372 27 19 11 4 3 342
小的内存页越多,说明碎片越多。
2.6.4 /proc/vmallocinfo
/proc/vmallocinfo中能看到vmalloc来自哪个调用者(caller),那是vmalloc()记录下来的,相应的源代码可见:
mm/vmalloc.c: vmalloc > __vmalloc_node_flags > __vmalloc_node > __vmalloc_node_range > __get_vm_area_node > setup_vmalloc_vm
通过vmalloc分配了多少内存,可以统计/proc/vmallocinfo中的vmalloc记录,例如:
# grep vmalloc /proc/vmallocinfo | awk '{total+=$2}; END {print total}'
23375872
一些driver以及网络模块和文件系统模块可能会调用vmalloc,加载内核模块(kernel module)时也会用到,可参见 kernel/module.c。
host2:~ # more /proc/vmallocinfo
0xffffc90000000000-0xffffc90000041000 266240 legacy_kdb_init+0x115/0x19a pages=64 vmalloc N0=64
0xffffc90000041000-0xffffc90002042000 33558528 alloc_large_system_hash+0x20b/0x286 pages=8192 vmalloc vpages N0=8192
0xffffc90002042000-0xffffc90002053000 69632 alloc_large_system_hash+0x20b/0x286 pages=16 vmalloc N0=16
0xffffc90002053000-0xffffc90003054000 16781312 alloc_large_system_hash+0x20b/0x286 pages=4096 vmalloc vpages N0=4096
0xffffc90003054000-0xffffc9000305d000 36864 alloc_large_system_hash+0x20b/0x286 pages=8 vmalloc N0=8
0xffffc9000305d000-0xffffc90003061000 16384 mem_cgroup_create+0x15/0x4a0 pages=3 vmalloc N0=3
0xffffc90003062000-0xffffc90003064000 8192 acpi_os_map_memory+0x11e/0x198 phys=fc00b000 ioremap
0xffffc90003064000-0xffffc90003066000 8192 init_hypercall_stubs+0x177/0x240 [xen_platform_pci] pages=1 vmalloc N0=1
0xffffc90003066000-0xffffc90003068000 8192 acpi_os_map_memory+0x11e/0x198 phys=fc000000 ioremap
0xffffc90003068000-0xffffc9000306b000 12288 acpi_os_map_memory+0x11e/0x198 phys=fc00a000 ioremap
0xffffc9000306b000-0xffffc9000306e000 12288 alloc_large_system_hash+0x20b/0x286 pages=2 vmalloc N0=2
2.6.5 /proc/sys/vm/drop_caches(强制释放内存,慎用)
blade11:~ # cat /proc/sys/vm/drop_caches
0
To free pagecache:
echo 1 > /proc/sys/vm/drop_caches
To free dentries and inodes:
echo 2 > /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes:
echo 3 > /proc/sys/vm/drop_caches
This is a non-destructive operation and will only free things that are completely unused. Dirty objects will continue to be in use until written out to disk and are not freeable. If you run "sync" first to flush them out to disk, these drop operations will tend to free more memory.
强制释放内存仅做应急操作,尽量不要操作。
2.6.6 /proc/swaps
host2:~ # cat /proc/swaps
Filename Type Size Used Priority
/dev/xvda1 partition 4192252 0 -1
检查swap空间 ,也可以用swapon -s查看
2.6.7 /proc//status(重点理解)
进程基本情况,包括内存使用情况。注意:无法看到swap使用的情况
host2:~ # cat /proc/1/status
Name: init
State: S (sleeping)
Tgid: 1
Pid: 1
PPid: 0
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 256
Groups:
VmPeak: 25480 kB
VmSize: 25280 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 1204 kB
VmRSS: 1204 kB
VmData: 212 kB
VmStk: 136 kB
VmExe: 36 kB
VmLib: 2288 kB
VmPTE: 68 kB
VmSwap: 0 kB
Threads: 1
SigQ: 0/256631
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: fffffffe57f0d8fc
SigCgt: 00000001a80b2603
CapInh: 0000000000000000
CapPrm: ffffffffffffffff
CapEff: ffffffffffffffff
CapBnd: ffffffffffffffff
Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff
Cpus_allowed_list: 0-127
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1886565
nonvoluntary_ctxt_switches: 9772
TracerPid 接收跟踪该进程信息的进程的ID号
FDSize 文件描述符的最大个数,file->fds
VmPeak: Peak virtual memory size
VmSize: Virtual memory size.
VmLck: 任务已经锁住的物理内存的大小。锁住的物理内存不能交换到硬盘 (locked_vm)
VmHWM: 程序得到分配到物理内存的峰值
VmRSS: 程序现在使用的物理内存.
VmData(KB) 程序数据段的大小(所占虚拟内存的大小),存放初始化了的数据; (total_vm-shared_vm-stack_vm)
VmStk(KB) 任务在用户态的栈的大小 (stack_vm)
VmExe(KB) 程序所拥有的可执行虚拟内存的大小,代码段,不包括任务使用的库 (end_code-start_code)
VmLib(KB) 被映像到任务的虚拟内存空间的库的大小 (exec_lib)
VmPTE 该进程的所有页表的大小,单位:kb (since Linux 2.6.10).
注意,VmData,VmStk,VmExe和VmLib之和并不等于VmSize。这是因为共享库函数的数 据段没有计算进去(VmData仅包含a.out程序的数据段,不包括共享库函数的数据段, 也不包括通过mmap映射的区域。VmLib仅包括共享库的代码段,不包括共享库的数据 段)。
Threads 共享使用该信号描述符的任务的个数,在POSIX多线程序应用程序中,线程组中的所有线程使用同一个信号描述符。
SigQ 待处理信号的个数
SigPnd 屏蔽位,存储了该线程的待处理信号
ShdPnd 屏蔽位,存储了该线程组的待处理信号
SigBlk 存放被阻塞的信号
SigIgn 存放被忽略的信号
SigCgt 存放被俘获到的信号
CapInh Inheritable,能被当前进程执行的程序的继承的能力
CapPrm Permitted,进程能够使用的能力,可以包含CapEff中没有的能力,这些能力是被进程自己临时放弃的,CapEff是CapPrm的一个子集,进程放弃没有必要的能力有利于提高安全性
CapEff Effective,进程的有效能力
CapBnd:Capability Bounding set (since kernel 2.6.26, see capabilities(7)).
Cpus_allowed: Mask of CPUs on which this process may run (since Linux 2.6.24, see cpuset(7)).
Cpus_allowed_list: Same as previous, but in "list format" (since Linux 2.6.26, see cpuset(7)).
Mems_allowed: Mask of memory nodes allowed to this process (since Linux 2.6.24, see cpuset(7)).
Mems_allowed_list: Same as previous, but in "list format" (since Linux 2.6.26, see cpuset(7)).
voluntary_context_switches, nonvoluntary_context_switches: Number of voluntary and involuntary context switches (since Linux 2.6.23).
2.6.8 /proc//statm
host2:~ # cat /proc/95992/statm
472595 262467 259744 47477 0 2577 0
进程内存使用情况,单位是页,按顺序如下
Size:同/proc/[pid]/status中的Vmsize
Resident:同VmRSS in /proc/[pid]/status
Share:shared pages (from shared mappings)
Text:程序段
Lib:library (unused in Linux 2.6)
Data:data + stack
Dt:dirty pages (unused in Linux 2.6)
2.6.9 /proc//smaps(重点理解)
host2:~ # cat /proc/95992/smaps|more
00400000-0bd75000 r-xp 00000000 ca:02 878479 /app/oracle/ora11g/bin/oracle
Size: 189908 kB
Rss: 12372 kB
Pss: 352 kB
Shared_Clean: 12348 kB
Shared_Dirty: 0 kB
Private_Clean: 24 kB
Private_Dirty: 0 kB
Referenced: 12372 kB
Anonymous: 0 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
0bf75000-0bf7d000 r--p 0b975000 ca:02 878479 /app/oracle/ora11g/bin/oracle
Size: 32 kB
Rss: 32 kB
Pss: 32 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 32 kB
Referenced: 32 kB
Anonymous: 32 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
查看进程每个文件内存使用详细情况,可以用来查进程使用的swap空间大小
2.6.10 /proc//maps
同pmap结果
3 典型故障
3.1 Free不足发生SWAP交换(未确认根因)
检查后未发现有异常进程,进一步检查发现发生swap交换时,atop中有六七千进程,但是atop #proc字段只有3000左右,大量进程名称带<>说明改采样周期内执行结束
3.2 Oracle进程未启用大页导致页表过大
主机物理内存256G,数据库SGA+PGA用了130G左右(40%~60%),这个大小是正常的
数据库session数1000多,大内存+高session可能会有操作系统页表过大的问题
/proc/meminfo中显示页表已经51G
PageTables: 51973296 kB
Awr报告显示负荷都差不多,主要是session数增加了50左右,session越多,oracle使用的页表就越大
3.3 /dev/shm中残留文件导致内存不足
[Issue Verify]
OS: suse 11 linux x86-64
DB: oracle 11.2.0.3.0
server: ATAE Vmware virual machine
KRAKENDB22:/proc # dmidecode |grep Product
Product Name: VMware Virtual Platform
Product Name: 440BX Desktop Reference Platform
problem summary:High Usage of physical memory and High Usage of Swap for VMSDB3
problem details:
top - 11:39:20 up 101 days, 16:39, 1 user, load
average: 0.23, 0.13, 0.08
Tasks: 439 total, 2 running, 437 sleeping, 0 stopped, 0 zombie
Cpu(s): 5.7%us, 3.1%sy, 0.0%ni, 89.5%id, 1.2%wa, 0.2%hi, 0.3%si, 0.0%st
Mem: 48270M total, 39360M used, 8909M free, 202M buffers
Swap: 16378M total, 11914M used, 4464M free, 33320M cached
[Issue Analyze]
- free –m, atop , /proc/meminfo all shows much swap used but memory still have much free space.
KRAKENDB25:/proc # free -m
total used free shared buffers cached
Mem: 48270 38051 10218 0 202 32020
-/+ buffers/cache: 5827 **42442 -> free memory**
Swap: 16378 **11914** 4464
Cat /proc/meminfo
MemTotal: 49428944 kB
MemFree: 10365748 kB
Buffers: 208952 kB
Cached: 32436288 kB
SwapCached: 16308 kB
Active: 27620648 kB
Inactive: 6640536 kB
Active(anon): 26416884 kB
Inactive(anon): 2576316 kB
Active(file): 1203764 kB
Inactive(file): 4064220 kB
Unevictable: 950812 kB
Mlocked: 23860 kB
SwapTotal: 16771852 kB
SwapFree: 4571732 kB
Dirty: 592 kB
Writeback: 0 kB
AnonPages: 2561952 kB
Mapped: 16889380 kB
Shmem: 27370376 kB
Slab: 468768 kB
SReclaimable: 367700 kB
SUnreclaim: 101068 kB
KernelStack: 7176 kB
PageTables: 2642764 kB -> page table not high
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 41486324 kB
Committed_AS: 43341768 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 397900 kB
VmallocChunk: 34324815544 kB
HardwareCorrupted: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 10240 kB
DirectMap2M: 50321408 kB
- check /proc/ and found some processes use swap but total size is only 362448 KB, while top shows about 11G swap used
KRAKENDB25:~ # grep -i swap /proc/*/status
/proc/100/status:Name: kswapd1
/proc/101/status:Name: kswapd2
/proc/99/status:Name: kswapd0
grep -i swap /proc/*/smaps | grep -v "0 kB"
行标签 | 求和项:size | CMD |
---|---|---|
/proc/3499/smaps | 202876 | /opt/hacs/jre1.7.0_51/bin/java |
/proc/14712/smaps | 15212 | /opt/oracrs/product/11gR2/grid/binohasd.bin reboot |
/proc/19272/smaps | 11816 | /opt/oracrs/product/11gR2/grid/binevmd.bin |
/proc/19254/smaps | 11324 | /opt/oracrs/product/11gR2/grid/binoraagent.bin |
/proc/20701/smaps | 10720 | /opt/oracrs/product/11gR2/grid/binocssd.bin |
/proc/12264/smaps | 8156 | /usr/openv/netbackup/bin/nbsl |
/proc/12094/smaps | 7424 | /usr/openv/netbackup/bin/nbrmms |
… | ||
Total | 362448 KB |
KRAKENDB25:/var/log # ps -ef | grep 3499
root 3499 1 2 Jun19 ? 2-22:52:19 /opt/hacs/jre1.7.0_51/bin/java -Djava.util.logging.config.file=/opt/hacs/OpenAS_Tomcat7/conf/logging.properties -DCATALINA_STARTUP_CHECKER_FLAG=/opt/hacs/OpenAS_Tomcat7/temp1a0b/HwEoLrLlOd.tcatpid -Dname=CSMTtomcat -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Dopenas.catalina.out.log.file.control=off -Dopenas.accesslog.control=on -Dopenas.tomcat.flow.control=false -Dopenas.tomcat.flow.control.socket.reuseaddr=true -Dopenas.tomcat.flow.control.reject.timeout=1000 -server -XX:+UseParallelGC -XX:ParallelGCThreads=8 -XX:+UseAdaptiveSizePolicy -Xms1024m -Xmx1024m -XX:NewRatio=4 -XX:PermSize=128m -XX:MaxPermSize=256m -Djava.security.egd=file:/dev/./urandom -Dsun.rmi.dgc.server.gcInterval=0x7FFFFFFFFFFFFFE -Dsun.rmi.dgc.client.gcInterval=0x7FFFFFFFFFFFFFE -Dopenas.log.close.interval=3600000 -Dopenas.log.debug.level=error -Djava.endorsed.dirs=/opt/hacs/OpenAS_Tomcat7/endorsed -classpath /opt/hacs/OpenAS_Tomcat7/bin/bootstrap.jar:/opt/hacs/OpenAS_Tomcat7/bin/tomcat-juli.jar -Dcatalina.base=/opt/hacs/OpenAS_Tomcat7 -Dcatalina.home=/opt/hacs/OpenAS_Tomcat7 -Djava.io.tmpdir=/opt/hacs/OpenAS_Tomcat7/temp org.apache.catalina.startup.Bootstrap start
- df –h shows /dev/shm uses about 37G, this is shared memory. But acutally oracle SGA is only 18G.
# /bin/df -h
Filesystem Size Used Avail Use% Mounted on
rootfs 9.9G 3.7G 5.7G 40% /
udev 24G 172K 24G 1% /dev
**tmpfs 48G 37G 11G 78% /dev/shm**
/dev/sda1 9.9G 3.7G 5.7G 40% /
/dev/sda7 9.9G 6.1G 3.3G 66% /dump
/dev/sda5 22G 13G 8.3G 60% /home
/dev/sda6 20G 15G 4.4G 77% /opt
/dev/sda8 9.9G 5.9G 3.6G 63% /usr
/dev/sda9 9.9G 2.8G 6.6G 30% /var
**shmfs 48G 37G 11G 78% /dev/shm**
/dev/mapper/openv_vg-openv_lv
10G 6.2G 3.9G 62% /usr/openv
cobalt23:/software 300G 193G 108G 65% /software
/dev/mapper/vg_ebs-lv_ebs
4.0T 931G 3.1T 23% /opt/ebs
user | /dev/shm files:bytes | |
---|---|---|
grid | 348127232 | |
oracle | 38788923392 | |
root | 66544 | |
Total | 39137117168 |
Oracle awr report
Memory Statistics
Begin | End | |
---|---|---|
Host Mem (MB): | 48270.5 | 48270.5 |
SGA use (MB):? -> this is shared memory | 18432 | 18432 |
PGA use (MB): | 551.2 | 547 |
% Host Mem used for SGA+PGA: | 39.33 | 39.32 |
ls -l /dev/shm
shows many shm_xxxx modified date are Sep 6 and others are today Sep 29. These files are actually shared memory segments. Some segments not freed when last time oracle instance shutdown down. As this is about 37G, it will use much memory , so swap is used.
-rw-r----- 1 oracle oinstall 67108864 Sep 6 05:10 ora_vmsdb_23166986_25
-rw-r----- 1 oracle oinstall 67108864 Sep 6 05:10 ora_vmsdb_23166986_26
-rw-r----- 1 oracle oinstall 67108864 Sep 6 05:10 ora_vmsdb_23166986_27
-rw-r----- 1 oracle oinstall 67108864 Sep 6 05:10 ora_vmsdb_23166986_28
-rw-r----- 1 oracle oinstall 67108864 Sep 6 05:10 ora_vmsdb_23166986_29
-rw-r----- 1 oracle oinstall 67108864 Jul 8 10:17 ora_vmsdb_23166986_3
-rw-r----- 1 oracle oinstall 67108864 Jul 8 10:17 ora_vmsdb_23166986_4
-rw-r----- 1 oracle oinstall 67108864 Jul 8 10:17 ora_vmsdb_23166986_5
-rw-r----- 1 oracle oinstall 67108864 Jul 8 10:17 ora_vmsdb_23166986_6
-rw-r----- 1 oracle oinstall 67108864 Sep 6 05:10 ora_vmsdb_23166986_7
-rw-r----- 1 oracle oinstall 67108864 Sep 6 04:00 ora_vmsdb_23166986_8
-rw-r----- 1 oracle oinstall 67108864 Sep 6 02:48 ora_vmsdb_23166986_9
-rw-r----- 1 oracle oinstall 67108864 Jul 8 10:17 ora_vmsdb_23199755_0
-rw-r----- 1 oracle oinstall 67108864 Sep 29 17:14 ora_vmsdb_257654787_0
-rw-r----- 1 oracle oinstall 67108864 Sep 29 17:15 ora_vmsdb_257654787_1
-rw-r----- 1 oracle oinstall 67108864 Sep 29 17:15 ora_vmsdb_257687556_0
To solve this issue, please consider shutdown oracle database and then check whether still exist files belongs to oracle user, if has , please delete them, then restart db again.
If you want to do it more safe, you can shutdown oracle and then reboot server.
ogg常用参数文件模板及示例
MGR
模板略
示例
AUTORESTART EXTRACT P*, RETRIES 4, WAITMINUTES 5, RESETMINUTES 30
PURGEOLDEXTRACTS ./dirdat/cdccloud/*, USECHECKPOINTS, MINKEEPDAYS 5,FREQUENCYMINUTES 30
Extract_Param_TEMPLATE【经典抽取模式】
EXTRACT ${extract}
SETENV (NLS_LANG = ${NLS_LANG})
EXTTRAIL ${EXTTRAIL}
${USERID}
TRANLOGOPTIONS BUFSIZE 10000000
TRANLOGOPTIONS DBLOGREADER, DBLOGREADERBUFSIZE 4096000
DBOPTIONS ALLOWUNUSEDCOLUMN
WARNLONGTRANS 2h,CHECKINTERVAL 30m
GETUPDATEBEFORES
GETTRUNCATES
NOCOMPRESSDELETES
NOCOMPRESSUPDATES
DYNAMICRESOLUTION
Integrated_Extract_TEMPLATE【集成模式抽取进程】
extract ${extract}
setenv (NLS_LANG = ${NLS_LANG})
EXTTRAIL ${EXTTRAIL}
${USERID}
DBOPTIONS ALLOWUNUSEDCOLUMN
WARNLONGTRANS 30M,CHECKINTERVAL 10M
GETUPDATEBEFORES
GETTRUNCATES
TRANLOGOPTIONS INTEGRATEDPARAMS (_CHECKPOINT_FREQUENCY 10000)
TRANLOGOPTIONS CHECKPOINTRETENTIONTIME 2
TRANLOGOPTIONS _DBFILTERDDL
NOCOMPRESSDELETES
NOCOMPRESSUPDATES
示例1
EXTRACT e_test
SETENV (NLS_LANG=AMERICAN_AMERICA.AL32UTF8)
USERID goldengate, PASSWORD AADAAAAAAAAAAAOAOAUFUFJASICFIHLDBAUIECACNGEEBGPIEEGCFFCGEBOGFHIHEFMGHAWCKDGJQBSE,encryptkey superkey
EXTTRAIL ./dirdat/e_test/e1
TRANLOGOPTIONS INTEGRATEDPARAMS (_CHECKPOINT_FREQUENCY 10000)
TRANLOGOPTIONS CHECKPOINTRETENTIONTIME 2
WARNLONGTRANS 2h,CHECKINTERVAL 30m
GETUPDATEBEFORES
NOCOMPRESSDELETES
示例2
EXTRACT e_test2
SETENV (NLS_LANG=AMERICAN_AMERICA.AL32UTF8)
USERID goldengate, PASSWORD******
EXTTRAIL ./dirdat/e_test2/e1
WARNLONGTRANS 2H,CHECKINTERVAL 30M
REPORTCOUNT EVERY 30 MINUTES,RATE
TRANLOGOPTIONS INTEGRATEDPARAMS (_CHECKPOINT_FREQUENCY 10000)
TRANLOGOPTIONS CHECKPOINTRETENTIONTIME 2
TRANLOGOPTIONS _DBFILTERDDL
DBOPTIONS ALLOWUNUSEDCOLUMN
GETTRUNCATES
GETUPDATEBEFORES
NOCOMPRESSUPDATES
NOCOMPRESSDELETES
DYNAMICRESOLUTION
Pump_Param_TEMPLATE【传输进程】
--exttrailsource ${exttrailsources}
extract ${extract}
setenv (NLS_LANG = ${NLS_LANG})
<#if passthru?exists>${passthru}</#if><#if userid?exists>${userid}</#if>
rmthost ${rmthost}, mgrport ${mgrport}, compress
rmttrail ${rmttrail}<#if format?exists>,format release ${format}</#if>
示例
--exttrailsource ./dirdat/t_test/a1
extract t_test
setenv (NLS_LANG = AMERICAN_AMERICA.AL32UTF8)
passthru
rmthost t_test2, mgrport 7809, compress
rmttrail ./dirdat/t_test/g2
Replicat_Param_TEMPLATE【复制进程】
--exttrail ${exttrails}
REPLICAT ${REPLICAT}
SETENV (NLS_LANG=${NLS_LANG})
${USERID}
REPORTCOUNT EVERY 30 MINUTES, RATE
SOURCEDEFS ${SOURCEDEFS}
DISCARDFILE ${DISCARDFILE}, APPEND, MEGABYTES 200
APPLYNOOPUPDATES
NOCOMPRESSDELETES
NOCOMPRESSUPDATES
GETTRUNCATES
GETUPDATEBEFORES
示例1
--exttrail ./dirdat/r_test/h6
REPLICAT r_test
SETENV (NLS_LANG=AMERICAN_AMERICA.AL32UTF8)
USERID GOLDENGATE, PASSWORD******
REPORTCOUNT EVERY 30 MINUTES, RATE
SOURCEDEFS ./dirdef/UCCUBE_TO_BRAPFM_r_test.def
DISCARDFILE ./dirdat/r_test/r_test.dsc, APPEND, MEGABYTES 200
APPLYNOOPUPDATES
NOCOMPRESSDELETES
NOCOMPRESSUPDATES
GETTRUNCATES
GETUPDATEBEFORES
MAP test_user.test_table,TARGET test_user.test_table,FILTER ( @getenv ("TRANSACTION", "CSN") > 14082832115273), COLMAP (
ID=ID,
LOT_ID=LOT_ID,
DEFECT_POSITION=DEFECT_POSITION,
DEFECT_RAW_MAT_ID=DEFECT_RAW_MAT_ID,
MAT_DESC=MAT_DESC,
DEFECT_DOT=DEFECT_DOT,
CREATE_USER_ID=CREATE_USER_ID,
CREATE_TIME=CREATE_TIME,
UPDATE_USER_ID=UPDATE_USER_ID,
UPDATE_TIME=UPDATE_TIME);
示例2
REPLICAT r_test
SETENV (NLS_LANG=AMERICAN_AMERICA.UTF8)
USERID goldengate, PASSWORD******
REPORTCOUNT EVERY 30 MINUTES, RATE
SOURCEDEFS ./dirdef/cep_source_to_df_scm.def
DISCARDFILE ./dirdat/dfscm/r_test.dsc, APPEND, MEGABYTES 200
ALLOWNOOPUPDATES
INSERTMISSINGUPDATES
GETTRUNCATES
DBOPTIONS SUPPRESSTRIGGERS
DBOPTIONS DEFERREFCONST
MAP GOLDENGATE.OGG_HEARTBEAT_CHECK_T, TARGET r_test.OGG_HEARTBEAT_CHECK_T , INSERTALLRECORDS, COLMAP (
TARGET="EDW",
PROCESS_NAME=@getenv ("GGENVIRONMENT", "GROUPNAME"),
HEARTBEAT_DATE=HEARTBEAT_DATE,
HEARTBEAT_VALUE=HEARTBEAT_VALUE,
r_test_TIMESTAMP=@getenv ("GGHEADER", "COMMITTIMESTAMP"),
r_test_CREATE_DATE=@DateNow (),
SOURCE="OSERP");
BigData_Replicat_Parameter【大数据R进程参数文件模板】
--exttrail ${exttrails}
REPLICAT ${REPLICAT}
REPORTCOUNT EVERY 30 MINUTES, RATE
SOURCEDEFS ${SOURCEDEFS}
TARGETDB LIBFILE libggjava.so SET property=dirprm/${BigDataProperties}.props
REPORTCOUNT EVERY 1 MINUTES, RATE
JavaUE_Param_TEMPLATE【HANA JavaUE进程模板文件】
Extract ${extract}
SourceDefs ${SourceDefs}
REPORTCOUNT EVERY 1 MINUTES, RATE
-- Print current environmental variable settings to the report file
getEnv (JAVA_HOME)
getEnv (PATH)
getEnv (LD_LIBRARY_PATH)
-- unix/linux:
CUserExit libggjava_ue.so CUSEREXIT PassThru IncludeUpdateBefores
GetUpdateBefores
GROUPTRANSOPS 1000
MAXTRANSOPS 1000
CACHEMGR CACHESIZE 4GB, CACHEDIRECTORY ./dirtmp 6GB
示例
Extract java_test
SourceDefs /oggnas/goldengate/javaue/dirdef/javaue_test.def
Extract java_test
SourceDefs /oggnas/goldengate/javaue/dirdef/javaue_test.def
REPORTCOUNT EVERY 1 MINUTES, RATE
-- Print current environmental variable settings to the report file
getEnv (JAVA_HOME)
getEnv (PATH)
getEnv (LD_LIBRARY_PATH)
-- unix/linux:
CUserExit libggjava_ue.so CUSEREXIT PassThru IncludeUpdateBefores
GetUpdateBefores
GROUPTRANSOPS 1000
MAXTRANSOPS 1000
CACHEMGR CACHESIZE 2GB, CACHEDIRECTORY ./dirtmp 4GB
HANA-PROPERTIES【HANA创建JavaUE进程所需的properties文件】
## list of active event handlers (handlers not in the list are ignored)
#gg.handlerlist=jue_poc
###############################################################
## Adds to classpath, for additional jars and/or directories.
## Alternatively, set JVM option (see below): -Djava.class.path=...
# custom param begin
${customParam}
# custom param end
gg.log.level=info
###############################################################
# Java Properties for native library ("C" User Exit)
# tx timestamp datatbase local (default) or UTC timestamp
goldengate.userexit.timestamp=utc
goldengate.userexit.nochkpt=true
goldengate.userexit.utf8mode=false
jvm.bootoptions=-Xms2048m -Xmx5000m -XX:-UseGCOverheadLimit -Dlog4j.configuration=./lib/log4j.xml
ddlfilter
CREATE OR REPLACE FUNCTION GGSYNC.filterDDL (stmt IN VARCHAR2,
ora_owner IN VARCHAR2,
ora_name IN VARCHAR2,
ora_objtype IN VARCHAR2,
ora_optype IN VARCHAR2)
RETURN VARCHAR2
IS
retVal VARCHAR2 (100);
errorMessage VARCHAR2 (32767);
v_stmt VARCHAR2 (32767);
BEGIN
retVal := 'EXCLUDE';
IF ( ora_objtype <> 'TABLESPACE'
OR ora_objtype <> 'TYPE'
OR ora_objtype <> 'TRIGGER'
OR ora_objtype <> 'PACKAGE'
OR ora_objtype <> 'PROCEDURE'
OR ora_objtype <> 'FUNCTION'
OR ora_objtype <> 'SEQUENCE'
OR ora_objtype <> 'VIEW')
THEN
v_stmt := LOWER (stmt);
v_stmt := REPLACE (v_stmt, CHR (10), ' ');
CASE
-- 11.2.0.2 11.2.0.3 filter Compression Advisor
WHEN INSTR (v_stmt, 'dbms_tabcomp_temp') > 0
THEN
retVal := 'EXCLUDE';
-- 11.2.0.4 filter Compression Advisor
WHEN INSTR (v_stmt, 'cmp') > 0 AND INSTR (v_stmt, '$') > 0
THEN
retVal := 'EXCLUDE';
-- alter table table_name add column
WHEN INSTR (v_stmt, 'alter ') > 0
AND INSTR (v_stmt, ' table ') > 0
AND INSTR (v_stmt, ' constraint ') = 0
AND INSTR (v_stmt, ' add ') > 0
THEN
retVal := 'INCLUDE';
-- alter table table_name modify length or datatype of column
WHEN INSTR (v_stmt, 'alter ') > 0
AND INSTR (v_stmt, ' table ') > 0
AND INSTR (v_stmt, ' constraint ') = 0
AND INSTR (v_stmt, ' modify ') > 0
THEN
retVal := 'INCLUDE';
-- alter table old_table_name rename to new_table_name
WHEN INSTR (v_stmt, 'alter ') > 0
AND INSTR (v_stmt, ' table ') > 0
AND INSTR (v_stmt, ' constraint ') = 0
AND INSTR (v_stmt, ' rename ') > 0
AND INSTR (v_stmt, ' column ') > 0
THEN
retVal := 'INCLUDE';
-- alter table table_name drop column
WHEN INSTR (v_stmt, 'alter ') > 0
AND INSTR (v_stmt, ' table ') > 0
AND INSTR (v_stmt, ' constraint ') = 0
AND INSTR (v_stmt, ' drop ') > 0
THEN
retVal := 'INCLUDE';
-- alter table table_name add/drop primary key
WHEN INSTR (v_stmt, 'alter ') > 0
AND INSTR (v_stmt, ' table ') > 0
AND INSTR (v_stmt, ' primary ') > 0
THEN
retVal := 'INCLUDE';
-- alter table table_name Split or add or drop or merge or truncate Partition
--When instr(stmt,'alter ')>0 AND instr(stmt,' table ')>0 And instr(stmt,' partition ')>0 And instr(stmt,'modify')=0 THEN
-- retVal := 'INCLUDE';
-- truncate table table_name ,exclude alter table table_name truncate Partition
-- WHEN INSTR (v_stmt, 'truncate ') > 0
-- AND INSTR (v_stmt, ' table ') > 0
-- AND INSTR (v_stmt, ' partition ') = 0
-- THEN
-- retVal := 'INCLUDE';
-- drop table table_name ,exclude alter table table_name drop Partition
-- WHEN INSTR (v_stmt, 'drop ') > 0-- AND INSTR (v_stmt, ' table ') > 0
-- AND INSTR (v_stmt, 'alter ') = 0
-- AND INSTR (v_stmt, ' partition ') = 0
-- THEN
-- retVal := 'INCLUDE';
-- create table table_name, exclude create Partition table
WHEN INSTR (v_stmt, 'create ') > 0
AND INSTR (v_stmt, ' table ') > 0
AND INSTR (v_stmt, ' partition ') = 0
THEN
retVal := 'INCLUDE';
-- comment on table
WHEN INSTR (v_stmt, 'comment ') > 0
AND INSTR (v_stmt, ' on ') > 0
AND INSTR (v_stmt, ' table ') > 0
THEN
retVal := 'INCLUDE';
-- comment on column
WHEN INSTR (v_stmt, 'comment ') > 0
AND INSTR (v_stmt, ' on ') > 0
AND INSTR (v_stmt, ' column ') > 0
THEN
retVal := 'INCLUDE';
ELSE
retVal := 'EXCLUDE';
END CASE;
END IF;
IF "GGSYNC".DDLReplication.trace_level >= 1
THEN
"GGSYNC".trace_put_line ('DDL',
'Returning ' || retVal || ' from filterDDL');
END IF;
RETURN retVal;
EXCEPTION
WHEN OTHERS
THEN
errorMessage := 'filterDDL:' || SQLERRM;
DBMS_OUTPUT.put_line (errorMessage);
RAISE;
END;
/
发票抬头:软通动力技术服务有限公司长沙分公司 部门:长沙HW商业使能套件实施四部
dg恢复案例
dg恢复案例
1. dataguard ORA-07445 [kggibr()+0034]
现象描述: dataguard 发现primary 节点归档目录使用率很高,但是备机(灾备节点)归档目录使用率很低,业务侧有基线同步错误;
告警信息: ORA-07445: exception encountered: core dump [kggibr()+0034]
原因分析: dataguard 是将primary的归档日志传送到备机上并且备机应用(apply)成功后在删除,目前primary节点归档目录较大,是由于没有将归档日志传送到备机;
处理过程: 1 检查备机的alert log
Tue Aug 14 11:19:15 2012
Media Recovery Log /archive_backup/archivelog/1_63091_748536157.dbf
Tue Aug 14 11:19:37 2012
Exception [type: SIGSEGV, Invalid permissions for mapped object] [ADDR:0x0] [PC:0x100198794, kggibr()+0034]
Errors in file /opt/oracle/diag/rdbms/p570ora_drc/p570ora/trace/p570ora_pr0l_12058772.trc (incident=360400):
ORA-07445: exception encountered: core dump [kggibr()+0034] [SIGSEGV] [ADDR:0x0] [PC:0x100198794] [Invalid permissions for mapped object] []
Incident details in: /opt/oracle/diag/rdbms/p570ora_drc/p570ora/incident/incdir_360400/p570ora_pr0l_12058772_i360400.trc
Tue Aug 14 11:19:39 2012
Trace dumping is performing id=[cdmp_20120814111939]
Tue Aug 14 11:19:41 2012
Sweep Incident[360400]: completed
2 同时请现场在主备节点执行datagurad 检查脚本来获取相关信息;
primary.sql请在主节点上执行。standby.sql请在备机上执行;请反馈下当前目录下生产的.out 文件;
3 由于有ORA-07445 的报错,向原厂进行分析。
最后原厂分析是bug9728806 导致,请现场安装bug(主备节点都要安装),问题解决;
建议与总结: 通过这个问题虽然是个bug,在分析dataguard的问题是,请现在首先执行附件的脚本,这两个脚本中几乎包含所有dataguard的信息,对问题的分析和定位很有帮助;
2. 业务库dataguard 归档日志失败
现象描述: XX局点dataguard数据库出现日志不同步故障。现场发现主库数据库归档目录使用率较高。
告警信息:
RFS[7]: Assigned to RFS process 14151
RFS[7]: Identified database type as 'physical standby': Client is ARCH pid 19752
Errors in file /oracle/app/diag/rdbms/drora11g/drora11g/trace/drora11g_rfs_14141.trc:
ORA-19815: WARNING: db_recovery_file_dest_size of 80530636800 bytes is 100.00% used, and has 0 remaining bytes available.
#######dataguard的归档目录使用率已经100%,导致无法接受主机归档;
原因分析: 由于现场standby 数据库的归档目录设置的大小是100G,由于现场最近在主库上进行了大量历史数据删除操作,主库产生大量归档,现场也没有定时删除历史归档的脚步,所以导致归档日志积压;
处理过程: 1 增大standby 数据库的db_recovery_size;
Alter system set db_recovery_file_dest_size=500G scope=both;
2 观察standby的alert log
Tue Sep 25 15:38:41 2012
ALTER SYSTEM SET db_recovery_file_dest_size='500G' SCOPE=BOTH;
Tue Sep 25 15:49:56 2012
RFS[175388]: Assigned to RFS process 16569
RFS[175388]: Identified database type as 'physical standby': Client is LGWR ASYNC pid 32061
Primary database is in MAXIMUM PERFORMANCE mode
RFS[175388]: Selected log 20 for thread 1 sequence 5277 dbid -182376693 branch 730487836
Tue Sep 25 15:52:24 2012
RFS[175389]: Assigned to RFS process 18399
RFS[175389]: Identified database type as 'physical standby': Client is ARCH pid 19744
RFS[175389]: Selected log 21 for thread 1 sequence 5276 dbid -182376693 branch 730487836
Tue Sep 25 15:55:47 2012
Archived Log entry 209 added for thread 1 sequence 5276 ID 0xf604c5ca dest 1:
Tue Sep 25 16:49:09 2012
RFS[175390]: Assigned to RFS process 28232
RFS[175390]: Identified database type as 'physical standby': Client is LGWR ASYNC pid 32061
Primary database is in MAXIMUM PERFORMANCE mode
Re-archiving standby log 20 thread 1 sequence 5277
RFS[175390]: Selected log 21 for thread 1 sequence 5278 dbid -182376693 branch 730487836
Tue Sep 25 16:49:11 2012
RFS[175391]: Assigned to RFS process 28246
###目前dataguard接受日志正常。
查看dataguard的详细详细:
SQL> select al.thrd "Thread", almax "Last Seq Received", lhmax "Last Seq Applied"
2 from (select thread# thrd, max(sequence#) almax
3 from v$archived_log
4 where resetlogs_change#=(select resetlogs_change# from v$database)
5 group by thread#) al,
6 (select thread# thrd, max(sequence#) lhmax
7 from v$log_history
8 where first_time=(select max(first_time) from v$log_history)
9 group by thread#) lh
10 where al.thrd = lh.thrd;
Thread Last Seq Received Last Seq Applied
------ ----------------- ----------------
1 5253 5206
但是发现dataguard从在gap,表示主库归档日志有中断:
ARCH CONNECTED ARCH 0 0 0 0
MRP0 WAIT_FOR_GAP N/A 5192 0 0 0
RFS IDLE UNKNOWN 0 0 0 0
##表示5192这个归档日志主库上没有找到,现场确认是把过久的归档日志转移到单独目录了,分析alert log
Wed Sep 26 11:27:16 2012
Archived Log entry 215 added for thread 1 sequence 5252 rlc 730487836 ID 0xf604c5ca dest 2:
Wed Sep 26 11:28:21 2012
Media Recovery Waiting for thread 1 sequence 5193
Fetching gap sequence in thread 1, gap sequence 5193-5199 <<缺少这些归档
解决方法:
把5192~5199这个归档手动拷贝到dataguard的db_recovery_file_dest目录下,手动注册归档日志:
alter database register physical logfile '/synology/Backup_ArchiveLog/DRORA11G/archivelog/1_5192_730487836.dbf';
然后在检查知道没有gap,
##由于日志积压目前dataguard和主库还相差47个归档日志,目前只能等待,dataguard应用全部日志,最终和主库保持一致;
Thread Last Seq Received Last Seq Applied
---------- ----------------- ----------------
1 5253 5206
建议与总结: 在处理dataguard问题是,首先需要分析dataguard的alert log 查看是否是空间不足,然后需要通过Oracle原厂的信息收集脚步来进一步分析(脚步见附件);建议在主库中rman删除归档策略是以下,这能保证没有被dataguard应用的归档日志无法删除:
DG_phy_stby_diag.sql是在dataguard上执行,dg_prim_diag.sql是在备库上执行;
附件: DG_phy_stby_diag.sql
dg_prim_diag.sql
3关于Oracle10g Dataguard数据同步后无法打开Standby database
现象描述: Oracle10g中DD数据同步后,容灾库(Standby)无法正常打开,数据文件不可用,DataGuard环境搭建失败。
告警信息: 无
原因分析: Oracle10g 中创建Vg类型时必须是Big,Scalable VG否则会导致Oracle10g偏移量告警,而在进行Oracle DataGuard DD数据同步时必须确保主数据库(Primary)和容灾数据(Standby)Vg类型一致,否则容灾数据库将无法正常打开。所以在用DD数据同步之前先检查当前Vg类型。
处理过程: 将容灾库Vg类型重新划分与主数据Vg类型保持一致,也可通过RMAN方式创建容灾数据库。
方法一
kfjddb02:/u01/oracle>$lsvg vg28
VOLUME GROUP:vg28 VG IDENTIFIER: 00cd92d100004c000000011a4ca6e15c
VG STATE: active PP SIZE: 512 megabyte(s)
VG PERMISSION: read/write TOTAL PPs: 1020 (522240 megabytes)
MAX LVs: 512 FREE PPs: 4 (2048 megabytes)
LVs: 127 USED PPs: 1016 (520192 megabytes)
OPEN LVs: 7 QUORUM: 3
TOTAL PVs: 4 VG DESCRIPTORS: 4
STALE PVs: 0 STALE PPs: 0
ACTIVE PVs: 4 AUTO ON: no
Concurrent: Enhanced-Capable Auto-Concurrent: Disabled
VG Mode: Concurrent
Node ID: 2 Active Nodes:
MAX PPs per VG: 130048
MAX PPs per PV: 1016 MAX PVs: 128
LTG size (Dynamic): 1024 kilobyte(s) AUTO SYNC: no
HOT SPARE: no BB POLICY: relocatable
lqueryvg -At -g 00cd92d100004c000000011a4ca6e15c
......
Total PPs: 1020
LTG size: 128
HOT SPARE: 0
AUTO SYNC: 0
VG PERMISSION: 0
SNAPSHOT VG: 0
IS_PRIMARY VG: 0
PSNFSTPP: 16128
VARYON MODE: 0
VG Type: 1
Max PPs: 130048
说明,VG Type 0是普通VG,1是Big VG,VG Type 2就是Scalable VG
方法二
VG 类型的配置限制有差异,用户可定义 LV 的最大数目等于每个 VG 的 LV 最大数目减 1,因为将保留一个 LV 给系统使用。因此,系统管理员可以在常规 VG、大容量 VG 和可扩展 VG 中分别配置 255、511 和 4095 个 LV。下表是VG配置限制
VG 的配置限制
VG类型 | PV最大数目 | LV最大数目 | 每个VG的PP最大数目 | PP最大容量 |
---|---|---|---|---|
常规VG | 32 | 256 | 32512 | 1GB |
大容量VG | 128 | 512 | 130048 | 1GB |
可扩展VG | 1024 | 4096 | 2097152 | 128GB |
根据前面vg28的Max PPs为130048,从上表可得知vg28为Big Vg.
4. 使用rman创建dataguard physical standby数据库失败
现象描述: OS平台:suse 10
数据库版本:ORACLE 11G
使用rman创建dataguard physical standby数据库失败。
告警信息:
sql statement: alter system archive log current
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate Db command at 03/17/2011 19:48:18
RMAN-03015: error occurred in stored script Memory Script
RMAN-03009: failure of sql command on clone_default channel at 03/17/2011 19:48:18
RMAN-10038: database session for channel clone_default terminated unexpectedly
Recovery Manager complete.
原因分析: Dataguard同步时需要使用归档日志,如果归档日志不连续,就会导致无法无法应用所有归档日志。
处理过程:
- 查看容灾脚本,发现是使用duplicate命令创建standby数据库
rman target / auxiliary sys/***@*** cmdfile=$HOME/gen_stb.rcv
gen_stb.rcv
run {
allocate channel prmy1 type disk;
allocate channel prmy2 type disk;
allocate channel prmy3 type disk;
allocate auxiliary channel stby1 type disk;
allocate auxiliary channel stby2 type disk;
allocate auxiliary channel stby3 type disk;
duplicate target database for standby from active database nofilenamecheck;
}
- duplicate命令执行时会自动分解为多个命令,查看RMAN日志,发现错误发生在archive current log时
Recovery Manager: Release 11.1.0.7.0 - Production on Thu Mar 17 17:21:24 2011
Copyright (c) 1982, 2007, Oracle. All rights reserved.
connected to target database: ORCL (DBID=1267502183)
connected to auxiliary database: ORCL (not mounted)
RMAN> run {
2> allocate channel prmy1 type disk;
3> allocate channel prmy2 type disk;
4> allocate channel prmy3 type disk;
5> allocate auxiliary channel stby1 type disk;
6> allocate auxiliary channel stby2 type disk;
7> allocate auxiliary channel stby3 type disk;
8> duplicate target database for standby from active database nofilenamecheck;
9> }
10>
using target database control file instead of recovery catalog
allocated channel: prmy1
channel prmy1: SID=123 device type=DISK
...
channel prmy3: datafile copy complete, elapsed time: 00:04:05
Finished backup at 2011/03/17 19:32:41
sql statement: alter system archive log current
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate Db command at 03/17/2011 19:48:18
RMAN-03015: error occurred in stored script Memory Script
RMAN-03009: failure of sql command on clone_default channel at 03/17/2011 19:48:18
RMAN-10038: database session for channel clone_default terminated unexpectedly
Recovery Manager complete.
3.查看归档日志,发现主库归档日志不连续
4.重启主库后重新执行脚本,执行成功。
**建议与总结: **
- 容灾实施出现问题时,一定要检查归档日志是否连续
- duplicate命令执行时会自动分解为多个命令,可以查看rman的输出日志确认报错在哪一步。
5. DataGuard容灾ORA-01274 ORA-01119错误解决办法
现象描述: 某客服局点数据库采用DATAGUARD容灾方案,局方维护人员在生产库扩表空间时增加了一个在灾备库没有的裸设备,导致STANDBY数据库异常MRP进程SHUTDOWN。
组网方案:
1、生产库由两台IMB P570+DS4700构成ORACLE RAC双机。
2、灾备库同样由两台IMB P570+DS4700构成ORACLE RAC双机。
3、ORACLE版本为 9.2.0.8。
告警信息:
stangby数据库的ALERT告警日志如下:
Successfully added datafile 280 to media recovery
Datafile #280: '/dev/rlv_data2vg84'
Media Recovery Log /archive1/standby/uidb2_10376.log
WARNING: File being created with same name as in Primary
Existing file may be overwritten
File #281 added to control file as 'UNNAMED00281'. Originally created as:
'/dev/rlv_index1vg100'
Recovery was unable to create the file as:
'/dev/rlv_index1vg100'
Wed Dec 3 16:19:53 2008
MRP0: Background Media Recovery terminated with error 1274
Wed Dec 3 16:19:53 2008
Errors in file /home/oracle/app/oracle/admin/uidb/bdump/uidb1_mrp0_360682.trc:
ORA-01274: cannot add datafile '/dev/rlv_index1vg100' - file could not be created
ORA-01119: error in creating database file '/dev/rlv_index1vg100'
ORA-27040: skgfrcre: create error, unable to create file
IBM AIX RISC System/6000 Error: 13: Permission denied
Some recovered datafiles maybe left media fuzzy
Media recovery may continue but open resetlogs may fail
MRP0: Background Media Recovery process shutdown
原因分析: 由于在生产库增加了一个灾备库没有的LV('/dev/rlv_index1vg100'),导致灾备库在应用归档日志文件时报错,进而导致MRP进程shutdown。
处理过程: 在备库执行下列操作:
(1)把备库的文件管理方式改为手动管理
SQL> alter system set standby_file_management='manual' scope=both;
System altered.
(2)生成数据文件(如果数据文件是裸设备,要提前创建裸设备)
SQL> alter database create datafile '/u01/ora9i/database/9.2.0/dbs/UNNAMED00008' as '/dev/vg00/rlv_tbs02';
Database altered.
说明:"/home/oracle/app/product/9.2.0/dbs/UNNAMED00008"是通过在灾备库上查看V$DATAFILE视图根据ID号查出来的。
,该ID和灾备库alert日志中的File #281 added to control file as 'UNNAMED00281'. Originally created as:中的281对应。
(3)把备库的文件管理方式改为自动管理
SQL> alter system set standby_file_management='auto';
System altered.
(4)置备库为恢复管理模式
SQL> recover managed standby database disconnect;
Media recovery complete.
建议与总结: 该问题首先要及时发现,保证生产和灾备库上的归档日志文件系统不能被写满,或者即将满。其次,绝对不可以随便删除归档日志文件,否则就无法采用上述恢复办法恢复,只能重建灾备库。
6. Dataguard show errors ORA-338 and ORA-312
象描述: Oracle Errors:
Errors in file /oracle/app/diag/rdbms/drora11g/ora11g/trace/ora11g_rfs_11701.trc:
ORA-00338: log 20 of thread 1 is more recent than control file
ORA-00312: online log 20 thread 1: '/dev/vx/rdsk/vgora/lv_stdredo1'.
告警信息: Thu Apr 26 11:28:41 2012 <====== The first time show ORA-338
Successful mount of redo thread 1, with mount id 4177830692
Physical Standby Database mounted.
Lost write protection disabled
Errors in file /oracle/app/diag/rdbms/drora11g/ora11g/trace/ora11g_arc1_24850.trc:
ORA-00338: log 20 of thread 1 is more recent than control file
ORA-00312: online log 20 thread 1: '/dev/vx/rdsk/vgora/lv_stdredo1'
Errors in file /oracle/app/diag/rdbms/drora11g/ora11g/trace/ora11g_arc1_24850.trc:
ORA-00338: log 20 of thread 1 is more recent than control file
ORA-00312: online log 20 thread 1: '/dev/vx/rdsk/vgora/lv_stdredo1'
Completed: alter database mount standby database.
...
...
Thu May 03 18:06:58 2012
Errors in file /oracle/app/diag/rdbms/drora11g/ora11g/trace/ora11g_rfs_11701.trc:
ORA-00338: log 20 of thread 1 is more recent than control file
ORA-00312: online log 20 thread 1: '/dev/vx/rdsk/vgora/lv_stdredo1'.
原因分析:
About the ORA-338, please help feedback the SCN of the controlfile and the logfiles.
- On the standby database
$ sqlplus / as sysdba
set linesize 400
select dbid,name,open_mode,checkpoint_change# from v$database;
select group#,thread#,sequence#,bytes,archived,status,first_change# from v$log;
select group#,sequence#,bytes,used,archived,status,first_change#,LAST_CHANGE# from v$standby_log;
2. On the primary database
$ sqlplus / as sysdba
set linesize 400
select dbid,name,open_mode,checkpoint_change# from v$database;
select group#,thread#,sequence#,bytes,archived,status,first_change# from v$log;
select group#,sequence#,bytes,used,archived,status,first_change#,LAST_CHANGE# from v$standby_log;
The result:
On the standby database, v$database.checkpoint_change# is behind than the v$standby_log.first_change# for group 20.
In the particular case the control file updates could not keep up with the rate of log switches.
In case the log switches is not forced manually or by an application then below checks/actions can be performed:
- Check the redo log file size, make sure it is adequate to the workload.
After adjusting the redo log file size, monitor your database alert log to determine the time between log switches.
Generally speaking, Oracle recommends redo log switch each 20~30 minutes. - Check which session is generating a lot of redo.
On the oracle 11gR2, maybe related with "Bug 12770551 Frequent ORA-338 during controlfile restore with ASYNC Data Guard" .
In this case, suggest that check the redo switches, and rebuild the standby controlfile.
处理过程: Try to clear logfile 20, and rebuild the standby controlfile
-- 1. On the standby database
SQL> alter database clear logfile group 20; <====== Need to clear the logfile 20
SQL> recover managed standby database cancel;
SQL> shutdown immediate;
SQL> starup nomount;
-- 2. on the primary database, create standby controlfile and rcp to the standby
rman nocatalog target /
RMAN> backup current controlfile for standby format '/oracle/app/controlforstandby.bak';
$ rcp /oracle/app/controlforstandby.bak standby_IP:/oracle/app/controlforstandby.bak <====== Please change to the standby database IP
-- 3. On the standby, create standby controlfile
rman nocatalog target /
RMAN> restore standby controlfile from '/oracle/app/controlforstandby.bak';
SQL> ALTER DATABASE MOUNT STANDBY DATABASE;
SQL> alter database recover managed standby database disconnect from session;
-- 4. On the standby, check the SCN
$ sqlplus / as sysdba
set linesize 400
select dbid,name,open_mode,checkpoint_change# from v$database;
select group#,thread#,sequence#,bytes,archived,status,first_change# from v$log;
select group#,sequence#,bytes,used,archived,status,first_change#,LAST_CHANGE# from v$standby_log;
select sequence#,applied from v$archived_log order by sequence#;
SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;
select process,status from v$managed_standby;
建议与总结: Suggest that open the backup of the controlfile:
$rman target / nocatalog
RMAN>CONFIGURE CONTROLFILE AUTOBACKUP ON;
7. 参数设置错误导致dataguard灾备数据库日志应用异常
现象描述: 数据库版本:oracle10g及以上
操作系统: 全部版本
故障现象: 灾备数据库长时间没有成功应用归档日志
现场工程师报说容灾节点的日志从2011.7.21之后就没有再应用,v$manage_standby动态性能视图中查询返回结果不再包含MRP0后台进程。
SQL> select process,status,thread#,sequence#,block#,blocks
from v$managed_standby;
PROCESS STATUS THREAD# SEQUENCE# BLOCK# BLOCKS
--------- ------------ ---------- ---------- ---------- ----------
MRP0 WAIT_FOR_LOG 1 102205 0 0
RFS RECEIVING 1 102128 1023998 1023998
RFS WRITING 1 102205 52170 1024000
Describe of process:
RFS: 负责接收主库端传输过来的redo log file
MRP0:负责应用接收到的redo log file
告警信息:
Errors in file /opt/oracle/app/oracle/admin/smoradb/bdump/smorastd_mrp0_103784.trc:
ORA-01670: new datafile 17 needed for standby database recovery
ORA-01122: database file 17 failed verification check
ORA-01110: data file 17: '/dev/rsmora_index04'
ORA-01251: Unknown File Header Version read for file number 17
Some recovered datafiles maybe left media fuzzy
Media recovery may continue but open resetlogs may fail
MRP0: Background Media Recovery process shutdown.
原因分析: 在这之前曾经出过两次相关的现网操作。
首先是存储曾经掉过一次电,所以当时怀疑存储导致的一个操作系统bug。让现场兄弟修复该bug后,问题依旧。
后现场工程师反映说,这个问题是从之前一次为tablespace增加datafile之后开始的。
远程登录现网环境,检查发现灾备端的参数standby_file_management被设置为了manual。设置这个参数值之后,主节点新增的数据文件需要到灾备端手工执行创建,之后归档日志才能再次顺利应用。
处理过程: 由于检测到现网的参数standby_file_management被设置为MANUAL,所以首先尝试将该参数修改为AUTO,这样之后在主节点新增数据文件时,灾备节点可以顺利执行数据文件的创建动作。
Alter system set standby_file_management=’AUTO’;
修改该参数后检查v$datafile,发现已经存在对应的数据文件/dev/rsmora_index04,但是日志的应用依旧出现错误提示。
尝试手工执行数据文件的创建动作。
这时执行alter database create datafile ‘/dev/rsmora_index04’ as ‘/dev/rsmora_index04’出现错误提示,说将参数修改为自动之后无法手工创建文件。
于是再次将参数修改为MANUAL,创建文件之后再修改回来即可。
Alter system set standby_file_management=’MANUAL’;
alter database create datafile ‘/dev/rsmora_index04’ as ‘/dev/rsmora_index04’;
Alter system set standby_file_management=’AUTO’;
完成动作后,将数据库重新设置为日志应用状态。
alter database recover managed standby database disconnect;
8. Dataguard备库手工同步方法之一
现象描述: 某局oracle 9i dataguard主备库环境下,发现备库存在GAP,且手工从主库拷贝缺少归档至备库后,仍无法同步。
The alert log show failed in the standby:
Sun Oct 9 15:19:14 2011
Failed to request gap sequence. Thread #: 1, gap sequence: 224-224
All FAL server has been attempted.
告警信息: 无。
原因分析: 检查同步情况:
SQL> select open_mode from v$database;
SQL> select sequence#,applied from v$archived_log order by sequence#;
SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;
SQL> select process,status from v$managed_standby;
从v$archived_log中发现存在224,225,226,227的applied为NO,且从v$managed_standby中也看到存在MRP0(WAIT_FOR_GAP)和FAL(WAITING)。此处是FAL无法自动获取224,可考虑手工同步未同步的归档。
处理过程: 1. 首先将224,225,226,227手工从主库传送至备库,注意备库归档目录大小,修改传送过来的属主和权限;
2. 在备库执行如下来恢复:
$ sqlplus '/ as sysdba'
SQL> recover managed standby database cancel;
--- 这时 MRP0 进程将结束
SQL> recover automatic standby database;
--- 此时备库将依次对224,225,226,227进行恢复,如果缺少某个文件,可暂不理会,立即手工重传归档文件至备库,比如225,然后在该命令提示符下输入225的绝对路径和该文件名:
/opt/oracle/oradata/archivelog/1_225.dbf
回车即可。 到最后报缺失主库当前的228时,可以在该命令提示符下输入AUTO,结束这手工RECOVER. 然后可以启用MRP0,如下:
SQL> alter database recover managed standby database disconnect from session;
建议与总结:
- 备库有可能缺少大量的归档,在手工传送的时候,请务必注意文件目录大小和文件的属主权限。
- 也可以尝试先恢复224,然后启用MRP0:
SQL> alter database recover managed standby database disconnect from session;
9. ASM dataguard 容灾重做
现象描述: 一线升级备库时,只在备库做了switchover,然后把备库open resetlogs,让后编译数据字典后把备库又切到standby 状态,主库没有做任何操作。
这样导致主备库不再是一套data guard,变成了两套独立的库。
告警信息: 备库日志中发生了switchover,但是主库中没有switchover日志
wed oct 26 01:53:07 2011
alter database commit to switchover to primary with session shutdown
alter database switchover to primary (boss2)
maximum wait for role transition is 15 minutes.
all dispatchers and shared servers shutdown
close: killing server sessions.
close: all sessions shutdown successfully.
wed oct 26 01:53:07 2011
smon: disabling cache recovery
backup controlfile written to trace file /opt/oracle/app/oracle/diag/rdbms/boss/boss2/trace/boss2_ora_340976.trc
standby terminal recovery start scn: 100688092178
resetlogs after incomplete recovery until change 100688092179
...
wed oct 26 01:53:09 2011
arc3: becoming the 'no srl' arch
completed: alter database commit to switchover to primary with session shutdown
备库resetlogs之后,有启动到managed standby模式,这样备库在等待之前备库resetlogs之后产生的归档,这样就表现为了无法同步(自己无法同步自己的归档)
fal[client, mrp0]: error 12545 connecting to (description = (load_balance = on)(address = (protocol = tcp)(host = scan)(port = 1521))(connect_data = (service_name = bossmain))) for fetching gap sequence errors in file /opt/oracle/app/oracle/diag/rdbms/boss/boss1/trace/boss1_mrp0_356970.trc:
ora-12545: connect failed because target host or object does not exist errors in file /opt/oracle/app/oracle/diag/rdbms/boss/boss1/trace/boss1_mrp0_356970.trc:
ora-12545: connect failed because target host or object does not exist sat oct 29 00:25:38 2011
fal[client]: failed to request gap sequence gap - thread 2 sequence 7-106 dbid 3468682850 branch 765510788 à sequence已经重置了
fal[client]: all defined fal servers have been attempted.
原因分析: 主备库不再是一套data guard,变成了两套独立的库。需要重做备库。
处理过程: 详细过程见附件
因为容灾库各个配置已经配好,不需要重新配置,只用做恢复就可以了。
1)创建standby controlfile
rman target /
backup current controlfile for standby format '/rman01/prima_control.bkp';
主库每天会自动全库备份,备份目录为/rman01,/rman02,/rman03和/rman04
2)把主库的rman备份拷贝到备库的/rman04目录
备份日期:2011/10/31
大小:1t左右
传输方式:移动硬盘+ftp(因为业务已经上线,各个网卡都在一个交换机上,为了不增加网络负担,采用移动硬盘拷贝)
传过去以后需要检查一下文件数量和大小是否一致,否则后面catalog和restore时会报错
3)恢复备库
(1)恢复standby controlfile
login p570db1
su - oracle
sqlplus / as sysdba
shutdown immediate
startup nomount
exit
rman target /
restore standby controlfile from '/rman04/prima_control.bkp';
(2)因为主库的备份文件全部都放到了备库的/rman04下,所以需要把备份catalog到备库的控制文件中,否则restore时会提示找不到备份文件
rman target /
alter database mount;
catalog backuppiece '/rman04/ bossmain_s_xxx';
(3)恢复备库(不用recover,后面mrp会自己recover)
rman target /
restore database;
4)创建standby redo,应用归档日志
sqlplus / as sysdba
alter database add standby logfile thread 1 group 10 '+data_dg' size 500m;
alter database add standby logfile thread 1 group 11 '+data_dg' size 500m;
alter database add standby logfile thread 2 group 12 '+data_dg' size 500m;
alter database add standby logfile thread 2 group 13 '+data_dg' size 500m;
recover managed standby database using current logfile disconnect from session;
有缺少的归档日志时,及时从主库拷贝到备库
5)恢复备库到管理模式
sqlplus / as sysdba
alter database open read only;
建议与总结:
1)对于容灾库的升级,opatch apply在主备库都执行,编译数据字典和无效对象只在主库执行,不要在备库执行。
2)对于使用ASM的容灾库。
10. MRP process of DataGuard redundancy machine runs abnormally
现象描述:
Mon Jul 02 02:01:20 2012
LGWR: Insufficient standby redo logfiles to archive thread 1 sequence 90
LGWR: Standby redo logfile selected for thread 1 sequence 90 for destination LOG_ARCHIVE_DEST_2 <====== The connect was normal.
Thread 1 advanced to log sequence 90 (LGWR switch)
Current log# 6 seq# 90 mem# 0: /dev/vx/rdsk/vgora/lvredo6
…
Tue Jul 03 00:54:43 2012
ORA-16198: LGWR received timedout error from KSR <====== Timeout, and can’t connect the LOG_ARCHIVE_DEST_2
LGWR: Attempting destination LOG_ARCHIVE_DEST_2 network reconnect (16198)
LGWR: Destination LOG_ARCHIVE_DEST_2 network reconnect abandoned
Errors in file /oracle/app/diag/rdbms/ora11g/ora11g/trace/ora11g_lgwr_13522.trc:
ORA-16198: Timeout incurred on internal channel during remote archival
LGWR: Network asynch I/O wait error 16198 log 6 service 'droradg11g'
LGWR: Error 16198 disconnecting from destination LOG_ARCHIVE_DEST_2 standby host 'droradg11g'
Destination LOG_ARCHIVE_DEST_2 is UNSYNCHRONIZED
LGWR: Failed to archive log 6 thread 1 sequence 120 (16198)
告警信息: Mon Jul 02 02:01:33 2012
Archived Log entry 79 added for thread 1 sequence 119 ID 0xf906586f dest 1:
Tue Jul 03 00:54:47 2012
RFS[19]: Possible network disconnect with primary database
..
Tue Jul 03 02:04:56 2012
RFS[23]: Assigned to RFS process 19996
RFS[23]: Identified database type as 'physical standby': Client is LGWR SYNC pid 13522
Primary database is in MAXIMUM AVAILABILITY mode
Changing standby controlfile to RESYNCHRONIZATION level
Standby controlfile consistent with primary
RFS[23]: Selected log 21 for thread 1 sequence 123 dbid -136908667 branch 781726552
RFS[22]: Opened log for thread 1 sequence 121 dbid -136908667 branch 781726552
Tue Jul 03 02:04:57 2012
RFS[24]: Assigned to RFS process 20000
RFS[24]: Identified database type as 'physical standby': Client is ARCH pid 14120
RFS[24]: Selected log 22 for thread 1 sequence 122 dbid -136908667 branch 781726552
…
RFS[23]: Selected log 22 for thread 1 sequence 124 dbid -136908667 branch 781726552
…
RFS[23]: Selected log 21 for thread 1 sequence 125 dbid -136908667 branch 781726552
…
RFS[30]: Selected log 24 for thread 1 sequence 132 dbid -136908667 branch 781726552
Can't get the archivelog files.
SQL> select process,status,client_process,sequence#,block#,active_agents,known_agents
2 from v$managed_standby;
PROCESS STATUS CLIENT_P SEQUENCE# BLOCK# ACTIVE_AGENTS KNOWN_AGENTS
------- ------------ -------- ---------- ---------- ------------- ------------
ARCH CLOSING ARCH 135 30721 0 0
ARCH CONNECTED ARCH 0 0 0 0
ARCH CLOSING ARCH 133 198657 0 0
ARCH CLOSING ARCH 134 327681 0 0
MRP0 APPLYING_LOG N/A 120 301170 0 0
RFS IDLE UNKNOWN 0 0 0 0
RFS IDLE UNKNOWN 0 0 0 0
RFS IDLE LGWR 136 217812 0 0
RFS IDLE UNKNOWN 0 0 0 0
原因分析:
We can got the following messages by time:
1). Jul 03 00:54:43/On the bmp1a: LGWR received timedout error
2). Jul 03 00:54:47/On the drbmp1a: RFS process. Failed. Until Jul 03 02:04:49.
3). Jul 03 01:11:18/On the bmp1a: ARC1 Attempting destination LOG_ARCHIVE_DEST_2 network reconnect. FAILED. Until Jul 03 02:04:52
4). 07/03/2012 02:01:29/On the bmp1a: 1_120_781726552.dbf was delete by the command “delete obsolete device type disk;”
RMAN> run {
2> # Hot database level 0 whole backup
3> allocate channel t1 type disk;
4> CROSSCHECK ARCHIVELOG ALL;
5> backup
6> as compressed backupset
7> incremental level 0 database
8> format '/home/oracle/archive/dbback/VPNTEM_%s_%p_SDU_bmp1a_DB_201207030200';
9> delete obsolete device type disk;
10> backup
…
deleted archived log
archived log file name=/home/oracle/archive/1_120_781726552.dbf RECID=258 STAMP=787625691 <====== The archive log 1_120_781726552.dbf was delete by the command “delete obsolete device type disk;” about the time “07/03/2012 02:01:29”
So, the standby database still waiting the sequence 120, because of the sequence 120 hadn’t been transferred to the standby database, and had been deleted by the rman backup scripts before the network was recovered.
The ORACLE Document: backup and recover reference
DELETE OBSOLETE considers only the backup retention policy and does not use the configured archived log deletion policy to determine which logs are obsolete.
处理过程:
The temporary solution:
Need to rebuild the standby database;
Optimize the rman backup scripts
RMAN> CONFIGURE RETENTION POLICY TO REDUNDANCY 3;
The finial solution:
- Optimize the network;
- Rebuild the standby database;
- Optimize the rman backup scripts;
建议与总结: - Don't delete the archivelog files directly.
- Increase the database redundance.
xml
dba常用脚本
--基础
--用户相关查询
--查看当前用户sid,serial#
select dbms_debug_jdwp.current_session_id sid,dbms_debug_jdwp.current_session_serial serial# from dual;
--查看某个用户所拥有的权限和角色
select grantee,to_char(wm_concat(granted_role)) from DBA_ROLE_PRIVS
--where grantee='BDIVM'
group by grantee;
--找到与所连接的会话有关的当前等待事件:
select SW.Sid,S.Username,SW.Event,SW.Wait_Time,SW.State,SW.Seconds_In_Wait SEC_IN_WAIT
from v$session S,v$session_wait SW where S.Username is not null and SW.Sid=S.Sid
and SW.event not like '%SQL*Net%' order by SW.Wait_Time Desc;
--查看当前用户环境
select userenv('ISDBA') from dual; --判断是否为DBA(包含OS和密码文件权限)
select userenv('LANGUAGE') from dual; --当前用户字符集(默认为数据库字符集)
select value from v$nls_parameters where parameter='NLS_CHARACTERSET'; --数据库使用字符集
select userenv('SID') from dual; --返回SID
select userenv('TERMINAL') from dual; --返回终端信息
select sys_context('USERENV','IP_ADDRESS') from dual; --返回客户端IP
select UTL_INADDR.get_host_address() from dual; --返回数据库IP
select sys_context('userenv','ip_address') from dual; --返回客户端IP
--查看用户正在执行的sql
SELECT SQL_TEXT FROM V$SQLTEXT T, V$SESSION S WHERE T.ADDRESS=S.SQL_ADDRESS
AND T.HASH_VALUE=S.SQL_HASH_VALUE AND S.MACHINE='XXXXX' OR USERNAME='WACOS';
--查出前台正在发出的sql语句:
select user_name,sql_text from v$open_cursor where sid in(select sid from (select sid,serial# from v$session where status='ACTIVE'));
--查询当前所执行的SQL语句:
select program ,sql_address from v$session where paddr in (select addr
from v$process where spid=3556);
PROGRAM SQL_ADDRESS
sqlplus@ctc20 (TNS V1-V3) 000000038FCB1A90
select sql_text from v$sqlarea where address='000000038FCB1A90';
--系统相关查询
--在ORACLE中查找TRACE文件的脚本:
select u_dump.value || '/' || instance.value || 'ora' ||
v$process.spid || nvl2(v$process.traceid, '_' || v$process.traceid, null ) || '.trc'"Trace File" from v$parameter u_dump cross join v$parameter instance cross join v$process join v$session on v$process.addr = v$session.paddr where u_dump.name = 'user_dump_dest' and
instance.name = 'instance_name' and v$session.audsid=sys_context('userenv','sessionid');
select d.value || '/ora_' || p.spid || '.trc' trace_file_name
from (select p.spid from sys.v_$mystat m,sys.v_$session s,
sys.v_$process p where m.statistic# = 1 and
s.sid = m.sid and p.addr = s.paddr) p,(select value from sys.v_$parameter where name ='user_dump_dest') d;
--查看所有表空间对应的数据文件名:
select distinct file_name,tablespace_name,AUTOEXTENSIBLE from dba_data_files;
--等待时间最多的5个系统等待事件的获取:
select * from (select * from v$system_event where event not like 'SQL%' order by total_waits desc) where rownum<=5;
--查看长事物
select username,sid,opname,round(sofar*100 / totalwork,0) || '%' as progress,time_remaining,sql_text from v$session_longops , v$sql where time_remaining <> 0 and sql_address=address and sql_hash_value = hash_value;
--Disk Read最高的SQL语句的获取:
select sql_text from (select * from v$sqlarea order by disk_reads)
where rownum<=5;
--查找前十条性能差的sql:
SELECT * FROM (SELECT PARSING_USER_ID
EXECUTIONS,SORTS,COMMAND_TYPE,DISK_READS,
sql_text FROM v$sqlarea ORDER BY disk_reads DESC)
WHERE ROWNUM<10 ;
--根据SID找ORACLE的某个进程:
select pro.spid from v$session ses,v$process pro where ses.sid=21 and ses.paddr=pro.addr;
如何查看系统当前最新的SCN号[不常用]:
select max(ktuxescnw * power(2,32) + ktuxescnb) from x$ktuxe;
/* 我猜测:在c语言里面 long 类型是一个32bit 整数,正好是 4G,而oracle核心正好是c语言开发的
所以,scn若在自增的时候采用long类型的整数,正好是4字节,则通常可以 scn base 作为自增的常量。而32bit满足不了数据库的需要,所以必须借助其他手段来扩充数字的大小,因此产生scn wrap ,这个表示每满一个 4G 则该值增加一
wrap 在oracle通常表示循环覆盖的意思,在这里也是这样的,每满4g大小则scn base 又从1开始,而 wrap加一
因此有 ktuxescnw*power(2,32)+ktuxescnb = scn
除此之外,该视图涉及死事物控制和回滚块的使用,详细用法http://www.cnblogs.com/zfyouxi/p/3893217.html
涉及并行回滚http://www.xifenfei.com/2534.html
*/
select current_scn scn from v$database; --【常用】
如何在生产数据库中创建一个追踪客户端IP地址的触发器:
create or replace trigger on_logon_trigger
after logon on database
begin
dbms_application_info.set_client_info(sys_context('userenv', 'ip_address'));
end;
--开启trace
exec dbms_monitor.session_trace_enable(session_id => 69,serial_num => 40453)
--数据库回滚段性能检查:
--检查Ratio执行
select sum(waits)* 100 /sum(gets) "Ratio", sum(waits)
"Waits", sum(gets) "Gets" from v$rollstat;
--检查count/value执行:
select class,count from v$waitstat where class like '%undo%';
select value from v$sysstat where name='consistent gets';
--(两者的value值相除)
--如何查看某个回滚段里面,跑的什么事物或者正在执行什么sql语句:
select d.sql_text,a.name
from v$rollname a,v$transaction b,v$session c,v$sqltext d
where a.usn=b.xidusn and b.addr=c.taddr and c.sql_address=
d.address and c.sql_hash_value=d.hash_value
and a.usn=1;
(备注:你要看哪个,就把usn=?写成几就行了)
--查看回滚段的使用情况,哪个用户正在使用回滚段的资源:
select s.username, u.name from v$transaction t,v$rollstat r,
v$rollname u,v$session s where s.taddr=t.addr and
t.xidusn=r.usn and r.usn=u.usn order by s.username;
--如何查看一下某个shared_server正在忙什么:
SELECT a.username,a.machine,a.program,a.sid,
a.serial#,a.status,c.piece,c.sql_text
FROM v$session a,v$process b,v$sqltext c
WHERE b.spid=13161 AND b.addr=a.paddr
AND a.sql_address=c.address(+) ORDER BY c.piece;
--数据库共享池性能检查:
Select namespace,gets,gethitratio,pins,pinhitratio,reloads,
Invalidations from v$librarycache where namespace in
('SQLAREA','TABLE/PROCEDURE','BODY','TRIGGER');
--检查数据重载比率:
select sum(reloads)/sum(pins)*100 "reload ratio" from
v$librarycache;
--检查数据字典的命中率:
select 1-sum(getmisses)/sum(gets) "data dictionary hit
ratio" from v$rowcache;
(对于library cache, gethitratio和pinhitratio应该大于90%,对于数据重载比率,reload ratio应该小于1%,对于数据字典的命中率,data dictionary hit ratio应该大于85%)
--检查共享内存的剩余情况:
select request_misses, request_failures from v$shared_pool_reserved;
(对于共享内存的剩余情况, request_misses 和request_failures应该接近0)
--数据高速缓冲区性能检查:
select 1-p.value/(b.value+c.value) "db buffer cache hit
ratio" from v$sysstat p,v$sysstat b,v$sysstat c where
p.name='physical reads' and b.name='db block gets' and
c.name='consistent gets';
--检查buffer pool HIT_RATIO执行
select name, (physical_reads/(db_block_gets+consistent_gets))
"MISS_HIT_RATIO" FROM v$buffer_pool_statistics WHERE (db_block_gets+ consistent_gets)> 0;
(正常时db buffer cache hit ratio 应该大于90%,正常时buffer pool MISS_HIT_RATIO 应该小于10%)
检查average_wait执行:
select event,total_waits,time_waited,average_wait from v$system_event
where event like '%undo%';
检查RBS header get ratio执行:
select n.name,s.usn,s.wraps, decode(s.waits,0,1,1- s.waits/s.gets)"RBS
header get ratio" from v$rollstat s,v$rollname n where s.usn=n.usn;
(正常时Ratio应该小于1%, count/value应该小于0.01%,average_wait最好为0,该值越小越好,RBS header get ratio应该大于95%)
查看排序段的性能:
SELECT name, value FROM v$sysstat WHERE name IN ('sorts (memory)', 'sorts (disk)');
查找object为哪些进程所用:
select p.spid,s.sid,s.serial# serial_num,s.username user_name,
a.type object_type,s.osuser os_user_name,a.owner,a.object object_name,decode(sign(48 - command),1,
to_char(command), 'Action Code #' || to_char(command) ) action,
p.program oracle_process,s.terminal terminal,s.program program,s.status session_status from v$session s, v$access a, v$process p
where s.paddr = p.addr and s.type = 'USER' and a.sid = s.sid
and a.object='SUBSCRIBER_ATTR'order by s.username, s.osuser;
找出消耗CPU最高的进程对应的SQL语句:
set line 240
set verify off
column sid format 999
column pid format 999
column S_# format 999
column username format A9 heading "ORA User"
column program format a29
column SQL format a60
COLUMN OSname format a9 Heading "OS User"
SELECT P.pid pid,S.sid sid,P.spid spid,S.username username,
S.osuser osname,P.serial# S_#,P.terminal,P.program program,
P.background,S.status,RTRIM(SUBSTR(a.sql_text, 1, 80)) SQL
FROM v$process P, v$session S,v$sqlarea A WHERE P.addr = s.paddr
AND S.sql_address = a.address (+) AND P.spid LIKE '%&1%';
Enter value for 1: PID(这里输入占用CPU最高的进程对应的PID)
set termout off
spool maxcpu.txt
SELECT '++'||S.username username,
RTRIM(REPLACE(a.sql_text,chr(10),''))||';'FROM v$process P, v$session S,
v$sqlarea A WHERE P.addr = s.paddr AND S.sql_address = a.address (+)
AND P.spid LIKE '%&&1%';
Enter value for 1: PID(这里输入占用CPU最高的进程对应的PID)
spool off(这句放在最后执行)
CPU用率最高的2条SQL语句的获取
执行:top,通过top获得CPU占用率最高的进程的pid。
select sql_text,spid,v$session.program,process from v$sqlarea,v$session,v$process where v$sqlarea.address=v$session.sql_address and v$sqlarea.hash_value=v$session.sql_hash_value
and v$session.paddr=v$process.addr and v$process.spid in (pid);
col machine format a30
col program format a40
set line 200
select sid,serial# ,username,osuser,machine,program,process,to_char(logon_time,'yyyy/mm/dd hh24:mi:ss') from v$session where paddr in(select addr from v$process where spid in([$spid]));
select sql_text from v$sqltext_with_newlines
where hash_value=(select SQL_HASH_VALUE from v$session where sid=&sid)
order by piece;
查看锁(lock)情况:
select /*+ RULE */ ls.osuser os_user_name, ls.username user_name,
decode(ls.type,'RW','Row wait enqueue lock','TM','DML enqueue lock','TX','Transaction enqueue lock','UL','User supplied lock') lock_type,o.object_name object,decode(ls.lmode, 1, null, 2,'Row Share',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive',null)lock_mode,o.owner,ls.sid,ls.serial# serial_num,ls.id1,ls.id2 from sys.dba_objects o,(select s.osuser,s.username,l.type,l.lmode,s.sid,s.serial#,l.id1,l.id2 from v$session s,v$lock l where s.sid=l.sid)ls where o.object_id=ls.id1 and o.owner<>'SYS' order by o.owner, o.object_name;
查看V$SQLAREA:
SELECT SQL_TEXT,SHARABLE_MEM,PERSISTENT_MEM,RUNTIME_MEM,SORTS,
VERSION_COUNT,LOADED_VERSIONS,OPEN_VERSIONS,USERS_OPENING,EXECUTIONS,
USERS_EXECUTING,LOADS,FIRST_LOAD_TIME,INVALIDATIONS,PARSE_CALLS,
DISK_READS,BUFFER_GETS,ROWS_PROCESSED FROM V$SQLAREA;
查看object分类数量:
select decode(o.type#,1,'INDEX',2,'TABLE',3,'CLUSTER',4,'VIEW',5,'SYNONYM',6, 'SEQUENCE','OTHER') object_type , count() quantity
from sys.obj$ o where o.type# > 1
group by decode(o.type#,1,'INDEX',2,'TABLE',3,'CLUSTER' ,4,'VIEW',5,'SYNONYM',6,'SEQUENCE','OTHER')
union select 'COLUMN', count() from sys.col$ union select 'DB LINK' , count(*) from all_objects;
有关connection的相关信息:
1)查看有哪些用户连接
select s.osuser os_user_name,decode(sign(48 - command),1,to_char(command),
'Action Code #' || to_char(command))action,p.program oracle_process,
status session_status,s.terminal terminal,s.program program,
s.username user_name,s.fixed_table_sequence activity_meter,''query,
0 memory,0 max_memory,0 cpu_usage,s.sid,s.serial# serial_num
from v$session s,v$process p where s.paddr=p.addr and s.type = 'USER'
order by s.username, s.osuser;
2)根据v.sid查看对应连接的资源占用等情况
select n.name,v.value,n.class,n.statistic#
from v$statname n,v$sesstat v where v.sid=18 and v.statistic# = n.statistic# order by n.class, n.statistic#;
3)根据sid查看对应连接正在运行的sql
select /*+ PUSH_SUBQ */ command_type,sql_text,sharable_mem, persistent_mem,runtime_mem,sorts,version_count,
loaded_versions,open_versions,users_opening,executions, users_executing,loads,first_load_time,invalidations, parse_calls,disk_reads,buffer_gets,rows_processed,sysdate start_time,sysdate finish_time,'>'|| address sql_address,
'N' status from v$sqlarea where address = (select sql_address from v$session where sid=8);
根据pid查看sql语句:
select sql_text from v$sql
where address in
(select sql_address from v$session
where sid in
(select sid from v$session where paddr in (select addr from v$process where spid=&pid)));
查询表空间的碎片程度:
select tablespace_name,count(tablespace_name) from dba_free_space group by tablespace_name having count(tablespace_name)>10;
--回收表空间碎片【该命令通常不用手工执行,如果dba_tablespaces中pct_increase!=0,则会自动合并碎片extent,否则在需要free_extent时才会合并,或者手动合并】
alter tablespace name coalesce;
--回收表的空闲块【回收高水位之上的空闲块】
alter table table_name deallocate unused;
查看索引是否是分区索引:
SELECT INDEX_NAME, TABLE_NAME, STATUS, PARTITIONED FROM USER_INDEXES WHERE TABLE_NAME LIKE '%USAGE';
如果返回的PATITIONED为YES,请再执行如下语句来查询分区索引的类型:SELECT index_name,table_name,locality FROM user_part_indexes;
查找前十条性能差的sql:
SELECT * FROM(SELECT PARSING_USER_ID EXECUTIONS,SORTS,COMMAND_TYPE,DISK_READS,sql_text FROM v$sqlarea ORDER BY disk_reads DESC) WHERE ROWNUM<10;
监控表空间的 I/O 比例
select df.tablespace_name name,df.file_name "file",f.phyrds pyr,
f.phyblkrd pbr,f.phywrts pyw, f.phyblkwrt pbw from v$filestat f, dba_data_files df where f.file# = df.file_id
order by df.tablespace_name;
显示所有数据库对象的类别和大小
select count(name) num_instances ,type ,sum(source_size) source_size,sum(parsed_size) parsed_size ,sum(code_size) code_size ,sum(error_size) error_size,sum(source_size) +sum(parsed_size) +sum(code_size) +sum(error_size) size_required from dba_object_size group by type order by 2;
监控 SGA 中重做日志缓存区的命中率,应该小于1%
SELECT name, gets, misses, immediate_gets, immediate_misses,
Decode(gets,0,0,misses/gets*100) ratio1, Decode(immediate_gets+immediate_misses,0,0, immediate_misses/(immediate_gets+immediate_misses)*100) ratio2
FROM v$latch WHERE name IN ('redo allocation', 'redo copy');
监控内存和硬盘的排序比率,最好使它小于 .10,增加 sort_area_size
SELECT name, value FROM v$sysstat WHERE name IN ('sorts (memory)', 'sorts (disk)');
18、找使用CPU多的用户session
select a.sid,spid,status,substr(a.program,1,40) prog,a.terminal,osuser,value/60/100 value from v$session a,v$process b,v$sesstat c
where c.statistic#=12 and c.sid=a.sid and a.paddr=b.addr order by value desc;
(12是cpu used by this session)
查看无法扩展的段
A、 脚本说明:
ORACLE对一个段比如表段或索引无法扩展时,取决的并不是表空间中剩余的空间是多少,而是取于这些剩余空间中最大的块是否够表比索引的“NEXT”值大,所以有时一个表空间剩余几个G的空闲空间,在你使用时ORACLE还是提示某个表或索引无法扩展,就是由于这一点,这时说明空间的碎片太多了。这个脚本是找出无法扩展的段的一些信息。
B、脚本原文:
SELECT segment_name,
segment_type,
owner,
a.tablespace_name "tablespacename",
initial_extent/1024 "inital_extent(K)",
next_extent/1024 "next_extent(K)",
pct_increase,
b.bytes/1024 "tablespace max free space(K)",
b.sum_bytes/1024 "tablespace total free space(K)"
FROM dba_segments a,
(SELECT tablespace_name,MAX(bytes) bytes,SUM(bytes) sum_bytes FROM dba_free_space GROUP BY tablespace_name) b
WHERE a.tablespace_name=b.tablespace_name
AND next_extent>b.bytes
ORDER BY 4,3,1;
查看段(表段、索引段)所使用空间的大小
A、 脚本说明:
有时你可能想知道一个表或一个索引占用多少M的空间,这个脚本就是满足你的要求的,把<>中的内容替换一下就可以了。
B、脚本原文:
SELECT owner,
segment_name,
SUM(bytes)/1024/1024
FROM dba_segments
WHERE owner=
And segment_name=
GROUP BY owner,segment_name
ORDER BY 3 DESC;
处理存储过程被锁
A、 脚本说明:
实际过程中可能你要重新编译某个存储过程理总是处于等待状态,最后会报无法锁定对象,这时你就可以用这个脚本找到锁定过程的那个sid,需要注意的是查v$access这个视图本来就很慢,需要一些耐心。
B、脚本原文:
SELECT * FROM V$ACCESS WHERE owner= And object=;
rename
数据库迁移数据文件
过程:数据库open状态下,直接使用mv将数据文件从locationA移动到locationB,在移动进行一半时,使用ctrl+c进行中止,同时从locationB移动回locationA,覆盖了源文件。然后关闭数据库,重启后无法open,提示ORA-1200
错误点:
1、首先数据库在线更改数据文件位置(例如数据文件迁移),需要使用cp,保证源文件不出错误。离线tablespace后,重新指定新位置进行重命名更变
2、mv一半后中止,并且重新mv回原位置,使得所有数据文件都从中截断,造成文件损坏,数据库因无法识别损坏文件而无法open
3、过早重启数据库。上述两个错误操作发生后,立即重启了数据库,导致写数据进程丢失,彻底无法恢复数据文件,数据库数据无法恢复。
该过程为经验教训,oracle每操作一步需要谨慎,三思而后行。
set pagesize 999
set linesize 999
select 'alter database rename file '||''''||name||''''||' to '''||replace(name,'/oradata/ebpdb/','/datalv/ebpdb/')||''';'
from v$tempfile
where name like '/oradata/ebpdb/%';
select 'alter database rename file '||''''||name||''''||' to '''||replace(name,'/oradata/ebpdb/','/datalv/ebpdb/')||''';'
from v$datafile
where name like '/oradata/ebpdb/%';
select 'alter database rename file '||''''||member||''''||' to '''||replace(member,'/oradata/ebpdb/','/datalv/ebpdb/')||''';'
from v$logfile
where member like '/oradata/ebpdb/%';
自动注册监听
# auto register instance
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(ORACLE_HOME = /opt/oracle/product/11gR2/db)
(SID_NAME = suseora)
)
(SID_DESC =
(ORACLE_HOME = /opt/oracle/product/11gR2/db)
(SID_NAME = VMTEST )
)
)
LISTENER =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.75.152.214)(PORT = 1526))
)
LOGGING_LISTENER = OFF
ADR_BASE_LISTENER = /opt/oracle
Oracle Dataguard详解
1. dataguard简介
1.1. 概述
简单理解,data guard就是一种冗余保护数据库方案,分为主库(primary)和容灾库(standby),主库上的变更会同步到容灾库。
官方概念:
Oracle Data Guard 是 Oracle 数据保护、数据可用性和灾难恢复解决方案。
Data Guard 提供管理、监视和自动化软件来创建和维护一个或多个备用数据库,为任务关键应用程序提供高可用性的同时,保护 Oracle 数据免受故障、灾难、人为错误和数据损坏的影响。
Data Guard 松散耦合的架构提供最佳数据保护和可用性:
直接从内存传输数据库更改,将备用数据库与主数据库上发生的 I/O 损坏隔离开来。
备用数据库使用的软件代码路径与主数据库不同,从而将其与影响主数据库的固件和软件错误隔离开来。
Oracle 损坏检测确保了数据在应用到备用数据库之前在逻辑上和物理上是一致的。
Data Guard 检测硬件错误(内存、cpu、磁盘、NIC)和数据传输故障所导致的静默损坏,防止其它们影响备用数据库。
备用数据库滚动执行计划维护、将停机时间降至最低,并消除在生产环境中进行改动所带来的风险。
Oracle Active Data Guard 11g 扩展了 Data Guard 基本功能,在不间断地应用接收自主数据库的更改的同时,允许对物理备用数据库进行只读访问。通过对主数据库上的即时查询、基于 Web 的访问、报表和备份进行分流,可以提高性能和投资回报率,同时还可提供灾难保护。
http://www.oracle.com/technetwork/cn/database/features/availability/dataguardoverview-083155-zhs.html
Data guard的主要原理就是将主库上的redo/archive日志传输到容灾库端,然后再应用到容灾库上,这种应用基本上是同步的,所以可以保证主库和容灾库数据相同。因为主库和容灾库一般是在不同的主机上,存储在不同的存储上,所以当主库发生灾难无法使用时,可以很快的切换到容灾库上。HA冷双机和RAC热双机数据库实际上都是一个,所以当存储数据库的存储发生故障时,是无法立即恢复的。
1.2. 进程结构
名称 | 说明 |
---|---|
LNS | Log Writer Network Server Process (10gR2开始有这个进程) 从10gR2开始,当主库LGWR进程写完redo log以后,LNS进程会把redo信息传到容灾端。之前的版本中,redo信息是直接通过LGWR进程或者arch进程传到容灾端。主库的alert日志中会有LNS的记录(9i里面显示的是arch进程),如:Sat May 25 16:27:42 2013 LNS: Standby redo logfile selected for thread 1 sequence 21 for destination LOG_ARCHIVE_DEST_2 |
In Oracle Database 10g Release 2, the new LGWR ASYNC behavior has changed since the LGWR process doesn't writes to the ASYNC buffer anymore.When the LGWR has completed writing to the online log, the LNSn process reads from the online redo log and ships the redo to the RFS-process on the standby database. If LGWR switches into a new online log file before the LNSn process has completed, then LNSn continues to remotely archive its current log file. If LGWR once again switches to a new online redo log file while the LNSn process is still on the original log file, then the ARCH process remotely archives the log file that the LNSn process has not yet begun to archive. Once LNSn has completed archiving its original log file, it begins archiving the current log file for LGWR. | |
When the LGWR is switching to the original online redo log and the LNS process is still not ready to archive the original online redo log, the LNS will be stop to archive this online redo log. At this time the online redo log is already locally archived. The standby database will recognize a GAP since the content from the original online redo log is not completely received there. The GAPs will be resolved automaticyll? by the ARCH process. | |
This new LGWR ASYNC behavior in 10gR2 eliminates the potential to stall the production database.How does LGWR/LNS process work in 10gR2 using LGWR ASYNC [ID 1057898.1] | |
RFS | remote file server process容灾库进程,接受主库的redo/archive log,保存在standby log或者archive log中。当主库和容灾库出现GAP(归档不连续)时,oracle会自动启动几个RFS进程传输缺少的归档日志。Alert日志:RFS[4]: Selected log 4 for thread 1 sequence 21 dbid 1877940761 branch 816351193 |
MRP/LSP | managed recovery process将redo/archive log应用到容灾库中。容灾库的同步进程 |
DMON | Data guard broker的进程,启用data guard broker时才会启动,日志和alert日志在一个路径下面 $ORACLE_BASE/diag/rdbms/DB_UNIQUE_NAME//trace/drc.log |
1.3. 重要概念
名称 | 说明 |
---|---|
GAP | 当主库的归档文件没有在容灾端产生时,主库和容灾库就不同步了,这种情况称为GAP。GAP一般出现在发生网络问题,一般分析方法检查主库和容灾库的alert日志和归档情况。Alert日志有LNS和RFS的字样。 |
1)当设置了FAL_SERVER和FAL_CLIENT初始化参数时,当容灾库发现出现GAP时,会启动一个或多个RFS进程来传输缺少的归档,然后MRP应用这些归档,这样容灾库就自动恢复到同步状态了。2)当不设置FAL_SERVER和FAL_CLIENT初始化参数时,出现GAP以后,下一次主库切换日志时LNS/arch(9i)会将缺少的归档传过去,容灾端只有一个RFS进程接收。Data Guard Gap Detection and Resolution [ID 232649.1] | |
Standby log | 创建了standby log以后,从主库传输的redo可以先写到standby log中,这样redo可以实时应用到容灾库中(real time apply)。Standby log的大小必须>= redo log,否则redo写一段时间以后就会报错。 |
最大保护模式 | 1)无数据丢失;2)commit时,redo必须写到主库的redo log和容灾库的standby log以后,commit才能结束;3)如果redo无法写到容灾库的standby log时,主库会关闭;4)需要配置:???(1)至少有一个容灾库配置standby log;???(2)至少有一个容灾库配置SYNC, LGWR和AFFIRM |
最大性能模式 | 1)默认模式;2)redo写到主库的redo log以后,commit就可以结束,不需要等待写到容灾端。3)不需要SYNC |
最大可用模式 | 1)介于最大性能模式和最大保护模式之间,尽量保证不丢失数据,所以最大保护模式条件符合时,和最大保护模式一样。2)当不能保证redo可以同时写到主库和容灾库时,主库不会shutdown,这时和最大性能模式一样;3)配置和最大保护模式一样:?(1)至少有一个容灾库配置standby log;???(2)至少有一个容灾库配置SYNC, LGWR和AFFIRM |
实现方式 | 从9i R2开始,Oracle data guard支持两种实现方式:一种是将生产机的log files传递给容灾机,通过Redo Apply技术来保障数据镜像能力,物理上提供了与生产数据库在数据块级的一致性镜像,也叫physical方式。另一种是通过SQL Apply(即Log Miner)技术,将接收到的日志文件还原成SQL语句,并在逻辑备份数据库上执行,从而达到数据一致性的目的,也叫logical?方式。两者区别:Physical方式支持异步传输方式,但容灾机处在恢复状态,不可用;Logical方式只支持同步传输方式,但容灾机可以处在read-only状态 |
容灾库状态 | 容灾库有两种状态:mount和open read only。在11g之前,如果容灾库在同步过程中(MRP进程启动),数据库无法到open read only。11gR1开始可以在open read only状态下同步数据。 |
数据库切换 | Failover:切换以后,两个数据库都变成主库,不能在进行数据同步,data guard损坏,恢复数据同步需要重建容灾库。Switchover:切换以后,主库变成容灾库,容灾库变成主库,还能保持数据同步 |
Data guard broker | Data guard broker是一个用来管理data guard的程序,使用data guard broker需要配置数据库参数:DG_BROKER_START = TRUE.数据库启动时会启动一个DMON进程,这个就是DG broker的进程。DG broker可以在EM和DGMGRL中使用。 |
1.4. 相关初始化参数
不需要死记硬背,通过配置data guard来掌握。
Role | 名称 | 说明 |
---|---|---|
Primary role | LOG_ARCHIVE_DEST_n | LOG_ARCHIVE_DEST_1:归档到本地的路径 LOG_ARCHIVE_DEST_1='LOCATION=/database/oracle/920DG/primary/arch';LOG_ARCHIVE_DEST_n(n>1):一般设置为归档到容灾端的配置,例:log_archive_dest_2='service=standby lgwr async';standby是tnsnames.ora中配置的容灾库tnsname(必须), lgwr表示使用lgwr写redo, async表示异步方式。valid_for=(redo_log_type, database_role):?指定归档生效条件;log_archive_dest_1一般配置valid_for=(ALL_LOGFILES,ALL_ROLES),表示任何情况都归档;log_archive_dest_2一般配置valid_for=(online_logfile,primary_role),表示当数据库是主库时,对online log进行归档,数据库是容灾库时,不进行归档。这样就能保证数据库是主库时会给容灾库传redo。 |
LOG_ARCHIVE_DEST_STATE_n | 默认值为true,表示启用LOG_ARCHIVE_DEST_n;对于容灾库的LOG_ARCHIVE_DEST_STATE_n(n>1),可以设置为defer(相当于是disable);Specifies that valid destination information and attributes are preserved, but the destination is excluded from archiving operations until re-enabled. | |
LOG_ARCHIVE_FORMAT | 归档文件命名格式,例LOG_ARCHIVE_FORMAT=%d_%t_%s.arc | |
Standby role | FAL_SERVER FAL_CLIENT | 配置的是tnsname,配置以后发生GAP时,容灾库会启动RFS进程传缺少的归档日志。FAL_SERVER:从哪个数据库拿归档,备库时设置;FAL_CLIENT:归档放到哪个数据库 |
STANDBY_FILE_MANAGEMENT | 仅physical standby database有效,要求设置为true。当设置为true时,主库上创建删除文件时,容载库会自动创建删除文件。 | |
STANDBY_ARCHIVE_DEST | 容灾库的归档路径,11g开始已经deprecated。指定容灾库的归档日志路径。11g中不设置时,会自动和log_archive_dest_1保持一致,alert日志中有提示。Using STANDBY_ARCHIVE_DEST parameter default value as /ora_arch | |
DB_FILE_NAME_CONVERT | 数据文件名称转换,一般用于路径转换。如主库数据文件放在/A,容灾库放在/B,设为DB_FILE_NAME_CONVERT?=('/A','/B'),如果两边路径一样的话,可以不设置。设置了以后,当在容灾库上做restore恢复文件或者主库创建了新的文件以后,容灾库上自动在新路径下产生数据文件。 | |
LOG_FILE_NAME_CONVERT | Redo文件名称转换,语法同DB_FILE_NAME_CONVERT。当主库上添加了新的redo log时,容载库会根据这个参数在响应的位置创建redo文件 | |
其他 | DG_BROKER_START | 默认为false,设置为true表示启用data guard broker。设置以后,数据库在nomount状态下就会有DMON进程。 |
DG_BROKER_CONFIG_FILEn | N为1或者2,指定data guard broker配置文件的路径。默认路径$ORACLE_HOME/dbs/drn<DB_UNIQUE_NAME>.dat | |
DB_UNIQUE_NAME | 数据库唯一名称,容灾数据库和主库的必须不一样。 |
本章讲解配置能够进行switchover的data guard的步骤。
主库:db_slot5
容灾库:db_slot9
2.1. 配置
2.1.1. 初始化参数
一般在data guard中,主库和容灾库配置专门的listener,通过这个listener进行主库和容灾库的通信。
主库:
### Primary database primary role parameterr ###
log_archive_dest_1='location=/ora_arch'
log_archive_dest_2='service=DB_SLOT9'
LOG_ARCHIVE_DEST_STATE_1=ENABLE
LOG_ARCHIVE_DEST_STATE_2=ENABLE
log_archive_format='%t_%s_%r.dbf'
### Primary database standby role parameters ###
FAL_SERVER=DB_SLOT9
FAL_CLIENT=DB_SLOT5
DB_FILE_NAME_CONVERT=('/opt/oracle/oradata/db_slot5','/opt/oracle/oradata/db_slot9')
LOG_FILE_NAME_CONVERT=('/opt/oracle/oradata/db_slot5','/opt/oracle/oradata/db_slot9')
STANDBY_FILE_MANAGEMENT=AUTO
## data guard broker ##
DG_BROKER_START=true
## Others ##
DB_UNIQUE_NAME=db_slot5
容灾库
### standby database standby role parameters ###
log_archive_dest_1='location=/ora_arch'
LOG_ARCHIVE_DEST_STATE_1=ENABLE
log_archive_format='%t_%s_%r.dbf'
FAL_SERVER=DB_SLOT5
FAL_CLIENT=DB_SLOT9
DB_FILE_NAME_CONVERT=('/opt/oracle/oradata/db_slot9','/opt/oracle/oradata/db_slot5')
LOG_FILE_NAME_CONVERT=('/opt/oracle/oradata/db_slot9','/opt/oracle/oradata/db_slot5')
STANDBY_FILE_MANAGEMENT=AUTO
### standby database primary role parameters ###
log_archive_dest_2='service=DB_SLOT5'
LOG_ARCHIVE_DEST_STATE_2=DEFER
## data guard broker ##
DG_BROKER_START=true
## Others ##
DB_UNIQUE_NAME=db_slot9
2.1.2. tnsnames配置
主库和容灾库都配置
DB_SLOT5=
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = T8000-slot5)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orahw)
)
)
DB_SLOT9=
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = T8000-slot9)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orahw)
)
)
2.1.3. 密码文件
因为容灾库一般在mount状态,mount状态无法用其他用户远程连接数据库,需要用sys用户通过listener进行连接,所以要配置密码文件。一般主库和备库密码一样,所以在主库创建或者重建密码文件以后,拷贝到容灾库。11g里面使用duplicate from active database时会自动把密码文件恢复到容灾库。
/opt/oracle/product/11g/db/bin/orapwd file=/opt/oracle/product/11g/db/dbs/orapworahw password=oracle force=y
2.2. 创建physical standby database
2.2.1. duplicate方式(忽略)
2.2.2. rman 备份恢复方式
1)主库上备份数据库
rman target /
Backup Database format '/ora_arch/dbbackup/%U_%s.bak';
sql "Alter System Archive Log Current";
Backup filesperset 10 ArchiveLog all delete input '/ora_arch/dbbackup/%U_%s.bak'; -->记下备份的最后一个归档的sequence号
Backup current controlfile for standby format '/ora_arch/dbbackup/standby.ctl';
exit
2)传到容灾库相同目录
3)恢复到容灾库
rman target /
startup nomount
restore standby controlfile from '/ora_arch/dbbackup/standby.ctl';
alter database mount; (11g里面可以直接mount,9i需要执行alter database mount standby database)
restore database;
recover database until sequence xxx;
exit
2.3. 创建standby log
主库:
alter database add standby logfile '/opt/oracle/oradata/db_slot5/stb01.log' size 50M;
alter database add standby logfile '/opt/oracle/oradata/db_slot5/stb02.log' size 50M;
alter database add standby logfile '/opt/oracle/oradata/db_slot5/stb03.log' size 50M;
容灾库:
alter database add standby logfile '/opt/oracle/oradata/db_slot9/stb01.log' size 50M;
alter database add standby logfile '/opt/oracle/oradata/db_slot9/stb02.log' size 50M;
alter database add standby logfile '/opt/oracle/oradata/db_slot9/stb03.log' size 50M;
容灾库的standby log创建以后,主库下次日志切换时,redo就开始写到standby log中,
主库alert日志提示
Sat May 25 16:27:42 2013
LNS: Standby redo logfile selected for thread 1 sequence 21 for destination LOG_ARCHIVE_DEST_2
容灾库alert日志提示:
Sat May 25 16:28:13 2013
Archived Log entry 6 added for thread 1 sequence 20 rlc 816351193 ID 0x6feebe19 dest 2:
RFS[4]: Selected log 4 for thread 1 sequence 21 dbid 1877940761 branch 816351193
查询v$standby_log显示有standby log是active状态
select * from v$standby_log
GROUP# DBID THREAD# SEQUENCE# BYTES
---------- -------------------------------------------------------------------------------- ---------- ---------- ----------
USED ARCHIV STATUS FIRST_CHANGE# FIRST_TIME LAST_CHANGE# LAST_TIME
---------- ------ -------------------- ------------- ------------ ------------ ------------
4 1877940761 1 26 52428800
1302016 YES ACTIVE 231655 25-MAY-13 232598 25-MAY-13
5 UNASSIGNED 1 0 52428800
512 NO UNASSIGNED 0 0
6 UNASSIGNED 0 0 52428800
512 YES UNASSIGNED 0 0
2.4. data guard同步
在容灾库上执行
Recover managed standby database using current logfile disconnect from session;
执行以后会启动MRP进程应用redo/archive logs
说明:
using current logfile:使用real time apply, 9i不支持
disconnect from session:将MRP放在后台,加此子命令以后,MRP进程启动以后会立刻返回到sql>提示符下。
Alert日志:
Sat May 25 16:38:06 2013
ALTER DATABASE RECOVER managed standby database using current logfile disconnect from session
Attempt to start background Managed Standby Recovery process (orahw)
Sat May 25 16:38:06 2013
MRP0 started with pid=27, OS id=22980
MRP0: Background Managed Standby Recovery process started (orahw)
Fast Parallel Media Recovery enabled
Managed Standby Recovery starting Real Time Apply
parallel recovery started with 8 processes
…
Media Recovery Log /ora_arch/1_15_816351193.dbf --> 使用归档同步,刚启动MRP或者发现GAP时,mrp的日志。
Media Recovery Log /ora_arch/1_16_816351193.dbf
Media Recovery Log /ora_arch/1_17_816351193.dbf
Sat May 25 16:38:16 2013
Media Recovery Log /ora_arch/1_18_816351193.dbf
Media Recovery Log /ora_arch/1_19_816351193.dbf
Media Recovery Log /ora_arch/1_20_816351193.dbf
Media Recovery Waiting for thread 1 sequence 21 (in transit)
Recovery of Online Redo Log: Thread 1 Group 4 Seq 21 Reading mem 0 --> 使用standby log实时应用redo
Mem# 0: /opt/oracle/oradata/db_slot9/stb01.log
检查V$managed_standby, MRP进程状态为applying_log
select * from v$managed_standby
PROCESS PID STATUS CLIENT_P CLIENT_PID
--------- ---------- ------------ -------- ----------------------------------------
CLIENT_DBID GROUP#
---------------------------------------- ----------------------------------------
RESETLOG_ID THREAD# SEQUENCE# BLOCK# BLOCKS DELAY_MINS KNOWN_AGENTS
----------- ---------- ---------- ---------- ---------- ---------- ------------
ACTIVE_AGENTS
-------------
ARCH 29922 CLOSING ARCH 29922
1877940761 4
816351193 1 30 90113 971 0 0
0
ARCH 29926 CONNECTED ARCH 29926
1877940761 N/A
0 0 0 0 0 0 0
0
ARCH 29930 CLOSING ARCH 29930
1877940761 4
816351193 1 29 90113 973 0 0
0
ARCH 29934 CLOSING ARCH 29934
1877940761 4
816351193 1 28 90113 975 0 0
0
MRP0 30279 APPLYING_LOG N/A N/A
N/A N/A
816351193 1 31 24722 102400 0 0
0
RFS 30088 IDLE UNKNOWN 30706
1877940761 N/A
0 0 0 0 0 0 0
0
RFS 30080 IDLE UNKNOWN 30712
1877940761 N/A
0 0 0 0 0 0 0
0
RFS 30084 IDLE LGWR 30817
1877940761 1
816351193 1 31 24723 1 0 0
0
8 rows selected.
3个RFS进程,对应的OS进程为local=no的oracle进程。
SQL> !ps -ef | grep 30088
oracle 13378 13331 0 12:12 pts/0 00:00:00 /bin/bash -c ps -ef | grep 30088
oracle 13380 13378 0 12:12 pts/0 00:00:00 grep 30088
oracle 30088 1 0 May25 ? 00:00:00 oracleorahw (LOCAL=NO)
SQL> !ps -ef | grep 30080
oracle 13381 13331 0 12:13 pts/0 00:00:00 /bin/bash -c ps -ef | grep 30080
oracle 13383 13381 0 12:13 pts/0 00:00:00 grep 30080
oracle 30080 1 0 May25 ? 00:03:04 oracleorahw (LOCAL=NO)
SQL> !ps -ef | grep 30084
oracle 13384 13331 0 12:13 pts/0 00:00:00 /bin/bash -c ps -ef | grep 30084
oracle 13386 13384 0 12:13 pts/0 00:00:00 grep 30084
oracle 30084 1 0 May25 ? 00:00:19 oracleorahw (LOCAL=NO)
RFS进程对应在主库上是LNS或归档进程,v$managed_standby中的CLIENT_PID就是主库上的进程PID
T8000-slot5:~ # ps -ef | grep 30706
root 13273 13217 0 12:16 pts/0 00:00:00 grep 30706
oracle 30706 1 0 May25 ? 00:00:01 ora_arc0_orahw
T8000-slot5:~ # ps -ef | grep 30712
root 13283 13217 0 12:17 pts/0 00:00:00 grep 30712
oracle 30712 1 0 May25 ? 00:00:03 ora_arc3_orahw
T8000-slot5:~ # ps -ef | grep 30817
root 13293 13217 0 12:17 pts/0 00:00:00 grep 30817
oracle 30817 1 0 May25 ? 00:00:14 ora_lns1_orahw
2.5. 打开到open read only模式
打开到open read only模式需要先停掉MRP
recover managed standby database cancel;
alter database open read only;
11g中,read only模式也可以保持同步状态,open以后,重新开mrp
recover managed standby database using current logfile disconnect from session;
(必须先cancel再open,然后再启动MRP)
Alert 日志:
Sat May 25 18:16:42 2013
ALTER DATABASE RECOVER managed standby database cancel
Sat May 25 18:16:42 2013
MRP0: Background Media Recovery cancelled with status 16037
Errors in file /opt/oracle/diag/rdbms/db_slot9/orahw/trace/orahw_mrp0_29962.trc:
ORA-16037: 妹禄搂妹妹贸寐∶没妹鹿寐幻赂麓虏妹梅
Managed Standby Recovery not using Real Time Apply
Shutting down recovery slaves due to error 16037
Recovery interrupted!
Recovered data files to a consistent state at change 232619
Errors in file /opt/oracle/diag/rdbms/db_slot9/orahw/trace/orahw_mrp0_29962.trc:
ORA-16037: 妹禄搂妹妹贸寐∶没妹鹿寐幻赂麓虏妹梅
MRP0: Background Media Recovery process shutdown (orahw)
Waiting for MRP0 pid 29962 to terminate
Managed Standby Recovery Canceled (orahw)
Completed: ALTER DATABASE RECOVER managed standby database cancel
alter database open read only
Data Guard Broker initializing...
Data Guard Broker initialization complete
Sat May 25 18:16:48 2013
SMON: enabling cache recovery
Dictionary check beginning
Dictionary check complete
Cannot re-create tempfile /opt/oracle/oradata/db_slot9/temp01.dbf, the same name file exists
Database Characterset is ZHS16GBK
Opening with internal Resource Manager plan
**********************************************************
WARNING: Files may exists in db_recovery_file_dest
that are not known to the database. Use the RMAN command
CATALOG RECOVERY AREA to re-catalog any such files.
If files cannot be cataloged, then manually delete them
using OS command.
One of the following events caused this:
1. A backup controlfile was restored.
2. A standby controlfile was restored.
3. The controlfile was re-created.
4. db_recovery_file_dest had previously been enabled and
then disabled.
**********************************************************
replication_dependency_tracking turned off (no async multimaster replication found)
Physical standby database opened for read only access.
Completed: alter database open read only
Sat May 25 18:18:00 2013
ALTER DATABASE RECOVER managed standby database using current logfile disconnect from session
Attempt to start background Managed Standby Recovery process (orahw)
Sat May 25 18:18:00 2013
MRP0 started with pid=18, OS id=30279
MRP0: Background Managed Standby Recovery process started (orahw)
Fast Parallel Media Recovery enabled
Managed Standby Recovery starting Real Time Apply
parallel recovery started with 8 processes
Waiting for all non-current ORLs to be archived...
All non-current ORLs have been archived
Media Recovery Waiting for thread 1 sequence 26 (in transit)
Recovery of Online Redo Log: Thread 1 Group 4 Seq 26 Reading mem 0
Mem# 0: /opt/oracle/oradata/db_slot9/stb01.log
Completed: ALTER DATABASE RECOVER managed standby database using current logfile disconnect from session
3. failover和switchover to physical standby database
主要讲解oracle 11g的failover和switchover,oracle 9i的步骤稍有不同。
3.1. Failover
Failover用户主库已经完全不可用的状况,所以所有操作都在容灾库上操作:
1)检查GAP
SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;
THREAD# LOW_SEQUENCE# HIGH_SEQUENCE#
---------- ------------- --------------
1 90 92
注意:GAP是MRP进程进行检测的,而且是主库和容灾库正常通信时才能检测,所以有时有GAP但是V$ARCHIVE_GAP可能没有结果。
建议同时检查主库和容灾库的
Archive log list
ls -l 归档路径
v$managed_standby
确认是否有GAP
如果有GAP的话,如果能找到归档,把归档copy到容灾库以后注册
ALTER DATABASE REGISTER PHYSICAL LOGFILE 'filespec1';
如果mrp正常启动的话,归档连续的情况下mrp会自动应用注册的归档;如果mrp没有启动,可以启动mrp来应用归档。
2)停止redo应用(停止之后可以再启动)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
3)finish redo应用(finish之后就不能再启动了)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
ALTER DATABASE ACTIVATE PHYSICAL STANDBY DATABASE;
执行成功后查询SWITCHOVER_STATUS为To Primary
SELECT SWITCHOVER_STATUS FROM V$DATABASE;
SWITCHOVER_STATUS
-----------------
TO PRIMARY
1 row selected
- 切换到主库角色
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
ALTER DATABASE OPEN;
3.2. Switchover
当主库和容灾库同步正常,可以进行switchover切换,切完以后还可以再切回来。
1)检查主库是否能切换成standby
SELECT SWITCHOVER_STATUS FROM V$DATABASE;
结果是TO STANDBY或者SESSIONS ACTIVE表示可以切换成standby
2)主库变成容灾库
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
执行成功以后,主库就变成容灾库
3)检查容灾库状态
SELECT SWITCHOVER_STATUS FROM V$DATABASE;
结果是TO PRIMARY或者SESSIONS ACTIVE表示可以切换成primary
4)容灾库切换成主库
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
ALTER DATABASE OPEN;
6)启动redo应用
在新的容灾库上执行
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
4. Data guard broker配置和使用
使用DG broker时,主库和容灾库都要使用spfile,否则配置时会有报错。而且dg broker中很多命令都要修改参数,修改参数时会指定scope=both
4.1. 配置
4.1.1. 配置初始化参数
必须指定dg_broker_start为true, dg_broker_config_filen可以不指定,使用默认值。
SQL> show parameter DG_BROKER
NAME TYPE VALUE
---------------------- --------- ----------------------------------------------
dg_broker_config_file1 string /opt/oracle/product/11g/db/dbs/dr1db_slot9.dat
dg_broker_config_file2 string /opt/oracle/product/11g/db/dbs/dr2db_slot9.dat
dg_broker_start boolean TRUE
4.1.2. 创建配置
使用dgmgrl
oracle@T8000-slot5:~> dgmgrl
DGMGRL for Linux: Version 11.1.0.7.0 - 64bit Production
Copyright (c) 2000, 2005, Oracle. All rights reserved.
Welcome to DGMGRL, type "help" for information.
连接数据库
DGMGRL> connect sys/oracle
Connected.
创建配置
DGMGRL> CREATE CONFIGURATION 'DRSolution' AS
> PRIMARY DATABASE IS 'DB_SLOT5'
> CONNECT IDENTIFIER IS DB_SLOT5;
Configuration "DRSolution" created with primary database "DB_SLOT5"
添加容灾库
DGMGRL> ADD DATABASE 'DB_SLOT9' as connect identifier is DB_SLOT9;
Database "DB_SLOT9" added
检查:
DGMGRL> SHOW CONFIGURATION;
Configuration
Name: DRSolution
Enabled: NO --> NO表示还未启用configuration
Protection Mode: MaxPerformance --> 最大保护模式
Databases:
DB_SLOT5 - Primary database
DB_SLOT9 - Physical standby database
Fast-Start Failover: DISABLED -->未开启fast start failover
Current status for "DRSolution":
DISABLED -->配置未启用
4.1.3. 启用配置
DGMGRL> ENABLE CONFIGURATION;
Enabled. -->启用配置
DGMGRL> SHOW CONFIGURATION;
Configuration
Name: DRSolution
Enabled: YES -->已经启用
Protection Mode: MaxPerformance
Databases:
DB_SLOT5 - Primary database
DB_SLOT9 - Physical standby database
Fast-Start Failover: DISABLED
Current status for "DRSolution":
Warning: ORA-16607: one or more databases have failed -->状态异常
4.1.4. 检查数据库问题
检查数据库总体情况
show database 'DB_SLOT9';
检查数据库具体错误:
show database 'DB_SLOT5' 'StatusReport';
查看更详细的信息
show database 'DB_SLOT5' 'InconsistentProperties';
DGMGRL> show database 'DB_SLOT9';
Database
Name: DB_SLOT9
Role: PHYSICAL STANDBY
Enabled: YES
Intended State: APPLY-ON
Instance(s):
orahw
Current status for "DB_SLOT9":
Error: ORA-16797: database is not using a server parameter file -->容灾库没有使用spfile
DGMGRL> show database 'DB_SLOT5';
Database
Name: DB_SLOT5
Role: PRIMARY
Enabled: YES
Intended State: TRANSPORT-ON
Instance(s):
orahw
Current status for "DB_SLOT5":
Error: ORA-16810: multiple errors or warnings detected for the database -->主库有多个错误
错误详细情况:
DGMGRL> show database 'DB_SLOT5' 'StatusReport';
STATUS REPORT
INSTANCE_NAME SEVERITY ERROR_TEXT
orahw ERROR ORA-16737: the redo transport service for standby database "DB_SLOT9" has an error
orahw WARNING ORA-16714: the value of property ArchiveLagTarget is inconsistent with the database setting
orahw WARNING ORA-16714: the value of property LogArchiveMaxProcesses is inconsistent with the database setting
orahw WARNING ORA-16714: the value of property LogArchiveMinSucceedDest is inconsistent with the database setting
DGMGRL> show database 'DB_SLOT5' 'InconsistentProperties';
INCONSISTENT PROPERTIES
INSTANCE_NAME PROPERTY_NAME MEMORY_VALUE SPFILE_VALUE BROKER_VALUE
orahw ArchiveLagTarget 0 0
orahw LogArchiveMaxProcesses 4 4
orahw LogArchiveMinSucceedDest 1 1
可以看到spfile中没有设置对应的参数,修改如下
SQL> alter system set Archive_lag_target=0 scope=spfile;
System altered.
SQL> alter system set Log_Archive_max_Processes=4 scope=spfile;
System altered.
SQL> alter system set Log_Archive_min_Succeed_dest=1 scope=spfile;
System altered.
再次检查,正常
DGMGRL> show database 'DB_SLOT5';
Database
Name: DB_SLOT5
Role: PRIMARY
Enabled: YES
Intended State: TRANSPORT-ON
Instance(s):
orahw
Current status for "DB_SLOT5":
SUCCESS
DGMGRL> SHOW CONFIGURATION;
Configuration
Name: DRSolution
Enabled: YES
Protection Mode: MaxPerformance
Databases:
DB_SLOT5 - Primary database
DB_SLOT9 - Physical standby database
Fast-Start Failover: DISABLED
Current status for "DRSolution":
SUCCESS
4.2. 使用
4.2.1. 配置修改各种属性
edit database 'DB_SLOT9' set PROPERTY property_name=value;
show database 'DB_SLOT9' 'property_name'
DGMGRL> edit database 'DB_SLOT9' set PROPERTY StaticConnectIdentifier='(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.71.111.50)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=DB_SLOT9_DGB)(INSTANCE_NAME=orahw)(SERVER=DEDICATED)))';
Property "staticconnectidentifier" updated
DGMGRL> show database 'DB_SLOT9' 'StaticConnectIdentifier';
StaticConnectIdentifier = '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.71.111.50)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=DB_SLOT9_DGB)(INSTANCE_NAME=orahw)(SERVER=DEDICATED)))'
打开/关闭redo transport
DGMGRL> show database 'DB_SLOT5';
Database
Name: DB_SLOT5
Role: PRIMARY
Enabled: YES
Intended State: TRANSPORT-ON
Instance(s):
orahw
Current status for "DB_SLOT5":
SUCCESS
DGMGRL> edit database 'DB_SLOT5' set State="TRANSPORT-OFF";
Succeeded.
DGMGRL> edit database 'DB_SLOT5' set State="TRANSPORT-ON";
Succeeded.
检查主库alert日志发现参数被修改了
Thu May 30 13:33:33 2013
ALTER SYSTEM SET log_archive_dest_2='service="db_slot9"',' LGWR ASYNC NOAFFIRM delay=0 OPTIONAL compression=DISABLE max_failure=0 max_connections=1 reopen=300 db_unique_name="DB_SLOT9" net_timeout=30 valid_for=(online_logfile,primary_role)' SCOPE=BOTH;
ALTER SYSTEM SET log_archive_dest_state_2='RESET' SCOPE=BOTH;
改回trasnport-on
DGMGRL> edit database 'DB_SLOT5' set State="TRANSPORT-ON";
Succeeded.
Alert日志:
ALTER SYSTEM SET log_archive_dest_state_2='ENABLE' SCOPE=BOTH;
ALTER SYSTEM ARCHIVE LOG
Thu May 30 13:34:54 2013
Thread 1 advanced to log sequence 37 (LGWR switch)
Current log# 1 seq# 37 mem# 0: /opt/oracle/oradata/db_slot5/redo01.log
Archived Log entry 43 added for thread 1 sequence 36 ID 0x6feebe19 dest 1:
Thu May 30 13:34:54 2013
******************************************************************
LGWR: Setting 'active' archival for destination LOG_ARCHIVE_DEST_2
******************************************************************
LNS: Standby redo logfile selected for thread 1 sequence 37 for destination LOG_ARCHIVE_DEST_2
4.2.2. 使用dg broker进行failover和switchover
Switchover
DGMGRL> switchover to 'DB_SLOT9';
Performing switchover NOW, please wait...
New primary database "DB_SLOT9" is opening...
Operation requires shutdown of instance "orahw" on database "DB_SLOT5"
Shutting down instance "orahw"...
ORA-01109: database not open
Database dismounted.
ORACLE instance shut down.
Operation requires startup of instance "orahw" on database "DB_SLOT5"
Starting instance "orahw"...
Unable to connect to database
ORA-12514: TNS:listener does not currently know of service requested in connect descriptor
Failed.
You are no longer connected to ORACLE
Please connect again.
Unable to start instance "orahw"
You must start instance "orahw" manually
Switchover succeeded, new primary is "DB_SLOT9"
DGMGRL>
Alert日志
主库:
Thu May 30 13:44:11 2013
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY (orahw)
...
Thu May 30 13:44:38 2013
Switchover: Complete - Database shutdown required (orahw)
Completed: ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN
ALTER SYSTEM SET log_archive_dest_2='' SCOPE=BOTH;
ALTER SYSTEM SET log_archive_dest_state_2='ENABLE' SCOPE=BOTH;
Thu May 30 13:44:41 2013
Shutting down instance: further logons disabled
Stopping background process MMNL
Stopping background process MMON
Shutting down instance (immediate)
...
Thu May 30 13:44:52 2013
Instance shutdown complete
Thu May 30 13:51:01 2013
Adjusting the default value of parameter parallel_max_servers
from 160 to 135 due to the value of parameter processes (150)
Starting ORACLE instance (normal)
...
Thu May 30 13:51:01 2013
alter database mount
...
Successful mount of redo thread 1, with mount id 1878382725
Physical Standby Database mounted.
Lost write protection disabled
Completed: alter database mount
alter database open
Data Guard Broker initializing...
Data Guard Broker initialization complete
...
ALTER SYSTEM SET log_archive_dest_1='location="/ora_arch"',' valid_for=(ALL_LOGFILES,ALL_ROLES)' SCOPE=BOTH SID='orahw';
ALTER SYSTEM SET log_archive_dest_state_1='ENABLE' SCOPE=BOTH SID='orahw';
ALTER SYSTEM SET log_archive_trace=0 SCOPE=BOTH SID='orahw';
ALTER SYSTEM SET log_archive_format='%t_%s_%r.dbf' SCOPE=SPFILE SID='orahw';
ALTER SYSTEM SET standby_file_management='AUTO' SCOPE=BOTH SID='*';
ALTER SYSTEM SET archive_lag_target=0 SCOPE=BOTH SID='*';
ALTER SYSTEM SET log_archive_max_processes=4 SCOPE=BOTH SID='*';
ALTER SYSTEM SET log_archive_min_succeed_dest=1 SCOPE=BOTH SID='*';
ALTER SYSTEM SET db_file_name_convert='/opt/oracle/oradata/db_slot5','/opt/oracle/oradata/db_slot9' SCOPE=SPFILE;
ALTER SYSTEM SET log_file_name_convert='/opt/oracle/oradata/db_slot5','/opt/oracle/oradata/db_slot9' SCOPE=SPFILE;
ALTER SYSTEM SET fal_server='db_slot9' SCOPE=BOTH;
ALTER SYSTEM SET fal_client='db_slot5' SCOPE=BOTH;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE THROUGH ALL SWITCHOVER DISCONNECT USING CURRENT LOGFILE
...
Thu May 30 13:51:28 2013
Completed: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE THROUGH ALL SWITCHOVER DISCONNECT USING CURRENT LOGFILE
容灾库:
Thu May 30 13:44:48 2013
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WAIT WITH SESSION SHUTDOWN
ALTER DATABASE SWITCHOVER TO PRIMARY (orahw)
Maximum wait for role transition is 15 minutes.
...
Switchover: Complete - Database mounted as primary (orahw)
Completed: ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WAIT WITH SESSION SHUTDOWN
...
Thu May 30 13:44:49 2013
ARC4 started with pid=25, OS id=18081
ARC0: Becoming the 'no SRL' ARCH
ALTER SYSTEM SET log_archive_dest_2='service="db_slot5"',' LGWR ASYNC NOAFFIRM delay=0 OPTIONAL compression=DISABLE max_failure=0 max_connections=1 reopen=300 db_unique_name="DB_SLOT5" net_timeout=30 valid_for=(online_logfile,primary_role)' SCOPE=BOTH;
ALTER SYSTEM SET log_archive_dest_state_2='ENABLE' SCOPE=BOTH;
ALTER DATABASE OPEN
...
Thu May 30 13:44:56 2013
QMNC started with pid=26, OS id=18105
LOGSTDBY: Validating controlfile with logical metadata
LOGSTDBY: Validation complete
Completed: ALTER DATABASE OPEN
ALTER SYSTEM SET log_archive_dest_1='location="/ora_arch"',' valid_for=(ALL_LOGFILES,ALL_ROLES)' SCOPE=BOTH SID='orahw';
ALTER SYSTEM SET log_archive_dest_state_1='ENABLE' SCOPE=BOTH SID='orahw';
ALTER SYSTEM SET log_archive_trace=0 SCOPE=BOTH SID='orahw';
ALTER SYSTEM SET log_archive_format='%t_%s_%r.dbf' SCOPE=SPFILE SID='orahw';
ALTER SYSTEM SET standby_file_management='AUTO' SCOPE=BOTH SID='*';
ALTER SYSTEM SET archive_lag_target=0 SCOPE=BOTH SID='*';
ALTER SYSTEM SET log_archive_max_processes=4 SCOPE=BOTH SID='*';
ALTER SYSTEM SET log_archive_min_succeed_dest=1 SCOPE=BOTH SID='*';
ALTER SYSTEM SET db_file_name_convert='/opt/oracle/oradata/db_slot5','/opt/oracle/oradata/db_slot9' SCOPE=SPFILE;
ALTER SYSTEM SET log_file_name_convert='/opt/oracle/oradata/db_slot5','/opt/oracle/oradata/db_slot9' SCOPE=SPFILE;
ALTER SYSTEM SET log_archive_dest_2='service="db_slot5"',' LGWR ASYNC NOAFFIRM delay=0 OPTIONAL compression=DISABLE max_failure=0 max_connections=1 reopen=300 db_unique_name="DB_SLOT5" net_timeout=30 valid_for=(online_logfile,primary_role)' SCOPE=BOTH;
ALTER SYSTEM SET log_archive_dest_state_2='ENABLE' SCOPE=BOTH;
...
Thu May 30 13:51:16 2013
ALTER SYSTEM SET log_archive_dest_state_2='ENABLE' SCOPE=MEMORY SID='*';
...
Thu May 30 13:51:37 2013
ALTER SYSTEM SET log_archive_dest_2='service="db_slot5"',' LGWR ASYNC NOAFFIRM delay=0 OPTIONAL compression=DISABLE max_failure=0 max_connections=1 reopen=300 db_unique_name="DB_SLOT5" net_timeout=30 valid_for=(online_logfile,primary_role)' SCOPE=BOTH;
ALTER SYSTEM SET log_archive_dest_state_2='ENABLE' SCOPE=BOTH;
Failover:
DGMGRL> failover to 'DB_SLOT9';
Performing failover NOW, please wait...
Failover succeeded, new primary is "DB_SLOT9"
DGMGRL> show configuration;
Configuration
Name: DRSolution
Enabled: YES
Protection Mode: MaxPerformance
Databases:
DB_SLOT9 - Primary database
DB_SLOT5 - Physical standby database (disabled)
Fast-Start Failover: DISABLED
Current status for "DRSolution":
SUCCESS
Alert日志:
容灾库:
Thu May 30 14:51:05 2013
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH FORCE
Terminal Recovery: Stopping real time apply
...
Completed: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH FORCE
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WAIT WITH SESSION SHUTDOWN
ALTER DATABASE SWITCHOVER TO PRIMARY (orahw)
Maximum wait for role transition is 15 minutes.
..
Switchover: Complete - Database mounted as primary (orahw)
Completed: ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WAIT WITH SESSION SHUTDOWN
...
Thu May 30 14:51:12 2013
ARC4 started with pid=26, OS id=18932
ARC0: Becoming the 'no SRL' ARCH
ALTER DATABASE OPEN
...
Completed: ALTER DATABASE OPEN
ALTER SYSTEM SET log_archive_dest_1='location="/ora_arch"',' valid_for=(ALL_LOGFILES,ALL_ROLES)' SCOPE=BOTH SID='orahw';
ALTER SYSTEM SET log_archive_dest_state_1='ENABLE' SCOPE=BOTH SID='orahw';
ALTER SYSTEM SET log_archive_trace=0 SCOPE=BOTH SID='orahw';
ALTER SYSTEM SET log_archive_format='%t_%s_%r.dbf' SCOPE=SPFILE SID='orahw';
ALTER SYSTEM SET standby_file_management='AUTO' SCOPE=BOTH SID='*';
ALTER SYSTEM SET archive_lag_target=0 SCOPE=BOTH SID='*';
ALTER SYSTEM SET log_archive_max_processes=4 SCOPE=BOTH SID='*';
ALTER SYSTEM SET log_archive_min_succeed_dest=1 SCOPE=BOTH SID='*';
ALTER SYSTEM SET db_file_name_convert='/opt/oracle/oradata/db_slot5','/opt/oracle/oradata/db_slot9' SCOPE=SPFILE;
ALTER SYSTEM SET log_file_name_convert='/opt/oracle/oradata/db_slot5','/opt/oracle/oradata/db_slot9' SCOPE=SPFILE;
Failover succeeded. Primary database is now db_slot9.
主库:
Thu May 30 14:51:01 2013
LNS: Attempting destination LOG_ARCHIVE_DEST_2 network reconnect (3135)
LNS: Destination LOG_ARCHIVE_DEST_2 network reconnect abandoned
Errors in file /opt/oracle/diag/rdbms/db_slot5/orahw/trace/orahw_lns1_24186.trc:
ORA-03135: á??óê§è¥áa?μ
LGWR: I/O error 3135 archiving log 2 to 'db_slot9'
Errors in file /opt/oracle/diag/rdbms/db_slot5/orahw/trace/orahw_lns1_24186.trc:
ORA-03135: á??óê§è¥áa?μ
Errors in file /opt/oracle/diag/rdbms/db_slot5/orahw/trace/orahw_lns1_24186.trc:
ORA-03135: á??óê§è¥áa?μ
LNS: Failed to archive log 2 thread 1 sequence 48 (3135)
Thu May 30 14:51:05 2013
ALTER SYSTEM SET log_archive_dest_state_2='RESET' SCOPE=BOTH;
DG broker日志:
DG 2013-05-30-14:51:04 0 2 0 RSM detected log transport problem: log transport for database 'DB_SLOT9' has the following error.
DG 2013-05-30-14:51:04 0 2 0 ORA-03135: á??óê§è¥áa?μ
DG 2013-05-30-14:51:04 0 2 0 RSM0: HEALTH CHECK ERROR: ORA-16737: the redo transport service for standby database "DB_SLOT9" has an error
DG 2013-05-30-14:51:04 0 2 456423069 Operation CTL_GET_STATUS canceled during phase 2, error = ORA-16778
DG 2013-05-30-14:51:04 0 2 456423069 Operation CTL_GET_STATUS canceled during phase 2, error = ORA-16778
DG 2013-05-30-14:51:05 0 2 0 NSV1: Received error ORA-16623 from target remote site DB_SLOT9.
DG 2013-05-30-14:51:05 0 2 456423069 DMON: Database DB_SLOT9 returned ORA-16623
DG 2013-05-30-14:51:05 0 2 456423069 for opcode = CTL_GET_STATUS, phase = BEGIN, req_id = 1.1.456423069
DG 2013-05-30-14:51:05 0 2 456423069 DMON: One or more standby sites have diverged.
DG 2013-05-30-14:51:05 0 2 456423069 DMON: Configuration will be deleted.
DG 2013-05-30-14:51:05 0 2 456423069 DMON: All standby site archivelog destinations will be deferred
DG 2013-05-30-14:51:05 0 2 0 Executing SQL [alter system set log_archive_dest_state_2 = 'RESET']
DG 2013-05-30-14:51:05 0 2 0 SQL [alter system set log_archive_dest_state_2 = 'RESET'] Executed successfully
4.2.3. dg broker问题定位
1)DCR日志(和alert日志在同一目录):$ORACLE_BASE/diag/rdbms/<DB_NAME>//trace/drc.log
2)设置16634事件:
alter system set events '16634 trace name context forever, level 1';
alter system set dg_broker_start=false scope=memory;
alter system set dg_broker_start=true scope=memory;
3)11.2.0.3以后可以设置TraceLevel级别到SUPPORT,默认是user级别
DGMGRL> edit configuration set property 'TraceLevel' = 'SUPPORT';
5. Data guard问题定位和案例
5.1. 收集信息
主库和容灾库的Alert日志:大部分问题都可以在alert日志中找到报错。
Listener状态、配置文件:如果listener有问题,主库、容灾库之间不能正常通信,data guard就会有问题。
诊断信息:ORACLE提供了两个脚本,可以收集主库和容灾库的dataguard相关信息
5.3. 案例讲解
性能优化案例1
- 通过GV$SESSION监控
可以用如下的脚本监控,SQL-1:
SELECT A.INST_ID, A.SID, A.USERNAME, A.PROGRAM, A.MODULE, A.SERVICE_NAME,
ROUND((SYSDATE-A.SQL_EXEC_START)*24*60,2) RUNTIME, A.SQL_EXEC_START,A.LOGON_TIME,
A.SQL_ID, B.PLAN_HASH_VALUE, B.SQL_TEXT, A.EVENT, A.WAIT_TIME, A.WAIT_CLASS, A.STATE, A.MACHINE
FROM GV$SESSION A, GV$SQLAREA B
WHERE A.INST_ID = B.INST_ID
AND A.SQL_ID = B.SQL_ID
AND A.STATUS = 'ACTIVE'
AND A.USERNAME IS NOT NULL
AND A.USERNAME NOT IN ('SYS','SYSTEM','GOLDENGATE')
AND A.MODULE LIKE 'SP%'
--AND A.INST_ID = 12
--AND A.SQL_ID LIKE 'c5s4ha2f99n9n'
--AND A.USERNAME = 'DWAPP'
--AND B.SQL_TEXT LIKE '%'
ORDER BY A.SQL_EXEC_START, A.SQL_ID
R&A系统在开发时使用了DBMS_APPLICATION_INFO包,V$Session的Module/Action字段记录实时信息。其中,Module记录过程名,Action记录每次调度的PROCESS_TIMEKEY。所以,通过条件A.MODULE LIKE 'SP%',就可以查到所有正在运行的SP。
One Pass调度程序和日常调度,都是使用DWAPP用户调度的。前台执行的程序,一般是RAWEB用户。
通过以上脚本的RUNTIME,可以知道单个SQL的耗时,如果耗时过长,则需要列为优化对象。
1.2 确定问题SQL
1.2.1 正在执行的SQL
确定正在执行的问题SQL比较简单,可以直接通过SQL-1,通过GV$SESSION获得SQL_ID,然后通过GV$SQLAREA或者GV$SQL获得SQL文本。
1.3 分析问题SQL执行计划
1.3.1 当前正在执行的SQL
1.3.1.1 获取SQL Monitor报告
系统会自动保留正在执行和刚刚执行的SQL的SQL Monitor报告,保存记录可以查询gv$sql_monitor获知。如果SQL执行计划过长,或者同一节点上报告数超出预定值,则可能会导致SQL Monitor报告不能生成。
SQL Monitor报告可以通过dbms_sqltune.REPORT_SQL_MONITOR()获取。如:
通过SQL_ID:
select dbms_sqltune.REPORT_SQL_MONITOR('5ngv50wj2cmju') from dual;
同一SQL_ID执行多次,则需要加sql_exec_id:
select dbms_sqltune.REPORT_SQL_MONITOR(sql_id =>'0jgk8kh3vu2q4', sql_exec_id => 16777276 ) from dual;
也可以使用inst_id和session_id获取该Session最近执行SQL的报告:
select dbms_sqltune.REPORT_SQL_MONITOR(inst_id => 12, session_id => 1234 ) from dual;
1.3.1.2 分析SQL Monitor报告
SQL Monitor报告主要分为如下几部分:
- SQL文本
- Global Information:包括执行时间,调度相关信息等。
- Binds:绑定变量信息,对于程序往往是传递的参数。
- Global Stats,总体资源消耗情况。
- 并行信息,包括申请的并行度,分配的并行度,以及每个并行Session的资源消耗情况和等待事件。
- 执行计划细节(分析重点)
下面是查看SQL Monitor报告的一些心得:
a. SQL文本里有并行提示,但SQL实际执行时却没有并行。
- 并行提示写错;
- 并行提示中加了错误的表名或别名;
- 提示所加的位置不对;
- 同一个SQL中有2个以上的不一致的Statement级提示,如/+Parallel(8)/和/+Parallel(4)/
- 有并行提示,但是系统没有能分配足够的并行度。这可能是当时节点并行执行程序多,并行度被拿光导致。
b. 执行计划中Rows (Estim) 和Rows (Actual)相差很大。
- 统计信息不准确
- 关联条件过多,或者列值分布不均匀
- 绑定变量影响
- Nested Loops影响
c. Activity列是各个步骤耗时比重。如果某一步骤比重过长,则需要重点分析。
d. Activity Detail列是各步骤等待时间,单位是秒。需重点关注耗时比较多的等待事件。
e. 在Exadata平台上,要特别关注Nested Loops。
之所以走Nested Loops,肯定是关联表的估计值比较低,并且表上有索引。如果统计信息准确,则不会有问题,如果统计信息不准确,实际数据量很大,则Nested Loops会消耗很多时间。这时,可以Invisible索引,或者加Full提示,或者加Use_Hash提示。
f. 如果使用了并行,要注意,对于大的表或者结果集,千万不能使用PX SEND BROADCAST,而要PX_SEND_HASH。这往往也是因为统计信息不对引起的。因为统计信息值比较小,优化器会选择PX SEND BROADCAST,但实际数据量却很大。
g. 执行计划里出现BUFFERED字样,表明该步关联以及之后的关联可能需要在临时表空间才能完成。一般是因为关联表多,中间结果集比较大才会需要在临时表空间完成。使用临时表空间的效率会比较低,应尽量避免。可以通过中间结果集落地等方式来避免。
1.3.1.3 当前SQL执行计划
如果因为特殊情况,无法获得当前执行SQL的SQL Monitor报告,可以通过如下脚本获取:
select * from table(dbms_xplan.display_cursor('f7cf46cgm8939'));
或者:
select * from table(dbms_xplan.display_cursor('f7cf46cgm8939', Null, 'ALLSTATS +PEEKED_BINDS'));
或者:
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(SQL_ID=>'bm1ydbmhbv6sb',CURSOR_CHILD_NO=>'0',FORMAT=>'ALL'));
注意,以上语句必须要在SQL运行的节点上执行。
1.3.1.4 分析当前SQL执行情况
一般通过如下方法分析当前SQL执行情况:
a. 通过SQL Monitor报告,查看其整体执行情况,分析执行计划是否正确。
b. 结合dba_hist_sqlstat,查看该SQL执行计划是否跟以往不同。
- 如果执行计划无变化,但执行时间变化较大,则主要考虑系统资源、数据量、表碎片等因素。
- 如果执行计划变化,则重点分析引起执行计划变化的原因。如某表数据量是否大幅变化、统计信息是否准确、有无索引增减等。
c. 结合gv$active_session_history,查看当前SQL的等待事件和执行细节。
d. 结合gv$sql,观察SQL的执行次数和执行时间。语句执行多次,如果发现 ELAPSED_TIME/1000000不断增加,但是EXECUTIONS不变,说明语句执行时间很长。如果EXECUTIONS增加也很快,那证明语句执行次数很多。
SELECT A.LAST_ACTIVE_TIME,A.INST_ID,A.SQL_ID,ROUND(A.ELAPSED_TIME/1000000,2) ELAPSED_TIME,A.EXECUTIONS,A.ROWS_PROCESSED,
A.BUFFER_GETS,A.PLAN_HASH_VALUE,A.SQL_PLAN_BASELINE,ROUND(A.ELAPSED_TIME/1000000,2) ELAPSED_TIME,ROUND(A.CLUSTER_WAIT_TIME/1000000,2) CLUSTER_WAIT_TIME,
ROUND(A.USER_IO_WAIT_TIME/1000000,2) USER_IO_WAIT_TIME,ROUND(A.CONCURRENCY_WAIT_TIME/1000000,2) CONCURRENCY_WAIT_TIME,
ROUND(A.CPU_TIME/1000000,2) CPU_TIME,A.SQL_TEXT,A.FETCHES,A.END_OF_FETCH_COUNT,A.CHILD_NUMBER,A.FIRST_LOAD_TIME,A.LAST_LOAD_TIME,A.*
FROM GV$SQL A
WHERE SQL_ID IN ('gg4ck6g1bqh4w')
--AND A.SQL_FULLTEXT LIKE '%SELECT AAA.PERIOD_ID%'
--AND A.LAST_ACTIVE_TIME >= TO_DATE('2012-12-03 05:12:16','YYYY-MM-DD HH24:MI:SS')
--AND A.LAST_ACTIVE_TIME <= TO_DATE('2012-12-03 11:55:54','YYYY-MM-DD HH24:MI:SS')
--AND A.INST_ID = 1
ORDER BY 1 ;
1.3.2 历史执行的SQL
1.3.2.1 获取AWR执行计划
如果想要查看某个SQL的历史执行计划,通过gv$sql_monitor已经查不到,这时可以通过AWR历史数据获取。
获取某一SQL_ID的所有历史执行计划:
select * from table(dbms_xplan.display_awr('gbqmhzj0g3nk7', format=>'ALL'));
获取某段时间某个节点的SQL_ID的AWR报告:
select output from table(dbms_workload_repository.AWR_SQL_REPORT_TEXT(4046037389, 1, 16150, 16154, 'cvx98c3n81ju7', 0));
以上例子中,4046037389为DBID,1为INST_ID,16150和16154为起止SNAP_ID。
1.3.2.2 分析AWR执行计划
通过AWR获取的历史执行计划,信息量不如SQL Monitor报告大。不过这对于我们分析一个SQL某次的执行情况仍然非常有用。
尤其是AWR里有多个执行计划时,我们可以通过对比好的执行计划和坏的执行计划,来找到优化思路。
1.3.2.3 分析历史SQL执行情况
首先我们要确定SQL执行当时的Plan Hash Value,可以通过查询dba_hist_sqlstat或者dba_hist_active_sess_history获取。
通过dba_hist_sqlstat可以查看历史执行计划的变更,如:
select * from dba_hist_sqlstat where SQL_ID = '72mcqs3hjywuj' order by snap_id DESC;
或者,更详细点,把每次执行时间列出来(该时间只是参考,如果SQL没有执行完,则不准确):
select trunc(b.begin_interval_time,'mi') begin_time, trunc(b.end_interval_time,'mi') end_time, a.*
from dba_hist_sqlstat a, dba_hist_snapshot b
where a.snap_id = b.snap_id and a.instance_number=b.instance_number
and SQL_ID = 'gbqmhzj0g3nk7' order by a.snap_id DESC;
或者:
SELECT TO_CHAR(ST.BEGIN_INTERVAL_TIME, 'YYYY-MM-DD HH24:MI:SS') RUN_DATE,ST.SNAP_ID,ST.DBID,SQL_ST.SQL_ID,ST.INSTANCE_NUMBER INS, PLAN_HASH_VALUE,SX.SQL_TEXT,ROUND(SQL_ST.ELAPSED_TIME_DELTA/1000000,2)ELAPSED_TIME_DELTA,SQL_ST.EXECUTIONS_DELTA,SQL_ST.ROWS_PROCESSED_DELTA,
ROUND(SQL_ST.CLWAIT_DELTA/1000000,2) CLWAIT_DELTA, SQL_ST.BUFFER_GETS_DELTA,SQL_ST.DISK_READS_DELTA,SQL_ST.FETCHES_DELTA,
ROUND(SQL_ST.CPU_TIME_DELTA/1000000,2) CPU_TIME_DELTA,
SQL_ST.PX_SERVERS_EXECS_DELTA,ROUND(SQL_ST.IOWAIT_DELTA/1000000,2) IOWAIT_DELTA,
ROUND(SQL_ST.CLWAIT_DELTA/1000000,2),SQL_ST.APWAIT_DELTA,SQL_ST.CCWAIT_DELTA, SQL_ST.DIRECT_WRITES_DELTA,SQL_ST.PLSEXEC_TIME_DELTA,SQL_ST.JAVEXEC_TIME_DELTA,SQL_ST.PHYSICAL_READ_REQUESTS_DELTA,
SQL_ST.PHYSICAL_READ_BYTES_DELTA,SQL_ST.PHYSICAL_WRITE_REQUESTS_DELTA ,SQL_ST.PHYSICAL_WRITE_BYTES_DELTA ,
OPTIMIZED_PHYSICAL_READS_DELTA ,CELL_UNCOMPRESSED_BYTES_DELTA,IO_OFFLOAD_RETURN_BYTES_DELTA,BIND_DATA ,FLAG ,
MODULE,TO_CHAR(BEGIN_INTERVAL_TIME, 'YYYY-MM-DD HH24:MI') BEGIN_TIME,
TO_CHAR(END_INTERVAL_TIME, 'YYYY-MM-DD HH24:MI') END_TIME
FROM DBA_HIST_SNAPSHOT ST,
DBA_HIST_SQLSTAT SQL_ST,
DBA_HIST_SQLTEXT SX
WHERE ST.SNAP_ID = SQL_ST.SNAP_ID
AND ST.DBID = SQL_ST.DBID
AND ST.INSTANCE_NUMBER = SQL_ST.INSTANCE_NUMBER
AND SQL_ST.SQL_ID = SX.SQL_ID
AND SQL_ST.DBID = SX.DBID
AND BEGIN_INTERVAL_TIME >= TO_DATE('2012-12-19 01:30:16', 'YYYY-MM-DD HH24:MI:SS')
AND BEGIN_INTERVAL_TIME <= TO_DATE('2012-12-19 10:50:16', 'YYYY-MM-DD HH24:MI:SS')
--AND IOWAIT_DELTA>60*100000
AND SQL_ST.SQL_ID IN ('3x70a416yzh50')
--AND SQL_ST.PLAN_HASH_VALUE IN ('19329223')
--AND SX.SQL_TEXT LIKE '% SELECT%use_hash(ocuu,oct,t,bct) parallel(oct,6)%'
查询dba_hist_active_sess_history,可以查看SQL执行当时的等待事件和执行细节。
select * from dba_hist_active_sess_history
where SQL_ID = '5kam6kc54ngvr' and snap_id between 16159 and 16167
order by sample_time desc;
查看dba_hist_sqlbind,可以获取SQL执行当时的绑定变量值。
select max(snap_id) from dba_hist_sqlbind where sql_id = '7k7kthr31dfp6';
select a.position, a.value_string from dba_hist_sqlbind a where sql_id = '7k7kthr31dfp6' and snap_id = 18586;
1.4 固定执行计划
1.4.1 通过SPM固定执行计划
a. 在DBA_SQLSET中,新建一个SQLSET NAME
EXEC DBMS_SQLTUNE.CREATE_SQLSET(SQLSET_NAME => 'dyxq726rs34q2');
b. 查询DBA_HIST_SQLSTAT,取得要固定的SQL_ID和PLAN_HASH_VALUE的两个相近的SNAP_ID,或取得要固定的SQL_ID和PLAN_HASH_VALUE的一个SNAP_ID值,再手工减1和加1,将查出的SNAP_ID包含在手工指定的范围内。
SELECT * FROM DBA_HIST_SQLSTAT A
WHERE A.SQL_ID IN ('dyxq726rs34q2')
AND A.PLAN_HASH_VALUE IN (1774024382)
ORDER BY A.SNAP_ID ;
c. 将好的执行计划,导入临时的DBA_SQLSET中。
DECLARE
BASELINE_REF_CURSOR DBMS_SQLTUNE.SQLSET_CURSOR;
BEGIN
OPEN BASELINE_REF_CURSOR FOR
SELECT VALUE(P)
FROM TABLE(DBMS_SQLTUNE.SELECT_WORKLOAD_REPOSITORY(21293, --手工减1
21295, --手工加1,将21294包含在范围内
'SQL_ID='||CHR(39)||'dyxq726rs34q2'||CHR(39)||' AND PLAN_HASH_VALUE=1774024382',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'ALL')) P;
DBMS_SQLTUNE.LOAD_SQLSET('dyxq726rs34q2', BASELINE_REF_CURSOR);
END;
/
d. 从临时的SQLSET中,导入SPM中。
VARIABLE CNT NUMBER;
EXEC :CNT := DBMS_SPM.LOAD_PLANS_FROM_SQLSET(SQLSET_NAME =>'dyxq726rs34q2',SQLSET_OWNER => 'HWDW',FIXED => 'YES',ENABLED => 'YES');
e. 查询新固定的执行计划是否加入。
SELECT SQL_HANDLE, PLAN_NAME,A.SQL_TEXT,A.CREATED, LAST_MODIFIED,ENABLED, ACCEPTED,A.*
FROM DBA_SQL_PLAN_BASELINES A
--WHERE UPPER(A.SQL_TEXT) LIKE '%SELECT /*+full(bl) parallel (bl 8)*/ BL.COMPANY_ID COMPANY_ID%'
ORDER BY A.LAST_MODIFIED DESC ;
f. 验证新固定的执行计划。
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE(SQL_HANDLE => 'SQL_b18d4d70efc7b98a',PLAN_NAME=>'SQL_PLAN_b33adf3rwgfca28127f46'));
g. 如果固定的执行计划不对,删除固定的执行计划。
VARIABLE CNT NUMBER;
EXEC :CNT := DBMS_SPM.DROP_SQL_PLAN_BASELINE(SQL_HANDLE => 'SQL_e0bd73cc62ec232e',PLAN_NAME => 'SQL_PLAN_f1gbmtjjfs8tf79d7241a');
h. 清掉执行计划,以便后续运行的SQL能按新的执行计划执行(但对不动的SQL需要kill session后,再启动)
1.4.2 通过SQL Profile固定执行计划
a. 定位并记录OUTLINE,记下目标OUTLINE的起始行号和结束行号。
如果是正在运行的SQL,可以从游标获取OUTLINE(在指定节点运行):
Select dbms_xplan.display_cursor('ct3awf4buy84a', null, 'OUTLINE') From Dual;
如果是已经运行完成的SQL,只能从AWR获取OUTLINE:
Select dbms_xplan.display_awr('ct3awf4buy84a', null,null, 'OUTLINE') From Dual;
记下目标OUTLINE的起始行号(BEGIN_OUTLINE_DATA)和结束行号(END_OUTLINE_DATA)。
b. 获取拼接后的OUTLINE。
先将第一步的起始行号和结束行号代入以下脚本,直接运行,然后从Output拷贝出来,注意删掉最后一个逗号。
declare
ar_hint_table sys.dbms_debug_vc2coll;
ar_profile_hints sys.sqlprof_attr := sys.sqlprof_attr();
i pls_integer;
begin
select substr (plan_table_output, 7)
bulk collect
into ar_hint_table from (
select a.* ,rownum rn from table(
dbms_xplan.display_awr('ct3awf4buy84a', null,null, 'OUTLINE')
--dbms_xplan.display_cursor('ct3awf4buy84a' , null , 'OUTLINE')
) a
) where rn >= 906 and rn <= 954; --起始行号和结束行号
i := ar_hint_table.first;
while i is not null loop
if ar_hint_table.exists(i + 1) then
if substr(ar_hint_table(i + 1), 1, 1) = ' ' then
ar_hint_table(i) := ar_hint_table(i) || trim(ar_hint_table(i + 1));
ar_hint_table.delete(i + 1);
end if;
end if;
i := ar_hint_table.next(i);
end loop;
dbms_output.put_line('SYS.SQLPROF_ATTR(');
i := ar_hint_table.first;
while i is not null loop
ar_profile_hints.extend;
ar_profile_hints(ar_profile_hints.count) := ar_hint_table(i);
dbms_output.put_line('q''['||ar_hint_table(i)||']'',');
i := ar_hint_table.next(i);
end loop;
dbms_output.put_line('); ');
end;
Output输出如下:
SYS.SQLPROF_ATTR(
q'[BEGIN_OUTLINE_DATA]',
q'[IGNORE_OPTIM_EMBEDDED_HINTS]',
q'[OPTIMIZER_FEATURES_ENABLE('11.2.0.3')]',
…………
…………
q'[GBY_PUSHDOWN(@"SEL$1")]',
q'[USE_HASH_AGGREGATION(@"SEL$1")]',
q'[END_OUTLINE_DATA]',
);
注意,要将倒数第2行,即END_OUTLINE_DATA所在行的最后一个逗号删除,然后拷贝到第3步的脚本中。
3、 固定执行计划。
将第2步获取的OUTLINE拷贝到ar_profile_hints:=后,将SQL文本(可以查询DBA_HIST_SQLTEXT或者GV$SQL获得)拷贝到cl_sql_text:=后。将dbms_sqltune.import_sql_profile里的name和description输入(可以随便命名,但是最好能标明sql_id和PHV)。
注意,如果SQL文本中有引号“’”,需要以双引号“’’”代替。
然后运行脚本,即可固定执行计划。
declare
ar_profile_hints sys.sqlprof_attr ;
cl_sql_text clob;
waitplan_sqlid varchar2(100);
begin
cl_sql_text:='INSERT /*+ APPEND PARALLEL(8)*/ INTO DM_REG_CF_IND_BASE_F_REFRE_TMP (REPORT_ITEM_ID, SUBJECT_AREA_ID, PERIOD_ID, SCENARIO_ID, DATA_CATEGORY_ID, VERSION_ID, BU_KEY, GEO_PC_KEY, SCHEDULE_TYPE_ID, RMB_AAA_PTD_AMT, RMB_AAP_PTD_AMT, USD_AAA_PTD_AMT, USD_AAP_PTD_AMT, RMB_AAA_QTD_AMT, RMB_AAP_QTD_AMT, USD_AAA_QTD_AMT, USD_AAP_QTD_AMT, RMB_AAA_YTD_AMT, RMB_AAP_YTD_AMT, USD_AAA_YTD_AMT, USD_AAP_YTD_AMT, RMB_AAA_PY_PTD_AMT, RMB_AAP_PY_PTD_AMT, USD_AAA_PY_PTD_AMT, USD_AAP_PY_PTD_AMT, RMB_AAA_PY_QTD_AMT, RMB_AAP_PY_QTD_AMT, USD_AAA_PY_QTD_AMT, USD_AAP_PY_QTD_AMT, RMB_AAA_PY_YTD_AMT, RMB_AAP_PY_YTD_AMT, USD_AAA_PY_YTD_AMT, USD_AAP_PY_YTD_AMT, RMB_AAA_PY_ALL_QTD_AMT, RMB_AAP_PY_ALL_QTD_AMT, USD_AAA_PY_ALL_QTD_AMT, USD_AAP_PY_ALL_QTD_AMT, RMB_AAA_PY_ALL_YTD_AMT, RMB_AAP_PY_ALL_YTD_AMT, USD_AAA_PY_ALL_YTD_AMT, USD_AAP_PY_ALL_YTD_AMT, RMB_AAA_PP_PTD_AMT, RMB_AAP_PP_PTD_AMT, USD_AAA_PP_PTD_AMT, USD_AAP_PP_PTD_AMT, RMB_AAA_PP_QTD_AMT, RMB_AAP_PP_QTD_AMT, USD_AAA_PP_QTD_AMT, USD_AAP_PP_QTD_AMT, CRT_JOB_ID) SELECT REPORT2.REPORT_ITEM_ID AS REPORT_ITEM_ID, :B6 AS SUBJECT_AREA_ID, S.PERIOD_ID AS PERIOD_ID, S.SCENARIO_ID AS SCENARIO_ID, DATA.DATA_CATEGORY_ID AS DATA_CATEGORY_ID, :B5 AS VERSION_ID, S.BU_KEY AS BU_KEY, S.GEO_PC_KEY AS GEO_PC_KEY, S.SCHEDULE_TYPE_ID AS SCHEDULE_TYPE_ID, NVL(SUM(S.RMB_AAA_PTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAA_PTD_AMT, NVL(SUM(S.RMB_AAP_PTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAP_PTD_AMT,NVL(SUM(S.USD_AAA_PTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAA_PTD_AMT, NVL(SUM(S.USD_AAP_PTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAP_PTD_AMT,NVL(SUM(S.RMB_AAA_QTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAA_QTD_AMT, NVL(SUM(S.RMB_AAP_QTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAP_QTD_AMT,NVL(SUM(S.USD_AAA_QTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAA_QTD_AMT, NVL(SUM(S.USD_AAP_QTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAP_QTD_AMT,NVL(SUM(S.RMB_AAA_YTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAA_YTD_AMT, NVL(SUM(S.RMB_AAP_YTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAP_YTD_AMT,NVL(SUM(S.USD_AAA_YTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAA_YTD_AMT, NVL(SUM(S.USD_AAP_YTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAP_YTD_AMT,NVL(SUM(S.RMB_AAA_PY_PTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAA_PY_PTD_AMT, NVL(SUM(S.RMB_AAP_PY_PTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAP_PY_PTD_AMT, NVL(SUM(S.USD_AAA_PY_PTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAA_PY_PTD_AMT,NVL(SUM(S.USD_AAP_PY_PTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAP_PY_PTD_AMT, NVL(SUM(S.RMB_AAA_PY_QTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAA_PY_QTD_AMT, NVL(SUM(S.RMB_AAP_PY_QTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAP_PY_QTD_AMT, NVL(SUM(S.USD_AAA_PY_QTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAA_PY_QTD_AMT, NVL(SUM(S.USD_AAP_PY_QTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAP_PY_QTD_AMT, NVL(SUM(S.RMB_AAA_PY_YTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAA_PY_YTD_AMT, NVL(SUM(S.RMB_AAP_PY_YTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAP_PY_YTD_AMT, NVL(SUM(S.USD_AAA_PY_YTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAA_PY_YTD_AMT, NVL(SUM(S.USD_AAP_PY_YTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAP_PY_YTD_AMT, NVL(SUM(S.RMB_AAA_PY_ALL_QTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAA_PY_ALL_QTD_AMT, NVL(SUM(S.RMB_AAP_PY_ALL_QTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAP_PY_ALL_QTD_AMT, NVL(SUM(S.USD_AAA_PY_ALL_QTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAA_PY_ALL_QTD_AMT, NVL(SUM(S.USD_AAP_PY_ALL_QTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAP_PY_ALL_QTD_AMT, NVL(SUM(S.RMB_AAA_PY_ALL_YTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAA_PY_ALL_YTD_AMT, NVL(SUM(S.RMB_AAP_PY_ALL_YTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAP_PY_ALL_YTD_AMT, NVL(SUM(S.USD_AAA_PY_ALL_YTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAA_PY_ALL_YTD_AMT, NVL(SUM(S.USD_AAP_PY_ALL_YTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAP_PY_ALL_YTD_AMT, NVL(SUM(S.RMB_AAA_PP_PTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAA_PP_PTD_AMT, NVL(SUM(S.RMB_AAP_PP_PTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAP_PP_PTD_AMT, NVL(SUM(S.USD_AAA_PP_PTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAA_PP_PTD_AMT, NVL(SUM(S.USD_AAP_PP_PTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAP_PP_PTD_AMT, NVL(SUM(S.RMB_AAA_PP_QTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAA_PP_QTD_AMT, NVL(SUM(S.RMB_AAP_PP_QTD_AMT * A.CALCULATE_SIGN), 0) AS RMB_AAP_PP_QTD_AMT, NVL(SUM(S.USD_AAA_PP_QTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAA_PP_QTD_AMT, NVL(SUM(S.USD_AAP_PP_QTD_AMT * A.CALCULATE_SIGN), 0) AS USD_AAP_PP_QTD_AMT, :B4 AS CRT_JOB_ID FROM DM_REG_PL_SUM_F S, DM_FACT_TABLE_METADATA SRC_TAB, DM_FACT_TABLE_METADATA TGT_TAB, DM_ETL_SOURCE_TARGET_M D, DWR_DIM_RPT_ITEM_CAL_R A, DM_DIM_REPORT_ITEM_D REPORT, DM_DIM_REPORT_ITEM_D REPORT2, DM_DIM_DATA_REP_CATEGORY_B DATA, DM_DIM_REPORT_CATEGORY_D RPT, DM_SCHEDULE_TYPE_SESSION_TMP SCHDL WHERE S.REPORT_ITEM_ID = D.REPORT_ITEM_ID AND D.SOURCE_TABLE_ID = SRC_TAB.FACT_TABLE_ID AND D.TARGET_TABLE_ID = TGT_TAB.FACT_TABLE_ID AND SRC_TAB.FACT_TABLE_PHYSICAL_NAME = ''DM_REG_PL_SUM_F'' AND TGT_TAB.FACT_TABLE_PHYSICAL_NAME = ''DM_REG_CF_INDIRECT_BASE_F'' AND D.ENABLED_FLAG = ''Y'' AND S.REPORT_ITEM_ID = REPORT.REPORT_ITEM_ID AND REPORT.REPORT_ITEM_CODE = A.CHILD_RPT_ITEM_CODE AND A.PARENT_RPT_ITEM_CODE = REPORT2.REPORT_ITEM_CODE AND S.DATA_CATEGORY_ID = DATA.DATA_CATEGORY_ID AND DATA.REPORT_CATEGORY_ID = RPT.REPORT_CATEGORY_ID AND RPT.REPORT_CATEGORY_CN_NAME = ''经营报告'' AND REPORT2.USER_GROUP_CODE = ''GEO'' AND REPORT.RPT_ITEM_FREQUENCE LIKE ''%'' || SUBSTR(:B3 , 1, 1) || ''%'' AND S.SCHEDULE_TYPE_ID = SCHDL.SCHEDULE_TYPE_ID AND S.PERIOD_ID = :B2 AND S.VERSION_ID = :B1 AND S.PERIOD_ID BETWEEN NVL(REPORT2.BEGIN_ACCOUNT_PERIOD, 190001) AND NVL(REPORT2.END_ACCOUNT_PERIOD, 471212) AND A.DEL_FLAG = ''N'' GROUP BY REPORT2.REPORT_ITEM_ID, S.PERIOD_ID, S.SCENARIO_ID, DATA.DATA_CATEGORY_ID, S.BU_KEY, S.GEO_PC_KEY, S.SCHEDULE_TYPE_ID';
--添加: ar_profile_hints:=
ar_profile_hints:=
SYS.SQLPROF_ATTR(
q'[BEGIN_OUTLINE_DATA]',
q'[IGNORE_OPTIM_EMBEDDED_HINTS]',
q'[OPTIMIZER_FEATURES_ENABLE('11.2.0.3')]',
q'[DB_VERSION('11.2.0.3')]',
q'[ALL_ROWS]',
q'[SHARED(8)]',
q'[OUTLINE_LEAF(@"SEL$1")]',
q'[OUTLINE_LEAF(@"INS$1")]',
q'[FULL(@"INS$1" "DM_REG_CF_IND_BASE_F_REFRE_TMP"@"INS$1")]',
q'[FULL(@"SEL$1" "RPT"@"SEL$1")]',
q'[FULL(@"SEL$1" "DATA"@"SEL$1")]',
q'[FULL(@"SEL$1" "S"@"SEL$1")]',
q'[FULL(@"SEL$1" "D"@"SEL$1")]',
q'[FULL(@"SEL$1" "SRC_TAB"@"SEL$1")]',
q'[FULL(@"SEL$1" "TGT_TAB"@"SEL$1")]',
q'[FULL(@"SEL$1" "REPORT"@"SEL$1")]',
q'[FULL(@"SEL$1" "A"@"SEL$1")]',
q'[FULL(@"SEL$1" "REPORT2"@"SEL$1")]',
q'[FULL(@"SEL$1" "SCHDL"@"SEL$1")]',
q'[LEADING(@"SEL$1" "RPT"@"SEL$1" "DATA"@"SEL$1" "S"@"SEL$1" "D"@"SEL$1" "SRC_TAB"@"SEL$1" "TGT_TAB"@"SEL$1" "REPORT"@"SEL$1" "A"@"SEL$1" "REPORT2"@"SEL$1" "SCHDL"@"SEL$1")]',
q'[USE_HASH(@"SEL$1" "DATA"@"SEL$1")]',
q'[USE_HASH(@"SEL$1" "S"@"SEL$1")]',
q'[USE_HASH(@"SEL$1" "D"@"SEL$1")]',
q'[USE_HASH(@"SEL$1" "SRC_TAB"@"SEL$1")]',
q'[USE_HASH(@"SEL$1" "TGT_TAB"@"SEL$1")]',
q'[USE_HASH(@"SEL$1" "REPORT"@"SEL$1")]',
q'[USE_HASH(@"SEL$1" "A"@"SEL$1")]',
q'[USE_HASH(@"SEL$1" "REPORT2"@"SEL$1")]',
q'[USE_HASH(@"SEL$1" "SCHDL"@"SEL$1")]',
q'[PQ_DISTRIBUTE(@"SEL$1" "DATA"@"SEL$1" BROADCAST NONE)]',
q'[PQ_DISTRIBUTE(@"SEL$1" "S"@"SEL$1" BROADCAST NONE)]',
q'[PQ_DISTRIBUTE(@"SEL$1" "D"@"SEL$1" NONE BROADCAST)]',
q'[PQ_DISTRIBUTE(@"SEL$1" "SRC_TAB"@"SEL$1" NONE BROADCAST)]',
q'[PQ_DISTRIBUTE(@"SEL$1" "TGT_TAB"@"SEL$1" NONE BROADCAST)]',
q'[PQ_DISTRIBUTE(@"SEL$1" "REPORT"@"SEL$1" NONE BROADCAST)]',
q'[PQ_DISTRIBUTE(@"SEL$1" "A"@"SEL$1" NONE BROADCAST)]',
q'[PQ_DISTRIBUTE(@"SEL$1" "REPORT2"@"SEL$1" NONE BROADCAST)]',
q'[PQ_DISTRIBUTE(@"SEL$1" "SCHDL"@"SEL$1" NONE BROADCAST)]',
q'[SWAP_JOIN_INPUTS(@"SEL$1" "D"@"SEL$1")]',
q'[SWAP_JOIN_INPUTS(@"SEL$1" "SRC_TAB"@"SEL$1")]',
q'[SWAP_JOIN_INPUTS(@"SEL$1" "TGT_TAB"@"SEL$1")]',
q'[SWAP_JOIN_INPUTS(@"SEL$1" "REPORT"@"SEL$1")]',
q'[SWAP_JOIN_INPUTS(@"SEL$1" "A"@"SEL$1")]',
q'[SWAP_JOIN_INPUTS(@"SEL$1" "REPORT2"@"SEL$1")]',
q'[SWAP_JOIN_INPUTS(@"SEL$1" "SCHDL"@"SEL$1")]',
q'[GBY_PUSHDOWN(@"SEL$1")]',
q'[USE_HASH_AGGREGATION(@"SEL$1")]',
q'[END_OUTLINE_DATA]'
);
dbms_sqltune.import_sql_profile(sql_text => cl_sql_text,
profile => ar_profile_hints,
name => 'sqlprofile_ct3awf4buy84a_4204918125',
--description => 'sqlprofile_3hxp5740kgya8_4204918125',
force_match => true);
end;
d. 删除固定的执行计划。
exec dbms_sqltune.drop_sql_profile(name => 'ct3awf4buy84a');
简单实现python自动化
简单实现python自动化
之前自己是有一个功能需求,想借助自动化来实现,就去了解了一下,发现这东西其实非常简单,但是实现后的效果,看着它自己在那里操作的过程感觉很有趣,就打算以社区签到的为例分享给大家。我们都知道python的自动化可以模拟浏览器的交互操作,所以运行之后就如同播放动画一般,你只需要看着这一系列的动作在你眼前演示完成,以社区签到为例:运行脚本之后,你会看见这样一幅美好的画面,浏览器自动弹出,浏览器自己打开了登录页面,自动输入了用户名口令完成登录,然后它打开安全社区的网页,点击签到,最后浏览器自己关闭了。(本来打算把这个过程录屏为flash的,可惜hi3好像不支持,所以只能自行脑补了,下文中附上脚本代码运行即可)。在了解的过程中,发现python自动化多应用于自动化测试,十一假期不是马上就要来了么,每次放假最头疼的莫过于抢火车票了,当然可以借助自动化替你完成,我之前看也早有同事分享过自动化抢票,实现也非常简洁,所以说自动化可以发挥你的想象,实现一些你的功能需求,以一个生动的小例子开启python自动化的大门。
自动化完成社区签到的小例子分享(你会发现,想get到,环境搭好后也只是分分钟的事~)
温馨小提示:签到的小例子在此仅作为引子,作为社区铁粉们,还是不建议大家用该种方式进行签到,目的希望更多人了解自动化的过程与实现,并在有相关自动化需求时,去更广的应用和实现。
准备工作
一、搭建环境(注:python基础环境必须)
1)主要用到的自动化利器:splinter和selenium(见附件或自行下载)
下载地址:
https://pypi.python.org/pypi/splinter/
https://pypi.python.org/pypi/selenium
如果只安装了splinter,运行是会报错,提示必须要安装selenium(安装方法见文末附录1)。
2)根据自己的习惯选择浏览器驱动,包括firefox和chorme浏览器的(见附件或自行下载,浏览器驱动的安装使用方法见文末附录2,)
下载地址:
firefox:https://github.com/mozilla/geckodriver/releases
chorme:http://chromedriver.storage.googleapis.com/index.html?path=2.30/
备注:如果下载的浏览器启动版本跟自己正在使用的浏览器版本不匹配,测试打开chrome浏览器时,会弹出来chromedriver.exe已停止工作的错误
通过修改下载地址中的path参数,可以下载到对应版本的驱动(当前附件中提供的是v2.30对应的chrome版本是v58-60)
关于查看版本之间对应关系的传送(由于有些同事不可以打开连接,将如何查看当前自己已安装的chrome版本以及驱动对应关系附在文末,可见文末):
http://3ms.huawei.com/km/blogs/details/5084655
3)编写自己的测试脚本(脚本见附件SignAutomation.zip)
这里我们写了一个自动化完成社区签到的,可以看到非常简单,主要使用的是splinter,贴出来,供大家搭建好环境好,直接运行测试使用:
-Python 代码
# -*- coding: utf-8 -*-
# 自动打开w3登录页面 输入用户名密码 点击登录 登录后再打开社区 自动点击签到按钮 签到完成 退出当前浏览器
from splinter.browser import Browser
import time
def sign(mode):
targeturl = "http://3ms.huawei.com/hi/group/2034125"
login_url = "https://login.huawei.com/login/"
browser = Browser('chrome')
username = u"U-W3-PID" # 此处内容替换为你的域账号:姓氏首字母+工号
# 开启自动输入用户密码时,需要填入密码
password = u"U-W3-PWD" # 密码
browser.visit(login_url)
browser.fill('uid', username)
time.sleep(1)
if mode == 0:
print u"等待输入密码,自行输入..." # 自行输入密码,只需输入密码,不需手动点击登录框,由自动化完成点击登录
time.sleep(10)
else:
browser.fill('password', password) # 由自动化脚本自动输入密码
time.sleep(3)
browser.find_by_name('Submit').click()
time.sleep(3)
browser.visit(targeturl)
time.sleep(3)
scores = browser.find_by_id('communityScores').text
print u"签到前社区积分:%r" % scores
time.sleep(3)
browser.find_by_id('sign').click()
time.sleep(3)
print u"签到后社区积分:%r" % scores
browser.quit()
if __name__ == "__main__":
mode = 0 # 是否开启自动输入密码模式,为0是自行输入
sign(mode)
代码实现中的几个小小的注意点:
在运行脚本之前,记得先在脚本中填入自己的w3域账号哦,然后在设置自己想要的登录模式,medo值为非0如1时,记得在脚本中填入自己的域口令,再运行
- 自动化打开的浏览器是由浏览器驱动打开的,是一个完全空白的,会弹出来需要输入域账号和口令先登录,而hi3是使用的w3的登录接口,当前我们的实现是先登录w3,再打开社区
- 完成登录,代码中实现了2种登录模式,当登录模式mode赋值为0,则浏览器自动输入用户名之后,会等待,等待我们自行输入口令,此时只需输入我们的口令,不需手动点击登录按钮,等待登录按钮自行触发即可。由于手工输入可能需要的时长稍久一点,所以我们设置需等待10s
- 如果mode值不为零,则为完全自动化,这种情况需要你将你的口令赋值到脚本中,可能有些人不想输入到脚本中,所以提供了2中的登录模式,由于我们只是为了简单实例完成自动化体验,所以在此处没有做过多的实现,待有兴趣的同事可以完善研究一下
附:
1)安装方法(该安装方法需要python先安装setuptools包):
splinter和selenium两者的安装方法一样,这里仅以splinter为例:
打开命令窗口,并进入到Splinter解压缩之后所在的目录:f:\ruanjian\splinter-0.7.6\splinter-0.7.6
输入安装命令:python setup.py build
完成之后再次输入命令:python setup.py install
完成安装之后,在python模式下,输入命令:from splinter.browser import Browser
如果没有报错,则说明安装成功
可以看到报了一个错误,是因为我们还没有安装selenium
同样的安装方法安装完成selenium之后,就可以运行splinter了
再次进入python模式,输入测试命令,可以看到不再报错,说明以上两个软件都以成功安装
2)接下来安装浏览器启动,将下载好的firefox和chorme浏览器的驱动解压,将解压得到的两个exe文件复制到python的安装根目录下,与python.exe同一目录,如果不是这样就需要设置环境变量
测试,继续在命令窗口中,之前的python模式下输入:browser = Browser
默认缺省没有指定要使用的浏览器时,默认打开的将会是firefox
没有报错说明安装成功,当前环境已经搭建好了
测试打开chorme
输入后自动打开了chorme,说明安装成功
3)弹出来chromedriver.exe已停止工作的错误的解决方案
根因:chromedriver和chrome的版本不匹配导致的
查看我们当前主机安装的chrome版本信息
在chrome浏览器中键入:chrome://version
可以查看我们当前安装运行的是59,然后找到对应的chromedriver版本
需要下载chrome v2.30以上的
访问下载链接:
http://chromedriver.storage.googleapis.com/index.html?path=2.30/
可以看到通过path参数的修改可以下载到我们想下载的对应版本的chrome驱动
附:chromedriver与chrome的对应关系
awrtest
有客户反映insert语句需要100min才能执行完成,查看相关语句,然后客户告知有表table1数据量比较大,一个分区每天20M rows,然后以此为主表进行关联。
sql乍一看似乎没什么问题,但是2kw行数据也不需要100min才能关联完成,需要执行计划才能确定问题。
分析该awrsql,发现user IO等待事件较长,同时buffer gets 与 diskread比较高且数值接近,说明使用了物理IO排序。但是仍然不是主要的耗时资源。
分析现场执行计划,发现2kw数据只需匹配30w即可,又开始从数据方面或者索引方面开始想。
由于属于OLAP,很快否定了索引解决办法。无意中发现执行计划中出现"PARTITION LIST ALL",上网搜索,得出意思是扫描了全部分区。
继续扩展执行计划,得到 pstart=1 pstop=61,也就是说数据是61*2kw,那么执行100min是理所当然。
更改了where条件,并修正了并行执行后。语句执行只需132s完成。
WORKLOAD REPOSITORY SQL Report
Snapshot Period Summary
Snap Id | Snap Time | Sessions | Cursors/Session | |
---|---|---|---|---|
Begin Snap: | 23363 | 09-Jan-17 06:45:33 | 94 | 1.4 |
End Snap: | 23366 | 09-Jan-17 09:45:14 | 128 | 1.9 |
Elapsed: | 179.69 (mins) | |||
DB Time: | 4,441.28 (mins) |
SQL Summary
SQL Id | Elapsed Time (ms) | Module | Action | SQL Text |
---|---|---|---|---|
d925mk4g1b4kh | 6,852,453 | INSERT INTO test( DAYCD , REGION_ID , DIST_... |
SQL ID: d925mk4g1b4kh
- 1st Capture and Last Capture Snap IDs refer to Snapshot IDs witin the snapshot range
- INSERT INTO test( DAYCD , REGION_ID , DIST_DE...
# | Plan Hash Value | Total Elapsed Time(ms) | Executions | 1st Capture Snap ID | Last Capture Snap ID |
---|---|---|---|---|---|
1 | 3321082722 | 6,852,453 | 1 | 23364 | 23365 |
Plan 1(PHV: 3321082722)
Back to TopPlan Statistics
- % Total DB Time is the Elapsed Time of the SQL statement divided into the Total Database Time multiplied by 100
Stat Name | Statement Total | Per Execution | % Snap Total |
---|---|---|---|
Elapsed Time (ms) | 6,852,453 | 6,852,453.31 | 2.57 |
CPU Time (ms) | 1,328,920 | 1,328,920.00 | 5.54 |
Executions | 1 | ||
Buffer Gets | 30,318,645 | 30,318,645.00 | 3.58 |
Disk Reads | 30,219,190 | 30,219,190.00 | 6.93 |
Parse Calls | 0 | 0.00 | 0.00 |
Rows | 26 | 26.00 | |
User I/O Wait Time (ms) | 4,166,410 | ||
Cluster Wait Time (ms) | 53,603 | ||
Application Wait Time (ms) | 0 | ||
Concurrency Wait Time (ms) | 77 | ||
Invalidations | 0 | ||
Version Count | 2 | ||
Sharable Mem(KB) | 147 |
Back to Plan 1(PHV: 3321082722)
Back to Top
Execution Plan
Id | Operation | Name | Rows | Bytes | Cost (%CPU) | Time | Pstart | Pstop |
---|---|---|---|---|---|---|---|---|
0 | INSERT STATEMENT | 8331K(100) | ||||||
1 | LOAD TABLE CONVENTIONAL | |||||||
2 | HASH GROUP BY | 1 | 415 | 8331K (1) | 27:46:19 | |||
3 | FILTER | |||||||
4 | HASH JOIN | 1 | 415 | 8331K (1) | 27:46:19 | |||
5 | HASH JOIN | 1 | 357 | 8331K (1) | 27:46:15 | |||
6 | HASH JOIN OUTER | 1 | 297 | 8330K (1) | 27:46:06 | |||
7 | HASH JOIN OUTER | 1 | 257 | 8330K (1) | 27:46:05 | |||
8 | HASH JOIN | 1 | 243 | 8330K (1) | 27:46:05 | |||
9 | PARTITION LIST ALL | 1 | 36 | 40830 (1) | 00:08:10 | 1 | 60 | |
10 | TABLE ACCESS FULL | table5 | 1 | 36 | 40830 (1) | 00:08:10 | 1 | 60 |
11 | PARTITION LIST ALL | 1491 | 301K | 8289K (1) | 27:37:55 | 1 | 61 | |
12 | TABLE ACCESS FULL | table1 | 1491 | 301K | 8289K (1) | 27:37:55 | 1 | 61 |
13 | TABLE ACCESS FULL | table3 | 11 | 154 | 3 (0) | 00:00:01 | ||
14 | TABLE ACCESS FULL | table4 | 6 | 240 | 3 (0) | 00:00:01 | ||
15 | TABLE ACCESS FULL | table2 | 566 | 33960 | 822 (1) | 00:00:10 | ||
16 | PARTITION LIST SINGLE | 15022 | 850K | 285 (47) | 00:00:04 | KEY | KEY | |
17 | TABLE ACCESS FULL | table6 | 15022 | 850K | 285 (47) | 00:00:04 | KEY | KEY |
- dynamic sampling used for this statement
Back to Plan 1(PHV: 3321082722)
Back to Top
Full SQL Text
参考文档
http://docs.oracle.com/cd/B14117_01/server.101/b10752/ex_plan.htm#7211
oracle ASM详解
1. ASM Components
- Oracle ASM Extents
An Oracle ASM extent is the raw storage used to hold the contents of an Oracle ASM file. An Oracle ASM file consists of one or more file extents. Each Oracle ASM extent consists of one or more allocation units on a specific disk.
Note:
An Oracle ASM extent is different from the extent used to store data in a segment. - Oracle ASM Allocation Units(AU)
An allocation unit is the fundamental unit of allocation within a disk group. An allocation unit is the smallest contiguous disk space that Oracle ASM allocates. One or more allocation units form an Oracle ASM extent.
ASM在分配空间时,以AU为单位进行,AU即Allocation units,是组成ASM disk的基本单元。
在Oracle 10gR2中,ASM AU的缺省单位大小是1M,相应的条带大小是128K。
在ASM中,可以通过调整_asm_ausize隐含参数的大小来进行调整,_asm_stripesize控制相应的条带化参数。
ASM has the following size limits:
• 63 disk groups in a storage system
• 10,000 ASM disks in a storage system
• 1 million files for each disk group
ORA-15196 WITH ASM DISKS LARGER THAN 2TB [ID 736891.1]
Can I create an 11.2 disk over the 2 TB limit [ID 1077784.1]
2. ASM processes
(1)ORACLE不支持一个节点上启动多个ASM实例,因为如果多个实例上面mount了同名的DG,但是物理上用的是不同的disk或裸设备,这样数据库实例就不知道用哪一个实例的DG了。但是实际上一个节点上启动多个ASM实例是可以的。
(2)RAC数据库的ASM实例主要通过asm disk的metadata进行通信
When you create a disk group for a cluster, or add new disks to an existing clustered disk group, you must prepare only the underlying physical storage on shared disks.The shared disk requirement is the only substantial difference between using Oracle ASM in an Oracle RAC database compared to using it in a single-instance Oracle database. Oracle ASM automatically rebalances the storage load after you add or delete a disk or disk group.
In a cluster, each Oracle ASM instance manages the metadata updates to the disk groups for the node on which it is running. In addition, each Oracle ASM instance coordinates disk group metadata with other nodes in the cluster.
2.1. Cluster Synchronization Services Requirements for ASM
The Cluster Synchronization Services (CSS) daemon provides cluster services for ASM, communication between the ASM and database instances, and other essential services. When DBCA creates a database, the CSS daemon is usually started and configured to start upon restart. If DBCA created the database, then you must ensure that the CSS daemon is running before you start the ASM instance.
2.1.1. 启动css服务 (CSS Daemon on UNIX and Linux Computers)
To determine if the CSS daemon is running, run the command crsctl check cssd. If Oracle displays the message CSS appears healthy, then the CSS daemon is running. Otherwise, to start the CSS daemon and configure the host to always start the daemon upon restart, do the following:
Log in to the host as the root user.
Ensure that the entry $ORACLE_HOME/bin is in your PATH environment variable.
Run the following command:
localconfig add
2.1.2. 重配css服务
su -
cd <oracle_home>/bin
./localconfig delete
./localconfig add
注意:RAC环境下请勿使用,否则会破坏ocr,导致crs不能启动。RAC环境下重配css服务需要重建ocr和voting disk
2.1.3. 停止css服务(待确认)
crsctl stop crs?
2.2. ASM Background Processes
The following background processes are an integral part of Automatic Storage Management:
· ARBn performs the actual rebalance data extent movements in an Automatic Storage Management instance. There can be many of these processes running at a time, named ARB0, ARB1, and so on.
· ASMB runs in a database instance that is using an ASM disk group. ASMB communicates with the ASM instance, managing storage and providing statistics. ASMB can also run in the ASM instance. ASMB runs in ASM instances when the ASMCMD cp command runs or when the database instance first starts if the SPFILE is stored in ASM.
· GMON maintains disk membership in ASM disk groups.
· MARK marks ASM allocation units as stale following a missed write to an offline disk. This essentially tracks which extents require resync for offline disks.
· RBAL runs in both database and ASM instances. In the database instance, it does a global open of ASM disks. In an ASM instance, it also coordinates rebalance activity for disk groups.
The processes described in the previous list are important for the ASM instance and should not be modified. In addition to the processes listed in this section, there are additional processes that run in both the ASM and database instances, such as database writer process (DBWn), log writer process (LGWR), Process Monitor Process (PMON), and System Monitor Process (SMON).
Also, there are ASM slave processes that run periodically to perform a specific task. For example, the Snnn transient slave process is responsible for performing the resync of extents at the time that the disk is brought online. The slave processes are not technically background processes.
For more information about Oracle database background processes, see the discussion about background processes in Oracle Database Concepts. For a description of the V$BGPROCESS view that displays information about background processes, see the Oracle Database Reference.
2.3. 进程间通信
2.3.1. css和asm: socket
root@sun880-1 # pfiles 3566
3566: /opt/oracle/db/product/11.1.0/db_1/bin/ocssd.bin
Current rlimit: 65536 file descriptors
0: S_IFCHR mode:0666 dev:379,0 ino:6815752 uid:0 gid:3 rdev:13,2
O_RDONLY|O_LARGEFILE
/devices/pseudo/mm@0:null
1: S_IFREG mode:0666 dev:118,3 ino:73632 uid:101 gid:0 size:175
O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE
/opt/oracle/db/product/11.1.0/db_1/log/sun880-1/cssd/cssdOUT.log
2: S_IFREG mode:0666 dev:118,3 ino:73632 uid:101 gid:0 size:175
O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE
/opt/oracle/db/product/11.1.0/db_1/log/sun880-1/cssd/cssdOUT.log
3: S_IFREG mode:0666 dev:118,3 ino:73632 uid:101 gid:0 size:175
O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE
/opt/oracle/db/product/11.1.0/db_1/log/sun880-1/cssd/cssdOUT.log
4: S_IFDOOR mode:0444 dev:388,0 ino:55 uid:0 gid:0 size:0
O_RDONLY|O_LARGEFILE FD_CLOEXEC door to nscd[241]
/var/run/name_service_door
5: S_IFREG mode:0644 dev:118,3 ino:6602 uid:101 gid:203 size:6656
O_RDONLY|O_LARGEFILE FD_CLOEXEC
/opt/oracle/db/product/11.1.0/db_1/srvm/mesg/procus.msb
6: S_IFREG mode:0644 dev:118,3 ino:57124 uid:101 gid:203 size:268644352
O_RDONLY|O_DSYNC|O_LARGEFILE
/opt/oracle/db/product/11.1.0/db_1/cdata/localhost/local.ocr
7: S_IFREG mode:0644 dev:118,3 ino:182560 uid:101 gid:203 size:4608
O_RDONLY|O_LARGEFILE FD_CLOEXEC
/opt/oracle/db/product/11.1.0/db_1/css/mesg/clssus.msb
8: S_IFREG mode:0644 dev:118,3 ino:73619 uid:101 gid:203 size:4567147
O_WRONLY|O_APPEND|O_LARGEFILE
/opt/oracle/db/product/11.1.0/db_1/log/sun880-1/cssd/ocssd.log
9: S_IFSOCK mode:0666 dev:386,0 ino:19296 uid:0 gid:0 size:0
O_RDWR|O_NDELAY FD_CLOEXEC
SOCK_DGRAM
SO_REUSEADDR,SO_SNDBUF(57344),SO_RCVBUF(57344),IP_NEXTHOP(0.0.224.0)
sockname: AF_INET 127.0.0.1 port: 32813
10: S_IFSOCK mode:0666 dev:386,0 ino:56432 uid:0 gid:0 size:0
O_RDWR FD_CLOEXEC
SOCK_STREAM
SO_SNDBUF(16384),SO_RCVBUF(5120)
sockname: AF_UNIX /var/tmp/.oracle/ssun880-1DBG_CSSD
11: S_IFSOCK mode:0666 dev:386,0 ino:30025 uid:0 gid:0 size:0
O_RDWR|O_NDELAY FD_CLOEXEC
SOCK_DGRAM
SO_REUSEADDR,SO_SNDBUF(57344),SO_RCVBUF(57344),IP_NEXTHOP(0.0.224.0)
sockname: AF_INET 127.0.0.1 port: 32814
12: S_IFSOCK mode:0666 dev:386,0 ino:30024 uid:0 gid:0 size:0
O_RDWR FD_CLOEXEC
SOCK_STREAM
SO_REUSEADDR,SO_SNDBUF(49152),SO_RCVBUF(49152),IP_NEXTHOP(0.0.192.0)
sockname: AF_INET 127.0.0.1 port: 32889
13: S_IFSOCK mode:0666 dev:386,0 ino:30023 uid:0 gid:0 size:0
O_RDWR|O_NDELAY FD_CLOEXEC
SOCK_DGRAM
SO_REUSEADDR,SO_SNDBUF(57344),SO_RCVBUF(57344),IP_NEXTHOP(0.0.224.0)
sockname: AF_INET 127.0.0.1 port: 32815
14: S_IFSOCK mode:0666 dev:386,0 ino:30022 uid:0 gid:0 size:0
O_RDWR FD_CLOEXEC
SOCK_STREAM
SO_REUSEADDR,SO_SNDBUF(49152),SO_RCVBUF(49152),IP_NEXTHOP(0.0.192.0)
sockname: AF_INET 127.0.0.1 port: 32890
15: S_IFSOCK mode:0666 dev:386,0 ino:19297 uid:0 gid:0 size:0
O_RDWR|O_NDELAY FD_CLOEXEC
SOCK_DGRAM
SO_REUSEADDR,SO_SNDBUF(57344),SO_RCVBUF(57344),IP_NEXTHOP(0.0.224.0)
sockname: AF_INET 127.0.0.1 port: 32816
16: S_IFSOCK mode:0666 dev:386,0 ino:56443 uid:0 gid:0 size:0
O_RDWR FD_CLOEXEC
SOCK_STREAM
SO_SNDBUF(16384),SO_RCVBUF(5120)
sockname: AF_UNIX /var/tmp/.oracle/sOracle_CSS_LclLstnr_localhost_0
17: S_IFSOCK mode:0666 dev:386,0 ino:6110 uid:0 gid:0 size:0
O_RDWR FD_CLOEXEC
SOCK_STREAM
SO_SNDBUF(16384),SO_RCVBUF(5120)
sockname: AF_UNIX /var/tmp/.oracle/sOCSSD_LL_sun880-1_
18: S_IFSOCK mode:0666 dev:386,0 ino:56436 uid:0 gid:0 size:0
O_RDWR FD_CLOEXEC
SOCK_STREAM
SO_SNDBUF(16384),SO_RCVBUF(5120)
sockname: AF_UNIX /var/tmp/.oracle/sOCSSD_LL_sun880-1_localhost
19: S_IFREG mode:0644 dev:118,3 ino:46690 uid:101 gid:203 size:10220
O_WRONLY|O_APPEND|O_LARGEFILE
/opt/oracle/db/product/11.1.0/db_1/log/sun880-1/alertsun880-1.log
20: S_IFREG mode:0644 dev:118,3 ino:6659 uid:101 gid:203 size:6656
O_RDONLY|O_LARGEFILE FD_CLOEXEC
/opt/oracle/db/product/11.1.0/db_1/has/mesg/clsdus.msb
21: S_IFSOCK mode:0666 dev:386,0 ino:6106 uid:0 gid:0 size:0
O_RDWR|O_NDELAY FD_CLOEXEC
SOCK_STREAM
SO_SNDBUF(16384),SO_RCVBUF(5120)
sockname: AF_UNIX /var/tmp/.oracle/sOCSSD_LL_sun880-1_
peername: AF_UNIX
22: S_IFSOCK mode:0666 dev:386,0 ino:6107 uid:0 gid:0 size:0
O_RDWR|O_NDELAY FD_CLOEXEC
SOCK_STREAM
SO_SNDBUF(16384),SO_RCVBUF(5120)
sockname: AF_UNIX /var/tmp/.oracle/sOCSSD_LL_sun880-1_
peername: AF_UNIX
oracle@sun880-1$ lsof | grep "/tmp/.oracle/"
ocssd.bin 3566 oracle 10u unix 105,309 0t0 55050244 /devices/pseudo/tl@0:ticots->/var/tmp/.oracle/ssun880-1DBG_CSSD (0x60017b8e008) (Vnode=0x6001e2f11c0)
ocssd.bin 3566 oracle 16u unix 105,311 0t0 55050244 /devices/pseudo/tl@0:ticots->/var/tmp/.oracle/sOracle_CSS_LclLstnr_localhost_0 (0x60017b8f798) (Vnode=0x6001e2f1ac0)
ocssd.bin 3566 oracle 17u unix 105,313 0t0 55050244 /devices/pseudo/tl@0:ticots->/var/tmp/.oracle/sOCSSD_LL_sun880-1_ (0x6001e2fbd10) (Vnode=0x6001e2f08c0)
ocssd.bin 3566 oracle 18u unix 105,315 0t0 55050244 /devices/pseudo/tl@0:ticots->/var/tmp/.oracle/sOCSSD_LL_sun880-1_localhost (0x60017b8e918) (Vnode=0x6001e2f07c0)
ocssd.bin 3566 oracle 21u unix 105,326 0t2483 55050244 /devices/pseudo/tl@0:ticots->/var/tmp/.oracle/sOCSSD_LL_sun880-1_ (0x6001e2fb5d0)
ocssd.bin 3566 oracle 22u unix 105,334 0t10246 55050244 /devices/pseudo/tl@0:ticots->/var/tmp/.oracle/sOCSSD_LL_sun880-1_ (0x6001e2fb7a0)
tnslsnr 8842 oracle 11u unix 105,319 0t0 55050244 /devices/pseudo/tl@0:ticots->/var/tmp/.oracle/s#8842.1 (0x60017b8f3f8) (Vnode=0x6001a602880)
tnslsnr 8842 oracle 12u unix 105,320 0t0 55050244 /devices/pseudo/tl@0:ticots->/var/tmp/.oracle/sEXTPROC1521 (0x60017b8e1d8) (Vnode=0x6001a602780)
oracle 10625 oracle 20u unix 105,325 0t2483 55050244 /devices/pseudo/tl@0:ticots->/var/tmp/.oracle/sOCSSD_LL_sun880-1_ (0x6001e2fb970->0x6001e2f08c0)
oracle 11862 oracle 19u unix 105,333 0t10246 55050244 /devices/pseudo/tl@0:ticots->/var/tmp/.oracle/sOCSSD_LL_sun880-1_ (0x60017b8e578->0x6001e2f08c0)
oracle@sun880-1$ ps -ef | grep 10625
oracle 10625 1 0 16:06:56 ? 0:04 ora_dbw0_orahw
oracle 29271 8523 0 10:57:44 pts/2 0:00 grep 10625
oracle@sun880-1$ ps -ef | grep 11862
oracle 11862 1 0 16:07:45 ? 0:04 asm_gmon_+ASM
oracle 29320 8523 0 10:57:56 pts/2 0:00 grep 11862
2.3.2. asm和rdbms:命名管道(FIFO)
asm实例和rdbms实例都可以访问asm disk,数据库实例启动以后,会启动ora_asmb_< RDBMS_SID >进程,同时会启动一个oracle<ASM_SID>asmb<RDBMS_SID>,这两个进程通过命名管道(FIFO)通信。
# procfiles -n 1508058
1508058 : ora_asmb_ora11g1
Current rlimit: 2147483647 file descriptors
0: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDWR name://dev/null
1: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDWR name://dev/null
2: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDWR name://dev/null
3: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
4: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
5: S_IFREG mode:0220 dev:10,18 ino:245508 uid:210 gid:500 rdev:0,0
O_WRONLY | O_APPEND size:0 name:/opt/oracle/db/diag/rdbms/ora11g/ora11g1/trace/ora11g1_ora_2228368.trc
6: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
7: S_IFREG mode:0660 dev:10,18 ino:183770 uid:210 gid:500 rdev:0,0
O_RDWR | O_SYNC size:0 name:/opt/oracle/db/product/11.1.0/db_1/dbs/hc_ora11g1.dat
8: S_IFREG mode:0660 dev:10,18 ino:183784 uid:210 gid:500 rdev:0,0
O_RDWR size:0 name:/opt/oracle/db/product/11.1.0/db_1/dbs/hc_ora11g1.dat
9: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
10: S_IFREG mode:0220 dev:10,18 ino:245509 uid:210 gid:500 rdev:0,0
O_WRONLY | O_APPEND size:0 name:/opt/oracle/db/diag/rdbms/ora11g/ora11g1/trace/ora11g1_ora_2228368.trm
11: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
13: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
15: S_IFREG mode:0444 dev:10,18 ino:165442 uid:210 gid:500 rdev:0,0
O_RDONLY size:0 name:/opt/oracle/db/product/11.1.0/db_1/rdbms/mesg/oraus.msb
16: S_IFREG mode:0660 dev:10,18 ino:183770 uid:210 gid:500 rdev:0,0
O_RDWR | O_SYNC size:0 name:/opt/oracle/db/product/11.1.0/db_1/dbs/hc_ora11g1.dat
19: S_IFREG mode:0444 dev:10,18 ino:100482 uid:210 gid:500 rdev:0,0
O_RDONLY size:0 name:/opt/oracle/db/product/11.1.0/db_1/srvm/mesg/procus.msb
25: S_IFIFO mode:00 dev:65535,65535 ino:4291619 uid:210 gid:500 rdev:0,0
O_WRONLY name:Cannot be retrieved
26: S_IFIFO mode:00 dev:65535,65535 ino:4291620 uid:210 gid:500 rdev:0,0
O_RDONLY name:Cannot be retrieved
#
# find . -inum 4291619
./proc/3080686/fd/24
./proc/1508058/fd/25
# find . -inum 4291620
./proc/3080686/fd/27
./proc/1508058/fd/26
# ps -ef | grep 3080686
root 2228288 3211606 0 10:28:03 pts/0 0:00 grep 3080686
oracle 3080686 1 0 10:10:06 - 0:00 oracle+ASM1_asmb_ora11g1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
# ps -ef | grep 1508058
oracle 1508058 1 0 10:10:06 - 0:00 ora_asmb_ora11g1
root 2359916 3211606 0 10:28:12 pts/0 0:00 grep 1508058
#
# procfiles -n 3080686
3080686 : oracle+ASM1_asmb_ora11g1 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
Current rlimit: 65534 file descriptors
0: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDWR name://dev/null
1: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDWR name://dev/null
2: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDWR name://dev/null
3: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
4: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
5: S_IFREG mode:0220 dev:10,18 ino:245508 uid:210 gid:500 rdev:0,0
O_WRONLY | O_APPEND size:0 name:/opt/oracle/db/diag/rdbms/ora11g/ora11g1/trace/ora11g1_ora_2228368.trc
6: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
7: S_IFREG mode:0660 dev:10,18 ino:183770 uid:210 gid:500 rdev:0,0
O_RDWR | O_SYNC size:0 name:/opt/oracle/db/product/11.1.0/db_1/dbs/hc_ora11g1.dat
8: S_IFREG mode:0660 dev:10,18 ino:183784 uid:210 gid:500 rdev:0,0
O_RDWR size:0 name:/opt/oracle/db/product/11.1.0/db_1/dbs/hc_ora11g1.dat
9: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
10: S_IFREG mode:0220 dev:10,18 ino:245509 uid:210 gid:500 rdev:0,0
O_WRONLY | O_APPEND size:0 name:/opt/oracle/db/diag/rdbms/ora11g/ora11g1/trace/ora11g1_ora_2228368.trm
11: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
12: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
13: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
14: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
16: S_IFREG mode:0660 dev:10,18 ino:183770 uid:210 gid:500 rdev:0,0
O_RDWR | O_SYNC size:0 name:/opt/oracle/db/product/11.1.0/db_1/dbs/hc_ora11g1.dat
17: S_IFCHR mode:00 dev:10,4 ino:28765 uid:210 gid:500 rdev:2,2
O_RDONLY name://dev/null
19: S_IFREG mode:0444 dev:10,18 ino:165442 uid:210 gid:500 rdev:0,0
O_RDONLY size:0 name:/opt/oracle/db/product/11.1.0/db_1/rdbms/mesg/oraus.msb
21: S_IFREG mode:0660 dev:10,18 ino:245518 uid:210 gid:500 rdev:0,0
O_RDWR | O_APPEND size:0 name:/opt/oracle/db/product/11.1.0/db_1/rdbms/audit/ora_3080686.aud
22: S_IFREG mode:0440 dev:10,18 ino:183766 uid:210 gid:500 rdev:0,0
O_RDONLY | O_SYNC size:0 name:/opt/oracle/db/product/11.1.0/db_1/dbs/ab_+ASM1.dat
24: S_IFIFO mode:00 dev:65535,65535 ino:4291619 uid:210 gid:500 rdev:0,0
O_RDONLY name:Cannot be retrieved
27: S_IFIFO mode:00 dev:65535,65535 ino:4291620 uid:210 gid:500 rdev:0,0
O_WRONLY name:Cannot be retrieved
29: S_IFREG mode:0444 dev:10,18 ino:100482 uid:210 gid:500 rdev:0,0
O_RDONLY size:0 name:/opt/oracle/db/product/11.1.0/db_1/srvm/mesg/procus.msb
#
3. ASM metadata
ASM metadata保存了ASM的信息,非常重要,如果metadata损坏,ASM通常都无法正常mount。
11g
http://www.killdb.com/wp-content/uploads/2013/01/asm_metadata.jpg
3.1. ASM 磁盘头
AU 0 blk 0是ASM的磁盘头,256 字节。AU 1 blk 254是磁盘头备份。
[oracle@10gasm ~]$ kfed read /dev/sdd aun=0 blkn=0| more
kfbh.endian: 1 ; 0x000: 0x01 --大小端,1:小端 0:大端
kfbh.hard: 130 ; 0x001: 0x82 -- H.A.R.D. magic # and block size
kfbh.type: 1 ; 0x002: KFBTYP_DISKHEAD -- metadata类型
kfbh.datfmt: 1 ; 0x003: 0x01--metadata block data format 取值为1,表示已经格式化
kfbh.block.blk: 0 ; 0x004: T=0 NUMB=0x0 -- block位置,磁盘头是blk 0
kfbh.block.obj: 2147483648 ; 0x008: TYPE=0x8 NUMB=0x0 --/* block object id Disk header 的type为8 ,num表示asm disk在group中的编号,即kfdhdb.dsknum,TYPE=0×8 NUMB=0×0表示为8000000,十进制也就是2147483648 */
kfbh.check: 2263475499 ; 0x00c: 0x86e9e52b -- 一致性检查位,会自动检查
kfbh.fcn.base: 0 ; 0x010: 0x00000000 --change number of last change
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfdhdb.driver.provstr: ORCLDISK ; 0x000: length=8 --ASMLIB driver reserved block If no driver is defined "ORCLDISK" is used. 如果没使用ASMlib,默认为 ORCLDISK,否则为ORCLDISK+Name
kfdhdb.driver.reserved[0]: 0 ; 0x008: 0x00000000
kfdhdb.driver.reserved[1]: 0 ; 0x00c: 0x00000000
kfdhdb.driver.reserved[2]: 0 ; 0x010: 0x00000000
kfdhdb.driver.reserved[3]: 0 ; 0x014: 0x00000000
kfdhdb.driver.reserved[4]: 0 ; 0x018: 0x00000000
kfdhdb.driver.reserved[5]: 0 ; 0x01c: 0x00000000
kfdhdb.compat: 168820736 ; 0x020: 0x0a100000 -ASM兼容版本 10.1.0.0.0
kfdhdb.dsknum: 0 ; 0x024: 0x0000 -- disk number
kfdhdb.grptyp: 1 ; 0x026: KFDGTP_EXTERNAL ---磁盘组冗余方式
kfdhdb.hdrsts: 3 ; 0x027: KFDHDR_MEMBER ---磁盘header 状态 3是可用状态
kfdhdb.dskname: DATA1_0000 ; 0x028: length=10 --- ASM磁盘名
kfdhdb.grpname: DATA1 ; 0x048: length=5 ---磁盘组名称
kfdhdb.fgname: DATA1_0000 ; 0x068: length=10 -- ASM failgroup name
kfdhdb.capname: ; 0x088: length=0 -- Capacity group name,未使用
kfdhdb.crestmp.hi: 32977478 ; 0x0a8: HOUR=0x6 DAYS=0x12 MNTH=0xc YEAR=0x7dc
kfdhdb.crestmp.lo: 2407340032 ; 0x0ac: USEC=0x0 MSEC=0x346 SECS=0x37 MINS=0x23
kfdhdb.mntstmp.hi: 32977622 ; 0x0b0: HOUR=0x16 DAYS=0x16 MNTH=0xc YEAR=0x7dc
kfdhdb.mntstmp.lo: 1597193216 ; 0x0b4: USEC=0x0 MSEC=0xcf SECS=0x33 MINS=0x17
kfdhdb.secsize: 512 ; 0x0b8: 0x0200 --Disk sector size (bytes) 默认取值512
kfdhdb.blksize: 4096 ; 0x0ba: 0x1000 -- block size
kfdhdb.ausize: 1048576 ; 0x0bc: 0x00100000 ---au单位大小,单位是byte,大小为1m.
kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80 --Stride between phys addr Aus 默认取值113792
kfdhdb.dsksize: 1024 ; 0x0c4: 0x00000400 ---该disk的大小,单位是au,由于默认au是1m,所以大小为1024m.
kfdhdb.pmcnt: 2 ; 0x0c8: 0x00000002 --Number of physically addressed allocation units
kfdhdb.fstlocn: 1 ; 0x0cc: 0x00000001 -- First FreeSpace table blk num 用于记录freespace信息的首个block,通过KFBTYP_FREESPC 获得
kfdhdb.altlocn: 2 ; 0x0d0: 0x00000002 -- First Alocation table blk num 用于记录allocation信息的首个block ,通过KFBTYP_ALLOCTBL获取
kfdhdb.f1b1locn: 2 ; 0x0d4: 0x00000002 ---file directory所在的au位置
kfdhdb.redomirrors[0]: 0 ; 0x0d8: 0x0000
kfdhdb.redomirrors[1]: 0 ; 0x0da: 0x0000
kfdhdb.redomirrors[2]: 0 ; 0x0dc: 0x0000
kfdhdb.redomirrors[3]: 0 ; 0x0de: 0x0000
kfdhdb.dbcompat: 168820736 ; 0x0e0: 0x0a100000 -- Comaptible database version
kfdhdb.grpstmp.hi: 32977478 ; 0x0e4: HOUR=0x6 DAYS=0x12 MNTH=0xc YEAR=0x7dc -- diskgroup create time
kfdhdb.grpstmp.lo: 2407301120 ; 0x0e8: USEC=0x0 MSEC=0x320 SECS=0x37 MINS=0x23
kfdhdb.ub4spare[0]: 0 ; 0x0ec: 0x00000000
kfdhdb.ub4spare[1]: 0 ; 0x0f0: 0x00000000
kfdhdb.ub4spare[2]: 0 ; 0x0f4: 0x00000000
........
kfdhdb.ub4spare[56]: 0 ; 0x1cc: 0x00000000
kfdhdb.ub4spare[57]: 0 ; 0x1d0: 0x00000000
kfdhdb.acdb.aba.seq: 0 ; 0x1d4: 0x00000000
kfdhdb.acdb.aba.blk: 0 ; 0x1d8: 0x00000000
kfdhdb.acdb.ents: 0 ; 0x1dc: 0x0000
kfdhdb.acdb.ub2spare: 0 ; 0x1de: 0x0000
值 | 类型 | 说明 |
---|---|---|
1 | KFBTYP_DISKHEAD | ASM磁盘头 |
2 | KFBTYP_FREESPC | |
3 | KFBTYP_ALLOCTBL | |
4 | KFBTYP_FILEDIR | |
5 | KFBTYP_LISTHEAD | |
6 | KFBTYP_DISKDIR | |
11 | KFBTYP_ALIASDIR | |
17 | KFBTYP_PST_META |
磁盘冗余方式kfdhdb.grptyp
值 | 类型 |
---|---|
0 | KFDGTP_INVALID |
1 | KFDGTP_EXTERNAL |
2 | KFDGTP_NORMAL |
3 | KFDGTP_HIGH |
kfdhdb.hdrsts:
值 | 类型 | 说明 |
---|---|---|
0 | KFDHDR_INVALID | Illegal value |
1 | KFDHDR_UNKNOWN | Disk header block unreadable |
2 | KFDHDR_CANDIDATE | No OSM or OS disk header found |
3 | KFDHDR_MEMBER | Normal member of the group |
4 | KFDHDR_FORMER | Disk dropped cleanly from group |
5 | KFDHDR_CONFLICT | Header conflicts |
6 | KFDHDR_INCOMPAT | Written by incompatible software |
7 | KFDHDR_PROVISIONED | Disk was prepared beforehand |
3.2. FST (Free space table)
grid@rac12c1:~> kfed read /dev/diskgroup/dg_ora aunum=0 blknum=1 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 2 ; 0x002: KFBTYP_FREESPC
kfbh.datfmt: 2 ; 0x003: 0x02
kfbh.block.blk: 1 ; 0x004: blk=1
kfbh.block.obj: 2147483648 ; 0x008: disk=0
kfbh.check: 2457056287 ; 0x00c: 0x9273b41f
kfbh.fcn.base: 9969 ; 0x010: 0x000026f1
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfdfsb.aunum: 0 ; 0x000: 0x00000000
kfdfsb.max: 254 ; 0x004: 0x00fe
kfdfsb.cnt: 23 ; 0x006: 0x0017 ---当前disk包含的fst kfdfse条目数,23个条目,kfdfse[22].fse以后就是没有值了
kfdfsb.bound: 0 ; 0x008: 0x0000
kfdfsb.flag: 1 ; 0x00a: B=1
kfdfsb.ub1spare: 0 ; 0x00b: 0x00
kfdfsb.spare[0]: 0 ; 0x00c: 0x00000000
kfdfsb.spare[1]: 0 ; 0x010: 0x00000000
kfdfsb.spare[2]: 0 ; 0x014: 0x00000000
kfdfse[0].fse: 0 ; 0x018: FREE=0x0 FRAG=0x0 -- fse条目,共4040个
kfdfse[1].fse: 0 ; 0x019: FREE=0x0 FRAG=0x0
…
kfdfse[9].fse: 0 ; 0x021: FREE=0x0 FRAG=0x0
kfdfse[10].fse: 119 ; 0x022: FREE=0x7 FRAG=0x7
kfdfse[11].fse: 16 ; 0x023: FREE=0x0 FRAG=0x1
kfdfse[12].fse: 16 ; 0x024: FREE=0x0 FRAG=0x1
kfdfse[13].fse: 16 ; 0x025: FREE=0x0 FRAG=0x1
kfdfse[14].fse: 16 ; 0x026: FREE=0x0 FRAG=0x1
kfdfse[15].fse: 16 ; 0x027: FREE=0x0 FRAG=0x1
kfdfse[16].fse: 16 ; 0x028: FREE=0x0 FRAG=0x1
kfdfse[17].fse: 16 ; 0x029: FREE=0x0 FRAG=0x1
kfdfse[18].fse: 16 ; 0x02a: FREE=0x0 FRAG=0x1
kfdfse[19].fse: 16 ; 0x02b: FREE=0x0 FRAG=0x1
kfdfse[20].fse: 16 ; 0x02c: FREE=0x0 FRAG=0x1
kfdfse[21].fse: 16 ; 0x02d: FREE=0x0 FRAG=0x1
kfdfse[22].fse: 16 ; 0x02e: FREE=0x0 FRAG=0x1
kfdfse[23].fse: 0 ; 0x02f: FREE=0x0 FRAG=0x0
kfdfse[24].fse: 0 ; 0x030: FREE=0x0 FRAG=0x0
kfdfse[25].fse: 0 ; 0x031: FREE=0x0 FRAG=0x0
kfdfse[26].fse: 0 ; 0x032: FREE=0x0 FRAG=0x0
…
kfdfse[4038].fse: 0 ; 0xfde: FREE=0x0 FRAG=0x0
kfdfse[4039].fse: 0 ; 0xfdf: FREE=0x0 FRAG=0x0
## 3.3. AT (Allocation table)
grid@rac12c1:~> kfed read /dev/diskgroup/dg_data aun=0 blkn=2 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 3 ; 0x002: KFBTYP_ALLOCTBL
kfbh.datfmt: 2 ; 0x003: 0x02
kfbh.block.blk: 2 ; 0x004: blk=2
kfbh.block.obj: 2147483648 ; 0x008: disk=0
kfbh.check: 2183627839 ; 0x00c: 0x8227843f
kfbh.fcn.base: 2021 ; 0x010: 0x000007e5
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfdatb.aunum: 0 ; 0x000: 0x00000000
kfdatb.shrink: 448 ; 0x004: 0x01c0
kfdatb.ub2pad: 0 ; 0x006: 0x0000
kfdatb.auinfo[0].link.next: 8 ; 0x008: 0x0008
kfdatb.auinfo[0].link.prev: 8 ; 0x00a: 0x0008
kfdatb.auinfo[1].link.next: 12 ; 0x00c: 0x000c
kfdatb.auinfo[1].link.prev: 12 ; 0x00e: 0x000c
kfdatb.auinfo[2].link.next: 16 ; 0x010: 0x0010
kfdatb.auinfo[2].link.prev: 16 ; 0x012: 0x0010
kfdatb.auinfo[3].link.next: 20 ; 0x014: 0x0014
kfdatb.auinfo[3].link.prev: 20 ; 0x016: 0x0014
kfdatb.auinfo[4].link.next: 24 ; 0x018: 0x0018
kfdatb.auinfo[4].link.prev: 24 ; 0x01a: 0x0018
kfdatb.auinfo[5].link.next: 28 ; 0x01c: 0x001c
kfdatb.auinfo[5].link.prev: 28 ; 0x01e: 0x001c
kfdatb.auinfo[6].link.next: 32 ; 0x020: 0x0020
kfdatb.auinfo[6].link.prev: 32 ; 0x022: 0x0020
kfdatb.flgs: 0 ; 0x024: 0x0000
kfdatb.spare: 0 ; 0x026: 0x0000
kfdate[0].discriminator: 1 ; 0x028: 0x00000001
kfdate[0].allo.lo: 0 ; 0x028: SNAP=0x0 XNUM=0x0
kfdate[0].allo.hi: 8388608 ; 0x02c: SNAP=0x0 V=1 I=0 H=0 FNUM=0x0
kfdate[1].discriminator: 1 ; 0x030: 0x00000001
kfdate[1].allo.lo: 0 ; 0x030: SNAP=0x0 XNUM=0x0
kfdate[1].allo.hi: 8388608 ; 0x034: SNAP=0x0 V=1 I=0 H=0 FNUM=0x0
kfdate[2].discriminator: 1 ; 0x038: 0x00000001
kfdate[2].allo.lo: 0 ; 0x038: SNAP=0x0 XNUM=0x0
kfdate[2].allo.hi: 8388610 ; 0x03c: SNAP=0x0 V=1 I=0 H=0 FNUM=0x2
kfdate[3].discriminator: 1 ; 0x040: 0x00000001
…
kfdate[447].discriminator: 1 ; 0xe20: 0x00000001
kfdate[447].allo.lo: 165 ; 0xe20: SNAP=0x0 XNUM=0xa5
kfdate[447].allo.hi: 8388869 ; 0xe24: SNAP=0x0 V=1 I=0 H=0 FNUM=0x105
3.4. PST (partnership and atatus table)
grid@rac12c1:~> kfed read /dev/diskgroup/dg_data aun=1 blkn=0 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 17 ; 0x002: KFBTYP_PST_META
kfbh.datfmt: 2 ; 0x003: 0x02
kfbh.block.blk: 256 ; 0x004: blk=256
kfbh.block.obj: 2147483648 ; 0x008: disk=0
kfbh.check: 1665622637 ; 0x00c: 0x6347626d
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfdpHdrPairBv1.first.super.time.hi:33021038 ; 0x000: HOUR=0xe DAYS=0x3 MNTH=0x7 YEAR=0x7df
kfdpHdrPairBv1.first.super.time.lo:3987749888 ; 0x004: USEC=0x0 MSEC=0xf SECS=0x1b MINS=0x3b
kfdpHdrPairBv1.first.super.last: 2 ; 0x008: 0x00000002
kfdpHdrPairBv1.first.super.next: 2 ; 0x00c: 0x00000002
kfdpHdrPairBv1.first.super.copyCnt: 1 ; 0x010: 0x01
kfdpHdrPairBv1.first.super.version: 1 ; 0x011: 0x01
kfdpHdrPairBv1.first.super.ub2spare: 0 ; 0x012: 0x0000
kfdpHdrPairBv1.first.super.incarn: 1 ; 0x014: 0x00000001
kfdpHdrPairBv1.first.super.copy[0]: 0 ; 0x018: 0x0000
kfdpHdrPairBv1.first.super.copy[1]: 0 ; 0x01a: 0x0000
kfdpHdrPairBv1.first.super.copy[2]: 0 ; 0x01c: 0x0000
kfdpHdrPairBv1.first.super.copy[3]: 0 ; 0x01e: 0x0000
kfdpHdrPairBv1.first.super.copy[4]: 0 ; 0x020: 0x0000
kfdpHdrPairBv1.first.super.dtaSz: 1 ; 0x022: 0x0001
kfdpHdrPairBv1.first.asmCompat:202375168 ; 0x024: 0x0c100000
kfdpHdrPairBv1.first.newCopy[0]: 0 ; 0x028: 0x0000
kfdpHdrPairBv1.first.newCopy[1]: 0 ; 0x02a: 0x0000
kfdpHdrPairBv1.first.newCopy[2]: 0 ; 0x02c: 0x0000
kfdpHdrPairBv1.first.newCopy[3]: 0 ; 0x02e: 0x0000
kfdpHdrPairBv1.first.newCopy[4]: 0 ; 0x030: 0x0000
kfdpHdrPairBv1.first.newCopyCnt: 0 ; 0x032: 0x00
kfdpHdrPairBv1.first.contType: 1 ; 0x033: 0x01
kfdpHdrPairBv1.first.pstFlag: 0 ; 0x034: 0x00000000
kfdpHdrPairBv1.first.ppat[0]: 0 ; 0x038: 0x0000
kfdpHdrPairBv1.first.ppat[1]: 0 ; 0x03a: 0x0000
kfdpHdrPairBv1.first.ppat[2]: 0 ; 0x03c: 0x0000
kfdpHdrPairBv1.first.ppat[3]: 0 ; 0x03e: 0x0000
kfdpHdrPairBv1.first.ppatsz: 0 ; 0x040: 0x00
kfdpHdrPairBv1.first.spare1: 0 ; 0x041: 0x00
kfdpHdrPairBv1.first.spare2: 0 ; 0x042: 0x0000
kfdpHdrPairBv1.first.spares[0]: 0 ; 0x044: 0x00000000
kfdpHdrPairBv1.second.super.time.hi: 0 ; 0x084: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfdpHdrPairBv1.second.super.time.lo: 0 ; 0x088: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfdpHdrPairBv1.second.super.last: 0 ; 0x08c: 0x00000000
kfdpHdrPairBv1.second.super.next: 0 ; 0x090: 0x00000000
kfdpHdrPairBv1.second.super.copyCnt: 0 ; 0x094: 0x00
kfdpHdrPairBv1.second.super.version: 0 ; 0x095: 0x00
kfdpHdrPairBv1.second.super.ub2spare: 0 ; 0x096: 0x0000
kfdpHdrPairBv1.second.super.incarn: 0 ; 0x098: 0x00000000
kfdpHdrPairBv1.second.super.copy[0]: 0 ; 0x09c: 0x0000
…
kfdpHdrPairBv1.second.super.copy[1]: 0 ; 0x09e: 0x0000
kfdpHdrPairBv1.second.super.copy[2]: 0 ; 0x0a0: 0x0000
kfdpHdrPairBv1.second.super.copy[3]: 0 ; 0x0a2: 0x0000
kfdpHdrPairBv1.second.super.copy[4]: 0 ; 0x0a4: 0x0000
kfdpHdrPairBv1.second.super.dtaSz: 0 ; 0x0a6: 0x0000
kfdpHdrPairBv1.second.asmCompat: 0 ; 0x0a8: 0x00000000
kfdpHdrPairBv1.second.newCopy[0]: 0 ; 0x0ac: 0x0000
kfdpHdrPairBv1.second.newCopy[1]: 0 ; 0x0ae: 0x0000
kfdpHdrPairBv1.second.newCopy[2]: 0 ; 0x0b0: 0x0000
kfdpHdrPairBv1.second.newCopy[3]: 0 ; 0x0b2: 0x0000
kfdpHdrPairBv1.second.newCopy[4]: 0 ; 0x0b4: 0x0000
kfdpHdrPairBv1.second.newCopyCnt: 0 ; 0x0b6: 0x00
kfdpHdrPairBv1.second.contType: 0 ; 0x0b7: 0x00
kfdpHdrPairBv1.second.pstFlag: 0 ; 0x0b8: 0x00000000
kfdpHdrPairBv1.second.ppat[0]: 0 ; 0x0bc: 0x0000
kfdpHdrPairBv1.second.ppat[1]: 0 ; 0x0be: 0x0000
kfdpHdrPairBv1.second.ppat[2]: 0 ; 0x0c0: 0x0000
kfdpHdrPairBv1.second.ppat[3]: 0 ; 0x0c2: 0x0000
kfdpHdrPairBv1.second.ppatsz: 0 ; 0x0c4: 0x00
kfdpHdrPairBv1.second.spare1: 0 ; 0x0c5: 0x00
kfdpHdrPairBv1.second.spare2: 0 ; 0x0c6: 0x0000
kfdpHdrPairBv1.second.spares[0]: 0 ; 0x0c8: 0x00000000
kfdpHdrPairBv1.second.spares[1]: 0 ; 0x0cc: 0x00000000
kfdpHdrPairBv1.second.spares[2]: 0 ; 0x0d0: 0x00000000
kfdpHdrPairBv1.second.spares[3]: 0 ; 0x0d4: 0x00000000
kfdpHdrPairBv1.second.spares[4]: 0 ; 0x0d8: 0x00000000
kfdpHdrPairBv1.second.spares[5]: 0 ; 0x0dc: 0x00000000
kfdpHdrPairBv1.second.spares[6]: 0 ; 0x0e0: 0x00000000
kfdpHdrPairBv1.second.spares[7]: 0 ; 0x0e4: 0x00000000
kfdpHdrPairBv1.second.spares[8]: 0 ; 0x0e8: 0x00000000
kfdpHdrPairBv1.second.spares[9]: 0 ; 0x0ec: 0x00000000
kfdpHdrPairBv1.second.spares[10]: 0 ; 0x0f0: 0x00000000
kfdpHdrPairBv1.second.spares[11]: 0 ; 0x0f4: 0x00000000
kfdpHdrPairBv1.second.spares[12]: 0 ; 0x0f8: 0x00000000
kfdpHdrPairBv1.second.spares[13]: 0 ; 0x0fc: 0x00000000
kfdpHdrPairBv1.second.spares[14]: 0 ; 0x100: 0x00000000
kfdpHdrPairBv1.second.spares[15]: 0 ; 0x104: 0x00000000
ub1[0]: 2 ; 0x108: 0x02
ub1[1]: 0 ; 0x109: 0x00
ub1[2]: 0 ; 0x10a: 0x00
ub1[3]: 0 ; 0x10b: 0x00
ub1[4]: 0 ; 0x10c: 0x00
…
ub1[3797]: 0 ; 0xfdd: 0x00
ub1[3798]: 0 ; 0xfde: 0x00
ub1[3799]: 0 ; 0xfdf: 0x00
grid@rac12c1:~> kfed read /dev/diskgroup/dg_data aun=1 blkn=2
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 13 ; 0x002: KFBTYP_PST_NONE
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 2147483650 ; 0x004: blk=2 (indirect)
kfbh.block.obj: 2147483648 ; 0x008: disk=0
kfbh.check: 17662467 ; 0x00c: 0x010d8203
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
grid@rac12c1:~> kfed read /dev/diskgroup/dg_data aun=1 blkn=3 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 18 ; 0x002: KFBTYP_PST_DTA
kfbh.datfmt: 2 ; 0x003: 0x02
kfbh.block.blk: 259 ; 0x004: blk=259
kfbh.block.obj: 2147483648 ; 0x008: disk=0
kfbh.check: 4292168374 ; 0x00c: 0xffd54ab6
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfdpDtaEv1[0].status: 127 ; 0x000: I=1 V=1 V=1 P=1 P=1 A=1 D=1
kfdpDtaEv1[0].fgNum: 1 ; 0x002: 0x0001
kfdpDtaEv1[0].addTs: 2110189275 ; 0x004: 0x7dc6eedb
kfdpDtaEv1[0].partner[0]: 10000 ; 0x008: P=0 P=0 PART=0x2710
kfdpDtaEv1[0].partner[1]: 0 ; 0x00a: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[2]: 0 ; 0x00c: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[3]: 0 ; 0x00e: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[4]: 0 ; 0x010: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[5]: 0 ; 0x012: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[6]: 0 ; 0x014: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[7]: 0 ; 0x016: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[8]: 0 ; 0x018: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[9]: 0 ; 0x01a: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[10]: 0 ; 0x01c: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[11]: 0 ; 0x01e: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[12]: 0 ; 0x020: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[13]: 0 ; 0x022: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[14]: 0 ; 0x024: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[15]: 0 ; 0x026: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[16]: 0 ; 0x028: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[17]: 0 ; 0x02a: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[18]: 0 ; 0x02c: P=0 P=0 PART=0x0
kfdpDtaEv1[0].partner[19]: 0 ; 0x02e: P=0 P=0 PART=0x0
kfdpDtaEv1[1].status: 0 ; 0x030: I=0 V=0 V=0 P=0 P=0 A=0 D=0
kfdpDtaEv1[1].fgNum: 0 ; 0x032: 0x0000
kfdpDtaEv1[1].addTs: 0 ; 0x034: 0x00000000
kfdpDtaEv1[1].partner[0]: 0 ; 0x038: P=0 P=0 PART=0x0
kfdpDtaEv1[1].partner[1]: 0 ; 0x03a: P=0 P=0 PART=0x0
kfdpDtaEv1[1].partner[2]: 0 ; 0x03c: P=0 P=0 PART=0x0
kfdpDtaEv1[1].partner[3]: 0 ; 0x03e: P=0 P=0 PART=0x0
kfdpDtaEv1[1].partner[4]: 0 ; 0x040: P=0 P=0 PART=0x0
…
kfdpDtaEv1[83].partner[16]: 0 ; 0xfb8: P=0 P=0 PART=0x0
kfdpDtaEv1[83].partner[17]: 0 ; 0xfba: P=0 P=0 PART=0x0
kfdpDtaEv1[83].partner[18]: 0 ; 0xfbc: P=0 P=0 PART=0x0
kfdpDtaEv1[83].partner[19]: 0 ; 0xfbe: P=0 P=0 PART=0x0
3.5. HeartBeat
grid@rac12c1:~> kfed read /dev/diskgroup/dg_data aun=1 blkn=255 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 19 ; 0x002: KFBTYP_HBEAT
kfbh.datfmt: 2 ; 0x003: 0x02
kfbh.block.blk: 511 ; 0x004: blk=511
kfbh.block.obj: 2147483648 ; 0x008: disk=0
kfbh.check: 1908322926 ; 0x00c: 0x71beb26e
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfdpHbeatB.instance: 2 ; 0x000: 0x00000002
kfdpHbeatB.ts.hi: 33021362 ; 0x004: HOUR=0x12 DAYS=0xd MNTH=0x7 YEAR=0x7df
kfdpHbeatB.ts.lo: 3275027456 ; 0x008: USEC=0x0 MSEC=0x13d SECS=0x33 MINS=0x30
kfdpHbeatB.rnd[0]: 4205784345 ; 0x00c: 0xfaaf2d19
kfdpHbeatB.rnd[1]: 3701952449 ; 0x010: 0xdca74fc1
kfdpHbeatB.rnd[2]: 3267168518 ; 0x014: 0xc2bd0906
kfdpHbeatB.rnd[3]: 3587929086 ; 0x018: 0xd5db73fe
3.6. File Directory (12c没找到)
oracle@rac1:~> kfed read /dev/diskgroup/dg_ora aun=2 blkn=0 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 5 ; 0x002: KFBTYP_LISTHEAD
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 0 ; 0x004: T=0 NUMB=0x0
kfbh.block.obj: 1 ; 0x008: TYPE=0x0 NUMB=0x1
kfbh.check: 851081716 ; 0x00c: 0x32ba79f4
kfbh.fcn.base: 16742 ; 0x010: 0x00004166
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfflhe[0].cnt: 0 ; 0x000: 0x00000000
kfflhe[0].rcvr: 0 ; 0x004: 0x00000000
kfflhe[0].high: 0 ; 0x008: 0x00000000
kfflhe[0].frlist.number: 4294967295 ; 0x00c: 0xffffffff
kfflhe[0].frlist.incarn: 0 ; 0x010: A=0 NUMM=0x0
kfflhe[0].dangle.number: 4294967295 ; 0x014: 0xffffffff
kfflhe[0].dangle.incarn: 0 ; 0x018: A=0 NUMM=0x0
kfflhe[1].cnt: 244 ; 0x01c: 0x000000f4
kfflhe[1].rcvr: 512 ; 0x020: 0x00000200
kfflhe[1].high: 512 ; 0x024: 0x00000200
kfflhe[1].frlist.number: 262 ; 0x028: 0x00000106
kfflhe[1].frlist.incarn: 868203422 ; 0x02c: A=0 NUMM=0x19dfddcf
kfflhe[1].dangle.number: 4294967295 ; 0x030: 0xffffffff
kfflhe[1].dangle.incarn: 0 ; 0x034: A=0 NUMM=0x0
kfflhe[2].cnt: 255 ; 0x038: 0x000000ff
kfflhe[2].rcvr: 256 ; 0x03c: 0x00000100
kfflhe[2].high: 256 ; 0x040: 0x00000100
kfflhe[2].frlist.number: 1 ; 0x044: 0x00000001
kfflhe[2].frlist.incarn: 0 ; 0x048: A=0 NUMM=0x0
kfflhe[2].dangle.number: 0 ; 0x04c: 0x00000000
kfflhe[2].dangle.incarn: 1 ; 0x050: A=1 NUMM=0x0
kfflhe[3].cnt: 0 ; 0x054: 0x00000000
kfflhe[3].rcvr: 0 ; 0x058: 0x00000000
kfflhe[3].high: 0 ; 0x05c: 0x00000000
kfflhe[3].frlist.number: 4294967295 ; 0x060: 0xffffffff
kfflhe[3].frlist.incarn: 0 ; 0x064: A=0 NUMM=0x0
kfflhe[3].dangle.number: 4294967295 ; 0x068: 0xffffffff
kfflhe[3].dangle.incarn: 0 ; 0x06c: A=0 NUMM=0x0
kfflhe[4].cnt: 0 ; 0x070: 0x00000000
…
kfflhe[144].cnt: 0 ; 0xfc0: 0x00000000
kfflhe[144].rcvr: 0 ; 0xfc4: 0x00000000
kfflhe[144].high: 0 ; 0xfc8: 0x00000000
kfflhe[144].frlist.number: 4294967295 ; 0xfcc: 0xffffffff
kfflhe[144].frlist.incarn: 0 ; 0xfd0: A=0 NUMM=0x0
kfflhe[144].dangle.number: 4294967295 ; 0xfd4: 0xffffffff
kfflhe[144].dangle.incarn: 0 ; 0xfd8: A=0 NUMM=0x0
oracle@rac1:~> kfed read /dev/diskgroup/dg_ora aun=2 blkn=1 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 4 ; 0x002: KFBTYP_FILEDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 1 ; 0x004: T=0 NUMB=0x1
kfbh.block.obj: 1 ; 0x008: TYPE=0x0 NUMB=0x1
kfbh.check: 2968936859 ; 0x00c: 0xb0f6619b
kfbh.fcn.base: 824 ; 0x010: 0x00000338
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfffdb.node.incarn: 1 ; 0x000: A=1 NUMM=0x0
kfffdb.node.frlist.number: 4294967295 ; 0x004: 0xffffffff
kfffdb.node.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kfffdb.hibytes: 0 ; 0x00c: 0x00000000
kfffdb.lobytes: 2097152 ; 0x010: 0x00200000
kfffdb.xtntcnt: 2 ; 0x014: 0x00000002
kfffdb.xtnteof: 2 ; 0x018: 0x00000002
kfffdb.blkSize: 4096 ; 0x01c: 0x00001000
kfffdb.flags: 1 ; 0x020: O=1 S=0 S=0 D=0 C=0 I=0 R=0 A=0
kfffdb.fileType: 15 ; 0x021: 0x0f
kfffdb.dXrs: 17 ; 0x022: SCHE=0x1 NUMB=0x1
kfffdb.iXrs: 17 ; 0x023: SCHE=0x1 NUMB=0x1
kfffdb.dXsiz[0]: 4294967295 ; 0x024: 0xffffffff
kfffdb.dXsiz[1]: 0 ; 0x028: 0x00000000
kfffdb.dXsiz[2]: 0 ; 0x02c: 0x00000000
kfffdb.iXsiz[0]: 4294967295 ; 0x030: 0xffffffff
kfffdb.iXsiz[1]: 0 ; 0x034: 0x00000000
kfffdb.iXsiz[2]: 0 ; 0x038: 0x00000000
kfffdb.xtntblk: 2 ; 0x03c: 0x0002
kfffdb.break: 60 ; 0x03e: 0x003c
kfffdb.priZn: 0 ; 0x040: 0x00
kfffdb.secZn: 0 ; 0x041: 0x00
kfffdb.ub2spare: 0 ; 0x042: 0x0000
kfffdb.alias[0]: 4294967295 ; 0x044: 0xffffffff
kfffdb.alias[1]: 4294967295 ; 0x048: 0xffffffff
kfffdb.strpwdth: 0 ; 0x04c: 0x00
kfffdb.strpsz: 0 ; 0x04d: 0x00
kfffdb.usmsz: 0 ; 0x04e: 0x0000
kfffdb.crets.hi: 33010510 ; 0x050: HOUR=0xe DAYS=0x1a MNTH=0xc YEAR=0x7de
kfffdb.crets.lo: 3386178560 ; 0x054: USEC=0x0 MSEC=0x13f SECS=0x1d MINS=0x32
kfffdb.modts.hi: 33010510 ; 0x058: HOUR=0xe DAYS=0x1a MNTH=0xc YEAR=0x7de
kfffdb.modts.lo: 3386178560 ; 0x05c: USEC=0x0 MSEC=0x13f SECS=0x1d MINS=0x32
kfffdb.dasz[0]: 0 ; 0x060: 0x00
kfffdb.dasz[1]: 0 ; 0x061: 0x00
kfffdb.dasz[2]: 0 ; 0x062: 0x00
kfffdb.dasz[3]: 0 ; 0x063: 0x00
kfffdb.spare[0]: 0 ; 0x064: 0x00000000
kfffdb.spare[1]: 0 ; 0x068: 0x00000000
kfffdb.spare[2]: 0 ; 0x06c: 0x00000000
kfffdb.spare[3]: 0 ; 0x070: 0x00000000
kfffdb.spare[4]: 0 ; 0x074: 0x00000000
kfffdb.spare[5]: 0 ; 0x078: 0x00000000
kfffdb.spare[6]: 0 ; 0x07c: 0x00000000
kfffdb.spare[7]: 0 ; 0x080: 0x00000000
kfffdb.spare[8]: 0 ; 0x084: 0x00000000
kfffdb.spare[9]: 0 ; 0x088: 0x00000000
kfffdb.spare[10]: 0 ; 0x08c: 0x00000000
kfffdb.spare[11]: 0 ; 0x090: 0x00000000
kfffdb.spare[12]: 0 ; 0x094: 0x00000000
kfffdb.spare[13]: 0 ; 0x098: 0x00000000
kfffdb.spare[14]: 0 ; 0x09c: 0x00000000
kfffdb.usm: ; 0x0a0: length=0
kfffde[0].xptr.au: 2 ; 0x4a0: 0x00000002
kfffde[0].xptr.disk: 0 ; 0x4a4: 0x0000
kfffde[0].xptr.flags: 0 ; 0x4a6: L=0 E=0 D=0 S=0
kfffde[0].xptr.chk: 40 ; 0x4a7: 0x28
kfffde[1].xptr.au: 93 ; 0x4a8: 0x0000005d
kfffde[1].xptr.disk: 0 ; 0x4ac: 0x0000
kfffde[1].xptr.flags: 0 ; 0x4ae: L=0 E=0 D=0 S=0
kfffde[1].xptr.chk: 119 ; 0x4af: 0x77
kfffde[2].xptr.au: 4294967295 ; 0x4b0: 0xffffffff
kfffde[2].xptr.disk: 65535 ; 0x4b4: 0xffff
kfffde[2].xptr.flags: 0 ; 0x4b6: L=0 E=0 D=0 S=0
kfffde[2].xptr.chk: 42 ; 0x4b7: 0x2a
kfffde[3].xptr.au: 4294967295 ; 0x4b8: 0xffffffff
kfffde[3].xptr.disk: 65535 ; 0x4bc: 0xffff
kfffde[3].xptr.flags: 0 ; 0x4be: L=0 E=0 D=0 S=0
kfffde[3].xptr.chk: 42 ; 0x4bf: 0x2a
kfffde[4].xptr.au: 4294967295 ; 0x4c0: 0xffffffff
…
kfffde[359].xptr.au: 4294967295 ; 0xfd8: 0xffffffff
kfffde[359].xptr.disk: 65535 ; 0xfdc: 0xffff
kfffde[359].xptr.flags: 0 ; 0xfde: L=0 E=0 D=0 S=0
kfffde[359].xptr.chk: 42 ; 0xfdf: 0x2a
grid@rac12c1:~> kfed read /dev/diskgroup/dg_ora aun=2 blkn=0 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 6 ; 0x002: KFBTYP_DISKDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 0 ; 0x004: blk=0
kfbh.block.obj: 2 ; 0x008: file=2
kfbh.check: 2421195025 ; 0x00c: 0x90508111
kfbh.fcn.base: 998 ; 0x010: 0x000003e6
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kffdnd.bnode.incarn: 1 ; 0x000: A=1 NUMM=0x0 ----分配信息,包括block的分支号和指向next freelist block的指针
kffdnd.bnode.frlist.number: 4294967295 ; 0x004: 0xffffffff
kffdnd.bnode.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kffdnd.overfl.number: 4294967295 ; 0x00c: 0xffffffff
kffdnd.overfl.incarn: 0 ; 0x010: A=0 NUMM=0x0 ---overfl,表示指向同层级的下一个block
kffdnd.parent.number: 0 ; 0x014: 0x00000000 ---表示指向上一层的block
kffdnd.parent.incarn: 1 ; 0x018: A=1 NUMM=0x0
kffdnd.fstblk.number: 0 ; 0x01c: 0x00000000
kffdnd.fstblk.incarn: 1 ; 0x020: A=1 NUMM=0x0
kfddde[0].entry.incarn: 1 ; 0x024: A=1 NUMM=0x0
kfddde[0].entry.hash: 0 ; 0x028: 0x00000000
kfddde[0].entry.refer.number:4294967295 ; 0x02c: 0xffffffff
kfddde[0].entry.refer.incarn: 0 ; 0x030: A=0 NUMM=0x0
---- 上面这部分是kfddde.entry信息,里面包括了分支号,hash值、以及指向下一层级相关block的指针
kfddde[0].dsknum: 0 ; 0x034: 0x0000 -- disk number
kfddde[0].state: 2 ; 0x036: KFDSTA_NORMAL -- disk状态
kfddde[0].ddchgfl: 132 ; 0x037: 0x84
kfddde[0].dskname: DG_ORA_0000 ; 0x038: length=11 -- disk name
kfddde[0].fgname: DG_ORA_0000 ; 0x058: length=11 -- failgroup disk name
kfddde[0].crestmp.hi: 33020686 ; 0x078: HOUR=0xe DAYS=0x18 MNTH=0x6 YEAR=0x7df --磁盘创建时间戳
kfddde[0].crestmp.lo: 3948684288 ; 0x07c: USEC=0x0 MSEC=0x309 SECS=0x35 MINS=0x3a
kfddde[0].failstmp.hi: 0 ; 0x080: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0 --失败时间戳
kfddde[0].failstmp.lo: 0 ; 0x084: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[0].timer: 0 ; 0x088: 0x00000000
kfddde[0].size: 10240 ; 0x08c: 0x00002800 -- disk size
kfddde[0].srRloc.super.hiStart: 0 ; 0x090: 0x00000000
kfddde[0].srRloc.super.loStart: 0 ; 0x094: 0x00000000
kfddde[0].srRloc.super.length: 0 ; 0x098: 0x00000000
kfddde[0].srRloc.incarn: 0 ; 0x09c: 0x00000000
kfddde[0].dskrprtm: 0 ; 0x0a0: 0x00000000
kfddde[0].start0: 0 ; 0x0a4: 0x00000000
kfddde[0].size0: 10240 ; 0x0a8: 0x00002800
kfddde[0].used0: 102 ; 0x0ac: 0x00000066
kfddde[0].slot: 0 ; 0x0b0: 0x00000000
kfddde[0].imbal00[0]: 99 ; 0x0b4: 0x00000063
kfddde[0].imbal00[1]: 0 ; 0x0b8: 0x00000000
kfddde[0].imbal00[2]: 0 ; 0x0bc: 0x00000000
kfddde[0].imbal00[3]: 0 ; 0x0c0: 0x00000000
kfddde[0].imbal01[0]: 0 ; 0x0c4: 0x00000000
…
kfddde[7].imbal33[0]: 0 ; 0xe14: 0x00000000
kfddde[7].imbal33[1]: 0 ; 0xe18: 0x00000000
kfddde[7].imbal33[2]: 0 ; 0xe1c: 0x00000000
kfddde[7].imbal33[3]: 0 ; 0xe20: 0x00000000
kfddde[0].state
值 | 类型 | 说明 |
---|---|---|
0 | KFDSTA_INVALID | Illegal value |
1 | KFDSTA_UNKNOWN | ASM disk state not known |
2 | KFDSTA_NORMAL | Happy disk |
3 | KFDSTA_UNUSED | Unused State - Open |
4 | KFDSTA_DROPPING | Disk being dropped from group |
5 | KFDSTA_HUNG | Disk drop operation hung |
6 | KFDSTA_FORCING | Disk beinng drop forced |
7 | KFDSTA_DROPPED | Disk no longer part of group |
3.7. Disk Directory
里面保存了DG的所有disk的信息,比如一个dg里面的所有ASM磁盘信息,磁盘头损坏重建的时候可以从这里获取到很多信息。
grid@rac12c1:~> kfed read /dev/diskgroup/dg_ora aun=2 blkn=1 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 6 ; 0x002: KFBTYP_DISKDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 1 ; 0x004: blk=1
kfbh.block.obj: 2 ; 0x008: file=2
kfbh.check: 17203712 ; 0x00c: 0x01068200
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kffdnd.bnode.incarn: 0 ; 0x000: A=0 NUMM=0x0
kffdnd.bnode.frlist.number: 2 ; 0x004: 0x00000002
kffdnd.bnode.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kffdnd.overfl.number: 0 ; 0x00c: 0x00000000
kffdnd.overfl.incarn: 0 ; 0x010: A=0 NUMM=0x0
kffdnd.parent.number: 0 ; 0x014: 0x00000000
kffdnd.parent.incarn: 0 ; 0x018: A=0 NUMM=0x0
kffdnd.fstblk.number: 0 ; 0x01c: 0x00000000
kffdnd.fstblk.incarn: 0 ; 0x020: A=0 NUMM=0x0
kfddde[0].entry.incarn: 0 ; 0x024: A=0 NUMM=0x0
kfddde[0].entry.hash: 0 ; 0x028: 0x00000000
kfddde[0].entry.refer.number: 0 ; 0x02c: 0x00000000
kfddde[0].entry.refer.incarn: 0 ; 0x030: A=0 NUMM=0x0
kfddde[0].dsknum: 0 ; 0x034: 0x0000
kfddde[0].state: 0 ; 0x036: KFDSTA_INVALID
kfddde[0].ddchgfl: 0 ; 0x037: 0x00
kfddde[0].dskname: ; 0x038: length=0
kfddde[0].fgname: ; 0x058: length=0
kfddde[0].crestmp.hi: 0 ; 0x078: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfddde[0].crestmp.lo: 0 ; 0x07c: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[0].failstmp.hi: 0 ; 0x080: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfddde[0].failstmp.lo: 0 ; 0x084: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[0].timer: 0 ; 0x088: 0x00000000
kfddde[0].size: 0 ; 0x08c: 0x00000000
kfddde[0].srRloc.super.hiStart: 0 ; 0x090: 0x00000000
kfddde[0].srRloc.super.loStart: 0 ; 0x094: 0x00000000
kfddde[0].srRloc.super.length: 0 ; 0x098: 0x00000000
kfddde[0].srRloc.incarn: 0 ; 0x09c: 0x00000000
kfddde[0].dskrprtm: 0 ; 0x0a0: 0x00000000
grid@blade11:~> kfed read /dev/diskgroup/dg_ora01 aun=3 blkn=0 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 6 ; 0x002: KFBTYP_DISKDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 0 ; 0x004: blk=0
kfbh.block.obj: 2 ; 0x008: file=2
kfbh.check: 17203761 ; 0x00c: 0x01068231
kfbh.fcn.base: 51 ; 0x010: 0x00000033
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kffdnd.bnode.incarn: 1 ; 0x000: A=1 NUMM=0x0
kffdnd.bnode.frlist.number: 4294967295 ; 0x004: 0xffffffff
kffdnd.bnode.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kffdnd.overfl.number: 4294967295 ; 0x00c: 0xffffffff
kffdnd.overfl.incarn: 0 ; 0x010: A=0 NUMM=0x0
kffdnd.parent.number: 0 ; 0x014: 0x00000000
kffdnd.parent.incarn: 1 ; 0x018: A=1 NUMM=0x0
kffdnd.fstblk.number: 0 ; 0x01c: 0x00000000
kffdnd.fstblk.incarn: 1 ; 0x020: A=1 NUMM=0x0
kfddde[0].entry.incarn: 1 ; 0x024: A=1 NUMM=0x0
kfddde[0].entry.hash: 0 ; 0x028: 0x00000000
kfddde[0].entry.refer.number:4294967295 ; 0x02c: 0xffffffff
kfddde[0].entry.refer.incarn: 0 ; 0x030: A=0 NUMM=0x0
kfddde[0].dsknum: 0 ; 0x034: 0x0000
kfddde[0].state: 2 ; 0x036: KFDSTA_NORMAL
kfddde[0].ddchgfl: 132 ; 0x037: 0x84
kfddde[0].dskname: DG_ORA_0000 ; 0x038: length=11
kfddde[0].fgname: FRORA01 ; 0x058: length=7
kfddde[0].crestmp.hi: 33048047 ; 0x078: HOUR=0xf DAYS=0xf MNTH=0x1 YEAR=0x7e1
kfddde[0].crestmp.lo: 1448357888 ; 0x07c: USEC=0x0 MSEC=0x10c SECS=0x25 MINS=0x15
kfddde[0].failstmp.hi: 0 ; 0x080: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfddde[0].failstmp.lo: 0 ; 0x084: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
kfddde[0].timer: 0 ; 0x088: 0x00000000
kfddde[0].size: 5120 ; 0x08c: 0x00001400
kfddde[0].srRloc.super.hiStart: 0 ; 0x090: 0x00000000
kfddde[0].srRloc.super.loStart: 0 ; 0x094: 0x00000000
kfddde[0].srRloc.super.length: 0 ; 0x098: 0x00000000
kfddde[0].srRloc.incarn: 0 ; 0x09c: 0x00000000
kfddde[0].dskrprtm: 0 ; 0x0a0: 0x00000000
kfddde[0].start0: 0 ; 0x0a4: 0x00000000
kfddde[0].size0: 5120 ; 0x0a8: 0x00001400
kfddde[0].used0: 49 ; 0x0ac: 0x00000031
kfddde[0].slot: 0 ; 0x0b0: 0x00000000
…
kfddde[0].dskname: DG_ORA_0000 ; 0x038: length=11
kfddde[0].fgname: FRORA01 ; 0x058: length=7
…
kfddde[1].dskname: DG_ORA_0001 ; 0x1f8: length=11
kfddde[1].fgname: FRORA01 ; 0x218: length=7
…
kfddde[2].dskname: DG_ORA_0002 ; 0x3b8: length=11
kfddde[2].fgname: FRORA02 ; 0x3d8: length=7
…
kfddde[3].dskname: DG_ORA_0003 ; 0x578: length=11
kfddde[3].fgname: FRORA02 ; 0x598: length=7
3.7. Active Change Directory
grid@rac12c1:~> kfed read /dev/diskgroup/dg_ora aun=3 blkn=0 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 7 ; 0x002: KFBTYP_ACDC
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 0 ; 0x004: blk=0
kfbh.block.obj: 3 ; 0x008: file=3
kfbh.check: 4122039296 ; 0x00c: 0xf5b15400
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfracdc.eyec[0]: 65 ; 0x000: 0x41
kfracdc.eyec[1]: 67 ; 0x001: 0x43
kfracdc.eyec[2]: 68 ; 0x002: 0x44
kfracdc.eyec[3]: 67 ; 0x003: 0x43
kfracdc.thread: 1 ; 0x004: 0x00000001
kfracdc.lastAba.seq: 4294967295 ; 0x008: 0xffffffff
kfracdc.lastAba.blk: 4294967295 ; 0x00c: 0xffffffff
kfracdc.blk0: 1 ; 0x010: 0x00000001
kfracdc.blks: 10751 ; 0x014: 0x000029ff
kfracdc.ckpt.seq: 5 ; 0x018: 0x00000005
kfracdc.ckpt.blk: 82 ; 0x01c: 0x00000052
kfracdc.fcn.base: 1015 ; 0x020: 0x000003f7
kfracdc.fcn.wrap: 0 ; 0x024: 0x00000000
kfracdc.bufBlks: 256 ; 0x028: 0x00000100
kfracdc.strt112.seq: 2 ; 0x02c: 0x00000002
kfracdc.strt112.blk: 0 ; 0x030: 0x00000000
kfracdc.domid: 1 ; 0x034: 0x0001
kfracdc.spare: 0 ; 0x036: 0x0000
kfracdc.dominc: 2 ; 0x038: 0x00000002
kfracdc.instnum: 2 ; 0x03c: 0x00000002
kfracdc.incarn: 2203833772 ; 0x040: 0x835bd5ac
kfracdc.mntstmp.hi: 33020851 ; 0x044: HOUR=0x13 DAYS=0x1d MNTH=0x6 YEAR=0x7df
kfracdc.mntstmp.lo: 895397888 ; 0x048: USEC=0x0 MSEC=0x3ac SECS=0x15 MINS=0xd
kfracdc.writestmp.hi: 0 ; 0x04c: HOUR=0x0 DAYS=0x0 MNTH=0x0 YEAR=0x0
kfracdc.writestmp.lo: 0 ; 0x050: USEC=0x0 MSEC=0x0 SECS=0x0 MINS=0x0
3.7. Change Directory
grid@rac12c1:~> kfed read /dev/diskgroup/dg_ora aun=3 blkn=1 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 8 ; 0x002: KFBTYP_CHNGDIR
kfbh.datfmt: 2 ; 0x003: 0x02
kfbh.block.blk: 1 ; 0x004: blk=1
kfbh.block.obj: 3 ; 0x008: file=3
kfbh.check: 917280177 ; 0x00c: 0x36ac95b1
kfbh.fcn.base: 0 ; 0x010: 0x00000000
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kfracdb2.aba.seq: 2 ; 0x000: 0x00000002
kfracdb2.aba.blk: 0 ; 0x004: 0x00000000
kfracdb2.ents: 2 ; 0x008: 0x0002
kfracdb2.ub2spare: 0 ; 0x00a: 0x0000
kfracdb2.instNum: 1 ; 0x00c: 0x00000001
kfracdb2.timestamp: 883234742 ; 0x010: 2015-6-24 14:59:2
kfracdb2.lge[0].valid: 1 ; 0x014: V=1 B=0 M=0
kfracdb2.lge[0].chgCount: 1 ; 0x015: 0x01
kfracdb2.lge[0].len: 52 ; 0x016: 0x0034
kfracdb2.lge[0].kfcn.base: 1 ; 0x018: 0x00000001
kfracdb2.lge[0].kfcn.wrap: 0 ; 0x01c: 0x00000000
kfracdb2.lge[0].bcd[0].kfbl.blk: 0 ; 0x020: blk=0
kfracdb2.lge[0].bcd[0].kfbl.obj: 4 ; 0x024: file=4
kfracdb2.lge[0].bcd[0].kfcn.base: 0 ; 0x028: 0x00000000
kfracdb2.lge[0].bcd[0].kfcn.wrap: 0 ; 0x02c: 0x00000000
kfracdb2.lge[0].bcd[0].oplen: 4 ; 0x030: 0x0004
kfracdb2.lge[0].bcd[0].blkIndex: 0 ; 0x032: 0x0000
kfracdb2.lge[0].bcd[0].flags: 28 ; 0x034: F=0 N=0 F=1 L=1 V=1 A=0 C=0 R=0
kfracdb2.lge[0].bcd[0].opcode: 212 ; 0x036: 0x00d4
kfracdb2.lge[0].bcd[0].kfbtyp: 9 ; 0x038: KFBTYP_COD_BGO
kfracdb2.lge[0].bcd[0].redund: 17 ; 0x039: SCHE=0x1 NUMB=0x1
kfracdb2.lge[0].bcd[0].pad: 63903 ; 0x03a: 0xf99f
kfracdb2.lge[0].bcd[0].KFRCOD_CRASH: 1 ; 0x03c: 0x00000001
kfracdb2.lge[0].bcd[0].au[0]: 47 ; 0x040: 0x0000002f
kfracdb2.lge[0].bcd[0].disks[0]: 0 ; 0x044: 0x0000
kfracdb2.lge[1].valid: 1 ; 0x048: V=1 B=0 M=0
kfracdb2.lge[1].chgCount: 1 ; 0x049: 0x01
kfracdb2.lge[1].len: 52 ; 0x04a: 0x0034
kfracdb2.lge[1].kfcn.base: 2 ; 0x04c: 0x00000002
kfracdb2.lge[1].kfcn.wrap: 0 ; 0x050: 0x00000000
kfracdb2.lge[1].bcd[0].kfbl.blk: 1 ; 0x054: blk=1
kfracdb2.lge[1].bcd[0].kfbl.obj: 4 ; 0x058: file=4
kfracdb2.lge[1].bcd[0].kfcn.base: 0 ; 0x05c: 0x00000000
kfracdb2.lge[1].bcd[0].kfcn.wrap: 0 ; 0x060: 0x00000000
kfracdb2.lge[1].bcd[0].oplen: 4 ; 0x064: 0x0004
kfracdb2.lge[1].bcd[0].blkIndex: 1 ; 0x066: 0x0001
kfracdb2.lge[1].bcd[0].flags: 28 ; 0x068: F=0 N=0 F=1 L=1 V=1 A=0 C=0 R=0
kfracdb2.lge[1].bcd[0].opcode: 212 ; 0x06a: 0x00d4
kfracdb2.lge[1].bcd[0].kfbtyp: 15 ; 0x06c: KFBTYP_COD_RBO
kfracdb2.lge[1].bcd[0].redund: 17 ; 0x06d: SCHE=0x1 NUMB=0x1
kfracdb2.lge[1].bcd[0].pad: 63903 ; 0x06e: 0xf99f
kfracdb2.lge[1].bcd[0].KFRCOD_CRASH: 0 ; 0x070: 0x00000000
kfracdb2.lge[1].bcd[0].au[0]: 47 ; 0x074: 0x0000002f
kfracdb2.lge[1].bcd[0].disks[0]: 0 ; 0x078: 0x0000
3.8. Alias Directory
ASM disk header中f1b1表示file directory的开始位置
grid@blade11:~> kfed read /dev/diskgroup/dg_ora01 | grep f1b1
kfdhdb.f1b1locn: 2 ; 0x0d4: 0x00000002
f1b6指向alias directory开始的block块,f1b1是au 2 blk 1,所以f1b6是au2 blk6。
kfed read /dev/diskgroup/dg_ora01 aun=2 blkn=6
...
kfffdb.usm: ; 0x0a0: length=0
《kfffde[0].xptr.au: 14 ; 0x4a0: 0x0000000e》
kfffde[0].xptr.disk: 1 ; 0x4a4: 0x0001
kfffde[0].xptr.flags: 0 ; 0x4a6: L=0 E=0 D=0 S=0
F1b6中显示kfffde[0].xptr.au=14,kfffde[0].xptr.disk=1,所以alias directory开始位置是在disk 1的au 14 blkn 0。
grid@blade11:~> kfed read /dev/diskgroup/dg_ora02 aun=14 blkn=0 | more
kfbh.endian: 1 ; 0x000: 0x01
kfbh.hard: 130 ; 0x001: 0x82
kfbh.type: 11 ; 0x002: KFBTYP_ALIASDIR
kfbh.datfmt: 1 ; 0x003: 0x01
kfbh.block.blk: 0 ; 0x004: blk=0
kfbh.block.obj: 6 ; 0x008: file=6
kfbh.check: 2628575481 ; 0x00c: 0x9cace0f9
kfbh.fcn.base: 506 ; 0x010: 0x000001fa
kfbh.fcn.wrap: 0 ; 0x014: 0x00000000
kfbh.spare1: 0 ; 0x018: 0x00000000
kfbh.spare2: 0 ; 0x01c: 0x00000000
kffdnd.bnode.incarn: 1 ; 0x000: A=1 NUMM=0x0
kffdnd.bnode.frlist.number: 4294967295 ; 0x004: 0xffffffff
kffdnd.bnode.frlist.incarn: 0 ; 0x008: A=0 NUMM=0x0
kffdnd.overfl.number: 4294967295 ; 0x00c: 0xffffffff
kffdnd.overfl.incarn: 0 ; 0x010: A=0 NUMM=0x0
kffdnd.parent.number: 0 ; 0x014: 0x00000000
kffdnd.parent.incarn: 1 ; 0x018: A=1 NUMM=0x0
kffdnd.fstblk.number: 0 ; 0x01c: 0x00000000
kffdnd.fstblk.incarn: 1 ; 0x020: A=1 NUMM=0x0
kfade[0].entry.incarn: 1 ; 0x024: A=1 NUMM=0x0
kfade[0].entry.hash: 2900784766 ; 0x028: 0xace6767e
《kfade[0].entry.refer.number: 1 ; 0x02c: 0x00000001 à ORA11G下目录/别名所在的blknum=1》
《kfade[0].entry.refer.incarn: 1 ; 0x030: A=1 NUMM=0x0》
《kfade[0].name: ORA11G ; 0x034: length=6 à 目录名称》
kfade[0].fnum: 4294967295 ; 0x064: 0xffffffff
kfade[0].finc: 4294967295 ; 0x068: 0xffffffff
kfade[0].flags: 4 ; 0x06c: U=0 S=0 S=1 U=0 F=0
kfade[0].ub1spare: 0 ; 0x06d: 0x00
kfade[0].ub2spare: 0 ; 0x06e: 0x0000
kfade[1].entry.incarn: 0 ; 0x070: A=0 NUMM=0x0
kfade[1].entry.hash: 0 ; 0x074: 0x00000000
kfade[1].entry.refer.number: 0 ; 0x078: 0x00000000
kfade[1].entry.refer.incarn: 0 ; 0x07c: A=0 NUMM=0x0
kfade[1].name: ; 0x080: length=0
kfade[1].fnum: 0 ; 0x0b0: 0x00000000
kfade[1].finc: 0 ; 0x0b4: 0x00000000
kfade[1].flags: 0 ; 0x0b8: U=0 S=0 S=0 U=0 F=0
kfade[1].ub1spare: 0 ; 0x0b9: 0x00
kfade[1].ub2spare: 0 ; 0x0ba: 0x0000
kfade[2].entry.incarn: 0 ; 0x0bc: A=0 NUMM=0x0
kfade[2].entry.hash: 0 ; 0x0c0: 0x00000000
kfade[2].entry.refer.number: 0 ; 0x0c4: 0x00000000
kfade[2].entry.refer.incarn: 0 ; 0x0c8: A=0 NUMM=0x0
kfade[2].name: ; 0x0cc: length=0
kfade[2].fnum: 0 ; 0x0fc: 0x00000000
kfade[2].finc: 0 ; 0x100: 0x00000000
kfade[2].flags: 0 ; 0x104: U=0 S=0 S=0 U=0 F=0
kfade[2].ub1spare: 0 ; 0x105: 0x00
kfade[2].ub2spare: 0 ; 0x106: 0x0000
kfade[3].entry.incarn: 0 ; 0x108: A=0 NUMM=0x0
kfade[3].entry.hash: 0 ; 0x10c: 0x00000000
kfade[3].entry.refer.number: 0 ; 0x110: 0x00000000
kfade[3].entry.refer.incarn: 0 ; 0x114: A=0 NUMM=0x0
kfade[3].name: ; 0x118: length=0
kfade[3].fnum: 0 ; 0x148: 0x00000000
kfade[3].finc: 0 ; 0x14c: 0x00000000
kfade[3].flags: 0 ; 0x150: U=0 S=0 S=0 U=0 F=0
根据以上信息可以找到alias的信息,
kfed read /dev/diskgroup/dg_ora02 aun=14 blkn=1
...
kfade[0].entry.incarn: 1 ; 0x024: A=1 NUMM=0x0
kfade[0].entry.hash: 4053320104 ; 0x028: 0xf198c1a8
kfade[0].entry.refer.number: 2 ; 0x02c: 0x00000002
kfade[0].entry.refer.incarn: 1 ; 0x030: A=1 NUMM=0x0
kfade[0].name: CONTROLFILE ; 0x034: length=11
kfade[0].fnum: 4294967295 ; 0x064: 0xffffffff
kfade[0].finc: 4294967295 ; 0x068: 0xffffffff
kfade[0].flags: 4 ; 0x06c: U=0 S=0 S=1 U=0 F=0
kfade[0].ub1spare: 0 ; 0x06d: 0x00
kfade[0].ub2spare: 0 ; 0x06e: 0x0000
kfade[1].entry.incarn: 1 ; 0x070: A=1 NUMM=0x0
kfade[1].entry.hash: 2803485489 ; 0x074: 0xa719cb31
kfade[1].entry.refer.number: 3 ; 0x078: 0x00000003
kfade[1].entry.refer.incarn: 1 ; 0x07c: A=1 NUMM=0x0
kfade[1].name: ONLINELOG ; 0x080: length=9
kfade[1].fnum: 4294967295 ; 0x0b0: 0xffffffff
kfade[1].finc: 4294967295 ; 0x0b4: 0xffffffff
kfade[1].flags: 4 ; 0x0b8: U=0 S=0 S=1 U=0 F=0
kfade[1].ub1spare: 0 ; 0x0b9: 0x00
kfade[1].ub2spare: 0 ; 0x0ba: 0x0000
kfade[2].entry.incarn: 1 ; 0x0bc: A=1 NUMM=0x0
kfade[2].entry.hash: 710518681 ; 0x0c0: 0x2a59a799
kfade[2].entry.refer.number: 4 ; 0x0c4: 0x00000004
kfade[2].entry.refer.incarn: 1 ; 0x0c8: A=1 NUMM=0x0
kfade[2].name: DATAFILE ; 0x0cc: length=8
kfade[2].fnum: 4294967295 ; 0x0fc: 0xffffffff
kfade[2].finc: 4294967295 ; 0x100: 0xffffffff
kfade[2].flags: 4 ; 0x104: U=0 S=0 S=1 U=0 F=0
kfade[2].ub1spare: 0 ; 0x105: 0x00
kfade[2].ub2spare: 0 ; 0x106: 0x0000
kfade[3].entry.incarn: 1 ; 0x108: A=1 NUMM=0x0
kfade[3].entry.hash: 2905271101 ; 0x10c: 0xad2aeb3d
kfade[3].entry.refer.number: 5 ; 0x110: 0x00000005
kfade[3].entry.refer.incarn: 1 ; 0x114: A=1 NUMM=0x0
kfade[3].name: TEMPFILE ; 0x118: length=8
kfade[3].fnum: 4294967295 ; 0x148: 0xffffffff
kfade[3].finc: 4294967295 ; 0x14c: 0xffffffff
kfade[3].flags: 4 ; 0x150: U=0 S=0 S=1 U=0 F=0
kfade[3].ub1spare: 0 ; 0x151: 0x00
kfade[3].ub2spare: 0 ; 0x152: 0x0000
kfade[4].entry.incarn: 1 ; 0x154: A=1 NUMM=0x0
kfade[4].entry.hash: 3261836913 ; 0x158: 0xc26bae71
kfade[4].entry.refer.number: 6 ; 0x15c: 0x00000006
kfade[4].entry.refer.incarn: 1 ; 0x160: A=1 NUMM=0x0
kfade[4].name: PARAMETERFILE ; 0x164: length=13
kfade[4].fnum: 4294967295 ; 0x194: 0xffffffff
kfade[4].finc: 4294967295 ; 0x198: 0xffffffff
kfade[4].flags: 4 ; 0x19c: U=0 S=0 S=1 U=0 F=0
kfade[4].ub1spare: 0 ; 0x19d: 0x00
kfade[4].ub2spare: 0 ; 0x19e: 0x0000
kfade[5].entry.incarn: 1 ; 0x1a0: A=1 NUMM=0x0
kfade[5].entry.hash: 1207472261 ; 0x1a4: 0x47f89085
kfade[5].entry.refer.number: 4294967295 ; 0x1a8: 0xffffffff
kfade[5].entry.refer.incarn: 0 ; 0x1ac: A=0 NUMM=0x0
kfade[5].name: spfileora11g.ora ; 0x1b0: length=16
kfade[5].fnum: 267 ; 0x1e0: 0x0000010b
kfade[5].finc: 926274971 ; 0x1e4: 0x3735d59b
kfade[5].flags: 17 ; 0x1e8: U=1 S=0 S=0 U=0 F=1
kfade[5].ub1spare: 0 ; 0x1e9: 0x00
kfade[5].ub2spare: 0 ; 0x1ea: 0x0000
kfade[6].entry.incarn: 1 ; 0x1ec: A=1 NUMM=0x0
kfade[6].entry.hash: 2056614501 ; 0x1f0: 0x7a957265
kfade[6].entry.refer.number: 4294967295 ; 0x1f4: 0xffffffff
kfade[6].entry.refer.incarn: 0 ; 0x1f8: A=0 NUMM=0x0
《kfade[6].name: system01 ; 0x1fc: length=8 à alias system01路径是》+DG_ORA/ORA11G/system01,
《kfade[6].fnum: 262 ; 0x22c: 0x00000106 à对应的ASM文件的file number是.262》
kfade[6].finc: 926274325 ; 0x230: 0x3735d315
kfade[6].flags: 17 ; 0x234: U=1 S=0 S=0 U=0 F=1
kfade[6].ub1spare: 0 ; 0x235: 0x00
kfade[6].ub2spare: 0 ; 0x236: 0x0000
kfade[7].entry.incarn: 1 ; 0x238: A=1 NUMM=0x0
kfade[7].entry.hash: 3144535201 ; 0x23c: 0xbb6dcca1
kfade[7].entry.refer.number: 4294967295 ; 0x240: 0xffffffff
kfade[7].entry.refer.incarn: 0 ; 0x244: A=0 NUMM=0x0
kfade[7].name: sysaux01 ; 0x248: length=8
kfade[7].fnum: 263 ; 0x278: 0x00000107
kfade[7].finc: 926274353 ; 0x27c: 0x3735d331
kfade[7].flags: 17 ; 0x280: U=1 S=0 S=0 U=0 F=1
kfade[7].ub1spare: 0 ; 0x281: 0x00
kfade[7].ub2spare: 0 ; 0x282: 0x0000
kfade[8].entry.incarn: 1 ; 0x284: A=1 NUMM=0x0
kfade[8].entry.hash: 1946127661 ; 0x288: 0x73ff8d2d
kfade[8].entry.refer.number: 4294967295 ; 0x28c: 0xffffffff
kfade[8].entry.refer.incarn: 0 ; 0x290: A=0 NUMM=0x0
kfade[8].name: undotbs01 ; 0x294: length=9
kfade[8].fnum: 264 ; 0x2c4: 0x00000108
kfade[8].finc: 926274381 ; 0x2c8: 0x3735d34d
kfade[8].flags: 17 ; 0x2cc: U=1 S=0 S=0 U=0 F=1
kfade[8].ub1spare: 0 ; 0x2cd: 0x00
kfade[8].ub2spare: 0 ; 0x2ce: 0x0000
kfade[9].entry.incarn: 1 ; 0x2d0: A=1 NUMM=0x0
kfade[9].entry.hash: 4060868867 ; 0x2d4: 0xf20bf103
kfade[9].entry.refer.number: 4294967295 ; 0x2d8: 0xffffffff
kfade[9].entry.refer.incarn: 0 ; 0x2dc: A=0 NUMM=0x0
kfade[9].name: user01 ; 0x2e0: length=6
kfade[9].fnum: 266 ; 0x310: 0x0000010a
kfade[9].finc: 926274389 ; 0x314: 0x3735d355
kfade[9].flags: 17 ; 0x318: U=1 S=0 S=0 U=0 F=1
kfade[9].ub1spare: 0 ; 0x319: 0x00
kfade[9].ub2spare: 0 ; 0x31a: 0x0000
kfade[10].entry.incarn: 1 ; 0x31c: A=1 NUMM=0x0
kfade[10].entry.hash: 3391938696 ; 0x320: 0xca2ce088
kfade[10].entry.refer.number:4294967295 ; 0x324: 0xffffffff
kfade[10].entry.refer.incarn: 0 ; 0x328: A=0 NUMM=0x0
kfade[10].name: temp01 ; 0x32c: length=6
kfade[10].fnum: 265 ; 0x35c: 0x00000109
kfade[10].finc: 926274383 ; 0x360: 0x3735d34f
kfade[10].flags: 17 ; 0x364: U=1 S=0 S=0 U=0 F=1
kfade[10].ub1spare: 0 ; 0x365: 0x00
kfade[10].ub2spare: 0 ; 0x366: 0x0000
kfade[11].entry.incarn: 1 ; 0x368: A=1 NUMM=0x0
kfade[11].entry.hash: 3199161443 ; 0x36c: 0xbeaf5463
kfade[11].entry.refer.number:4294967295 ; 0x370: 0xffffffff
kfade[11].entry.refer.incarn: 0 ; 0x374: A=0 NUMM=0x0
kfade[11].name: redo01 ; 0x378: length=6
kfade[11].fnum: 257 ; 0x3a8: 0x00000101
kfade[11].finc: 926274323 ; 0x3ac: 0x3735d313
kfade[11].flags: 17 ; 0x3b0: U=1 S=0 S=0 U=0 F=1
kfade[11].ub1spare: 0 ; 0x3b1: 0x00
kfade[11].ub2spare: 0 ; 0x3b2: 0x0000
kfade[12].entry.incarn: 1 ; 0x3b4: A=1 NUMM=0x0
kfade[12].entry.hash: 522607785 ; 0x3b8: 0x1f265ca9
kfade[12].entry.refer.number:4294967295 ; 0x3bc: 0xffffffff
kfade[12].entry.refer.incarn: 0 ; 0x3c0: A=0 NUMM=0x0
kfade[12].name: redo02 ; 0x3c4: length=6
kfade[12].fnum: 258 ; 0x3f4: 0x00000102
kfade[12].finc: 926274325 ; 0x3f8: 0x3735d315
kfade[12].flags: 17 ; 0x3fc: U=1 S=0 S=0 U=0 F=1
kfade[12].ub1spare: 0 ; 0x3fd: 0x00
kfade[12].ub2spare: 0 ; 0x3fe: 0x0000
kfade[13].entry.incarn: 1 ; 0x400: A=1 NUMM=0x0
kfade[13].entry.hash: 2479919349 ; 0x404: 0x93d090f5
kfade[13].entry.refer.number:4294967295 ; 0x408: 0xffffffff
kfade[13].entry.refer.incarn: 0 ; 0x40c: A=0 NUMM=0x0
kfade[13].name: redo03 ; 0x410: length=6
kfade[13].fnum: 259 ; 0x440: 0x00000103
kfade[13].finc: 926274325 ; 0x444: 0x3735d315
kfade[13].flags: 17 ; 0x448: U=1 S=0 S=0 U=0 F=1
kfade[13].ub1spare: 0 ; 0x449: 0x00
kfade[13].ub2spare: 0 ; 0x44a: 0x0000
kfade[14].entry.incarn: 1 ; 0x44c: A=1 NUMM=0x0
kfade[14].entry.hash: 4070080510 ; 0x450: 0xf2987ffe
kfade[14].entry.refer.number:4294967295 ; 0x454: 0xffffffff
kfade[14].entry.refer.incarn: 0 ; 0x458: A=0 NUMM=0x0
kfade[14].name: redo05 ; 0x45c: length=6
kfade[14].fnum: 260 ; 0x48c: 0x00000104
kfade[14].finc: 926274325 ; 0x490: 0x3735d315
kfade[14].flags: 17 ; 0x494: U=1 S=0 S=0 U=0 F=1
kfade[14].ub1spare: 0 ; 0x495: 0x00
kfade[14].ub2spare: 0 ; 0x496: 0x0000
kfade[15].entry.incarn: 1 ; 0x498: A=1 NUMM=0x0
kfade[15].entry.hash: 73845760 ; 0x49c: 0x0466cc00
kfade[15].entry.refer.number:4294967295 ; 0x4a0: 0xffffffff
kfade[15].entry.refer.incarn: 0 ; 0x4a4: A=0 NUMM=0x0
kfade[15].name: redo06 ; 0x4a8: length=6
kfade[15].fnum: 261 ; 0x4d8: 0x00000105
kfade[15].finc: 926274325 ; 0x4dc: 0x3735d315
kfade[15].flags: 17 ; 0x4e0: U=1 S=0 S=0 U=0 F=1
kfade[15].ub1spare: 0 ; 0x4e1: 0x00
kfade[15].ub2spare: 0 ; 0x4e2: 0x0000
kfade[16].entry.incarn: 0 ; 0x4e4: A=0 NUMM=0x0
kfade[16].entry.hash: 0 ; 0x4e8: 0x00000000
kfade[16].entry.refer.number: 0 ; 0x4ec: 0x00000000
kfade[16].entry.refer.incarn: 0 ; 0x4f0: A=0 NUMM=0x0
3. ASM disk和diskgroup
ASM实例主要是通过asm_diskstring参数来读取asm disk的头信息,头信息里面保存了disk group的信息,所以必须要设定asm_diskstring参数,但是可以不设置asm_diskgroups参数。
3.1. asm_diskstring
当指定asm_diskstring =/dev/ora_*时,会读取有读写权限的所有匹配文件。如果是asm disk,header_status为meber,如果是其他文件如ocr或者voting disk的话,header_status为FOREIGN;如果是未使用的disk,状态为CANDIDATE。
注意:如果asm文件头损坏,状态也可能会是CANDIDATE。
SQL> show parameter disk
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
asm_diskgroups string
asm_diskstring string /dev/ora_*
disk_asynch_io boolean TRUE
SQL> select * from v$asm_disk;
GROUP_NUMBER DISK_NUMBER COMPOUND_INDEX INCARNATION MOUNT_S HEADER_STATU MODE_ST STATE REDUNDA
------------ ----------- -------------- ----------- ------- ------------ ------- -------- -------
LIBRARY OS_MB TOTAL_MB FREE_MB NAME
---------------------------------------------------------------- ---------- ---------- ---------- ------------------------------
FAILGROUP LABEL
------------------------------ -------------------------------
PATH
----------------------------------------------------------------------------------------------------------------------------------
UDID PRODUCT CREATE_DA MOUNT_DAT REPAIR_TIMER
---------------------------------------------------------------- -------------------------------- --------- --------- ------------
READS WRITES READ_ERRS WRITE_ERRS READ_TIME WRITE_TIME BYTES_READ BYTES_WRITTEN P
---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------- -
0 0 0 4100548235 IGNORED MEMBER ONLINE NORMAL UNKNOWN
System 8192 0 0
/dev/ora_asm
30-JAN-12 16-MAR-12 0
0 2 2 4100548237 CLOSED FOREIGN ONLINE NORMAL UNKNOWN
System 512 0 0
/dev/ora_voting
0
0 1 1 4100548236 CLOSED MEMBER ONLINE NORMAL UNKNOWN
System 512 0 0
/dev/ora_asm2
13-FEB-12 14-FEB-12 0
SQL> !ls -l /dev/ora_*
crw-r----- 1 oracle oinstall 10, 21 Mar 20 10:55 /dev/ora_asm
crw-r----- 1 oracle oinstall 10, 22 Feb 15 12:08 /dev/ora_asm2
《crw-r----- 1 root oinstall 10, 19 Mar 20 10:51 /dev/ora_ocr à oracle用户没有写权限,没有读取到asm disk中》
crw-r----- 1 oracle oinstall 10, 20 Mar 20 10:55 /dev/ora_voting
添加写权限以后,可以读取到
SQL> !ls -l /dev/ora_*
crw-r----- 1 oracle oinstall 10, 21 Mar 20 10:57 /dev/ora_asm
crw-r----- 1 oracle oinstall 10, 22 Feb 15 12:08 /dev/ora_asm2
crw-《rw》---- 1 root oinstall 10, 19 Mar 20 10:59 /dev/ora_ocr
crw-r----- 1 oracle oinstall 10, 20 Mar 20 11:00 /dev/ora_voting
SQL> select * from v$asm_disk;
GROUP_NUMBER DISK_NUMBER COMPOUND_INDEX INCARNATION MOUNT_S HEADER_STATU MODE_ST STATE REDUNDA
------------ ----------- -------------- ----------- ------- ------------ ------- -------- -------
LIBRARY OS_MB TOTAL_MB FREE_MB NAME
---------------------------------------------------------------- ---------- ---------- ---------- ------------------------------
FAILGROUP LABEL
------------------------------ -------------------------------
PATH
----------------------------------------------------------------------------------------------------------------------------------
UDID PRODUCT CREATE_DA MOUNT_DAT REPAIR_TIMER
---------------------------------------------------------------- -------------------------------- --------- --------- ------------
READS WRITES READ_ERRS WRITE_ERRS READ_TIME WRITE_TIME BYTES_READ BYTES_WRITTEN P
---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------- -
0 0 0 4100607656 IGNORED MEMBER ONLINE NORMAL UNKNOWN
System 8192 0 0
/dev/ora_asm
30-JAN-12 20-MAR-12 0
0 3 3 4100607659 CLOSED 《FOREIGN》 ONLINE NORMAL UNKNOWN
System 512 0 0
/dev/ora_voting
0
0 2 2 4100607658 CLOSED 《 FOREIGN》 ONLINE NORMAL UNKNOWN
System 512 0 0
/dev/ora_ocr
0
0 1 1 4100607657 CLOSED MEMBER ONLINE NORMAL UNKNOWN
System 512 0 0
/dev/ora_asm2
13-FEB-12 14-FEB-12 0
3.2. ASM Disk
ASM磁盘头存储ASM disk和DG的相关信息,对于ASM非常重要,但是ASM文件头不保存ASM实例信息,所以ASM实例名是什么并不重要。所以理论上ASM应该是可以做物理拷贝迁移的。
3.2.2. strings方法
(用处不大,只能判断是否是asm disk)
$ strings /dev/ora_asm | more
AIX LVCB
00c0a26000004c0000000133
lvoraasm
Mon Jan 30 16:33:50 2012 à create time
Mon Jan 30 16:33:50 2012
0A2604C00
None
ca2cc5f4.21
ORCLDISK
ORA_DG_0000 à disk group信息
ORA_DG
ORA_DG_0000
3.2.3. amdu工具收集
(简单直观,10g开始支持,可以直观显示是否有损坏)
$ amdu -diskstring /dev/ora_asm
amdu_2012_03_20_11_19_14/
$ cd amdu_2012_03_20_11_19_14
$ ls
report.txt
$ cat report.txt
-*-amdu-*-
******************************* AMDU Settings ********************************
ORACLE_HOME = /opt/oracle/db/product/11.1.0/db_1
System name: AIX
Node name: P570
Release: 1
Version: 6
Machine: 00C0A2604C00
amdu run: 20-MAR-12 11:19:14
Endianess: 0
--------------------------------- Operations ---------------------------------
------------------------------- Disk Selection -------------------------------
-diskstring '/dev/ora_asm'
------------------------------ Reading Control -------------------------------
------------------------------- Output Control -------------------------------
********************************* DISCOVERY **********************************
----------------------------- DISK REPORT N0001 ------------------------------
Disk Path: /dev/ora_asm
Unique Disk ID:
Disk Label:
Physical Sector Size: 512 bytes
Disk Size: 8192 megabytes
Group Name: ORA_DG
Disk Name: ORA_DG_0000
Failure Group Name: ORA_DG_0000
Disk Number: 0
Header Status: 3
Disk Creation Time: 2012/01/30 17:40:35.866000
Last Mount Time: 2012/03/20 10:50:00.403000
Compatibility Version: 0x0a100000
Disk Sector Size: 512 bytes
Disk size in AUs: 8192 AUs
Group Redundancy: 1
Metadata Block Size: 4096 bytes
AU Size: 1048576 bytes
Stride: 113792 AUs
Group Creation Time: 2012/01/30 17:40:35.802000
File 1 Block 1 location: AU 2
******************************* END OF REPORT ********************************
3.2.3 kfed read
(内容详细,但只是单纯读文件头,需要自己判断是否损坏)
kfbh.endian: 1 ; 0×000: 0×01 /* endianness of writer Little endian = 1|Big endian = 0 1 高字节为0*/
kfbh.hard: 130 ; 0×001: 0×82 /* H.A.R.D. magic # and block size */
kfbh.type: 1 ; 0×002: KFBTYP_DISKHEAD /* metadata block type 此处取值为1.对于我们重构需要的类型有 1.KFBTYP_DISKHEAD 2.KFBTYP_FREESPC 3.KFBTYP_ALLOCTBL 4.KFBTYP_FILEDIR 5.KFBTYP_LISTHEAD 6.KFBTYP_DISKDIR 17.KFBTYP_PST_META 等 */
kfbh.datfmt: 1 ; 0×003: 0×01 /* metadata block data format 取值为1,表示已经格式化*/
kfbh.block.blk: 0 ; 0×004: T=0 NUMB=0×0 /* block location of this block* Disk header should have T=0 and NUMB=0×0 取值为0 */
kfbh.block.obj: 2147483648 ; 0×008: TYPE=0×8 NUMB=0×0 /* block object id Disk header 的type为8 ,num表示asm disk在group中的编号,即kfdhdb.dsknum,TYPE=0×8 NUMB=0×0表示为8000000,十进制也就是2147483648 */
kfbh.check: 3359966064 ; 0x00c: 0xc8450370 /* check value to verify consistency * 通过kfed可自动计算/
kfbh.fcn.base: 108 ; 0×010: 0x0000006c /* change number of last change*/
kfbh.fcn.wrap: 0 ; 0×014: 0×00000000
kfbh.spare1: 0 ; 0×018: 0×00000000
kfbh.spare2: 0 ; 0x01c: 0×00000000
kfdhdb.driver.provstr: ORCLDISK ; 0×000: length=8 /* ASMLIB driver reserved block If no driver is defined "ORCLDISK" is used. 如果没使用ASMlib,默认为 ORCLDISK,否则为ORCLDISK+Name*/
kfdhdb.driver.reserved[0]: 0 ; 0×008: 0×00000000
kfdhdb.driver.reserved[1]: 0 ; 0x00c: 0×00000000
kfdhdb.driver.reserved[2]: 0 ; 0×010: 0×00000000
kfdhdb.driver.reserved[3]: 0 ; 0×014: 0×00000000
kfdhdb.driver.reserved[4]: 0 ; 0×018: 0×00000000
kfdhdb.driver.reserved[5]: 0 ; 0x01c: 0×00000000
kfdhdb.compat: 168820736 ; 0×020: 0x0a100000 /* Comaptible software version 0x0a100000:10.1.0.0.0 */
kfdhdb.dsknum: 0 ; 0×024: 0×0000 /* This is the disk number. 可以通过kfbh.block.obj获得编号,也可以通过disk directory获得 */
kfdhdb.grptyp: 1 ; 0×026: KFDGTP_EXTERNAL /* Disk group type 通过PST获得 0:KFDGTP_INVALID 1:KFDGTP_EXTERNAL 2:KFDGTP_NORMAL 3:KFDGTP_HIGH */
kfdhdb.hdrsts: 3 ; 0×027: KFDHDR_MEMBER /* Disk header status */
KFDHDR_INVALID – Illegal value
KFDHDR_UNKNOWN – Disk header block unreadable
KFDHDR_CANDIDATE – No OSM or OS disk header found
KFDHDR_MEMBER – Normal member of the group
KFDHDR_FORMER – Disk dropped cleanly from group
KFDHDR_CONFLICT – Header conflicts
KFDHDR_INCOMPAT – Written by incompatible software
KFDHDR_PROVISIONED – Disk was prepared beforehand */
kfdhdb.dskname: KAO_0000 ; 0×028: length=8 /* ASM disk name */
kfdhdb.grpname: KAO ; 0×048: length=3 /* ASM diskgroup name,通过disk directory 获得 */
kfdhdb.fgname: KAO_0000 ; 0×068: length=8 /* ASM failgroup name ,通过disk directory 获得*/
kfdhdb.capname: ; 0×088: length=0 /* Capacity group name, unused*/
kfdhdb.crestmp.hi: 32944719 ; 0x0a8: HOUR=0xf DAYS=0×12 MNTH=0xc YEAR=0x7da /* Creation timestamp 通过disk directory 获得*/
kfdhdb.crestmp.lo: 3943035904 ; 0x0ac: USEC=0×0 MSEC=0x17d SECS=0×30 MINS=0x3a /* Creation timestamp 通过disk directory 获得*/
kfdhdb.mntstmp.hi: 32944743 ; 0x0b0: HOUR=0×7 DAYS=0×13 MNTH=0xc YEAR=0x7da /* mount timestamp* 非定值,可根据规则自定值*/
kfdhdb.mntstmp.lo: 1611210752 ; 0x0b4: USEC=0×0 MSEC=0×248 SECS=0×0 MINS=0×18 /* mount timestamp* 非定值,可根据规则自定值*/
kfdhdb.secsize: 512 ; 0x0b8: 0×0200 /* Disk sector size (bytes) 默认取值512*/
kfdhdb.blksize: 4096 ; 0x0ba: 0×1000 /* Metadata block (bytes) 默认取值4096*/
kfdhdb.ausize: 1048576 ; 0x0bc: 0×00100000 /* Allocation Unit (bytes) 默认取值1M*/
kfdhdb.mfact: 113792 ; 0x0c0: 0x0001bc80 /* Stride between phys addr AUs 默认取值113792 */
kfdhdb.dsksize: 200 ; 0x0c4: 0x000000c8 /* Disk size 可通过KFBTYP_FREESPC获得,也可通过disk directory获得*/
kfdhdb.pmcnt: 2 ; 0x0c8: 0×00000002 /* Number of physically addressed allocation units */
kfdhdb.fstlocn: 1 ; 0x0cc: 0×00000001 /* First FreeSpace table blk num 用于记录freespace信息的首个block,通过KFBTYP_FREESPC 获得 */
kfdhdb.altlocn: 2 ; 0x0d0: 0×00000002 /* First Alocation table blk num 用于记录allocation信息的首个block ,通过KFBTYP_ALLOCTBL 获得*/
kfdhdb.f1b1locn: 2 ; 0x0d4: 0×00000002 /* File Directory blk 1 AU num File Directory起始地址 */
kfdhdb.redomirrors[0]: 0 ; 0x0d8: 0×0000
kfdhdb.redomirrors[1]: 65535 ; 0x0da: 0xffff
kfdhdb.redomirrors[2]: 65535 ; 0x0dc: 0xffff
kfdhdb.redomirrors[3]: 65535 ; 0x0de: 0xffff
kfdhdb.dbcompat: 168820736 ; 0x0e0: 0x0a100000 /*Comaptible database version 0x0a100000:10.1.0.0.0 */
kfdhdb.grpstmp.hi: 32944719 ; 0x0e4: HOUR=0xf DAYS=0×12 MNTH=0xc YEAR=0x7da /* diskgroup create time 可根据规则重新定义 */
kfdhdb.grpstmp.lo: 3943035904 ; 0x0e8: USEC=0×0 MSEC=0x17d SECS=0×30 MINS=0x3a /* diskgroup create time 可根据规则重新定义 */
kfdhdb.ub4spare[0]: 0 ; 0x0ec: 0×00000000
kfdhdb.ub4spare[1]: 0 ; 0x0f0: 0×00000000
...
kfdhdb.ub4spare[56]: 0 ; 0x1cc: 0×00000000
kfdhdb.ub4spare[57]: 0 ; 0x1d0: 0×00000000
kfdhdb.acdb.aba.seq: 0 ; 0x1d4: 0×00000000
kfdhdb.acdb.aba.blk: 0 ; 0x1d8: 0×00000000
kfdhdb.acdb.ents: 0 ; 0x1dc: 0×0000
kfdhdb.acdb.ub2spare: 0 ; 0x1de: 0×0000
3.2.4. v$asm_disk v$asm_disk_stat
(两个视图结果一样)
SQL> select * from v$asm_disk;
GROUP_NUMBER DISK_NUMBER COMPOUND_INDEX INCARNATION MOUNT_S HEADER_STATU MODE_ST STATE REDUNDA
------------ ----------- -------------- ----------- ------- ------------ ------- -------- -------
LIBRARY OS_MB TOTAL_MB FREE_MB NAME
---------------------------------------------------------------- ---------- ---------- ---------- ------------------------------
FAILGROUP LABEL
------------------------------ -------------------------------
PATH
----------------------------------------------------------------------------------------------------------------------------------
UDID PRODUCT CREATE_DA MOUNT_DAT REPAIR_TIMER
---------------------------------------------------------------- -------------------------------- --------- --------- ------------
READS WRITES READ_ERRS WRITE_ERRS READ_TIME WRITE_TIME BYTES_READ BYTES_WRITTEN P
---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------- -
1 0 16777216 4100607660 CACHED MEMBER ONLINE NORMAL UNKNOWN
System 8192 8192 6834 ORA_DG_0000
ORA_DG_0000
/dev/ora_asm
30-JAN-12 20-MAR-12 0
4018 3907 0 0 110.698125 113.775272 21725184 16003072
3.3. ASM diskgroup(待续)
3.4. ASM disk hearbeat(待续)
4. 工具
4.1. kfod
$ kfod -help
_asm_a/llow_only_raw_disks KFOD allow only raw devices [_asm_allow_only_raw_disks=TRUE/(FALSE)]
_asm_l/ibraries ASM Libraries[_asm_libraries='lib1','lib2',...]
_asms/id ASM Instance[_asmsid=sid]
a/sm_diskstring ASM Diskstring [asm_diskstring='discoverystring', 'discoverystring' ...]
d/isks Disks to discover [disks=raw,asm,all]
g/roup Disks in diskgroup [group='diskgroup']
n/ohdr KFOD header suppression [nohdr=TRUE/(FALSE)]
o/p KFOD options type [OP=DISKS/GROUPS/INSTS/VERSION/CLIENTS/ALL]
p/file ASM parameter file [pfile='parameterfile']
s/tatus Include disk header status [status=TRUE/(FALSE)]
v/erbose KFOD verbose errors [verbose=TRUE/(FALSE)]
例:
$ kfod disks=all
----------------------------------------------------------------------------
Disk Size Path
============================================================================
1: 8192 Mb /dev/ora_asm
2: 512 Mb /dev/ora_asm2
3: 512 Mb /dev/ora_ocr
4: 512 Mb /dev/ora_voting
---------------------------------------------------------------------------
ORACLE_SID ORACLE_HOME
===========================================================================
+ASM1 /opt/oracle/db/product/11.1.0/db_1
4.2. kfed
$ kfed -help
as/mlib ASM Library [asmlib='lib']
aun/um AU number to examine or update [AUNUM=number]
aus/z Allocation Unit size in bytes [AUSZ=number]
blkn/um Block number to examine or update [BLKNUM=number]
blks/z Metadata block size in bytes [BLKSZ=number]
ch/ksum Update checksum before each write [CHKSUM=YES/NO]
cn/t Count of AUs to process [CNT=number]
d/ev ASM device to examine or update [DEV=string]
o/p KFED operation type [OP=READ/WRITE/MERGE/NEW/FORM/FIND/STRUCT]
p/rovnm Name for provisioning purposes [PROVNM=string]
s/eek AU number to seek to [SEEK=number]
te/xt File name for translated block text [TEXT=string]
ty/pe ASM metadata block type number [TYPE=number]
4.3. amdu
$ amdu -help
a/usize AU size for corrupt disks
-ausize <bytes>: This option must be set when -baddisks is set. It
must be a power of 2. This size is required to scan a disk looking
for metadata, and it is normally read from the disk header. The
value applies to all disks that do not have a valid header. The
value from the disk header will be used if a valid header is
found.
...
### 4.4. GetAsmDH.sh
参考Collecting Data To Diagnose ASM Disk Header Corruption. [ID 870334.1]
输出
$ GetAsmDh.sh
############################################
- Collecting Information About the Disks:
############################################
SQL*Plus: Release 11.1.0.6.0 - Production on Tue Mar 20 14:09:07 2012
Copyright (c) 1982, 2007, Oracle. All rights reserved.
SQL> Connected.
SQL> SQL> SQL> SQL> SQL> SQL> SQL>
1 0 /dev/ora_asm
SQL> SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, Real Application Clusters, OLAP, Data Mining
and Real Application Testing options
-rw-r--r-- 1 oracle oinstall 229 Mar 20 14:09 /tmp/HC/asmdisks.lst
############################################
2) Generating asm_diskh.sh script.
############################################
-rwx------ 1 oracle oinstall 106 Mar 20 14:09 /tmp/HC/asm_diskh.sh
############################################
3) Executing asm_diskh.sh script to
generate dd dumps.
############################################
-rw-r--r-- 1 oracle oinstall 1048576 Mar 20 14:09 /tmp/HC/dsk_1_0.dd
############################################
4) Compressing dd dumps in the next format:
(asm_dd_header_all_<date_time>.tar)
############################################
a /tmp/HC/dsk_1_0.dd 2048 blocks.
-rw-r--r-- 1 oracle oinstall 39047 Mar 20 11:30 /tmp/HC/asm_dd_header_all_03-20-2012_11:30:20.tar.Z
-rw-r--r-- 1 oracle oinstall 39015 Mar 20 14:09 /tmp/HC/asm_dd_header_all_03-20-2012_14:09:07.tar.Z
4.5. Kfed.sh
代码:
#!/bin/sh
rm -rf /tmp/kfed
mkdir /tmp/kfed
for i in ls /dev/ora_*
à 使用时修改为实际的diskstring
do
echo $i >> /tmp/kfed/kfed_DH.out
kfed read $i >> /tmp/kfed/kfed_DH.out
echo $i >> /tmp/kfed/kfed_FS.out
kfed read $i blkn=1 >> /tmp/kfed/kfed_FS.out
echo $i >> /tmp/kfed/kfed_BK.out
kfed read $i aun=1 blkn=254 >> /tmp/kfed_BK.out
echo $i >> /tmp/kfed/kfed_FD.out
kfed read $i aun=2 blkn=1 >> /tmp/kfed/kfed_FD.out
echo $i >> /tmp/kfed/kfed_DD.out
kfed read $i aun=2 blkn=2 >> /tmp/kfed/kfed_DD.out
Done
## 5. troubleshoot
### 5.1. 收集信息
0) CRS or CSS info à 主要分析asm无法配置或启动
$ORA_CRS_HOME/log//cssd/ocssd.log
$ORACLE_HOME/log//cssd/ocssd.log
1) ASM info à 主要分析asm dg无法mount
Please replace <asm_diskstring> with the actual value
su - oracle
export ORACLE_SID=+ASM_SID à replace ASM_SID with actual value
sqlplus / as sysdba
set lin 130
set pagesize 1000
show parameter disk
select * from v$asm_disk;
select * from v$asm_diskgroup;
alter diskgroup diskgroup_name check all norepair;
exit
ls -l <asm_diskstring>
./Kfed.sh
amdu -diskstring <asm_diskstring>
./GetAsmDH.sh
kfod disks=all
Feedback the output and generated files
2) alert log
$ORACLE_BASE/diag/rdbms/<DB_NAME>//trace/alert_.log
$ORACLE_BASE/diag/asm//<ASM_SID>/trace/alert_<ASM_SID>.log
3) init file
`$ORACLE_HOME/dbs/init<ASM_SID>.ora`
5.2. 定位
1)查看asm alert信息,检查问题是asm无法启动还是dg无法mount
2)检查初始化参数和v$asm_disk,ls -l asm_disk的结果,看看参数设置,disk权限是否正确。
3)检查amdu和kfed信息,确实是否文件头损坏,如果损坏了,需要使用kfed write或kfed repair修复(修复完DG不一定完全可用)
4)检查初始化参数文件中asm_diskgroups参数是否设置正确
5)如果DG mount之后,过一会儿自动dismount,检查dg里面的数据文件是否有坏块
对于ASM无法配置的问题,原因很多,有时也很难定位,一般检查
1)检查crs/localconfig日志
$ORACLE_HOME/$ORA_CRS_HOME/log/<nodename>/diskmon
$ORACLE_HOME/$ORA_CRS_HOME/log/<nodename>/cssd
$ORACLE_HOME/$ORA_CRS_HOME/log/<nodename>/client
2)目录文件是否存在,权限是否正确,目录是否满了
/var/tmp/.oracle
/tmp/.oracle
/ à检查根目录是否满了
Crs中/var/tmp/.oracle和/tmp/.oracle的权限都是root:system
$ ls -al /var/tmp | grep ".oracle"
drwxrwxrwt 2 root system 256 Mar 16 13:35 .oracle
$ ls -al /tmp/ | grep ".oracle"
drwxrwxrwt 2 root system 4096 Mar 20 10:46 .oracle
如果是非RAC ASM实例,权限是oracle:dba或oracle:oinstall
$ ls -l /var/tmp/.oracle
total 0
$ ls -l /tmp/.oracle
total 0
srwxrwxrwx 1 oracle oinstall 0 Mar 16 13:35 sAp570_ascluster_evm
srwxrwxrwx 1 root system 0 Mar 16 13:35 sCRSD_UI_SOCKET
srwxrwxrwx 1 oracle oinstall 0 Mar 16 13:35 sCp570_ascluster_evm
srwxrwxrwx 1 oracle oinstall 0 Mar 16 13:35 sOCSSD_LL_p570_
srwxrwxrwx 1 oracle oinstall 0 Mar 16 13:35 sOCSSD_LL_p570_ascluster
srwxrwxrwx 1 oracle oinstall 0 Mar 16 13:35 sOracle_CSS_LclLstnr_ascluster_1
srwxrwxrwx 1 oracle oinstall 0 Mar 16 13:35 sSYSTEM.evm.acceptor.auth
srwxrwxrwx 1 root system 0 Mar 16 13:35 sora_crsqs
srwxrwxrwx 1 root system 0 Mar 16 13:35 sp570DBG_CRSD
srwxrwxrwx 1 oracle oinstall 0 Mar 16 13:35 sp570DBG_CSSD
srwxrwxrwx 1 oracle oinstall 0 Mar 16 13:35 sp570DBG_EVMD
srwxrwxrwx 1 root system 0 Mar 16 13:35 sprocr_local_conn_0_PROC
标红的文件必须存在并且权限要是oracle:oinstall或oracle:dba
3)strace/truss/tusc localconfig或者cssd.d进程检查
文档
CSS Deamon doesn't start after server reboot - ASM gives ORA-29701 [ID 733826.1].htm
CSS does not start - localconfig hang at init.cssd start process [ID 601508.1].htm
CSS not starting up - localconfig root.sh hang [ID 351917.1].htm
CSS service Is Unable To Start Due To LANG Setting. [ID 880129.1].htm
ORA-29701 Not able to start the CSS for ASM [ID 341613.1].htm
- 恢复ASM
6.1. 文件头修复(待续)
6.2. LVM metadata
前512字节为空, 0x2000x272共115个字节是PV label0x21F是label header,
0x200
struct label_header {
int8_t id[8]; /* LABELONE */
uint64_t sector_xl; /* Sector number of this label */
uint32_t crc_xl; /* From next field to end of sector */
uint32_t offset_xl; /* Offset from start of struct to contents */
int8_t type[8]; /* LVM2 001 */
} __attribute__ ((packed));
从4k~0x1022共35个字节
rac12c1:~ # strings sdd_pv
LABELONE
LVM2 001vw1zNcbAbkuPlgku3ypiT2uH0CekH0bW
5` LVM2 x[5A%r0N*>
rac12c1:~ # pvdisplay
--- Physical volume ---
PV Name /dev/sdd
VG Name vgtest
PV Size 1.00 GB / not usable 4.00 MB
Allocatable yes
PE Size (KByte) 4096
Total PE 255
Free PE 254
Allocated PE 1
PV UUID vw1zNc-bAbk-uPlg-ku3y-piT2-uH0C-ekH0bW
rac12c1:~ # strings sdd_vg
LABELONE
LVM2 001vw1zNcbAbkuPlgku3ypiT2uH0CekH0bW
LVM2 x[5A%r0N*>
vgtest {
id = "w1IXxD-FDZ8-ddWM-WhrN-zfc5-58ch-F2yaIQ"
seqno = 1
status = ["RESIZEABLE", "READ", "WRITE"]
extent_size = 8192
max_lv = 0
max_pv = 0
physical_volumes {
pv0 {
id = "vw1zNc-bAbk-uPlg-ku3y-piT2-uH0C-ekH0bW"
device = "/dev/sdd"
status = ["ALLOCATABLE"]
dev_size = 2097152
pe_start = 384
pe_count = 255
# Generated by LVM2 version 2.02.39 (2008-06-27): Sat Jul 11 22:58:47 2015
contents = "Text Format Volume Group"
version = 1
description = ""
creation_host = "rac12c1" # Linux rac12c1 2.6.32.59-0.7-default #1 SMP 2012-07-13 15:50:56 +0200 x86_64
creation_time = 1436626727 # Sat Jul 11 22:58:47 2015
rac12c1:~ # strings sdd_lv
LABELONE
LVM2 001vw1zNcbAbkuPlgku3ypiT2uH0CekH0bW
LVM2 x[5A%r0N*>
vgtest {
id = "w1IXxD-FDZ8-ddWM-WhrN-zfc5-58ch-F2yaIQ"
seqno = 1
status = ["RESIZEABLE", "READ", "WRITE"]
extent_size = 8192
max_lv = 0
max_pv = 0
physical_volumes {
pv0 {
id = "vw1zNc-bAbk-uPlg-ku3y-piT2-uH0C-ekH0bW"
device = "/dev/sdd"
status = ["ALLOCATABLE"]
dev_size = 2097152
pe_start = 384
pe_count = 255
# Generated by LVM2 version 2.02.39 (2008-06-27): Sat Jul 11 22:58:47 2015
contents = "Text Format Volume Group"
version = 1
description = ""
creation_host = "rac12c1" # Linux rac12c1 2.6.32.59-0.7-default #1 SMP 2012-07-13 15:50:56 +0200 x86_64
creation_time = 1436626727 # Sat Jul 11 22:58:47 2015
vgtest {
id = "w1IXxD-FDZ8-ddWM-WhrN-zfc5-58ch-F2yaIQ"
seqno = 2
status = ["RESIZEABLE", "READ", "WRITE"]
extent_size = 8192
max_lv = 0
max_pv = 0
physical_volumes {
pv0 {
id = "vw1zNc-bAbk-uPlg-ku3y-piT2-uH0C-ekH0bW"
device = "/dev/sdd"
status = ["ALLOCATABLE"]
dev_size = 2097152
pe_start = 384
pe_count = 255
logical_volumes {
lv_test {
id = "MBzHmW-yj1B-OPXT-di5F-17du-cdLP-s4zfqq"
status = ["READ", "WRITE", "VISIBLE"]
segment_count = 1
segment1 {
start_extent = 0
extent_count = 1
type = "striped"
stripe_count = 1 # linear
stripes = [
"pv0", 0
# Generated by LVM2 version 2.02.39 (2008-06-27): Sat Jul 11 23:05:27 2015
contents = "Text Format Volume Group"
version = 1
description = ""
creation_host = "rac12c1" # Linux rac12c1 2.6.32.59-0.7-default #1 SMP 2012-07-13 15:50:56 +0200 x86_64
creation_time = 1436627127 # Sat Jul 11 23:05:27 2015
rac12c1:~ #
6.2. 重建ASM DG
export ORACLE_SID=+ASM1
sqlplus / as sysdba
drop diskgroup DG_DATA;
CREATE DISKGROUP dg_data External REDUNDANCY DISK '/dev/raw/raw4' SIZE 204800M ,
'/dev/raw/raw5' SIZE 204800M;
如果raw5,raw6无法添加的话,关闭数据库和asm,然后用
dd if=/dev/zero of=/dev/raw/raw5 bs=4k count=1
格式化ASM磁盘头
然后重启ASM重新创建DG_DATA
7. 案例
6.1. ORACLE不支持多个ASM实例
在一个节点创建两个ASM实例+ASM1和+ASM_S,分别在两个实例上建DG_DATA(使用不同的disk)。因为ASM实例是通过asm_diskstring去读disk的metadata信息,所以如果asm_diskstring设置不当,就会失败。
/dev/ora_asm为+ASM1实例的ORA_DG对应的disk
/dev/ora_asm2为+ASM_S实例的ORA_DG对应的disk
+ASM_S的Asm_diskstring设置为/dev/ora_*时,ASM实例可以发现/dev/ora_asm和/dev/ora_asm2,会读取/dev/ora_asm上的ORA_DG信息,导致在+ASM_S上无法再创建ORA_DG
SQL> alter system set asm_diskstring='/dev/ora_*' scope=memory;
System altered.
SQL> select * from v$asm_diskgroup;
GROUP_NUMBER NAME SECTOR_SIZE BLOCK_SIZE ALLOCATION_UNIT_SIZE STATE TYPE TOTAL_MB FREE_MB
------------ ------------------------------ ----------- ---------- -------------------- ----------- ------ ---------- ----------
REQUIRED_MIRROR_FREE_MB USABLE_FILE_MB OFFLINE_DISKS COMPATIBILITY
----------------------- -------------- ------------- ------------------------------------------------------------
DATABASE_COMPATIBILITY
------------------------------------------------------------
0 ORA_DG 512 4096 0 DISMOUNTED 0 0
0 0 0 0.0.0.0.0
0.0.0.0.0
修改为/dev/ora_asm2以后+ASM_S无法发现+ASM1实例的ORA_DG,在+ASM_S上创建新的ORA_DG成功
SQL> alter system set asm_diskstring='/dev/ora_asm2';
System altered.
SQL> select * from v$asm_diskgroup;
no rows selected à没有发现DG
SQL>
SQL> create diskgroup ora_dg EXTERNAL REDUNDANCY disk '/dev/ora_asm2';
Diskgroup created.
创建成功
然后两个实例上的ORA_DG都可以mount!!
SQL> select * from v$asm_diskgroup;
GROUP_NUMBER NAME SECTOR_SIZE BLOCK_SIZE ALLOCATION_UNIT_SIZE STATE TYPE TOTAL_MB FREE_MB
------------ ------------------------------ ----------- ---------- -------------------- ----------- ------ ---------- ----------
REQUIRED_MIRROR_FREE_MB USABLE_FILE_MB OFFLINE_DISKS COMPATIBILITY
----------------------- -------------- ------------- ------------------------------------------------------------
DATABASE_COMPATIBILITY
------------------------------------------------------------
1 ORA_DG 512 4096 1048576 MOUNTED EXTERN 8192 7197
0 7197 0 10.1.0.0.0
10.1.0.0.0
SQL> select * from v$instance;
INSTANCE_NUMBER INSTANCE_NAME HOST_NAME VERSION STARTUP_T
--------------- ---------------- ---------------------------------------------------------------- ----------------- ---------
STATUS PAR THREAD# ARCHIVE LOG_SWITCH_WAIT LOGINS SHU DATABASE_STATUS INSTANCE_ROLE ACTIVE_ST BLO
------------ --- ---------- ------- --------------- ---------- --- ----------------- ------------------ --------- ---
2 +ASM1 P570 11.1.0.6.0 13-FEB-12
STARTED YES 0 STOPPED ALLOWED NO ACTIVE UNKNOWN NORMAL NO
SQL> exit
SQL> select * from v$instance;
INSTANCE_NUMBER INSTANCE_NAME HOST_NAME VERSION STARTUP_T
--------------- ---------------- ---------------------------------------------------------------- ----------------- ---------
STATUS PAR THREAD# ARCHIVE LOG_SWITCH_WAIT LOGINS SHU DATABASE_STATUS INSTANCE_ROLE ACTIVE_ST BLO
------------ --- ---------- ------- --------------- ---------- --- ----------------- ------------------ --------- ---
1 +ASM_S P570 11.1.0.6.0 13-FEB-12
STARTED YES 0 STOPPED ALLOWED NO ACTIVE UNKNOWN NORMAL NO
SQL> select * from v$asm_diskgroup;
GROUP_NUMBER NAME SECTOR_SIZE BLOCK_SIZE ALLOCATION_UNIT_SIZE STATE TYPE TOTAL_MB FREE_MB
------------ ------------------------------ ----------- ---------- -------------------- ----------- ------ ---------- ----------
REQUIRED_MIRROR_FREE_MB USABLE_FILE_MB OFFLINE_DISKS COMPATIBILITY
----------------------- -------------- ------------- ------------------------------------------------------------
DATABASE_COMPATIBILITY
------------------------------------------------------------
1 ORA_DG 512 4096 1048576 MOUNTED EXTERN 512 0
0 0 0 10.1.0.0.0
10.1.0.0.0
这时存在两个ASM实例,两个ORA_DG,这样数据库不知道找哪个ORA_DG,结果找了新建的ORA_DG,导致无法启动。
# su - oracle
$ echo $ORACLE_SID
ora11g1
$ sqlplus / as sysdba
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Feb 13 15:22:34 2012
Copyright (c) 1982, 2007, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup
ORA-01078: failure in processing system parameters
ORA-01565: error in identifying file '+ORA_DG/ora11g/spfileora11g.ora'
ORA-17503: ksfdopn:2 Failed to open file +ORA_DG/ora11g/spfileora11g.ora
ORA-15056: additional error message
ORA-17503: ksfdopn:DGOpenFile05 Failed to open file +ORA_DG/ora11g/spfileora11g.ora
ORA-17503: ksfdopn:2 Failed to open file +ORA_DG/ora11g/spfileora11g.ora
ORA-15173: entry 'ora11g' does not exist in directory '/'
ORA-06512: at line 4
SQL>
所以,ORACLE说不支持一个节点上多个ASM实例,尽管我们可以在一个节点上启动多个ASM实例。
SR 3-5313494271: CCP: how does an asm instance know DG created in another asm instance on the same server
History
Oracle Support - February 14, 2012 2:31:41 PM GMT+08:00 [ODM Answer]
2 ASM instances on the same node is not supported.
One ASM instance can serve multiple database instance on the same node.
6.2. diskmon目录权限不对导致无法配置非RAC ASM
执行localconfig reset以后ASM无法启动
osssvr-master:~ # /opt/oracle/oradb/home/bin/localconfig reset
Successfully accumulated necessary OCR keys.
Creating OCR keys for user 'root', privgrp 'root'..
Operation successful.
Configuration for local CSS has been initialized
Stale CSS daemon is running... killing it now
Cleaning up Network socket directories
Setting up Network socket directories
Adding to inittab
Startup will be queued to init within 30 seconds.
Checking the status of new Oracle init process...
Expecting the CRS daemons to be up within 600 seconds.
Cluster Synchronization Services is active on these nodes.
osssvr-master
Cluster Synchronization Services is active on all the nodes.
Oracle CSS service is installed and running under init(1M)
osssvr-master:~ # su - oracle
oracle@osssvr-master:~> ORACLE_SID=+ASN
oracle@osssvr-master:~> ORACLE_SID=+ASM
oracle@osssvr-master:~> sqlpluls /as sysdba
-bash: sqlpluls: command not found
oracle@osssvr-master:~> sqlplus / as sysdba
SQL*Plus: Release 11.1.0.7.0 - Production on Wed Feb 22 02:22:31 2012
Copyright (c) 1982, 2008, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup
ORA-03113: end-of-file on communication channel
SQL>
检查css日志发现diskmon超时
TRACE: kgzf_send_main1: connection to master diskmon timed out
TRACE: KGZF: Fatal diskmon condition, IO fencing is not available. For additional error info look at the master diskmon log file (diskmon.log)
ERROR: ASSERT clsssc.c 2471
ERROR: clssscSAGEInitFenceCompl: Fence completion failed, rc 56859
检查后发现$ORACLE_HOME/log//diskmon目录属组是root:system,改为oracle:oinstall以后问题解决。
oracle@osssvr-master:~/oradb/home/log/osssvr-master> ls -ltr
total 23
drwxrwx--- 2 oracle oinstall 112 2012-02-22 02:57 cssd
drwxr-x--- 2 oracle oinstall 144 2012-02-22 03:02 diskmon
drwxrwx--- 2 oracle oinstall 3096 2012-02-22 03:13 client
-rw-r--r-- 1 oracle oinstall 17201 2012-02-22 03:33 alertosssvr-master.log
6.3. ASM无法启动
alert日志中显示asm实例启动失败,检查后发现crs没有启动。
Tue Feb 28 19:14:14 2012
Starting ORACLE instance (normal)
WARNING: Deprecated privilege SYSDBA for command 'STARTUP'
LICENSE_MAX_SESSION = 0
LICENSE_SESSIONS_WARNING = 0
Errors in file /opt/oracle/diag/asm/+asm/+ASM2/trace/+ASM2_ora_23442.trc:
ORA-27504: IPC error creating OSD context
ORA-27300: OS system dependent operation:skgxnqtsz failed with status: 0
ORA-27301: OS failure message: Error 0
ORA-27302: failure occurred at: SKGXN not av
clsssinit ret = 21
interconnect information is not available from OCR
WARNING: No cluster interconnect has been specified. Depending on
the communication driver configured Oracle cluster traffic
may be directed to the public interface of this machine.
Oracle recommends that RAC clustered databases be configured
with a private interconnect for enhanced security and
performance.
Picked latch-free SCN scheme 3
Using LOG_ARCHIVE_DEST_1 parameter default value as /opt/oracle/product/11g/db/dbs/arch
Autotune of undo retention is turned on.
LICENSE_MAX_USERS = 0
SYS auditing is disabled
6.4. asm_diskstring设置不对
不设asm_diskstrings时,实例无法发现asm disk
$ export ORACLE_SID=+ASM_S
$ ps -ef | grep pmon
oracle 2097770 3015234 0 14:52:07 pts/0 0:00 grep pmon
$
$ sqlplus / as sysdba
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Feb 13 14:52:11 2012
Copyright (c) 1982, 2007, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup
ASM instance started
Total System Global Area 283930624 bytes
Fixed Size 2137504 bytes
Variable Size 256627296 bytes
ASM Cache 25165824 bytes
ORA-15110: no diskgroups mounted
SQL> select * from v$asm_diskgroup;
no rows selected
SQL> create diskgroup ora_dg EXTERNAL REDUNDANCY disk '/dev/ora_asm2';
create diskgroup ora_dg EXTERNAL REDUNDANCY disk '/dev/ora_asm2'
*
ERROR at line 1:
ORA-15018: diskgroup cannot be created
ORA-15031: disk specification '/dev/ora_asm2' matches no disks
ORA-15014: path '/dev/ora_asm2' is not in the discovery set à 提示dicovery set,这个表示ASM是通过asm_diskstring来读取asm disk和dg信息的
6.5. 清除/tmp/导致db instance can't startup and asmb died repeatedly错误
crs无法拉起数据库,手动也无法启动数据库。
ASM alert log
Sun Feb 26 11:58:58 2012
Starting background process ASMB
Sun Feb 26 11:58:58 2012
ASMB started with pid=20, OS id=7600
NOTE: ASMB process exiting due to lack of ASM file activity for 5 seconds
Sun Feb 26 11:59:14 2012
NOTE: ASM client ora11g1:ora11g died unexpectedly.
NOTE: Process state recorded in trace file /opt/oracle/diag/asm/+asm/+ASM1/trace/+ASM1_ora_7767.trc
db alert log
Reconfiguration complete
NOTE:Loaded library: System
SUCCESS: diskgroup DG_ORA was mounted
USER (ospid: 7806): terminating the instance
System state dump is made for local instance
System State dumped to trace file /opt/oracle/diag/rdbms/ora11g/ora11g1/trace/ora11g1_diag_7685.trc
Trace dumping is performing id=[cdmp_20120226115910]
Instance terminated by USER, pid = 7806
diag trace showed state of some processes are KJP_FROZEN.
ORACLE判断
Sun Feb 26 11:58:16 2012
ASMB started with pid=20, OS id=6269
NOTE: ASMB process exiting due to lack of ASM file activity for 5 seconds
>>>>>>>>>>>>>Note: this is just a notice infor, can be ignore.
ASMB process exiting due to lack of ASM file activity (Doc ID 754110.1)
检查其他日志,没有发现有用信息
imonora11g.log
------------------------------
SQL> ORACLE instance started.
Total System Global Area 1.0021E+10 bytes
Fixed Size 2168296 bytes
Variable Size 5771364888 bytes
Database Buffers 4227858432 bytes
Redo Buffers 19988480 bytes
ORA-03113: end-of-file on communication channel <===================crs启数据库时就失败了
Process ID: 7253
Session ID: 885 Serial number: 3
SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, Real Application Clusters, OLAP, Data Mining
and Real Application Testing options
SQL*Plus: Release 11.1.0.7.0 - Production on Sun Feb 26 11:58:55 2012
Copyright (c) 1982, 2008, Oracle. All rights reserved.
Enter user-name: Connected to an idle instance.
SQL> ORACLE instance shut down. <===================
SQL> Disconnected
ora11g1_diag_7685.trc
-----------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
O/S info: user: oracle, term: UNKNOWN, ospid: 7806
OSD pid info: Unix process pid: 7806, image: oracle@rac1 (TNS V1-V3)
...
service name: SYS$USERS
client details:
O/S info: user: oracle, term: , ospid: 7582
machine: rac1 program: sqlplus@rac1 (TNS V1-V3) <=== pid=7806 is a sqlplus session, maybe come from CRS.
application name: sqlplus@rac1 (TNS V1-V3), hash value=3186068794
Current Wait Stack:
Not in wait; last wait ended 2.275831 sec ago
strace启动过程发现,实例再不断尝试心跳节点的各个端口进行通信,但是都失败了。
strace -ftto /tmp/sqlplus1.out sqlplus sys/oracle as sysdba
startup
日志:
In the truss log, such errors repeatedly.
10293 10:50:01.493409 <... read resumed> "10256 (oracle) S 1 10256 10256 0"..., 999) = 231
10218 10:50:01.493436 write(25, "\0\0\0\0", 4 <unfinished ...>
10390 10:50:01.493462 sendmsg(23, {msg_name(16)={sa_family=AF_INET, sin_port=htons(41372), sin_addr=inet_addr("192.168.1.20")}, msg_iov(3)=[{"\4\3\2\1h\31\0\0\0\0\0\0MRON\0\2\0\0\0\0\0\0001\303\2<"..., 76}, {"\1\262\200\353\377\177\0\0\330\0\0\0\26+\0\0h\31\0\0\0"..., 28}, {"\356G\177\201\2\0\0\0\302\t\f\r\0\0\0\0\222jKm\377\376"..., 216}], msg_controllen=0, msg_flags=0}, 0 <unfinished ...>
10293 10:50:01.493523 close(28 <unfinished ...>
10218 10:50:01.493550 <... write resumed> ) = 4
10390 10:50:01.493570 <... sendmsg resumed> ) = 320
10293 10:50:01.493587 <... close resumed> ) = 0
10218 10:50:01.493611 lseek(25, 8196096, SEEK_SET <unfinished ...>
10390 10:50:01.493633 sendmsg(23, {msg_name(16)={sa_family=AF_INET, sin_port=htons(41378), sin_addr=inet_addr("192.168.1.20")}, msg_iov(3)=[{"\4\3\2\1h\31\0\0\0\0\0\0MRON\0\2\0\0\0\0\0\0001\303\2<"..., 76}, {"\1\262\200\353\377\177\0\0\330\0\0\0\26+\0\0h\31\0\0\0"..., 28}, {"\361G\177\201\2\0\0\0:}\3031\0\0\0\0\371{<.\0\377\364T"..., 216}], msg_controllen=0, msg_flags=0}, 0 <unfinished ...>
recvmsg returns EAGAIN errors.
this repeate serveral times.
And the 192.168.1.20 is rac2_heart.
this truss should be generated on rac1, so does this mean there is network problem with two nodes.
一线反馈之前清过tmp文件夹,这样/tmp/.oracle文件夹就被删除了,ORACLE说可以重新删除.oracle文件,然后重启crs就可以解决问题,但是尝试后没有成功,最终重建crs解决问题。
6.6. disk timeout导致asm文件头损坏
ASM dg无法mount,alert日志报heartbeat错误,用kred检查没有发现文件头有损坏
Wed Feb 29 19:24:29 2012
SQL> ALTER DISKGROUP ALL MOUNT
WARNING: Deprecated privilege SYSDBA for command 'ALTER DISKGROUP MOUNT'
NOTE: cache registered group DG_DATA number=1 incarn=0x4a20d40c
NOTE: cache began mount (first) of group DG_DATA number=1 incarn=0x4a20d40c
NOTE: cache registered group DG_ORA number=2 incarn=0x4a20d40d
NOTE: cache began mount (first) of group DG_ORA number=2 incarn=0x4a20d40d
WARNING::ASMLIB library not found. See trace file for details.
NOTE: Assigning number (1,1) to disk (/dev/raw/raw5)
NOTE: Assigning number (1,0) to disk (/dev/raw/raw4)
NOTE: Assigning number (2,0) to disk (/dev/raw/raw3)
WARNING: disk 0.2524980482 (DG_DATA_0000) not responding to heart beat à heartbeat err
ERROR: too many offline disks in PST (grp 1) à grp1: raw4,raw5
WARNING: Disk DG_DATA_0000 in mode 0x7f will be taken offline
ERROR: PST could not check any hearbeat (grp 1)
NOTE: cache dismounting group 1/0x4A20D40C (DG_DATA)
NOTE: dbwr not being msg'd to dismount
NOTE: lgwr not being msg'd to dismount
NOTE: cache dismounted group 1/0x4A20D40C (DG_DATA)
NOTE: cache ending mount (fail) of group DG_DATA number=1 incarn=0x4a20d40c
kfdp_dismount(): 4
kfdp_dismountBg(): 4
NOTE: De-assigning number (1,0) from disk (/dev/raw/raw4)
NOTE: De-assigning number (1,1) from disk (/dev/raw/raw5)
ERROR: diskgroup DG_DATA was not mounted
NOTE: start heartbeating (grp 2)
kfdp_query(DG_ORA): 6
kfdp_queryBg(): 6
NOTE: cache opening disk 0 of grp 2: DG_ORA_0000 path:/dev/raw/raw3
NOTE: F1X0 found on disk 0 fcn 0.0
NOTE: cache mounting (first) group 2/0x4A20D40D (DG_ORA)
* allocate domain 2, invalid = TRUE
NOTE: attached to recovery domain 2
NOTE: starting recovery of thread=1 ckpt=13.4098 group=2
NOTE: starting recovery of thread=2 ckpt=13.468 group=2
NOTE: advancing ckpt for thread=1 ckpt=13.4098
NOTE: advancing ckpt for thread=2 ckpt=13.468
NOTE: cache recovered group 2 to fcn 0.106249
NOTE: LGWR attempting to mount thread 1 for diskgroup 2
NOTE: LGWR mounted thread 1 for disk group 2
NOTE: opening chunk 1 at fcn 0.106249 ABA
NOTE: seq=14 blk=4099
NOTE: cache mounting group 2/0x4A20D40D (DG_ORA) succeeded
NOTE: cache ending mount (success) of group DG_ORA number=2 incarn=0x4a20d40d
kfdp_query(DG_ORA): 7
kfdp_queryBg(): 7
NOTE: Instance updated compatible.asm to 10.1.0.0.0 for grp 2
SUCCESS: diskgroup DG_ORA was mounted
ORA-15032: not all alterations performed
ORA-15066: offlining disk "DG_DATA_0000" may result in a data loss
ERROR: ALTER DISKGROUP ALL MOUNT
手动mount DG_DATA时,报错发生变化,变成了disk损坏
sql>alter diskgroup DG_DATA mount;
SQL> alter diskgroup DG_DATA mount
WARNING: Deprecated privilege SYSDBA for command 'ALTER DISKGROUP MOUNT'
NOTE: cache registered group DG_DATA number=1 incarn=0xcd24de3b
NOTE: cache began mount (first) of group DG_DATA number=1 incarn=0xcd24de3b
NOTE: Assigning number (1,1) to disk (/dev/raw/raw5)
NOTE: Assigning number (1,0) to disk (/dev/raw/raw4)
....
Fri Mar 02 10:01:28 2012
NOTE: attached to recovery domain 1
NOTE: starting recovery of thread=1 ckpt=13.2216 group=1
WARNING: cache read a corrupted block gn=1 fn=3 blk=10752 from disk 0
NOTE: a corrupted block was dumped to /opt/oracle/diag/asm/+asm/+ASM2/trace/+ASM2_ora_22676.trc
ERROR: cache failed to read gn=1 fn=3 blk=10752 from disk(s): 0
ORA-15196: invalid ASM block header [kfc.c:9192] [obj_kfbl] [3] [10752] [64 != 3]
System State dumped to trace file /opt/oracle/diag/asm/+asm/+ASM2/trace/+ASM2_ora_22676.trc
NOTE: cache initiating offline of disk 0 group 1
NOTE: process 22676 initiating offline of disk 0.2545168081 (DG_DATA_0000) with mask 0x7e in group 1
WARNING: Disk DG_DATA_0000 in mode 0x7f is now being taken offline
....
NOTE: De-assigning number (1,0) from disk (/dev/raw/raw4)
NOTE: De-assigning number (1,1) from disk (/dev/raw/raw5)
ERROR: diskgroup DG_DATA was not mounted
ORA-15032: not all alterations performed
ORA-15130: diskgroup "DG_DATA" is being dismounted
ORA-15066: offlining disk "DG_DATA_0000" may result in a data loss
ERROR: alter diskgroup DG_DATA mount
使用amdu检查,发现确实损坏了
amdu
amdu_2012_03_02_12_03_05
cd amdu_2012_03_02_12_03_05
cat report.txt
-*-amdu-*-
******************************* AMDU Settings ********************************
ORACLE_HOME = /opt/oracle/product/11g/db
System name: Linux
Node name: mip1
Release: 2.6.16.60-0.21-smp
Version: #1 SMP Tue May 6 12:41:02 UTC 2008
Machine: x86_64
amdu run: 02-MAR-12 12:03:05
Endianess: 1
--------------------------------- Operations ---------------------------------
-dump DG_DATA
------------------------------- Disk Selection -------------------------------
-diskstring '/dev/raw/raw*'
------------------------------ Reading Control -------------------------------
------------------------------- Output Control -------------------------------
********************************* DISCOVERY **********************************
----------------------------- DISK REPORT N0001 ------------------------------
Disk Path: /dev/raw/raw7
Unique Disk ID:
Disk Label:
Physical Sector Size: 512 bytes
Disk Size: 2048 megabytes
** NOT A VALID ASM DISK HEADER. BAD VALUE IN FIELD blksize_kfdhdb ** à 非asm disk
...
***************** Slept for 6 seconds waiting for heartbeats *****************
读DG信息之前要等待6秒 heartbeats
************************* SCANNING DISKGROUP DG_DATA *************************
Creation Time: 2011/11/11 16:45:26.677000
Disks Discovered: 2
Redundancy: 1
AU Size: 1048576 bytes
Metadata Block Size: 4096 bytes
Physical Sector Size: 512 bytes
Metadata Stride: 113792 AU
Duplicate Disk Numbers: 0
---------------------------- SCANNING DISK N0003 -----------------------------
Disk N0003: '/dev/raw/raw4'
AMDU-00209: Corrupt block found: Disk N0003 AU [26] block [0] type [4096]
AMDU-00201: Disk N0003: '/dev/raw/raw4'
AMDU-00209: Corrupt block found: Disk N0003 AU [26] block [12] type [4096]
AMDU-00201: Disk N0003: '/dev/raw/raw4'
AMDU-00209: Corrupt block found: Disk N0003 AU [26] block [13] type [4096]
AMDU-00201: Disk N0003: '/dev/raw/raw4'
...
AMDU-00209: Corrupt block found: Disk N0003 AU [48] block [12] type [4096]
AMDU-00201: Disk N0003: '/dev/raw/raw4'
Allocated AU's: 24064
Free AU's: 180736
AU's read for dump: 58
Block images saved: 12361
Map lines written: 58
Heartbeats seen: 0
Corrupt metadata blocks: 96 à 文件头损坏
Corrupt AT blocks: 0
...
----------------------- SUMMARY FOR DISKGROUP DG_DATA ------------------------
Allocated AU's: 48123
Free AU's: 361477
AU's read for dump: 110
Block images saved: 24434
Map lines written: 110
Heartbeats seen: 0
Corrupt metadata blocks: 96
Corrupt AT blocks: 0
******************************* END OF REPORT ********************************
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.