b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

weblogic连接池配置_weblogic连接scan ip_weblogic长连接(20)

电脑杂谈  发布时间:2017-02-02 06:33:31  来源:网络整理

Read the rest of this entry

performance

提起Oracle的Hint,几乎每一个DBA都知道这一强大工具。在Oracle中,Hint可以用来改变SQL的执行计划、固定SQL的执行计划。Oracle内部的很多特性也依赖于Hint,比如Outline、Profile等。

但是在日常工作中,很多开发人员或DBA,对Hint的使用仍然存在一些错误的方式。下面将列举主要的2种。(本文不讨论Hint的滥用即过度使用问题)。

1. NOLOGGING的不正确使用。

很知道,在进行数据处理时,如果不产生日志或只产生少量的日志,将会有明显的、甚至是巨大的效率提升。下面有几条不同的SQL:

INSERT INTO T1 NOLOGGING;
INSERT INTO T1 SELECT * FROM T2 NOLOGGING;
INSERT /*+ NOLOGGING */ INTO T1 VALUES ('0');
INSERT /*+ NOLOGGING */ INTO T1 SELECT * FROM T2;
DELETE /*+ NOLOGGING */ FROM T1;
UPDATE /*+ NOLOGGING */ T1 SET A='1';

实际上,上述所有的SQL没有一个能够实现“不产生”日志的数据更改操作。第1-2条SQL语句虽然没有将NOLOGGING写为Hint的形式,但是也是很的错误写法,一并列在此处。事实上,NOLOGGING并不是Oracle的一个有效的Hint,而是一个SQL关键字,通常用于DDL语句中。这里NOLOGGING相当于给SELECT的表指定了一个别名为“NOLOGGING”。下面是NOLOGGING的一些正确用法:

CREATE TABLE T1 NOLOGGING AS SELECT * FROM T2;
CREATE INDEX T1_IDX ON T1(A) NOLOGGING;
ALTER INDEX T1_IDX REDUILD ONLINE NOLOGGING;
ALTER TABLE T1 NOLOGGING;

上述SQL中,最后一条SQL只是将表的LOGGING属性改为"NO"。而之前的几条SQL能够有效地减少DDL操作时减少的日志量。

在DML操作中,只有下面一种方式能够在大数据量时仍然只会产生极少量的日志:

INSERT /*+ APPEND */ INTO T1 SELECT * FROM T2;

也就是使用append hint。但是这个hint要达到目的,需要以下几个条件:

weblogic连接池配置_weblogic连接scan ip_weblogic长连接

使用INSERT /*+ APPEND */ INTO .. SELECT .. FROM形式的INSERT SQL。

如果是在归档模式下,需要将表的LOGGING属性置为NO。

表空间或的FORCE LOGGING属性为NO。注意在非归档模式下也是可以设置FORCE LOGGING的。

这里提到的insert语句中的append hint,对于索引,仍然会产生日志,也就是说append hint对索引是没有效果的。

另外,DDL中使用的nologging关键字和inset语句中使用的append hint,并不是说完全不产生日志,只是对表的数据块的数据部分的更改不会有日志产生,但是SQL执行过程中数据字典的更改、空间分配等递归SQL、段头和位图块的更改、将数据块标记为unrecoverable等仍然会产生少量日志。

2. Hint的不正确写法。

这是一个比较不容易发现的问题。下面几条SQL,哪一条SQL的append hint会生效:

1. INSERT /*+ append,parallel(t1) */ INTO T1 SELECT * FROM T2;
2. INSERT /*+ parallel(t1), append */ INTO T1 SELECT * FROM T2;
3. INSERT /*+ this is append */ INTO T1 SELECT * FROM T2;
4. INSERT /*+ this append */ INTO T1 SELECT * FROM T2;

要回答这个问题,请先看下面的测试(测试环境:10.2.0.1 for Windows):

SQL> INSERT /*+ append,parallel(t1) */ INTO T1 SELECT * FROM T2;
已创建55640行。
统计信息
----------------------------------------------------------
      12304  redo size
SQL> COMMIT;

SQL> INSERT /*+ parallel(t1), append */ INTO T1 SELECT * FROM T2;
已创建55640行。
统计信息
----------------------------------------------------------
    5739584  redo size
SQL> COMMIT;

