[Из песочницы] Механизм контроля версий базы данных в GIT (управление дампами MySQL)

habr.png

Привет, любители Хабра! Сегодня я решил поделиться своим вариантом бекапа данных из MySql и рассказать о том как его можно использовать для контроля версий в Git. И если вам интересно узнать, как можно контролировать состояние базы данных на всех этапах разработки, или просто делать правильные бекапчики базы своих проектиков и разворачивать из в любой момент времени, тогда прошу к прочтению!


Что это?

Это набор скриптов написанных на BASH, что позволяет им работать практически на любой машине в которой работает данная оболочка, предназначенный для облегчения создания и разворачивания бекапов. Изначальная идея была в том чтобы можно было создавать контрольные точки БД при написании проекта командой разработчиков, и хранить его в гите, я знаю что есть более серьезные вещи для такой цели, и это решение никак не претендует на их место.


Для кого?

К примеру вы предпочитаете разрабатывать сайт сразу на хостинге заказчика и контролировать ход разработки и изменения в БД. Либо у вас мало денег (или жаба душит) чтобы тратить их на хорошие продукты контроля версий БД. Вы также можете использовать проект в качестве бекапера данных по определенным правилам, который можно использовать по крону. И конечно пригодится если вы начинающий разработчик и только начинаете осваивать азы разработки, и у вас периодически происходит 500-я и вы не знаете почему. Либо вы разрабатываете продукт командой и хотите автоматически при пуше в мастер синхронизировать его с продакшеном для оценки заказчика.

Рассмотрим пример стандартной разработки сайта на стороне хостера (большинство случаев):


  1. Есть сервер, на котором крутится проект и скорее всего это либо локальная машина, либо хостинг клиента текущего проекта.
  2. Есть локальный компьютер, за которым вы работаете и по традиции там же храните файлики и снимки состояний.
  3. И Продакшен, это то куда сливается итоговый продукт —, но он может являтся и 1-м пунктом просто другой папкой.


Как с этим работать?

Для того, чтобы соблюсти контроль версии базы данных используя гит, очевидно нужно получать ее дампы на некоторых этапах, где то их хранить, и при переключении веток учитывать этот момент. Для этого я использовал хуки гита, которые представляют из себя файлики соответствующих скриптов (они должны быть установлены на локальном компьютере, где используется git). В зависимости от настроек конфигурационного файла процесс работы может выглядеть следующим образом:

Создаем ветку (автоматически произошел бекап) и переключаемся, работаем, добавляем файлики, создаем комит (автоматически произошел бекап)…
переключились на мастер верку, произшло переключения БД на предыдущее состояние…
вернулись в разработку, слили ветки, запушили. Т.е. бекапы автоматом создаются при комитах,
либо принудительно перед чекаутом, поведение настраивается в конфиге. Вы можете вручную вызывать экспорт либо импорт БД на сервере, с вашего локального компа, запуская соответствующий скрипт.

У каждого скрипта можно получить справку классическим путем через аргумент -h либо --help.

Я не рекомендую бекапить всю БД, гит не любит больших файлов, да и в большинстве случаев это и не нужно. Поэтому вы можете легко настроить используя config.ini Так как настройки используются и на серверной стороне (на которой поднят mySql) и клиентской (комп разработчика), то за настройку отвечает один и тот же файл. И Конечно это может быть один и тот же компьютер, если вы ведете разработку локально.


Что можно настраивать для создания дампа


  • Настройки подключения к БД и пути храния дампов
  • Указание провайдера, который сможет не только получить данные подключения к БД, но
    и правильно очистить кеш на сервере при переключении веток.
  • Экспорт всей БД
  • Список таблиц которые нужно исключить из экспорта
  • Либо экспорт определенных таблиц
  • Сохранение структуры без вставки данных у определенных таблиц
  • Указание полей у таблиц значения которых не должны экспортироваться, и должны
    быть заменены значениями по умолчанию.
  • Отдельные наборы правил в одном конфиге, что позволит делать различные бекапы по CRON-у

Для того чтобы облегчить процесс создания дампов. Я использовал файлы — провайдеры. И настроил (пока один единственный) для CMS MODX revolution. На его основе можно написать такой же провайдер для любой CMS.


Краткие шаги к началу работы

Скачаем проект, рекомендую положить в папку рядом с .git, либо внутрь проекта, скрипт все равно найдет git

