天天看點

《循序漸進Oracle:資料庫管理、優化與備份恢複》一一1.3 資料庫建立的腳本

本節書摘來自異步社群出版社《循序漸進oracle:資料庫管理、優化與備份恢複》一書中的第1章,第1.3節,作者:蓋國強,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

循序漸進oracle:資料庫管理、優化與備份恢複

在dbca的最後一個步驟,如果儲存生成了建立資料庫的腳本,則可以通過手工執行這些腳本,在指令行完成資料庫的建立工作,這可以使我們擺脫圖形界面的困擾,特别是在一些不易于運作圖形界面的環境。此外,很多時候通過dbca建立資料庫可能會遇到一些錯誤,這些錯誤在圖形界面下可能不易判斷,但是通過指令行則要容易定位得多。

現在通過資料庫的建立腳本來深入地了解一下資料庫的建立過程。按照上面的路徑找到生成的資料庫建立腳本。

在linux/unix環境下,同樣存在這樣一系列的腳本:

如果通過手工執行腳本來建立資料庫,需要執行的腳本為eygle.bat(在linux/unix下是eygle.sh腳本),來看一下這個腳本的内容:

這就是oracle建立資料庫的過程。

(1)建立一系列的目錄。

注意,這裡建立的bdump目錄是oracle重要的警告日志的存放地點,其預設名稱為alert_< sid >.log,我們應該定期檢查該檔案以發現資料庫的故障或錯誤資訊;在oracle database 11g中,這些檔案的統一路徑由參數diagnostic_dest定義。

第二個需要格外注意的是cfgtoollogsdbcaeygle目錄,在建立資料庫時,主要的日志檔案或輸出資訊會記錄在該目錄中,通過檢查這些檔案可以用來診斷建立過程中出現的一些錯誤。

(2)設定oracle_sid環境變量。

(3)通過oradim建立并配置執行個體。

(4)通過sqlplus運作腳本開始建立資料庫。

oradim工具是oracle在windows上的一個指令行工具,用于手工進行oracle服務的建立、修改、删除等工作。oradim的使用很簡單,通過幫助檔案可以看到常用的指令示例,此處不再贅述。

oradim在資料庫恢複中也常被用到,很多朋友都問過這樣的問題:在windows上,如果系統崩潰了,可能資料庫軟體丢掉了,但是資料檔案、控制檔案、日志檔案等都還在,該怎樣來恢複oracle資料庫?

其實過程很簡單,通常隻要按原來的目錄結構重新安裝oracle軟體,然後通過oradim工具重建服務,就可以啟動執行個體、加載資料庫(當然,相關的參數檔案和密碼檔案等需要儲存在$oracle_homedatabase目錄中)。

來看以下過程,通過oradim建立一個服務後,執行個體會随之啟動:

用net指令可以檢視系統啟動了哪些服務,看到oracle的服務已經啟動:

如果你的系統裝了一些unix增強工具(強烈建議在windows上安裝unix增強工具集,熟悉常用unix指令),那麼可以通過grep過濾一下:

使用oradim工具後,會在$oracle_homedatabase目錄下生成一個日志檔案。

注意到在oradim建立服務之前,首先設定了oracle_sid:

在linux/unix系統的建立中,同樣要設定oracle_sid,不過linux/unix上不存在服務這項内容,執行個體是可以通過參數檔案直接啟動的(注意:啟動資料庫執行個體還和一些核心參數有關,在産品環境中需要按手冊認真設定)。

看一下linux上正常情況下啟動到nomount狀态的過程:

注意這裡,oracle根據參數檔案的内容,建立了instance,配置設定了相應的記憶體區域,啟動了一組背景程序。

回顧一下前面的内容,注意到sid和oracle_sid已經多次出現,那麼sid是什麼?在資料庫啟動過程中又起到什麼作用呢?

sid是system identifier的縮寫,而oracle_sid就是oracle system identifier的縮寫,在oracle系統中,oracle_sid以環境變量的形式出現,在特定版本的oracle軟體安裝(也就是oracle_home)下,當oracle執行個體啟動時,作業系統上fork的程序必須通過這個sid将執行個體與其他執行個體區分開來,這就是sid的作用。

我們知道oracle的執行個體(instance)是由一塊共享記憶體區域(sga)和一組背景程序(background processes)共同組成;而背景程序正是資料庫和作業系統進行互動的通道,這些程序的名稱就是通過oracle_sid決定的。

執行個體的啟動僅需要一個參數檔案,而這個參數檔案的名稱就是由oracle_sid決定的。對于init檔案,預設的檔案名稱是init< oracle_sid >.ora,對于spfile檔案,預設的檔案名為spfile< oracle_sid >.ora,oracle依據oracle_sid來決定和尋找參數檔案啟動執行個體,參數檔案的預設位置為$oracle_home/dbs(windows上為$oracle_homedatabase目錄)。

