Bucardo: Multimaster репликация

от автора

В процессе мучений перелопатил тонну статей и решил написать подробнокомментируемый мануал. Тем более, что информации по конфигурированию multimaster и на русском языке очень мало и она какая-то кусочная.

Немного вводной. Чтобы Bucardo заработал, мы должы:
1) Сказать ему какие базы-участники на каких серверах вообще существуют.
2) Сказать ему какие таблицы участвуют в репликации.
Внимание: если разработчики добавят в приложение новую таблицу, мы должны об этом сообщить bucardo.
Тоже самое касается изменения схемы существующих таблиц.

3) Сказать ему какие группы таблиц существуют и какие таблицы попадают в какие группы. Группы нужны на тот случай, если между разными серверами надо реплицировать разные таблицы. Удобнее работать с группой, чем каждую отдельно указывать (очень похоже на группы в Nagios).
4) Сказать ему какие группы баз данных существуют. Цель — та же, что и для таблиц.

Перейдем к установке. Вариант для Debian 7.

Подразумевается, что пакеты postgresql-9.1 и postgresql-client-9.1 уже установлены.

Предварительная подготовка.

Серверы будут называться node1 и node2.

Обязательно также проверить, чтобы все участвующие PostreSQL-серверы слушали внешние интерфейсы:

# netstat -plnt4 | grep 5432 tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      12345/postgres 

Устанавливаем пакет Bucardo и поддержку PL/Perl для PostgreSQL на каждом из серверов:

# apt-get install bucardo postgresql-plperl-9.1

Активируем на каждом из серверов:

# sed -i 's/ENABLED=0/ENABLED=1/' /etc/default/bucardo

Мейнтенеры пакета почему-то не догадались создать директорию под PID, поэтому создадим ее сами на каждом из серверов:

# mkdir /var/run/bucardo

Удостоверяемся, что мы можем подключиться через TCP-сокет к СУБД на каждом из серверов:

# psql -U postgres -h 127.0.0.1

Если не помните пароль, то простейшая инструкция здесь.
Если PG не хочет принимать запросы с конкретного адреса конкретного пользователя, то настройте /etc/postgresql/9.1/main/pg_hba.conf

Далее будет происходить инициализация базы. Она будет создана пользователем postgres, но наполнена пользователем bucardo, поэтому можно упереться в проблему подключения.
Дабы ее избежать, заранее внесем строку для него в /etc/postgresql/9.1/main/pg_hba.conf. Кроме того, уже в процессе работы Bucardo будет обращаться не только к своей ноде кластера, но и к парной. Поэтому ее тоже не забываем. Если у Вас в кластере серверов больше, то не забудьте о них. На каждом из серверов:

host    all             bucardo         127.0.0.1/32              trust host    all             bucardo         SECOND.NODE.IP.ADDRESS/32 password

После этого рестартанем СУБД:

# pg_ctlcluster 9.1 main restart
Установка Bucardo.

Утилита bucardo_ctl в последних версиях Debian была заменена на bucardo, поэтому мы будем использовать ее.
Инициализируем базу данных:

# bucardo install

Диалог выглядит примерно так:

# bucardo install This will install the bucardo database into an existing Postgres cluster. Postgres must have been compiled with Perl support, and you must connect as a superuser  Current connection settings: 1. Host:           localhost 2. Port:           5432 3. User:           postgres 4. Database:       postgres 5. PID directory:  /var/run/bucardo Enter a number to change it, P to proceed, or Q to quit: P  Password for user postgres: Postgres version is: 9.1 Password for user postgres: Creating superuser 'bucardo' Password for user postgres: Attempting to create and populate the bucardo database and schema Password for user postgres: Database creation is complete  Updated configuration setting "piddir" Installation is now complete. If you see errors or need help, please email bucardo-general@bucardo.org  You may want to check over the configuration variables next, by running: bucardo show all Change any setting by using: bucardo set foo=bar