[git clone ](https://github.com/Setest/.git-db-watcher)

установим права на запуск на локальном компе и сервере
chmod +x install.sh;

ставим локально
./install.sh

ставим на сервере, где не нужны хуки

./install.sh -nh

Теперь необходимо внести правки в config.ini. Для примера вот так:

;общий раздел
[hooks]
  ; H_CHECK_DB_HASH_BEFORE_CHECKOUT=1
  ; импорт файла БД даже если checkout происходит на эту же ветку
  ; также это правило распростроняется при переключении на вновь созданную ветку
  ; через git checkout -b new_branch_name
  H_CHECKOUT_FORCE=0
  ; автоматическое добавление файла БД при каждом комите
  H_CHECKOUT_EVERCOM=1
  ;автоматическая очистка директории кеша после переключения БД
  H_CHECKOUT_CLEARCACHE=1

[common]
  ;результирующий файл в который будут экспортироваться данные
  EXPORT_FILE="db.sql"
;на локальном компе используется из хуков гита и ручного экспорта БД
;через запуск файла ./export.sh

[develop]
  ;скрипт запуска db_export.sh на сервере
  CLI_DB_EXPORT="ssh host '/path/to/project/on/server/.git-db-watcher/db_export.sh'"
  CLI_DB_IMPORT="ssh host '/path/to/project/on/server/.git-db-watcher/db_import.sh'"

;только на сервере
[server]
  PHP_PATH="/usr/local/bin/php"
  CONFIG_INC_PATH="/path/to/project/on/server/core/config/config.inc.php"
  PROVIDER=modx
  DB_TABLES_INCLUDE=site_content
  DB_TABLES_AUTOPREFIX=1

[server_full_site]
  PHP_PATH="/usr/local/bin/php"
  CONFIG_INC_PATH="/path/to/project/on/server/core/config/config.inc.php"
  ; '' - берет данные из настроек с префиксом DB_CONFIG_ иначе из файла лежащего
  ; папке providers
  PROVIDER=modx
  ;не обязательно но можно указать настройки вручную если нет провайдера
  DB_CONFIG_HOST=
  DB_CONFIG_TYPE=
  DB_CONFIG_USER=
  DB_CONFIG_PASSWORD=
  DB_CONFIG_CONNECTION_CHARSET=
  DB_CONFIG_DBASE=
  DB_CONFIG_TABLE_PREFIX=
  DB_CONFIG_DATABASE_DSN=
  ;если указаны то будут экспортированы только эти таблицы (разделитель пробел)
  ;заворачивать строку в кавычки нельзя
  ; DB_TABLES_INCLUDE=manager_log register_messages user_attributes
  ; DB_TABLES_INCLUDE=site_content
  ;таблицы исключаемые из экспорта
  ; DB_TABLES_EXCLUDE=session register_messages mse2_words ec_messages
  ;добавление префиксов, взятых из файла конфигурации, к именам таблиц
  DB_TABLES_AUTOPREFIX=1
  ;таблицы из которых будет удалены запросы на INSERT
  DB_TABLES_REMOVE_INSERT="manager_log session register_messages"
  ; DB_TABLES_REMOVE_INSERT="manager_log"

  ;список таблиц поля которых будут выставлены по умолчанию
  ; DB_TABLES_DEFAULT=user_attributes users
  DB_TABLES_DEFAULT=user_attributes
  ;список полей соответствующих таблице, значения кот будут выставлены
  ;по умолчанию в соответствие с со структурой таблицы, это не обязательно и
  ; можно не указывать
  DB_TABLES_DEFAULT_user_attributes=sessionid logincount lastlogin thislogin
  ; DB_TABLES_DEFAULT_users=session_stale

;получает только пользователей, с удалением лишних данных
[only_users]
  DB_TABLES_INCLUDE=user user_attributes
  EXPORT_FILE="users.sql"
  DB_TABLES_DEFAULT=user_attributes user
  DB_TABLES_DEFAULT_user_attributes=sessionid logincount lastlogin thislogin
  DB_TABLES_DEFAULT_users=session_stale

Если все настроено правильно можно запустить ./export.sh и у вас должен
появиться дамп БД на локальном компе и на сервере.


Остальные вопросы


Мне нужно сохранить результат на сервере в другое место:
  ./db_export.sh --output 1>./xxx.sql


Хочу производить экспорт на сервере используя данные своего раздела файла конфигурации:
  ./db_export.sh -с=only_users --output 1>./users.sql


Хочу импортировать файл БД, но не хочу это делать через перехватчики GIT-а?
  ./import.sh
  ./import.sh EXPORT_FILE=site_name.sql
  ./import.sh DB_BACKUP_FILE=/.../../site_name.sql
  ./import.sh --config=site DB_BACKUP_FILE=./site_name.sql


A как производить импорт находясь на сервере?
  ./db_import.sh < db_backup/db.sql


В разных проектах я использую CMS xxx и мне надоело каждый раз вводить данные
для управления БД, как можно упростить процесс?

Для этого нужно написать свой файл провайдера по аналогии с имеющимися.


Я создал задание CRON и конфигурацию с использованием провайдера php, но оно
не выполняется, либо кеш сайта CMS не очищается, в чем может быть дело?

В зависимости от настроек сервера и самого задания, задания CRON могут запускаться совсем в другом окружении, в котором путь к php препроцессору может отличаться и как следствие, запускать совсем другую версию php не совместимую с той, на которой работает ваша CMS.


Послесловие

Я никогда не писал на BASH скрипты и поэтому вероятно наговнокодил, я уверен, тут есть грамотные ребята, которые в случае заинтересованности смогут добавить свои правки. Я же буду развивать проект по мере поступающего интереса и выявлении ошибок в работе.

И не стоит сразу вонять, что ничего не работает, возможно вы не смогли разобраться в том как произвести правильную настройку и установку (в особенности если вы работаете на Windows, все же BASH это линуксовая среда).

Инструкция по установке и использованию лежит в README. Я старался сразу писать на английском, но и из-за моего любительского уровня, возможно будет не все понятно, в дальнейшем напишу на русском. Если есть желание внести правки в перевод или код, форкайте на здоровье! A если есть хорошие советы — поделитесь.

P.S: если вы дочитали до саааааамого низа, значит Вам стало интересно и не терпится попробовать :-)

Тогда тычь смелее на эту ссылочку!

© Habrahabr.ru