Репликация Postgresql 9.0 (Master/Slave)

Ответить
Аватара пользователя
Raven
Бородатый сис
Бородатый сис
Сообщения: 2800
Зарегистрирован: 03 мар 2010, 15:12
ОС: RHEL 8
Откуда: Из серверной

Репликация Postgresql 9.0 (Master/Slave)

Сообщение Raven » 25 авг 2011, 10:25

Возникла у меня необходимость завязать 2 сервера слона таким образом, чтобы данные синхронизировались на 2 серверах... Но к сожалению у PostgreSQL хотя и много вкусностей, синхронизация в версиях 8.x (а именно такая у меня на Оракле и стояла) возможна лишь при использовании сторонних утилит, таких как Slony-I или PgPool-II и пр. Перекопав несколько вариантов пришел к выводу, что Slony работает чисто на триггерах PgSQL, что мне абсолютно не улыбалось (+ ни о какой failover'ности речи не могло быть - максимум что я получил в результате - целостность данных), PgPool все время порывался завязать базы в режиме Master/Master (+ никаких потуг к синхронизации данных я за ним так и не заметил, зато лагов он мне насыпал... на всю жисть хватит!), от репликатора разработаного для сервера Skype я остался в шоке еще на стадии чтения документации - детально расписывать в базе все действия по запросам мне как-то не особо улыбалось. Наконец выяснилось что в 9-й версии pg появилась возможность репликации master/slave. А мне именно оно и было нужно!

Почему именно master/slave (горизонтальная репликация), почему не master/master? Потому, что именно такой вид репликации как мне кажется наиболее надежен. При репликациях типа master/master велика вероятность возникновения конфликтов одновременной записи (т.е. когда например 1 сервер вносит в ячейку Х скажем значение равное 100, а второй в то же самое время пытается вписать в нее же значение равное к примеру 200, и кто тогда из них прав?). Вот чтобы не разгребать всю эту кашу мой и была выбрана именно схема master/slave (что мешает в критический момент повернуть все вспять и поднять слейв вместо мастера? ;)

Итак, сносим все старье!

Код: Выделить всё

# yum remove postgresql postgresql-libs postgresql-server postgresql-plperl postgresql-contrib postgresql-pltcl postgresql-devel postgresql-odbc postgresql-test postgresql-docs postgresql-plpython postgresql-jdbc
Да, именно столько пакетов pg у меня и было установлено :)
Дергаем отсюда SRPM-пакетики для 6-го редхата:

Код: Выделить всё

# wget http://yum.postgresql.org/srpms/9.0/redhat/rhel-6Server-x86_64/postgresql90-9.0.4-1PGDG.rhel6.src.rpm
и пересобираем:

Код: Выделить всё

# rpmbuild --rebuild postgresql90-9.0.4-1PGDG.rhel6.src.rpm
после чего в папке $HOME/rpmbuild/RPMS/$arch находим готовые к установке rpm пакеты (думаю не стоит обьяснять как их установить))))

Чтож, предположим что СУБД установлена, создана база test1. Я буду описывать процесс исходя из того, что базы pg у меня лежат в /var/lib/postgresql/, если у вас они расположены не так — используйте корректный для вас путь.

Настраиваем мастер
* Предположим, что у ip мастера 192.168.10.1, а слейва — 192.168.10.2.
Правим строку listen в postgresql.conf:

Код: Выделить всё

listen_addresses = '*' 
(ибо как сказано в каментах postgresql.conf слушаются либо все, либо локалхост)

В конец pg_hba.conf вносим такие строки:

Код: Выделить всё

host   al  l all   192.168.10.1/32   trust
host   all   all   192.168.10.2/32   trust
Теперь собственно к репликации

Код: Выделить всё

# Указываем вести журнал таким образом, чтобы слейв мог использоваться для чтения. Можно вместо [i]hot_standby[/i] поставить [i]archive[/i] и тогда он будет просто хранилищем журанала(нечитаемым).
 wal_level = hot_standby

 #Определим максимальное количество слейвов
 max_wal_senders = 2

 #Сколько кусков лога будем хранить?Если вдруг у вас большая нагрузка на запись в базу - возможно это значение нужно будет увеличить, чтобы всё успевало доезжать до реплики.
 wal_keep_segments = 32

 #На случай ядерной войны дублируем журнал в отдельное место(лучше чистить по крону эту локацию, удаляя всё, чему больше суток). Хотя, офф. ман говорит, что оно вообще не обязательно.
 archive_mode = on
 archive_command = 'cp %p /var/lib/postgresql/backup/%f'
Теперь мастер нужно перезапустить.

Переносим базу на слейв
Нам потребуется что-нибудь, что умеет пересылать данные по сети. Я обошелся scp, хотя, разумеется, можно применять любое другое средство. Вырубим на слейве postgresql, сохраняем бекапы всех конфигов из папки /var/lib/postgresql, после чего на мастере выполняем следующее:

Код: Выделить всё

#su - postgres
$ psql -c "SELECT pg_start_backup('label', true)"
$ scp -rp /var/lib/postgresql root@192.168.10.2:/var/lib/postgresql
$ psql -c "SELECT pg_stop_backup()"
Возвращаем конфиги слейва на место за исключением pg_hba.conf (тут сойдет и от мастера).

Настраиваем слейв
Правим postgresql.conf:

Код: Выделить всё

listen_addresses = '*'
hot_standby = on
Создаем конфиг репликации на слейве /var/lib/postgresql/recovery.conf куда вписываем следующее:

Код: Выделить всё

standby_mode = 'on'
primary_conninfo = 'host=192.168.0.1 port=5432 user=postgres'
trigger_file = '/var/lib/postgresql/trigger'
restore_command = 'cp /var/lib/postgresql/backup/%f "%p"'
Что же такое trigger_file? В нормальном режиме работы его нет и быть не должно. Но он нужен в том случае, когда падает мастер, чтобы остановить процесс репликации и сделать слейв доступным на запись, т.е. если мы создадим этот файл ноды разделятся и мы получим 2 независимых мастера.

Запускаем слейв и проверяем репликацию - смотрим вывод ps aux, если там имеется процесс postgres: wal receiver process, значит мы сделали все правильно, и базы реплицируются.
Я не злопамятный, я просто часто ковыряю логи
Ответить

Вернуться в «PostgreSQL»