В процесс инициализации база была создана из файла /usr/share/bucardo/bucardo.schema, поэтому нет необходимости ее заполнять руками, как это описано в мануалах прошлых версий.

Bucardo установлен, можно его запустить:

# bucardo start
Настройка репликации.

Прежде, чем настроить репликацию, создадим тестовые базы, которые будем реплицировать.
На каждом из серверов:

# psql -U postgres -c "CREATE DATABASE mydb;" # psql -U postgres mydb -c "CREATE TABLE mytable ( num123 integer PRIMARY KEY, abc varchar(10) );"

Еще один важный момент касательно безопасности. После добавления реплицируемой базы в настройку, Bucardo впишет пароль пользователя в базу. А так как при установке он его не запросил, то сделал его точно таким же, как у пользователя postgres. Другими словами у нас в базе bucardo будет храниться в открытом виде пароль от суперпользователя, что несколько опасно.
Поэтому сделаем ему другой пароль. На каждом из серверов:

# psql -U postgres -c "ALTER USER bucardo WITH PASSWORD 'eiP4uSash5';"

Далее даем информацию Bucardo, как подключиться к базе данных, которую будем реплицировать. Я не поклонник Unix-сокетов в условиях высокой нагрузки (отдельная тема для разговора), поэтому даже там, где локально, укажем TCP-сокет.

ВНИМАНИЕ: Это мы делаем на сервере node1. И вообще далее работаем только с node1 пока не уточнено, что надо делать на обоих.

Добавим локальную (mydb_node1) и ее удаленную копию (mydb_node2) с сервера node2:

# bucardo add database mydb_node1 dbname=mydb dbhost=127.0.0.1 dbuser=bucardo dbpass=eiP4uSash5 Added database "mydb_node1"

# bucardo add database mydb_node2 dbname=mydb dbhost=node2.example.com dbuser=bucardo dbpass=eiP4uSash5 Added database "mydb_node2"

Здесь:
mydb_nodeX — внутренее обозначение базы. Это имя Bucardo использует во внутренних работах с базой.
dbname=mydb — реальное имя базы в PostgreSQL, на которое ссылается mydb_nodeX.
dbuser=bucardo — под кем Bucardo будет подключаться к СУБД, чтобы работать с этой базой.

Результат мы можем видеть так:

# bucardo list database Database: mydb_node1  Status: active  Conn: psql -p  -U bucardo -d mydb -h 127.0.0.1 Database: mydb_node2  Status: active  Conn: psql -p  -U bucardo -d mydb -h node2.example.com

Эти настройки берутся из таблицы db базы bucardo, где и сидит упомянутый выше пароль:

# psql -U postgres bucardo -c "SELECT name,dbname,dbhost,dbuser,dbpass,status FROM db;"     name    | dbname |      dbhost       | dbuser  |   dbpass   | status ------------+--------+-------------------+---------+------------+--------  mydb_node1 | mydb   | 127.0.0.1         | bucardo | eiP4uSash5 | active  mydb_node2 | mydb   | node2b.forbet.net | bucardo | eiP4uSash5 | active (2 rows) 

Теперь нам надо добавить таблицу, которую мы будем между ними реплицировать. В большинстве случаев люди реплицируют целиком базу, поэтому уж сразу все добавим (группа таблиц(herd) создастся автоматически). Если разработчики придумают новую таблицу, мы просто добавим ее потом в группу и все само заработает — так как дальнейшие настройки будут касаться группы целиком.

# bucardo add table all --db=mydb_node1 --herd=mydb_herd Creating herd: mydb_herd Added table public.mytable to herd mydb_herd New tables added: 1

Здесь:
—herd=mydb_herd — имя группы таблиц, чтобы потом настраивать синхронизацию не к каждой отдельно, а всем скопом.

И сразу можем ее посмотреть:

# bucardo list tables 1. Table: public.mytable  DB: mydb_node1  PK: num123 (int4) Здесь нужно заострить внимание на PK. Bucardo, похоже, не работает с таблицами без первичных ключей. Вы потом не сможете синк сделать. 

