Если столбца который мог бы стать primary key не находится, добавьте новый столбец типа serial (ALTER TABLE ADD COLUMN), и заполните его значениями. Настоятельно НЕ рекомендую использовать «table add key» slonik-a.
Продолжаем. Создаём таблицы и всё остальное на slave:
slony@customers_master$ pg_dump -s customers | \ psql -U slony -h customers_slave.com customers
pg_dump -s сдампит только структуру нашей БД.
pg_dump -s customers должен пускать без пароля, а вот для psql -U slony -h customers_slave.com customers придётся набрать пароль (slony_user_pass). Важно: я подразумеваю что сейчас на мастер-хосте ещё не установлен Slony (речь не про make install), то есть в БД нет таблиц sl_*, триггеров и прочего. Если есть, то возможно два варианта:
добавляется узел в уже функционирующую систему репликации (читайте раздел 5);
это ошибка :-) Тогда до переноса структуры на slave выполните следующее:slonik «EOF cluster name = customers_slave; node Y admin conninfo = 'dbname=customers host=customers_master.com port=5432 user=slony password=slony_user_pass'; uninstall node (id = Y); echo 'okay'; EOF
Y число. Любое. Важно: если это действительно ошибка, cluster name может иметь какой-то другое значение, например T1 (default). Нужно его выяснить и сделать uninstall.
Если структура уже перенесена (и это действительно ошибка), сделайте uninstall с обоих узлов (с master и slave).
Инициализация кластера
Если Сейчас мы имеем два сервера PgSQL которые свободно «видят» друг друга по сети, на одном
из них находится мастер-база с данными, на другом только структура.
На мастер-хосте запускаем такой скрипт:
#!/bin/sh CLUSTER=customers_rep DBNAME1=customers DBNAME2=customers HOST1=customers_master.com HOST2=customers_slave.com PORT1=5432 PORT2=5432 SLONY_USER=slony slonik «EOF cluster name = $CLUSTER; node 1 admin conninfo = 'dbname=$DBNAME1 host=$HOST1 port=$PORT1 user=slony password=slony_user_password'; node 2 admin conninfo = 'dbname=$DBNAME2 host=$HOST2 port=$PORT2 user=slony password=slony_user_password'; init cluster ( id = 1, comment = 'Customers DB replication cluster' ); echo 'Create set'; create set ( id = 1, origin = 1, comment = 'Customers DB replication set' ); echo 'Adding tables to the subscription set'; echo ' Adding table public.customers_sales...'; set add table ( set id = 1, origin = 1, id = 4, full qualified name = 'public.customers_sales', comment = 'Table public.customers_sales' ); echo ' done'; echo ' Adding table public.customers_something...'; set add table ( set id = 1, origin = 1, id = 5, full qualified name = 'public.customers_something, comment = 'Table public.customers_something ); echo ' done'; echo 'done adding'; store node ( id = 2, comment = 'Node 2, $HOST2' ); echo 'stored node'; store path ( server = 1, client = 2, conninfo = 'dbname=$DBNAME1 host=$HOST1 port=$PORT1 user=slony password=slony_user_password' ); echo 'stored path'; store path ( server = 2, client = 1, conninfo = 'dbname=$DBNAME2 host=$HOST2 port=$PORT2 user=slony password=slony_user_password' ); store listen ( origin = 1, provider = 1, receiver = 2 ); store listen ( origin = 2, provider = 2, receiver = 1 ); EOF
Здесь мы инициализируем кластер, создаём репликационный набор, включаем в него две таблицы. Важно: нужно перечислить все таблицы, которые нужно реплицировать, id таблицы в наборе должен быть уникальным, таблицы должны иметь primary key.
Важно: replication set запоминается раз и навсегда. Чтобы добавить узел в схему репликации не нужно заново инициализировать set.
Важно: если в набор добавляется или удаляется таблица нужно переподписать все узлы. То есть сделать unsubscribe и subscribe заново.
Подписываем slave-узел на replication set
Скрипт:
#!/bin/sh CLUSTER=customers_rep DBNAME1=customers DBNAME2=customers HOST1=customers_master.com HOST2=customers_slave.com PORT1=5432 PORT2=5432 SLONY_USER=slony slonik «EOF cluster name = $CLUSTER; node 1 admin conninfo = 'dbname=$DBNAME1 host=$HOST1 port=$PORT1 user=slony password=slony_user_password'; node 2 admin conninfo = 'dbname=$DBNAME2 host=$HOST2 port=$PORT2 user=slony password=slony_user_password'; echo'subscribing'; subscribe set ( id = 1, provider = 1, receiver = 2, forward = no); EOF
Старт репликации
Теперь, на обоих узлах необходимо запустить демона репликации.
slony@customers_master$ slon customers_rep \ "dbname=customers user=slony"
и
slony@customers_slave$ slon customers_rep \ "dbname=customers user=slony"
Сейчас слоны обменяются сообщениями и начнут передачу данных. Начальное наполнение происходит с помощью COPY, slave DB на это время полностью блокируется.
В среднем время актуализации данных на slave-системе составляет до 10-ти секунд. slon успешно обходит проблемы со связью и подключением к БД, и вообще требует к себе достаточно мало внимания.
Общие задачи
Добавление ещё одного узла в работающую схему репликации
Выполнить [subsec:slonyI-settings-1] и выполнить [subsec:slonyI-settings-2].
Новый узел имеет id = 3. Находится на хосте customers_slave3.com, «видит» мастер-сервер по сети и мастер может подключиться к его PgSQL. После дублирования структуры (п [subsec:slonyI-settings].2) делаем следующее: