免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
深入解析:Oracle由11g而始的數(shù)據(jù)庫一致讀行為的改變


崔華,網(wǎng)名 dbsnake

Oracle ACE Director,ACOUG 核心專家

編輯手記:感謝崔華授權(quán)我們獨家轉(zhuǎn)載其精品文章,也歡迎大家向“Oracle”社區(qū)投稿。

我們都知道,在Oracle數(shù)據(jù)庫中是commit的數(shù)據(jù)我們讀不到,commit后的數(shù)據(jù)我們也不一定能馬上讀到,這其中的后者當然是因為Oracle數(shù)據(jù)庫中久負盛名的一致讀行為的存在。

但從Oracle 11g開始,Oracle更改了在某些特定條件一致讀的行為,這使得一些看起來不合常理的行為在Oracle 11g以及后續(xù)的版本中得以出現(xiàn),即在Oracle 11g以及后續(xù)的版本中,當滿足一定的條件時,我們就可以馬上讀到commit后的數(shù)據(jù),而不再存在以前的那種一致讀的行為。

Oracle將這種改動稱為“RowCR Optimization”Oracle簡單的描述了什么是RowCR OptimizationA brief overview of this optimization is that we try to avoid rollbacks while constructing a CR block if the present block has no uncommitted changes.這里的avoid rollback,意味著在滿足特定的條件時,Oracle就不做一致讀了。

RowCR Optimization通過隱含參數(shù)“_row_cr”來控制,但遺憾的是,Oracle11g及其后續(xù)的版本中將這個參數(shù)的默認值改成了TRUE,這意味著上述這種在滿足特定的條件時,Oracle就不做一致讀的行為在Oracle 11g及其后續(xù)的版本中在默認情況下就已經(jīng)被開啟了,這也許有些激進。國內(nèi)的某銀行在升級到Oracle 11g后就出現(xiàn)了一致讀的問題,在這次的CAB技術(shù)峰會上,Oracle負責(zé)高可用性研發(fā)的VP Wei Hu承認:我們在默認情況下開啟了RowCR Optimization,這也許是不恰當?shù)摹?/span>

說了這么多背景,我們現(xiàn)在來看一個RowCR Optimization的實例:

這里用的Oracle數(shù)據(jù)庫版本為11.2.0.1,我們在其中創(chuàng)建了如下的存儲過程p_demo_cr_read_change

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0

Connected as scott

SQL> create or replace procedure p_demo_cr_read_change is

  2    cursor c1 is select * from emp where empno=7369;

  3    employee_rec emp%rowtype;

  4  begin

  5    open c1;

  6    dbms_lock.sleep(60);

  7 

  8    fetch c1 into employee_rec;

  9    while (c1%found) loop

 10 

 11       dbms_output.put_line(’employee id: ‘ || employee_rec.empno);

 12       dbms_output.put_line(’employee name: ‘ || employee_rec.ename);

 13 

 14      fetch c1 into employee_rec;

 15    end loop;

 16    close c1;

 17  end p_demo_cr_read_change;

 18  /

Procedure created

上述存儲過程針對的是SCOTT用戶下的表EMP,在列EMPNO上存在一個名為PK_EMP的主鍵:

