Как вы управляете базами данных при разработке, тестировании и производстве?

171

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

Вот наша установка. У каждого разработчика есть виртуальная машина с нашим приложением и база данных MySQL. Это их личная песочница, чтобы делать все, что они хотят. В настоящее время разработчики внесут изменения в схему SQL и сделают дамп базы данных в текстовый файл, который они фиксируют в SVN.

Мы хотим развернуть сервер разработки с непрерывной интеграцией, на котором всегда будет работать последний принятый код. Если мы сделаем это сейчас, он перезагрузит базу данных из SVN для каждой сборки.

У нас есть тестовый (виртуальный) сервер, который запускает «кандидатов на выпуск». Развертывание на тестовом сервере в настоящее время является очень ручным процессом и обычно включает в себя загрузку последней версии SQL из SVN и ее настройку. Также данные на тестовом сервере противоречивы. В результате вы получите все тестовые данные, которые последний разработчик зафиксировал на своем сервере-песочнице.

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

Если бы проблема была только в схеме, это была бы более простая проблема, но в базе данных есть «базовые» данные, которые также обновляются во время разработки, такие как метаданные в таблицах безопасности и разрешений.

Это самый большой барьер, который я вижу в продвижении к непрерывной интеграции и пошаговой сборке. Как вы это решаете?


Дополнительный вопрос: как вы отслеживаете версии базы данных, чтобы знать, какие сценарии нужно запустить для обновления данного экземпляра базы данных? Таблица версий, которую упоминает Ланс, ниже стандартной процедуры?


Спасибо за ссылку на Тарантино. Я не нахожусь в среде .NET, но я нашел их вики-страницу DataBaseChangeMangement очень полезной. Особенно эта презентация Powerpoint (.ppt)

Я собираюсь написать сценарий Python, который проверяет имена *.sqlсценариев в данном каталоге по таблице в базе данных и запускает те, которых там нет, по порядку на основе целого числа, которое образует первую часть имени файла. Если это довольно простое решение, как я подозреваю, оно будет опубликовано здесь.


У меня есть рабочий сценарий для этого. Он обрабатывает инициализацию БД, если она не существует, и запускает сценарии обновления по мере необходимости. Есть также переключатели для очистки существующей базы данных и импорта тестовых данных из файла. Это около 200 строк, поэтому я не буду публиковать его (хотя я мог бы поставить его на pastebin, если есть интерес).

Мэтт Миллер
источник
Релевантно: stackoverflow.com/questions/52583/…
Эшвин,
«Я собираюсь написать сценарий Python, который проверяет имена сценариев * .sql в данном каталоге по таблице в базе данных и запускает те, которых там нет, по порядку на основе целого числа, которое образует первую часть имя файла. Если это довольно простое решение, как я подозреваю, оно будет опубликовано здесь ". Похоже, вы внедряете flyway.
masterxilo

Ответы:

53

Есть несколько хороших вариантов. Я бы не стал использовать стратегию «восстановления резервной копии».

  1. Сценарий всех изменений схемы, и ваш сервер CI запускает эти сценарии в базе данных. Иметь таблицу версий для отслеживания текущей версии базы данных и выполнять сценарии только в том случае, если они предназначены для более новой версии.

  2. Используйте решение для миграции. Эти решения различаются в зависимости от языка, но для .NET я использую Migrator.NET. Это позволяет вам создавать версии вашей базы данных и перемещаться вверх и вниз между версиями. Ваша схема указана в коде C #.

Лэнс Фишер
источник
28

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

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

tbreffni
источник
13

Посмотрите, как Ruby on Rails делает это.

Сначала существуют так называемые файлы миграции, которые в основном преобразуют схему базы данных и данные из версии N в версию N + 1 (или в случае понижения с версии N + 1 до N). База данных имеет таблицу, которая сообщает текущую версию.

Тестовые базы данных всегда очищаются перед юнит-тестами и заполняются фиксированными данными из файлов.

Юха Сыряля
источник
10

Книга « Рефакторинг баз данных: эволюционный дизайн баз данных» может дать вам некоторые идеи о том, как управлять базой данных. Краткая версия также доступна для чтения по адресу http://martinfowler.com/articles/evodb.html.

