Sign inSign up

grufos/postgres

By grufos

•Updated over 2 years ago

Image
0

2.7K

grufos/postgres repository overview

⁠docker-postgres

Оригинальный код: 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

Контейнер ориентирован на работу с русской локалью. Внутри выполняются следующие команды для локализации:

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 Professional
  • sendemail - используется для отправки почты
  • установлен пакет для коннекта к 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

В шаблонную БД установлены расширения:

ExtensionDescription
adminpackadministrative functions for PostgreSQL
amcheckfunctions for verifying relation integrity
btree_ginsupport for indexing common datatypes in GIN
citextdata type for case-insensitive character strings
dblinkconnect to other PostgreSQL databases from within a database
file_fdwforeign-data wrapper for flat file access
fuzzystrmatchdetermine similarities and distance between strings
hunspell_en_usen_US Hunspell Dictionary
hunspell_ru_ruRussian Hunspell Dictionary
hunspell_ru_ru_aotRussian Hunspell Dictionary (from AOT.ru group)
pageinspectinspect the contents of database pages at a low level
pg_buffercacheexamine the shared buffer cache
pg_dbo_timestampPostgreSQL extension for storing time and author of database structure modification
pg_prewarmprewarm relation data
pg_repackReorganize tables in PostgreSQL databases with minimal locks
pg_stat_statementstrack execution statistics of all SQL statements executed
pg_trgmtext similarity measurement and index searching based on trigrams
pg_tsparserparser for text search
pg_variablessession variables with various types
pgstattupleshow tuple-level statistics
pldbgapiserver-side support for debugging PL/pgSQL functions
plpgsqlPL/pgSQL procedural language
plpgsql_checkextended check for plpgsql functions
plpython3uPL/Python3U untrusted procedural language
postgisPostGIS geometry, geography, and raster spatial types and functions
postgis_tiger_geocoderPostGIS tiger geocoder and reverse geocoder
postgis_topologyPostGIS topology spatial types and functions
postgres_fdwforeign-data wrapper for remote PostgreSQL servers
rumRUM index access method
shared_ispellProvides shared ispell dictionaries.
uuid-osspgenerate universally unique identifiers (UUIDs)

Настроены 5 конфигураций полнотекстового поиска для русского и английского языка:

NameDescription
fts_aot_en_ruFTS hunspell AOT configuration for russian language based on shared_ispell without stopwords
fts_aot_en_ru_swFTS hunspell AOT configuration for russian language based on shared_ispell with stopwords
fts_hunspell_en_ruFTS hunspell Lebedev configuration for russian language based on shared_ispell without stopwords
fts_hunspell_en_ru_swFTS hunspell Lebedev configuration for russian language based on shared_ispell with stopwords
fts_snowball_en_ru_swFTS 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 -it temp_postgres_1 update-extension.sh <доп.БД>

где имя temp_postgres_1 - имя запущенного postgres-контейнера. В выводе команды docker ps это колонка NAMES.

<доп.БД> - можно передать имя пользовательской БД которую необходимо "дотянуть" до стандарта по расширениям и настройкам текущего контейнера. БД должна быть уже создана.

Если же в настройках docker-compose файла указать:

command: |
      -c shared_preload_libraries='plugin_debugger,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,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 оптимизирован под 2 ГБ ОЗУ и SSD диски. При необходимости, после первичной инициализации уточните параметры конфигурации.

⁠Пользовательская БД

Чтобы создать свою БД, рекомендуется использовать шаблон template_extension:

CREATE DATABASE my_db WITH TEMPLATE template_extension;

В созданной таким образом БД настроены все необходимые расширения и создана схема с именем dbo как схема для пользовательских таблиц. Однако права и пути поиска нельзя перенести таким образом, поэтому для дотягивания БД до стандартов контейнера нужно выполнить скрипт: update-extension.sh как описано чуть выше и передать как параметр этому скрипту имя созданной БД.

$ docker exec -it temp_postgres_1 update-extension.sh my_db

Путь поиска после выполнения скрипта в указанной БД выглядит так: search_path = dbo, public, tiger;

