Перенос с MySQL на PostgreSQL на Linux (Kubuntu)
Долгое время в системе далеко, далеко...
Попытка переноса базы данных с MySQL на PostgreSQL. Вся документация, которую я прочитал, содержит подробные сведения о том, как перенести структуру. Я очень мало документировал миграцию данных. Схема имеет 13 таблиц (которые были успешно перенесены) и 9 ГБ данных.
Версия MySQL: 5.1.x
Версия PostgreSQL: 8.4.x
Я хочу использовать язык программирования R для анализа данных с помощью операторов выбора SQL; PostgreSQL имеет PL/R, но MySQL не имеет ничего (насколько я могу судить).
Новая надежда
Создайте расположение базы данных (/var
не хватает места, а также не нравится, что версия версии PostgreSQL повсюду - обновление приведет к поломке скриптов!):
-
sudo mkdir -p /home/postgres/main
-
sudo cp -Rp /var/lib/postgresql/8.4/main /home/postgres
-
sudo chown -R postgres.postgres /home/postgres
-
sudo chmod -R 700 /home/postgres
-
sudo usermod -d /home/postgres/ postgres
Все хорошо здесь. Затем перезапустите сервер и настройте базу данных с помощью этих инструкций по установке:
-
sudo apt-get install postgresql pgadmin3
-
sudo /etc/init.d/postgresql-8.4 stop
-
sudo vi /etc/postgresql/8.4/main/postgresql.conf
- Измените
data_directory
на /home/postgres/main
-
sudo /etc/init.d/postgresql-8.4 start
-
sudo -u postgres psql postgres
-
\password postgres
-
sudo -u postgres createdb climate
-
pgadmin3
Используйте pgadmin3
для настройки базы данных и создания схемы.
Эпизод продолжается в удаленной оболочке, известной как bash
, при запуске обеих баз данных и установке набора инструментов с довольно необычным логотипом: SQL Fairy.
-
perl Makefile.PL
-
sudo make install
-
sudo apt-get install perl-doc
(как ни странно, он не называется perldoc
)
-
perldoc SQL::Translator::Manual
Извлеките DDL, совместимый с PostgreSQL, и все данные MySQL
:
-
sqlt -f DBI --dsn dbi:mysql:climate --db-user user --db-password password -t PostgreSQL > climate-pg-ddl.sql
- Измените
climate-pg-ddl.sql
и преобразуйте идентификаторы в нижний регистр и вставьте ссылку схемы (используя VIM):
-
:%s/"\([A-Z_]*\)"/\L\1/g
-
:%s/ TABLE / TABLE climate./g
-
:%s/ on / on climate./g
-
mysqldump --skip-add-locks --complete-insert --no-create-db --no-create-info --quick --result-file="climate-my.sql" --databases climate --skip-comments -u root -p
Возможно, стоит просто переименовать таблицы и столбцы в MySQL в нижний регистр:
-
select concat( 'RENAME TABLE climate.', TABLE_NAME, ' to climate.', lower(TABLE_NAME), ';' ) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='climate';
- Выполните команды с предыдущего шага.
- Возможно, есть способ сделать то же самое для столбцов; Я изменил их вручную, потому что это было быстрее, чем выяснить, как написать запрос.
База данных наносит ответный удар
Восстановите структуру в PostgreSQL следующим образом:
-
pgadmin3
(переключитесь на него)
- Нажмите Выполнить произвольные запросы SQL
- Открыть
climate-pg-ddl.sql
- Найдите
TABLE "
замените на TABLE climate."
(введите имя схемы climate
)
- Найдите
on "
замените на on climate."
(введите имя схемы climate
)
- Нажмите
F5
для выполнения
Это приводит к:
Query returned successfully with no result in 122 ms.
Ответы джедая
В этот момент я в тупике.
- Где я могу перейти отсюда (каковы шаги) для преобразования
climate-my.sql
в climate-pg.sql
, чтобы они могли быть выполнены против PostgreSQL?
- Как я уверен, что индексы скопированы правильно (для поддержания ссылочной целостности, у меня нет ограничений на данный момент, чтобы облегчить переход)?
- Как я могу гарантировать, что добавление новых строк в PostgreSQL начнет перечисляться из индекса последней вставленной строки (и не конфликтует с существующим первичным ключом из последовательности)?
- Как вы гарантируете, что имя схемы появляется при преобразовании данных из MySQL в PostgreSQL вставки?
Ресурсы
Для достижения этой цели понадобилась справедливая информация:
Спасибо!
Ответы
Ответ 1
То, что я обычно делаю для таких миграций, является двукратным:
- Извлечь все определение базы данных из MySQL и адаптировать его к синтаксису PostgreSQL.
- Перейдите по определению базы данных и преобразуйте его, чтобы воспользоваться функциональностью в PostgreSQL, которая не существует в MySQL.
Затем выполните преобразование и напишите программу на любом языке, который вам наиболее удобен, выполнив следующее:
- Считывает данные из базы данных MySQL.
- Выполняет любое преобразование, необходимое для хранения данных в базе данных PostgreSQL.
- Сохраняет теперь преобразованные данные в базе данных PostgreSQL.
Редизайн таблиц для PostgreSQL, чтобы воспользоваться его возможностями.
Если вы просто сделаете что-то вроде sed
script для преобразования дампа SQL из одного формата в следующий, все, что вы делаете, это поместить базу данных MySQL на сервер PostgreSQL. Вы можете это сделать, и от этого все равно будет какая-то польза, но если вы собираетесь мигрировать, полностью переносите.
Это потребует немного больше времени, затраченного на фронт, но мне еще предстоит столкнуться с ситуацией, когда это не стоит.
Ответ 2
Преобразование файла mysqldump в формат PostgreSQL
Преобразуйте данные следующим образом (не используйте mysql2pgsql.perl):
-
Сбросьте кавычки.
sed "s/\\\'/\'\'/g" climate-my.sql | sed "s/\\\r/\r/g" | sed "s/\\\n/\n/g" > escaped-my.sql
-
Замените USE "climate";
на путь поиска и прокомментируйте комментарии:
sed "s/USE \"climate\";/SET search_path TO climate;/g" escaped-my.sql | sed "s/^\/\*/--/" > climate-pg.sql
-
Подключиться к базе данных.
sudo su - postgres
psql climate
-
Установите кодировку (mysqldump игнорирует свой параметр кодирования), а затем выполните script.
\encoding iso-8859-1
\i climate-pg.sql
Эта серия шагов, вероятно, не будет работать для сложных баз данных со многими смешанными типами. Однако он работает для integer
s, varchar
s и float
s.
Индексы, первичные ключи и последовательности
Так как mysqldump
включал первичные ключи при создании операторов INSERT
, они будут превзойти автоматическую последовательность таблицы. После проверки последовательности для всех таблиц остались 1.
Задайте последовательность после импорта
Использование команды ALTER SEQUENCE
установит их в любое значение.
Префикс схемы
Нет необходимости префиксных таблиц с именем схемы. Использование:
SET search_path TO climate;
Ответ 3
Если вы преобразовали схему, то миграция данных будет легкой частью:
-
dump schema из PostgreSQL (вы сказали, что вы преобразовали схему в postgres, поэтому сейчас мы будем ее выгружать, поскольку мы будем удалять и воссоздавать целевую базу данных, чтобы очистить ее):
pg_dump dbname > /tmp/dbname-schema.sql
-
разделите схему на 2 части - /tmp/dbname-schema-1.sql
, содержащие инструкции create table, /tmp/dbname-schema-2.sql
- остальные. PostgreSQL необходимо импортировать данные, прежде чем импортировать внешние ключи, триггеры и т.д., Но после импорта таблиц.
-
воссоздайте базу данных только с одной частью схемы:
drop database dbname
create database dbname
\i /tmp/dbname-schema-1.sql
-- now we have tables without data, triggers, foreign keys etc.
-
импортировать данные:
(
echo 'start transaction';
mysqldump --skip-quote-names dbname | grep ^INSERT;
echo 'commit'
) | psql dbname
-- now we have tables with data, but without triggers, foreign keys etc.
В MySQL 5.1.3 добавлена опция < <22 > , поэтому, если у вас установлена более старая версия, то временно установите более новую mysql в /tmp/mysql
(configure --prefix=/tmp/mysql && make install
) и используйте /tmp/mysql/bin/mysqldump
.
-
импортировать остальную часть схемы:
psql dbname
start transaction
\i /tmp/dbname-schema-2.sql
commit
-- we're done
Ответ 4
Отъезд etlalchemy. Он позволяет вам перейти с MySQL на PostgreSQL или между несколькими другими базами данных в 4 строках Python. Вы можете прочитать об этом здесь.
Для установки: pip install etlalchemy
Для запуска:
from etlalchemy import ETLAlchemySource, ETLAlchemyTarget
# Migrate from MySQL to PostgreSQL
src = ETLAlchemySource("mysql://user:[email protected]/dbname")
tgt = ETLAlchemyTarget("postgresql://user:[email protected]/dbname",
drop_database=True)
tgt.addSource(src)
tgt.migrate()