Русский
Русский
English
Статистика
Реклама

Секционирование

DBA меняем слонов на переправе

05.04.2021 12:20:40 | Автор: admin

Как нормальные DBA, мы подождали выпуск пары минорных версий к PostgreSQL 13, который должен порадовать нас многими полезными вещами, и теперь готовы перенести базу нашего сервиса мониторинга этой СУБД с 12-й версии на 13-ю.

Но как это сделать с минимальным простоем, а лучше вообще без него? На помощь придет функционал Foreign Data Wrappers, а точнее - postgres_fdw.

Структура исходной базы

Некоторые детали об устройстве базы нашего сервиса, которые помогают нам очень быстро записывать приходящие данные, я рассказывал в статьях "Пишем в PostgreSQL на субсветовой: 1 host, 1 day, 1TB" и "Экономим копеечку на больших объемах в PostgreSQL". Если в двух словах, то грамотное секционирование БД решает массу проблем производительности.

Мы применяем секционирование по дням в силу того, что у нас приходит по 100-150GB данных ежедневно. Давайте смоделируем структуру нашей базы tst на PostgreSQL 12:

CREATE TABLE archive(  dt    date, val    integer)PARTITION BY RANGE(dt); -- секционирование по диапазонамCREATE TABLE archive_20210401 -- секция конкретного дня  PARTITION OF archive    FOR VALUES FROM ('2021-04-01') TO ('2021-04-02');    -- dt >= '2021-04-01' AND dt < '2021-04-02'CREATE TABLE archive_20210402  PARTITION OF archive    FOR VALUES FROM ('2021-04-02') TO ('2021-04-03');

Хоть каждый день и представлен конкретным значением dt, мы все равно предпочитаем использовать PARTITION BY RANGE с указанием FOR VALUES FROM (dt) TO (dt + 1) вместо PARTITION BY LIST, поскольку этот вариант допускает определенную гибкость - например, можно слить некоторые архивные секции до месячных вместо суточных.

Проверим, как раскладываются по секциям записи при вставке в такую таблицу:

INSERT INTO archiveVALUES  ('2021-04-01', 1), ('2021-04-02', 2)RETURNING  tableoid::regclass, *;
 tableoid        |  dt        | valarchive_20210401 | 2021-04-01 |   1archive_20210402 | 2021-04-02 |   2

tableoid - это одно из системных полей записи, представляющее ссылку на конкретную таблицу (в нашем случае - секцию), в которой она находится. Подробнее можно прочитать в статье "PostgreSQL Antipatterns: уникальные идентификаторы".

"Подцепляем" старые данные

К особенностям нашей базы, как и многих баз мониторинга, можно отнести доминирующую активность только 1-2 последних секций и постепенное "отмирание" с течением времени более не требующихся блоков "сырых" данных.

Поэтому мы можем спокойно развернуть PostgreSQL 13 прямо на том же сервере, не создавая никакой избыточной нагрузки. Для определенности примем, что v12 доступна на :5439, а v13 будет на :5440.

Сначала повторим структуру базы для новых секций на новом сервере:

CREATE TABLE archive(  dt    date, val    integer)PARTITION BY RANGE(dt);CREATE TABLE archive_20210403  PARTITION OF archive    FOR VALUES FROM ('2021-04-03') TO ('2021-04-04');

Чтобы не создавать проекции всех старых секций с помощью IMPORT FOREIGN SCHEMA, ограничимся единственной вспомогательной секцией на определенный вид данных (планы, запросы, ...). Но раз таких видов у нас много, сразу настроим полный доступ к старому серверу, чтобы не копипастить параметры каждый раз:

CREATE EXTENSION postgres_fdw;CREATE SERVER postgresql_12  FOREIGN DATA WRAPPER postgres_fdw    OPTIONS (host '127.0.0.1', port '5439', dbname 'tst');CREATE USER MAPPING FOR postgres  SERVER postgresql_12    OPTIONS (user 'postgres', password 'postgres');

Теперь остается всего лишь создать служебную секцию, обеспечивающую доступ к старым данным:

CREATE FOREIGN TABLE archive_old  PARTITION OF archive    FOR VALUES FROM ('-infinity') TO ('2021-04-03')    -- dt < '2021-04-03'  SERVER postgresql_12    OPTIONS(table_name 'archive');

Тут нам снова удачно помогло использование PARTITION BY RANGE вместо BY LIST, позволив опереться на неравенство.

Проверим, как на новом сервере отработает аналогичная вставка данных:

INSERT INTO archiveVALUES  ('2021-04-01', 1), ('2021-04-02', 2), ('2021-04-03', 3)RETURNING  tableoid::regclass, *;
 tableoid        |  dt        | valarchive_old      | 2021-04-01 |   1 -- старый серверarchive_old      | 2021-04-02 |   2archive_20210403 | 2021-04-03 |   3 -- новая секция

Дополнительные настройки FDW

Если в течение какого-то времени нам необходимо поддерживать возможность записи в старые секции, убедитесь в правильном задании значения FDW-параметра updatable, а если планируете активно читать оттуда - обратите внимание на use_remote_estimate и fetch_size.

Ровно таким же способом, с помощью FDW-секций, можно распределять дисковую нагрузку на другие серверы - только тут уже лучше использовать PARTITION BY HASH, конечно.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru