Показаны сообщения с ярлыком PostgreSQL. Показать все сообщения
Показаны сообщения с ярлыком PostgreSQL. Показать все сообщения

воскресенье, 13 ноября 2011 г.

PostgreSQL Slony - настройка асинхронной master/slave репликации


(ОС: Debian 6.0 x64, PostgreSQL 8.4, Slony 2.0)


Терминология:
  • кластер – набор баз данных;
  • нода – база данных, которая может быть распределена;
  • репликационный набор – набор таблиц, которые могут быть реплицированы между нодами кластера;
  • источник (или провайдер) и подписчик – у каждой репликации есть одна нода-источник, остальные ноды могут быть подписчиками;
  • slon – демон, присутствующий на каждой ноде и управляющий ее репликациями;
  • slonik – командная утилита для общего управления нодами.


Устанавливаем ПО на master сервер:

apt-get install postgresql-8.4 slony1-2-bin
(при инсталляции slony1-2-bin как рекомендательный пакет притянет в установку postgresql-8.4-slony1-2)

Устанавливаем ПО на slave сервер:

apt-get install postgresql-8.4 postgresql-8.4-slony1-2

Разрешаем на master сервере сетевые подключения с slave сервера, открываем /etc/postgresql/8.4/main/pg_hba.conf и прописываем

host    all         slony        172.16.0.101/16          md5

где slony это спец.пользователь из под которого будет действовать slony, а 172.16.0.101 это IP адрес slave сервера

Разрешаем на slave сервере сетевые подключения с master сервера, открываем /etc/postgresql/8.4/main/pg_hba.conf и прописываем


host    all         slony        172.16.0.102/16          md5

где slony это спец.пользователь из под которого будет действовать slony, а 172.16.0.102 это IP адрес master сервера

На обоих серверах в /etc/postgresql/8.4/main/postgresql.conf

listen_addresses = '*'


Создаем postgres пользователя slony на обоих серверах и выдаем ему привилегии суперпользователя (такие привилегии это требования самого slony)

postgres=# create user slony with password 'slony_pass';
postgres=# alter user slony createuser;


Создаем целевую базу (ту которую планируем реплицировать) на master сервере и импортируем в нее данные

postgres=# create database of_db;
root@postgresql-1:~# psql -U postgres -f of_db.sql of_db


включаем поддержку pl/pgsql для этой базы

root@postgresql-1:~# createlang -U postgres -d of_db plpgsql


в данном примере будем реплицировать несколько таблиц, ofvcard и ofuserprop вышеозвученной базы, смотрим наличие индексов у этих таблиц


of_db=# \d ofvcard;
            Table "public.ofvcard"
  Column  |         Type          | Modifiers
----------+-----------------------+-----------
 username | character varying(64) | not null
 vcard    | text                  | not null
Indexes:
    "ofvcard_pk" PRIMARY KEY, btree (username)


of_db=# \d ofuserprop;
           Table "public.ofuserprop"
  Column   |          Type          | Modifiers
-----------+------------------------+-----------
 username  | character varying(64)  | not null
 name      | character varying(100) | not null
 propvalue | text                   | not null
Indexes:
    "ofuserprop_pk" PRIMARY KEY, btree (username, name)


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

Теперь на slave сервере создаем базу данных, таблицы которой в дальнейшем будут реплицироваться


postgres=# create database of_db;

включаем поддержку pl/pgsql и для этой базы


root@postgresql-2:~# createlang -U postgres -d of_db plpgsql


на master сервере выполняем экспорт структуры базы и импортируем ее на slave сервер в одноименную базу

root@postgresql-1:~#pg_dump -U postgres -s of_db > of_db.sql
root@postgresql-2:~# psql -U postgres -f of_db.sql of_db



теперь можно с помощью утилиты slonik инициализировать наш кластер, slonik это cli утилита принимающая команды с файла или stdin

создаем аналогичный скрипт и запускаем его на master сервере

#!/bin/bash


slonik <<_EOF_
    cluster name = simple_cluster;
    node 1 admin conninfo = 'dbname=of_db host=172.16.0.102 user=slony password=slony_pass';
    node 2 admin conninfo = 'dbname=of_db host=172.16.0.101 user=slony password=slony_pass';
    
    init cluster ( id=1, comment = 'Master Node');


    create set (id=1, origin=1, comment='of_db replication set');
    set add table (set id=1, origin=1, id=1, fully qualified name = 'public.ofvcard', comment='card');
    set add table (set id=1, origin=1, id=2, fully qualified name = 'public.ofuserprop', comment='prop');
    
    store node (id=2, comment = 'Slave node', event node=1);
    store path (server = 1, client = 2, conninfo='dbname=of_db host=172.16.0.102 user=slony password=slony_pass');
    store path (server = 2, client = 1, conninfo='dbname=of_db host=172.16.0.101 user=slony password=slony_pass');
