Oracle 存盤程序在執行時突然拋出 ORA-01555。
select
a,b
from table1 S into a_var,b_var
where s.abc=systedate
and requiedate between add_months(sysdate,-2) and sysdate
AND Currency= NVL(currency_CODe,USD)
group by S.actcount;
table1_invoice(1)=a_var;
table1_invoice(2)=b_var;
FORALL indx in 1..test.count SAVE EXCEPTIONS
insert into table2 values
table1_invoice(indx);
當程式運行并使用表 A 時,我在同一個表上并行執行索引重建。
完成后,我在表 A 上執行收集統計資訊。
這是否會產生錯誤 ORA-01555。重建索引是否消耗回滾段,未提交資料的舊快照被洗掉。
我已經粘貼了虛擬代碼。
uj5u.com熱心網友回復:
我在同一張表上并行執行索引重建。
這可能是您的原因。ORA-1555 與能夠為您提供一致的資料視圖有關。例如,使用您的虛擬代碼作為模板:
- 你在上午 9 點打開游標
- 您在上午 9 點開始從該游標中獲取資料,假設查詢的總執行時間為 60 秒。
- 因此,假設您在該提取的 40 秒標記處。因為(您)讀取資料并不會阻止其他人更改它,您可能會遇到一些最近被其他人更改(例如 3 秒前)的資料。
- 我們無法向您提供該資料,因為我們必須向您顯示上午 9 點的資料(當您的查詢開始時)。
- 因此,我們找到了 3 秒前更改該資料的事務,并使用這些事務寫入的撤消資訊來撤消更改。我們將繼續這樣做,直到資料現在看起來像早上 9 點
- 現在我們可以使用該(撤消的)資料,因為它與您打開游標的時間一致。
那么 ORA-1555 適合在哪里呢?如果我們的查詢運行(比如說)一個小時怎么辦?現在我們可能需要撤消近一個小時前運行的其他事務。我們為(已完成的)事務的撤消保留的空間只有這么多,因為我們需要在新事務進入時釋放它。我們丟棄舊的東西,因為這些事務已經提交。所以重新審視上面的處理,可能會發生以下情況:
- 你在上午 9 點打開游標
- 您在上午 9 點開始從該游標中獲取資料,假設查詢的總執行時間為 60 秒。
- 因此,假設您在該提取的 40 秒標記處。因為(您)讀取資料并不會阻止其他人更改它,您可能會遇到一些最近被其他人更改(例如 3 秒前)的資料。
- 我們無法向您提供該資料,因為我們必須向您顯示上午 9 點的資料(當您的查詢開始時)。
- 因此,我們找到 3 秒前更改該資料的事務,并使用這些事務寫入的撤消資訊來撤消更改。
- 不好了!該撤消資訊已被丟棄!!!
現在我們被卡住了,因為我們不能再給你早上 9 點的資料了,因為我們不能把一些改變的資料一直帶回早上 9 點。您想要的資料的時間快照太舊了。
因此“ORA-1555:快照太舊”
這就是為什么最常見的解決方案只是重試您的操作,因為現在您是在最近的時間開始查詢。
所以你可以看到 - 在查詢時從其他會話對資料庫進行的活動越多,遇到 ORA-1555 的風險就越大,因為撤消空間正在迅速消耗,因此我們可能會更多地丟棄舊的東西迅速。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/461926.html
上一篇:oracle-合并多個列值
