講解為使用者提供對回滾操作時間準確評估

2021-04-23 07:21:08 字數 3763 閱讀 3552

講解為使用者提供對回滾操作時間準確評估

在回滾長期執行的事務時,經常會有些使用者不停地詢問相同的問題。這些問題是合理的,因為該事務進行了鎖定,正常的處理經常受到回滾程序的影響。

在 oracle 9i database 及更低的版本中,您可以執行查詢

select used_urec

from v$transaction;

該語句返回由當前事務所使用的重做記錄的數量,而如果重複地執行該語句,將會顯示連續減少的數值,因為回滾程序在其處理過程中會釋放重做記錄。隨後您可以通過對一段間隔進行快照來計算其速率,然後推斷出評估結束時間的結果。

雖然在檢視 v$transaction 中有乙個名為 start_time 的列,但該列只顯示整個事務的起始時間(也就是在回滾執行之前)。因此,除了推斷,您沒有辦法知道回滾實際上是在什麼時間執行的。

事務回滾的擴充套件統計資訊

在 oracle database 10g 中,這種操作很簡單。當事務回滾時,事件被記錄在檢視 v$session_longops 中,該檢視顯示長期執行的事務。用於回滾,如果程序耗時超過六秒,則記錄出現在該檢視中。在回滾執行以後,您可能會隱藏所檢視的監視螢幕並執行以下的查詢:

select time_remaining

from v$session_longops

where sid = ;

既然您意識到這個檢視 v$session_longops 的重要性,就讓我們來看它必須提供的其他資訊。該檢視在 oracle database 10g 的預覽版中提供,但沒有捕獲關於回滾事務的資訊。為了以一種易讀的方式顯示所有的列,我們將使用由 tom kyte 在 asktom.com 中所描述的 print_table 函式。此過程簡單地以**方式而不是常用的行方式來顯示列。

sql> set serveroutput on size 999999

sql> exec print_table(@#select * from

v$session_longops where sid = 9@#)

sid : 9

serial# : 68

opname :transaction rollback

target :

target_desc :xid:0x000e.01c.00000067

sofar : 20554

totalwork : 10234

units :blocks

start_time :07-dec-2003 21:20:07

last_update_time :07-dec-2003 21:21:24

time_remaining : 77

elapsed_seconds : 77

context : 0

message :transaction rollback:xid:0x000e.01c.00000067 :

10234 out of 20554 blocks done

username :sys

sql_address :00000003b719ed08

sql_hash_value : 1430203031

sql_id :306w9c5amyanr

qcsid : 0

注意,此處顯示對行的所有更改,即使刪除並重新插入行時也是如此。version_operation 列顯示對該行執行的操作 (insert/update/delete)。完成這些操作不需要歷史表或額外的列。

讓我們仔細檢查這些列中的每一列。在會話中可能會有超過多個長期執行操作 — 特別是因為檢視中包含以前的會話中所有長期執行操作的歷史。列 opname 顯示該記錄用於「事務回滾」,這為我們指出了正確的方向。列 time_remaining 顯示所評估的剩餘時間秒數,這在前面已經描述過,而列 elapsed_seconds 顯示到目前為止所消耗的時間。

那麼該錶如何提供對剩餘時間的評估呢?可以在列 totalwork 中找到線索,該列顯示要完成的「工作」總量,還有 sofar 顯示到目前為止已經完成了多少工作。工作的單位顯示在列 units 中。在本例中以資料塊為單位;因此,到目前為止已經回滾了 20,554 個資料塊中共計 10,234 個資料塊。此操作到目前為止已消耗了 77 秒。因此,剩餘資料塊將消耗:

77 * ( 10234 / (20554-10234) ) ? 77 秒

但您不必利用這種方法來獲得該數值,它已經清楚地顯示出來了。最後,列 last_update_time 顯示有關當前檢視內容的時間,這將用於加強您對結果的解釋。

sql 語句

另一部分重要的新資訊是正在被回滾的 sql 語句的識別符號。在早先,sql_address 和 sql_hash_value 用於獲取正在被回滾的 sql 語句。新的列 sql_id 對應於檢視 v$sql 的 sql_id,如下所示:

select sql_text

from v$sql

where sql_id = ;

該查詢返回所回滾的語句,因此提供了額外的校驗以及 sql 語句的位址和雜湊值。

並行例項恢復

如果 dml 操作是並行操作,則列 qcsid 顯示並行查詢伺服器會話的 sid。在並行回滾事件中,如例項恢復以及隨後的故障事務恢復期間,經常用到該資訊經常。

例如,假設在大型的更新期間,例項異常關閉。當例項啟動時,發生故障的事務被回滾。如果啟用了用於並行恢復的初始化引數值,則回滾並行地而不是序列地發生,如同它發生在常規事務回滾中一樣。下一步的任務是評估回滾程序的完成時間。

檢視 v$fast_start_transactions 顯示為回滾故障事務所產生的事務。類似的檢視 v$fast_start_servers 顯示對回滾進行處理的並行查詢伺服器的數量。這兩個檢視都在以前的版本中提供,但顯示事務識別符號的新列 xid 使得聯接更方便了。在 oracle9i database 以及更低的版本中,您必須通過三列(usn — 重做段號,slt — 重做段中的儲存區號,seq — 序列號)來聯接檢視。其父集顯示在 parentusn、parentslt 和 parentseq 中。在 oracle database 10g 中,您只需將其聯接到 xid 列,其父 xid 由直觀的名稱表示:pxid。

最有用的資訊部分來自於 v$fast_start_transactions 檢視中的列 rcvservers。如果發生並行回滾,則該列中顯示並行查詢伺服器的數量。您可以檢視該列,了解啟動了多少並行查詢程序:

select rcvservers from v$fast_start_transactions;

如果輸出是 1,則事務正在由 smon 程序進行序列回滾 — 顯然這是完成工作的一種不充分的方法。您可以將初始化引數 recovery_parallelism 的值改為除 0 或 1 以外的值,重新啟動例項進行並行回滾。隨後您可以執行 alter system set fast_start_parallel_rollback = high,按 cpu 數量的 4 倍建立並行伺服器。

如果上述查詢的輸出顯示不是 1,則正在進行並行回滾。您可以查詢同一檢視 (v$fast_start_transactions) 來獲得父事務和子事務(父事務 id — pxid,而子事務 id — xid)。xid 還可用於聯接此檢視與 v$fast_start_servers,以獲得其他詳細資訊。

結論

總之,當在 oracle database 10g 中回滾長期執行的事務時 — 無論是並行例項恢復會話還是使用者執行的回滾語句 — 您所需做的一切就是檢視檢視 v$session_longops 並評估還需要多少時間

開源就是為使用者提供更多選擇

開源是未來的趨勢,它能讓企業增強自身的競爭力。紅帽公司亞太區高階市場總監frank feldmann在接受記者採訪時表示,今後,如果不採用開源架構,企業就不可能取得成功。從linux作業系統到開放混合雲,紅帽公司在不斷拓寬產品領域的同時,始終堅持 開源 開放 這一核心原則,並讓其客戶和合作夥伴從開源...

C 編譯器何時為使用者提供預設建構函式

第一種是類成員中有成員是類物件,並且該成員的類含有預設建構函式,那麼c 編譯器會幫你給這個類也生成乙個預設建構函式,用來呼叫其成員物件的建構函式,完成該成員的初始化構造。需要強調的是,如果這個成員的類也沒有給出缺省建構函式,那麼c 編譯器也不會幫你生成該類的預設建構函式。第二種情況是這個類的基類有預...

C 編譯器何時為使用者提供預設建構函式

第一種是類成員中有成員是類物件,並且該成員的類含有預設建構函式,那麼c 編譯器會幫你給這個類也生成乙個預設建構函式,用來呼叫其成員物件的建構函式,完成該成員的初始化構造。需要強調的是,如果這個成員的類也沒有給出缺省建構函式,那麼c 編譯器也不會幫你生成該類的預設建構函式。第二種情況是這個類的基類有預...