Программирование >>  Oracle 

1 ... 73 74 75 [ 76 ] 77 78 79 ... 469


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х повторного выполнения и отмены и продемонстрировал, что она не является излишней тратой ресурсов: журналы повторного выполнения и сегменты отката являются неотъемлемыми и необходимыми компонентами базы данных. Глубоко понимая их работу и назначение, вы сможете использовать их с максимальной отдачей. Кроме того, вы должны усвоить, что при более частой, чем необходимо, фиксации ничего не экономится (фактически ресурсы транжирятся: необходимо больше процессорного времени, больше места на диске и больше программирования). Разберитесь, что должен делать сервер баз данных, и позвольте ему функционировать нормально.



1 ... 73 74 75 [ 76 ] 77 78 79 ... 469

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика