СУБД Сокол (SoQoL) – Telegram
СУБД Сокол (SoQoL)
951 subscribers
53 photos
67 links
Разрабатываем транзакционную СУБД с производительностью кратно выше ведущих систем для рынков России и за рубежом

https://soqol.ru

АО НПП "РЕЛЭКС"
Download Telegram
Что делает СУБД быстрой или медленной, если она работает с диском? Какой ценой достигается более высокое быстродействие?

Все СУБД реализуют свой внутренний кеш для содержимого с диска. При этом они:
1. Могут использовать системный файловый кеш, положившись на организацию ввода-вывода ОС.
2. Запретить ОС кешировать ввод/вывод и реализовать собственную схему ввода-вывода.

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

Второй вариант не имеет недостатков первого, но требует более сложной реализации в СУБД (например, в СУБД Сокол), которая должна обеспечивать:

1. Эффективный ввод/вывод, выраженный в объеме записанной информации в единицу времени.
2. "Честный" ввод/вывод, равномерно обслуживающий запросы ввода/вывода и соблюдающий приоритеты.
3. Масштабируемый ввод/вывод, позволяющий утилизировать возможности современных дисковых систем.

Эффективность ввода-вывода в СУБД Сокол реализуется за счет укрупнения областей в запросах ввода/вывода.

"Честность" обеспечивается за счет постановки запросов ввода-вывода от параллельных задач в глобальную очередь внутри СУБД.
Разделение запросов по приоритету обеспечивается за счет выделения разных очередей для категорий:
- абсолютно приоритетная очередь записи журнала;
- приоритетная очередь чтения запрашиваемых данных;
- приоритетная очередь записи вытеснения;
- очередь отложенной записи данных хранилища - то, что ассоциируется с checkpointing.

Более высокий приоритет определяется большей разрешенной "глубиной очереди" - количеством активных запросов к ОС из данной очереди. Большая глубина очереди обеспечивает большую пропускную способность запросов из нее. Очередь записи в журнал имеет самый высокий приоритет и не имеет ограничений на глубину, кроме ограничений внутреннего алгоритма группового коммита.

Очереди всех категорий обрабатываются параллельно всеми ядрами ЦПУ. Это обеспечивает возможность масштабирования ввода-вывода. Глубина менее приоритетных очередей регулируется динамически и при отсутствии конкуренции они могут занять всю пропускную полосу диска.

Что известно о других системах:
- В opensource любят "срезать углы" - тут в основном используется вариант двойного кеширования.
- MS SQL и Oracle используют ввод-вывод без двойного кеширования. В документации у них нет упоминания о внутреннем планировщике ввода-вывода. Безусловно это не означает, что они не решали обозначенные задачи. Просто их терминология, постановка задачи и решение немного другие.

Что вы знаете о кешировании и вводе/выводе в известных вам системах, а также о преимуществах и недостатках в их реализации?
7👍2
Из каких фаз состоит процесс трансляции SQL-запроса в Соколе? Есть ли здесь место для дополнительных оптимизаций?

В Соколе можно выделить следующие фазы трансляции SQL-запроса:
1. Поиск по тексту запроса готового кода исполнения в кеше (назовем его кеш №1) для текущей схемы.
2. Синтаксический анализ и параметризация запроса (константы тоже выносятся в параметры), на выходе - абстрактное синтаксическое дерево.
3. Компоновка, связывание символических объектных ссылок с объектами базы данных, на выходе - связанное синтаксическое дерево.
4. Поиск по сериализованной структуре связанного синтаксического дерева готового кода исполнения запроса в кеше (назовем его кеш №2).
5. Оптимизация:
- построение разных вариантов реляционных деревьев и выбор оптимального на основе связанного синтаксического дерева;
- построение вариаций физических планов и выбор оптимального на основе реляционных деревьев.
6. Кодогенерация:
- генерация виртуального IR (Internal Representation) кода;
- (опционально) генерация нативного JIT кода на основе LLVM.
7. Сохранение кода откомпилированного запроса в кешах запросов:
- по тексту запроса для текущей схемы в кеш №1;
- по сериализованной структуре связанного синтаксического дерева в кеш №2.

Тему устройства кешей рассмотрим в отдельном посте.

В прочих СУБД процесс трансляции может отличаться, но в целом соответствует описанной схеме.
Принципиальные отличия:
- обозначенные 2 кеша запросов (по тексту и по по сериализованной структуре связанного синтаксического дерева) реализованы на основе неблокирующих подходов;
- наличие обязательного этапа кодогенерации и на каких принципах происходит генерация кода (о чем чуть подробней далее).

JIT трансляция активируется хинтом /*+ JIT_CODEGEN */, который нужно разместить после ключевых слов операторов SELECT/INSERT/UPDATE/DELETE. Для процедур и функций хинт должен находиться после спецификации аргументов, а для анонимных блоков после ключевого слова DECLARE.

Для генерации кода используется дата-центричный подход. Идея была озвучена в статье: http://sites.computer.org/debull/A14mar/p3.pdf

Изначальная идея исполнительной системы Сокола формировалась на основе генерации нативного кода. Тем не менее, дата-центричный подход хорошо работает и для виртуального кода. Для коротких запросов из TPC-C бечмарка разница в пиковых результатах между JIT кодом и виртуальным не превышает 10%. Для более серьезных и длительных запросов JIT показывает двукратное повышение производительности. Использование виртуального кода обусловлено высокой ценой JIT-трансляции.

Другая отличительная черта исполнительной системы Сокола - это бесшовный переход исполнения от процедурного кода к коду запроса. Обе подсистемы исполнены в единой архитектуре исполнительной системы. Генерируемый код процедуры включает в себя код статических запросов, используемых внутри процедуры, без какого-либо переключения контекста (привет Ораклу).

Идею генерации кода можно развить дальше, например:
- код хранимых процедур оформить в виде динамически загружаемых библиотек. В качестве единицы трансляции (DLL-библиотека) здесь подходит пакет хранимых процедур;
- сделать трансляцию запросов в JIT быстрой (и обязательной) за счет использования собственного быстрого кодогенератора на основе подхода copy and patch - https://en.wikipedia.org/wiki/Copy-and-patch

Как оцениваете идею помещения кода хранимых процедур в DLL (не путать с DDL :) ) на фоне однородности кода хранимок и SQL-запросов, которой удалось достичь в Соколе?
С какими узкими местами в описанном процессе приходилось бороться?
👍62
Через 15 минут выступаем
🔥26🎉2🆒1
Во время выступления
👍16
После выступления. Спасибо всем, кто смотрел и задавал вопросы!
👍13
Слайды презентации нашего выступления на ArchDays в Москве 5 ноября - https://archdays.ru/?speaker=2081 (скроллингуйте вниз)
👍2🔥2
В Соколе в ночных сборках появилась поддержка функций. Пока описания синтаксиса в документации нет, но для начала можно оттолкнуться от примера:

create or replace function f_inc(a IN int) return int
as
begin
return a + 1;
end;

Синтаксис тела и описания параметров функций соответствует синтаксису хранимых процедур (примеры есть в папке examples дистрибутива).

Пока тестируем. Уже пробуете? 😉
🔥11👍1🤓1
Рады сообщить вам итог одной важной работы, проделанной совместно с компанией ФОРС Дистрибуция. Многие из вас знают, что эта компания является одним из крупнейших сервисных центров по технологиям Oracle в России и прекрасно понимает толк в вопросах быстродействия СУБД. Делимся результатами в совместном пресс-релизе.
👍21🔥2
Новые изменения в новом окружении.
Так как Сокол - это дисковая СУБД, то интересно увидеть, как она работает с диском.
Во всех указанных здесь измерениях на основе TPC-C бенчмарка оперативная память ограничена 192GB. Нас интересовало массовое обслуживания, поэтому количество параллельных соединений не брали из малого диапазона, а взяли 1600.

Необходимость вытеснения на диск в измерении варьируется за счет количества складов теста TPC-C:
- размер базы данных из 1 тысячи складов занимает примерно 100GB на диске;
- размер базы данных из 10 тысяч складов занимает примерно 1TB на диске.

Предлагаем 3 набора измерений Сокола (количество ядер ЦПУ варьируется и диски тоже разного качества - этим тоже интересны тесты):
- 20 виртуальных ядер из vmware, виртуальный диск на неизвестной конфигурации tatlin поверх SSD;
- 40 логических ядер с учетом гипертрейдинга, диск NVME SSD 4х6.4T;
- 80 логических ядер с учетом гипертрейдинга, диск SATA SSD 8x200GB.
👍6
Поздравляем с наступающим Новым 2025 Годом! 🎉🎊💥 Здоровья и счастья в новом году! Пусть все желания сбудутся! Сокол будет присматривать за их исполнением
🍾24👍3🔥3🆒21👏1
Доброго дня, наши подписчики!

Приветствуем вас в новом 2025 году! Надеемся, что вы успешно в него вступили и горите новыми идеями и задачами. Сил вам для всех свершений!

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

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

Отличительные черты разрабатываемого решения:

• масштабируемый процесс репликации для утилизации современного многоядерного оборудования. Подразумевается что передача, прием и воспроизведение реплицируемых данных осуществляются параллельно;

• отказоустойчивость основывается на переработанной идеи RAFT-протокола, RAFT-журнал является вторичным по отношению к WAL и допускает сегментацию на несколько потоков для параллельного обслуживания;

• используется формат только логической репликация для уменьшения объема передаваемой информации и возможной интеграции с третьесторонними продуктами в будущем, например, для полного копирования БД или формирования инкрементных обновлений для сторонних СУБД посредством повторной сериализации операций из RAFT-журнала;

• сервисы горячего резервирования и архивирования создаются на основе общего протокола и механизма репликации. Ожидается, что в кластере репликации могут находиться одновременно и узлы архивирования (с поддержкой PITR) и узлы резервирования. Например, отказоустойчивая конфигурация может состоять из 3-х узлов: 2 операционных узла, любой из которых может быть лидером в определенный момент, и узел синхронного архивирования, который также участвует в консенсус алгоритмах, хотя и не может стать лидером;

• узел с синхронной репликацией может находиться на значительном расстоянии при удовлетворительной пропускной способности сети. Расплатой является бОльшая латенси подтверждения транзакции. При этом, характеристика производительности кластера репликации при параллельной нагрузке сохраняется;

• данные на репликах доступны для чтения. Дополнительно можно организовать масштабирование операций чтения;

• режим использования репликации в сервисах - синхронный, асинхронная репликация опциональна.

Поддерживаете такое видение или нужны корректировки "политики партии"?
9👍5
Доброго дня всем! Сегодня поговорим об этом.
upd: по оси ординат число транзакций в минуту
🔥4
Часто спрашивают, а есть ли в Соколе "connection pool". Ну, типа, в любой серьезной СУБД такое должно быть.

Краткий ответ "нет и вам это не нужно", обычно не воспринимается как положительный.
Давайте, разбираться.

Рассмотрим ранее приведенные измерения TPC-C бенчмарка с разным количеством складов: 10К-1К.
Только сделаем два набора измерений: с числом клиентов 160 и 1600. Почему 160 клиентов? Ну просто потому, что ранее у PG при таких условиях мы наблюдали пик производительности.

Для PG особой разницы для двух измерений не видно, разве что большее количество соединений требует больше памяти, но это в измерениях не фигурирует. В PG практикуется использование различных прокси-приложений, играющих роль "connection pool", как минимум для экономии памяти.

В Соколе же большее количество соединений дает бОльшую отдачу от системы.
Причины:
1. Большое число параллельных активных соединений способствует более эффективному GROUP COMMIT, цена синхронизации отдельной транзакции падает.
2. При большем количестве соединений поддерживается постоянная нагрузка на ЦПУ - пока одни потоки ожидают подтверждения коммита, другие работают.
3. Фрагментация памяти между конкурирующим соединениями исключается за счет предварительной оценки необходимых ресурсов для исполнения запроса и атомарного запроса их целиком у системы.
4. Ресурсные затраты для неактивного соединения минимизированы, все ресурсы освобождаются.

Что можно на основе этого сказать?
1. Использование промежуточного приложения-мультиплексора соединений (он же "connection pool") - это часто вынужденная мера для компенсации архитектурных особенностей в существующей системе.
2. Мультиплексор соединений может быть даже вреден и может препятствовать эффективной работе СУБД, которая хорошо работает с большим количество соединений.
3. Сокол использует модель "coroutine per connection" и более того, неактивное соединение переходит в бесстековое состояние. Неактивное соединение не требует каких-либо значительных ресурсов. Можно сказать, что сам Сокол является отличным мультиплексором соединений.

Уточнение:
Термин "connection pool" может быть использован в разных смыслах. Здесь мы рассматривали его именно как мультиплексор соединений к СУБД, когда количество логических подключений от пользователя больше, чем число возможных подключений, которое обеспечивает СУБД.
Другое дело когда "connection pool" создается с целью уменьшения времени установления каждого нового соединения. Такая практика имеет право на жизнь и ее не будем оспаривать.
🔥13
Всем доброго дня!
В понедельник, 17 марта состоится шестой митап российского сообщества разработчиков СУБД и распределенных систем, где мы от команды СУБД Сокол выступим с докладом "Можно ли сделать репликацию параллельной и как увязать RAFT-журнал с WAL-журналом?".
Мероприятие бесплатное. Регистрация обязательна. При очном участии обязательно наличие паспорта. Участвующим онлайн будет доступна трансляция на YouTube и чат.
Присоединяйтесь - https://databaseinternals.timepad.ru/event/3263638/
🔥4👍3
Отличной всем пятницы!

💥 На конференции Saint HighLoad++ 23/24 июня 2025 в Санкт-Петербурге выступаем с докладом "Пределы и узкие места масштабирования дисковых СУБД" (https://highload.ru/spb/2025/abstracts/15004) "... Предлагаем рассмотреть СУБД Сокол в озвученных обстоятельствах в сравнении с другими системами."
Планируйте, приезжайте и приходите
👍23🔥6
Channel name was changed to «СУБД Сокол (SoQoL)»
Опция NOLOGGING

На днях мы немного пообщались с отдельными подписчиками в чате, привязанному к каналу (доступен в настройках канала в разделе "Посмотреть обсуждение"). Но поскольку не все на него подписаны, многие не получили уведомлений об этом. Поэтому мы решили написать собственно в канал. Тем более мы давно уже не радовали вас тут новой информацией и знаем, что вы соскучились по ней и по обсуждениям 😀

А вы помните, что временные таблицы логируются, изменения ведутся транзакционно и могут быть откачены в том числе с использованием точек сохранения?

Но транзакционная работа во временных таблицах нужна не всегда. Появилась возможность использовать опцию NOLOGGING при создании временных таблиц. В этом случае при работе с ними запись в журнал WAL вестись не будет.

Опция NOLOGGING позволяет уравнять сложность работы с хранилищем временных таблиц до уровня объектов пользовательских табличных типов. Кстати, в Соколе появилась возможность использования табличных типов данных в процедурном языке и SQL, но об этом в другом посте.

Примеры:
  CREATE GLOBAL TEMPORARY TABLE tt0 (i int) ON COMMIT DELETE ROWS NOLOGGING;
CREATE GLOBAL TEMPORARY TABLE tt1 (i int) ON COMMIT PRESERVE ROWS NOLOGGING;
CREATE PRIVATE TEMPORARY TABLE #tt1 (i int) ON COMMIT preserve definition NOLOGGING;


Если используете такое, ставьте 👏.
4👏4🔥2👍1
Передача выборок из исполняемого на сервере процедурного кода клиентскому приложению

Некоторые из вас знают, насколько элегантно выглядит в MS SQL Server синтаксис передачи клиенту табличных данных из процедуры - используется оператор SELECT без указания переменных для сохранения результата. Нужно извлечь несколько результатов табличного вида (то есть выборок, состоящих из строк и столбцов) из одной процедуры - пожалуйста! Для этого напишите нужные SELECT в нужных местах хранимой процедуры. Результаты в виде отдельных resultSet уходят в клиентское приложение.

Теперь так можно делать и в Соколе.

Можно использовать такую возможность не только по прямому назначению (передача пользовательских данных), но и для передачи, например, отладочной информации и т.д.
Только не забывайте об одном важном моменте - сервер гарантирует завершение исполнения процедуры только в том случае, если извлечены (точнее проитерированы) все ее результаты (вспоминаем про метод moreResultSet).

А если вам не терпится попробовать, быстренько настраиваем DBeaver. Для этого идем в настройки драйвера для доступа к Соколу (Driver Settings) открываем вкладку Advanced Parameters и ставим галку в параметре Driver supports multiple results. Это всё. Успехов!

Пример процедурного кода в виде анонимного блока:
BEGIN
SELECT 1,'первая выборка';
SELECT 'другая выборка', CURRENT_TIMESTAMP;
END;


Если можете рассказать о ваших примерах применения таких возможностей в используемой вами СУБД, будем рады послушать.
🔥14