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

1 ... 69 70 71 [ 72 ] 73 74 75 ... 469


Учитывая все это, избегайте удаления строк из временных таблиц. Можно использовать оператор TRUNCATE или дождаться автоматической очистки при фиксировании транзакции или удалении сеанса. Все эти методы не генерируют данные отмены и, как следствие, данные повторного выполнения. Старайтесь не изменять временные таблицы, если для этого нет серьезной причины. Временные таблицы используются в основном для вставки данных и запросов. При этом оптимально используется их уникальная возможность - не генерировать данные повторного выполнения.

Анализ данных повторного выполнения

Завершая рассмотрение файлов журнала повторного выполнения, попробуем ответить на часто задаваемый вопрос: как проанализировать эти файлы? Ранее, до появления версии Oracle 8i, это было очень сложно. Приходилось обращаться в службу поддержки Oracle, чтобы получить магическую команду для перевода содержимого файла журнала повторного выполнения в текстовый вид. В результате создавался текстовый отчет, который можно было читать и, имея некоторое представление о внутренних, недокументированных особенностях СУБД Oracle, даже приходить к каким-то выводам. С практической точки зрения это было неприемлемо, особенно если надо было проанализировать файлы журнала повторного выполнения и найти, скажем, время удаления таблицы или установки отрицательного значения столбца SALARY в транзакции и т.п.

И тут появился Log Miner. Речь идет о новом пакете, DBMS LOGMNR, поставляемом в составе Oracle 8i и позволяющем загружать содержимое файлов журнала повторного выполнения в таблицу базы данных V$, а затем выполнять к ней SQL-запросы. Можно получить предварительное и окончательное значение каждого столбца, затронутого оператором ЯМД. Можно получить SQL-оператор, фактически повторно выполняющий или отменяющий транзакцию. В этой таблице можно найти оператор удаления из таблицы OBJ$ (принадлежащая пользователю SYS таблица словаря данных) и увидеть, когда именно была случайно удалена таблица. Вдруг администратор базы данных сможет вернуть базу данных в состояние на момент времени, непосредственно предшествующий выполнению этого оператора DROP TABLE и восстановить таблицу.

Пока я просто упомяну Log Miner. В приложении А пакет DBMS LOGMNR будет описан детально. Подробнее о встроенных пакетах см. в последней части книги.

Откат

Были уже затронуты многие темы, связанные с сегментами отката. Мы рассматривали, как они используются в ходе восстановления, как взаимодействуют с журналами повторного выполнения, а также упоминали, что они используются для обеспечения согласованного, не блокирующего чтения данных. В этом разделе я хочу описать проблемы, связанные с сегментами отката. Основную часть времени мы посвятим печально известной ошибке ORA-01555: snapshot too old, но до этого разберемся еще с двумя проблемами, касающимися отката. Сначала мы выясним, какие действия генерируют наибольший/наименьший объем данных отмены (возможно, вы и сами, после изучения предыдущих примеров с временными таблицами, сможете ответить). Затем рассмотрим,



Оператор 8 TRANSACTION

SQL-оператор SET TRANSACTION позволяет задать сегмент отката, который должна использовать транзакция. Обычно это делается для выделения большого сегмента отката для операции, затрагивающей большой объем данных. Мне не нравится эта практика, особенно, когда ею злоупотребляют. Для нечастых множественных изменений это вполне приемлемо как разовое действие. Я, однако, считаю, что надо использовать сегменты отката одинакового размера, а выбор сегмента для транзакции предоставить системе. При использовании сегментов отката, которые могут увеличиваться (если параметр MAXEXTENTS имеет достаточно большое значение) и для которых установлен размер OPTIMAL (т.е. они уменьшаются до некоторого размера после существенного увеличения), отдельный большой сегмент не нужен.

Однако, если применяется один большой сегмент отката, ничто не мешает другой транзакции его использовать. Практически ничего нельзя сделать, чтобы отдать сегмент отката одной транзакции. В выделенном пространстве будут работать и другие транзакции. Гораздо проще дать системе самой выбрать сегмент отката и разрешить увеличивать его при необходимости. Кроме того, некоторые инструментальные средства не разрешают выбирать сегмент отката, например утилита IMP (импорт). При обновлении моментального снимка, однако, указывать сегмент отката можно, а при использовании

