例子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檔案,發現如下內容:
從上面來看,是控制檔案故障。 現在重建控制檔案,先到日誌檔案中找到一個相關引數的例子,在alert_sales.log檔案中找出[[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
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用,原來保留的資料也只有放棄了。