Многие операции с данными в Oracle выполняются в области кэша буферов базы данных, расположенного в наборе сегментов разделяемой памяти ядра Oracle, который называется системной глобальной областью. Поэтому все аналитики производительности уделяют внимание тому, что происходит в кэше буферов базы данных. Сообщается о том, что доступ к буферам кэша осуществляется из сотен различных фрагментов кода ядра Oracle [Lewis (2003)]. Из всех таких обращений к буферам наибольшие затраты связаны с операциями логического ввода/ вывода Oracle (LIO). Количество LIO для вызова базы данных равно сумме значений его статистик cr и cu из данных трассировки SQL.
Практически в каждой из Oracle-систем, которые я встречал, более 50% общего процессорного времени, отданного приложениям Oracle, занимали ненужные вызовы LIO. Во многих случаях можно избавиться от более чем 90% нагрузки на систему без потери какой бы то ни было функциональности для бизнеса.
Избыточные обращения к буферам для базы подобны патологическому ожирению для человека. Как лишние двадцать фунтов жира вредят работе почти любой подсистемы организма (кровеносной, почечной, костно-мышечной, зрительной...), так и избыточные вызовы LIO ухудшают производительность практически любой подсистемы приложения Oracle.
Обращение к слишком большому количеству буферов вызывает дополнительную нагрузку на процессор и приводит к росту времени, проведенному вне исполнения, проявляющемуся в больших неучтенных длительностях. Избыточные операции LIO приводят к возникновению ожиданий освобождения защелок в цепочках буферов кэша (cache buffer chains) и служат причиной избыточных системных вызовов чтения, проявляющихся в виде событий db file sequential read или db file scattered read.
Многие события ожидания Oracle могут служить иллюстрацией вредных побочных эффектов ненужных обращений к буферам. Например, любая производительность ухудшается по мере увеличения очереди к процессору. Событие ожидания Oracle log file sync - один из первых признаков возрастания задержек, возникающих в очереди к процессору. Негативные последствия избыточных обращений к буферам могут проявиться в абсолютно неожиданных местах. Например, если избыточные обращения к буферам приводят к усилению конкуренции за дисковый ввод/вывод, процессы записи DBWR могут стоять в очереди позади вызовов чтения. Если процесс DBWR не успевает за изменениями буферов, то в приложениях появляются события ожидания free buffer waits, write complete waits и даже log file switch (checkpoint incomplete). Зачастую оказывается, что причина проблем с ожиданием освобождения буфера buffer busy waits кроется в избыточном количестве операций LIO. Ошибки, приводящие к ненужным операциям LIO, могут вызвать даже лишние выполнения событий SQL*Net message from client.
Причины частых проблем с LIO
Существует ряд причин, по которым столь многие системы страдают от избыточных вызовов LIO. Одна из них заключается в том, что всех нас учили, что обращение к памяти выполняется гораздо быстрее, чем к диску, из чего следовало, что в бесконечных обращениях к памяти нет ничего страшного [Millsap (2001c)]. Более глубокая причина того, что огромное количество приложений Oracle страдает от избыточности операций LIO, состоит в том, что пользователи могут создать проблему множеством способов. Рассмотрим небольшой пример:
Пользователи приложений
Пользователи приложений могут заставить их выполнять ненужные обращения к буферам разными способами. Можно выполнять запросы, не пользуясь фильтрами, например, поиск продавца с названием «Xerox» можно осуществлять посредством запроса «вслепую» вместо того, чтобы наложить на имя ограничение вида X%. Можно запрашивать отчеты, не указывая аргументов, например можно запустить формирование отчета по продажам всей компании начиная с ее основания вместо того, чтобы сформировать нужный отчет по своему отделу за определенный месяц. Кроме того, в те моменты, когда система начинает работать медленнее из-за избытка вызовов LIO, пользователи могут отправлять на исполнение одну и ту же операцию несколько раз, в результате чего одни и те же вызовы LIO выполняются по несколько раз.
Администраторы приложений
Ошибки, приводящие к ненужным обращениям к буферам, могут совершать и администраторы приложений. В конфигурируемых приложениях, например в Oracle e-Business Suite, способы организации плана бухгалтерских счетов и настройки приложения могут серьезно повлиять на количество вызовов LIO, совершаемых типовыми бизнес-функциями. Некоторые приложения, подобные продукту Oracle General Ledger, имеют собственные встроенные средства оптимизации запросов. Применяя подобные средства и пренебрегая при этом внимательным изучением их влияния на производительность, можно породить много ненужных вызовов LIO. Ошибки администраторов приложений в деле архивирования и очистки данных могут привнести в приложение миллионы ненужных вызовов LIO.
Администраторы экземпляров
К ошибкам администратора экземпляра, которые могут привести к избыточным вызовам LIO, относится неудачный выбор десятков параметров, подобных HASH_AREA_SIZE и DB_FILE_MULTIBLOCK_READ_COUNT, влияющих на работу оптимизатора запросов Oracle по стоимости.
Администраторы данных
Администраторы данных могут инициировать избыточные вызовы LIO огромным количеством способов. Вероятно, самый распространенный из них - предоставление некорректной информации о таблицах и индексах оптимизатору Oracle по стоимости (Cost-Based Query Optimizer - CBO) из-за того, что статистика собрана неправильно. Таблицы, страдающие миграцией или сцеплением строк в тяжелой форме, порождают больше вызовов LIO. То же самое происходит, если неудачно выбраны значения PCTFREE и PCTUSED. Отсутствие в соответствующих ситуациях индексированных таблиц, кластеров и разделов может привести к обработке излишних LIO. Отсутствие ограничений (например, не назначены столбцы, выступающие в качестве первичных или внешних ключей, не определено, какие столбцы допускают использование NULL, а какие - нет) может помешать оптимизатору запросов Oracle использовать планы выполнения, ограничивающие количество вызовов LIO. Конечно же, недостаточное количество индексов (или просто неправильные индексы) может вызвать ненужные вызовы LIO для запросов, а избыточное количество индексов может привести к выполнению лишних вызовов LIO в командах INSERT, UPDATE и DELETE.
Разработчики приложений
Естественно, что решения разработчиков приложений оказывают огромное влияние на количество LIO. Некоторые виды конструкций
SQL делают невозможным применение эффективного плана выполнения запроса ядром Oracle. Например, наличие в инструкции WHERE предиката TRUNC(STARTDATE) = TO_DATE(:b1, 'mm/dd/rr') может помешать серверному процессу Oracle использовать индекс для START_DATE, который мог бы значительно уменьшить количество LIO. Бывает и так, что в коде приложения качество SQL очень высоко, но вызовов LIO все равно слишком много. Так, приложение с построчной выборкой из курсора Oracle может выполнять в сто раз больше вызовов LIO, чем такое же приложение, в котором реализован механизм выборки массивом (array fetch) для извлечения 100 строк в одном вызове LIO. Игнорирование возможности выборки массивом приводит к дополнительной нагрузке не только на базу данных, но и на сеть. Дополнительные вызовы базы данных, необходимые для обработки многочисленных маленьких наборов строк приводят к тому, что возрастает количество выполнений события SQL*Net message from client, а это сразу же отражается на времени отклика пользовательской операции.
Проектировщики приложений
Проектировщики приложений также могут сделать невозможным создание эффективного приложения с небольшим количеством LIO. Одно приложение отслеживания материальных ценностей, над которым несколько лет назад работал Джефф, не позволяло определить местонахождение предмета хранения без воссоздания полной истории его перемещений. Вместо быстрого индексированного просмотра «где находится нечто», приложение требовало применения сложного и долго выполняющегося запроса CONNECT BY.
Учитывая, что масса разных специалистов одновременно должна выполнить свою работу безошибочно, чтобы исключить проблемы с LIO, не приходится удивляться наличию избыточных вызовов LIO в большинстве систем.
< Предыдущая | Следующая > |
---|