2020年8月31日 星期一

4.8 自動啟動與關閉資料庫

先前介紹過 Oracle 資料庫的啟動與關閉必須進入 sqlplus 執行 startup 或是 shutdown ,在作業系統開機時並不會自動執行這些命令,所以每次主機重新開機之後必須要再手動將資料庫開啟,那麼要如何在主機開機之後自動地將 Oracle 資料庫啟動 ? 如果是 Windows 平台,在資料庫建立好的同時會在 Windows 服務上建立一個 Oracle 服務,隨著主機的開機與關機,這些服務也會自動控制 Oracle 資料庫的啟動與關閉,但是如果是 Unix 平台,在沒有 CRS 服務(RAC或 Oracle Restart)的狀態下,就必須自己寫 script 來設定資料庫的啟動與關閉。


Oracle 資料庫在安裝完成的同時已經在 $ORACLE_HOME/bin 底下幫我們建立好 DB 啟動與關閉的腳本了,分別為 dbstart (開啟 DB) 與 dbshut (關閉 DB),我們只需要在開機與關機的同時呼叫這個腳本就可以協助我們開啟與關閉資料庫了。


dbstart 與 dbshut 會去檢查 /etc/oratab 的內容來決定要開啟與關閉那些資料庫,/etc/oratab 內容裡面有三個區塊分別用 “:” 分開

這三個區塊分別表示 <ORACLE_SID>:<ORACLE_HOME>:<是否開啟>

dbstart / dbshut 會去判斷最後一個區塊是否為 “Y” ,如果為 “Y”,那麼就從指定的 ORACLE_HOME 底下來啟動這個資料庫,如果為 “N” 就表示不啟動這個資料庫。


了解 dbstart 與 dbshut 之後就可以簡單利用它來建立兩個腳本,start_db.sh 與 stop_db.sh 如下:


start_db.sh

ORA_HOME=/opt/app/oracle/product/11.2.0.4/dbhome_1

ORA_OWNER=oracle

su - $ORA_OWNER -c "dbstart $ORA_HOME"


stop_db.sh

ORA_HOME=/opt/app/oracle/product/11.2.0.4/dbhome_1

ORA_OWNER=oracle

su - $ORA_OWNER -c "dbshut $ORA_HOME"


建立完畢後授予執行權限:

# chmod 755 /etc/init.d/start_db.sh

# chmod 755 /etc/init.d/stop_db.sh


接下來我們只需要把它放入啟動程序就可以了,以 Linux 為例,啟動一般為 3或5,關閉一般為0或6,所以把 start_db.sh 放入 rc3.d與rc5.d,stop_db.sh 放入 rc0.d 與 rc6.d:

# cd /etc/rc3.d

# ln -s /etc/init.d/start_db.sh K99STARTDB

# cd /etc/rc5.d

# ln -s /etc/init.d/start_db.sh K99STARTDB

# cd /etc/rc0.d

# ln –s /etc/init.d/stop_db.sh K10STOPDB

# cd /etc/rc6.d

# ln –s /etc/init.d/stop_db.sh K10STOPDB


另一個方式則可以把資料庫啟動與關閉的腳本放入 Linux 服務當中,這樣就不需要自行連結至 run level 了。


首先於 /etc/init.d 建立 dbora 腳本:

#!/bin/sh

# chkconfig: 35 99 10

# description: Oracle auto start-stop script.


ORA_HOME=/opt/app/oracle/product/11.2.0.4/dbhome_1

ORA_OWNER=oracle

case $1 in

'start')

        su - $ORA_OWNER -c "dbstart $ORA_HOME"

        ;;

'stop')

        su - $ORA_OWNER -c "dbshut $ORA_HOME"   

       ;;

esac


前面 chkconfig 是用來設定 run level ,35 表示此服務會在 run level 3與5的時候啟動,在其他 level 的時候關閉;99表示此服務會在最後的順位啟動;10表示此服務會在最前面的順位停止。


接下來將此腳本註冊於 Linux 服務當中就可以了:

# chmod 755 /etc/init.d/dbora

# /sbin/chkconfig --add dbora


如果是 Linux 7 以上的版本,則必須使用 systemctl 來建立服務。首先於 /lib/systemd/system 底下建立 dbora.service ,裡面的內容呼叫我們之前建立的 start_db.sh 與 stop_db.sh:


/lib/system/system/dbora.service

[Unit]

Description=DB Auto Start and Stop

After=syslog.target network.target


[Service]

LimitMEMLOCK=infinity

LimitNOFILE=65535

RemainAfterExit=yes

User=oracle

Group=oinstall

Restart=no

ExecStart=/bin/bash -c '/etc/init.d/start_db.sh'

ExecStop=/bin/bash -c '/etc/init.d/stop_db.sh'


[Install]

WantedBy=multi-user.target


建立好之後再將此服務啟用就可以了:

# systemctl daemon-reload

# systemctl enable dbora.service



2020年8月25日 星期二

4.7 啟動與關閉資料庫

Oracle 資料庫的啟動與關閉必須透過sqlplus來執行,如果是Windows平台,則可以從windows service直接啟動與關閉資料庫。


使用 sqlplus 啟動或關閉資料庫時,必須先設定環境變數 ORACLE_SID,例如在unix 作業系統上要啟動orcl這個資料庫時必須先執行export ORACLE_SID=orcl,然後再進入sqlplus裡面執行startup。


ORACLE_SID代表的是資料庫的instance_name,主要是告訴作業系統說我要啟動哪一個資料庫,然後他會去載入相關的參數檔 (pfile, init<SID>.ora 或是 spfile, spfile<SID>.ora) 進行啟動,如果 ORACLE_SID 與參數檔的設定無誤,那麼資料庫就可以開啟了:

 

資料庫從開始啟動到啟動完成總共會經歷三個階段:

nomount: 開始啟動 instance 並載入參數檔裡面的設定。

mount: 確認controlfile 是否存在並載入 controlfile 的設定。

open: 最後階段,檢查所有 datafile 是否存在,而且所有file的scn是否一致,檢查通過後正常開啟資料庫。

資料庫在開啟的時候可以指定要開啟到哪一個階段:

SQL> startup

     (直接開到 open)

SQL> startup mount

     (開啟到 mount 狀態)

SQL> startup nomount

     (開啟到 nomount 狀態)

SQL> alter database mount;

     (將資料庫從 nomount 開啟到 mount 狀態)

SQL> alter database open;

     (將資料庫從 mount 狀態開啟到 open)


一般來說只有在進行資料庫特殊維護作業的時候才會指定開啟到某一個狀態。在nomount狀態下只有載入參數檔,因此開到nomount可以進行參數的更改、還原(restore) controlfile;在mount狀態下只有載入參數檔與controlfile,可以在這個狀態下進行資料庫的還原(restore/recover)、更改datafile/redo log 的名稱或路徑、進行archive/noarchive 模式的轉換…等。


除此之外,Oracle資料庫還可以開啟到限制模式(restrict) 與唯讀模式(read only):

SQL> startup restrict

     (開啟到限制模式,只有具有 sysdba 權限的使用者可以登入)

SQL> alter database open read only;

     (將資料庫從 mount 狀態開啟到唯讀模式)


關閉資料庫使用的是shutdown 指令,shutdown 後面有四種模式可以選擇:


shutdown normal: 

預設選項,只有執行shutdown則表示為shutdown normal,在此模式下會等待已連接的session全部自行登出後才會進行shutdown動作。一般來說,連接資料庫的使用者來自四面八方,不太可能要求或是等待全部使用者自行登出,因此不太會使用此種模式來關閉資料庫。


shutdown immediate:

最常使用的模式,執行shutdown immediate會強制踢出所有的連線,如果有正在執行的交易會強制rollback後再關閉資料庫。


shutdown abort:

直接關閉資料庫,類似將機器power off的動作,執行shutdown abort之後所有的連線直接踢出,正在執行的交易也是馬上踢出不會進行rollback。因為交易執行到一半突然被中斷掉了,所以在資料庫重新開啟時必須進行recover的動作將未執行完畢的交易進行修復,正常情況下在啟動時SMON會嘗試做Instance recovery 的動作,如果SMON無法成功完成recover,那麼就必須使用備份來還原資料庫了。此種模式下關閉資料庫存在著資料不一致且資料庫無法開啟的風險,因此在非必要的情況下不會使用此模式關閉資料庫。


shutdown transactional:

此種模式會踢出所有的連線,但是正在執行的交易不會強制rollback,會等到所有進行的交易自行結束後才會關閉資料庫。


同樣的,資料庫從開始關閉到關閉完成總共也是會經歷三個階段:

Closed: 關閉資料庫所有正在進行的transaction。

Dismounted: 將資料庫進行卸載,把目前的狀態寫回control file。

Instance shutdown: 完成資料庫的關閉。


如果是使用shutdown abort的話,則不會經過closed與dismounted階段,直接Instance shutdown。


 

不同於startup的是,資料庫在11g之前並不能指定他要關閉到哪一個階段,而在Oracle 11g之後提供了 alter database close 與 alter database dismount 兩個指令,讓資料庫可以關閉到某一個階段:

SQL> alter database close

     (從 open 狀態關閉至 mount 狀態)

SQL> alter database dismount

     (從 mount 狀態關閉至 nomount狀態)


而關閉資料庫的順序是不可逆的,例如執行了alter database close之後就不能再執行 alter database open,只能再 alter database dismount一路的關閉下去。


