|
Программирование >> Oracle
меняющим таблицу! Это кажется невозможным; зачем нужны данные в сегменте отката для таблицы, которая не изменяется? Далее мы разберемся с этим. Прежде чем проиллюстрировать все три причины, хочу поделиться своим опытом устранения проблем, связанных с ошибкой. ORA-1555. В общем случае возможны следующие решения. Проанализировать используемые объекты. Это поможет избежать третьей причины. Поскольку очистка блоков выполняется в результате множественных изменений или вставок очень большого объема данных, это все равно надо делать. Увеличить или добавить сегменты отката. Это уменьшает вероятность перезаписи данных отмены при выполнении продолжительного запроса. Это решение помогает устранить все три перечисленные ранее причины. Сократить время выполнения запроса (настроить запрос). Это наилучший выход, поэтому именно к нему следует прибегнуть в первую очередь. В результате сократится потребность в больших сегментах отката. Это решение помогает устранить все три причины возникновения ошибки. Мы вернемся к этим решениям позже, однако в общих чертах опишем их здесь. Сегменты отката очень маленькие Сценарий следующий: имеется система, транзакции в которой - маленькие. Естественно, в сегментах отката требуется очень мало места. Рассмотрим, например, следующую ситуацию. Каждая транзакция генерирует в среднем 1 Кбайт данных отмены. В среднем выполняется пять таких транзакций в секунду (генерируется 5 Кбайт данных отмены в секунду, 300 Кбайт в минуту). В среднем раз в минуту выполняется транзакция, генерирующая 1 Мбайт данных отмены. В результате генерируется примерно 1,3 Мбайт данных отмены в минуту. В системе сконфигурированы сегменты отката общим размером 5 Мбайт. Для обработки транзакции места в сегментах отката в этой базе данных предостаточно. Система будет переходить на следующий сегмент отката и использовать место в нем повторно в среднем раз в три-четыре минуты. Если размер сегментов отката определен на основе этой информации о предполагаемых транзакциях, - все в порядке. В этой же среде, однако, надо еще создавать отчеты. Некоторые из запросов выполняются весьма долго, - скажем, пять минут. Вот тут и возникает проблема. Если запросы выполняются пять минут и им понадобится представление данных на момент начала запроса, велика вероятность возникновения ошибки ORA-01555. Поскольку сегменты отката в ходе выполнения этого запроса переписываются, понятно, что часть данных отмены, сгенерированных с начала выполнения запроса, потеряна, - они были перезаписаны. Если мы столкнемся с блоком, измененным сразу после начала запроса, данные отмены для этого блока не будет найдены, и мы получим сообщение об ошибке ORA-01555. Рассмотрим небольшой пример. Пусть имеется таблица с блоками 1, 2, 3,... 1000000. Вот последовательный список событий, которые могли произойти:
3:00 Запрос все еще выполняется. Он уже дошел до блока 600000. 4:00 Сегменты отката начинают перезаписываться, и пространство, использовавшееся в начале выполнения запроса, в момент 0:00, начинает использоваться повторно. В частности, мы только что повторно использовали в сегменте отката место, где были записаны данные отмены для блока 1000000, измененного в момент времени 0:01. 5:00 Запрос добрался, наконец, до блока 1000000. Оказывается, блок был изменен после начала выполнения запроса. Сервер обращается к сегменту отката и пытается найти данные отмены для этого блока, чтобы получить его согласованное по времени представление. В этот момент выясняется, что необходимой информации больше нет. Возникает ошибка ORA-01555, и запрос заканчивается неудачно. 4:00 5:00 Сегменты отката начинают перезаписываться, и пространство, использовавшееся в начале выполнения запроса, в момент 0:00, начинает использоваться повторно. В частности, мы только что повторно использовали в сегменте отката место, где были записаны данные отмены для блока 1000000, измененного в момент времени 0:01. Запрос добрался, наконец, до блока 1000000. Оказывается, блок был изменен после начала выполнения запроса. Сервер обращается к сегменту отката и пытается найти данные отмены для этого блока, чтобы получить его согласованное по времени представление. В этот момент выясняется, что необходимой информации больше нет. Возникает ошибка ORA-01555, и запрос заканчивается неудачно. Вот и все. Если сегменты отката имеют такой размер, что могут быть перезаписаны по ходу выполнения запросов, и запросы эти обращаются к данным, которые могли быть только при выполнении операторов INSERT, UPDATE и DELETE. Факт выполнения продолжительного запроса не заставляет сервер Oracle увеличить сегмент отката, чтобы при необходимости сохранить его данные. Это может сделать только продолжительная транзакция, изменяющая данные. В представленном примере, хотя сегменты отката могли расти, они не росли. Для этой системы надо изначально создать большие сегменты отката. Необходимо выделить постоянное пространство для сегментов отката, а не просто дать возможность расти при необходимости. Для решения этой проблемы надо либо создать сегменты отката такого размера, чтобы они переписывались не чаще, чем один раз в шесть-десять минут, либо сделать так, чтобы запросы выполнялись не более двух-трех минут. Первое решение основано на том факте, что имеются запросы, выполняющиеся пять минут. В этом случае администратор базы данных должен увеличить объем постоянно выделяемых сегментов отката в два-три раза. Второе решение тоже вполне допустимо. Если можно ускорить выполнение запросов, это надо делать. Если блоки в сегментах отката, сгенерированные с начала запроса, никогда не перезаписываются, ошибка ORA-01555 не возникнет. Важно помнить, что вероятность возникновения ошибки ORA-01555 определяется размером наименьшего сегмента отката в системе. Добавление одного большого сегмента отката не устранит проблему. Достаточно при выполнении запроса повторно использовать самый маленький сегмент отката, и сразу появляется возможность возникновения ошибки ORA-01555. Вот почему мне очень нравится идея создавать сегменты отката одинакового размера. При этом каждый сегмент отката - одновременно наибольший и наименьший. Вот почему я также избегаю использования сегментов отката оптимального размера. При сжатии вынужденно увеличенного сегмента отката выбрасывается множество данных отмены, которые могут еще понадобиться. Хотя удаляются самые старые данные в сегменте отката, определенный риск все же остается. Я предпочитаю уменьшать сегменты отката в периоды минимальной нагрузки вручную, если это вообще делается. Пожалуй, я слишком глубоко вошел в роль администратора базы данных, так что давайте перейдем к следующему случаю: ошибка ORA-01555 вызвана тем, что размер сегментов отката для текущего объема изменений определен неправильно. Единственное решение - правильно задавать размер сегментов отката в соответствии с объемом изменений. Это не ваша ошибка, но это ваша проблема, раз уж вы с ней столкнулись. Эта ситуация аналогична нехватке временного пространства в ходе выполнения запроса. Надо либо предусмотреть достаточное количество временного пространства в системе, либо переписать запросы так, чтобы при выполнении для них требовалось меньше временного пространства. Чтобы продемонстрировать этот эффект, можно создать небольшой тестовый пример. Ниже я создам очень маленький сегмент отката. Будет работать только один сеанс, использующий только этот сегмент отката, что практически гарантирует перезапись и многократное повторное использование выделенного пространства. Сеанс, использующий этот сегмент отката, будет изменять таблицу Т. Он будет выполнять полный просмотр таблицы Т, и читать ее от начала до конца. В другом сеансе мы выполним запрос к таблице Т, который будет читать ее по индексу. Т.е. он будет читать строки таблицы в относительно случайном порядке. Он прочитает строку 1, затем - строку 1000, стоку
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |