Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Изменение схемы таблиц без долгих блокировок в PostgreSQL

Изменение схемы таблиц без долгих блокировок в PostgreSQL

Владимир Колясинский (Яндекс) @ MoscowPython Meetup 60

"Во время многих операций по изменению схемы базы данных сервис не может корректно работать на запись. В докладе я расскажу о том, какие операции в PostgreSql требуют длительных блокировок и как мы в Формах Яндекс.Коннекта обеспечиваем почти стопроцентную доступность сервиса на запись во время выполнения таких операций. Также мы поговорим о Django-библиотеке, призванной автоматизировать некоторые из описанных процессов".

Видео: http://www.moscowpython.ru/meetup/60/change-postresql-table-schema/

Moscow Python Meetup
PRO

September 21, 2018
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. View Slide

  2. Владимир Колясинский, разработчик Яндекс.Коннекта
    Изменение схемы таблиц
    без долгих блокировок в
    PostgreSQL

    View Slide

  3. 3
    connect.yandex.ru

    View Slide

  4. 4

    View Slide

  5. Операции требующие длительной блокировки
    Как избежать блокировок по время этих операций
    Операции не требующие длительной блокировки
    Библиотека zero_downtime_migrations
    Содержание
    5

    View Slide

  6. Операции требующие
    долгой блокировки

    View Slide

  7. 7
    ALTER TABLE table ALTER COLUMN column TYPE VARCHAR(32)
    ALTER TABLE table ADD COLUMN column boolean DEFAULT True
    NOT NULL
    VACUUM FULL table
    ALTER TABLE table ADD UNIQUE column
    ALTER TABLE table ADD CONSTRAINT
    CREATE INDEX
    Операции требующие долгой блокировки

    View Slide

  8. Как избежать долгих
    блокировок при
    выполнении этих операций

    View Slide

  9. 〉нельзя запускать в транзакции
    〉занимает больше времени
    〉потенциально может завершиться неудачей
    〉не блокирует таблицу на изменения
    CREATE INDEX CONCURRENTLY
    9
    Создание индекса

    View Slide

  10. Добавление новой not null колонки с default
    10
    ALTER TABLE data ADD COLUMN some_bool INTEGER DEFAULT 1
    NOT NULL;
    UPDATE data SET some_bool = 1 where id in (select id from data where
    some_bool is null limit 5000);
    ALTER TABLE public.comments ALTER COLUMN source_type SET NOT NULL;
    BEGIN;
    ALTER TABLE data ADD COLUMN some_bool INTEGER;
    ALTER TABLE data ALTER COLUMN some_bool SET DEFAULT 1;
    COMMIT;
    =

    View Slide

  11. Изменение типа колонки
    11
    ALTER TABLE table ALTER COLUMN column TYPE type USING (…);
    =
    ALTER TABLE table ADD COLUMN column_new type;
    сделать триггер на insert/update
    перенести данные порциями
    BEGIN;
    DELETE TRIGGER trigger_name;
    ALTER TABLE table DROP COLUMN column;
    ALTER TABLE table RENAME column_new TO column;
    COMMIT;

    View Slide

  12. ALTER TABLE large_table ADD CONSTRAINT token UNIQUE
    USING INDEX token_is_unique;
    12
    Добавление уникальной колонки
    ALTER TABLE table ADD COLUMN column text UNIQUE;
    CREATE UNIQUE INDEX CONCURRENTLY
    token_is_unique ON large_table(token);
    =

    View Slide

  13. Добавление constraint
    13
    ALTER TABLE large_table ADD CONSTRAINT con1 CHECK (column> 100)
    ALTER TABLE large_table VALIDATE CONSTRAINT con1;
    ALTER TABLE large_table ADD CONSTRAINT con1 CHECK (column> 100) NOT
    VALID;
    =

    View Slide

  14. Операции не требующие
    долгой блокировки

    View Slide

  15. ALTER TABLE ADD COLUMN
    15
    ALTER TABLE SET DEFAULT
    ALTER TABLE SET NOT NULL
    ALTER TABLE RENAME column TO new_column
    Изменение длины колонки
    Операции не требующие долгой блокировки
    ALTER TABLE DROP COLUMN

    View Slide

  16. 16
    ALTER TABLE table_name ADD CONSTRAINT constraint_name
    CHECK (column IS NOT NULL) NOT VALID;
    ALTER TABLE table_name VALIDATE CONSTRAINT constraint_name;
    〉существует отдельно от колонки (на уровне таблицы)
    〉0.5-1% влияние на производительность
    〉документация советует явно указывать NOT NULL у колонки
    ALTER TABLE table_name ALTER COLUMN column SET NOT NULL
    Установка колонки not nullable
    =

    View Slide

  17. 〉быстрая операция по умолчанию
    〉колонка помечается устаревшей в pg_attribute
    〉удаление с файловой системы происходит только после
    VACUUM
    DROP COLUMN
    17
    Удаление колонки

    View Slide

  18. zero_downtime_migrations

    View Slide

  19. ZDM Текущие возможности
    19
    https://github.com/Smosker/zero-downtime-migrations
    〉добавление колонки с default значением (nullable or not nullable)
    〉добавление индекса
    〉возможность перезапуска при возникновении ошибок

    View Slide

  20. Подключение
    20
    # settings.py
    DATABASES = {
    'default': {
    'ENGINE': 'zero_downtime_migrations.backend',
    ...
    }
    }
    〉Возможно использование в качестве Mixin в ваших собственных DataBaseWrapper/
    SchemaEditor

    View Slide

  21. Пример работы
    21
    ALTER TABLE "test" ADD COLUMN "field" boolean DEFAULT True NOT NULL;
    ALTER TABLE "test" ALTER COLUMN "field" DROP DEFAULT;
    Стандартный SchemaEditor
    BEGIN;
    ALTER TABLE "test" ADD COLUMN "field" boolean NULL;
    ALTER TABLE "test" ALTER COLUMN "field" SET DEFAULT true;
    COMMIT;
    SchemaEditor из библиотеки

    View Slide

  22. 22
    WITH cte AS (
    SELECT id as pk
    FROM "test" WHERE "field" is null
    LIMIT 10000)
    UPDATE "test" table_
    SET "field" = true FROM cte
    WHERE table_.id = cte.pk
    ALTER TABLE "test" ALTER COLUMN "field" SET NOT NULL;
    ALTER TABLE "test" ALTER COLUMN "field" DROP DEFAULT;

    View Slide

  23. 23
    Выводы
    перед запуском django миграций следует запускать sqlmigrate
    достигаем высокой доступности на запись используя библиотеку
    библиотека развивается - принимаем пул реквесты
    с ростом базы миграции могут замедляться
    в Яндекс.Коннект тысячи RPS, недопустим простой на запись
    запускаем все новые сервисы и нагрузка только растет

    View Slide

  24. Владимир Колясинский
    Разработчик Яндекс.Коннекта
    [email protected]
    @smosker
    Спасибо за внимание
    github.com/Smosker/zero-downtime-migrations
    yandex.ru/forms/

    View Slide