spfile從oracle 9i開始引入并成為了預設使用的參數檔案,oracle啟動執行個體時按照以下順序從預設目錄查找參數檔案:

spfile.ora→spfile.ora →init.ora。

如果這3個檔案都不存在,則oracle執行個體将無法啟動。

通過這些資訊可以知道,在同一個oracle_home下,oracle能夠根據oracle_sid将執行個體區分開來;但是如果在不同的oracle_home下,oracle将不屏蔽相同名稱的oracle_sid,也就是說在同一台主機的不同oracle_home下,oracle也是能夠建立相同oracle_sid的執行個體的。

以下是一個測試。首先啟動一個oracle 8i下oracle_sid為eygle的執行個體:

接下來又可以啟動另外oracle_home下oracle_sid為eygle的執行個體:

現在這同一台主機上就啟動了兩個相同名稱的執行個體,在作業系統上,oracle能夠通過id辨別将共享記憶體或信号量區分開來:

通過oracle提供的一個小工具sysresv,我們可以找到對應于不同的oracle_sid,作業系統上建立的共享記憶體段id(shared memory)和信号量id(semaphores)等資訊。

在linux/unix上,一個名為oratab的檔案還記錄有oracle_sid資訊。在solaris環境中,這個檔案一般位于/var/opt/oracle目錄下,在linux及其他unix平台,這個檔案一般位于/etc目錄下。

該檔案的主要内容如下:

當執行dbstart腳本時,oracle會根據這裡記錄的oracle_sid的< n|y >的設定來決定是否啟動相關執行個體。

與linux/unix上的情況類似,windows上的oracle環境也依賴于服務而存在,如圖1-24所示。

《循序漸進Oracle:資料庫管理、優化與備份恢複》一一1.3 資料庫建立的腳本

我們注意到oracle環境的初始化是通過oracle.exe eygle來完成的,至于執行個體和資料庫是否随服務啟動要依賴于系統資料庫中的設定。

通過手動在指令行執行類似指令,可以初始化任意的oracle應用環境,例如,以下指令就初始化了名為julia的運作時環境:

此後就可以連接配接到這個環境啟動執行個體:

當然還需要建立參數檔案和密碼檔案等:

此後,執行個體可以順利啟動,并可以挂接和打開資料庫:

如果在環境視窗中按下ctrl+c組合鍵退出,則資料庫将異常中斷。

總結一下,實際上不管在windows還是linux/unix環境下,oracle_sid的作用就是設定一個oracle環境視窗,通過這個環境變量來标示和命名系統程序,此後oracle的活動可以由此展開。

作為oracle資料庫的重要組成部分instance也存在一個參數辨別:instance_name。

instance_name是oracle資料庫的一個參數,在參數檔案中定義,用于标示資料庫執行個體的名稱,其預設值通常就是oracle_sid,但是不同的執行個體可以有相同的執行個體名。通過簡單的參數檔案複制,我們就可以在同一台伺服器上建立多個具有相同instance_name參數設定的執行個體。

首先确認目前的參數檔案:

複制參數檔案,更改名稱:

接下來通過導入新的oracle_sid我們就可以啟動新的執行個體:

現在oracle_sid為julia的執行個體已經啟動,作業系統上的程序以julia名稱标記:

總結一下,oracle_sid在這裡用于标示程序,而instance_name則用來标示執行個體,兩者可以具有不同的名稱。但是如果不同往往帶來歧義,不具備實際的意義,是以從oracle database 10g開始,預設的情況下,oracle将instance_name這個參數從參數檔案中剔除,這樣就能夠盡量保證oracle_sid和instance_name的一緻。

此外oracle的監聽器(listener)配置檔案中的sid_name就是來自instance_name參數,監聽器通過instance_name才能确定需要将連接配接請求注冊到哪一個執行個體上。通常listener.ora檔案中sid_name相關設定類似如下示例:

繼續前面的腳本,在建立和啟動了執行個體之後,oracle開始調用eygle.sql腳本,我們将這個腳本分開來介紹。

這個腳本的最初部分是要求定義使用者密碼,然後使用定義的sys使用者密碼建立密碼檔案:

這裡又引入了另外一個工具orapwd,這個工具在linux/unix上同樣存在,當密碼檔案丢失或損壞之後,可以通過這個工具重建密碼檔案,這個工具的文法為:

 there must be no spaces around the equal-to (=) character.

注意:

force參數是oracle 10g中增加的,ignorecase參數是11g新增加的。

oracle在啟動過程中,會在$oracle_home/dbs(windows下相應的目錄則是$oracle_homedatabase)目錄下查找密碼檔案,查找的順序是首先檢查orapw< oracle_sid >檔案,如果不存在則查找orapw檔案,如果orapw檔案也不存在,就會報出如下錯誤:

密碼檔案丢失或損壞後,通常可以通過如下指令重建密碼檔案:

[oracle@jumper dbs] $ orapwd file=orapwhsjf password=oracle entries=5

在資料庫沒有啟動之前,資料庫内建使用者是無法通過資料庫來驗證身份的,此時密碼檔案的作用就展現了出來。密碼檔案中存放了具有sysdba / sysoper身份使用者的使用者名及密碼,oracle允許使用者通過密碼檔案驗證,在資料庫未啟動之前登入,進而啟動執行個體進而加載并打開資料庫;而如果沒有密碼檔案,在資料庫未啟動之前就隻能通過作業系統認證方式來啟動執行個體。在oracle dataguard環境中,要求主資料庫和備用資料庫的密碼檔案sys使用者密碼相同,這時候經常會用到使用orapwd工具重建密碼檔案的技能。

oracle通過一個初始化參數remote_login_passwordfile來限制密碼檔案的使用,通過這個參數可以設定使用者登入時是否檢查密碼檔案,以及有多少個資料庫可以使用密碼檔案。這個參數有3個選項:exclusive、shared和none。

當remote_login_passwordfile設定為none時,遠端使用者将不能通過sysdba/sysoper身份登入資料庫:

此時,通過遠端連接配接會收到如下錯誤:

此處實際上是無法通過密碼檔案驗證。

預設的remote_login_passwordfile參數設定為exclusive,支援遠端sysdba的登入操作:

這個參數是靜态參數,修改後重新開機資料庫才能生效。當remote_login_passwordfile參數設定為exclusive時,可以通過遠端以sysdba身份登入資料庫:

當remote_login_passwordfile參數設定為shared時,則多個資料庫可以共享一個密碼檔案,但是此時密碼檔案中隻能存儲sys使用者的密碼,此時其他使用者不能被授予sysdba身份:

此時的密碼檔案中是不能添加使用者的。很多朋友的疑問在于:密碼檔案的預設名稱是orapw< oracle_sid >,怎麼能夠共享?

前面已經提到,oracle資料庫在啟動時,首先查找的是orapw< oracle_sid >的密碼檔案,如果該檔案不存在,則開始查找orapw的密碼檔案;如果同一主機上的多個資料庫同時使用orapw檔案,則密碼檔案就可以共享(當然通過其他方式,如符号連結等也可以實作共享)。

來看一下測試,首先移動預設的密碼檔案:

此時,啟動資料庫會出現如下錯誤:

複制一個orapw密碼檔案,這時候再啟動資料庫就不會出現這個錯誤:

那麼你可能會有這樣的疑問:多個exclusive的資料庫是否可以共享一個密碼檔案(orapw)呢?

繼續這個測試,首先檢視一下密碼檔案的内容,注意這裡僅記錄着internal/sys的密碼:

當remote_login_passwordfile=exclusive時:

這裡以exclusive方式啟動以後,執行個體名稱資訊被寫入密碼檔案。

此時,如果有其他執行個體以exclusive模式啟動,仍然可以使用這個密碼檔案,密碼檔案中的執行個體名稱同時被改寫,也就是說,資料庫隻在啟動過程中才讀取密碼檔案,資料庫運作過程中并不鎖定該檔案,類似于pfile/spfile檔案。

進一步地,如果對其他使用者授予sysdba的身份:

注意此時增加的sysdba使用者,其相關資訊可以被寫入到密碼檔案,一旦密碼檔案中增加了其他sysdba使用者,此檔案就不再能夠被其他exclusive的執行個體共享。

繼續來看eygle.sql的内容,接下來的腳本才是建立資料庫中最關鍵的:

第一個腳本是createdb.sql,其主要内容如下:

可以看到,這個檔案的主要操作步驟如下:

(1)通過sys連接配接;

(2)通過配置的參數檔案init.ora啟動執行個體;

(3)開始資料庫建立;

(4)将資料庫生成的控制檔案名稱追加到參數檔案。

由于選擇了omf管理檔案,控制檔案的名稱在建立資料庫之前是未知的,是以建立資料庫之後才能得到名稱加入參數檔案中。

在啟動執行個體後執行的建立資料庫中,第一個語句就是:

create database "eygle"

這是資料庫最重要的開始,其中"eygle"也就是圖1-4中定義的資料庫名稱。

對于oracle資料庫來說,db_name代表資料庫的名稱,而instance_name代表執行個體的名稱,instance_name通過參數檔案即可修改,而db_name則不然。

我們來看一下oracle對于資料庫名稱的定義:db_name必須是一個不超過8個字元的文本串。在資料庫建立過程中,db_name被記錄在資料檔案,日志檔案和控制檔案中。如果資料庫執行個體啟動過程中參數檔案中的db_name和控制檔案中的資料庫名稱不一緻,則資料庫不能啟動。

通過以上定義可以看到,db_name是最具有穩定意義的參數,在資料檔案、日志檔案和控制檔案中都會記錄資料庫的名稱,這個名稱完全可以不同于instance_name。又由于db_name具有存儲的穩定性,是以不能簡單地随意更改。

以下的測試資料庫擁有相同的db_name和instance_name:

我們建立一個新的pfile為julia這個新的執行個體使用:

修改這個檔案更改instance_name參數:

然後我們啟動執行個體名稱為julia的instance:

注意,此時試圖加載資料庫時會出現錯誤,因為目前資料庫被另外一個執行個體(eygle instance)加載。在非并行模式(ops/rac)下,一個資料庫同時隻能被一個執行個體加載。

此時已經啟動了兩個資料庫執行個體,從背景程序可以看出:

關閉eygle這個資料庫執行個體後,就可以通過執行個體julia加載并打開db_name=eygle的資料庫了:

新的執行個體具有獨立的instance_name和db_name參數設定:

我們再來看一看如果參數檔案中的db_name和控制檔案中的db_name不一緻會出現什麼錯誤。

修改參數檔案中的db_name參數:

在啟動過程中,我們看到,在mount階段,資料庫會對參數檔案和控制檔案進行比較,如果兩者記錄的db_name不一緻,則資料庫無法啟動:

關于db_name在檔案頭上的存儲,可以通過很多方式來讀取,以下通過oracle 9i中随軟體提供的bbed可以最為直覺的觀察和了解(這一工具在windows平台上,oracle 9i之後不再提供):

進行了如上設定之後,我們可以檢查檔案頭的結構資訊,kcvfh是檔案頭資訊的結構體:

在以上輸出中,kccfhdbn就是db_name的保留白間,共保留了8位,也正因為如此,資料庫的db_name不能超過8個字元。又因為每個檔案頭上的實體存儲,修改db_name的動作會較為複雜,一個名為nid的小工具可以用來更改資料庫名稱:

最後總結一下,一個執行個體(instance_name)可以mount并打開任何資料庫(db_name),但是同一時間一個執行個體隻能打開一個資料庫;一個資料庫(db_name)同一時間可以為任一執行個體(instance_name)所打開,但是在非rac情況下,同一時間隻能被同一個執行個體所打開。

在create database的過程中,oracle會調用$oracle_home/rdbms/admin/sql.bsq腳本,用于建立資料字典,這是非常重要的一個腳本,其中存儲了資料字典的建立語句及注釋說明。當我們對某些資料字典存在興趣時,可以通過檢查這個檔案得到更為詳細的資訊,例如,對于控制資料庫啟動的bootstrap$表,其建立語句就可以從這個檔案中找到:

提示:

sql.bsq檔案值得每個接觸oracle資料的人,認真閱讀了解。

sql.bsq檔案的位置受到一個隐含的初始化參數(_init_sql_file)的控制:

如果在資料庫的建立過程中,oracle無法找到sql.bsq檔案,則資料庫建立将會出錯。可以測試一下移除sql.bsq檔案,來看一下資料庫建立過程:

此時警告日志(alert_< oracle_sid >.log)中會記錄如下資訊:

這就是sql.bsq檔案在資料庫建立過程中的作用。知道了這個内容之後,我們甚至可以通過手工修改sql.bsq檔案來更改資料庫字典對象參數,進而實作特殊要求資料庫的建立或測試自定義庫,也可以通過修改_init_sql_file參數來重定位sql.bsq檔案的位置(但是通常這些是不建議變更的)。

sql.bsq檔案中包含的資料庫核心資訊非常重要,在很多時候,這個檔案可以幫助我們解答很多技術疑惑。

在oracle 11g中,sql.bsq檔案的内容被分散隔離為多個檔案。

再來看createdbfiles.sql檔案:

這個檔案向資料庫中追加了users表空間,并将該表空間設定為系統預設的資料表空間,注意最後一句:

這是oracle 10g增加的新特性,在oracle 10g之前,如果建立使用者不指定預設的資料表空間,那麼使用者的預設表空間會被指向系統表空間,增加了資料庫預設資料表空間後,如果不指定,那麼建立使用者的預設資料表空間會被指向這裡:

作為一個資料庫屬性,這個資訊也可以從字典表props$中查詢得到:

繼續前面的讨論,接下來oracle通過createdbcatalog.sql建立資料字典:

這個檔案依次調用oracle的字典建立檔案等。

emrepository.sql檔案是用于建立em檔案庫的:

最後一個執行的檔案是postdbcreation.sql:

在建立過程中,需要經曆以下幾個步驟後,資料庫的建立才算正式完成:

(1)oracle首先通過參數檔案建立了spfile檔案;

(2)解鎖兩個賬号;

(3)編譯;

(4)配置em。