RESTRICT、QUIESCE和SUSPEND(二)

yangtingkun發表於2009-04-23

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

這一篇介紹QUIESCE狀態。

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

 

 

當資料庫處於QUIESCE狀態時,只有DBA會話可以進行操作,而普通會話會處於等待狀態,只有當資料庫退出QUIESCE狀態,普通會話才能繼續操作。

QUIESCE似乎和RESTRICT很相似,都是修改資料庫的狀態,使得DBA使用者可以進行管理操作,避免非DBA使用者同時訪問。但是二者還是有明顯的區別的。首先RESTRICT是禁止普通使用者登陸,而對已經登陸的使用者無能為力。如果要徹底禁止普通使用者的訪問,就必須透過重啟或者手工判斷已經連線的普通會話,並執行KILL SESSION的操作。而QUIESCE並不是這樣,透過設定系統的QUIESCE RESTRICTED,使得所有的非DBA使用者處於等待狀態,不管是新登陸的還是已經存在的普通使用者會話,都無法執行新的操作,直到系統退出QUIESCE狀態。

因此QUIESCE狀態對於7*24環境是十分有幫助的,對於其他使用者而言,只是操作的等待時間變得很長,而並不會報錯。當然QUIESCERESTRICT所沒有的優點,也必然有一些額外的要求,那就是資料庫必須配置了資源管理Resource Management

[oracle@bjtest ~]$ sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on 星期三 4 22 00:25:59 2009

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


連線到:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production

SQL> show parameter resource

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
enqueue_resources                    integer     3144
resource_limit                       boolean     FALSE
resource_manager_plan                string
SQL> alter system quiesce restricted;
alter system quiesce restricted
*
ERROR
位於第 1 :
ORA-25507:
沒有使資源管理器一直處於開啟狀態

如果資源管理器沒有開啟,在9i中就會出現上面的ORA-25507錯誤。

bash-2.03$ sqlplus "/ as sysdba"

SQL*Plus: Release 10.2.0.3.0 - Production on 星期五 2 20 00:30:49 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> show parameter resource

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
resource_limit                       boolean     FALSE
resource_manager_plan                string
SQL> alter system quiesce restricted;

系統已更改。

而從10g開始,這個限制已經被取消了。

如果是9i,那麼必須設定resource_limit引數為true,並設定resource_manager_plan引數指向一個資源計劃:

SQL> alter system set resource_limit = true;

系統已更改。

SQL> select plan from dba_rsrc_plans;                   

PLAN
------------------------------
SYSTEM_PLAN
INTERNAL_QUIESCE
INTERNAL_PLAN

SQL> alter system set resource_manager_plan = system_plan;

系統已更改。

SQL> alter system quiesce restricted;
alter system quiesce restricted
*
ERROR
位於第 1 :
ORA-25507:
沒有使資源管理器一直處於開啟狀態


SQL> shutdown immediate
資料庫已經關閉。
已經解除安裝資料庫。
ORACLE
例程已經關閉。
SQL> startup
ORACLE
例程已經啟動。

Total System Global Area 9432971568 bytes
Fixed Size                   756016 bytes
Variable Size             838860800 bytes
Database Buffers         8589934592 bytes
Redo Buffers                3420160 bytes
資料庫裝載完畢。
資料庫已經開啟。
SQL> show parameter resource

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
enqueue_resources                    integer     3144
resource_limit                       boolean     TRUE
resource_manager_plan                string      SYSTEM_PLAN
SQL> alter system quiesce restricted;

系統已更改。

雖然修改RESOURCE_LIMITRESOURCE_MANAGER_PLAN引數不需要重啟資料庫,但是QUIESCE狀態的修改要求資料庫例項必須自啟動以來資源管理器一直處於開啟的狀態,因此必須重啟資料庫。

當資料庫置於QUIESCE狀態下,普通使用者的新連線將處於等待狀態:

SQL> conn test/test

只有當系統撤銷QUIESCE狀態,使用者才能登陸到資料庫:

SQL> alter system unquiesce;

系統已更改。

這時TEST使用者登陸成功:

已連線。
SQL> select * from session_roles;

ROLE
------------------------------
CONNECT
RESOURCE
DBA
SELECT_CATALOG_ROLE
HS_ADMIN_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
EXP_FULL_DATABASE
IMP_FULL_DATABASE
GATHER_SYSTEM_STATISTICS
WM_ADMIN_ROLE
JAVA_ADMIN
JAVA_DEPLOY
XDBADMIN
OLAP_DBA
PLUSTRACE

已選擇16行。

SQL> show user
USER
"TEST"
SQL> SET SQLP 'SQL2> '
SQL2> SELECT * FROM DUAL;

D
-
X

可以看到,和文件描述的一樣,對於TEST使用者而言,即使擁有了DBA角色,也被QUIESCE狀態所禁止,而只有SYSSYSTEM使用者可以對資料庫進行管理操作。

下面再次將資料庫置於QUIESCE狀態,看看對QUIESCE對已經登陸的會話是否有效:

SQL> alter system quiesce restricted;

系統已更改。

檢查第2個會話:

SQL2> SELECT * FROM DUAL;

這個會話在執行操作的時候同樣被HANG住,處於等待狀態:

SQL> select sid from v$session
  2  where sql_address in
  3  (select address from v$sql         
  4  where sql_text = 'SELECT * FROM DUAL');

       SID
----------
        17

SQL> select sid, event from v$session_wait
  2  where sid = 17;

       SID EVENT
---------- ----------------------------------------------------------------
        17 resmgr:waiting in run (queued)

可以看到,會話2在等待執行,而這個事件是資源管理器所觸發的。

SQL> alter system unquiesce;

系統已更改。

再次解除QUIESCE狀態,下面看看QUIESCE對執行中操作的影響:


D
-
X

SQL2> begin
  2  dbms_lock.sleep(300);
  3  end;
  4  /

在會話2中執行一個5分鐘長的等待事務,然後在會話1執行ALTER SYSTEM QUIESCE RESTRICTED命令:

SQL> alter system quiesce restricted;

這次QUIESCE命令也進入等待狀態,這說明QUIESCE命令會等待所有的當前操作結束,並禁止所有新的操作執行。

這也是QUIESCERESTRICT的差別之一,QUIESCE對所有的會話有效,而RESTRICT只對新連線的會話生效,對已經連線的會話無效。

最後還是看一下QUIESCERAC環境中是如何工作的。

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

隨後在例項1上發出ALTER SYSTEM QUIESCE RESTRICTED語句,檢查這個操作對例項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 01:28:39 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 quiesce restricted;

系統已更改。

SQL> select instance_name from v$instance;

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

使用普通使用者連線例項1

SQL> CONN TEST/TEST@TESTRAC1

連線被掛起,下面連線例項2

SQL> CONN TEST/TEST@TESTRAC2

例項2的連線也被掛起,看來QUIESCE會傳播到RAC環境的其他例項,那麼對於新啟動的資料庫例項是否有效呢:

SQL> host
$ srvctl start inst -d testrac -i testrac3
PRKP-1001 : Error starting instance testrac3 on node racnode3
CRS-0215: ???????????? 'ora.testrac.testrac3.inst'??

利用SVRCTL命令啟動例項3居然失敗了,下面登陸例項3所在節點,透過SQLPLUS啟動資料庫:

$ sqlplus "/ as sysdba"

SQL*Plus: Release 10.2.0.3.0 - Production on 星期二 4 21 17:44:33 2009

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

已連線到空閒例程。

SQL> startup
ORACLE
例程已經啟動。

Total System Global Area 2147483648 bytes
Fixed Size                  2031480 bytes
Variable Size             385876104 bytes
Database Buffers         1744830464 bytes
Redo Buffers               14745600 bytes
資料庫裝載完畢。
ORA-25503:
無法開啟資料庫, 因為資料庫正在被靜默

錯誤已經很明顯了,雖然執行QUIESCE命令是ALTER SYSTEM語句,但是顯然QUIESCE命令對整個資料庫都是生效的,且RAC的其他例項是無法在QUIESCE狀態下啟動的。

$ exit

SQL> select instance_name, status, active_state from gv$instance;

INSTANCE_NAME    STATUS       ACTIVE_ST
---------------- ------------ ---------
testrac1         OPEN         QUIESCED
testrac3         MOUNTED      NORMAL
testrac2         OPEN         QUIESCED

可以透過V$INSTANCEACTIVE_STATE列檢視資料庫的QUIESCE狀態。

SQL> CONN SYS@TESTRAC2 AS SYSDBA
輸入口令:
已連線。
SQL> ALTER SYSTEM UNQUIESCE;

系統已更改。

SQL> SELECT INSTANCE_NAME, STATUS, ACTIVE_STATE FROM GV$INSTANCE;

INSTANCE_NAME    STATUS       ACTIVE_ST
---------------- ------------ ---------
testrac2         OPEN         NORMAL
testrac1         OPEN         NORMAL
testrac3         MOUNTED      NORMAL

SQL> SELECT INSTANCE_NAME FROM V$INSTANCE;

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

既然QUIESCE對於每個例項都生效,那麼UNQUIESCE操作也可以在任意一個例項上執行。

 

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

相關文章