Sign inSign up

thalidzhokov/mariadb

By thalidzhokov

•Updated 28 days ago

Image
1

2.0K

thalidzhokov/mariadb repository overview

⁠mariadb

Образ MariaDB поверх официального mariadb с расчетом параметров под ресурсы контейнера, скриптами обслуживания и диагностикой.

Что добавлено к базовому образу:

  • расчет innodb_buffer_pool_size, innodb_log_file_size, key_buffer_size, max_connections, innodb_io_capacity и innodb_flush_neighbors при запуске контейнера, а не при сборке образа;
  • конфиг с настройками бинлогов, slow log и performance_schema;
  • опциональный пользователь debezium с правами для CDC;
  • скрипты экспорта, импорта, пересоздания, оптимизации, бенчмарка и диагностики нагрузки;
  • fio, percona-toolkit и MySQLTuner внутри образа.

⁠Запуск

docker run -d --name mariadb \
  -e MARIADB_ROOT_PASSWORD=secret \
  -e MARIADB_DATABASE=app_db \
  -e MARIADB_USER=app \
  -e MARIADB_PASSWORD=apppass \
  -v mariadb-data:/var/lib/mysql \
  thalidzhokov/mariadb:11.8

Через compose: скопировать docker-compose.yml и .env, заменить пароли, запустить docker compose up -d. В compose подключен init/test_init.sql: таблица test_table с данными и индексом idx_test_table_name, на нее же в .env настроены MARIADB_HEALTHCHECK_TABLE и MARIADB_HEALTHCHECK_INDEX. Файлы из /docker-entrypoint-initdb.d выполняются один раз, при первой инициализации тома, в базе MARIADB_DATABASE.

На томе, созданном образом без пользователей healthcheck, нужен MARIADB_AUTO_UPGRADE=1: именно он их создает. Без него HEALTHCHECK контейнера остается в состоянии health: starting, хотя сервер работает.

Теги: 11.8 и latest. Архитектуры: linux/amd64, linux/arm64.

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

Базовый образ поддерживает все свои переменные (MARIADB_ROOT_PASSWORD, MARIADB_DATABASE, MARIADB_USER, MARIADB_PASSWORD, MARIADB_AUTO_UPGRADE и остальные), включая варианты с суффиксом _FILE для docker secrets. Энтрипоинт разворачивает _FILE только в своем процессе, поэтому скрипты обслуживания читают файлы сами через scripts/env.sh: для MARIADB_ROOT_PASSWORD, MARIADB_DATABASE, MARIADB_USER, MARIADB_PASSWORD и MARIADB_DEBEZIUM_PASSWORD. Дополнительно:

ПеременнаяПо умолчаниюНазначение
MARIADB_DEBEZIUM_PASSWORDне заданаПароль пользователя debezium, есть вариант _FILE. Пока не задана, пользователь не создается
MARIADB_AUTOTUNE10 отключает расчет параметров целиком
MARIADB_AUTOTUNE_MIN_MB512Ниже этого лимита cgroup (МБ) расчет не выполняется, остается конфиг сервера. Рекомендуемый минимум для образа
MARIADB_AUTOTUNE_IO10 отключает замер IOPS через fio
MARIADB_BUFFER_POOL_PERCENT60Доля доступной памяти под buffer pool (целое 1..90; иначе 60)
MARIADB_KEY_BUFFER_SIZE_MB32key_buffer_size в мегабайтах
MARIADB_AUTOTUNE_FIO_SIZE1GРазмер тестового файла fio в томе данных
MARIADB_AUTOTUNE_FIO_RUNTIME30Длительность замера IOPS в секундах
MARIADB_AUTOTUNE_FIO_FORCEне заданаПовторить замер IOPS, игнорируя кеш
MARIADB_INNODB_FLUSH_NEIGHBORSавто0 / 1 / 2 — ручной innodb_flush_neighbors. Без переменной: SSD/NVMe/Msft Virtual Disk/tmpfs → 0, HDD → 1
MARIADB_DUMP_DIR/mariadb-dumpКаталог для дампов
MARIADB_HEALTHCHECK_TABLEне заданаТаблица, наличие которой проверяет scripts/healthcheck.sh
MARIADB_HEALTHCHECK_INDEXне заданаИмя индекса в этой таблице, у первичного ключа это всегда PRIMARY

Свои переменные используют тот же префикс MARIADB_, что и базовый образ, поэтому при обновлении базы возможны пересечения имен.

⁠Расчет параметров

Параметры считаются при каждом запуске и складываются в /etc/mysql/conf.d/95-autotune.cnf.

Память берется из лимита cgroup контейнера, а не из /proc/meminfo: внутри контейнера MemTotal показывает память хоста, поэтому расчет от него дает завышенные значения. Если лимит меньше MARIADB_AUTOTUNE_MIN_MB (по умолчанию 512M), расчет не выполняется: удаляется прежний 95-autotune.cnf, сервер идет на своих дефолтах. У образа включены performance_schema, бинлоги и slow log — для продакшена лучше не ставить mem_limit ниже 512M, комфортнее от 1G.

Под buffer pool отводится 60% лимита, под redo log четверть buffer pool, нижние границы равны серверным дефолтам (срабатывают только когда расчет уже идет при лимите ≥ порога).

max_connections считается от остатка после buffer pool: половина остатка делится на 8M, столько по 99-override.cnf может занять одно соединение. Результат ограничен снизу 50 и сверху 250. Без лимита памяти у контейнера расчет идет от памяти хоста, поэтому на разделяемом хосте стоит задать mem_limit в compose.

IOPS замеряются fio при первом запуске на томе данных: случайная запись блоком 16K, поскольку innodb_io_capacity ограничивает именно фоновую запись страниц. Результат кешируется в /var/lib/mysql/.autotune-io-capacity, так что повторные запуски проходят без замера. innodb_io_capacity берется как треть измеренных IOPS, innodb_io_capacity_max не опускается ниже серверного дефолта 2000.

innodb_flush_neighbors выбирается по queue/rotational устройства тома данных: на SSD/NVMe (0), tmpfs/ramfs и когда тип не определился — 0. При rotational=1 значение перепроверяется: диск Msft/Virtual Disk (Docker Desktop на Windows — VHDX, не RAM, часто врёт rotational) считаем SSD и ставим 0. Иначе оставляем сброс соседей для HDD. Значение можно задать явно через MARIADB_INNODB_FLUSH_NEIGHBORS:

  • 0 — сбрасывать только нужную грязную страницу (SSD/NVMe);
  • 1 — ещё непрерывных соседей рядом (обычно достаточно для HDD);
  • 2 — всех грязных страниц из того же extent (агрессивно, почти не нужен).

Порядок чтения конфигов: /etc/mysql/conf.d/ подключается после /etc/mysql/mariadb.conf.d/, поэтому 95-autotune.cnf и 99-override.cnf переопределяют пакетный 50-server.cnf. Любой смонтированный в conf.d файл с именем на букву читается последним и переопределяет оба.

⁠Скрипты

Запускаются из корня контейнера, напр. docker exec -t mariadb bash scripts/export.sh.

СкриптНазначение
create.shСоздать базу и пользователя, обновить его пароль
drop.shУдалить базу
export.shДамп в latest_<день недели>.sql.gz
import.shИмпорт самого свежего latest_*.sql.gz; если нет — /docker-entrypoint-initdb.d/latest.sql.gz
recreate.shУдаление, создание, импорт последнего дампа; debezium только если задан пароль. С --export сначала снимает свежий дамп (нужен до смены MARIADB_PASSWORD)
create-debezium-user.shСоздать или обновить пользователя debezium
upgrade.shmariadb-upgrade системных таблиц
optimize.shOPTIMIZE TABLE по всем таблицам базы
scripts/healthcheck.shПолная проверка пользователей, прав, бинлогов и запуск MySQLTuner
benchmark.shЗамеры через mariadb-slap с отчетами
diagnose-load.shСрезы processlist, блокировки (sys.innodb_lock_waits / sys.schema_table_lock_waits, с MariaDB 10.6), топ запросов, хвост slow log

Два разных healthcheck.sh — не путать:

  • HEALTHCHECK образа вызывает штатный healthcheck.sh базового образа (он на PATH): только --connect --innodb_initialized. На MARIADB_HEALTHCHECK_TABLE / INDEX не смотрит.
  • Полная проверка — только явно: docker exec -t mariadb bash scripts/healthcheck.sh (/scripts не в PATH). MySQLTuner в ней занимает около 15 секунд. docker exec … healthcheck.sh без scripts/ попадёт в штатный скрипт.

⁠Дампы и права

Пользователь сервера внутри контейнера имеет uid и gid 999. Каталог /mariadb-dump создан в образе с этим владельцем, поэтому свежий named volume наследует права и на хосте настраивать ничего не нужно.

Скрипты обслуживания запускаются через docker exec, то есть от root, поэтому в bind mount дампы пишутся без подготовки прав, но остаются с владельцем root:root и режимом 644. Если на хосте их забирает или ротирует непривилегированный процесс, каталог стоит создать заранее с нужным владельцем:

install -d -o 999 -g 999 -m 750 /var/backups/myproject/mariadb

⁠Пользователь debezium

Создается при первой инициализации тома данных, если задан MARIADB_DEBEZIUM_PASSWORD: энтрипоинт вызывает scripts/create-debezium-user.sh сразу после штатного docker_setup_db, в том же проходе, что и MARIADB_USER. Права: SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, BINLOG MONITOR, SLAVE MONITOR глобально плюс SELECT и LOCK TABLES на MARIADB_DATABASE.

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

docker exec -t mariadb bash scripts/create-debezium-user.sh

⁠Сборка

docker build -t thalidzhokov/mariadb:11.8 .
docker build --build-arg MARIADB_VERSION=11.4 -t thalidzhokov/mariadb:11.4 .

⁠Проверка

tests/run.sh поднимает контейнер из собранного образа и проверяет HEALTHCHECK, применение autotune, вход root и debezium по *_FILE, пароли с кавычкой и слешем, экранирование _ в GRANT, инициализацию из init/test_init.sql, scripts/healthcheck.sh с проверкой таблицы и индекса и recreate.sh со сменой пароля. Контейнер и том удаляются по завершении.

bash tests/run.sh thalidzhokov/mariadb:11.8

В CI тесты идут перед публикацией образа.

Tag summary

Content type

Image

Digest

sha256:676242db4…

Size

154.8 MB

Last updated

28 days ago

docker pull thalidzhokov/mariadb