На этот раз рассмотрим перенос данных из MySQL в PostgreSQL, пригодный, пожалуй, для любых приложений, предоставляющих выбор из этих двух СУБД.
pgloader может перенести содержимое базы данных полностью в автоматическом режиме, воссоздавая необходимые таблицы, индексы и внешние ключи. Но этот подход не самый лучший, потому что в дальнейшем могут возникнуть непредвиденные проблемы при работе приложения или в процессе миграции на его более свежие версии. Поэтому лучше будет создать пустую базу данных, взять структуру этой новой пустой базы данных и наполнить её существующими данными.
Рассмотрим эту стратегию миграции на примере Redmine.
Схема базы данных - это её структура, то есть таблицы, индексы, ключи, без данных.
Установим дополнительно пакет, отвечающий за работу Redmine совместно с СУБД PostgreSQL:
# apt-get install redmine-pgsql
Для начала перейдём в каталог /etc/redmine/, в котором есть подкаталоги, соответствующие экземплярам redmine:
# cd /etc/redmine/
Скопируем каталог одного из экземпляров в другой каталог, создав таким образом новый экземпляр. В данном случае копируем экземпляр default и создаём на его основе экземпляр pgsql:
# rsync -rogp default/ pgsql/
Открываем файл /etc/redmine/pgsql/database.yml и заменяем в нём имя пользователя в поле username, имя базы данных в поле database и тип базы данных в поле adapter. У меня получился такой файл:
production: adapter: postgresql database: redmine_pgsql host: localhost port: username: redmine_pgsql password: password encoding: utf8
Теперь нужно создать соответствующего пользователя и базу данных:
# su - postgres $ createuser -P redmine_pgsql $ createdb -E UTF-8 -O redmine_pgsql redmine_pgsql $ exit
Пустая база данных и пользователь созданы. Теперь нам нужно наполнить эту базу данных структурой и первичными данными. Для этого переходим в каталог /usr/share/redmine/, в котором находится Redmine, и запускаем команду миграции экземпляра pgsql, которая сделает всё необходимое:
# cd /usr/share/redmine # rake db:migrate RAILS_ENV=production X_DEBIAN_SITEID=pgsql
Теперь, если всё прошло успешно, создаём резервную копию этой базы данных, но без собственно данных:
# su - postgres $ pg_dump -s -d redmine_pgsql > redmine_pgsql.sql
Теперь можно удалить этого пользователя и его базу данных, от них нам больше ничего не нужно:
$ dropdb redmine_pgsql $ dropuser redmine_pgsql $ exit
Теперь можно удалить и каталог с настройками экземпляра pgsql:
# cd /etc/redmine # rm -R pgsql
Как стало ясно в процессе дальнейших попыток воспользоваться дампом, его нужно откорректировать:
Сделать это можно вот так:
$ cat redmine_pgsql.sql | sed -e 's/^--.*$//g; s/^COMMENT .*$//; /^$/d; s/"//g; s/TO redmine_pgsql/TO redmine_default/g' > redmine_default.sql
Теперь нужно поделить файл redmine_default.sql на две части. Первый должен создать структуру базы данных без ограничений и внешних ключей, а второй - добавлять их. К счастью, стандартный дамп, созданный pg_dump, можно легко поделить на нужные нам части. Первая часть заканчивается запросами вида "ALTER TABLE ONLY ... ALTER COLUMN ... SET DEFAULT ...", а вторая часть начинается запросами вида "ALTER TABLE ONLY ... ADD CONSTRAINT ...". В результате должны получиться файлы redmine_default1.sql и redmine_default2.sql
Приведу ссылки на эти файлы: redmine_default1.sql и redmine_default2.sql Они соответствуют версии Remine, поставляющейся в репозиториях Debian Jessie (версии пакетов - 3.0~20140825-5). Если у вас именно эта версия Redmine, можно пропустить весь этот раздел и сразу воспользоваться этими файлами.
Если pgloader ещё не установлен, установим его:
# apt-get install pgloader
Теперь создадим файл redmine_default.sql с настройками миграции:
LOAD DATABASE FROM mysql://redmine_default:password@localhost/redmine_default INTO postgresql://redmine_default:password@localhost/redmine_default WITH include no drop, truncate, create no tables, create no indexes, no foreign keys, reset sequences, data only SET maintenance_work_mem TO '128MB', work_mem to '12MB' BEFORE LOAD EXECUTE redmine_default1.sql
Теперь отключаем Redmine, чтобы данные не менялись в процессе переноса в новую СУБД:
# /etc/init.d/uwsgi stop redmine
Открываем файл с настройками подключения к базе данных мигрируемого экземпляра default. В данном случае это файл /etc/redmine/default/database.yml, который в данный момент настроен на использование MySQL. Нужно создать точно такого же пользователя и базу данных в PostgreSQL:
# su - postgres $ createuser -P redmine_default $ createdb -E UTF-8 -O redmine_default redmine_default $ exit
Запускаем миграцию:
$ pgloader redmine_default.load
После миграции открываем снова файл с настройками подключения к базе данных мигрируемого экземпляра default. Это файл /etc/redmine/default/database.yml, заменяем в нём тип базы данных с mysql2 на postgresql.
Теперь можно запустить uwsgi, чтобы Redmine вновь стал доступен для пользователей. Тестируем, всё ли правильно работает. Дальше можно перенести другие экземпляры Redmine и по окончании миграции удалить пакет Redmine для работы с MySQL:
# apt-get purge redmine-mysql