SQL> select dbms_metadata.get_ddl(‘TABLE’,’EMP’,’SCOTT’) from dual;

  CREATE TABLE “SCOTT”.”EMP”

   (       “EMPNO” NUMBER(4,0),

            “ENAME” VARCHAR2(10),

            ……省略顯示部分內(nèi)容

            “DEPTNO” NUMBER(2,0),

             CONSTRAINT “PK_EMP” PRIMARY KEY (“EMPNO”)

  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS

 ……省略顯示部分內(nèi)容

FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE “USERS”

現(xiàn)在表EMPempno=7369的記錄所對應(yīng)的ename列的值是“SMITH”:

SQL> select empno,ename from emp where empno=7369;

EMPNO ENAME

—–    ———-

 7369  SMITH

我們現(xiàn)在開啟兩個Session,分別為Session 1Session 2,在Session 1中執(zhí)行上述存儲過程p_demo_cr_read_change,同時在Session 2中利用Session 1的存儲過程p_demo_cr_read_changeopen c1fetch之間間隔的那60秒緩沖時間對表EMPempno=7369的記錄做修改操作,即在這60秒緩沖時間內(nèi)將表EMPempno=7369的記錄所對應(yīng)的ename列的值從“SMITH”改為“CUIHUA”并commit,這樣通過觀察Session 1中存儲過程p_demo_cr_read_change最后的輸出結(jié)果即可驗證RowCR Optimization的行為,具體來說就是如下這樣:

1、Session 1中的最終輸出結(jié)果如果是“SMITH”,則說明發(fā)生了常規(guī)的一致讀,沒有做RowCR Optimization;

2、Session 1中的最終輸出結(jié)果如果是“CUIHUA”,則說明已經(jīng)做了RowCR Optimization,沒有做常規(guī)的一致讀;

現(xiàn)在我們來實際測試一下,在Session 1中執(zhí)行p_demo_cr_read_change

Session 1

SQL> set serveroutput on

SQL> exec p_demo_cr_read_change

……這里會等待60秒,然后才會顯示輸出結(jié)果

然后在60秒的緩沖時間段內(nèi)去Session 2中做如下修改操作:

Session 2

SQL> update emp set ename=’CUIHUA’ where empno=7369;

1 row updated

SQL> commit;

Commit complete

SQL> select empno,ename from emp where empno=7369;

EMPNO ENAME

—–    ———-

 7369  CUIHUA

等過了60秒的緩沖時間后,我們再回到Session 1,此時看到了如下輸出結(jié)果:

Session 1

SQL> exec p_demo_cr_read_change

employee id: 7369

employee name: CUIHUA

PL/SQL procedure successfully completed

上述Session 1的最終輸出結(jié)果顯示Oracle此時確實沒有做常規(guī)的一致讀,而是馬上讀到了commit后的數(shù)據(jù),即此時已經(jīng)發(fā)生了RowCR Optimization。

我們現(xiàn)在去Session 2中把表EMPempno=7369的記錄所對應(yīng)的ename列的值恢復(fù)成原先的“SMITH”并且drop掉表EMP上的主鍵PK_EMP

Session 2

SQL> update emp set ename=’SMITH’ where empno=7369;

1 row updated

SQL> commit;

Commit complete

SQL> select empno,ename from emp where empno=7369;

EMPNO ENAME

—–    ———-

 7369  SMITH

SQL> alter table emp drop constraint pk_emp;

Table altered

然后我們再次以同樣的方法重復(fù)之前測試RowCR Optimization的過程, Session 1的最終輸出結(jié)果為如下所示:

Session 1

SQL> exec p_demo_cr_read_change

employee id: 7369

employee name: SMITH

PL/SQL procedure successfully completed

    上述Session 1的最終輸出結(jié)果顯示Oracle此時并沒有做RowCR Optimization,即并沒有馬上讀到commit后的數(shù)據(jù),這說明當我們把列empno上的主鍵drop掉后(即dropempno上的唯一性索引后),Oracle并沒有做RowCR Optimization,而是做了常規(guī)的一致讀。

我們現(xiàn)在去Session 2中把表EMPempno=7369的記錄所對應(yīng)的ename列的值恢復(fù)成原先的“SMITH”并且在列empno上創(chuàng)建一個名為idx_emp_empno的非唯一性索引:

Session 2

……這里省略將ename列的值恢復(fù)成原先的“SMITH”的過程

SQL> create index idx_emp_empno on emp(empno);

Index created

然后我們再次以同樣的方法重復(fù)之前測試RowCR Optimization的過程, Session 1的最終輸出結(jié)果為如下所示:

Session 1

SQL> exec p_demo_cr_read_change

employee id: 7369

employee name: SMITH

PL/SQL procedure successfully completed

   上述Session 1的最終輸出結(jié)果顯示Oracle此時也沒有做RowCR Optimization,即并沒有馬上讀到commit后的數(shù)據(jù),這說明即使列empno上存在非唯一性索引,Oracle也沒有做RowCR Optimization,而是做了常規(guī)的一致讀。

我們現(xiàn)在去Session 2中把表EMPempno=7369的記錄所對應(yīng)的ename列的值恢復(fù)成原先的“SMITH”并且在列empno上創(chuàng)建一個名為idx_uk_emp_empno的唯一性索引:

Session 2

……這里省略將ename列的值恢復(fù)成原先的“SMITH”的過程

SQL> drop index idx_emp_empno;

Index dropped

SQL> create unique index idx_uk_emp_empno on emp(empno);

Index created

然后我們再次以同樣的方法重復(fù)之前測試RowCR Optimization的過程, Session 1的最終輸出結(jié)果為如下所示:

Session 1

SQL> exec p_demo_cr_read_change

employee id: 7369

employee name: CUIHUA

PL/SQL procedure successfully completed

   上述Session 1的最終輸出結(jié)果顯示Oracle此時沒有做常規(guī)的一致讀,而是馬上讀到了commit后的數(shù)據(jù),即在列empno存在唯一性索引的情形下,Oracle選擇做了RowCR Optimization

我們現(xiàn)在去Session 2中把表EMPempno=7369的記錄所對應(yīng)的ename列的值恢復(fù)成原先的“SMITH”并且將隱含參數(shù)“_row_cr”的值改為FALSE

Session 2

……這里省略將ename列的值恢復(fù)成原先的“SMITH”的過程

SQL> alter system set “_row_cr” = false scope=both;

System altered

SQL> select name,value from sys.all_parameters where name like ‘_row_cr%’;

NAME                 VALUE

——————–   ——————–

_row_cr               FALSE

然后我們再次以同樣的方法重復(fù)之前測試RowCR Optimization的過程, Session 1的最終輸出結(jié)果為如下所示:

Session 1

SQL> exec p_demo_cr_read_change

employee id: 7369

employee name: SMITH

PL/SQL procedure successfully completed

上述Session 1的最終輸出結(jié)果顯示即使列empno上存在唯一性索引,Oracle此時也沒有做RowCR Optimization,即并沒有馬上讀到commit后的數(shù)據(jù),這說明隱含參數(shù)“_row_cr”確實能控制RowCR Optimization的開啟與否。

Oracle在描述RowCR Optimization時曾經(jīng)提到其生效的前提條件為:A brief overview of this optimization is that we try to avoid rollbacks while constructing a CR block if the present block has no uncommitted changes.

但經(jīng)過我們測試,上述這種說法是不嚴謹?shù)模?/span>

