home

Миграция Drupal с MySQL/MariaDB на PostgreSQL

Встала необходимость мигрировать сайт Drupal7 с MariaDB 10.2 на PostgreSQL12 (на котором 500 тыс. нод в качестве электронной библиотеки ELiS).

DBTNG Migrator[править]

Обычно рекомендуется именно этот модуль. Но в процессе миграции возникала ошибка из-за дублирования ключей в одном из полей. Причина не понятна. Так что пришлось искать другой способ.

pgloader[править]

Можно в лоб перенести с помощью pgloader.

Как устанавливать на сайте модуля написано, я на CentOS7 поставил из реп.

Установка PostgreSQL[править]

Установите из реп вашего дистрибутива или с официального репозитария. Под CentOS я поставил PostgreSQL с официального репозитария так как там PostgreSQL свежее.

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

Создание базы[править]

Вам надо создать пользователя в PostgreSQL, базу и предоставить на нее привилегии. У меня в примере пользователь elis и база elis. Вы подставьте свое, включая пароль.

sudo -u postgres psql -c "create user elis with password 'db_secret';"
sudo -u postgres psql -c "create database elis WITH OWNER=elis ENCODING 'UTF8' LC_COLLATE = 'ru_RU.UTF-8' LC_CTYPE = 'ru_RU.UTF-8' TEMPLATE = template0;"
sudo -u postgres psql -c "grant all privileges on database elis to elis;"
sudo -u postgres psql -c "ALTER DATABASE elis SET bytea_output='escape';"

Установка pgloader[править]

По возможности ставьте из репозитария вашего дистрибутива, чтобы не собирать руками. Если у вас CentOS и PostgreSQL вы поставили из официального репозитория PostgreSQL, то там pgloader версии 3.6.2 уже будет и достаточно выполнить yum install pgloader.

Написание скрипта импорта[править]

Создайте в любом месте скрипт pgloader.lisp со следующим содержимым:

LOAD DATABASE
FROM mysql://mysql_user:mysql_password@127.0.0.1/db_name
INTO postgresql://pg_user:pg_password@127.0.0.1/db_name
WITH include drop, create tables, create indexes, reset sequences,
     workers = 4, concurrency = 1,
     multiple readers per thread, rows per range = 500,
     prefetch rows = 1000, batch size = 10MB, batch rows = 1000
ALTER SCHEMA 'db_name' RENAME TO 'public';

Вместо db_name подставьте название базы, а вместо mysql_user, mysql_password, pg_user, pg_password соответствующие значения.

Также обратите внимание на ALTER SCHEMA 'db_name' RENAME to 'public', вам здесь также надо заменить db_name, чтобы pgloader при создании таблиц создал их со схемой public, а не db_name.

Запуск миграции[править]

Стоит очистить кеш Drupal чтобы не мигрировать лишние таблицы.

Запустите миграцию, вызвав pgloader c указанием имени скрипта из пункта выше:

pgloader pgloader.lisp

Ошибки[править]

В процессе миграции вы увидите ошибки, если они будут или предупреждения.

У меня была только одна на счет индекса одного из полей.

Но если поставить модуль Schema, то он сверяет что в базе и что в схеме в Drupal и выводит разницу. Оказалось, что индексы pgloader создает с другими именами нежели Drupal и модуль Schema не находит нужные индексы и ругается на отсутствие индексов, хотя они есть, просто названы иначе.

Замена settings.php[править]

В sites/default/settings.php закомментируйте настройки базы к MySQL и добавьте к PostgreSQL:

$databases = array (
  'default' => array (
    'default' =>
       array (
         'database' => 'db_name',
         'username' => 'pg_user',
         'password' => 'pg_password',
         'host' => '127.0.0.1',
         'port' =>,
         'driver' => 'pgsql',
         'prefix' =>,
       ),
   ),
 );

Здесь столкнулся с багом, что настройки базы mysql нельзя просто изменить с 'default' на что-то другое и оставить их выше настроек pgsql, надо именно чтобы настройки pgsql шли первыми в массиве databases.