В одном проекте PHP + MySQL у меня был номер версии базы данных, сохраненный в базе данных, и когда программа подключается к базе данных, она сначала проверяет версию. Если программа требует другой ревизии, она откроет страницу для обновления базы данных. Каждое обновление указывается в коде PHP, который изменит схему базы данных и перенесет все существующие данные.

Эско Луонтола
источник
5
  • Назовите свои базы данных следующим образом: - dev_<<db>> , tst_<<db>> , stg_<<db>> , prd_<<db>>(Очевидно , что вы никогда не должны жёстко имен БД
  • Таким образом, вы сможете развернуть даже разные типы БД на одном и том же физическом сервере (я не рекомендую, но вам, возможно, придется ... если ресурсы ограничены)
  • Убедитесь, что вы сможете перемещать данные между этими автоматическими
  • Отделите сценарии создания БД от совокупности = всегда должна быть возможность воссоздать БД с нуля и заполнить ее (из старой версии БД или из внешнего источника данных
  • не используйте строки кода с жестким кодом в коде (даже не в файлах конфигурации) - используйте в файлах конфигурации шаблоны строк подключения, которые вы заполняете динамически, каждая реконфигурация application_layer, которая требует перекомпиляции, BAD
  • используйте версионность баз данных и версионность объектов БД - если вы можете себе это позволить, используйте готовые продукты, если не разрабатываете что-то самостоятельно
  • отслеживать каждое изменение DDL и сохранять его в какой-либо таблице истории ( пример здесь )
  • ЕЖЕДНЕВНЫЕ резервные копии! Проверьте, насколько быстро вы сможете восстановить что-то потерянное из резервной копии (используйте автоматические сценарии восстановления
  • даже у вашей базы данных DEV и PROD точно такой же сценарий создания, что у вас будут проблемы с данными, поэтому позвольте разработчикам создать точную копию prod и поиграть с ней (я знаю, что получу минусы для этого, но изменения в мышление и бизнес-процесс обойдутся вам гораздо дешевле, когда дерьмо попадет на веер - поэтому заставьте кодеров легально подписывать все, что он делает, но убедитесь, что это
Йордан Георгиев
источник
Последний пункт действительно настроение. Если это необходимо, это показывает, что определение проекта нарушено. Разработка должна вести перед производством. Если производственные данные вызывают побочные эффекты, это показывает большие проблемы. Очистите производственные данные. Также уточните последний этап с сотрудником по защите данных, если есть причина - как вы предполагаете - что живые данные должны быть в системах разработки, проверьте, применимо ли это по закону. Также точная копия производственных данных в значительной степени замедляет разработку и интеграцию. Рассмотрим менее дорогостоящий процесс, если вы не можете позволить себе такую ​​роскошь.
Хакре
Дело в том, что во время разработки просто невозможно даже представить все ключевые случаи в потоке управления и изменения качества данных, которые произойдут в производстве. Если вы находитесь в такой большой корпорации, чтобы иметь юридические проблемы для этого, необходимо внедрить какое-либо решение для скремблирования и / или маскирования данных, которое добавляет дополнительный уровень сложности, но все равно должно сохранять аспекты качества данных, которые вызвали ошибку на первом месте в любом случае ...
Йордан Георгиев
4

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

  • dbChanges_1.sql
  • dbChanges_2.sql
  • ...
  • dbChanges_n.sql

Это работало достаточно хорошо, пока мы не начали поддерживать две линии разработки: магистраль / магистраль для новой разработки и ветвь обслуживания для исправления ошибок, краткосрочных улучшений и т. Д. Неизбежно возникла необходимость вносить изменения в схему в ветке. На данный момент у нас уже есть dbChanges_n + 1.sql в магистрали, поэтому мы в итоге пошли по схеме, подобной следующей:

  • dbChanges_n.1.sql
  • dbChanges_n.2.sql
  • ...
  • dbChanges_n.3.sql

Опять же, это работало достаточно хорошо, пока мы однажды не подняли глаза и не увидели 42 дельта-сценария в основной строке и 10 в ветви. ARGH!

В наши дни мы просто поддерживаем один дельта-скрипт и позволяем SVN его версии - т.е. мы перезаписываем скрипт с каждым выпуском. И мы уклоняемся от внесения изменений в схемы в ветвях.

Так что меня это тоже не устраивает. Мне очень нравится концепция миграции с Rails. Я очень увлекся LiquiBase . Он поддерживает концепцию инкрементного рефакторинга базы данных. Это стоит посмотреть, и я скоро рассмотрим это подробно. У кого-нибудь есть опыт работы с этим? Мне было бы очень любопытно услышать о ваших результатах.

Мэтт Стайн
источник
4

Вы также можете взглянуть на использование такого инструмента, как SQL Compare, чтобы записать разницу между различными версиями базы данных, что позволяет быстро мигрировать между версиями.

Rad
источник
3

У нас очень похожая настройка на ОП.

Разработчики развиваются в виртуальных машинах с частными БД.

[Разработчики скоро будут совершать в частных филиалах]

Тестирование выполняется на разных машинах (фактически в виртуальных машинах, размещенных на сервере) [Скоро будет запущен сервером Hudson CI]

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

Затем запустите модульные и системные тесты.

Производство развертывается для клиентов в качестве установщиков.

Что мы делаем:

Мы берем дамп схемы нашей БД песочницы. Затем дамп данных SQL. Различаем это до предыдущего базового уровня. эта пара дельт должна обновить n-1 до n.

настраиваем дампы и дельты.

Поэтому, чтобы установить версию N CLEAN, мы запускаем дамп в пустую базу данных. Чтобы исправить, примените промежуточные исправления.

(Юха упомянул, что идея Rail о наличии таблицы, записывающей текущую версию БД, хороша и должна сделать установку обновлений менее сложной.)

Дельты и дампы должны быть проверены перед бета-тестированием. Я не вижу никакого способа обойти это, так как видел, как разработчики сами вставляли тестовые учетные записи в БД.

Тим Виллискрофт
источник
3

Боюсь, я согласен с другими постерами. Разработчики должны написать свои изменения.

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

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

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

MarkR
источник
1

Посмотрите на dbdeploy , там уже есть инструменты Java и .net, вы можете следовать их стандартам для макетов файлов SQL и таблицы версий схемы и написать свою версию на python.

Дейв Маршалл
источник
1

Мы используем командную строку mysql-diff : она выводит разницу между двумя схемами базы данных (из действующей БД или скрипта) в качестве скрипта ALTER. mysql-diff выполняется при запуске приложения, и если схема изменилась, он сообщает об этом разработчику. Таким образом, разработчикам не нужно писать ALTERs вручную, обновления схемы происходят полуавтоматически.

stepancheg
источник
0

Я написал инструмент, который (подключаясь к Open DBDiff ) сравнивает схемы базы данных и предложит вам сценарии миграции. Если вы внесете изменение, удаляющее или изменяющее данные, оно выдаст ошибку, но предложит сценарий (например, если столбец отсутствует в новой схеме, он проверит, был ли столбец переименован, и создаст xx-сгенерированный script.sql.suggestion, содержащий оператор переименования).

http://code.google.com/p/migrationscriptgenerator/ Только SQL Server, боюсь :( Это тоже довольно альфа, но ОЧЕНЬ низкое трение (особенно, если вы комбинируете его с Tarantino или http://code.google .com / p / simplescriptrunner / )

Я использую его, чтобы иметь проект SQL-скриптов в вашем .sln. У вас также есть локальная база данных db_next, в которую вы вносите свои изменения (используя Management Studio или NHibernate Schema Export или LinqToSql CreateDatabase или что-то в этом роде). Затем вы запускаете migrationscriptgenerator с базами данных _dev и _next, который создает. сценарии обновления SQL для миграции.

оборота mcintyre321
источник
0

Для базы данных oracle мы используем инструменты oracle-ddl2svn .

Этот инструмент автоматизировал следующий процесс

  1. для каждой схемы дб получаем схему ддлс
  2. поставить его под версию контроля

изменения между экземплярами разрешаются вручную

popalka
источник