我們在進行一個大的查詢的時候,往往會碰到這個錯誤:
創(chuàng)新互聯(lián)建站堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:做網(wǎng)站、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的華坪網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!回滾記錄版本太舊,無法獲取用戶記錄
碰到這種問題,我們怎么解決呢?
有三個方法
? 擇機執(zhí)行
? 適當調(diào)整 undo_retention
? 考慮啟用 ENABLE_IGNORE_PURGE_REC 參數(shù)
處理方法一:
在涉及到的數(shù)據(jù),無人改動時,執(zhí)行對應(yīng)的操作(查詢,或者查詢建表等),
可以簡單理解為(不是對等的情況,但是可以大概這么理解):在你執(zhí)行這個語句開始后,數(shù)據(jù)被其他人修改,而且提交了。數(shù)據(jù)庫保留了一份最新的值,這是修改后的值,基于事務(wù)可見性,你執(zhí)行的那個語句,是在修改之前開始的,不應(yīng)該查詢到被修改的數(shù)據(jù)。你應(yīng)該查詢到的是,修改之前的數(shù)據(jù) —— 這時候,修改過的舊值,就在回滾段里。
但是,數(shù)據(jù)庫不是一個可以無限存儲的機器啊,在回滾段里面的值,對應(yīng)的事務(wù)已經(jīng)提交的情況下,它本應(yīng)該可以被清理了,但是為了 我們當前執(zhí)行的這類查詢不報錯,我們也需要適當留一留。
那么,留多久,有一個 undo_retention 的參數(shù) 決定,2017 年往后的版本,默認值是 300s 了(以前默認是 900s )
如何查看這個值:
`select * from v$dm_ini where para_name LIKE 'UNDO_RETENTION'`
這個就是說,如果你這個sql 執(zhí)行時,涉及到的數(shù)據(jù),被其他人修改了,而且超過 300s 了,就有可能遇到報錯(回滾記錄版本太久)。
那么,我們 只要在無人修改相關(guān)數(shù)據(jù)的時候執(zhí)行,無論執(zhí)行多少個 300s 都不會報錯。
處理方法二:
暫時修改 undo_retention ,比如我們預(yù)期這個語句需要執(zhí)行 30min ,那么我么可以暫時修改這個參數(shù)為 30*60 = 1800
在執(zhí)行完后,在修改回原先的默認值。
這是修改為 18000 的sql 語句,直接通過 執(zhí)行sql 的方式,執(zhí)行這個語句,就對這個參數(shù)進行了調(diào)整
`sp_set_para_value(1,'UNDO_RETENTION',1800);`
相應(yīng) 的,這個就是修改回 300s
`sp_set_para_value(1,'UNDO_RETENTION',300);`
修改之前,確認下之前是多少。以免改錯(過大或過小)影響其他人或者其他應(yīng)用使用。(該值 過大對性能 是有負面影響的)
處理方法三:
在知道怎么回事的時候,我們也可以知道,數(shù)據(jù)庫給我們提供了這樣一個參數(shù),畢竟,對于數(shù)據(jù)庫的性能來說 undo_retention 保持較小的值比較好,個別的查詢,其實可以忽略那條數(shù)據(jù),不影響我們的執(zhí)行預(yù)期。那么,我們可以啟用這個參數(shù)(而且也是 動態(tài)參數(shù))
ENABLE_IGNORE_PURGE_REC 默認值為 0 動態(tài),會話級 當返回 EC_RN_NREC_PURGED ( -7120 )錯誤(回滾記錄版本太舊,無法獲取用戶記錄)時的處理策略; 0 :報錯; 1 :忽略這一條記錄,繼續(xù)執(zhí)行 |