⁠Работа с бэкапами

Контейнер рассчитан на работу с утилитой бэкапирования 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-13 archive-push -B /mnt/pgbak --instance 13 --wal-file-path %p --wal-file-name %f -j 4 --batch-size=50; else exit 0; fi; fi

restore_command:
if [ -f archive_active.trigger ]; then pg_probackup-13 archive-get -B /mnt/pgbak --instance 13 --wal-file-path %p --wal-file-name %f; else exit 0; fi

Чтобы WAL файлы начали сохраняться, нужно в каталоге данных создать файл с именем: archive_active.trigger (автоматически создаётся при первом вызове backup.sh) При его наличии каждый WAL файл сохраняется в бэкап-каталог.

При его отсутствии WAL файлы не сохраняются!

Чтобы временно приостановить выгрузку WAL файлов в бэкап-каталог нужно создать файл: archive_pause.trigger (это может понадобиться для временных работ с бэкапным каталогом).

В контейнере есть 3 дополнительных скрипта:

backup.sh - создаёт новый бэкап

show.sh - показывает какие бэкапы есть

check_cluster.sh - выполняет проверку кластера на возможные ошибки в структуре БД

Для запуска можно использовать команды:

$ docker exec -it temp_postgres_1 backup.sh
$ docker exec -it temp_postgres_1 show.sh
$ docker exec -it temp_postgres_1 check_cluster.sh

Скрипт backup.sh может принимать до 3-х параметров:

$1 - количество потоков для выполнения бэкапа: 4 (по умолчанию) или указанное число
$2 - указывает режим создания инкрементального бэкапа: delta (по умолчанию) или page
$3 - признак создания автономного бэкапа типа stream: yes (по умолчанию) или любой другой текст для варианта "archive"

Скрипт show.sh может принимать до 2-х параметров:

$1 - yes/no (нужно ли отсылать письмо с отчетом по текущим бэкапам)
$2 - список email получателей письма (через пробел и обрамить двойными кавычками)

Скрипт check_cluster.sh может принимать до 2 -х параметров:

$1 - 'amcheck' включить доп.проверку кластера при помощи расширения amcheck
$2 - 'heapallindexed' будет дополнительно проверено, что в индексе действительно представлены все кортежи кучи, которые должны в него попасть

⁠Переменные окружения контейнера

Часть переменных имеет значения по умолчанию, это значит, что если их не указывать при старте контейнера, то они имеют указанные значения.

Переменные использующиеся только при первичной инициализации:

NameDefault valueDescription
POSTGRES_INITDB_ARGS--locale=ru_RU.UTF8 --data-checksumsЭту необязательную переменную среды можно использовать для отправки аргументов в postgres initdb. Значение представляет собой строку аргументов, разделенных пробелами, как того и ожидает postgres initdb.
POSTGRES_HOST_AUTH_METHODmd5Эту необязательную переменную можно использовать для управления методом аутентификации для соединений с хостом для всех баз данных, всех пользователей и всех адресов. Это значение используется только на этапе первичной инициализации.
PGDATA/var/lib/postgresql/dataЭту необязательную переменную можно использовать для определения другого местоположения - например, подкаталога - для файлов базы данных. По умолчанию это /var/lib/postgresql/data. Если используемый вами том данных является точкой монтирования файловой системы (например, с постоянными дисками GCE) или удаленной папкой, которая не может быть подключена для пользователя postgres (например, некоторые точки монтирования в NFS), Postgres initdb рекомендует создать подкаталог для хранения данных
POSTGRES_INITDB_WALDIRPGDATA/pg_walЭту необязательную переменную среды можно использовать для определения другого места для журнала транзакций Postgres. Иногда может быть желательно хранить журнал транзакций в другом каталоге, который может поддерживаться хранилищем с другими характеристиками производительности или надежности.

Пример показывающий использование подкаталога для каталога данных:

$ 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

Переменные с данными по подключению к БД:

NameDefault valueDescription
POSTGRES_USERpostgresЭта переменная создаст указанного пользователя с полномочиями суперпользователя и базу данных с тем же именем. Не рекомендуется менять значение этой переменной.
POSTGRES_DBpostgresЭту необязательную переменную среды можно использовать для определения другого имени для базы данных по умолчанию, которая создается при первом запуске образа. Если он не указан, будет использоваться значение POSTGRES_USER. Не рекомендуется менять значение этой переменной.
POSTGRES_PASSWORDОпределяет пароль пользователя POSTGRES_USER. Это значение указывается в настройках мапинга пользователя для FDW серверов.
DEV_SCHEMAdboИмя схемы, выбираемая как схема по умолчанию для пользовательских объектов. Это имя включается в параметр search_path и эта схема создается если её нет.
DEPLOY_PASSWORDПароль для создаваемого пользователя с именем deploy. Это пользователь с повышенными правами, но не superuser. Предполагается, что он будет владельцем всех создаваемх БД и объектов в них

Переменная указывающая на временную зону в которой работает контейнер:

NameDefault valueDescription
TZУказывает на временную зону в которой работает контейнер. Например: "Europe/Moscow" или "Etc/UTC"

Переменные для отправки писем:

NameDefault valueDescription
EMAILTOНа какой адрес отправлять почтовые сообщения
EMAIL_SERVERИмя почтового сервера для отправки писем
EMAIL_HOSTNAMEnoreply@my_host.ru⁠имя отправителя писем
EMAIL_SENDyesОтправку писем можно отменить указав no

Переменные влияющие на работу скриптов по бэкапам:

NameDefault valueDescription
BACKUP_MODEdeltaРежим инкрементального бэкапа. Альтернативное значение page
BACKUP_PATH/mnt/pgbakКаталог используемый утилитой pg_probackup для хранения всех бэкапов
BACKUP_THREADS4На сколько потоков можно параллелить бэкап/рестор процесс
BACKUP_STREAMyesyes - создавать автономные резервные копии. no - создавать резервные копии для которых обязательно нужны WAL файлы.

⁠Предустановленные роли

Контейнер поддерживает следующие предустановленные роли (используйте скрипт update-extension.sh)

рольописаниепараметры
mamonsuспециализированная роль для активного агента mamonsuLOGIN 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

⁠Каталоги для маппинга

Контейнер ожидает следующие примапленные каталоги

NameDescription
/var/lib/postgresql/dataкаталог с данными кластера
/var/log/postgresqlкаталог с файлами логов
/mnt/pgbakкаталог для бэкапов кластера
/usr/share/postgresql/tsearch_dataкаталог хранения словарей для FTS

Обратите внимание, что на подключаемые каталоги нужно заранее выдать права на запись пользователю с uid=999 (код пользователя postgres внутри контейнера)

⁠Пример старта контейнера через docker run

запуск без примапленных каталогов. Всё данные кластера будут храниться внутри докер контейнера. В данном примере 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:13.3 \
           -c shared_preload_libraries="plugin_debugger,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm" \
           -c shared_ispell.max_size=70MB

запуск с указанием примапленных каталогов. Все данные кластера будут храниться вне контейнера в каталоге /var/lib/pgsql/13/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/13/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" \
       grufos/postgres:13.3 \
       -c shared_preload_libraries="plugin_debugger,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

⁠Пример docker-compose файла

Создаём файл postgres-service.yml

version: '3.5'
services:
 
  postgres:

#    image: grufos/postgres:13.3
    build:
      context: ./docker-postgres
      dockerfile: Dockerfile
    shm_size: '2gb'
    command: |
      -c shared_preload_libraries='plugin_debugger,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm'
      -c shared_ispell.max_size=70MB
    volumes:
      - "/var/lib/pgsql/13_1/data:/var/lib/postgresql/data"
      - "/var/log/postgresql1:/var/log/postgresql"
      - "/mnt/pgbak2/:/mnt/pgba

Tag summary

Content type

Image

Digest

sha256:cf26a463c…

Size

244.5 MB

Last updated

over 2 years ago

docker pull grufos/postgres