Перейти к основному содержимому

Структура исходного кода OrioleDB

примечание

Эта страница переведена при помощи нейросети GigaChat.

Структура исходного кода OrioleDB включает различные компоненты, такие как процессы CI/CD, документация, тесты и файлы C-исходного кода. Организация предусматривает удобное проведение разработки, тестирования (включая работу под Valgrind) и развертывания расширения OrioleDB для PostgreSQL. Особое внимание уделяется тестированию конкурентности и анализу производительности через события остановки (stop events) и CI-процессы.

Структура файлов

orioledb
|- .github
| |- workflows – процессы GitHub
|
|- ci – скрипты для сборки, тестирования и автоматизации CI
|- doc – документация
|- docker
| |- tests – тесты Docker-образов
| |- Dockerfile – Dockerfile на базе Alpine, используется в процессах docker.yml и dockertest.yml
| |- Dockerfile.ubuntu – Dockerfile на базе Ubuntu, используется в процессах docker.yml и dockertest.yml
| |- README.md – документация тестов Docker-образов
| |- docker-entrypoint.sh – файл точки входа для Docker-образов
| |- orioledb-config.sh – конфигурация тестов Docker-образов
| |- postgresql.docker.conf – файл конфигурации, используемый Docker-образами
|- include – C-заголовки расширения
|- perf – тесты производительности
|- sql – скрипты установки с определениями объектов расширения на уровне SQL
|- src – C-исходные коды расширения
|- test
| |- expected – ожидаемый вывод для регрессионных и изоляционных тестов
| |- integration – интеграционные тесты
| |- specs – изоляционные тесты
| |- sql – регрессионные тесты
| |- t – тесты на Python
| |- orioledb_isolation.conf – файл конфигурации, используемый во время изоляционных тестов
| |- orioledb_regression.conf – файл конфигурации, используемый во время регрессионных тестов
|- Makefile – определяет цели make
|- README.md – главный файл документации
|- orioledb.control – файл управления расширением
|- stopevents.txt – список «событий остановки»
|- stopevents_gen.py – генерирует include/utils/stopevents_(defs|data).h из stopevents.txt
|- typedefs_gen.py – генерирует список C-символов в orioledb.so в orioledb.typedefs
|- valgrind.supp – правила подавления для проверок valgrind

Цели Makefile

Все цели, связанные с тестированием, принимают аргумент VALGRIND=1, который запускает тесты под valgrind. Valgrind замедляет выполнение тестов примерно в ~100 раз, но обнаруживает обращения к неинициализированной памяти. Еще одним положительным следствием сверхмедленного выполнения тестов под Valgrind является изменение временных параметров, что позволяет выявить различные типы ошибок конкурентности.

  • regresscheck – запустить SQL-тесты (смотрите ниже);
  • isolationcheck – запустить изоляционные тесты (смотрите ниже);
  • testgrescheck – запустить тесты testgres (смотрите ниже);
  • testgrescheck_part_1 – первая половина проверок testgres. Тесты testgres разделены на две примерно равные части для избежания чрезмерно длительных индивидуальных CI-запусков;
  • testgrescheck_part_2 – вторая половина проверок testgres;
  • installcheck – запустить все типы тестов при установке через систему расширений PostgreSQL (USE_PGXS=1);
  • check – запустить все типы тестов при установке из папки contrib исходного кода PostgreSQL;
  • pgindent – автоматическое форматирование отступов в исходных кодах OrioleDB. Утилита pgindent должна быть доступна в $PATH. Следует учесть необходимость предварительной установки pg_bsd_indent. Также требуется наличие GNU Objdump в $PATH под именем objdump или gobjdump, либо указание через переменную окружения OBJDUMP.

Скрипты SQL расширения

Файлы расширения OrioleDB организованы с использованием основного скрипта установки базовой версии, за которым следуют скрипты обновления для соответствующих минорных версий. Например, при установке версии 1.7 PostgreSQL сначала применяет скрипт 1.0, а затем последовательно выполняет все скрипты обновления от 1.0 до 1.7.

Для повышения версии расширения (например, с 1.6 до 1.7) необходимо выполнить шаги:

  1. Изменить параметр default_version в файле orioledb.control на новую версию.

  2. Вручную создать скрипты обновления для разработки и производства в директории sql:

    • ./sql/orioledb--1.6--1.7_prod.sql;
    • ./sql/orioledb--1.6--1.7_dev.sql;
  3. Добавить соответствующие заголовки в скрипты и заполнить изменениями:

    • изменения, предназначенные только для среды разработки (например, тестовые функции, которые не должны быть доступны в системах производства), размещаются в _dev.sql;
    • все стандартные изменения размещаются в файле _prod.sql.
примечание

Система сборки (make) использует оба файла для автоматической генерации итогового скрипта ./sql/orioledb--1.6--1.7.sql. Поэтому создавать этот итоговый файл вручную не требуется. Содержимое _dev.sql включается только при указании флага IS_DEV во время сборки. Дублировать изменения между двумя файлами не нужно.

  1. Добавить сгенерированный файл (./sql/orioledb--1.6--1.7.sql) в файлы .gitignore и .dockerignore.

Тесты

