异步提交oracle,Asynchronous Commit 【异步提交】

User I/O测试过程如下:

SQL> ALTER SYSTEM SET COMMIT_WRITE = IMMEDIATE,WAIT ;

System altered.

SQL> exec DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT();

PL/SQL procedure successfully completed.

SQL> begin

2    for x in (select * from all_objects)

3     loop

4      insert into wwm2 values x;

5      commit;

6   end loop;

7   end;

8  /

PL/SQL procedure successfully completed.

SQL> exec DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT();

PL/SQL procedure successfully completed.

SQL> ALTER SYSTEM SET COMMIT_WRITE = BATCH, NOWAIT;

System altered.

SQL> exec DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT();

PL/SQL procedure successfully completed.

SQL> begin

2    for x in (select * from all_objects)

3     loop

4      insert into wwm2 values x;

5      commit;

6   end loop;

7   end;

8  /

PL/SQL procedure successfully completed.

SQL> exec DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT();

PL/SQL procedure successfully completed.

SQL> select count(*) from wwm2;

COUNT(*)

----------

396850

SQL> select count(*) from all_objects;

COUNT(*)

----------

49634

SQL> exit

Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

[oracle@localhost ~]$ exit

logout

[root@localhost ~]# exit

logout

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

三、commit时设置异步提交

CREATE TABLE commit_test (

id           NUMBER(10),

description  VARCHAR2(50),

CONSTRAINT commit_test_pk PRIMARY KEY (id)

);

CONN A/A

SET SERVEROUTPUT ON

DECLARE

function get_waits(p_event in varchar2) return number

is

l_waits  NUMBER;

begin

select total_waits

into l_waits

from v$session_event

where event = p_event

and sid = (select sid from v$mystat where rownum=1);

return l_waits;

exception

when no_data_found then return 0;

end;

PROCEDURE do_loop (p_type  IN  VARCHAR2) AS

l_start  NUMBER;

l_loops  NUMBER := 1000;

l_lfs    NUMBER;

BEGIN

EXECUTE IMMEDIATE 'TRUNCATE TABLE commit_test';

l_lfs := get_waits('log file sync');

l_start := DBMS_UTILITY.get_time;

FOR i IN 1 .. l_loops LOOP

INSERT INTO commit_test (id, description)

VALUES (i, 'Description for ' || i);

CASE p_type

WHEN ' ' THEN COMMIT;

WHEN 'WRITE' THEN COMMIT WRITE;

WHEN 'WRITE WAIT' THEN COMMIT WRITE WAIT;

WHEN 'WRITE NOWAIT' THEN COMMIT WRITE NOWAIT;

WHEN 'WRITE BATCH' THEN COMMIT WRITE BATCH;

WHEN 'WRITE IMMEDIATE' THEN COMMIT WRITE IMMEDIATE;

WHEN 'WRITE BATCH WAIT' THEN COMMIT WRITE BATCH WAIT;

WHEN 'WRITE BATCH NOWAIT' THEN COMMIT WRITE BATCH NOWAIT;

WHEN 'WRITE IMMEDIATE WAIT' THEN COMMIT WRITE IMMEDIATE WAIT;

WHEN 'WRITE IMMEDIATE NOWAIT' THEN COMMIT WRITE IMMEDIATE NOWAIT;

END CASE;

END LOOP;

DBMS_OUTPUT.put_line(RPAD('COMMIT ' || p_type, 30)

|| ': ' || (DBMS_UTILITY.get_time - l_start)

|| ': ' || (get_waits('log file sync') - l_lfs)

);

END;

BEGIN

do_loop(' ');

do_loop('WRITE');

do_loop('WRITE WAIT');

do_loop('WRITE NOWAIT');

do_loop('WRITE BATCH');

do_loop('WRITE IMMEDIATE');

do_loop('WRITE BATCH WAIT');

do_loop('WRITE BATCH NOWAIT');

do_loop('WRITE IMMEDIATE WAIT');

do_loop('WRITE IMMEDIATE NOWAIT');

END;

/

COMMIT                        : 19: 0

COMMIT WRITE                  : 151: 1000

COMMIT WRITE WAIT             : 150: 1000

COMMIT WRITE NOWAIT           : 20: 0

COMMIT WRITE BATCH            : 151: 1000

COMMIT WRITE IMMEDIATE        : 152: 1000