測試過程為如下所示:

我們現(xiàn)在去Session 2中把表EMPempno=7369的記錄所對應(yīng)的ename列的值恢復(fù)成原先的“SMITH”并且將隱含參數(shù)“_row_cr”的值改為TRUE

Session 2

……這里省略將ename列的值恢復(fù)成原先的“SMITH”的過程

SQL> alter system set “_row_cr” = true scope=both;

System altered

SQL> select name,value from sys.all_parameters where name like ‘_row_cr%’;

NAME                 VALUE

——————–   ——————–

_row_cr                TRUE

從如下查詢結(jié)果中我們可以看到,表EMP13條記錄全部在datafile 4,block 151這個數(shù)據(jù)塊中:

SQL> select empno, ename, dbms_rowid.rowid_relative_fno(rowid) || ‘_’ || dbms_rowid.rowid_block_number(rowid) location from emp;

EMPNO ENAME      LOCATION

—– ———- ——————–

 7369 SMITH      4_151

 7499 ALLEN      4_151

 7521 WARD       4_151

 7566 JONES      4_151

 7654 MARTIN     4_151

 7698 BLAKE      4_151

 7782 CLARK      4_151

 7788 SCOTT      4_151

 7844 TURNER     4_151

 7876 ADAMS      4_151

 7900 JAMES      4_151

 7902 FORD       4_151

 7934 MILLER     4_151

13 rows selected

然后我們再次以同樣的方法重復(fù)之前測試RowCR Optimization的過程,只不過這一次在Session 2中做了如下的修改操作(即構(gòu)造了datafile 4,block 151這個數(shù)據(jù)塊存在未commit數(shù)據(jù)的情形):

Session 2

SQL> update emp set ename=’CUIHUA’ where empno=7369;

1 row updated

SQL> commit;

Commit complete

SQL> select empno,ename from emp where empno=7369;

EMPNO ENAME

——-   ———-

7369  CUIHUA

SQL> update emp set ename=’CUIHUA1′ where empno=7499;

1 row updated

等過了60秒的緩沖時間后,我們再回到Session 1,此時看到了如下輸出結(jié)果:

Session 1

SQL> exec p_demo_cr_read_change

employee id: 7369

employee name: CUIHUA

PL/SQL procedure successfully completed

上述Session 1的最終輸出結(jié)果顯示Oracle此時沒有做常規(guī)的一致讀,而是馬上讀到了commit后的數(shù)據(jù),即在被訪問的數(shù)據(jù)塊存在未commit的數(shù)據(jù)的情形下也依然發(fā)生了RowCR Optimization。

最后,我們來總結(jié)一下,從上述測試過程我們可以得到如下結(jié)論:

Oracle 11g以及后續(xù)的版本中,默認情況下(即隱含參數(shù)“_row_cr”的值為TRUE的情況下),如果是通過唯一性索引去訪問數(shù)據(jù),則我們就可以馬上讀到commit后的數(shù)據(jù),而不再存在以前的那種一致讀的行為。

如何加入"云和恩墨大講堂"微信群
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
oracle for update和for update nowait的區(qū)別
Oracle PL/SQL開發(fā)基礎(chǔ)(第七彈:ROWNUM偽列)
oracle的基本查詢
數(shù)據(jù)庫技術(shù)-oracle的優(yōu)化(同樣適用于其他數(shù)據(jù)庫)
ORACLE數(shù)據(jù)庫PROC編程經(jīng)驗介紹
Oracle 10g的使用【SQLPLUS操作大全】
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服