Xpoint
   [напомнить пароль]

Синхронизация структуры БД на 2 машинах

Метки: [без меток]
2006-06-08 11:05:01 [обр] Дмитрий Котеров(6/912)[досье]

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

Довольно хорошо известно, что в общем случае, имея 2 версии структуры одной и той же БД, невозможно автоматически их синхронизировать между собой. Например, мы на тестовой базе переименовали некоторое поле. Как синхронизатор поймет, что произошло: переименование, лил удаление поля + создание нового с другим именем? Ситуация еще более усложняется при наличии связей с внешними ключами.

Для того чтобы "догнать" версию базы на реальном сервере до версии базы на тестовом, необходимо выполнить на первой те же самые ALTER-команды, что и на второй. Т.е. нужно тщательно хранить все ALTER-команды, выполняющиеся над базой разработчиками, и потом разом "накатывать" их на другие базы.

Внимимание: здесь схема существенно отличается от схемы работы с исходными кодами сайта, когда обновление их элементарно производится через CVS. Получается, у нас 2 сущности: исходники и БД, причем последняя очень плохо поддается версионности (а уж об откате к предыдущей версии вообще и говорить не приходится). Хотелось бы хотя бы чуть-чуть приблизить их друг к другу.

Очень часто приходится видеть такую схему: ALTER-команды каждый разработчик логирует самостоятельно, а затем складывает их в CVS и обеспечивает версионность. Но такая схема очень сильно подвержена различного рода ошибкам, она неустойчива: достаточно 1 раз ошибиться, чтобы структуры баз начали отличаться, и отличие это мы уже найти не сможем, если база большая (или сможем, но с трудом).

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

Собственно, от самой СУБД хотелось бы иметь 2 команды в API:

  1. get_current_version() - возвращает текущую версию структуры БД. С каждым новом ALTER-ом текущая версия увеличивается на 1.
  2. get_diff_alters(from_version) - возвращает список ALTER-команд, выполненных над базой от версии from_version до текущей

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

Спрашивается, новы ли эти мысли, и реализовано ли что-то подобное хотя бы для одной из популярных СУБД? Конечно, прежде всего интересуют PostgreSQL и MySQL.

спустя 5 часов [обр] 30-ый(4/584)[досье]

О реализации подобных методов не слыщал... ни в My-, ни в Postgres-, ни в MS-SQL. И у меня есть большие сомнение в том, что внедрение этой штуки не ударит сильно по производительности и надежности. Вспомните, до недавнего времени даже добавленные поля нельзя было из базы удалять...

Обычно это реализуется назначением ответственного за базу и все ALTER проходят через него. Эту должность в частности часто занимает руководитель проекта или ведущий программист.

Кроме этого количество баз часто меньше, чем версий. Т.е. если версии три developing-testing-production, то две первые используют одну базу.

Для синхронизации в последнем проекте мы пользовались продуктом EMS (http://www.sqlmanager.net), благо недерогой...

спустя 8 часов [обр] Закиров Руслан(5/343)[досье]

Мы в одном из проектов (www.bestpractical.com/rt) предоставляем ALTER'ы и скрипты для обновления баз на разных платформах, так что обновление привязано к версии продукта и производится полуавтоматически. ALTER'ы и новые объекты системы забиваем ручками, и складируем в папочку версии, а пользователь последовательно запускает скрипты начиная со старой версии до новой.

В новом проекте (www.jifty.org) ввели таблицу со свойствами, куда пишем версию БД, при изменении версии пользователь запускает обновление одной коммандой.

Практика показывает, что ряд задач обновления БД не решается простыми ALTER'ами.

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

Еще есть ряд проектов, которые позволяют управлять структурой БД программно и абстрагируют ALTER'ы для различных БД. Например Alzabo и другие.

Если например описывать только изменения БД, то всегда можно будет сгенерить CREATE'ы для любой версии, тогда можно избавиться от одно проблемы - расхождения обновления с новой установкой, такое часто бывает, когда в первом проекте программисты забывают обновить ALTER'ы, но изменяют основную структуру.

Powered by POEM™ Engine Copyright © 2002-2005