alter database close 指令並不會強制踢出所有連線,必須所有的資料庫連線自行登出後才有辦法執行 alter database close,因此這個命令的實用性並不高,一般正常關閉資料庫的方式都是直接使用 shutdown immediate 指令。




4.6 Oracle 參數

Oracle 的參數可以分為動態參數與靜態參數兩種。動態參數表示參數可以在線上(也就是資料庫開啟的時候)進行修改並且立即生效,而靜態參數則是修改完必須重啟資料庫才會生效。


不論資料庫是用pfile或是spfile啟動,都可以線上進行動態參數的修改,差別在於如果資料庫啟動時使用的是pfile,那麼動態參數修改的內容不會更新到pfile上面,除非自行再去pfile裡面修改,不然下次再使用pfile重新啟動時這個參數的異動會消失;而使用spfile開啟資料庫的話,動態參數的修改會更新回spfile,下次啟動時參數的異動仍然會保留。


更改動態參數直接使用 alter system set 命令直接修改,例如修改undo_retention參數:

SQL> alter system set undo_retention=1500;


修改動態參數會立即生效:

undo_retention從900修改為1500立即生效。


靜態參數的修改必須重新啟動資料庫後才會生效,因此必須先將參數於pfile或是spfile裡面先修改,然後再重新啟動,若是線上直接修改靜態參數則是會直接報錯:


這個時候必須將參數先修改至spfile裡面,然後再重啟讓參數生效,修改的方法於alter system set 命令再加上scope= 設定:

SQL> alter system set processes=300 scope=spfile;


scope 可以設定的範圍如下:


scope=spfile

 表示將參數異動至spfile裡面但是不生效,必須重啟資料庫後重新讀取spfile才會生效,靜態與動態參數皆可以使用。


scope=memory

 表示參數異動立即生效,但是異動不寫入spfile,重啟之後參數異動會消失,只有動態參數可以使用,


scope=both 

 預設選項,沒有使用 scope 關鍵字時預設就是scope=both,參數異動立即生效並且寫入spfile內,只有動態參數可以使用。


那麼要如何判斷參數是靜態或是動態參數 ? 我們可以從 v$parameter 裡面的 issys_modifiable 欄位來判斷,例如要查詢 sga 相關參數是否為動態參數:


SQL> select name,value,issys_modifiable from v$parameter

        where name like ‘sga%’;

issys_modifiable 顯示為false表示為靜態參數,immediate表示為動態參數,以這個例子來說,sga_max_size為靜態參數、sga_target為動態參數。


不論是靜態參數或動態參數都可以透過pfile直接進行修改,透過文字編輯器開啟一份pfile便可以看到目前所使用的參數:

pfile所使用的格式為 <instance_name>.<parameter> 。 * 號表示此參數在所有instance的設定都一樣,RAC 架構下有可能每個 instance 的參數設定會不一樣,例如undo_tablespace:



設定表示instance ORA111 的 undo_tablespace 為 UNDOTBS1,ORA112的undo_tablespace為UNDOTBS2。


如果要查詢目前參數的設定,除了可以直接從參數檔查詢外,也可以直接在sqlplus裡面使用 ”show parameter + 關鍵字” 這個命令來查閱參數:


SQL> show parameter;

     (列出 DB 所有參數)

SQL> show parameter sga_target;

     (列出 sga_target 這個參數)

SQL> show parameter log_archive;

     (列出所有含 log_archive 關鍵字的參數)


另外有一種特殊的參數是以底線 “_” 開頭的,這些都是資料庫的隱藏參數,一般 show parameter 是不會顯示出這些參數,只有被修改過的隱藏參數才可以用 show parameter 顯示出來,必須透過下列指令查詢所有隱藏參數:

select

x.ksppinm name,

y.ksppstvl value,

y.ksppstdf isdefault,

decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod

from sys.x$ksppi x, sys.x$ksppcv y

where x.indx=y.indx 

order by translate(x.ksppinm,'_','');


同樣的ismod欄位表示隱藏參數是否可以修改後立即生效,或是必須修改完重啟資料庫後生效。ksppinm表示隱藏參數的名稱,例如要查詢 “_gc_read_mostly_locking” 這個隱藏參數則多加入 ksppinm這個條件:


select

x.ksppinm name,

y.ksppstvl value,

y.ksppstdf isdefault,

decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod

from sys.x$ksppi x, sys.x$ksppcv y

where x.indx=y.indx 

  AND x.ksppinm = '_gc_read_mostly_locking'

order by translate(x.ksppinm,'_','');


 

修改隱藏參數的方法與一般參數無異,可以直接寫入pfile或是使用alter system set 命令來設定,差別在於隱藏參數必須使用雙引號 “ 框起來,否則系統無法辨識參數名稱。


