|
Программирование >> Oracle
196900 Для возникновения представленной выше ошибки я использовал ту же таблицу Т с примерно 22000 строк, как и в прежних примерах (в моей системе она занимает около 300 блоков). У меня сконфигурирован буферный кэш размером 300 блоков (10 процентов от него составляет 30 блоков). Оператор UPDATE в строке 4 должен оставить около 270 блоков, требующих очистки. Затем мы выполняем оператор SELECT * из таблицы, в которой требуется очистить множество блоков. Для каждой извлекаемой строки выполняется 20 транзакций, причем я предусмотрел, чтобы эти транзакции направлялись в тот же сегмент отката, что и первоначальный оператор UPDATE (конечная цель - переписать его слот в таблице транзакций). После обработки около 10000 строк в запросе к таблице Т (о чем свидетельствует значение в таблице SMALL) мы получили сообщение об ошибке ORA-01555. Теперь, чтобы показать, что это не связано с извлечением данных в нескольких транзакциях (это вполне возможно, поскольку при извлечении данных выполняются операторы COMMIT), мы используем два сеанса. Первый сеанс мы начнем с создания таблицы STOP OTHER SESSION. Ее мы будем использовать для уведомления другого сеанса, генерирующего множество транзакций, что пора остановиться. Затем, сеанс изменит множество блоков в таблице еще раз, как в предыдущем примере, и начнет продолжительный запрос к таблице. Процедура DBMS LOCK. SLEEP используется для реализации ожидания между извлечениями строк, что увеличивает время выполнения запроса. Это имитирует время выполнения, необходимое для сложной обработки каждой строки: tkyte@TKYTE816> create table stop other session (x int) ; Table created. tkyte@TKYTE816> declare 2 l cnt number := 0; 3 begin 4 commit; 5 set transaction use rollback segment rbs small; 6 update t 7 set object type - lower(object type); 8 commit; 9 10 for x in (select * from t) 11 loop 12 dbms lock.sleep(1); 13 end loop; 14 end; 15 / Теперь, пока выполняется представленный выше код, в другом сеансе необходимо выполнить следующее: tkyte@TKYTE816> create table small(x int) ; Table created. tkyte@TKYTE816> insert into small values (0) ; 1 row created. tkyte@TKYTE816> begin 2 commit; 3 set transaction use rollback segment rbs small; 4 for i in 1 . . 500000 5 loop 6 update small set x = x+1; 7 commit; 8 set transaction use rollback segment rbs small; 9 for x in (select * from stop other session) 10 loop 11 return; - остановиться, когда другой сеанс попросит это - сделать 12 end loop; 13 end loop; 14 end; 15 / PL/SQL procedure successfully completed. Через некоторое время в первом сеансе будет получено такое сообщение: declare ERI GR at line 1: ORA-01555: snapshot too old: rollback segment number 10 with name RBS SM too small ORA-06512: at line 10 Сообщение об ошибке - то же самое, но теперь мы не извлекали данные в нескольких транзакциях, т.е. читаемые данные никем не изменялись. Как я уже упоминал, это - редкий случай. Необходимо стечение многих обстоятельств. Необходимо наличие блоков, требующих очистки, а такие блоки в версии Oracle8i встречаются редко (это случалось в версиях 7.x и 8.0). Оператор сбора статистики ANALYZE избавляет от этих блоков, поэтому большинство обычнгх причин их возникновения, в частности множественные изменения и загрузку большого объема данных, можно не учитывать, поскольку после таких действий таблицы все равно надо анализировать. Транзакции затрагивают менее 10 процентов блоков в буферном кэше, т.е. не генерируют блоки, требующие очистки. Если вы уверены, что столкнулись именно с этой проблемой (оператор SELECT к таблице, к которой не применяются при этом операторы ЯМД, заканчивается сообщением об ошибке ORA-01555), попытайтесь сделать следующее. Прежде всего убедитесь, что используете транзакции соответствующего размера. Проверьте, что не фиксируете транзакции чаще, чем это необходимо. Проанализируйте соответствующие объекты. Поскольку очистка блоков требуется в результате очень больших множественных изменений или вставок данных, это все равно надо сделать. Увеличьте размер сегментов отката или создайте дополнительные. Благодаря этому уменьшится вероятность перезаписи слота таблицы транзакций сегмента отката в случае продолжительного запроса. Кроме того, это позволит избежать других причин возникновения ошибки ORA-01555 (фактически эти две причины тесно связаны; при обработке запроса вы сталкиваетесь с повторным использованием сегмента отката). Сократите время выполнения запроса (настройте его). В случае успеха это будет удачным решением, поэтому именно с этого и стоит начать. Резюме В этой главе мы рассмотрели значение для разработчика данных повторного выполнения и отмены. Здесь я представил в основном те проблемы, которые касаются администратора базы данных или системного администратора. Я показал важность данн1х повторного выполнения и отмены и продемонстрировал, что она не является излишней тратой ресурсов: журналы повторного выполнения и сегменты отката являются неотъемлемыми и необходимыми компонентами базы данных. Глубоко понимая их работу и назначение, вы сможете использовать их с максимальной отдачей. Кроме того, вы должны усвоить, что при более частой, чем необходимо, фиксации ничего не экономится (фактически ресурсы транжирятся: необходимо больше процессорного времени, больше места на диске и больше программирования). Разберитесь, что должен делать сервер баз данных, и позвольте ему функционировать нормально.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |