[PostgreSQL, Java, Тестирование веб-сервисов] История о PostgreSQL 13, Testcontainers и багах
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Привет Хабр!Несмотря на то, что на текущем месте работы взаимодействовать с PostgreSQL приходится значительно меньше, я продолжаю поддерживать свою библиотеку pg-index-health. Недавно я зарелизил версию 0.3.1, ключевой особенностью которой стала поддержка PostgreSQL 13.Эта история началась достаточно давно, ещё в октябре 2020. В процессе мне пришлось отказаться от embedded версии СУБД в тестах, перейти на Testcontainers, столкнуться с ошибкой в PG13 и даже немного пообщаться в переписке с одним из разработчиков Постгреса... Но обо всем по порядку.
Изначально для тестирования библиотеки я использовал embedded PostgreSQL. Я уже рассказывал об этом ранее. В целом это был неплохой вариант, но он завязан на чужие бинарники и их релизный цикл. Артефакта с 13-й версией долгое время не было (зарелизили только 13 ноября, спустя полтора месяца с момента начала моих экспериментов). Очевидно, что дальше жить с таким вариантом было крайне неудобно.Альтернативный подход тоже был известен – Testcontainers (спасибо Николаю Кондратьеву за всю подготовительную работу), но мне до последнего момента не хотелось на него переходить. Дело в том, что Testcontainers — это дополнительный достаточно толстый слой между приложением и базой, запускаемой в Docker-контейнере. На MacOS и Windows такое решение время от времени ломается. И я столкнулся с этим. Дважды. Сначала на MacOS, затем на Windows.Но что более печально, в Github Actions тесты с использованием Testcontainers можно запускать только на Ubuntu. По крайней мере у меня не получилось сделать это для Windows и MacOS. Если вы знаете, как настроить такую связку, буду премного благодарен за совет.В какой-то момент времени все тесты в моём проекте оказались переведены на Testcontainers и успешно проходили на 11-й и 12-й версиях. Затем я переключил проект на ванильный образ с 13.0... И тут меня ждал облом... Тесты на оценку bloat'а индексов упали. В отдельной ветке я подготовил проект для демонстрации этой ошибки.
Ошибки в тестах на PostgreSQL 13.0Первичный анализ ничего не дал. Никаких принципиальных изменений, которые бы ломали обратную совместимость между 12-й и 13-й версиями не было. Углублённое чтение release notes познакомило меня со сжатием дубликатов в b-tree индексах в новой версии - фичей, которую я ранее как-то совсем упустил (да, так тоже бывает).Возможно, эти доработки и стали причиной изменившегося поведения (а может и нет - на детальное изучение кодовой базы PostgreSQL у меня не было времени и сил). Но вот "баг это или фича" и как теперь правильно оценивать bloat индексов, я не понимал. В открытых источниках ничего полезного найти не удалось.И тогда я решил написать одному из соавторов доработок по сжатию дубликатов в b-tree индексах - Анастасии Лубенниковой. И… нет, здесь happy end'а не случилось: у Анастасии не было для меня готового решения, а потом навалилась работа, и на долгих два месяца я забросил проект...Вернуться к PG 13 удалось только в начале января 2021. И я решил попробовать недавно вышедшее минорное обновление 13.1. Представьте себе моё удивление и радость, когда на этой версии все тесты прошли. На 13.1 оценка bloat'а индексов снова стала работать корректно!Мораль этой истории проста и банальна: не стоит тащить новую версию любимой СУБД сразу в production. Ошибки бывают везде. Главное, чтобы они оперативно исправлялись. Ну а лично для меня приятным открытием стало то, что моё детище можно использовать как инструмент для acceptance testing (вернее, как его небольшую часть).А что там со сжатием дубликатов в b-tree, спросите вы? Может быть, оно способно полностью решить проблему с null value в индексах?.. Увы, нет.Сжатие дубликатов работает хорошо, даже замечательно. Вы можете проверить это самостоятельно. По ссылке подготовлен скрипт для инициализации и наполнения небольшой тестовой БД и команды для запуска двух разных версий СУБД в контейнере.Init-db скрипт
create table if not exists test
(
id bigserial primary key,
fld varchar(255),
mark varchar(255),
nil varchar(255)
);
insert into test
select data.id, case when data.id % 2 = 0 then now()::text else null end, case when data.id % 2 = 0 then 'test_string'::text else null end, null
from generate_series(1, 100000) as data(id);
create index if not exists i_test_fld_with_nulls on test (fld);
create index if not exists i_test_fld_without_nulls on test (fld) where fld is not null;
create index if not exists i_test_mark_with_nulls on test (mark);
create index if not exists i_test_mark_without_nulls on test (mark) where mark is not null;
create index if not exists i_test_nil_with_nulls on test (nil);
create index if not exists i_test_nil_without_nulls on test (nil) where nil is not null;
Команды для запуска в Docker
docker run --name postgres-13 -e POSTGRES_USER=testuser -e POSTGRES_PASSWORD=testpwd -e POSTGRES_DB=testdb -d -p 5432:5432 -v /absolute/path/to/initdb.sql:/docker-entrypoint-initdb.d/initdb.sql postgres:13.2
docker run --name postgres-12 -e POSTGRES_USER=testuser -e POSTGRES_PASSWORD=testpwd -e POSTGRES_DB=testdb -d -p 6432:5432 -v /absolute/path/to/initdb.sql:/docker-entrypoint-initdb.d/initdb.sql postgres:12.6
psql -U testuser -d testdb
SQL запрос для оценки размера индексов
select
x.indrelid::regclass as table_name,
x.indexrelid::regclass as index_name,
pg_size_pretty(pg_relation_size(x.indexrelid)) as index_size
from pg_index x
join pg_stat_all_indexes psai on x.indexrelid = psai.indexrelid and psai.schemaname = 'public'
order by 1,2;
На выходе получим следующее:Результаты в текстовом видеPostgreSQL 12table_nameindex_nameindex_sizetesttest_pkey2208 kBtesti_test_fld_with_nulls3552 kBtesti_test_fld_without_nulls2456 kBtesti_test_mark_with_nulls2664 kBtesti_test_mark_without_nulls1568 kBtesti_test_nil_with_nulls2224 kBtesti_test_nil_without_nulls8192 bytesPostgreSQL 13table_nameindex_nameindex_sizetesttest_pkey2208 kBtesti_test_fld_with_nulls704 kBtesti_test_fld_without_nulls368 kBtesti_test_mark_with_nulls696 kBtesti_test_mark_without_nulls360 kBtesti_test_nil_with_nulls696 kBtesti_test_nil_without_nulls8192 bytesОбратите внимание, что размер индекса по первичному ключу, где все значения уникальны, не изменился.
Демонстрация сжатия дубликатовКак видите, выбрасывать null value из индекса целиком по-прежнему крайне выгодно, и этой диагностикой не стоит пренебрегать.Ну и напоследок. Embedded PG уходит в прошлое. Сейчас стоит отдавать предпочтение более современным и совершенным решениям наподобие Testcontainers.
===========
Источник:
habr.com
===========
Похожие новости:
- [JavaScript, Angular, TypeScript] Глобальные объекты в Angular
- [Java] Управление памятью Java (перевод)
- [Тестирование IT-систем, Я пиарюсь, Тестирование веб-сервисов, Тестирование мобильных приложений, Тестирование игр] Лучшие сайты для практики автоматизации тестирования (перевод)
- [Java, Анализ и проектирование систем, Lisp, Проектирование и рефакторинг, Конференции] Effective Programs (10 Years of Clojure) — Rich Hickey (с русским переводом) (перевод)
- [Java] Настройка Spring Data JPA с помощью Spring Boot (перевод)
- [Информационная безопасность, Системное администрирование, DevOps, Kubernetes] 10 Kubernetes Security Context, которые необходимо понимать (перевод)
- [Nginx, Машинное обучение, DevOps, Микросервисы, Flask] Развертывание ML модели в Docker с использованием Flask (REST API) + масштабирование нагрузки через Nginx балансер
- [Scala, Браузеры, Тестирование веб-сервисов] Scala + Selenium. Сколько человек в сборной имеют более одного гражданства?
- [PostgreSQL] Рекомендации по развертыванию Гибридного Облака (Hybrid Cloud) PostgreSQL (перевод)
- [Java, C++, Go] Внимание: все сервисы Bintray будут прекращены, а ваши учетные записи будут отключены 1 мая 2021 года. — JFrog
Теги для поиска: #_postgresql, #_java, #_testirovanie_vebservisov (Тестирование веб-сервисов), #_testcontainers, #_docker, #_postgresql, #_bloat, #_embedded_database, #_postgresql, #_java, #_testirovanie_vebservisov (
Тестирование веб-сервисов
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 10:15
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Привет Хабр!Несмотря на то, что на текущем месте работы взаимодействовать с PostgreSQL приходится значительно меньше, я продолжаю поддерживать свою библиотеку pg-index-health. Недавно я зарелизил версию 0.3.1, ключевой особенностью которой стала поддержка PostgreSQL 13.Эта история началась достаточно давно, ещё в октябре 2020. В процессе мне пришлось отказаться от embedded версии СУБД в тестах, перейти на Testcontainers, столкнуться с ошибкой в PG13 и даже немного пообщаться в переписке с одним из разработчиков Постгреса... Но обо всем по порядку. Изначально для тестирования библиотеки я использовал embedded PostgreSQL. Я уже рассказывал об этом ранее. В целом это был неплохой вариант, но он завязан на чужие бинарники и их релизный цикл. Артефакта с 13-й версией долгое время не было (зарелизили только 13 ноября, спустя полтора месяца с момента начала моих экспериментов). Очевидно, что дальше жить с таким вариантом было крайне неудобно.Альтернативный подход тоже был известен – Testcontainers (спасибо Николаю Кондратьеву за всю подготовительную работу), но мне до последнего момента не хотелось на него переходить. Дело в том, что Testcontainers — это дополнительный достаточно толстый слой между приложением и базой, запускаемой в Docker-контейнере. На MacOS и Windows такое решение время от времени ломается. И я столкнулся с этим. Дважды. Сначала на MacOS, затем на Windows.Но что более печально, в Github Actions тесты с использованием Testcontainers можно запускать только на Ubuntu. По крайней мере у меня не получилось сделать это для Windows и MacOS. Если вы знаете, как настроить такую связку, буду премного благодарен за совет.В какой-то момент времени все тесты в моём проекте оказались переведены на Testcontainers и успешно проходили на 11-й и 12-й версиях. Затем я переключил проект на ванильный образ с 13.0... И тут меня ждал облом... Тесты на оценку bloat'а индексов упали. В отдельной ветке я подготовил проект для демонстрации этой ошибки. Ошибки в тестах на PostgreSQL 13.0Первичный анализ ничего не дал. Никаких принципиальных изменений, которые бы ломали обратную совместимость между 12-й и 13-й версиями не было. Углублённое чтение release notes познакомило меня со сжатием дубликатов в b-tree индексах в новой версии - фичей, которую я ранее как-то совсем упустил (да, так тоже бывает).Возможно, эти доработки и стали причиной изменившегося поведения (а может и нет - на детальное изучение кодовой базы PostgreSQL у меня не было времени и сил). Но вот "баг это или фича" и как теперь правильно оценивать bloat индексов, я не понимал. В открытых источниках ничего полезного найти не удалось.И тогда я решил написать одному из соавторов доработок по сжатию дубликатов в b-tree индексах - Анастасии Лубенниковой. И… нет, здесь happy end'а не случилось: у Анастасии не было для меня готового решения, а потом навалилась работа, и на долгих два месяца я забросил проект...Вернуться к PG 13 удалось только в начале января 2021. И я решил попробовать недавно вышедшее минорное обновление 13.1. Представьте себе моё удивление и радость, когда на этой версии все тесты прошли. На 13.1 оценка bloat'а индексов снова стала работать корректно!Мораль этой истории проста и банальна: не стоит тащить новую версию любимой СУБД сразу в production. Ошибки бывают везде. Главное, чтобы они оперативно исправлялись. Ну а лично для меня приятным открытием стало то, что моё детище можно использовать как инструмент для acceptance testing (вернее, как его небольшую часть).А что там со сжатием дубликатов в b-tree, спросите вы? Может быть, оно способно полностью решить проблему с null value в индексах?.. Увы, нет.Сжатие дубликатов работает хорошо, даже замечательно. Вы можете проверить это самостоятельно. По ссылке подготовлен скрипт для инициализации и наполнения небольшой тестовой БД и команды для запуска двух разных версий СУБД в контейнере.Init-db скрипт create table if not exists test
( id bigserial primary key, fld varchar(255), mark varchar(255), nil varchar(255) ); insert into test select data.id, case when data.id % 2 = 0 then now()::text else null end, case when data.id % 2 = 0 then 'test_string'::text else null end, null from generate_series(1, 100000) as data(id); create index if not exists i_test_fld_with_nulls on test (fld); create index if not exists i_test_fld_without_nulls on test (fld) where fld is not null; create index if not exists i_test_mark_with_nulls on test (mark); create index if not exists i_test_mark_without_nulls on test (mark) where mark is not null; create index if not exists i_test_nil_with_nulls on test (nil); create index if not exists i_test_nil_without_nulls on test (nil) where nil is not null; docker run --name postgres-13 -e POSTGRES_USER=testuser -e POSTGRES_PASSWORD=testpwd -e POSTGRES_DB=testdb -d -p 5432:5432 -v /absolute/path/to/initdb.sql:/docker-entrypoint-initdb.d/initdb.sql postgres:13.2
docker run --name postgres-12 -e POSTGRES_USER=testuser -e POSTGRES_PASSWORD=testpwd -e POSTGRES_DB=testdb -d -p 6432:5432 -v /absolute/path/to/initdb.sql:/docker-entrypoint-initdb.d/initdb.sql postgres:12.6 psql -U testuser -d testdb
select
x.indrelid::regclass as table_name, x.indexrelid::regclass as index_name, pg_size_pretty(pg_relation_size(x.indexrelid)) as index_size from pg_index x join pg_stat_all_indexes psai on x.indexrelid = psai.indexrelid and psai.schemaname = 'public' order by 1,2; Демонстрация сжатия дубликатовКак видите, выбрасывать null value из индекса целиком по-прежнему крайне выгодно, и этой диагностикой не стоит пренебрегать.Ну и напоследок. Embedded PG уходит в прошлое. Сейчас стоит отдавать предпочтение более современным и совершенным решениям наподобие Testcontainers. =========== Источник: habr.com =========== Похожие новости:
Тестирование веб-сервисов ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 10:15
Часовой пояс: UTC + 5