И группу тоже видно:

# bucardo list herd Herd: mydb_herd  DB: mydb_node1  Members: public.mytable

Тоже самое касается последовательностей. В нашем примере их нет, но вдруг кто использует. Группу под них свою создавать не будем, чтобы не усложнять. Вероятность того, что таблицы реплицируются в одном направлении, а последовательности в другом — чрезвычайно мала. Поэтому пусть будет одна группа для таблиц и последовательностей:

# bucardo add sequence all --db=mydb_node1 --herd=mydb_herd Sorry, no sequences were found New sequences added: 0 

Следующая наша задача создать репликационную группу. В этой группе мы скажем какая база будет источником, а какая реципиентом данных. Создадим сначала саму группу, пока пустую:

# bucardo add dbgoup other_mydb_servers Created database group "mydb_servers_group"

Добавляем оба наших сервера в группу, указывая кто какую роль будет исполнять. Это единственная точка, где отличаеся настройка master-slave от master-master.
Изначально можно подумать, что source — это источник, а target — это реципиент. На самом деле это не совсем так. source — это тот, кто работает и как источник и как реципиент, а target — только реципиент.
То есть если у нас master-slave, то указываем одного source, а второго target. А если у нас master-master, то оба будут source, а target’ов не будет вообще.

Вариант для MASTER—>SLAVE:

# bucardo add dbgroup mydb_servers_group mydb_node1:source Added database "mydb_node1" to group "mydb_servers_group" as source  # bucardo add dbgroup mydb_servers_group mydb_node2:target Added database "mydb_node2" to group "mydb_servers_group" as target
Вариант для MASTER<—>MASTER:

# bucardo add dbgroup mydb_servers_group mydb_node1:source Added database "mydb_node1" to group "mydb_servers_group" as source  # bucardo add dbgroup mydb_servers_group mydb_node2:source Added database "mydb_node2" to group "mydb_servers_group" as source

Все! У нас написано какие есть базы. Написано какие есть в них таблицы. Написано кто в какой группе. Осталось сказать заключительный штрих — сказать какая группа таблиц будет «курсировть» между базами какой группы. Другими словами — создать «синк»:

# bucardo add sync mydb_sync herd=mydb_herd dbs=mydb_servers_group Added sync "mydb_sync"

Можем посмотреть, что у нас получилось:

# bucardo list sync Sync: mydb_sync  Herd: mydb_herd [Active]   DB group mydb_servers_group: mydb_node1 (source) mydb_node2 (source или target - как настроили)

После изменения настроек обязательно рестартовать Bucardo:

# bucardo restart

========

Проверка:

на первой ноде node1 запускаем:

# psql -U postgres mydb -c "INSERT INTO mytable VALUES (1, 'a');"

а на второй node2 проверяем:

# psql -U postgres mydb -c "SELECT * FROM mytable;"

кто сделал multimaster, тому надо и в обратном направлении проверять. Создаете на node2, а проверяете на node1.

========

Вопросы, которые возникнут у большинства людей:
1) Что будет с таблицей на target-базе, если таблица на source-базе была изменена пока Bucardo был выключен или сеть была недоступна?

Ответ: все Ok. При старте или при появлении сети Bucardo передаст данные на target-сервер. Так что target-сервер может ломаться как угодно. Единственное требование — на нем должна быть та же схема данных (структура таблиц), что и на первом.
__
2) Если база большая (десятки-сотни гигабайт), Bucardo «отламывается» и не синхронизирует до конца. Как быть?

Ответ: переведите sync в состояние неактивного. Но Bucardo должен быть включен для source-базы для логивания запросов.
bucardo update sync mydb_sync status=inactive (для multimaster на всех нодах)
Далее делаете pg_dump/pg_restore руками и возвращаете синк в активный режим (для multimaster сначала на той, куда шли новые запросы после запуска дампа).
ссылка на оригинал статьи https://habrahabr.ru/post/327674/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *