Оригинальный код: https://github.com/sgrinko/docker-postgres
Докер основан на официальном образе postgres и postgis:
https://hub.docker.com/_/postgres
https://github.com/docker-library/postgres
https://hub.docker.com/r/postgis/postgis
https://github.com/postgis/docker-postgis
Разработан набор контейнеров, обеспечивающих полную поддержку всех компонентов для развертывания на DEV, TEST и PROD в единой конфигурации
Докеры для работы с постгрес находятся в подкаталоге docker-postgres Для каждой версии Postgres создан свой подкаталог по номеру мажорной версии. Докер docker-pgbouncer не зависит от версии PostgreSQL, поэтому в github он находится в отдельном репозитарии https://github.com/sgrinko/docker-pgbouncer Для того чтобы использовать докеры в работе (и в разработке) рекомендуется в произвольном каталоге расположить в таком виде докеры;
Общая структура каталогов:
├── bin
├── docker-analyze
├── docker-mamonsu
├── docker-pgbouncer
├── docker-pgprobackup
├── docker-pgprorestore
├── docker-pgupgrade
└── docker-postgres
Для более удобного управления стартом/разработкой контейнеров используется docker-compose. Для этого разработаны следующие compose yml файлы, которые лежат в корне каталога:
Скрипт | Описание |
---|---|
analyze-service.yml | настройки запуска контейнера docker-analyze для выполнения процедуры сбора статистики выполняемых запросов в Postgres и ротации логов |
backup-service.yml | настройки запуска контейнера docker-pgprobackup для выполнения процедуры создания бэкапа кластера БД |
check_cluster_service.yml | настройки запуска контейнера docker-pgprobackup для выполнения процедуры проверки кластера |
postgres-pgupgrade.yml | настройки запуска контейнера docker-pgupgrade (контейнер обновления мажорной версии) |
postgres-service_all.yml | настройки запуска 3-х контейнеров: docker-postgres, docker-pgbouncer и docker-mamonsu |
postgres-service_pgb.yml | настройки запуска контейнера docker-postgres, docker-pgbouncer |
postgres-service.yml | настройки запуска контейнера docker-postgres |
restore-service.yml | настройки запуска контейнера docker-pgprorestore для выполнения процедуры восстановления кластера из бэкапа |
show_backup-service.yml | настройки запуска контейнера docker-pgprobackup. Выполняет процедуру показа содержимого каталога бэкапов с возможностью отправки этой информации на почту |
Эти скрипты лежат в корне каталога соотвествующей версии контейнеров.
В каталоге bin находятся sh файлы для старта/сборки контейнеров:
Скрипт | Описание |
---|---|
analyze_start.sh | сбор статистики выполнения запросов в Postgres и выполнения ротации логов. Логи Postgres хранятся в течение 30 дней, а логи mamonsu и pgbouncer в течение 1 недели |
backup_start.sh | запуск создания бэкапа (FULL или DELTA/PAGE) |
check_cluster_start.sh | полная очистка каталога контейнеров. При множественной корректировке контейнеров накапливается много "старых" контейнеров и выполнять их чистку иногда полезно |
clear_all_docker.sh | удаление всех загруженных image контейнеров и их производных, чтобы полностью очистить рабочее пространство |
docker_start.sh | запуск контейнера postgres используя команду docker run ... |
hub_push.sh | скрипт загрузки образов докер на hub.docker.com |
postgres_start_all.sh | запуск комплекса контейнеров (postgres + pgbouncer + mamonsu) работающих не в фоне и выводящих свои сообщения в терминал |
postgres_start_pgb.sh | запуск комплекса контейнеров (postgres + pgbouncer) работающих не в фоне и выводящих свои сообщения в терминал |
postgres_start.sh | запуск контейнера postgres работающего не в фоне и выводящего свои сообщения в терминал |
restore_start.sh | запуск восстановления кластера из бэкапа. При этом контейнер postgres не должен работать |
show_start.sh | запуск вывода информации о текущих созданных бэкапах. Есть возможность отправки на почту результатов |
upgrade_start.sh | запуск контейнера pgupgrade для мажорного обновления кластера |
Контейнер ориентирован на работу с русской локалью. Внутри выполняются следующие команды для локализации:
RUN localedef -i ru_RU -c -f UTF-8 -A /usr/share/locale/locale.alias ru_RU.UTF-8
ENV LANG ru_RU.utf8
Инициализация новой БД выполняется по умолчанию с параметрами к initdb: --locale=ru_RU.UTF8 --data-checksums
Дополнительно добавлены следующие компоненты:
pg_probackup
- утилита для работы с бэкапами от Postgres Professionalsendemail
- используется для отправки почты- установлен пакет для коннекта к MSSQL через FDW расширение
tds_fdw
c использованием пакетаfreetds
. В файле конфигурации/etc/freetds/freetds.conf
для параметраtext size
установлено значение: 1262485504 (1204Мб) - В БД postgres добавлено расширение
pg_cron
для возможности выполнения заданий внутри каждой БД по расписанию. В других БД создаётся обертка из схемыpg_cron
, 2-х внешних таблиц и нескольких функций, что позволяет использовать простое управление заданиями локально для каждой БД. htop
- удобная утилита для просмотра запущенных процессов внутри контейнераmc
- всем известный файловый менеджер- дополнительно к исходным 3-м БД создана шаблонная БД с именем
template_extension
В шаблонную БД установлены расширения:
Extension | Description |
---|---|
adminpack | administrative functions for PostgreSQL |
amcheck | functions for verifying relation integrity |
btree_gin | support for indexing common datatypes in GIN |
citext | data type for case-insensitive character strings |
dblink | connect to other PostgreSQL databases from within a database |
file_fdw | foreign-data wrapper for flat file access |
fuzzystrmatch | determine similarities and distance between strings |
hunspell_en_us | en_US Hunspell Dictionary |
hunspell_ru_ru | Russian Hunspell Dictionary |
hunspell_ru_ru_aot | Russian Hunspell Dictionary (from AOT.ru group) |
pageinspect | inspect the contents of database pages at a low level |
pg_buffercache | examine the shared buffer cache |
pg_background | Run SQL queries in the background |
pg_dbo_timestamp | PostgreSQL extension for storing time and author of database structure modification |
pg_prewarm | prewarm relation data |
pg_repack | Reorganize tables in PostgreSQL databases with minimal locks |
pg_stat_statements | track execution statistics of all SQL statements executed |
pg_trgm | text similarity measurement and index searching based on trigrams |
pg_tsparser | parser for text search |
pg_variables | session variables with various types |
pgstattuple | show tuple-level statistics |
pldbgapi | server-side support for debugging PL/pgSQL functions |
plpgsql | PL/pgSQL procedural language |
plpgsql_check | extended check for plpgsql functions |
plpython3u | PL/Python3U untrusted procedural language |
postgis | PostGIS geometry, geography, and raster spatial types and functions |
postgis_tiger_geocoder | PostGIS tiger geocoder and reverse geocoder |
postgis_topology | PostGIS topology spatial types and functions |
postgres_fdw | foreign-data wrapper for remote PostgreSQL servers |
rum | RUM index access method |
shared_ispell | Provides shared ispell dictionaries. |
uuid-ossp | generate universally unique identifiers (UUIDs) |
Настроены 5 конфигураций полнотекстового поиска для русского и английского языка:
Name | Description |
---|---|
fts_aot_en_ru | FTS hunspell AOT configuration for russian language based on shared_ispell without stopwords |
fts_aot_en_ru_sw | FTS hunspell AOT configuration for russian language based on shared_ispell with stopwords |
fts_hunspell_en_ru | FTS hunspell Lebedev configuration for russian language based on shared_ispell without stopwords |
fts_hunspell_en_ru_sw | FTS hunspell Lebedev configuration for russian language based on shared_ispell with stopwords |
fts_snowball_en_ru_sw | FTS snowball configuration for russian language based on tsparser with stopwords |
Особенность:
- использование парсера
tsparser
и загрузки используемых словарей в общую память однократно при старте сервера. Используется расширениеshared_ispell
. Русские и английские словари взяты из расширенияhunspell_dicts
- 3 конфигурации с использованием стоп-слов (постфикс "_sw") и 2 конфигурации без использования стоп-слов
Контейнер рассчитан на 2 режима начального старта:
- Старт с пустым каталогом данных
При запуске контейнера с пустым каталогом данных выполняется его инициализация через вызов initdb
и созданием шаблонной БД template_extension
. Из-за особенностей старта официального образа при такой инициализации не выполняется создание расширений pg_cron
и ispell_shared
, а также не выполняется настройка конфигураций полнотекстового поиска.
Поэтому после такого первого старта очень желательно выполнить запуск скрипта обновления БД кластера через команду:
$ docker exec temp_postgres_1 update-extension.sh <доп.БД>
где имя temp_postgres_1
- имя запущенного postgres-контейнера. В выводе команды docker ps это колонка NAMES
.
<доп.БД> - можно передать имя пользовательской БД которую необходимо "дотянуть" до стандарта по расширениям и настройкам текущего контейнера. БД должна быть уже создана.
Если же в настройках docker-compose файла указать:
command: |
-c shared_preload_libraries='plugin_debugger,plpgsql_check,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm'
-c shared_ispell.max_size=70MB
то проблему 1-го старта с последующей донастройкой можно избежать. Однако надо помнить, что указание такой строки в качестве параметра старта службы не позволит изменить эти значение через файл настроек.
- Старт с уже инициализированным каталогом
Когда контейнер запускается с уже присоединённым каталогом кластера БД, то никаких внутренних скриптов инициализации не применяется. Однако, если есть желание "дотянуть" до стандарта по расширениям и настройкам текущего контейнера, то необходимо иметь ввиду, что для полноценной работы внутренних скриптов необходимо в настройках кластера загружать следующие shared библиотеки:
shared_preload_libraries='plugin_debugger,plpgsql_check,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm'
а также в файле настроек указать параметр:
shared_ispell.max_size=70MB
Чтобы "дотянуть" БД до стандарта по расширениям и настройкам текущего контейнера выполните вызов скрипта: update-extension.sh
как описано чуть выше.
В кластере БД, созданном с нуля, pg_hba.conf
и pg_ident.conf
имеют значения, рассчитанные на вход по паролю (на это оказывает влияние параметр POSTGRES_HOST_AUTH_METHOD), а postgresql.conf
оптимизирован под 512 MБ ОЗУ и SSD диски. При необходимости, после первичной инициализации уточните параметры конфигурации.
Чтобы создать свою БД, рекомендуется использовать шаблон template_extension
:
CREATE DATABASE my_db WITH TEMPLATE template_extension;
В созданной таким образом БД настроены все необходимые расширения и создана схема с именем dbo
как схема для пользовательских таблиц.
Однако права и пути поиска нельзя перенести таким образом, поэтому для дотягивания БД до стандартов контейнера нужно выполнить скрипт: update-extension.sh
как описано чуть выше и передать как параметр этому скрипту имя созданной БД.
$ docker exec temp_postgres_1 update-extension.sh my_db
Путь поиска после выполнения скрипта в указанной БД выглядит так: search_path = dbo, public, tiger;
Пример:
смотрим какие сейчас контейнеры работают:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
04c3a3a2f43b 15_postgres "docker-entrypoint.s…" 11 minutes ago Up 11 minutes 0.0.0.0:5433->5432/tcp, :::5433->5432/tcp 15_postgres_1
создадим БД с именем MyDbNew и отдельного пользователя по имени БД MyDbNew (будет владельцем новой БД)
$ docker exec 15_postgres_1 /bin/bash -c "su - postgres -c 'psql -f /usr/local/bin/pre.sql -v APP_DB=\"MyDbNew\" -v APP_DB_PASSWORD=\"MyDbNew_PASSWORD\"'"
выполним обновление БД до настроек контейнера:
$ docker exec 15_postgres_1 update-extension.sh "MyDbNew"
Меняем владельца БД на вновь созданного пользователя (по умолчанию там deploy)
$ docker exec 15_postgres_1 /bin/bash -c 'su - postgres -c "echo ALTER DATABASE \\\"MyDbNew\\\" OWNER TO \\\"MyDbNew\\\" | psql"'
Контейнер рассчитан на работу с утилитой бэкапирования pg_probackup
от компании Postgres Professional. В настройках archive_command
и restore_command
написана bash команда для вызова архивации/восстановления WAL файлов:
archive_command:
if [ -f archive_pause.trigger ]; then exit 1; else if [ -f archive_active.trigger ]; then pg_probackup-15 archive-push -B /mnt/pgbak --instance 15 --wal-file-path %p --wal-file-name %f -j 4 --batch-size=10; else exit 0; fi; fi
restore_command:
if [ -f archive_active.trigger ]; then pg_probackup-15 archive-get -B /mnt/pgbak --instance 15 --wal-file-path %p --wal-file-name %f; else exit 0; fi
Чтобы WAL файлы начали сохраняться, нужно в каталоге данных создать файл с именем: archive_active.trigger
(автоматически создаётся при первом вызове backup.sh
)
При его наличии каждый WAL файл сохраняется в бэкап-каталог.
При его отсутствии WAL файлы не сохраняются!
Чтобы временно приостановить выгрузку WAL файлов в бэкап-каталог нужно создать файл: archive_pause.trigger
(это может понадобиться для временных работ с бэкапным каталогом).
В контейнере есть 2 дополнительных скрипта:
backup.sh
- создаёт новый бэкап
show.sh
- показывает какие бэкапы есть
Для запуска можно использовать команды:
$ docker exec temp_postgres_1 backup.sh
$ docker exec temp_postgres_1 show.sh
Скрипт backup.sh
может принимать до 3-х параметров:
$1 - указывает режим создания инкрементального бэкапа: delta (по умолчанию) или page или full
$2 - признак создания автономного бэкапа типа stream: yes или stream (по умолчанию) или любой другой текст для варианта "archive"
$3 - количество потоков для выполнения бэкапа: 4 (по умолчанию) или указанное число
Скрипт show.sh
может принимать до 2-х параметров:
$1 - yes/no (по умолчанию yes) нужно ли отсылать письмо с отчетом по текущим бэкапам
$2 - список email получателей письма (через пробел и обрамить двойными кавычками)
Часть переменных имеет значения по умолчанию, это значит, что если их не указывать при старте контейнера, то они имеют указанные значения.
Переменные использующиеся только при первичной инициализации:
Name | Default value | Description |
---|---|---|
POSTGRES_INITDB_ARGS | --locale=ru_RU.UTF8 --data-checksums | Эту необязательную переменную среды можно использовать для отправки аргументов в postgres initdb. Значение представляет собой строку аргументов, разделенных пробелами, как того и ожидает postgres initdb. |
POSTGRES_HOST_AUTH_METHOD | md5 | Эту необязательную переменную можно использовать для управления методом аутентификации для соединений с хостом для всех баз данных, всех пользователей и всех адресов. Это значение используется только на этапе первичной инициализации. |
PGDATA | /var/lib/postgresql/data | Эту необязательную переменную можно использовать для определения другого местоположения - например, подкаталога - для файлов базы данных. По умолчанию это /var/lib/postgresql/data. Если используемый вами том данных является точкой монтирования файловой системы (например, с постоянными дисками GCE) или удаленной папкой, которая не может быть подключена для пользователя postgres (например, некоторые точки монтирования в NFS), Postgres initdb рекомендует создать подкаталог для хранения данных |
POSTGRES_INITDB_WALDIR | PGDATA/pg_wal | Эту необязательную переменную среды можно использовать для определения другого места для журнала транзакций Postgres. Иногда может быть желательно хранить журнал транзакций в другом каталоге, который может поддерживаться хранилищем с другими характеристиками производительности или надежности. |
APP_DB | Эту необязательную переменную среды можно использовать для определения имени БД которую нужно создать сразу при старте контейнера. БД будет создана только если кластер БД не существует. БД создается также как если вручную создать БД на основе шаблонной БД template_extension и по ней пргонать скрипт update-extension.sh | |
APP_DB_PASSWORD | Эту необязательную переменную среды можно использовать для определения пароля учетной записи по имени создаваемой БД. Учетная запись будет создана только если кластер БД не существует. БД создается также как если вручную создать БД на основе шаблонной БД template_extension и по ней пргонать скрипт update-extension.sh | |
ENV_DB_VALUE | DEV | Эту необязательную переменную среды можно использовать для установки нужного значения на БД пользовательского параметра "adm.environment" |
Значение ENV_DB_VALUE устанавливается для параметра "adm.environment" во время первичной иннициализации кластера или же при вызове скрипта обновления update-extension.sh Значение присваивается, только если в этой БД ещё нет такого параметра.
При указании имени в переменной APP_DB и пустом каталоге данных (PGDATA) будет создана новая БД с указанным именем.
Для доступа к эту БД будет создан логин с таким же именем как и БД. Этот логин будет включен в следующие группы:
write_group
и execution_group
Также этот пользователь является владельцем вновь созданной БД.
Для того, чтобы создаваемая БД могла быть иннициализирована в нужное состояние есть возможность задать набор скриптов sql в каталоге: /app_db_init_sql
Если в этот каталог положить необходимые файлы, то они будут выполнены сразу после создания БД.
Пример показывающий использование подкаталога для каталога данных:
$ docker run -d \
--name some-postgres \
-e POSTGRES_PASSWORD=qweasdzxc \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v /custom/mount:/var/lib/postgresql/data \
postgres
Обратите внимание, что мы подключаемый каталог монтируем на 1 уровень выше, чем указали в переменной PGDATA. В этом и есть смысл использования переменной PGDATA
Переменные с данными по подключению к БД:
Name | Default value | Description |
---|---|---|
POSTGRES_USER | postgres | Эта переменная создаст указанного пользователя с полномочиями суперпользователя и базу данных с тем же именем. Не рекомендуется менять значение этой переменной. |
POSTGRES_DB | postgres | Эту необязательную переменную среды можно использовать для определения другого имени для базы данных по умолчанию, которая создается при первом запуске образа. Если он не указан, будет использоваться значение POSTGRES_USER. Не рекомендуется менять значение этой переменной. |
POSTGRES_PASSWORD | Определяет пароль пользователя POSTGRES_USER. Это значение указывается в настройках мапинга пользователя для FDW серверов. | |
DEV_SCHEMA | dbo | Имя схемы, выбираемая как схема по умолчанию для пользовательских объектов. Это имя включается в параметр search_path и эта схема создается если её нет. |
DEPLOY_PASSWORD | Пароль для создаваемого пользователя с именем deploy. Это пользователь с повышенными правами, но не superuser. Предполагается, что он будет владельцем всех создаваемх БД и объектов в них |
Переменная указывающая на временную зону в которой работает контейнер:
Name | Default value | Description |
---|---|---|
TZ | Указывает на временную зону в которой работает контейнер. Например: "Europe/Moscow" или "Etc/UTC" |
Переменные для отправки писем:
Name | Default value | Description |
---|---|---|
EMAILTO | На какой адрес отправлять почтовые сообщения | |
EMAIL_SERVER | Имя почтового сервера для отправки писем | |
EMAIL_HOSTNAME | noreply@my_host.ru | имя отправителя писем |
EMAIL_SEND | yes | Отправку писем можно отменить указав no |
В конфигурационном файле postgresql.conf есть параметр, в котором указывается значение указанное из переменной окружения EMAIL_SERVER. Значение переносится в файл во время первичной иннициализации кластера или же при вызове скрипта обновления update-extension.sh Например: adm.email_smtp_server = 'mail.company.ru'
Это значение используется функцией отправки почты: util.send_email()
Переменные влияющие на работу скриптов по бэкапам:
Name | Default value | Description |
---|---|---|
BACKUP_MODE | delta | Режим инкрементального бэкапа. Альтернативное значение page |
BACKUP_PATH | /mnt/pgbak | Каталог используемый утилитой pg_probackup для хранения всех бэкапов |
BACKUP_THREADS | 4 | На сколько потоков можно параллелить бэкап/рестор процесс |
BACKUP_STREAM | yes | yes - создавать автономные резервные копии. no - создавать резервные копии для которых обязательно нужны WAL файлы. |
Контейнер поддерживает следующие предустановленные роли (используйте скрипт update-extension.sh)
роль | описание | параметры |
---|---|---|
mamonsu | специализированная роль для активного агента mamonsu | LOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION |
deploy | роль владелец для всех новых БД и их объектов | LOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION PASSWORD |
replicator | роль для использования с логической и потоковой репликацией | LOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION |
readonly_group | роль-группа выдающая права на чтение таблиц, использование последовательностей и типов | NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION |
write_group | роль-группа выдающая права на чтение/запись таблиц, последовательностей и использование типов | NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION |
execution_group | роль-группа выдающая права на запуск всех функций и процедур | NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION |
read_procedure_group | роль-группа выдающая права на чтение текста процедур/функций | NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION |
monitoring_group | роль-группа выдающая права на обращение к статистическим функциям, таблицам, представлениям | NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION |
Контейнер ожидает следующие примапленные каталоги
Name | Description |
---|---|
/var/lib/postgresql/data | каталог с данными кластера |
/var/log/postgresql | каталог с файлами логов |
/mnt/pgbak | каталог для бэкапов кластера |
/usr/share/postgresql/tsearch_data | каталог хранения словарей для FTS |
Обратите внимание, что на подключаемые каталоги нужно заранее выдать права на запись пользователю с uid=999 (код пользователя postgres внутри контейнера)
Докер-контейнерам по умолчанию выделяется 64 МБ общей памяти. Опция --shm-size используется для установки требуемого размера /dev/shm внутри контейнера. Вот информация из документации
--shm-size=""
Size of /dev/shm. The format is . number must be greater than 0. Unit is optional and can be b (bytes), k (kilobytes), m (megabytes), or g (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses 64m.
Эта память используется при работе параллельных процессов для передачи через неё всех необходимых данных. Их размер зависит от передаваемых данных, и их может быть выделено несколько, поэтому этот ресурс сложнее контролировать.
В системе с ограниченной памятью можно отключить параллельные запросы (тогда и размер памяти под shm-size можно оставить по умолчанию). Это ускоряет запросы, но использует больше ресурсов для каждого запроса, поэтому общая пропускная способность не улучшается. Чтобы отключить параллельные запросы, установите для параметра max_parallel_workers значение 0.
В нашем контейнере, распараллеливание используется. Контейнер рассчитан на производственную среду с большими данными. Поэтому этот параметр нужно задавать и рекомендуется его устанавливать в 2 ГБ.
запуск без примапленных каталогов. Всё данные кластера будут храниться внутри докер контейнера. В данном примере postgres мапится на порт 5433.
docker run -d --name dev-db -p 5433:5432/tcp --shm-size 2147483648 \
-e POSTGRES_PASSWORD=qweasdzxc \
-e POSTGRES_HOST_AUTH_METHOD=trust \
-e DEPLOY_PASSWORD=cxzdsaewq \
-e TZ="Etc/UTC" \
grufos/postgres:15.4 \
-c shared_preload_libraries="plugin_debugger,plpgsql_check,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm" \
-c shared_ispell.max_size=70MB
запуск с указанием примапленных каталогов. Все данные кластера будут храниться вне контейнера в каталоге /var/lib/pgsql/15/data
, а логи в каталоге /var/log/postgresql
docker run -d --name dev-db -p 5433:5432/tcp --shm-size 2147483648 \
-e POSTGRES_PASSWORD=qweasdzxc \
-e POSTGRES_HOST_AUTH_METHOD=trust \
-e DEPLOY_PASSWORD=cxzdsaewq \
-e TZ="Etc/UTC" \
-v "/var/lib/pgsql/15/data:/var/lib/postgresql/data" \
-v "/var/log/postgresql:/var/log/postgresql" \
-v "/mnt/pgbak2:/mnt/pgbak" \
-v "/usr/share/postgres/tsearch_data:/usr/share/postgresql/tsearch_data" \
-v "/var/lib/pgsql/app_db_init_sql:/app_db_init_sql" \
grufos/postgres:15.4 \
-c shared_preload_libraries="plugin_debugger,plpgsql_check,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm" \
-c shared_ispell.max_size=70MB
остановка контейнера
docker stop dev-db
запуск ранее остановленного контейнера
docker start dev-db
Создаём файл postgres-service.yml
version: '3.5'
services:
postgres:
# image: grufos/postgres:15.4
build:
context: ./docker-postgres
dockerfile: Dockerfile
shm_size: '2gb'
command: |
-c shared_preload_libraries='plugin_debugger,plpgsql_check,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm'
-c shared_ispell.max_size=70MB
volumes:
- "/var/lib/pgsql/15_1/data:/var/lib/postgresql/data"
- "/var/log/postgresql1:/var/log/postgresql"
- "/mnt/pgbak2/:/mnt/pgbak/"
- "/usr/share/postgres/tsearch_data:/usr/share/postgresql/tsearch_data"
- "/var/lib/pgsql/15_1/app_db_init_sql:/app_db_init_sql"
ports:
- "5433:5432"
environment:
APP_DB: "My_db"
APP_DB_PASSWORD: qweasdzxc
# POSTGRES_INITDB_ARGS: "--locale=ru_RU.UTF8 --data-checksums"
POSTGRES_PASSWORD: qweasdzxc
POSTGRES_HOST_AUTH_METHOD: trust
DEPLOY_PASSWORD: qweasdzxc
# TZ: "Etc/UTC"
TZ: "Europe/Moscow"
EMAILTO: "DBA-PostgreSQL@my_name.ru"
EMAIL_SERVER: "mail.name.ru"
EMAIL_HOSTNAME: "noreplay@my_host.ru"
BACKUP_THREADS: "4"
BACKUP_MODE: "page"
Этот управляющий файл рекомендуется запускать командами:
#!/bin/bash
clear
rm -rf /var/log/postgresql/*
docker-compose -f "postgres-service.yml" up --build "$@"
Пример файл для запуска нескольких сервисов сразу postgres-service-all.yml
version: '3.5'
services:
postgres:
# image: grufos/postgres:15.4
build:
context: ./docker-postgres
dockerfile: Dockerfile
shm_size: '2gb'
command: |
-c shared_preload_libraries='plugin_debugger,plpgsql_check,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm'
-c shared_ispell.max_size=70MB
volumes:
- "/var/lib/pgsql/15_1/data:/var/lib/postgresql/data"
- "/var/log/postgresql1:/var/log/postgresql"
- "/mnt/pgbak2/:/mnt/pgbak/"
- "/usr/share/postgres/tsearch_data:/usr/share/postgresql/tsearch_data"
- "/var/lib/pgsql/15_1/app_db_init_sql:/app_db_init_sql"
ports:
- "5433:5432"
environment:
APP_DB: "My_db"
APP_DB_PASSWORD: qweasdzxc
# POSTGRES_INITDB_ARGS: "--locale=ru_RU.UTF8 --data-checksums"
POSTGRES_PASSWORD: qweasdzxc
POSTGRES_HOST_AUTH_METHOD: trust
DEPLOY_PASSWORD: qweasdzxc
# TZ: "Etc/UTC"
TZ: "Europe/Moscow"
EMAILTO: "DBA-PostgreSQL@my_name.ru"
EMAIL_SERVER: "mail.name.ru"
EMAIL_HOSTNAME: "noreplay@my_host.ru"
BACKUP_THREADS: "4"
BACKUP_MODE: "page"
pgbouncer:
# image: grufos/pgbouncer:1.17.0
build:
context: ./docker-pgbouncer
dockerfile: Dockerfile
volumes:
- "/etc/pgbouncer1/:/etc/pgbouncer/"
- "/var/log/pgbouncer1:/var/log/pgbouncer"
- "/etc/localtime:/etc/localtime"
ports:
- "6433:6432"
restart: always
depends_on:
- postgres
environment:
# если в каталоге файлов есть файлы настройки то указанные ниже переменные не обрабатываются
# если файлы настройки не указываются, то нужно передать в переменных параметры подключения.
# 1-й вариант - использование передачи через URI подключения к серверу
# - DATABASE_URL=postgresql://postgres:[email protected]:5432
# 2-й вариант - отдельные переменные
# Обязательно нужно указывать DB_PASSWORD
- DB_PASSWORD=qweasdzxc
# - DB_HOST=127.0.0.1
- DB_HOST=postgres
- DB_PORT=5432
- DB_USER=postgres
mamonsu:
# image: grufos/mamonsu:15_3.5.2
build:
context: ./docker-mamonsu
dockerfile: Dockerfile
volumes:
- "/mnt/pgbak2/:/mnt/pgbak/"
- "/var/log/mamonsu1:/var/log/mamonsu"
- "/etc/mamonsu1/:/etc/mamonsu/"
environment:
# TZ: "Etc/UTC"
TZ: "Europe/Moscow"
PGPASSWORD: qweasdzxc
# PGHOST: 127.0.0.1
PGHOST: postgres
PGPORT: 5432
MAMONSU_PASSWORD: 1234512345
ZABBIX_SERVER_IP: name.server.ru
ZABBIX_SERVER_PORT: 10051
CLIENT_HOSTNAME: my_host.server.ru
MAMONSU_AGENTHOST: 127.0.0.1
INTERVAL_PGBUFFERCACHE: 1200
PGPROBACKUP_ENABLED: "False"
restart: always
ports:
- "10051:10051"
- "10052:10052"
depends_on:
- postgres
Как запустить контейнер в tmpfs - https://stackoverflow.com/questions/42226418/how-to-move-postresql-to-ram-disk-in-docker
Контейнер предназначен для выполнения мажорного обновления Postgres. Для каждой версии существует своя редакция такого контейнера. Контейнер в каталоге 15-й версии выполняет обновление с 14-й версии на 15-ю версию. Необходимость разработки такого контейнера обусловлена тем, что в моих контейнерах используется много разных расширений и многие из них должны быть предварительно загружены в виде библиотек. В противном случае утилита pg_upgrade выдаст сообщение о несовместимости кластеров.
Внимание:
- для корректной работы рекомендуется все же небольшое количество HugePages иметь доступными. Рекомендуется 150 страниц иметь свободными в запасе.
Файлы контейнера:
Dockerfile - скрипт создания контейнера
upgrade.sh - основной скрипт выполняющий всю процедуру мажорного обновления
pg_hba.conf - файл доступов к серверу
pg_ident.conf - файл маппинга пользователей
postgresql.conf - настройки postgres текущей версии
Файлы конфигураций используются те же, что и в контейнере Postgres текущей версии. Дополнительно в процессе обновления часть настроек берётся из предыдущей обновляемой версии. Это необходимо делать, так как некоторые настройки могут быть критичными для работы контура и зависящие от параметров железа на котором мы работаем. На сейчас выполняется перенос следующих параметров:
- max_connections
- shared_buffers
- huge_pages
- work_mem
- timezone
- wal_level
- effective_cache_size
- maintenance_work_mem
- autovacuum_work_mem
- max_prepared_transactions
- logical_decoding_work_mem
- max_worker_processes
- max_parallel_maintenance_workers
- max_parallel_workers_per_gather
- max_parallel_workers
- cron.timezone
далее по тексту будет использование указание в виде:
PREV
- номер версии текущей обновляемой версии Postgres, к примеру 14
NEW
- номер версии новой версии Postgres, к примеру 15
Контейнер ожидает следующие примапленные каталоги
Name | Description |
---|---|
/var/lib/postgresql/ | каталог с данными кластеров. |
/var/log/postgresql | каталог с файлами логов |
/usr/share/postgresql/PREV/tsearch_data | каталог хранения словарей для FTS обновляемой версии |
/usr/share/postgresql/NEW/tsearch_data | каталог хранения словарей для FTS новой версии (должен быть пуст) |
Подробности по каталогу данных контейнера /var/lib/postgresql/
:
Внутри ожидается следующая структура каталогов:
PREV/data - каталог с данными для обновляемой версии
NEW/data - каталог с данными для новой версии. Важно, этот каталог должен быть пуст на момент старта контейнера
Итак, получается, что когда мы мапим каталог верхнего уровня в контейнер:
-v /mnt/bigdrive/postgresql:/var/lib/postgresql/
То, контейнер ожидает, что данные обновляемого кластера находятся по пути: /mnt/bigdrive/postgresql/PREV/data
.
Данные нового кластера будут созданы по пути: /mnt/bigdrive/postgresql/NEW/data
.
При таком варианте маппинга контейнер может реализовать поддержку опции --link
Если по каким-то причинам нет возможности в таком маппинге каталогов, то можно использовать и вот такой подход:
Name | Description |
---|---|
/var/lib/postgresql/PREV/data | каталог с данными обновляемого кластера |
/var/lib/postgresql/NEW/data | каталог с данными нового кластера |
как пример:
-v /mnt/bigdrive/postgresql-14/data:/var/lib/postgresql/14/data\
-v /mnt/bigdrive/postgresql-15/data:/var/lib/postgresql/15/data\
Внимание: каталог для новой версии кластера (/mnt/bigdrive/postgresql-15
) должен быть пустым!
В этом случае предполагается, что данные нового кластера находятся на другом физическом устройстве, поэтому возможности использовать опцию --link
не будет.
Опция --link
позволяет создать физические ссылки на файлы и таким образом избежать их копирования. Это позволяет очень сильно сократить время выполнения обновления.
Контейнер выполняет простейшие проверки входных каталогов на предмет их ожидаемого содержимого.
В каталогах полнотекстового поиска не содержится никаких очень объемных данных, поэтому для них всегда используется обычное копирование файлов.
При старте контейнера в указанном каталоге полнотекстового поиска новой версии (должен быть пуст изначально) создаются все необходимые файлы новой версии и потом туда копируются только лишь пользовательские файлы синонимов (*.syn
) и тезаурусов (*.ths
)
Переменные контейнера:
Name | Description |
---|---|
PGDATACOPY_MODE | режим копирования каталога PGDATA: HARDLINK (по умолчанию), AUTO, COPY |
- HARDLINK жесткие ссылки обязательны! Если нет возможности выполнять жесткие ссылки между файлами обновление будет прервано
- COPY при обновление нужно выполнять простое копирование файлов
- AUTO протестировать возможность делать жесткие ссылки и если они доступны, то использовать их. В проотивном случае применить обычное копирование файлов.
Контейнер выполняет сначала проверку совместимости каталогов данных с новой версией и если всё в порядке выполняет обновление.
После выполнения обновления и старта нового контейнера postgres, необходимо выполнить команды:
vacuumdb --all --analyze-in-stages
Также рекомендуется сразу сделать полный бэкап кластера.
В зависимости от Release Notes могут потребоваться некие дополнительные работы над кластером.
Каталог данных старого кластера можно теперь удалить.
version: '3.5'
services:
pgupgrade:
# image: grufos/pgupgrade:15.4
build:
context: ./docker-pgupgrade
dockerfile: Dockerfile
stop_grace_period: 60s
shm_size: '2gb'
volumes:
- "/var/lib/pgsql/15_1:/var/lib/postgresql"
- "/var/log/postgresql1:/var/log/postgresql"
- "/usr/share/postgres/14_1/tsearch_data:/usr/share/postgresql/14/tsearch_data"
- "/usr/share/postgres/15_1/tsearch_data:/usr/share/postgresql/15/tsearch_data"
docker run --rm --name upgrade-db --shm-size 2147483648 \
-v "/var/lib/pgsql/15_1:/var/lib/postgresql" \
-v "/var/log/postgresql1:/var/log/postgresql" \
-v "/usr/share/postgres/14/tsearch_data:/usr/share/postgresql/14/tsearch_data" \
-v "/usr/share/postgres/15/tsearch_data:/usr/share/postgresql/15/tsearch_data" \
grufos/pgpostgres:15.4
# 15_pgupgrade