1. 程式人生 > >例子2之解決ORA-03113: 通訊通道的檔案結尾(實質是Control filesequence number mismatch)

例子2之解決ORA-03113: 通訊通道的檔案結尾(實質是Control filesequence number mismatch)

VC Appliance停機是用待機方式將Oracle資料庫停了。再啟動時,Oracle不能啟動。用SQLPLUS中的Starup命令。出現下面的提示:

由於ORA-03113錯誤是一個通用的錯誤提示,能給的資訊量很少。

於是一步步的來Debug,由於startup相當於3個命令的集合,就一步步地執行

先執行

SQL>startup nomount

並沒有發現什麼明顯的失敗資訊,說明啟動資料庫例項是沒有問題的,再執行第二步

SQL>alter database mount;

出現故障

看來故障出現在掛載資料庫檔案時,這一步驟主要是“允許特定的維護操作, 例如, 重新命名資料檔案, 新增, 刪除或重新命名重做日誌檔案, 啟用和禁用重做歸檔選項, 執行完全資料庫恢復。它不允許對資料庫進行一般的訪問。”

找到$ORACLE_HOME/rdbms/log目錄,用ls -ltr找到最近的日誌檔案。在本例中是sales_ora_27010.trc

看來是olr.loc和ocr.loc兩個檔案不能開啟。但是我的機器上根本沒有這個檔案。在網上搜索,發現這兩個檔案和Oracle的叢集有關,我這裡是單節點的,按說是不需要Oracle Local Registry的。

在網上搜索,也沒有什麼特別有用的提示,但是發現了另一個問題,就是我找的日誌檔案可能不對,找了原來安裝時匯出的備份虛擬機器,用命令

SQL>show parameter background

找到正確的日誌路徑/usr/local/oracle/diag/rdbms/oracle/sales/trace

檢視啟動時的日誌,在最後發現

Starting ORACLE instance (normal) LICENSE_MAX_SESSION = 0 LICENSE_SESSIONS_WARNING = 0 Picked latch-free SCN scheme 3 Using LOG_ARCHIVE_DEST_1 parameter default value as USE_DB_RECOVERY_FILE_DEST Autotune of undo retention is turned on. … Wed Aug 07 15:37:46 2013 SMON started with pid=13, OS id=30687 Wed Aug 07 15:37:46 2013 RECO started with pid=14, OS id=30689 Wed Aug 07 15:37:46 2013 MMON started with pid=15, OS id=30691 starting up 1 dispatcher(s) for network address ‘(ADDRESS=(PARTIAL=YES)(PROTOCOL=TCP))’… Wed Aug 07 15:37:46 2013 MMNL started with pid=16, OS id=30693 starting up 1 shared server(s) … ORACLE_BASE from environment = /usr/local/oracle Wed Aug 07 15:37:46 2013 ALTER DATABASE   MOUNT USER (ospid: 30698): terminating the instance Instance terminated by USER, pid = 30698

重試了多次,結果大多類似。在日誌相同目錄裡,找到最近的trc檔案,發現如下內容:

[[email protected] trace]# vi sales_ora_20498.trc

Release:        2.6.32-279.el6.x86_64

Version:        #1 SMP Fri Jun 22 12:19:21 UTC 2012

Machine:        x86_64

Instance name: sales

Redo thread mounted by this instance: 0 <none>

Oracle process number: 19

Unix process pid: 20498, image: [email protected] (TNS V1-V3)

*** 2013-08-08 09:23:49.818

*** SESSION ID:(125.37) 2013-08-08 09:23:49.818

*** CLIENT ID:() 2013-08-08 09:23:49.818

*** SERVICE NAME:() 2013-08-08 09:23:49.818

*** MODULE NAME:([email protected] (TNS V1-V3)) 2013-08-08 09:23:49.818

*** ACTION NAME:() 2013-08-08 09:23:49.818

Error: kccpb_sanity_check_2

