В этом году в рамках PG Day'17 Russia пройдет двухдневный поток докладов по Oraclе DB: Ярослав Киселев расскажет о мониторинге и диагностике производительности приложения с точки зрения Oracle DB, Николай Кудинов сделает технический ликбез о минимизации ожиданий log file sync и log file parallel write, Александр Халухин из Deutsche Bank готовит интенсивный мастер-класс о диагностике производительности Oracle Database. Полный список выступлений смотрите у нас на сайте!
Для специалистов, интересующихся коммерческими базами данных мы подготовили перевод публикаций от специалистов по базам данных из CERN. Сегодняшний материал открывает цикл из нескольких статей, посвященных трассировке и отладке производительности Oracle DB с помощью SystemTap.
Эта статья посвящена использованию SystemTap для поиска и устранения неполадок в СУБД Oracle. В частности, вы узнаете, как исследовать процессы Oracle и их функции userspace. Эти методы будут полезны и увлекательны для всех, кто заинтересован в том, чтобы заглядывать под капот технологий и повышать свою эффективность в поиске и устранении неисправностей, а также в исследованиях производительности.
Введение
Трассировка userspace — очень мощный метод, который может использоваться для дополнения доступной в Oracle информации о производительности и профилировании, таких как V$ views и файлы трассировки 'event 10046', а также для расширенной диагностики и изучения ядра Oracle. Подобные исследования уже несколько лет доступны, в основном, на Solaris с внедрением DTrace (см., например, блог Тэнела).
Инструменты динамической трассировки, которые позволяют профилировать ядро и userspace, также набирают обороты в мире Linux, благодаря недавним дополнениям к ядру. Существует несколько инструментов, предоставляющих интерфейс для сбора, агрегирования и вывода данных динамической трассировки. SystemTap является одним из наиболее развитых, но постоянно появляются новые инструменты, в том числе 2 порта DTrace. Для исследования этой темы посмотрите презентацию Брендана Грегга (Brendan Gregg) на LinuxCon 2014.
Я впервые узнал о том, что можно использовать SystemTap для трассировки userspace от Фрица Хугланда (Frits Hoogland), и был весьма впечатлен возможностями, которые открываются для расширенного поиска неисправностей, а именно, как это может помочь исследовать рабочие нагрузки Oracle с целью настройки производительности и продвинутой диагностики.
Кроме того, я был рад узнать, что методы, описанные в этой статье, работают в том числе и под RHEL 6.5, что является для меня отличной новостью, поскольку означает, что я могу начать использовать SystemTap на многих существующих системах, не дожидаясь обновлений до самых последних версий ядра.
В документации SystemTap есть дополнительные сведения о реализации userspace probes: с ядрами Linux версии старше 3.5 (например, при использовании RHEL 7.0, OL 7.0 или OL6.5 с UEK3) SystemTap будет использовать модуль UPROBES для трассировки userspace, с более старыми ядрами SystemTap может использовать расширения ядра UTRACE, если они доступны. SystemTap в состоянии обеспечить трассировку userspace как с UTRACE, так и с UPROBES, другие инструменты динамической трассировки, по-видимому, работают только с UPROBES и, следовательно, только с более поздними версиями Linux. Как пишет Фриц в вышеупомянутой статье, вам понадобится SystemTap 2.5 и выше для трассировки userspace. На момент написания этой статьи вышел SystemTap 2.6.
Вот так можно проверить, настроены ли расширения UTRACE:
# grep CONFIG_UTRACE /boot/config-`uname -r`
CONFIG_UTRACE=y
А вот так проверяется, доступны ли UPROBES:
# grep CONFIG_UPROB /boot/config-`uname -r`
CONFIG_UPROBES=y
CONFIG_UPROBE_EVENT=y
Ниже вы найдете несколько примеров, идей и тестовый код, чтобы начать использовать трассировку userspace с помощью SystemTap в Oracle. Скрипты, обсуждаемые в данной статье, можно найти по этой ссылке.
Глубокое погружение: SystemTap читает данные интерфейса событий ожидания Oracle и таблиц X$
В этом параграфе вы узнаете, как подключить SystemTap к интерфейсу событий ожидания Oracle. Это дает возможность соединить два типа инструментария: данные, собранные с помощью SystemTap probes, и данные интерфейса событий ожидания Oracle. Таким образом мы прокладываем путь для более сложных исследований.
Основное, что нужно сделать, — создать SystemTap probe в «правильной точке» ядра Oracle и заставить ее читать необходимую нам информацию.
Как обсуждалось в предыдущей работе, посвященной DTrace и Oracle, для этой цели может быть использована функция ядра Oracle «kskthewt». Она вызывается ядром Oracle в конце каждого события ожидания, предположительно для обновления соответствующих счетчиков производительности. Нашим первым шагом является создание probe, которая запускается после того, как исполняемый файл Oracle входит в функцию kskthewt. Следующий шаг — заставить SystemTap читать информацию, которая нам нужна. Доступны регистры процессора и области памяти. Некоторые из регистров используются для передачи аргументов в функцию, как описано в соглашении x86 calling conventions. В других случаях регистры CPU могут содержать полезную информацию, «оставшуюся» после вызовов родительских функций. Чтение непосредственно из областей памяти и, в частности, из SGA открывает путь к большинству данных Oracle instrumentation.
Дополнительные факты, которые я недавно обнаружил в сотрудничестве с Фрицем Хугландом, помогающие при создании probe для функции Oracle kskthewt:
- Когда выполнение переходит в функцию kskthewt, регистр CPU R13, оказывается, хранит указатель на структуру памяти X$KSUSE (со смещением). R12, похоже, указывает на тот же адрес большую часть времени, но бывали случаи, когда это было не так, поэтому я предпочитаю использовать R13.
- X$KSUSE является “нижележащей” сервисной таблицей для V$SESSION и, следовательно, содержит много интересной информации. X$KSUSE выделяется в памяти как сегментированный массив в SGA, посмотрите презентацию Джулиана Дайка (Julian Dyke) о внутреннем устройстве SGA для более подробной информации по этой увлекательной теме.
- V$SESSION.SADDR — базовый адрес данных текущей сессии в V$SESSION и X$KSUSE — может быть получен из значения R13 путем вычитания смещения. Значение смещения зависит от версии Oracle и порта, и может быть найдено «экспериментально» с помощью SystemTap или gdb (подробнее см. в каталоге скрипт: trace_oracle_events_debug.stp).
- Поля X$KSUSE, представляющие интерес (то есть значения столбцов V$SESSION), можно найти из базового значения X$KSUSE со смещением, вычисленным с помощью запроса из X$KQFCO и X$KQFTA (см. скрипт: ksuse_find_offsets.sql).
- Было обнаружено, что регистр RDI (который отображается в аргумент arg1 в SystemTap probe) установлен в значение метки времени. Это временная метка события ожидания — то же значение, которое можно увидеть в файле трассировки для события 10046, если оно активировано.
- Регистр RSI (arg2 в SystemTap probes) оказывается установленным в номер события ожидания.
Если вы объедините всё это, то сможете написать скрипт SystemTap для сбора и вывода события ожидания и требуемых данных v$session. Пример такого скрипта показан на рисунке. Скрипты можно скачать здесь в виде zip-файла. Прямые ссылки: trace_oracle_events_11204.stp и trace_oracle_events_12102.stp. Эти скрипты были протестированы на версиях Oracle 11.2.0.4 на RHEL6.5 и Oracle 12.1.0.2 на OEL7, соответственно.
Рис. 1: Скрипт и пример выходных данных SystemTap probe, собирающей события ожидания и подробности V$SESSION из функций ядра Oracle и памяти SGA.
Примечание: В приведенном выше примере видно, что результат SystemTap передается в sed -f eventsname.sed. Это необходимо для преобразования номеров идентификаторов событий в строки. Файл eventsname.sed генерируется путем запуска скрипта eventsname.sql.
Агрегация и фильтрация данных событий ожидания в Systemtap
Одной из сильных сторон SystemTap, присущих остальным инструментам динамической трассировки, является агрегация и фильтрация «на лету». Это помогает сократить объем собранных данных, а, значит, минимизировать footprint операций трассировки, сохраняя при этом возможность создавать осмысленные отчеты и выполнять трассировку в реальном времени. Теперь, взяв за основу описанные выше примеры создания SystemTap probes, подключающихся к интерфейсу событий ожидания, вы можете добавлять агрегации и фильтры для вычисления гистограмм событий ожидания с точностью до микросекунды.
Один простой и впечатляющий результат вы можете легко воспроизвести: написать скрипт, фактически портирующий функциональность создания микросекундных гистограмм событий ожидания в 12c. Это может быть очень полезно при изучении коротких событий, таких как random disk reads с твердотельных устройств (SSD). С помощью настраиваемых фильтров вы можете агрегировать детали события ожидания для данного пользователя или для заданного файла, а также любого другого выбранного условия. В целом SystemTap предоставляет большую свободу и широкие возможности в разработке наших probes.
Два скрипта с примерами, которые можно скачать отсюда, прямые ссылки: histograms_oracle_events_11204.stp и histograms_oracle_events_12102.stp
Рис. 2: Скрипт и пример выходных данных SystemTap probe, вычисляющей гистограммы событий ожидания с точностью до микросекунды.
Рассмотрим альтернативный способ создания SystemTap probes для сбора, а также агрегирования и фильтрации данных о задержках событий ожидания Oracle. Для этого вам понадобится дополнительный фрагмент данных, получаемый после вызовов функций ядра Oracle: функция kews_update_wait_time вызывается непосредственно перед kskthewt, устанавливая значение регистра CPU RSI равным времени ожидания в микросекундах (регистр RSI доступен в SystemTap probes как arg2). Изучите также информацию, приведённую в предыдущей работе. Таким образом, вы можете создать probe, вычисляющую гистограммы событий независимо от версии Oracle. Пример скрипта: histograms_oracle_events_version_independent.stp.
Рис. 3: Скрипт и пример выходных данных SystemTap probe, вычисляющей гистограммы событий ожидания с точностью до микросекунды независимо от версии Oracle.
Трассировка логического ввода-вывода Oracle с помощью SystemTap userspace probes
Вы можете использовать Systemtap userspace probes в том числе и для трассировки логического ввода-вывода Oracle. В основе этой probe лежит исследование, проведенное Тэнелом Подером (Tanel Poder) (ищите скрипт qer_trace.sh, использующий DTrace), и обширная работа Александра Анохина.
Прицепившись к функции kcbgtcr ядра Oracle, мы можем получить информацию о logical reads или, скорее, cache consistent reads, как объяснил Александр Анохин; kcbgtcr = Kernel Cache Buffer Get Consistent Read, и первый аргумент вызываемой функции указывает на структуру памяти с информацией о tablespace, относительным номером файла, номером блока и номером объекта consistent read. Мы можем использовать все это для создания профилирующей probes trace_oracle_logical_io_basic.stp.
probe process("oracle").function("kcbgtcr") {
printf("tbs#=%d, rfile=%d, block#=%d, obj#=%dn",user_int32(u64_arg(1)), user_int32(u64_arg(1)+4) >> 22 & 0x003FFFFF, user_int32(u64_arg(1)+4) & 0x003FFFFF, user_int32(u64_arg(1)+8))
}
На основе этого вы также можете создавать probes, которые выполняют агрегации и вычисляют статистику операций logical reads, например: trace_oracle_logical_io_count.stp.
Рис. 4: Скрипт и пример выходных данных SystemTap probe для сбора и агрегации информации о логическом вводе-выводе (для операции consistent read) в Oracle.
Systemtap может интегрировать данные о событии ожидания Oracle с трассировкой OS
Отслеживание системных вызовов является сильной стороной и первоочередным способом SystemTap. Используя эту возможность, вы можете углубиться в процесс трассировки Oracle, объединив данные интерфейса событий ожидания Oracle (собранные с помощью SystemTap, как показано выше) с данными, поступающими из SystemTap OS probes.
Ниже вашему вниманию предлагается пример, основанный на Oracle с использованием ASM, когда хранилище становится видимым со стороны OS как блочные устройства (asmlib в данном примере не используется). В этом случае вызовы функций ввода-вывода, осуществляемые процессами Oracle, как правило, будут представлять собой pread и pwrite для синхронных одноблочных операций ввода-вывода, io_submit и io_getevents для многоблочных и/или асинхронных операций ввода-вывода. На более низком уровне все операции ввода-вывода для блочных устройств могут отслеживаться как запросы ioblock.
Вы можете начать изучение взаимосвязи между событиями ожидания Oracle, системными вызовами ввода-вывода и блочным вводом-выводом, используя следующий скрипт: trace_oracle_iocalls_12102.stp.
Рис. 5: SystemTap probes для трассировки ввода-вывода OS и трассировки событий ожидания Oracle. Это позволяет получить объединенное представление о действиях, лежащих в основе события ввода-вывода Oracle и связанных с ними действий OS.
На рисунке 6, представленном ниже, вы можете увидеть пример трассировки ввода-вывода Oracle, где одноблочный (синхронный) ввод-вывод выполняется через вызов pread к OS. Это типичный сценарий доступа для операций случайного ввода-вывода Oracle. На стороне OS вызов pread передается в стек блочного устройства как io_block_request. В интерфейсе событий ожидания Oracle операция ввода-вывода учитывается как db file sequential read wait с указанием номера файла и номера блока (параметры p1 и p2)
Рис. 6: Oracle, выполняющий одноблочный ввод-вывод, профилируемый с использованием SystemTap probes. Это обеспечивает сквозную трассировку операции ввода-вывода: мы можем видеть детали вызова OS и соответствующие им данные события ожидания Oracle.
Интерфейс асинхронного ввода-вывода Linux часто используется Oracle для многоблочных операций ввода-вывода. Это делается, в первую очередь, из соображений производительности и может быть выполнено лишь в том случае, если допускается файловой системой (такой подход имеет место в примерах, приведенных здесь, поскольку мы используем ASM). Изучение асинхронного ввода-вывода Oracle уведет нас слишком далеко от основной темы, поэтому давайте ограничимся обсуждением некоторых основных наблюдений и примером того, как вы можете использовать SystemTap probes для дальнейшего изучения этого вопроса.
В случае с asynchronous IO ядро фактически выполняет ввод-вывод, пользовательский процесс только лишь запрашивает выполнение операции ввод-вывод и позднее запрашивает возврат требуемой информации. При исследовании асинхронного ввода-вывода вам необходимо трассировать, как минимум, два вызова: один для отправки запросов ввода-вывода (io_submit) и один для получения результатов (io_getevents). Запросы ввода-вывода затем передаются на уровень блочного ввода-вывода. На этом этапе они могут быть разделены на несколько операций меньшего размера, как показано в примерах на рисунке 7. Прочитайте также статью Мартина Баха (Martin Bach) на тему «Увеличение максимального размера ввода-вывода в Linux». Более подробные сведения о трассировке ввода-вывода Oracle можно найти в отличной работе Фрица Хугланда по профилированию Oracle с помощью gdb и его исследовании многоблочных операций ввода-вывода.
Рис. 7: Пример SytemTap probe, демонстрирующей профилирование ввода-вывода Oracle в случае multi-block read, когда Oracle решил выполнить асинхронный ввод-вывод. Запросы ввода-вывода на уровне ОС осуществляются с помощью io_submit, сбор результатов происходит с помощью io_getevents. SystemTap позволяет также увидеть, что происходит на уровне блочного устройства, когда операции ввода-вывода разбиваются на более мелкие куски с максимальным размером 512 КБ в системе, используемой для этого теста.
Настройка демонстрационного стенда и документация
Ниже вы найдете советы по настройке тестовой среды для экспериментов с методами и скриптами, рассмотренными выше:
— Скачайте и установите Oracle Virtual Box
— Скачайте OL 7.0 (or OL 6.x), например, отсюда https://edelivery.oracle.com/linux
— Также установите kernel-devel rpm
Если вы хотите использовать ОС probes в сочетании с SystemTap, загрузите и установите пакеты debuginfo и debuginfo-common для используемого вами ядра. RPM можно найти по адресу https://oss.oracle.com/ol7/debuginfo/ и https://oss.oracle.com/el6/debuginfo/ для OEL 7 и OEL 6, соответственно. Аналогичным образом установите libaio-debuginfo и libaio-devel, если хотите отслеживать вызовы ОС для асинхронного ввода-вывода.
Обратите внимание, что если вы хотите запускать probes только для функций Oracle userspace, установку пакетов kernel и libaio debuginfo можно пропустить.
Скрипты, обсуждаемые здесь, требуют systemtap 2.5 или выше. Подумайте о деинсталляции systemtap, если у вас уже стоит более старая версия.
Загрузите последнюю версию systemtap по адресу https://sourceware.org/systemtap/ftp/releases/ (версия 2.6 на момент написания этой статьи).
Чтобы установить SystemTap из загруженного исходного кода, запустите:
./configure
# вывод configure укажет, требуются ли дополнительные пакеты ОС; в этом случае, то установите их и повторите операцию
make
make install
В качестве проверки после инсталляции запустите:
stap --help
Хорошим началом для изучения документации SystemTap является руководство для начинающих, а также справочник по языку и tapset reference manual.
Скачайте и установите Oracle версии 12.1.0.2 или 11.2.0.4.
Программное обеспечение можно скачать здесь: https://edelivery.oracle.com/
Предустановленные виртуальные машины с базой данных Oracle можно скачать с OTN (например, по этой ссылке)
Руководства по установке, помимо документации Oracle, также доступны по адресу http://www.oracle-base.com/articles/12c/articles-12c.php и в вики-книге racattack.
Заключение
Динамическая трассировка делает доступными probes уровня userspace в ядре Oracle и Linux probes на уровне ядра ОС, которые могут быть использованы для дополнения информации о производительности Oracle (в частности, данных, поступающих от интерфейса событий ожидания и счетчиков статистики). Эти методы могут в значительной степени увеличить объем данных, доступный при изучении проблем производительности и диагностике неполадок, а, следовательно, помогают специалисту использовать системные подходы к решению проблем и оставаться в целом более успешным и последовательным в своих действиях.
В данной статье вашему вниманию были предложены несколько советов и примеры для начала работы (их можно скачать по этой ссылке или с Github). Применение и совершенствование предложенных методов для исследования и диагностики Oracle и других сложных платформ является перспективным направлением, обладающим большим потенциалом. Я планирую осветить еще несколько примеров в будущих публикациях. Я надеюсь, что вам понравилось изучать предложенные примеры, и желаю всем читателям, которые были достаточно терпеливы и добрались до этих строк, успеха и удовольствия от использования этих методов в своих системах!
Благодарности
Я хочу поблагодарить трех авторов, чьи оригинальные идеи вдохновили меня на написание этого материала: Брендана Грегга (Brendan Gregg), Тэнела Подера (Tanel Poder) и Фрица Хугланда (Frits Hoogland). Дополнительная благодарность Фрицу Хугланду за проверку этой статьи.
Надеемся, что этот выпуск оказался для вас полезным. В следующей части мы углубимся в тонкости трассировки logical и physical I/O Oracle, используя возможности SystemTap.
Автор: PG Day'17 Russia