как оператор SET TRANSACTION используется для указания сегмента отката, и обсудим, и каких случаях нужно его использовать. И только после этого подробно рассмотрим загадочную ошибку ORA-01555.

Что генерирует основной/наименьший объем данных отмены?

Ответить на этот вопрос очень легко. Наименьший объем информации отмены генерирует оператор INSERT, поскольку серверу Oracle достаточно записать идентификатор строки для удаления. Оператор UPDATE по этому показателю обычно идет вторым. Достаточно записать только измененные байты. Чаше всего изменяется лишь небольшая часть данных строки. Поэтому только небольшую часть строки придется записывать в сегмент отката. Многие из представленных ранее примеров демонстрировали как раз обратное, но лишь потому, что изменялись большие строки фиксированной длины, причем изменялись целиком. Гораздо чаще изменяется лишь небольшая часть строки. Оператор DELETE, как правило, генерирует наибольший объем данных отмены. Для оператора DELETE сервер Oracle должен записать в сегмент отката предварительный образ всей строки в целом. Представленный ранее пример, в котором генерировались данные повторного выполнения для временной таблицы, прекрасно это продемонстрировал. Оператор INSERT сгенерировал очень немного данных отмены, которую пришлось регистрировать в журнале. Оператор UPDATE сгенерировал данные, равные по объему предварительным образам измененных данных, а оператор DELETE сгенерировал всю строку данных, которая и была записана в сегмент отката.



утилиты SQLLDR - нет. Я считаю, что все сегменты отката должны иметь достаточный размер для выполняемых в системе транзакций.

С учетом всего этого, для рассматриваемого оператора остается нечастое, однократное применение. При выполнении множественных изменений большого объема информации его использование оправдано. Создается временный сегмент отката на одном из дополнительных дисков, и выполняется изменение. После изменения этот сегмент отката отключается и удаляется. Вероятно, еще лучше сначала фрагментировать большую таблицу и выполнять изменение параллельно. В этом случае, каждый из подчиненных процессов параллельного запроса будет привязан к отдельному сегменту отката, в результате чего транзакция может использовать все сегменты отката одновременно. Этого нельзя достичь при выполнении изменения последовательно.

ORA-01555: snapshot too old

Ошибка ORA-01555 - одна из ошибок, сбивающих людей с толку. С ней связано много мифов, неточностей и предположений. На самом деле эта ошибка очевидна и возникает только по двум причинам, но поскольку специальный случай одной из этих причин встречается слишком часто, можно выделить три причины:

сегменты отката слишком малы для выполняемых в системе действий;

программы извлекают данные между фиксациями (по сути это разновидность первой причины);

очистка блоков.

Первые две причины непосредственно связаны с моделью согласованности по чтению Oracle. Если вспомнить главу 2, посвященную архитектуре, результаты запроса предопределены - они хорошо известны еще до извлечения сервером Oracle первой строки. Сервер Oracle обеспечивает этот согласованный по времени моментальный снимок базы данных, используя сегменты отката для отмены изменений в блоках, изменившихся с начала выполнения запроса. Любой выполняемый оператор, например:

update t set x = 5 where x = 2;

insert into t select * from t where x = 2;

delete from t where x = 2;

select * from t where x = 2;

получит согласованное по чтению представление таблицы Т и набор строк, в которых х=2, независимо от других действий, параллельно выполняемых в базе данных. Все операторы, читающие таблицу, используют этот механизм согласованности по чтению. В представленном выше примере оператор UPDATE читает таблицу, чтобы найти в ней строки, где х=2 (и затем изменить их). Оператор INSERT читает таблицу в поисках строк, где х=2, и затем вставляет их, и так далее. Использование сегментов отката для этих двух целей - отката неудачнгх транзакций и обеспечения согласованности по чтению - и приводит к возникновению ошибки ORA-01555.

Третья причина возникновения ошибки ORA-01555 более загадочна, поскольку в этом случае ошибка может возникать в базе данных с единственным сеансом, причем - не из-



1 ... 69 70 71 [ 72 ] 73 74 75 ... 469

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