RESTRICT、QUIESCE和SUSPEND(三)

yangtingkun發表於2009-04-24

資料庫的這三種狀態有相似之處,這裡簡單總結一下。

這一篇介紹SYSPEND狀態。

RESTRICTQUIESCESUSPEND(一): http://yangtingkun.itpub.net/post/468/483100

RESTRICTQUIESCESUSPEND(二):http://yangtingkun.itpub.net/post/468/483165

 

 

RESTRICT限制的是沒有RESTRICTED SESSION許可權的使用者,使得這些使用者無法登陸資料庫。而QUIESCE針對所有的非SYSSYSTEM使用者,禁止這個使用者的任何新的操作,包括登陸、查詢、DML等等。和RESTRICTQUIESCE不同的是,SUSPEND主要是限制資料庫IO操作的。而且SUSPEND限制的不僅僅是普通使用者,而是資料庫中任何的使用者。

SQL> alter system suspend;

系統已更改。

在另一個終端上執行:

SQL> SET SQLP 'SQL2> '
SQL2> conn test/test
已連線。
SQL2> conn / as sysdba
已連線。
SQL2> select * from dual;

DU
--
X

SQL2> conn test/test
已連線。
SQL2> select * from dual;

DU
--
X

SQL2> select count(*) from t;

由於資料庫已經執行了一段時間,很多資料都在快取之中,因此無論是DBA使用者,還是普通使用者,都可以正常登陸,且都可以執行查詢操作,只要結果可以在CACHE中找到,不引起物理IO,就不會被阻塞,直到查詢引發了物理IO操作,導致會話被掛起。

SQL> alter system resume;

系統已更改。

直到執行了RESUME命令,被掛起的操作恢復執行:


  COUNT(*)
----------
     54020

SQL2> select * from session_roles;

ROLE
------------------------------------------------------------
CONNECT
RESOURCE

下面再次將資料庫置於SUSPEND狀態:

SQL> alter system suspend;

系統已更改。

執行剛才被阻塞的SQLSELECT COUNT(*) FROM T

SQL2> select count(*) from t;

  COUNT(*)
----------
     54020

SQL2> delete t;

由於CACHE快取的作用,這次查詢T表所有的IO都是邏輯IO,不會導致物理IO的產生,因此上一次被阻塞的操作,這次可以順利執行,不過隨後的DELETE操作由於要產生物理IO,因此被阻塞了。

SQL> alter system resume;

系統已更改。

執行RESUME後,DELETE操作完成:


已刪除54020行。

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

       SID
----------
       155

查詢V$SESSION_WAIT的資訊,並將資料庫再次置於SYSPEND狀態:

SQL> select event from v$session_wait where sid = 155;

EVENT
--------------------------------------------------------------------------------
SQL*Net message from client

SQL> alter system suspend;

系統已更改。

在會話2執行ROLLBACK操作:

SQL2> rollback;

由於ROLLBACK會導致物理IO,會話被阻塞,下面回到會話1,檢查會話2的等待事件:

SQL> select event from v$session_wait where sid = 155;

EVENT
--------------------------------------------------------------------------------
writes stopped by instance recovery or database suspension

這是寫操作被阻塞時,會話的等待事件,這個事件的名稱已經很清楚的說明了問題。

最後還是看看RAC環境下SUSPEND對不同例項的影響。

依舊是在一個三節點的RAC環境中進行測試,其中兩個節點處於啟動狀態,另一個節點關閉。

隨後在例項1上發出ALTER SYSTEM SUSPEN語句,檢查這個操作對例項2是否生效,將例項3啟動,檢查這個限制新啟動的例項3是否有效。

bash-2.03$ srvctl status db -d testrac
Instance testrac1 is running on node racnode1
Instance testrac2 is running on node racnode2
Instance testrac3 is running on node racnode3
bash-2.03$ srvctl stop inst -d testrac -i testrac3
bash-2.03$ srvctl status db -d testrac
Instance testrac1 is running on node racnode1
Instance testrac2 is running on node racnode2
Instance testrac3 is not running on node racnode3
bash-2.03$ sqlplus "/ as sysdba"

SQL*Plus: Release 10.2.0.3.0 - Production on 星期五 2 20 19:17:04 2009

Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.


連線到:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, Real Application Clusters, OLAP and Data Mining options

SQL> alter system suspend;

系統已更改。

SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
testrac1

現在檢查例項2上是否也會產生禁止物理IO的產生:

SQL> conn test/test@testrac2
已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
testrac2

SQL> select * from tab;

顯然例項2上的操作被阻塞了,現在啟動例項3,看看例項3上是否也會阻塞物理IO操作:

SQL> host
$ srvctl start inst -d testrac -i testrac3

SVRCTL命令居然也被HANG住了,那麼SUSPEND是否和QUIESCE一樣,禁止沒有啟動的例項啟動呢,透過sqlplus直接連線例項3

$ sqlplus /nolog

SQL*Plus: Release 10.2.0.3.0 - Production on 星期五 2 20 19:23:02 2009

Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.

SQL> conn sys@testrac3 as sysdba
輸入口令:
已連線。
SQL> select instance_name from v$instance;

INSTANCE_NAME
----------------
testrac3

SQL> conn test/test@testrac3
ERROR:
ORA-01033: ORACLE initialization or shutdown in progress


警告: 您不再連線到 ORACLE

可以看到,資料庫還沒有完全被開啟,就處於被阻塞狀態了。

登陸例項3

SQL> conn sys@testrac3 as sysdba
輸入口令:
已連線。
SQL> select instance_name, status, database_status from v$instance;

INSTANCE_NAME    STATUS       DATABASE_STATUS
---------------- ------------ -----------------
testrac3         STARTED      ACTIVE

SQL> conn sys@testrac1 as sysdba
輸入口令:
已連線。
SQL> select instance_name, status, database_status from v$instance;

INSTANCE_NAME    STATUS       DATABASE_STATUS
---------------- ------------ -----------------
testrac1         OPEN         SUSPENDED

SQL> conn sys@testrac2 as sysdba
輸入口令:
已連線。
SQL> select instance_name, status, database_status from v$instance;

INSTANCE_NAME    STATUS       DATABASE_STATUS
---------------- ------------ -----------------
testrac2         OPEN         SUSPENDED

顯然SUSPEND對所有當前執行的RAC例項生效,而新啟動的例項,資料庫狀態並非SUSPEND,而是ACTIVE,但是和文件描述不同的是,這個例項根本無法成功的啟動,從這一點上將,SUSPEND還是會對整個資料庫起作用的。

同樣在例項1和例項2上,都可以執行RESUME命令,來恢復資料庫狀態:

SQL> conn sys@testrac2 as sysdba
輸入口令:
已連線。
SQL> alter system resume;

系統已更改。

 

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-591752/,如需轉載,請註明出處,否則將追究法律責任。

相關文章