Перенос таблицы в другую базу данных postgres без простоя приложения
В продолжении темы о нескольких базах данных в одном rails-приложении расскажу о том, как изящно перенести одну большую таблицу в другую БД postgresql.
Пусть у нас есть таблица messages с большим количеством данных (10 миллионов записей), которые мы решили перенести на другой сервер. Мы сделали, как написано в статье, указанной выше, а также создали в новой БД таблицу messages с такой же структурой.
Теперь с помощью londiste настраиваем репликацию из первой БД во вторую для таблицы messages (об этом я напишу подробнее попозже, пока же можно прочитать об этом у Андрея Стихеева в рассылке ror2ru).
После того, как прошла синхронизация, во второй БД выполняем следующее:
SELECT setval('messages_id_seq', (SELECT max(id) FROM messages) + 1000000)
Перезапускаем приложение. После этого какое-то время у нас будут существовать старая и новая версия приложения. Старая версия будет писать в старую базу — эти данные накатятся с помощью репликации, новая версия будет писать в новую базу. За счет того, что id записей не будут пересекаться, эта позволит сделать перенос таблицы не останавливая приложения.
После того, как londiste londiste.ini replay будет показывать достаточно долго count: 0, то есть, когда не останется thin (mongrel) серверов, которые пишут в старую базу данных, репликацию можно остановить и отключить.
Конечно, будет существовать такой короткий момент времени, когда не все данные будут доступны нужному приложению (старый thin попытается считать новую запись, либо новый thin попытается считать старую запись, которая еще не докатилась репликацией). В нашей ситуации такими случаями можно было принебречь.
Буквально вчера я проделал такую операцию для 4-х больших таблиц сразу (миллионы записей в каждой). Простой приложения при такой выкатке оказался таким же, как обычно. В случае же, если останавливать приложение, делать backup этих таблиц и подымать его на новой БД, было бы хорошо, если бы мы уложились в час.