COMMIT WRITE BATCH WAIT       : 151: 1000

COMMIT WRITE BATCH NOWAIT     : 15: 0

COMMIT WRITE IMMEDIATE WAIT   : 153: 1000

COMMIT WRITE IMMEDIATE NOWAIT : 20: 0

可以看出

1) COMMIT什么参数都不带, 等于NOWAIT,

2) 参数默认是IMMEDIATE, WAIT

3) BATCH和IMMEDIATE速度差不多(为啥?)

4) WAIT产生等待事件, NOWAIT不产生

5) BATCH+NOWAIT最快, IMMEDIATE+WAIT最慢

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

四、通过参数设置异步提交

新增的系统参数是 COMMIT_WRITE

语法: COMMIT_WRITE = '{IMMEDIATE | BATCH},{WAIT |NOWAIT}'

可以在系统级或会话级设置, ALTER SYSTEM, ALTER SESSION

conn a/a

SET SERVEROUTPUT ON

DECLARE

function get_waits(p_event in varchar2) return number

is

l_waits  NUMBER;

begin

select total_waits

into l_waits

from v$session_event

where event = p_event

and sid = (select sid from v$mystat where rownum=1);

return l_waits;

exception

when no_data_found then return 0;

end;

PROCEDURE do_loop (p_type  IN  VARCHAR2) AS

l_start  NUMBER;

l_loops  NUMBER := 1000;

l_lfs    NUMBER;

BEGIN

if p_type is not null then

EXECUTE IMMEDIATE 'ALTER SESSION SET COMMIT_WRITE=''' || p_type || '''';

end if;

EXECUTE IMMEDIATE 'TRUNCATE TABLE commit_test';

l_lfs := get_waits('log file sync');

l_start := DBMS_UTILITY.get_time;

FOR i IN 1 .. l_loops LOOP

INSERT INTO commit_test (id, description)

VALUES (i, 'Description for ' || i);

COMMIT;

END LOOP;

DBMS_OUTPUT.put_line(RPAD('COMMIT_WRITE=' || p_type, 30)

|| ': ' || (DBMS_UTILITY.get_time - l_start)

|| ': ' || (get_waits('log file sync') - l_lfs)

);

END;

BEGIN

do_loop(NULL);

do_loop('WAIT');

do_loop('NOWAIT');

do_loop('BATCH');

do_loop('IMMEDIATE');

do_loop('BATCH,WAIT');

do_loop('BATCH,NOWAIT');

do_loop('IMMEDIATE,WAIT');

do_loop('IMMEDIATE,NOWAIT');

END;

/

COMMIT_WRITE=                 : 20: 0

COMMIT_WRITE=WAIT             : 151: 1000

COMMIT_WRITE=NOWAIT           : 19: 0

COMMIT_WRITE=BATCH            : 14: 0

COMMIT_WRITE=IMMEDIATE        : 19: 0

COMMIT_WRITE=BATCH,WAIT       : 150: 1000

COMMIT_WRITE=BATCH,NOWAIT     : 15: 0

COMMIT_WRITE=IMMEDIATE,WAIT   : 153: 1000

COMMIT_WRITE=IMMEDIATE,NOWAIT : 20: 0

第因为在第3步设置了NOWAIT, 所以后面第4,5步也继承了这个配置

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

五、PLSQL中的优化

PL/SQL 会自动将其中的 COMMIT 优化成为"COMMIT WRITE NOWAIT", 只有最后一次 COMMIT 才是真正的"COMMIT"

conn a/a

set serveroutput on size unlimited

truncate table commit_test;

select total_waits

from v$session_event

where event = 'log file sync'

and sid = (select sid from v$mystat where rownum=1);

declare

l_loops number := 1000;

begin

FOR i IN 1 .. l_loops LOOP

INSERT INTO commit_test (id, description)

VALUES (i, 'Description for ' || i);

COMMIT;

END LOOP;

end;

/

select total_waits

from v$session_event

where event = 'log file sync'

and sid = (select sid from v$mystat where rownum=1);

TOTAL_WAITS

-----------

1

SQL>   2    3    4    5    6    7    8    9   10

PL/SQL procedure successfully completed.

SQL>   2    3    4

TOTAL_WAITS

-----------

2

只产生了1次等待事件

10gR2版本以前也发现有异步提交, 见The LGWR dilemma

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值