В OrioleDB предусмотрено 3 группы тестов, описанные ниже.

  • SQL-тесты находятся в папке test/sql. Это самый простой тип тестов. SQL-файл передается в psql, результат сравнивается с эталонным выводом в папке test/expected. Следует учесть, что для одного входного файла может существовать несколько эталонных выводов. Например, collate.sql содержит тесты, чувствительные к региональным настройкам (collation). Результат может соответствовать collate.out, collate_1.out или collate_2.out в зависимости от кодировки базы данных и наличия libicu.
  • Изоляционные тесты находятся в папке specs. Эти тесты моделируют несколько одновременных подключений. Смотрите README в дереве исходного кода PostgreSQL. Данные тесты обладают особой эффективностью в комбинации с событиями остановки.
  • Тесты на Python testgres находятся в t. Это самые мощные и сложные тесты. Помимо возможности моделирования нескольких одновременных подключений, они позволяют выполнять действия с целым экземпляром PostgreSQL, такие как запуск, остановка, резервное копирование, репликация и т. д. Подробности смотрите в документации testgres.
примечание

Для корректной интеграции в набор тестов имена тестовых файлов должны заканчиваться на _test.py.

CI

В OrioleDB используется CI GitHub. CI-процессы описаны ниже.

check.yml

Данный процесс выполняет следующие тесты для каждого из двух компиляторов (gcc и clang) и каждой из поддерживаемых мажорных версий PostgreSQL (16 и 17).

  • normal – выполнение тестов без утверждений (asserts) и без отладочных символов;
  • debug – выполнение тестов с утверждениями и с отладочными символами;
  • sanitize – выполнение тестов с утверждениями, с отладочными символами, с проверкой выравнивания и другими санитайзерами. Это заменяет выполнение тестов на архитектурах со строгим выравниванием, обеспечивая даже более строгие проверки (например, перехват обращения к правильно выровненному члену неправильно выровненной структуры, чего реальное оборудование не делает);
  • check_page – выполнение тестов с утверждениями, с отладочными символами и с включенным макросом CHECK_PAGE_STRUCT. Данный макрос обеспечивает проверку структуры страницы при каждой операции разблокировки страницы;
  • valgrind_1 – выполняет regresscheck, isolationcheck и testgrescheck_part_1 под valgrind с утверждениями и с отладочными символами;
  • valgrind_2 – выполняет testgrescheck_part_2 под Valgrind с утверждениями и с отладочными символами;
  • static – выполняет clang-analyzer или cppcheck по исходным кодам.

docker.yml

Данный процесс собирает Docker-образы для архитектур amd64 и arm64v8 под Linux Alpine и Ubuntu. Данный Dockerfile представляет собой незначительно модифицированный Dockerfile PostgreSQL. Подробности смотрите на dockerhub.

dockertest.yml

Данный процесс тестирует Docker-образы. Запускается при каждом push и pull request.

pgindent.yml

Данный процесс проверяет форматирование кода с помощью pgindent. Запускается при каждом push и pull request.

rpm.yml

Данный процесс собирает RPM-пакеты для CentOS 7 по спецификации из репозитория orioledb/pgrpms, являющегося форком репозитория pgrpms.

static.yml

Данный процесс выполняет статический анализ кода. Запускается при каждом push и pull request.

События остановки (Stop events)

События остановки — это специальные места в коде, где выполнение может быть приостановлено на основе конкретных условий. События остановки используются для воспроизведения проблем конкурентности. Изоляционные и тесты testgres в OrioleDB используют события остановки.

Событие остановки предоставляет набор параметров, инкапсулированных в значение jsonb. Условия на параметры события остановки определяются с помощью языка путей SQL/JSON.

Функции и переменные на уровне SQL для управления событиями остановки перечислены ниже.

  • orioledb.enable_stopevents – включает проверку событий остановки для процесса. Проверка событий остановки является ресурсоемкой и значительно влияет на производительность. По этой причине события остановки отключены по умолчанию;
  • orioledb.trace_stopevents – включает логирование всех событий остановки. Отключено по умолчанию;
  • pg_stopevent_set(eventname text, condition jsonpath) RETURNS void – задает условие для события остановки. После выполнения функции все процессы, выполняющие данное событие остановки с параметрами, удовлетворяющими указанному условию jsonpath, будут остановлены;
  • pg_stopevent_reset(eventname text) RETURNS bool – сбрасывает событие остановки. Все процессы, ранее остановленные на данном событии остановки, продолжат выполнение;
  • pg_stopevents(OUT stopevent text, OUT condition jsonpath, OUT waiter_pids int[]) RETURNS SETOF record – возвращает все установленные события остановки с их условиями и PID ожидающих процессов.

На уровне C предоставляются следующие макросы для управления событиями остановки:

  • STOPEVENTS_ENABLED() – проверяет, включены ли события остановки;
  • STOPEVENT(event_id, params) – вызывает указанное событие остановки с заданными параметрами jsonb;
  • STOPEVENT_CONDITION(event_id, params) – проверяет условие события остановки без остановки выполнения. Используется для имитации ошибок.

Список событий остановки определен в файле stopevents.txt. Скрипт stopevents_gen.py генерирует файлы include/utils/stopevents_defs.h (макросы) и include/utils/stopevents_data.h (строки имен) с определениями на C списка событий остановки.