《用Oracle12.2手工創建數據庫的一個坑》要點:
本文介紹了用Oracle12.2手工創建數據庫的一個坑,希望對您有用。如果有疑問,可以聯系我們。
作者介紹
楊建榮,DBAplus社群聯合發起人.現就職于搜狐暢游,Oracle ACE、YEP成員,超7年數據庫開發和運維經驗,擅長電信數據業務、數據庫遷移和性能調優.持Oracle 10G OCP,OCM,MySQL OCP認證,《Oracle DBA工作筆記》作者.
Oracle 12cR2推出以來,確實吸引了不少DBA的注意力,新版本特性還是需要多測試、多演練,做到心中有數,我從12cR2 Linux版本發布的第一天,就風風火火使用DBCA靜默建庫,嘗了嘗鮮,毫無疑問其中一個亮點就是多租戶,也就是容器數據庫CDB.
12c中因為有了CDB,這個架構相當動了Oracle的地基,所以create database語句也肯定會有大的變化,里面引入了seed數據庫,而且在12.2中一個較大的變化是undo有local和share模式,這是區別于12.1的一大改進.
大家有沒有試過手工建庫呢?從自己的測試來看是有一些坑的,在此希望給需要的同學一些幫助,少走彎路.當然我在這方面也做了一些功課,我們不光會對12.2中碰到的問題提供解決方法,而且會討論下create database語句在10g、11g中的異同,從多個維度一窺Oracle在這些版本中細小改變,畢竟保持好奇心是一個技術人員求知進步的一把鑰匙.
首先使用create database語句創建數據庫,官方文檔在12.2中提示的非常詳細,詳細的步驟可以參考如下鏈接:
http://docs.oracle.com/database/122/ADMIN/creating-and-configuring-a-cdb.htm#ADMIN13529
對于使用create database語句創建容器數據庫,文檔提供了兩類方式,一種是使用OMF(Oracle Managed Files),另外一種是非OMF的方式,對于我們的日常使用來說,其實更傾向于使用非OMF方式,而如果數據庫放在ASM里,則會傾向自動管理,因為ASM的文件管理是基于OMF方式的.
為了演示方便,我就使用OMF來說明,這樣create database語句的結構相對清晰簡單.
我們創建一個CDB,創建參數文件,啟動數據庫至nomount狀態后,就可以使用下面的語句了.
CREATE DATABASE newcdb
USER SYS IDENTIFIED BY sys_password
USER SYSTEM IDENTIFIED BY system_password
EXTENT MANAGEMENT LOCAL
DEFAULT TABLESPACE users
DEFAULT TEMPORARY TABLESPACE temp
UNDO TABLESPACE undotbs1
ENABLE PLUGGABLE DATABASE
?? SEED
?? SYSTEM DATAFILES SIZE 125M AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED
?? SYSAUX DATAFILES SIZE 100M;
和以往的版本不同的就是上面黃色部分標準的部分.
至于PDB seed的意義,就是提供了模板數據,盡可能高效地構建出PDB,可以移步參考之前的一篇文章《Oracle DBCA高級玩法:從模板選擇、腳本調用到多租戶》.
創建數據庫的步驟完成之后,只是完成了不到一半的工作量,另外一部分重點的工作就是初始化數據字典了,我們需要手工運行catalog.sql catproc.sql,這兩個是初始化數據字典的核心腳本,而其它的一些publd.sql等腳本則是相應的輔助腳本,但是12.2卻一改常態,在文檔中表示需要使用catcdb.sql 這個腳本即可.
12.1中的catcdb.sql是一個確確實實的SQL文件,只是會在腳本中引用更多的SQL腳本,無論如何它的本質還是SQL腳本.
12.2中有了大的改進,catcdb.sql引用的是catcdb.pl這樣一個Perl腳本,你不會直接看到catalog.sql,catproc.sql這樣的字眼了,這些都被封裝起來了.
當然換湯不換藥,調用方式還是類似的.
這個腳本個人吐槽一下,運行腳本需要輸入兩個參數,但是兩個參數的含義也沒給解釋,這一點值得改進,其實需要輸入的是$ORACLE_HOME/rdbms/admin和catcdb.pl兩個參數,如果你不知道輸入什么也別擔心,因為你會碰到一些其他的問題要先解決,我們不輸入任何參數,先回車.
@?/rdbms/admin/catcdb.sql
SQL> host perl -I &&rdbms_admin &&rdbms_admin_catcdb –logDirectory &&1 –logFilename &&2
Enter value for 1:
Enter value for 2:
Can’t locate Term/ReadKey.pm?in @INC (@INC contains: /U01/app/oracle/product/12.2/rdbms/admin /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /U01/app/oracle/product/12.2/rdbms/admin/catcdb.pl line 30.
BEGIN failed–compilation aborted at /U01/app/oracle/product/12.2/rdbms/admin/catcdb.pl line 30.
拋出的錯誤提示找不到ReadKey.pm,但是我們知道Linux,Unix其實都是自帶Perl的,是不是我們還要單獨去重新配置安裝Perl,其實不必,需要的文件在$ORACLE_HOME下的Perl目錄,安裝版本是5.22.0了,你只需要把這個目錄引用到PATH變量中就可以了,比如:
export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$ORACLE_HOME/perl/bin: $ORACLE_HOME/jdk/bin:$PATH
第一個問題就解決了,別急,還有幾個問題呢.
第二個問題來了,那就是找不到util.pm,還是Perl里的模塊.
Can’t locate util.pm?in @INC (you may need to install the util module) (@INC contains: /U01/app/oracle/product/12.2/rdbms/admin /home/U01/app/oracle/product/12.2/perl/lib/site_perl/5.22.0/x86_64-linux-thread-multi /home/U01/app/oracle/product/12.2/perl/lib/site_perl/5.22.0 /home/U01/app/oracle/product/12.2/perl/lib/5.22.0/x86_64-linux-thread-multi /home/U01/app/oracle/product/12.2/perl/lib/5.22.0 .) at /U01/app/oracle/product/12.2/rdbms/admin/catcdb.pl line 35.
BEGIN failed–compilation aborted at /U01/app/oracle/product/12.2/rdbms/admin/catcdb.pl line 35.
這個問題該怎么破,我們只能做點額外的工作了,在Perl的目錄下查找util.pm竟然沒有,是不是這個地方要重新安裝這個模塊,我們換一個思路,把util改為Util,竟然有5條匹配的記錄.
$ find $ORACLE_HOME -name util.pm | wc -l
0
$ find $ORACLE_HOME -name Util.pm | wc -l
5條匹配的記錄內容如下:
$ find $ORACLE_HOME -name Util.pm
/U01/app/oracle/product/12.2/perl/lib/5.22.0/x86_64-linux-thread-multi/List/Util.pm
/U01/app/oracle/product/12.2/perl/lib/5.22.0/x86_64-linux-thread-multi/Scalar/Util.pm
/U01/app/oracle/product/12.2/perl/lib/5.22.0/x86_64-linux-thread-multi/Sub/Util.pm
/U01/app/oracle/product/12.2/perl/lib/5.22.0/x86_64-linux-thread-multi/Hash/Util.pm
/U01/app/oracle/product/12.2/perl/lib/site_perl/5.22.0/HTTP/Headers/Util.pm
這個過程中到底該選哪個目錄下的Util.pm呢,如果多點耐心仔細看看里面的內容還是能夠找到一些頭緒的,最后選擇的是:
/U01/app/oracle/product/12.2/perl/lib/5.22.0/x86_64-linux-thread-multi/Hash/Util.pm
那么問題來了,這個catcdb.pl腳本是不是要改動呢.
修改文件catcdb.pl,把如下黃色部分的util修改為Util
use Term::ReadKey;????????????? # to not echo password
use Getopt::Long;
use Cwd;
use File::Spec;
use Data::Dumper;
use?Util?qw(trim, splitToArray);
use catcon qw(catconSqlplus);
再來一輪測試,結果發現還是會有報錯,這種嘗試會讓你開始懷疑自己的選擇到底是不是正確的方向.
如果還是沒有找到,說明在當前的環境變量中沒有匹配到相關的內容,我們需要直接切換到目錄Hash下,然后運行腳本才可以,這個時候輸出才算有了改觀,提示你輸入密碼.
SQL> host perl -I &&rdbms_admin &&rdbms_admin_catcdb –logDirectory &&1 –logFilename &&2
Enter value for 1: /U01/app/oracle/product/12.2/rdbms/admin
Enter value for 2: /U01/app/oracle/product/12.2/rdbms/admin/catcdb.pl
Enter new password for SYS: xxxx
Enter new password for SYSTEM: xxxx
Enter temporary tablespace name: temp
No options to container mapping specified, no options will be installed in any containers
catcon: ALL catcon-related output will be written to [/U01/app/oracle/product/12.2/rdbms/admin/catalog_catcon_46984.lst]
catcon: See [/U01/app/oracle/product/12.2/rdbms/admin/catalog*.log] files for output generated by scripts
catcon: See [/U01/app/oracle/product/12.2/rdbms/admin/catalog_*.lst] files for spool files, if any
然后就是一段時間的等待,可以從日志看到會關聯調用catalog.sql,catproc.sql等腳本文件.
而在處理問題的過程中,也參考了一些資料,發現Deiby Gomez?也碰到了類似的問題,他在博客里提供了類似的解決方法.所以說這的的確確是12.2新版本中create database的一個坑,如果你對create database失去了信心,也別擔心,其實不一定是你的錯.
12c的坑討論完了,我們來換個思路,看看10g、11g中是什么情況.
Create database語句在10g、11g的差別
一個簡單的create database語句在10g、11g還是有一些變化的,這些變化我們需要一些敏銳的“嗅覺”.
Oracle 11g的create database語句大體是這樣的,我們只需要簡單修改下路徑就基本可用.
CREATE DATABASE mynewdb
USER SYS IDENTIFIED BY sys_password USER SYSTEM IDENTIFIED BY system_password
LOGFILE GROUP 1 (‘/u01/logs/my/redo01a.log’,’/u02/logs/my/redo01b.log’) SIZE 100M BLOCKSIZE 512,
GROUP 2 (‘/u01/logs/my/redo02a.log’,’/u02/logs/my/redo02b.log’) SIZE 100M BLOCKSIZE 512,
GROUP 3 (‘/u01/logs/my/redo03a.log’,’/u02/logs/my/redo03b.log’) SIZE 100M BLOCKSIZE 512
MAXLOGFILES 5
MAXLOGMEMBERS 5
MAXLOGHISTORY 1
MAXDATAFILES 100
CHARACTER SET AL32UTF8
NATIONAL CHARACTER SET AL16UTF16
EXTENT MANAGEMENT LOCAL
DATAFILE ‘/u01/app/oracle/oradata/mynewdb/system01.dbf’ SIZE 325M REUSE
SYSAUX DATAFILE ‘/u01/app/oracle/oradata/mynewdb/sysaux01.dbf’ SIZE 325M REUSE
DEFAULT TABLESPACE users
DATAFILE ‘/u01/app/oracle/oradata/mynewdb/users01.dbf’
SIZE 500M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED
DEFAULT TEMPORARY TABLESPACE tempts1
TEMPFILE ‘/u01/app/oracle/oradata/mynewdb/temp01.dbf’
SIZE 20M REUSE
UNDO TABLESPACE undotbs
DATAFILE ‘/u01/app/oracle/oradata/mynewdb/undotbs01.dbf’
SIZE 200M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
而如果你使用11g的create database語句,毫無疑問會在10g環境中拋出錯誤.
SQL> @createdb.sql
LOGFILE GROUP 1 (‘/u02/oracle/oradata/TEST10G/disk1/redo01a.log’,’/u02/ oracle/oradata/TEST10G/disk2/redo01b.log’) SIZE 100M BLOCKSIZE 512,
*
ERROR at line 4:
ORA-02165: invalid option for CREATE DATABASE
在這一點上,我們需要點耐心,我把10g的創建語句拿出來比較一下,發現有3處不同(標黃部分).
CREATE DATABASE mynewdb
USER SYS IDENTIFIED BY pz6r58
USER SYSTEM IDENTIFIED BY y1tz5p
LOGFILE GROUP 1 (‘/u01/oracle/oradata/mynewdb/redo01.log’) SIZE 100M,
? ? ? ? ? ?GROUP 2 (‘/u01/oracle/oradata/mynewdb/redo02.log’) SIZE 100M,
? ? ? ? ? ?GROUP 3 (‘/u01/oracle/oradata/mynewdb/redo03.log’) SIZE 100M
MAXLOGFILES 5
MAXLOGMEMBERS 5
MAXLOGHISTORY 1
MAXDATAFILES 100
MAXINSTANCES 1
CHARACTER SET US7ASCII
NATIONAL CHARACTER SET AL16UTF16
DATAFILE ‘/u01/oracle/oradata/mynewdb/system01.dbf’ SIZE 325M REUSE
EXTENT MANAGEMENT LOCAL
SYSAUX DATAFILE ‘/u01/oracle/oradata/mynewdb/sysaux01.dbf’ SIZE 325M REUSE
DEFAULT TABLESPACE tbs_1
DEFAULT TEMPORARY TABLESPACE tempts1
TEMPFILE ‘/u01/oracle/oradata/mynewdb/temp01.dbf’
SIZE 20M REUSE
UNDO TABLESPACE undotbs
DATAFILE ‘/u01/oracle/oradata/mynewdb/undotbs01.dbf’
SIZE 200M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
(1)第一處不同是關于redo日志組的設置,10g中默認配置一組日志中只有一個日志成員,而在11g中是默認有2個.
(2)第二個不同之處是在10g中有一個配置MAXINSTANCES,而在11g中卻沒有,因為是單實例數據庫,所以不會是這個地方的不同引起的問題.
(3)第三個問題就更加明顯了,在10g中只有default tablespace tbs_1語句而沒有定義明細的信息,這個語句是不能運行的,還需要手工去補充,在11g中,語句已經補充完整了.只需要簡單的根據自己的需求調整一下即可.
所以第二、三處不同很明顯不是問題的原因,那么我們看看第一處不同,還有什么地方有可能會導致語句出現問題.
11g中日志組的定義的如下:
LOGFILE GROUP 1 (‘/u01/logs/my/redo01a.log’,’/u02/logs/my/redo01b.log’) SIZE 100M BLOCKSIZE 512,
10g中日志組的定義如下:
LOGFILE GROUP 1 (‘/u01/oracle/oradata/mynewdb/redo01.log’) SIZE 100M,
除了日志成員的不同外,還有就是blocksize的不同,在10g中沒有blocksize的字樣.
把blocksize去掉,在11g環境中再次運行語句,語句就運行成功了.
原來問題在這里,因為blocksize的值是在數據庫的源代碼中固定的,與操作系統相關,默認的值為512,在不同的操作系統中會有所不同.
查看blocksize的配置,可以使用基表.
從Oracle的內部視圖中獲得:
SQL> select max(lebsz) from x$kccle;
MAX(LEBSZ)
———-
512
所以可見在10g和11g的很多細節之處還是可以發現很多值得推敲的地方,Oracle文檔也在不斷地改進和完善之中.
小結
以上的問題也算是拋磚引玉,希望大家不要輕視這些技術細節,我們不求每個版本都很完美,但是能夠從中能夠悟出一些更通用的東西,里面的一點一滴的改進都是我們值得琢磨和推敲的地方,給大家的工作中有所幫助,我的目的也就達到了.
文章來自微信公眾號:DBAplus社群
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/4096.html