一般來說不會特別去修改隱藏參數,大多時候是因為系統出了問題 (例如bug),或是為了禁用資料庫的某些功能才會特別去設定隱藏參數。





4.5 Oracle 參數檔

在啟動 Oracle 資料庫的時候,第一件事情就是先去讀取 Oracle 參數檔裡面的設定,因此在使用 Oracle 資料庫之前必須先了解參數檔。


Oracle 的參數檔可分為 pfile 以及 spfile 兩種,pfile 是文字模式,可以使用文字編輯器(例如 vi, notepad…etc) 來編輯裡面的內容;而 spfile 則是 binary 模式,不可使用文字編輯器進行修改,要修改spfile裡面的內容只能透過資料庫裏面的 alter system set 指令來進行修改。早在Oracle 8i 之前只有pfile一種參數檔,到了Oracle 9i 首次推出spfile格式,直到現在spfile一直是Oracle主要使用的參數檔格式。從Oracle 9i 開始出現了RAC架構,需要一個可以讓多個server共享且可以存放在raw device 的參數檔,因此推出了spfile。


參數檔的位置在Unix系統上預設為 $ORACLE_HOME/dbs 底下,而Windows系統則在 $ORACLE_HOME/database底下。參數檔的檔名格式是固定的,如果不依照指定的格式命名,則資料庫預設不會去讀取這個參數檔,pfile的格式為init<SID>.ora,spfile的格式為spfile<SID>.ora。pfile的存放位置無法更改,資料庫啟動時會去預設的 $ORACLE_HOME/dbs底下讀取pfile,若不想使用預設路徑,則在資料庫啟動的時候可以使用參數 pfile= 來指定 pfile的位置;spfile的路徑則可以更改,只需在init<SID>.ora裡面設定 spfile= 來指定spfile的位置即可,資料庫在啟動時會先去找到 init<SID>.ora,然後從裡面讀取到spfile的位置,再去指定的路徑讀取spfile。若是 RAC 系統,更是可以使用 srvctl modify database –d <db_name> -spfile <spfile location>,將spfile的訊息直接記錄在CRS上面。


既然Oracle有兩種參數檔,那麼資料庫在啟動時就可以選擇使用pfile或是spfile來做啟動,那麼要如何知道此時資料庫使用的是pfile還是spfile ?


透過sqlplus 查詢參數 spfile:


SQL> show parameter spfile;


如果是使用spfile開啟資料庫的,那麼此時參數就會顯示出spfile的路徑:


如果是使用pfile,那麼此時參數顯示為空:


由於spfile只能透過sqlplus使用命令來更改參數,有的時候為了方便起見還是會想要使用文字編輯器來修改參數,因此有了 spfile 與 pfile 之間互相轉換的機制,我們可以將 spfile 轉換為 pfile,然後用文字編輯器修改參數,修改完成後再將pfile轉換回spfile。


將spfile轉換為pfile必須使用sqlplus執行下列指令:

SQL> create pfile from spfile;

     (抓取預設路徑的 spfile 轉換 pfile 產生在預設位置)

SQL> create pfile=’/tmp/initorcl.ora’ from spfile;

     (抓取預設路徑的 spfile 轉換 pfile 到指定的位置)

SQL> create pfile=’/tmp/initorcl.ora’ from spfile=’/tmp/spfileorcl.ora’;

     (指定 pfile 與 spfile 的位置)


同樣的將 pfile 轉換為 spfile 只需要把命令反過來下就可以了:

SQL> create spfile from pfile;

     (抓取預設路徑的 pfile 轉換 spfile 產生在預設位置)

SQL> create spfile=’/tmp/spfileorcl.ora’ from pfile;

     (抓取預設路徑的 pfile 轉換 spfile 到指定的位置)

SQL> create spfile=’/tmp/spfileorcl.ora’ from spfile=’/tmp/initorcl.ora’;

     (指定 spfile 與 pfile 的位置)


執行 pfile 與 spfile 轉換的時候不需要 sqlplus 到一個存在並且 open 的 db 來執行,即便是 Connected to an idle instance. (意即 DB 不存在或沒開啟) 也可以執行這個轉換。


會將pfile與spfile執行轉換的情境大多是在測試參數異動的影響,為了不影響spfile的內容,會先將其轉變為pfile並更改參數,然後先用此pfile開啟資料庫驗證參數的正確性與影響,確認完畢後再將參數更新回spfile。


而另一種情境則是參數修改不當導致DB無法使用spfile開啟,例如修改SGA過大導致DB無法開啟,因為DB無法開啟所以也無法使用 alter system set 的命令來更正spfile的內容,此時就需要將spfile轉換為pfile,然後使用文字編輯器將pfile裡面錯誤的參數進行修正,修正完畢後再轉換回spfile。


參數檔是Oracle資料庫的基礎,在使用資料庫之前必須先熟悉參數檔。