SQL> INSERT /*+ this is append */ INTO T1 SELECT * FROM T2;
已创建55640行。
统计信息
----------------------------------------------------------
    5746604  redo size
SQL> COMMIT;

SQL> INSERT /*+ this append */ INTO T1 SELECT * FROM T2;
已创建55640行。
统计信息
----------------------------------------------------------
      12052  redo size
SQL> COMMIT;

从上面的输出可以看到,通过insert语句执行产生的redo size判断,4条SQL语句中,1和4这2条SQL中的append hint起了作用,而2和3这2条SQL中的append hint没有起作用。我们看看第1和第2条SQL,只不过是parallel和append换了个位置,结果就截然不同;而第3和第4条SQL,只是一个多了"is"这个词,另一个没有,其结果也完全不同。这里有什么玄机吗?

这里就需要了解Oracle在解析SQL时,是怎样解析hint的。

Oracle在解析hint,从左到右进行,如果遇到一个词是oracle关键字或者说是保留字,将忽略这个词以及之后的所有词。如果遇到的一个词即不是关键字也不是hint,就忽略该词。如果遇到的一个词是有效的hint,那么就会保留该hint。

Oracle的保留字或者说是关键词(虽然二者在意义不一样,但这里不将其区分),可以通过视图v$reserved_words来查询。"is"正是一个关键词,甚至连","(逗号)也是一个关键词。这样,上面的第2和第3条SQL,Oracle解析时当遇到","和"is"时,就忽略了后面的所有hint。在第4条SQL中,this并不是一个关键词,所以append hint有效。基于这个原理,下面的一条SQL中的hint也是不起作用的:

INSERT /*+ NOLOGGING APPEND */ INTO T1 SELECT * FROM T2;

在9.2.0.8和11.2.0.2这2个版本下进行同样的测试,结果完全一样。

为了避免这样的情况,在SQL中书写hint时,在/*+ */和--+这2种结构内只写hint,而不要写逗号,或者是其他的注释。如果要对SQL写注释,在专门的注释结构中写入。比如/* test comment */。如果与hint混写注释,虽然当时没有关键词在里面,但随着版本升级,很可能会加入新的关键词。

另外,一些很常见的hint形式,比如/*+ parallel(t,8) */,/*+ index(t,t_idx) */,虽然当前没有问题,但标准的写法应该是:

/*+ parallel(t 8) */,/*+ index(t t_idx) */

--end end.

hint

客户一套运行在Oracle 10.2.0.5 RAC上的系统,间歇性地出现性能问题。其性能现象为前台反映性能缓慢,从系统上看CPU利用率大幅增加,load增加。这种性能问题通常在出现几分钟后自动恢复正常。

从AWR中的TOP 5等待来看:

Top 5 Timed Events                                         Avg %Total
~~~~~~~~~~~~~~~~~~                                        wait   Call
Event                                 Waits    Time (s)   (ms)   Time Wait Class
------------------------------ ------------ ----------- ------ ------ ----------
latch: cache buffers lru chain      774,812     140,185    181   29.7      Other
gc buffer busy                    1,356,786      61,708     45   13.1    Cluster
latch: object queue header ope      903,456      55,089     61   11.7      Other
latch: cache buffers chains         360,522      49,016    136   10.4 Concurrenc
gc current grant busy               112,970      19,893    176    4.2    Cluster
          -------------------------------------------------------------

可以看到,TOP 5中,有3个是latch相关的等待,而另外2个则是跟RAC相关的等待。

如果再查看更细的等待数据,可以发现其他问题:


                                                                  Avg
                                            %Time  Total Wait    wait     Waits
Event                                 Waits -outs    Time (s)    (ms)      /txn
---------------------------- -------------- ----- ----------- ------- ---------
latch: cache buffers lru cha        774,812   N/A     140,185     181       1.9
gc buffer busy                    1,356,786     6      61,708      45       3.3
latch: object queue header o        903,456   N/A      55,089      61       2.2
latch: cache buffers chains         360,522   N/A      49,016     136       0.9
gc current grant busy               112,970    25      19,893     176       0.3
gcs drm freeze in enter serv         38,442    97      18,537     482       0.1
gc cr block 2-way                 1,626,280     0      15,742      10       3.9
gc remaster                           6,741    89      12,397    1839       0.0
row cache lock                       52,143     6       9,834     189       0.1

从上面的数据还可以看到,除了TOP 5等待,还有"gcs drm freeze in enter server mode“以及"gc remaster"这2种比较少见的等待事件,从其名称来看,明显与DRM有关。那么这2种等待事件与TOP 5的事件有没有什么关联?。MOS文档"Bug 6960699 - "latch: cache buffers chains" contention/ORA-481/kjfcdrmrfg: SYNC TIMEOUT/ OERI[kjbldrmrpst:!master] [ID 6960699.8]”提及,DRM的确可能会引起大量的"latch: cache buffers chains"、"latch: object queue header operation"等待,虽然文档没有提及,但不排除会引起”latch: cache buffers lru chain“这样的等待。

为了进一步证实性能问题与DRM相关,使用tail -f命令监控LMD后台进程的trace文件。在trace文件中显示开始进行DRM时,查询v$session视图,发现大量的 "latch: cache buffers chains" 、"latch: object queue header operation"等待事件,同时有"gcs drm freeze in enter server mode“和"gc remaster"等待事件,同时系统负载升高,前台反映性能下降。而在DRM完成之后,这些等待消失,系统性能恢复到正常。

看起来,只需要关闭DRM就能避免这个问题。怎么样来关闭/禁止DRM呢?很多MOS文档提到的方法是设置2个隐含参数:

_gc_affinity_time=0
_gc_undo_affinity=FALSE

不幸的是,这2个参数是静态参数,也就是说必须要重启实例才能生效。

实际上可以设置另外2个动态的隐含参数,来达到这个目的。按下面的值设置这2个参数之后,不能完全算是禁止/关闭了DRM,而是从”事实上“关闭了DRM。

_gc_affinity_limit=250
_gc_affinity_minimum=10485760

甚至可以将以上2个参数值设置得更大。这2个参数是立即生效的,在所有的节点上设置这2个参数之后,系统不再进行DRM,经常一段时间的观察,本文描述的性能问题也不再出现。

下面是关闭DRM之后的等待事件数据:

Top 5 Timed Events                                         Avg %Total
~~~~~~~~~~~~~~~~~~                                        wait   Call
Event                                 Waits    Time (s)   (ms)   Time Wait Class
------------------------------ ------------ ----------- ------ ------ ----------
CPU time                                         15,684          67.5
db file sequential read           1,138,905       5,212      5   22.4   User I/O
gc cr block 2-way                   780,224         285      0    1.2    Cluster
log file sync                       246,580         246      1    1.1     Commit
SQL*Net more data from client       296,657         236      1    1.0    Network
          -------------------------------------------------------------
          
                                                                  Avg
                                            %Time  Total Wait    wait     Waits
Event                                 Waits -outs    Time (s)    (ms)      /txn
---------------------------- -------------- ----- ----------- ------- ---------
db file sequential read           1,138,905   N/A       5,212       5       3.8
gc cr block 2-way                   780,224   N/A         285       0       2.6
log file sync                       246,580     0         246       1       0.8
SQL*Net more data from clien        296,657   N/A         236       1       1.0
SQL*Net message from dblink          98,833   N/A         218       2       0.3
gc current block 2-way              593,133   N/A         218       0       2.0
gc cr grant 2-way                   530,507   N/A         154       0       1.8
db file scattered read               54,446   N/A         151       3       0.2
kst: async disk IO                    6,502   N/A         107      16       0.0
gc cr multi block request           601,927   N/A         105       0       2.0
SQL*Net more data to client       1,336,225   N/A          91       0       4.5
log file parallel write             306,331   N/A          83       0       1.0
gc current block busy                 6,298   N/A          72      11       0.0
Backup: sbtwrite2                     4,076   N/A          63      16       0.0
gc buffer busy                       17,677     1          54       3       0.1
gc current grant busy                75,075   N/A          54       1       0.3
direct path read                     49,246   N/A          38       1       0.2

那么,这里不得不提的是,什么是DRM?DRM对系统来说有什么好处?本文不再详述,因为下面的2篇文档已经描述得比较清楚,有兴趣的朋友可以参考:

MOS文档:DRM - Dynamic Resource management [ID 390483.1]

Object Remastering In RAC

关于本文所使用的2个隐含参数,在上述第二篇文档中也有详细描述。

--END---

rac

当一个存储过程所依赖(引用的)对象发生某些更改时,会使得存储过程失效(invalidated),比如存储过程依赖(引用)的表增加减少了列、存储过程依赖(引用)的存储过程被重新编译。本文将介绍一种特殊的会引起存储过程失效的情况。

下面通过测试来演示与DB LINK相关的存储过程失效的情况:

1. 在TEST用户下创建到db1的DB LINK:

SQL> create database link to_db connect to perfstat identified by xxx using 'db1';

链接已创建。

2.在TEST2用户下创建到db2的DB LINK,DB LINK的名称仍然为to_db,但实际上连接的与TEST用户下to_db这个DB LINK连接的并不是同一个:

SQL> create database link to_db connect to perfstat identified by xxx using 'db2';

链接已创建。

3. 在TEST用户下创建存储过程TEST_P1:

SQL> create or replace procedure test_p1
  2  is
  3    v_dbid number;
  4  begin
  5    select dbid into v_dbid from stats$snapshot@to_db where rownum<2;
  6  end;
  7  /

过程已创建。

SQL> select object_id,status from user_objects where object_name='TEST_P1';

 OECT_ID STATUS
---------- ----------
     18443 VALID

4. 在TEST2用户下创建存储过程TEST2_P1,这里存储过程TEST2_P1的代码与TEST用户下存储过程TEST_P1的代码明显不同。这两个存储过程的共同点是都引用了STATS$SNAPSHOT@TO_DB这个远程表。由于TEST和TEST2用户下TO_DB连接的是不同的,因此这2个存储过程引用的STATS$SNAPSHOT@TO_DB位于不同的上,也就是说是不同的表:

SQL> create or replace procedure test2_p1
  2  is
  3    v_snap_time date;
  4  begin
  5    select snap_time into v_snap_time from stats$snapshot@to_db where rownum<2;
  6  end;
  7  /

过程已创建。

SQL> select object_id,status from user_objects where object_name='TEST2_P1';

 OECT_ID STATUS
---------- ----------
     18445 VALID

5. 在TEST用户下查看存储过程TEST_P1的状态,发现其状态为INVALID,而实际上这个时候这个存储过程以及其引用的对象没有任何变更:

SQL> select object_id,status from user_objects where object_name='TEST_P1';

 OECT_ID STATUS
---------- ----------
     18443 INVALID

6. 如果重新编译TEST.TEST_P1,那么其状态会成为VALID,但是这个时候TEST2.TEST2_P1则又莫名其妙地变成为INVALID:

SQL> alter procedure test.test_p1 compile;

过程已更改。

SQL> select object_id,owner,object_name,status from dba_objects 
  where object_name in ('TEST_P1','TEST2_P1');

 OECT_ID OWNER           OECT_NAME                    STATUS
---------- --------------- ------------------------------ ----------
     18443 TEST            TEST_P1                        VALID
     18445 TEST2           TEST2_P1                       INVALID

7. 在TEST2用户下执行存储过程TEST2_P1,然后再次检查存储过程状态:

SQL> exec test2_p1

PL/SQL 过程已成功完成。

SQL> select object_id,owner,object_name,status from dba_objects
  2  where object_name in ('TEST_P1','TEST2_P1');

 OECT_ID OWNER           OECT_NAME                    STATUS
---------- --------------- ------------------------------ ----------
     18443 TEST            TEST_P1                        INVALID
     18445 TEST2           TEST2_P1                       VALID

可以看到,TEST.TEST_P1失效了,而TEST2.TEST2_P1又正常了。

在这里就可以提出问题了:为什么创建了TEST2.TEST2_P1这个存储过程之后,TEST.TEST_P1就失效了?为什么TEST.TEST_P1重新编译之后TEST2.TEST2_P1又失效了?为什么TEST2.TEST2_P1重新执行(有一个隐式的编译过程)后,TEST.TEST_P1又失效了?

其实上以上三个问题可以归纳为一个问题:为什么TEST.TEST_P1和TEST2.TEST2_P1这2个存储过程,在其中一个状态正常的情况下,另一个为失效状态?

Read the rest of this entry

dblink

我给《DBA 手记III》投的一篇稿子,名为《一次由隐含参数引起性能问题的处理》,这篇文章描述了一套关键的系统,由于"_kghdsidx_count"这个参数设置为1,导致了严重的性能问题。从故障现象上看是大量的library cache latch的等待,以及shared pool latch的等待,但是前者的等待时间比后者长得多。在文章中,我提到,在当时我推断,由于"_kghdsidx_count"这个隐含参数设置为1,导致shared pool只有1个subpool,引起了shared pool latch的严重竞争,进而引起了library cache cache的更为严重的竞争,这个竞争的过程如下:

由于"_kghdsidx_count"=1,使得shared pool latch只有1个child latch。而library cache latch的child latch数量跟CPU数量有关,最大值为67,编号为child #1-#67。

会话1持有shared pool latch。

会话2解析SQL语句,首先持有了library cache latch的child latch,假设这里为child #1,然后去请求shared pool latch。很显然,这时候被会话1持有,那么会话2就会等待shared pool latch。

会话3解析SQL语句,首先需要请求library cache latch,如果请求的library cache child latch刚好是#1,那么由于会话2持有了这个child latch,就会等待library cache latch。

因此,实际上会话1和会话2的shared pool latch的竞争引起了会话3的library cache latch的等待。如果并发数不是太高,那么shared pool latch的竞争看上去就会比library cache latch的竞争多一些。但是如果有几百个活动会话,这个时候,就会有大量的会话首先等待library cache latch,因为在解析SQL时是首先需要获取library cache latch再获取shared pool latch。由于大量的软解析,甚至不需要获取shared pool latch,同时一个大型的OLTP系统中,某几条相同的SQL并发执行的概率很高,这样会使很多会话同时请求同一library cache child latch;另外,在解析过程中,可能会多次请求library cache latch和shared pool latch,而前者请求和释放的次数会比后者多得多;这样大量的会话在获取library cache latch时处于等待状态,从现象上看就比shared pool latch的等待多得多。

而本文主要表达的是,怎么来验证在解析时,Oracle进程在持有了library cache latch的情况下去请求shared pool latch,而不是在请求shared pool时不需要持有library cache latch。

由于这个验证过程过于internal,所以没有在《DBA手记III》中描述出来。这里写出来,供有兴趣的朋友参考。

验证上面的这一点,有2个方法。下面以测试过程来详细描述。

测试环境 :Oracle 10.2.0.5.1 for Linux X86.

方法一:使用oradebug。

1. 将的"_kghdsidx_count"参数值设为1,并重启,以保证只有一个shared pool child latch。

2. 使用sqlplus连接到,假设这个会话是session-1,查询当前的SID:

SQL> select sid from v$mystat where rownum=1;

       SID
----------
       159

同时获得当前连接的spid为2415。

3. 新建一个连接到,假设会话是session-2,查询shared pool latch的地址,并使用oradebug将这个地址对应的值置为1,以表示该latch已经被持有:


SQL> select addr,latch#,level#,child#,name,gets  from v$latch_children where name='shared pool';

ADDR         LATCH#     LEVEL#     CHILD# NAME                                                     GETS
-------- ---------- ---------- ---------- -------------------------------------------------- ----------
200999BC        216          7          1 shared pool                                             34949
20099A20        216          7          2 shared pool                                                 6
20099A84        216          7          3 shared pool                                                 6
20099AE8        216          7          4 shared pool                                                 6
20099B4C        216          7          5 shared pool                                                 6
20099BB0        216          7          6 shared pool                                                 6
20099C14        216          7          7 shared pool                                                 6

SQL> oradebug poke 0x200999BC 4 1
BEFORE: [200999BC, 200999C0) = 00000000
AFTER:  [200999BC, 200999C0) = 00000001

4. 在session-1会话中执行下面的SQL:

SQL> select owner from t where object_id=3003;

正如预料之中的反映,这个会话hang住。

5. 在session-2中,对session-1的进程作process dump。(注意这个时候不能查询v$session_wait、v$latchholder等视图)

SQL> oradebug setospid 2415
Oracle pid: 15, Unix process pid: 2415, image: oracle@xty (TNS V1-V3)
SQL> oradebug dump processstate 10
Statement processed.
SQL> oradebug tracefile_name
/oracle/app/oracle/admin/xty/udump/xty_ora_2415.trc

然后从/oracle/app/oracle/admin/xty/udump/xty_ora_2415.trc这个TRACE文件中可以找到下面的信息:

Read the rest of this entry


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-30053-20.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...