Control file sequence number mismatch!

fhcsq: 38637 bhcsq: 38638 cfn 0

*** 2013-08-08 09:23:49.819

USER (ospid: 20498): terminating the instance

從上面來看,是控制檔案故障。 現在重建控制檔案,先到日誌檔案中找到一個相關引數的例子,在alert_sales.log檔案中找出
Create controlfile reuse set database “oracle” MAXINSTANCES 8 MAXLOGHISTORY 1 MAXLOGFILES 16 MAXLOGMEMBERS 3 MAXDATAFILES 100 Datafile ‘/usr/local/oradata/ora11g/ORA11G/oracle/system01.dbf’, ‘/usr/local/oradata/ora11g/ORA11G/oracle/sysaux01.dbf’, ‘/usr/local/oradata/ora11g/ORA11G/oracle/undotbs01.dbf’, ‘/usr/local/oradata/ora11g/ORA11G/oracle/users01.dbf’ LOGFILE GROUP 1 (‘/usr/local/oradata/ora11g/ORA11G/oracle/redo01.log’) SIZE 51200K, GROUP 2 (‘/usr/local/oradata/ora11g/ORA11G/oracle/redo02.log’) SIZE 51200K, GROUP 3 (‘/usr/local/oradata/ora11g/ORA11G/oracle/redo03.log’) SIZE 51200K RESETLOGS WARNING: Default Temporary Tablespace not specified in CREATE DATABASE command Default Temporary Tablespace will be necessary for a locally managed database in future release Successful mount of redo thread 1, with mount id 1691519286 Completed: Create controlfile reuse set database “oracle”
STARTUP NOMOUNT CREATE CONTROLFILE REUSE DATABASE “PRIMARY” NORESETLOGS  ARCHIVELOG –  SET STANDBY TO MAXIMIZE PERFORMANCE MAXLOGFILES 5 MAXLOGMEMBERS 3 MAXDATAFILES 100 MAXINSTANCES 1 MAXLOGHISTORY 226 LOGFILE GROUP 1 ‘/opt/oracle/oradata/primary/redo01.log’  SIZE 10M, GROUP 2 ‘/opt/oracle/oradata/primary/redo02.log’  SIZE 10M, GROUP 3 ‘/opt/oracle/oradata/primary/redo03.log’  SIZE 10M – STANDBY LOGFILE DATAFILE ‘/opt/oracle/oradata/primary/system01.dbf’, ‘/opt/oracle/oradata/primary/undotbs01.dbf’, ‘/opt/oracle/oradata/primary/users01.dbf’ CHARACTER SET ZHS16GBK ; RECOVER DATABASE ALTER SYSTEM ARCHIVE LOG ALL; ALTER DATABASE OPEN; ALTER TABLESPACE TEMP ADD TEMPFILE ‘/opt/oracle/oradata/primary/temp01.dbf’ SIZE 41943040  REUSE AUTOEXTEND ON NEXT 655360  MAXSIZE 32767M;
在SQL>下先執行startup nomount,然後直接將根據上面和日誌中引數,定義下面的指令碼直接貼上到SQL>下
CREATE CONTROLFILE REUSE DATABASE “oracle” NORESETLOGS  ARCHIVELOG –  SET STANDBY TO MAXIMIZE PERFORMANCE MAXLOGFILES 16 MAXLOGMEMBERS 3 MAXDATAFILES 100 MAXINSTANCES 8 MAXLOGHISTORY 1 LOGFILE GROUP 1 ‘/usr/local/oradata/ora11g/ORA11G/oracle/redo01.log’  SIZE 51200K, GROUP 2 ‘/usr/local/oradata/ora11g/ORA11G/oracle/redo02.log’  SIZE 51200K, GROUP 3 ‘/usr/local/oradata/ora11g/ORA11G/oracle/redo03.log’  SIZE 51200K – STANDBY LOGFILE DATAFILE ‘/usr/local/oradata/ora11g/ORA11G/oracle/vpx01.dbf’, –’/usr/local/oradata/ora11g/ORA11G/oracle/temp01.dbf’, ‘/usr/local/oradata/ora11g/ORA11G/oracle/system01.dbf’, ‘/usr/local/oradata/ora11g/ORA11G/oracle/sysaux01.dbf’, ‘/usr/local/oradata/ora11g/ORA11G/oracle/undotbs01.dbf’, ‘/usr/local/oradata/ora11g/ORA11G/oracle/users01.dbf’
在上面指令碼中,我重試了幾次,一次是日誌大小,我想改成10M,但是不成功,另一次是提示temp01.dbf不是有效的資料庫檔案,我只有把它註釋掉了,只能參照網上的指令碼,一步步執行 其中,最後一句
ALTER TABLESPACE TEMP ADD TEMPFILE ‘/usr/local/oradata/ora11g/ORA11G/oracle/temp01.dbf’ SIZE 20480K REUSE AUTOEXTEND ON NEXT 640K MAXSIZE UNLIMITED
我也是從日誌檔案中找出來的。 根據上面顯示的結果,應該是恢復成功了。 先重啟作業系統。再手工啟動Oracle,一切正常,但是對應的VCSA卻不能啟動,用OEM進去看到有資料塊錯誤 從圖中可以看到,ORA-01578錯誤,出現檔案損壞,Block是45953。 用dbv命令檢查檔案
[[email protected] ~]$ dbv FILE=’/usr/local/oradata/ora11g/ORA11G/oracle/vpx01.dbf’ BLOCKSIZE=8192
得到下面的結果: 從中可以看出,被標記會Corrupt的塊有452個。 再查詢是哪些損壞的哪些內容:
Select tablespace_name,segment_type,owner,segment_name From dba_extents Where file_id=5 and 45953 between block_id and block_id+blocks-1;
結果如下: 說明損壞的是LOBSEGMENT 用命令找到損壞的表名和列名
select table_name, column_name from dba_lobs where segment_name=’SYS_LOB0000075100C00016$$’ and owner =’VPXADMIN’;
結果為:
select count(*) from VPXADMIN.VPX_RESOURCE_POOL;
發現這個表中只有8行資料。
ROWID                      ID —————— ———- AAASVcAAFAAACfjAAA          8 AAASVcAAFAAACfkAAB        523 AAASVcAAFAAACfkAAA        816 AAASVcAAFAAACfkAAC        826 AAASVcAAFAAACfkAAD        833 AAASVcAAFAAACfkAAE        839 AAASVcAAFAAACflAAB       1212 AAASVcAAFAAACfjAAC       1601
一行一行地試
select * from VPXADMIN.VPX_RESOURCE_POOL where id>1212;
發現ID=1212的這條記錄是損壞的。
delete  from  VPXADMIN.VPX_RESOURCE_POOL where id=1212;
刪除後,這個表可以正常地訪問了,用DBV檢查,結果沒有什麼不同。 shutdown immadiate資料庫,提示沒有Commit,看來刪除並沒有真正成功,於是在SQL命令列下,直接輸入commit提交了修改。然後可以關閉資料庫了。重啟資料庫DBV檢查情況並無改觀,說明這些還不夠。 想了半天,也沒有什麼頭緒,回到OEM頁面中,在“可用 性”裡面,選擇了“執行恢復”,看看能不能將表空間VPX恢復到8月3日之前。 點了半天后,提示操作失敗,同時VPX也離線了,在圖形介面中卻怎麼為無法聯機。真是事情越搞越亂,好在問題並不複雜,在SQL環境下,執行
recover datafile 5 alter database datafile 5 online; alter tablespace VPX online;
就可以聯機了。 再回到原來的問題。 排查到現在,還有兩個方向研究,一個是從vCenter伺服器不能啟動服務入手,檢視日誌,查看出錯的地點和原因。一個還是從DBV出的錯誤結果入手。 先從DBV入手,在網上搜索到這篇文章,發現,可能根據DBV出的錯誤資訊找到出錯的檔案和塊,從而找到對應的表。 下面一部分的DBV 201錯誤塊資訊
… DBV-00201: Block, DBA 21044390, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044391, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044393, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044394, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044395, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044397, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044398, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044399, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044401, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044402, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044403, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044406, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044407, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044410, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044411, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044412, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044414, marked corrupt for invalid redo application DBV-00201: Block, DBA 21044415, marked corrupt for invalid redo application
根據最後的顯示,應該有452個塊,這裡這是一部分,因為終端顯示不完全。 拿最後一個來測試一下
select dbms_utility.data_block_address_file(21044415) from dual; select dbms_utility.data_block_address_block(21044415) from dual;
結果是File為5,Block為72895。再用
Select tablespace_name,segment_type,owner,segment_name From dba_extents Where file_id=5 and 72895 between block_id and block_id+blocks-1;
得到Segment名為SYS_LOB0000075068C00059$$用
select table_name, column_name from dba_lobs where segment_name=’SYS_LOB0000075068C00059$$’ and owner =’VPXADMIN’
得到表名為VPX_HOST,列表為RESOURCE_INFO,測試一下: 這裡又出現了一個塊10309,用相同的方法找到是VPX_HOST表中的另一個列CAPABILITY,這種方法很明顯能找到故障表,但是對於修復卻幫助不大,因為數量太大,沒有辦法手工處理。 按上文中提到的修復方法先創一個表
create table corrupted_data (corrupted_rowid rowid);
然後,在SQL提示符下貼上下面指令碼程式碼,最後用/結束並執行。
set concat off declare error_1578 exception; pragma exception_init(error_1578,-1578); n number; begin for cursor_lob in (select rowid r, &&lob_column from &table_owner.&table_with_lob) loop begin n:=dbms_lob.instr(cursor_lob.&&lob_column,hextoraw(’889911′)); exception when error_1578 then insert into corrupted_data values (cursor_lob.r); commit; end; end loop; end;
根據提示符,輸入需要的各變數值,列名為RESOURCE_INFO,所有者VPXADMIN,表名為VPX_HOST。指令碼會把有問題行的ROWID寫到上表建立的表中。上面的程式碼中hextoraw(’889911′)有點奇怪,不知道是什麼意思,在上文最後到是提到了,原來這個值是隨便寫的,主要是讓n總是返回0值。 然後再將有問題行中的對應列資料填為空值。
set concat off update &table_owner.&table_with_lob set &lob_column=empty_blob() where rowid in (select corrupted_rowid from corrupted_data);
出現下面的錯誤提示
ORA-00932: inconsistent datatypes: expected NCLOB got BLOB
於是將上面的程式碼修改成
update &table_owner.&table_with_lob set &lob_column=empty_clob() where rowid in (select corrupted_rowid from corrupted_data);
回到命令列方式,用DBV再試一次,結果卻仍是有452個Page被標記為壞。 但是這次用Select * from vpxadmin.vpx_host;能返回正常的值了。說明表的確是被修復了。但量DBV結果仍標記為Corrupted,用DBV來找壞表的實用性就差了許多。像這樣有452個壞塊,一個一個地測試,太麻煩了。 轉到vCenter的伺服器中, 發現在啟動過程中,初始化VPXD時出錯。 檢視/var/log/vmware/vpx目錄下的日誌。大致可判斷為資料庫中資料讀出來後,反序列化出錯。但是因為上面的原因我又找到不出故障的表的內容,用OEM在表空間裡試了幾個表,都是好的,從VCenter日誌中也找不出線索,問題就變成死問題了。 看來只能重建一個表空間給vCenter用,原來保留的資料也只有放棄了。