Перенос изменений базы данных из разработки в живую - PullRequest
15 голосов
/ 29 августа 2008

Пожалуй, самый большой риск в реализации новой функциональности связан с изменениями базы данных, необходимыми для нового кода. Я полагаю, что в Rails они имеют «миграции», в которых вы можете программно вносить изменения в хост разработки, а затем вносить те же изменения в живую вместе с кодом, использующим пересмотренную схему. И, если необходимо, откатитесь назад, синхронно.

Кто-нибудь сталкивался с подобным набором инструментов для PHP / MySQL? Хотелось бы услышать об этом или о любых программных или технологических решениях, которые помогут сделать это менее рискованным ...

Ответы [ 10 ]

5 голосов
/ 30 августа 2008

Я не доверяю программным миграциям. Если это простое изменение, например, добавление столбца NULLable, я просто добавлю его непосредственно на работающий сервер. Если это сложнее или требует изменения данных, я напишу пару файлов миграции SQL и протестирую их в базе данных реплики.

При использовании миграций, всегда тестирует миграцию отката. Это ваша аварийная кнопка "о, дерьмо".

5 голосов
/ 30 августа 2008

Я никогда не сталкивался с инструментом, который бы делал эту работу. Вместо этого я использовал отдельные файлы, пронумерованные так, чтобы я знал, какой порядок их запускать: по сути, это ручная версия миграций Rails, но без отката.

Вот о чем я говорю:

000-clean.sql         # wipe out everything in the DB
001-schema.sql        # create the initial DB objects
002-fk.sql            # apply referential integrity (simple if kept separate)
003-reference-pop.sql # populate reference data
004-release-pop.sql   # populate release data
005-add-new-table.sql # modification
006-rename-table.sql  # another modification...

У меня никогда не было проблем с этим, но это не очень элегантно. От вас зависит, какие скрипты необходимо запустить для данного обновления (более разумная схема нумерации может помочь). Он также отлично работает с контролем источника.

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

3 голосов
/ 15 августа 2010

Решение, которое я использую (первоначально разработанное моим другом), является еще одним дополнением к yukondude.

  1. Создайте каталог схемы под управлением версиями, а затем для каждого изменения базы данных сохраняйте файл .sql с требуемым SQL-запросом и запрос sql для обновления таблицы db_schema.
  2. Создайте таблицу базы данных с именем "db_schema" с целочисленным столбцом с именем version.
  3. В каталоге схемы создайте два сценария оболочки: «текущий» и «обновление». Выполнение current говорит вам, к какой версии схемы БД в данный момент подключена база данных. При запуске update каждый файл .sql последовательно пронумерован больше, чем версия в таблице db_schema, до тех пор, пока вы не доберетесь до файла с наибольшим номером в директории схемы.

Файлы в схеме dir:

0-init.sql 
1-add-name-to-user.sql
2-add-bio.sql

Как выглядит типичный файл, обратите внимание на обновление db_schema в конце каждого файла .sql:

BEGIN;
-- comment about what this is doing
ALTER TABLE user ADD COLUMN bio text NULL;

UPDATE db_schema SET version = 2;
COMMIT;

«Текущий» скрипт (для psql):

#!/bin/sh

VERSION=`psql -q -t <<EOF
\set ON_ERROR_STOP on
SELECT version FROM db_schema;
EOF
`

[ $? -eq 0 ] && {
    echo $VERSION
    exit 0
}

echo 0

скрипт обновления (также psql):

#!/bin/sh

CURRENT=`./current`
LATEST=`ls -vr *.sql |egrep -o "^[0-9]+" |head -n1`

echo current is $CURRENT
echo latest is $LATEST

[[ $CURRENT -gt $LATEST ]] && {
    echo That seems to be a problem.
    exit 1
}

[[ $CURRENT -eq $LATEST ]] && exit 0

#SCRIPT_SET="-q"
SCRIPT_SET=""

for (( I = $CURRENT + 1 ; I <= $LATEST ; I++ )); do
    SCRIPT=`ls $I-*.sql |head -n1`
    echo "Adding '$SCRIPT'"
    SCRIPT_SET="$SCRIPT_SET $SCRIPT"
done

echo "Applying updates..."
echo $SCRIPT_SET
for S in $SCRIPT_SET ; do
    psql -v ON_ERROR_STOP=TRUE -f $S || {
    echo FAIL
    exit 1
    }
done
echo OK

Мой 0-init.sql имеет полную начальную структуру схемы вместе с начальным «UPDATE db_schema SET version = 0;». Не должно быть слишком сложно изменить эти сценарии для MySQL. В моем случае у меня также есть

export PGDATABASE="dbname"
export PGUSER="mike"

в моем .bashrc. И запрашивает пароль для каждого исполняемого файла.

3 голосов
/ 18 сентября 2008

@ [yukondude]

Я сам использую Perl, и таким же образом я прошел путь миграции в стиле Rails полу-вручную.

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

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

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

3 голосов
/ 18 сентября 2008

Я использовал этот инструмент раньше, и он отлично работал.

http://www.mysqldiff.org/

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

2 голосов
/ 18 сентября 2008

Почти то, что описал Лот105.

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

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

Некоторые изменения нельзя сделать с помощью простого скрипта ALTER, такого как инструмент, подобный sqldiff; некоторые изменения требуют не изменения схемы, а программного изменения существующих данных. Поэтому вы не можете обобщать, поэтому вам нужен отредактированный человеком сценарий.

2 голосов
/ 30 августа 2008

Я использую SQLyog , чтобы скопировать структуру, и я ВСЕГДА, позвольте мне повторить ВСЕГДА, сначала сделайте резервную копию.

2 голосов
/ 29 августа 2008

Symfony имеет плагин sfMigrationsLight, который обрабатывает основные миграции. CakePHP также имеет миграции.

По какой-то причине поддержка миграции никогда не была приоритетной для большинства PHP-фреймворков и ORM.

0 голосов
/ 28 июня 2011

В прошлом я использовал LiquiBase , инструмент на основе Java, в котором вы конфигурируете свои миграции в виде файлов XML. С его помощью вы можете сгенерировать необходимый SQL.

Сегодня я бы использовал библиотеку Doctrine 2 , которая имеет средств миграции , аналогичных Ruby.

Инфраструктура Symfony 2 также имеет хороший способ справиться с изменениями схемы - ее инструмент командной строки может анализировать существующую схему и генерировать SQL, чтобы сопоставить базу данных с определениями измененной схемы.

0 голосов
/ 26 июня 2009

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

У вас будет только 1 база данных, и, если вы решите запретить удаление столбца из таблицы, вы знаете, что ваш новый код будет соответствовать используемой вами базе данных.

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

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

Еще одним побочным эффектом является возможность переноса через небольшую группу «бета-тестеров» для использования сайта в повседневном использовании. Это может привести к большому количеству откликов, которые вы можете реализовать до публичного запуска.

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

...