作者:Digital Observer(施嘉偉)
Oracle ACE Pro: Database
PostgreSQL ACE Partner
11年數(shù)據(jù)庫行業(yè)經(jīng)驗(yàn),現(xiàn)主要從事數(shù)據(jù)庫服務(wù)工作
擁有Oracle OCM、DB2 10.1 Fundamentals、MySQL 8.0 OCP、WebLogic 12c OCA、KCP、PCTP、PCSD、PGCM、OCI、PolarDB技術(shù)專家、達(dá)夢師資認(rèn)證、數(shù)據(jù)安全咨詢高級等認(rèn)證
ITPUB認(rèn)證專家、PolarDB開源社區(qū)技術(shù)顧問、HaloDB技術(shù)顧問、TiDB社區(qū)技術(shù)布道師、青學(xué)會MOP技術(shù)社區(qū)專家顧問、國內(nèi)某高校企業(yè)實(shí)踐指導(dǎo)教師
公眾號:Digital Observer;CSDN:施嘉偉;ITPUB:sjw1933;墨天輪:Digital Observer;PGFans:施嘉偉。
達(dá)夢數(shù)據(jù)庫(DM)作為國產(chǎn)數(shù)據(jù)庫的代表之一,廣泛應(yīng)用于政府、金融等行業(yè)中。由于其較為復(fù)雜的架構(gòu)和配置,故障分析顯得尤為重要。以下是針對 達(dá)夢8 數(shù)據(jù)庫的故障分析方法,涵蓋了 SQL 類、實(shí)例類和人為操作類故障的處理步驟。
第一部分 SQL類故障
SQL類故障主要有三種類型,分別是:結(jié)果集異常、執(zhí)行長期沒有返回?cái)?shù)據(jù)、執(zhí)行過程中數(shù)據(jù)庫進(jìn)程異常等三種情況
1.1 結(jié)果集異常
首先我們要定位到結(jié)果集異常的語句,可以通過應(yīng)用日志、驅(qū)動日志、數(shù)據(jù)庫SQL日志、VSQL_HISTORY 視圖等方法找到該語句。一般情況下,結(jié)果集異常大部分是由于優(yōu)化器對查詢語句的錯誤改寫或者優(yōu)化導(dǎo)致的,我們盡量保證提取到的語句和實(shí)際執(zhí)行的語句是嚴(yán)格一致、綁定參數(shù)相同、數(shù)據(jù)庫參數(shù)一致,這樣可以保證我們進(jìn)行驗(yàn)證時能準(zhǔn)確的復(fù)現(xiàn)問題。在計(jì)劃一致的情況下,如果可以重現(xiàn)查詢結(jié)果集異常的情況,我們可以嘗試對異常的查詢語句進(jìn)行裁剪,也可以參照當(dāng)前計(jì)劃,有目的修改通過 SQL 語句摘除計(jì)劃中的某些操作符,一步步的得到導(dǎo)致結(jié)果集出錯的最精簡語句。然后通過修改參數(shù)、/HINT/ 、改寫語句等方式,調(diào)整問題操作符為等價的其他操作符來解決問題。
查看vsql_history視圖
打開數(shù)據(jù)庫監(jiān)控參數(shù),默認(rèn)為開啟狀態(tài)
SQL> alter system set 'ENABLE_MONITOR'=1;
應(yīng)用執(zhí)行相關(guān)問題模塊,然后查看v$sql_history,通過SQL_ID, SESS_ID,TRX_ID,TOP_SQL_TEXT, START_TIME等字段定位語句
SQL> select SQL_ID, SESS_ID,TRX_ID,TOP_SQL_TEXT,START_TIME from v$sql_history;
某些信息沒有及時更新也可能出現(xiàn)結(jié)果集異常,如:查詢涉及到全文索引沒有更新、查詢涉及到的物化視圖沒有更新、錯誤的使用確定性函數(shù)標(biāo)記了不確定函數(shù)、非一致讀備機(jī)查詢數(shù)據(jù)存在延遲。
1.2 執(zhí)行長時間沒有返回?cái)?shù)據(jù)
如果SQL執(zhí)行長時間沒有返回?cái)?shù)據(jù),可能由以下情況造成:所執(zhí)行語句本身存在性能問題、執(zhí)行過程中某些對象/資源發(fā)生等待,其他特殊情況等。
1.2.1 性能問題
先根據(jù)vsessions視圖確認(rèn)語句是否處于活動狀態(tài),再根據(jù)活動語句的trxid在vtrxwait視圖中查詢語句是否存在等待,沒有查詢結(jié)果的話就是語句沒有發(fā)生等待。如果語句活動中,且沒有發(fā)生等待,那大概率是存在性能問題,需要對語句進(jìn)行調(diào)優(yōu)。
通過state字段查詢語句是否在ACTIVE狀態(tài)
SQL> SELECT sess_id,sql_text,user_name,trx_id,state,clnt_ip FROM v$sessions WHERE state='ACTIVE' AND dbms_lob.substr(sf_get_session_sql(sess_id)) LIKE '%語句片段%';
根據(jù)獲取到的trxid查詢是否處于等待狀態(tài)
SQL> SELECT * FROM v$trxwait WHERE id = 上面SQL獲取到的trx_id
1.2.2 發(fā)生等待
如果語句處于活動狀態(tài),且在vtrxwaitc查詢中有返回記錄,說明語句有等待發(fā)生,然后通過WAIT_FOR_ID字段到vsessions中定位到所等待的會話信息,一般來說,都是因?yàn)槟承捇蛘呖蛻舳送涍M(jìn)行提交或者回滾操作,后續(xù)就一直空閑了,導(dǎo)致其他的事務(wù)由于跟該事務(wù)存在一些事務(wù)上的依賴關(guān)系發(fā)生等待,針對這種情況,我們需要在確認(rèn)安全的情況針對這個阻塞源頭會話進(jìn)行操作,關(guān)閉客戶端 /CLOSE 會話/發(fā)送提交或者回滾命令等。
另外一種等待不會通過 VTRXWAIT 查詢得到結(jié)果,比如某些表發(fā)生 DDL 操作過程中,其他的會話嘗試對該表進(jìn)行查詢,由于字典對象發(fā)生變化,所以發(fā)生字典對象的等待,這種阻塞可以通過查詢 SELECT * FROM vlock WHERE blocked = 1 來進(jìn)行確認(rèn),查詢結(jié)果中可以對相關(guān)鎖對象的持有事務(wù)來查詢 V$SESSIONS,來確認(rèn)阻塞來源。
一般情況下這種 DDL 導(dǎo)致的等待會有一個顯示的等待時間,由 dm.ini 參數(shù) DDL_WAIT_TIME 來進(jìn)行控制,默認(rèn)是 10,也就是說如果等待 10 秒鐘后,阻塞源頭的 DDL 還沒有執(zhí)行完釋放資源,會拋出鎖超時錯誤。
通過state字段查詢語句是否在ACTIVE狀態(tài)
SQL> SELECT sess_id,sql_text,user_name,trx_id,state,clnt_ip FROM v$sessions WHERE state='ACTIVE' AND dbms_lob.substr(sf_get_session_sql(sess_id)) LIKE '%語句片段%';
根據(jù)獲取到的trxid查詢是否處于等待狀態(tài)
SQL> SELECT * FROM v$trxwait WHERE id = 上面SQL獲取到的trx_id
然后根據(jù)vtrxwait視圖中獲取到的wait_for_id字段在vsessions定位到會話
SQL> SELECT * FROM v$sessions WHERE trx_id = 查詢到的 WAIT_FOR_ID
1.2.3 特殊情況
還有一些其他情況造成的等待:
(1)查詢中由于存在臨時表 /SORT/HASH JOIN/HAGR 等操作導(dǎo)致使用的臨時表空間,INI 參數(shù)又限制了 TEMP 表空間大小,在臨時表空間沒有被其他會話使用完并釋放時發(fā)生等待。
(2)主備、讀寫分離等環(huán)境運(yùn)行過程中,由于備機(jī)自身或者配置相關(guān)的原因(備機(jī) IO 出現(xiàn)異常、主備網(wǎng)絡(luò)異常、數(shù)據(jù)延遲達(dá)到配置的主備最大延遲)等,導(dǎo)致主機(jī)上運(yùn)行一些需要刷 REDO 日志的語句發(fā)生等待,這種等待需要備機(jī)上的這些現(xiàn)象緩解之后才會解開。
(3)大表發(fā)生 DELETE 量數(shù)據(jù)、TRUNCATE 后,對該表的查詢或者 DML 操作緩慢,這個時由于大批量刪除數(shù)據(jù)之后,由于這些數(shù)據(jù)都只是被標(biāo)記刪除,在一定事件后會由回收站進(jìn)行統(tǒng)一的清理操作,清理過程中需要對數(shù)據(jù)頁進(jìn)行修改,而涉及的數(shù)據(jù)頁又非常多,所以導(dǎo)致執(zhí)行速度緩慢。
(4)數(shù)據(jù)庫自身 BUG 導(dǎo)致的死鎖,正常情況下,如果存在某些事務(wù)互相等待的情況,數(shù)據(jù)庫會主動拋出死鎖報錯,但是如果時數(shù)據(jù)庫內(nèi)部自身 BUG,導(dǎo)致自身的一些臨界區(qū)資源出現(xiàn)死鎖,是不能自動處理的,一般我們最后考慮這種情況。
1.3 執(zhí)行過程中數(shù)據(jù)庫進(jìn)程異常
一般可分為以下幾種:運(yùn)行過程中數(shù)據(jù)庫發(fā)生 halt、運(yùn)行過程中數(shù)據(jù)庫段錯誤、運(yùn)行過程中發(fā)生PAGE FAULT、運(yùn)行過程中發(fā)生線程污染(TAINED)、運(yùn)行過程中發(fā)生 OOM 錯誤,具體信息可以看第二部分實(shí)例故障。
第二部分 實(shí)例故障
DM 實(shí)例故障,即數(shù)據(jù)庫進(jìn)程 dmserver 出現(xiàn)異常,表現(xiàn)為異常中止,進(jìn)程存在但無響應(yīng)或者無法登錄的狀態(tài),出現(xiàn)此類問題都屬于比較嚴(yán)重的故障,一般情況下我們需要盡可能的收集到所需要的信息進(jìn)行故障分析,這里我們將把故障分為兩類,一種是數(shù)據(jù)庫異常中止,一種是連接異常。
2.1 異常中止
數(shù)據(jù)庫異常時,可以通過查看進(jìn)程來確認(rèn)數(shù)據(jù)庫是否異常中止
shell> ps -ef|grep dmserver
dmdba 1199 1 0 09:06 ? 00:00:00 /home/dmdba/dmdbms/bin/dmserver /data/DAMENG/dm.ini -noconsole
root 1430 1388 0 09:07 pts/0 00:00:00 grep --color=auto dmserver
沒有dmserver進(jìn)程信息的,說明數(shù)據(jù)庫已經(jīng)異常中止
2.1.1 數(shù)據(jù)庫halt
數(shù)據(jù)庫實(shí)例在運(yùn)行過程中會實(shí)時進(jìn)行一些檢查,比如授權(quán)過期信息、文件完整性信息、內(nèi)存是否污染信息、數(shù)據(jù)頁校驗(yàn)信息等,如果出現(xiàn)一些比較嚴(yán)重的問題被數(shù)據(jù)庫自查到,數(shù)據(jù)庫自身會選擇自殺并給出提示信息,來防止更嚴(yán)重的錯誤產(chǎn)生。對于數(shù)據(jù)庫halt類型的錯誤,我們可以通過查看數(shù)據(jù)庫的運(yùn)行日志,搜索 halt,如果發(fā)現(xiàn)存在 halt 字樣的日志內(nèi)容,會在 halt 之前又具體的 halt 原因說明,這個是數(shù)據(jù)自己保證數(shù)據(jù)安全的一種方式,當(dāng)檢測到一些嚴(yán)重異常時,采取自殺的方式來保全數(shù)據(jù),防止更進(jìn)一步的異常。
查看數(shù)據(jù)庫日志抓取halt信息,日志命名方式為 dm_實(shí)例名_年月.log
shell> cat /home/dmdba/dmdbms/log/dm_DMSERVER01_202103.log |grep halt
對于其他幾種類型的錯誤,我們從數(shù)據(jù)庫運(yùn)行日志中一般不會發(fā)現(xiàn)明顯的信息,都是運(yùn)行日志刷新過程中突然中斷了,這些錯誤我們可以通過查詢操作系統(tǒng)日志(一般是 /var/log/messages*),然后搜索異常前的 dmserver 的進(jìn)程號或者搜索 DM 相關(guān)的信息,根據(jù)查詢到的信息不同的類型進(jìn)行不同的處理。
查看系統(tǒng)日志,搜索DM異常信息
cat /var/log/messages* |grep DM
2.1.2 段錯誤
一種是因?yàn)?halt 時,通過主動進(jìn)行除 0 操作引發(fā)的異常,另一種是由于數(shù)據(jù)庫自身 BUG,導(dǎo)致發(fā)生內(nèi)存寫溢出、越界、空指針操作等引起的異常。
第二種情況發(fā)生時通常數(shù)據(jù)庫日志、系統(tǒng)日志中均沒有相關(guān)記錄,會在bin目錄下生成一個core文件,通常是因?yàn)椴僮飨到y(tǒng)、cpu與數(shù)據(jù)庫軟件版本的兼容性有關(guān),建議更換數(shù)據(jù)庫軟件版本或操作系統(tǒng)。
2.1.3 PAGE FUALT
一般 PAGE FUALT 后會跟有具體的錯誤碼,code: xx,在 LINUX 內(nèi)核中定義了這些報錯對應(yīng)的內(nèi)容。
如果 code 是 0,一般是由于數(shù)據(jù)庫運(yùn)行中沒有辦法申請到需要使用的內(nèi)存導(dǎo)致,這種時候需要考慮修改 INI 相關(guān)配置,調(diào)整數(shù)據(jù)庫的內(nèi)存使用量。其他幾種 code 或者是 code 的組合(比如 6 = 4 + 2 表示存在兩種錯誤),基本是發(fā)生內(nèi)存讀寫越界引起。
2.1.4 線程污染TAINED
如果操作系統(tǒng)日志中出現(xiàn)了 DM 相關(guān)線程 tained 相關(guān)的信息,一般是由于第三方軟件(主要是殺毒軟件或者安全軟件),對 DM 的相關(guān)線程進(jìn)行污染,導(dǎo)致數(shù)據(jù)庫的一些線程被異常中止,不同類型的線程被中止可能導(dǎo)致不同的結(jié)果,而且是不可預(yù)期的,這種情況下需要及時調(diào)整現(xiàn)場的環(huán)境,讓相關(guān)軟件盡量不影響數(shù)據(jù)庫進(jìn)程
2.1.5 OOM錯誤
OOM 操作系統(tǒng)本身對于自己的一種保護(hù)機(jī)制,對占用大量內(nèi)存的進(jìn)程,如果滿足一定條件,就會被操作系統(tǒng)中止,騰出空余內(nèi)存,如果頻繁發(fā)生數(shù)據(jù)庫進(jìn)程被 oom kill,則需要調(diào)整數(shù)據(jù)庫內(nèi)存相關(guān)參數(shù),操作系統(tǒng)內(nèi)存相關(guān)參數(shù)等,防止數(shù)據(jù)庫進(jìn)程被頻繁 oom。
2.2 連接異常
使用本地disql工具連接數(shù)據(jù)庫,測試連接是否異常
SYSDBA/SYSDBA為數(shù)據(jù)庫用戶名和密碼,5236為數(shù)據(jù)庫端口號
shell> home/dmdba/dmdbms/disql SYSDBA/SYSDBA@127.0.0.1:5236
2.2.1 配置不正確
大多數(shù)情況下,連接異常類問題都是由于配置不正確導(dǎo)致。具體的表現(xiàn):在任務(wù)管理器中查看 dmserver 進(jìn)程能夠看到正常的 CPU 活動信息,查看磁盤網(wǎng)絡(luò)等活動也存在正常的波動,但是新建連接連接數(shù)據(jù)庫會提示網(wǎng)絡(luò)通訊異常。
常見原因:
(1)dm.ini 中限制了最大連接數(shù)(相關(guān)參數(shù) MAX_SESSIONS),數(shù)據(jù)庫連接達(dá)到該值后會拒絕創(chuàng)建新連接,在數(shù)據(jù)庫運(yùn)行日志中會發(fā)現(xiàn) reach max session limit 相關(guān)日志。
查看MAX_SESSIONS信息
SQL> select * from v$dm_ini where para_name='MAX_SESSIONS';
查看當(dāng)前連接數(shù)
select count(*) from v$sessions;
(2)由于操作系統(tǒng)的用戶資源限制引起,我們通過命令 cat /proc/dmserver 的 pid/limits 可以查看到當(dāng)前數(shù)據(jù)庫進(jìn)程的一些資源限制,我們主要關(guān)注的是 Open files 這個限制,由于在 DM 中每一個會話都是一個線程,一個線程在 linux 中需要一個獨(dú)立的文件句柄去控制,如果該項(xiàng)限制太小,會導(dǎo)致創(chuàng)建線程失敗,從而在外部顯示為連接數(shù)據(jù)庫失敗,這種情況一般在數(shù)據(jù)庫運(yùn)行日志中會有 create thread failed 相關(guān)信息,并且檢查進(jìn)程 limits 會發(fā)現(xiàn) Open files 限制的較小,通過 ls -l /proc/dmserver 的 pid/fd|grep -c 命令,查看數(shù)據(jù)庫已經(jīng)打開的句柄以及等于或者超過 limits 值,由于這些 limits 是在進(jìn)程啟動時生效的,不能動態(tài)修改,如果已經(jīng)出現(xiàn)了這種現(xiàn)象,只能修改相關(guān)的配置(ulimit -n 65535等命令),并且重啟數(shù)據(jù)庫進(jìn)程。
查看dmserver資源限制,1199為dmserver的進(jìn)程號
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 39419 39419 processes
Max open files 1024 4096 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 39419 39419 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
查看進(jìn)程已打開句柄數(shù)
shell> ls -l /proc/1199/fd|grep -c ">"
2.2.2 數(shù)據(jù)庫缺陷
還有些情況是由于數(shù)據(jù)庫自身的缺陷引起,如果出現(xiàn)連接異常,檢查數(shù)據(jù)庫配置以及操作系統(tǒng)配置沒有發(fā)現(xiàn)異常,并且連接數(shù)據(jù)庫時長期不成功也不返回報錯,這種情況大概率時由于數(shù)據(jù)庫自身的原因?qū)е驴蛻舳诉B接過程中發(fā)生資源等待或者死鎖,導(dǎo)致登錄消息一直陷入在資源/臨界區(qū)等待狀態(tài)。
第三部分 人為操作
DM 數(shù)據(jù)庫實(shí)例包含數(shù)據(jù)文件部分和執(zhí)行文件,執(zhí)行文件即通過 DM 的安裝包安裝后在目標(biāo)機(jī)器上存在的可執(zhí)行程序以及動態(tài)庫,數(shù)據(jù)文件是通過 DM 的實(shí)例初始話工具初始化的實(shí)例文件,包含數(shù)據(jù)文件(DBF 文件)、配置文件(ini 文件)、控制文件(ctl 文件)以及一些其他必須的文件 (dm_service.prikey) 等,若此類文件在運(yùn)行過程中被誤刪除,可能導(dǎo)致異常的情況。
另外在運(yùn)維過程中,可能存在對數(shù)據(jù)的誤操作,更新、刪除插入等,如果存在這種情況,也可能導(dǎo)致應(yīng)用系統(tǒng)的問題。
3.1 誤刪文件
3.1.1 執(zhí)行文件
在 Windows 環(huán)境下,執(zhí)行文件在被引用過程中是無法被刪除的,出現(xiàn)此類問題的情況比較少,但在 Linux 環(huán)境下,數(shù)據(jù)庫進(jìn)程存在的情況下,相關(guān)執(zhí)行文件可以被刪除,程序會繼續(xù)運(yùn)行,但是運(yùn)行過程中的日志等文件在程序執(zhí)行完后可能會丟失,此中情況下,通過查詢 dmserver 的進(jìn)程 pid,然后進(jìn)入到 /proc/pid/cwd 路徑下,依然可以看到執(zhí)行過程中依賴的相關(guān)文件,可以通過拷貝命令將相關(guān)文件拷貝存放,供后續(xù)使用。
3.1.2 dm_service.prikey
該實(shí)例的 RSA 鑰文件,涉及基本的數(shù)據(jù)庫一些重要數(shù)據(jù)的加解密,誤刪除無法簡單處理,需重新初始化實(shí)例。
3.1.3 控制文件
控制文件,即 dm.ctl,記錄數(shù)據(jù)庫實(shí)例的實(shí)例相關(guān)信息、數(shù)據(jù)版本信息和重做日志文件、數(shù)據(jù)文件路徑屬性等,如果被異常刪除,表空間屬性相關(guān)修改可能出現(xiàn)異常,如果不能正常修復(fù),可能導(dǎo)致某些數(shù)據(jù)文件、REDO 日志文件沒有被數(shù)據(jù)庫實(shí)例納入到管理范圍,引發(fā)其他的嚴(yán)重問題。
如果發(fā)現(xiàn)(一般在巡檢中)該文件被異常刪除,需要及時對該文件進(jìn)行修復(fù),DM 數(shù)據(jù)庫自身定期會對該文件進(jìn)行備份,ctl 的備份路徑可以在 dm.ini 中進(jìn)行配置,在該目錄下找到最接近故障時間的 ctl 備份文件進(jìn)行恢復(fù)。
3.1.4 重做日志文件
默認(rèn)在數(shù)據(jù)庫實(shí)例下存在以實(shí)例名 .log 命名的重做日志文件,該文件記錄的是數(shù)據(jù)庫運(yùn)行過程中對實(shí)際的數(shù)據(jù)文件修改的日志信息,并且相關(guān)的修改信息達(dá)到一定的條件才會實(shí)際被應(yīng)用在數(shù)據(jù)文件上,如若發(fā)生誤刪除,首先在日志上這些部分未應(yīng)用日志信息涉及的數(shù)據(jù)一定就丟失了,另外可能導(dǎo)致數(shù)據(jù)庫無法正常啟動。
首選的恢復(fù)方式是通過備份還原,由于歸檔文件中如實(shí)的記錄了重做日志的信息,所以 REDO 中涉及的數(shù)據(jù)通過備份還原并對歸檔的讀取可以正常的將數(shù)據(jù)庫恢復(fù)。
如果備份還原不可用,或者歸檔丟失等,只能通過替換重做日志文件的方式對庫做應(yīng)急處理,如下所示:
(1)通過 dminit 工具初始化一個新的實(shí)例,相關(guān)參數(shù)參考目前故障庫的 dminitxxxx.log 中的配置保持一致。
(2)將新建實(shí)例正常啟動并停止一次。
(3)將新實(shí)例的重做日志文件拷貝到故障庫下。
(4)通過 $DM_HOME/bin 目錄下的 dmmdf 工具查看故障庫的數(shù)據(jù)文件的相關(guān)信息。
(5)用 dmmdf 工具按照前面查到的信息對拷貝過來的新重做日志文件修改兩個 magic 值。
(6)修改完成后,數(shù)據(jù)庫可以正常啟動。
此類方法在集群環(huán)境下不適用,由于重做日志記錄的部分頭部信息和實(shí)例間同步相關(guān),新建重做日志會導(dǎo)致集群不可用,另外這種方法只能臨時用于啟動數(shù)據(jù)庫,需要盡快將數(shù)據(jù)遷出至健康環(huán)境。
3.1.5 數(shù)據(jù)文件
如果運(yùn)行過程中 DBF 文件被誤刪除,首選的方式是通過備份還原對數(shù)據(jù)庫進(jìn)行最大長度的恢復(fù)(指定時間點(diǎn)),如果備份不存在或者不可用,在可能的情況下,盡可能快的停止一切對數(shù)據(jù)庫的寫操作(切斷應(yīng)用、網(wǎng)絡(luò)),同樣,如果在 Linux 環(huán)境下,可能對該文件還存在鏡像,可以從 proc 中進(jìn)行冷拷貝操作嘗試還原。
3.2 誤修改、刪除數(shù)據(jù)
如果存在誤操作,并且語句沒有提交的,可直接rollback進(jìn)行回滾,如果出現(xiàn)誤操作并提交,最安全的辦法依然是通過備份恢復(fù)到盡可能新的狀態(tài),如若備份、歸檔存在問題,則需要其他的方式進(jìn)行處理。
3.2.1插入
對于錯誤插入,在 DM 的每一行數(shù)據(jù)上,都存在 trxid 偽列,一般情況誤插入如果是批量的,通過查詢相關(guān)事務(wù)號進(jìn)行分組,確認(rèn)批量行數(shù),結(jié)合檢查數(shù)據(jù)一般是可以找到問題數(shù)據(jù)再進(jìn)行清理。
3.2.2刪除
當(dāng)數(shù)據(jù)發(fā)生刪除并提交時,實(shí)際的數(shù)據(jù)還是存在于數(shù)據(jù)文件上的,只是該行數(shù)據(jù)被打上了刪除標(biāo)記,被打上刪除標(biāo)記的數(shù)據(jù)對查詢是不可見的,并且在 ini 配置的 undo_retention 時間后,有刪除標(biāo)記的數(shù)據(jù)會被完全清理,在數(shù)據(jù)文件上就不可見了。如果啟用了閃回查詢,出現(xiàn)此類問題時,直接通過閃回查詢指定時間點(diǎn),可以將不可見的數(shù)據(jù)直接返回到數(shù)據(jù)庫客戶端上(UPDATE類似),然后將這些數(shù)據(jù)進(jìn)行落地保存,用于后續(xù)的修復(fù)。
如果開啟了邏輯附加歸檔,可以通過 dbms_logmnr 工具對邏輯附加歸檔進(jìn)行分析,分析完成后獲取相關(guān)數(shù)據(jù)信息,用于數(shù)據(jù)回填。
3.2.3更新
如果是 UPDATE 誤操作,且不滿足以上幾種恢復(fù)的條件,如果存在物理歸檔,可以通過 $DM_HOME/bin 目錄下的 dmlcvt 工具對歸檔進(jìn)行分析(具體用法參考 dmlcvt help),分析表空間號為 1(ROLL.DBF)的所有記錄,分析完成后,在分析結(jié)果中找到所有的 urec_upd 類型記錄,該記錄包含了更新涉及的 KEY,以及更新的舊值信息,使用這些信息還原更新。
在處理 SQL 類故障、實(shí)例故障 和 人為操作 方面的故障時,最重要的是保持冷靜、系統(tǒng)地排查問題,并結(jié)合豐富的工具和日志資源,確保能夠精準(zhǔn)定位問題的根本原因。無論是性能問題、系統(tǒng)資源的瓶頸,還是因人為操作引發(fā)的數(shù)據(jù)異常,都需要有條理地逐步解決。
總結(jié)建議:
-
備份與恢復(fù): 在所有操作中,始終保持最新的備份。及時備份數(shù)據(jù)文件、控制文件和日志文件是避免災(zāi)難性故障后果的最有效手段。
-
系統(tǒng)監(jiān)控與日志分析: 配置完善的監(jiān)控系統(tǒng),定期查看關(guān)鍵系統(tǒng)的運(yùn)行狀況。
-
應(yīng)急響應(yīng): 針對各種故障,盡量提前準(zhǔn)備好應(yīng)急方案,并定期進(jìn)行故障演練,確保在出現(xiàn)故障時能迅速反應(yīng),減少系統(tǒng)停機(jī)時間。
-
問題復(fù)現(xiàn)與調(diào)優(yōu): 當(dāng)問題復(fù)現(xiàn)時,要確保測試環(huán)境和生產(chǎn)環(huán)境的一致性,以便能夠準(zhǔn)確診斷。對于慢查詢、死鎖等常見問題,調(diào)優(yōu)建議應(yīng)結(jié)合實(shí)際工作負(fù)載和業(yè)務(wù)需求,逐步推進(jìn)。
通過持續(xù)的監(jiān)控、系統(tǒng)優(yōu)化和故障應(yīng)急演練,能夠?qū)?shù)據(jù)庫故障的風(fēng)險降到最低,確保系統(tǒng)的穩(wěn)定性和可靠性。同時,通過不斷總結(jié)經(jīng)驗(yàn),優(yōu)化流程,將能夠有效提高團(tuán)隊(duì)?wèi)?yīng)對復(fù)雜數(shù)據(jù)庫問題的能力。