_EOF_

после его выполнения запускаем следующий скрипт, который подпишет slave сервер на репликационный набор

#!/bin/bash


slonik <<_EOF_
     cluster name = simple_cluster;
     node 1 admin conninfo = 'dbname=of_db host=172.16.0.102 user=slony password=slony_pass';
     node 2 admin conninfo = 'dbname=of_db host=172.16.0.101 user=slony password=slony_pass';


     subscribe set ( id = 1, provider = 1, receiver = 2, forward = no);
_EOF_


готово, теперь на master сервере прописываем настройки в конфиг.файлы slony, сначала в /etc/slony1/slon_tools.conf


if ($ENV{"SLONYNODES"}) {
    require $ENV{"SLONYNODES"};
} else {
    $CLUSTER_NAME = 'simple_cluster';
    $LOGDIR = '/var/log/slony1';
    $MASTERNODE = 1;
    $DEBUGLEVEL = 2;
    add_node(node     => 1,
             host     => '172.16.0.102',
             dbname   => 'of_db',
             port     => 5432,
             user     => 'slony',
             password => 'slony_pass');
    add_node(node     => 2,
             host     => '172.16.0.101',
             dbname   => 'of_db',
             port     => 5432,
             user     => 'slony',
             password => 'slony_pass');
}
$SLONY_SETS = {
    "set1" => {
        "set_id"       => 1,
        "table_id"     => 1,
        "pkeyedtables" => ["public.ofvcard", "public.ofuserprop"],
    },
};
if ($ENV{"SLONYSET"}) {
    require $ENV{"SLONYSET"};
}
1;


потом в файл /etc/default/slony1 прописываем ноды

SLON_TOOLS_START_NODES="1 2"

запускаем slon'а

invoke-rc.d slony1 start


Видим что к реплицируемым таблицам добавились триггеры

of_db=# \d ofvcard;
            Table "public.ofvcard"
  Column  |         Type          | Modifiers
----------+-----------------------+-----------
 username | character varying(64) | not null
 vcard    | text                  | not null
Indexes:
    "ofvcard_pk" PRIMARY KEY, btree (username)
Triggers:
    _simple_cluster_logtrigger AFTER INSERT OR DELETE OR UPDATE ON ofvcard FOR EACH ROW EXECUTE PROCEDURE _simple_cluster.logtrigger('_simple_cluster', '1', 'k')
Disabled triggers:
    _simple_cluster_denyaccess BEFORE INSERT OR DELETE OR UPDATE ON ofvcard FOR EACH ROW EXECUTE PROCEDURE _simple_cluster.denyaccess('_simple_cluster')


of_db=# \d ofuserprop;
           Table "public.ofuserprop"
  Column   |          Type          | Modifiers
-----------+------------------------+-----------
 username  | character varying(64)  | not null
 name      | character varying(100) | not null
 propvalue | text                   | not null
Indexes:
    "ofuserprop_pk" PRIMARY KEY, btree (username, name)
Triggers:
    _simple_cluster_logtrigger AFTER INSERT OR DELETE OR UPDATE ON ofuserprop FOR EACH ROW EXECUTE PROCEDURE _simple_cluster.logtrigger('_simple_cluster', '2', 'kk')
Disabled triggers:
    _simple_cluster_denyaccess BEFORE INSERT OR DELETE OR UPDATE ON ofuserprop FOR EACH ROW EXECUTE PROCEDURE _simple_cluster.denyaccess('_simple_cluster')


Проверяем работу репликации, на master сервере добавляем/удаляем какие нибудь данные в наших целевых таблицах и проверяем чтобы эти данные синхронизировались и в базе на slave сервере. Если все хорошо, то на этом тестовая настройка репликации закончена.

среда, 2 ноября 2011 г.

PgBouncer легкий пул коннектов для PostgreSQL

Преимущество использования пула коннектов это существенное снижение нагрузки на Postgresql сервера, такие дорогостоящие для сервера действия как постоянное открытие/закрытие коннектов, общее управление коннектами, частично ложатся на плечи Pgbouncer. Кроме этого важен тот дополнительный функционал, которые привносит Pgbouncer сам по себе.

Достоинства Pgbouncer

  • Малое потребление оперативной памяти
  • Отсутствие жесткой привязки к одному backend серверу, соответственно сервера назначения могут располагаться на разных хостах
  • Поддержка реконфигурации большинства настроек без перезапуска
  • Поддержка онлайн перезапуска

Установка

(ОС: Debian 6.0 x64)

apt-get install pgbouncer

самый простой пример настроек /etc/pgbouncer/pgbouncer.ini для доступа к БД of_db под именем pseudo_db в пуле

[databases]
pseudo_db = host=127.0.0.1 port=5432 dbname=of_db

[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
admin_users = pgb_admin

добавляем пользователя в файл /etc/pgbouncer/userlist.txt, логин и пароль необходимо указывать точно такие же как и у реальных аккаунтов в Postgresql

"postgres" "md553f48b7c4b76a86ce72276c5755f217d"

включаем в /etc/default/pgbouncer сам Pgbouncer

START=1

запускаем его

invoke-rc.d pgbouncer start

проверяем его работу, коннектимся Postgresql клиентом к пулу, если все хорошо, то выходим и смотрим процессы и сетевую активность. Несмотря на то что мы отключились Pgbouncer продолжает поддерживать коннект к серверу, продолжительность поддержки коннекта зависит от настроек Pgbouncer

postgres  4030  0.0  0.1 102280  1524 ?        Ss   12:23   0:00  \_ postgres: wal writer process
postgres  4031  0.0  0.1 102556  1892 ?        Ss   12:23   0:00  \_ postgres: autovacuum launcher process
postgres  4032  0.0  0.1  73960  1572 ?        Ss   12:23   0:00  \_ postgres: stats collector process
postgres  5478  0.0  0.3 103608  4840 ?        Ss   13:36   0:00  \_ postgres: postgres of_db 127.0.0.1(38636) idle

tcp        0      0 127.0.0.1:38636         127.0.0.1:5432          ESTABLISHED 5217/pgbouncer

вторник, 1 ноября 2011 г.

PostgreSQL сумбурные записи

(ОС: FreeBSD)


Включение SSL шифрования для подключений IPv4 к PostgreSQL с аутентификацией по логину и паролю

Приводим указанный конфиг к такому виду /usr/local/pgsql/data/pg_hba.conf
# "local" is for Unix domain socket connections only
local   all             all                                     password
# IPv4 local connections:
#host    all             all             127.0.0.1/32            password
hostssl    all             all             0.0.0.0/0            password
# IPv6 local connections:
# host    all             all             ::1/128                 trust
В postgresql.conf выставляем
ssl = on
Генерируем сертификаты, ключи и выставляем на них необходимые права
cd /usr/local/pgsql/data

openssl req -x509 -nodes -newkey rsa:1024 -days 3650 -keyout server.key -out server.crt

chown pgsql:pgsql server.key
chown pgsql:pgsql server.crt

chmod 600 server.key
chmod 600 server.crt
Некоторые команды
\c <name_db> - подключиться к базе данных
\dt - вывести список всех таблиц текущей выбранной базы
\l - вывести список всех баз данных

select * from pg_user; - вывести список всех пользователей
select * from pg_shadow; - вывести список всех пользователей и их пароли

ALTER USER pgsql WITH PASSWORD 'new_pass'; - сменить пароль пользователю "pgsql"
Создание пользователей и настройка их параметров
create user tom
with password 'password'; - создание пользователя tom с паролем

create user tom createdb
with password 'password' valid until '2011-01-01'; - создание пользователя tom с правами на создание новых баз данных и паролем истекающим 2011.01.01

alter user tom
with password 'new_password';    - смена пароля

alter user tom        - выдать права на создание новых пользователей
createuser;

drop user tom;        - удаление пользователя
Управление группами
create group sales 
with user allen, vincent  - создание новой группы и добавление в нее пользователей allen и vincent

drop group sales        - удаление группы sales

alter group sales add user allen    - добавление пользователя "allen" в группу sales
alter group sales drop user vincent    - удаление пользователя vincent из группы sales
Выдача и отзыв прав
grant all on database drupal_db to drupal_user;        - выдача всех прав пользователю drupal_user для базы данных drupal_db

revoke all on database drupal_db from drupal_user;      - отзыв всех прав пользователя drupal_user для базы данных drupal_db

revoke all on database test from public;                - отзыв всех прав у всех пользователей для базы данных test
Группы
create group sales with user allen, vincent        - создание новой группы sales с добавлением пользователей allen и vincent

drop group sales;                    - удаление группы sales

alter group sales { add | drop } user <username>    - добавление или удаление пользователя из группы sales

grant select on database test to group sales;        - выдача права select для базы данных test группе sales