суббота, 15 апреля 2017 г.

Установка и настройка Postgres-XL в CentOS7



Устанавливаем необходимые пакеты:
# yum install nano wget
# yum install glibc gcc make autoconf automake libtool glib2 pcre slang gettext
# yum groupinstall 'Development Tools'
# yum install cvs
# yum install readline-devel
# yum install zlib-devel
# yum install net-tools
# yum install python-devel 

Отключаем возможность установки старых версий PostgreSQL из стандартного репозитария:
# nano /etc/yum.repos.d/CentOS-Base.repo
Добавляем в секции [base] и [updates] строку
exclude=postgresql*
# yum update

Отключаем SELinux
# nano /etc/sysconfig/selinux
Комментируем все, вставляем строку
SELINUX=disabled
Перезагружаемся:
# reboot

Отключаем firewall в CentOS 7
# service firewalld stop
# chkconfig firewalld off

Заходим в каталог /usr/src/
# cd /usr/src/

Скачиваем со страницы загрузки http://www.postgres-xl.org/download/ пакет исходных кодов:
# wget http://files.postgres-xl.org/postgres-xl-9.5r1.4.tar.gz
Распаковываем архив:
# tar -xvzf postgres-xl-9.5r1.4.tar.gz
Переходим в архив:
# cd postgres-xl-9.5r1.4

Конфигурируем и собираем:
# ./configure
Или лучше для конфигурирования с модулем PL/Python:
# ./configure --with-python
Затем:
# gmake
Сборка заканчивается сообщением:
All of Postgres-XL successfully made. Ready to install.
Выполняем установку:
# gmake install
Установка завершается сообщением:
Postgres-XL installation complete.
Установка по умолчанию выполняется в директорию /usr/local/pgsql/

Если ранее в системе не было установлено экземпляра базы данных PostgreSQL, то значит не было создано пользователя postgres, который необходим для работы.
Проверить существование пользователя postgres можно так:
# cat /etc/passwd | grep postgres
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
У меня в системе он уже был.
Если пользователя postgres нет, то cоздание пользователя выполняем так:
# adduser postgres

Прописываем переменные, требуемые для корректного запуска:
# echo 'export PGUSER=postgres' >> /etc/profile
# echo 'export PGHOME=/usr/local/pgsql' >> /etc/profile
# echo 'export PATH=$PATH:$PGHOME/bin' >> /etc/profile
# echo 'export LD_LIBRARY_PATH=$PGHOME/lib' >> /etc/profile

Процедуру установки неоюходимо сделать на каждом сервере, на котором будет разварачиваться кластер Postgres-XL

Postgres-XL состоит из трех основных компонентов:
Global Transaction Monitor (GTM) – Глобальный монитор транзакций, который следит за тем, что бы данные в кластере были актуальными и все запросы к данным завершились успешно.
Coordinator – Координатор. Элемент обеспечивающий связь пользователя с узлами данных Data Node. Координатор сам разберет сложный запрос, запросит данные у узлов, соберет их вместе и вернут пользователю.
Data Node – Узел данных, работающий непосредственно с данными.
Так как GTM, является узлов, при выходе которого из строя рушиться система, GTMов делают два – Основной (master) и резервный (slave).
Решение Postgres-XL ориентировано на установку составных элементов в одной высоконадежной сети. То есть распределенное хранилище данных, с разнесением элементов по разным городам работать будет плохо.


Рекомендуют координаторов сделать столько же, сколько узлов данных и на каждом сервере размещать по элементу Coordinator + Data Node. Для GTM в документации рекомендуют отдельный сервер. Каждому элементу Data Node и Coordinator нужны заданные порты (port) для приема сообщений Postgres и порты (pooler port) для подключения к другим узлам кластера. Порты pooler port должны быть разные на всех узлах кластера.
Наша конфигурация будет такая:


Предполагается, что на обеих машинах проведена инсталляция пакета Postgres-XL.

Все элементы Postgres-XL – это отдельные экземпляры базы данных PostgreSQL, которые необходимо инициировать в разных каталогах. Для этого необходимо эти каталоги создать и назначить на них права пользователю postgres

Создаем на сервере №1 каталоги для узлов системы:
# mkdir /usr/local/pgsql/data_coord1
# mkdir /usr/local/pgsql/data_datanode_1
# mkdir /mnt/data_datanode_2
# mkdir /usr/local/pgsql/data_gtm
# chown postgres /usr/local/pgsql/data_coord1
# chown postgres /usr/local/pgsql/data_datanode_1
# chown postgres /mnt/data_datanode_2
# chown postgres /usr/local/pgsql/data_gtm
Создаем на сервере №2 каталоги для узлов системы:
# mkdir /usr/local/pgsql/data_coord
# mkdir /usr/local/pgsql/data_datanode
# mkdir /usr/local/pgsql/data_gtm
# chown postgres /usr/local/pgsql/data_coord
# chown postgres /usr/local/pgsql/data_datanode
# chown postgres /usr/local/pgsql/data_gtm

Проводим инициирование узлов на сервере №1
Инициирование узлов кластера выполняется из под пользователя postgres, поэтому переходим в консоль пользователя postgres:
# su - postgres
Последний вход в систему:Сб мар 25 14:53:06 MSK 2017на pts/0
-bash-4.2$
Выполняем инициирование GTM на сервере №1
-bash-4.2$ /usr/local/pgsql/bin/initgtm -D /usr/local/pgsql/data_gtm -Z gtm
Опция D указывает в каком каталоге инициировать GTM узел. Опция Z указывает какой тип GTM нужно создать (gtm или gtm-proxy). Мы создаем GTM.
Вывод команды:
The files belonging to this GTM system will be owned by user "postgres".
This user must also own the server process.

fixing permissions on existing directory /usr/local/pgsql/data_gtm ... ok
creating configuration files ... ok
creating control file ... ok

Success.
You can now start the GTM server using:

    /usr/local/pgsql/bin/gtm -D /usr/local/pgsql/data_gtm
or
    /usr/local/pgsql/bin/gtm_ctl -Z gtm -D /usr/local/pgsql/data_gtm -l logfile start

Выполняем инициирование координатора на сервере №1
-bash-4.2$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data_coord1 --nodename coord1
Процесс инициирования отображается на экране:
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "ru_RU.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "russian".

Data page checksums are disabled.

fixing permissions on existing directory /usr/local/pgsql/data_coord1 ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok
creating template1 database in /usr/local/pgsql/data_coord1/base/1 ... ok
initializing pg_authid ... ok
initializing dependencies ... ok
creating system views ... ok
creating cluster information ... ok
loading system objects' descriptions ... ok
creating collations ... ok
creating conversions ... ok
creating dictionaries ... ok
setting privileges on built-in objects ... ok
creating information schema ... ok
loading PL/pgSQL server-side language ... ok
vacuuming database template1 ... ok
copying template1 to template0 ... ok
copying template1 to postgres ... ok
syncing data to disk ... ok
freezing database template0 ... ok
freezing database template1 ... ok
freezing database postgres ... ok

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.

Success.
You can now start the database server of the Postgres-XL coordinator using:

    /usr/local/pgsql/bin/postgres --coordinator -D /usr/local/pgsql/data_coord1
or
    /usr/local/pgsql/bin/pg_ctl start -D /usr/local/pgsql/data_coord1 -Z coordinator -l logfile

 You can now start the database server of the Postgres-XL datanode using:

    /usr/local/pgsql/bin/postgres --datanode -D /usr/local/pgsql/data_coord1
or
    /usr/local/pgsql/bin/pg_ctl start -D /usr/local/pgsql/data_coord1 -Z datanode -l logfile

Выполняем инициирование узла datanode в каталоге /usr/local/pgsql/data_datanode_1 на сервере №1
-bash-4.2$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data_datanode_1 --nodename datanode_1
Процесс инициирования практически ничем не отличается от предыдущего.

Выполняем инициирование узла datanode в каталоге /mnt/data_datanode_2 на сервере №1
-bash-4.2$ /usr/local/pgsql/bin/initdb -D /mnt/data_datanode_2 --nodename datanode_2
Процесс инициирования так же не примечателен.

Проводим инициирование узлов на сервере №2
Выполняем инициирование GTM на сервере №2
$ /usr/local/pgsql/bin/initgtm -D /usr/local/pgsql/data_gtm -Z gtm
Выполняем инициирование координатора на сервере №2
$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data_coord --nodename coord2
Выполняем инициирование узла datanode в каталоге /usr/local/pgsql/data_datanode на сервере №2
$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data_datanode --nodename datanode_3

Во время инициирования узлов кластера, в каждой директории создаются каталоги, которые будут содержать базы данных и файлы конфигураций.
Необходимо провести конфигурирование узлов кластера.
GTM сервера №1
$ nano /usr/local/pgsql/data_gtm/gtm.conf
Вписываем имя nodename. Снимаем комментарий с директив listen_addresses и startup.
Разрешаем логирование путям снятия комментария с директив log_file и log_min_messages.
#------------------------------------------------------------------
# GENERAL PARAMETERS
#------------------------------------------------------------------
nodename = 'gtm1'                 # Specifies the node name.
                                  # (changes requires restart)
listen_addresses = '*'            # Listen addresses of this GTM.
                                  # (changes requires restart)
port = 6666                       # Port number of this GTM.
                                  # (changes requires restart)

startup = ACT                     # Start mode. ACT/STANDBY.


#---------------------------------------
# OTHER OPTIONS
#---------------------------------------
#keepalives_idle = 0              # Keepalives_idle parameter.
#keepalives_interval = 0          # Keepalives_interval parameter.
#keepalives_count = 0             # Keepalives_count
log_file = 'gtm.log'              # Log file name
log_min_messages = WARNING        # log_min_messages.  

Coordinator сервера №1
$ nano /usr/local/pgsql/data_coord1/postgresql.conf
Здесь определяем директивой listen_addresses прослушивать все интерфейсы на порту 5433 (port = 5433). Задается pooler_port – номер порта, по которому координатор будет коннектится к узлам datanode. Здесь же происывается информация, необходимая для соединения с GTM. Директивой pgxc_node_name задается имя узла.
#listen_addresses = 'localhost'  # what IP address(es) to listen on;
listen_addresses ='*'          # comma-separated list of addresses;
                               # defaults to 'localhost'
                               # (change requires restart)
port = 5433                    # (change requires restart)


pooler_port = 40100            # Pool Manager TCP port
                               # (change requires restart)


gtm_host = '10.10.49.152'      # Host name or address of GTM
                               # (change requires restart)
gtm_port = 6666                # Port of GTM
                               # (change requires restart)
pgxc_node_name = 'coord1'      # Coordinator or Datanode name
                               # (change requires restart)
Далее необходимо задать права доступа к координатору в файле pg_hba.conf
$ nano /usr/local/pgsql/data_coord1/pg_hba.conf
В файле добавляем строку, разрешающую соединение с узлом из сети 10.10.0.0/16 и комментируем строку, описывающую подключение по IPv6
# IPv4 local connections:
host    all             all          127.0.0.1/32            trust
host    all             all          10.10.0.0/16            trust
# IPv6 local connections:
#host    all             all         ::1/128                 trust

Data Node 1 сервера №1 (в директории /usr/local/pgsql/data_datanode_1)
$ nano /usr/local/pgsql/data_datanode_1/postgresql.conf
Задаем директивы listen_addresses, port, pooler_port. Определяем параметры подключения к GTM и имя узла.
#listen_addresses = 'localhost' # what IP address(es) to listen on;
listen_addresses = '*'          # comma-separated list of addresses;
                                # defaults to 'localhost'
                                # (change requires restart)
port = 15432                    # (change requires restart)


pooler_port = 40101             # Pool Manager TCP port
                                # (change requires restart)


gtm_host = '10.10.49.152'      # Host name or address of GTM
                               # (change requires restart)
gtm_port = 6666                # Port of GTM
                               # (change requires restart)
pgxc_node_name = 'datanode_1'  # Coordinator or Datanode name
                               # (change requires restart)
Права доступа к узлу задаем в файле pg_hba.conf
$ nano /usr/local/pgsql/data_datanode_1/pg_hba.conf
В файле добавляем строку, разрешающую соединение с узлом из сети 10.10.0.0/16 и комментируем строку, описывающую подключение по IPv6
# IPv4 local connections:
host    all             all       127.0.0.1/32            trust
host    all             all       10.10.0.0/16            trust
# IPv6 local connections:
#host    all             all      ::1/128                 trust

Data Node 2 сервера №1 (в директории /mnt/data_datanode_2)
$ nano /mnt/data_datanode_2/postgresql.conf
Задаем директивы listen_addresses, port, pooler_port. Определяем параметры подключения к GTM и имя узла.
#listen_addresses = 'localhost' # what IP address(es) to listen on;
listen_addresses = '*'          # comma-separated list of addresses;
                                # defaults to 'localhost'
                                # (change requires restart)
port = 15433                    # (change requires restart)


pooler_port = 40102             # Pool Manager TCP port
                                # (change requires restart)


gtm_host = '10.10.49.152'       # Host name or address of GTM
                                # (change requires restart)
gtm_port = 6666                 # Port of GTM
                                # (change requires restart)
pgxc_node_name = 'datanode_1'   # Coordinator or Datanode name
                                # (change requires restart)
Права доступа к узлу задаем в файле pg_hba.conf
$ nano /mnt/data_datanode_2/pg_hba.conf
В файле добавляем строку, разрешающую соединение с узлом из сети 10.10.0.0/16 и комментируем строку, описывающую подключение по IPv6
# IPv4 local connections:
host    all             all         127.0.0.1/32            trust
host    all             all         10.10.0.0/16            trust
# IPv6 local connections:
#host    all             all        ::1/128                 trust

GTM сервера №2
$ nano /usr/local/pgsql/data_gtm/gtm.conf
#------------------------------------------------------------------
# GENERAL PARAMETERS
#------------------------------------------------------------------
nodename = 'gtm2'                 # Specifies the node name.
                                  # (changes requires restart)
listen_addresses = '*'            # Listen addresses of this GTM.
                                  # (changes requires restart)
port = 6666                       # Port number of this GTM.
                                  # (changes requires restart)

startup = STANDBY                 # Start mode. ACT/STANDBY.
#------------------------------------------------------------------
# GTM STANDBY PARAMETERS
#------------------------------------------------------------------
#Those parameters are effective when GTM 
# is activated as a standby server
active_host = '10.10.49.152'      # Listen address of active GTM.
                                  # (changes requires restart)
active_port = 6666                # Port number of active GTM.
                                  # (changes requires restart)

#---------------------------------------
# OTHER OPTIONS
#---------------------------------------
keepalives_idle = 15             # Keepalives_idle parameter.
keepalives_interval = 15         # Keepalives_interval parameter.
keepalives_count = 3             # Keepalives_count 
log_file = 'gtm.log'             # Log file name
log_min_messages = WARNING       # log_min_messages.  
                                 #Default WARNING.    
synchronous_backup = on 
Здесь кроме параметров, используемых и на основном GTM необходимо задать параметры основного GTM сервера: active_host и active_port

Coordinator сервера №2
$ nano /usr/local/pgsql/data_coord/postgresql.conf
#listen_addresses = 'localhost'  # what IP address(es) to listen on;
listen_addresses ='*'            # comma-separated list of addresses;
                                 # defaults to 'localhost'
                                 # (change requires restart)
port = 5433                      # (change requires restart)


pooler_port = 40103              # Pool Manager TCP port
                                 # (change requires restart)


gtm_host = '10.10.49.152'        # Host name or address of GTM
                                 # (change requires restart)
gtm_port = 6666                  # Port of GTM
                                 # (change requires restart)
pgxc_node_name = 'coord2'        # Coordinator or Datanode name
                                 # (change requires restart)
Далее необходимо задать права доступа к координатору в файле pg_hba.conf
$ nano /usr/local/pgsql/data_coord/pg_hba.conf
# IPv4 local connections:
host    all             all        127.0.0.1/32            trust
host    all             all        10.10.0.0/16            trust
# IPv6 local connections:
#host    all             all       ::1/128                 trust

Data Node сервера №2 (в директории /usr/local/pgsql/data_datanode)
$ nano /usr/local/pgsql/data_datanode/postgresql.conf
Задаем директивы listen_addresses, port, pooler_port. Определяем параметры подключения к GTM и имя узла.
#listen_addresses = 'localhost' # what IP address(es) to listen on;
listen_addresses = '*'          # comma-separated list of addresses;
                                # defaults to 'localhost'
                                # (change requires restart)
port = 15432                    # (change requires restart)


pooler_port = 40104             # Pool Manager TCP port
                                # (change requires restart)


gtm_host = '10.10.49.152'       # Host name or address of GTM
                                # (change requires restart)
gtm_port = 6666                 # Port of GTM
                                # (change requires restart)
pgxc_node_name = 'datanode_3'   # Coordinator or Datanode name
                                # (change requires restart)
Права доступа к узлу задаем в файле pg_hba.conf
$ nano /usr/local/pgsql/data_datanode/pg_hba.conf
# IPv4 local connections:
host    all             all        127.0.0.1/32            trust
host    all             all        10.10.0.0/16            trust
# IPv6 local connections:
#host    all             all       ::1/128                 trust

Запуск кластера
Запуск GTM выполняется в консоли пользователя postgres вот так
$ gtm_ctl start -Z gtm -D /usr/local/pgsql/data_gtm >logfile_gtm 2>&1 &
[1] 28366
Остановка выполняется так:
$ gtm_ctl stop -Z gtm -D /usr/local/pgsql/data_gtm
waiting for server to shut down.... done
server stopped
Команды для обоих серверов №1 и №2 одинаковы.

Запуск координаторов выполняется командой pg_ctl
На сервере №1
$ pg_ctl start -D /usr/local/pgsql/data_coord1 -Z coordinator -l logfile_coord 2>&1 &
На сервере №2
$ pg_ctl start -D /usr/local/pgsql/data_coord -Z coordinator -l logfile_coord 2>&1 &
Пример остановки координатора:
$ pg_ctl stop -D /usr/local/pgsql/data_coord1 -Z coordinator

Запуск Data Node выполняется так же командой pg_ctl
На сервере №1 запускаем две ноды:
$ pg_ctl start -D /usr/local/pgsql/data_datanode_1 -Z datanode -l logfile_datanode_1 2>&1 &
$ pg_ctl start -D /mnt/data_datanode_2 -Z datanode -l logfile_datanode_2 2>&1 &
На сервере №2 запускается одна нода:
$ pg_ctl start -D /usr/local/pgsql/data_datanode -Z datanode -l logfile_datanode 2>&1 &
Пример остановки ноды:
$ pg_ctl stop -D /mnt/data_datanode_2 -Z datanode

Убеждаемся, что все порты, определенные в конфигах кластера прослушиваются командой netstat, запускаемой из-под пользователя root.
# netstat -ltupn | grep 'postgres'
# netstat -ltupn | grep 'gtm'

После запуска кластера, необходимо каждому узлу кластера «рассказать» конфигурацию всей системы. Рассказывать конфигурацию будем через координаторы.
Подключаемся к первому координатору на сервере №1:
# su - postgres
$ psql -p 5433
psql (PGXL 9.5r1.4, based on PG 9.5.5 (Postgres-XL 9.5r1.4))
Type "help" for help.
postgres=#
Удаляем текущую конфигурацию:
postgres=# delete from pgxc_node;
DELETE 1
Создаем конфигурацию кластера:
postgres=# create node coord1 with (type=coordinator, host='10.10.49.152', port=5433);
postgres=# create node datanode_1 with (type=datanode, host='10.10.49.152', port=15432);
postgres=# create node datanode_2 with (type=datanode, host='10.10.49.152', port=15433);
postgres=# create node coord2 with (type=coordinator, host='10.10.49.154', port=5433);
postgres=# create node datanode_3 with (type=datanode, host='10.10.49.154', port=15432);
Перезагружаем узел
postgres=# SELECT pgxc_pool_reload();
 pgxc_pool_reload
------------------
 t
(1 row)
Смотрим, что получилось:
postgres=# select * from pgxc_node;
Через координатор №1 рассказываем конфигурацию системы узлу datanode_1 сервера №1. Удалить конфигурацию удаленно через EXECUTE DIRECT ON нельзя. Будем менять параметры.
postgres=# EXECUTE DIRECT ON (datanode_1) 'create node coord1 with (type=coordinator, host=''10.10.49.152'', port=5433)';
postgres=# EXECUTE DIRECT ON (datanode_1) 'create node datanode_2 with (type=datanode, host=''10.10.49.152'', port=15433)';
postgres=# EXECUTE DIRECT ON (datanode_1) 'create node coord2 with (type=coordinator, host=''10.10.49.154'', port=5433)';
postgres=# EXECUTE DIRECT ON (datanode_1) 'create node datanode_3 with (type=datanode, host=''10.10.49.154'', port=15432)';
postgres=# EXECUTE DIRECT ON (datanode_1) 'ALTER NODE datanode_1 WITH (TYPE = ''datanode'', HOST = ''10.10.49.152'', PORT = 15432)';
postgres=# EXECUTE DIRECT ON (datanode_1) 'SELECT pgxc_pool_reload()';
postgres=# EXECUTE DIRECT ON (datanode_1) 'select * from pgxc_node';
Через координатор №1 рассказываем конфигурацию системы узлу datanode_2 сервера №1
postgres=# EXECUTE DIRECT ON (datanode_2) 'create node coord1 with (type=coordinator, host=''10.10.49.152'', port=5433)';
postgres=# EXECUTE DIRECT ON (datanode_2) 'create node datanode_1 with (type=datanode, host=''10.10.49.152'', port=15432)';
postgres=# EXECUTE DIRECT ON (datanode_2) 'create node coord2 with (type=coordinator, host=''10.10.49.154'', port=5433)';
postgres=# EXECUTE DIRECT ON (datanode_2) 'create node datanode_3 with (type=datanode, host=''10.10.49.154'', port=15432)';
postgres=# EXECUTE DIRECT ON (datanode_2) 'ALTER NODE datanode_2 WITH (TYPE = ''datanode'', HOST = ''10.10.49.152'', PORT = 15433)';
postgres=# EXECUTE DIRECT ON (datanode_2) 'SELECT pgxc_pool_reload()';
postgres=# EXECUTE DIRECT ON (datanode_2) 'select * from pgxc_node';
Через координатор №1 рассказываем конфигурацию системы узлу datanode_3 сервера №2
postgres=# EXECUTE DIRECT ON (datanode_3) 'create node coord1 with (type=coordinator, host=''10.10.49.152'', port=5433)';
postgres=# EXECUTE DIRECT ON (datanode_3) 'create node datanode_1 with (type=datanode, host=''10.10.49.152'', port=15432)';
postgres=# EXECUTE DIRECT ON (datanode_3) 'create node coord2 with (type=coordinator, host=''10.10.49.154'', port=5433)';
postgres=# EXECUTE DIRECT ON (datanode_3) 'create node datanode_2 with (type=datanode, host=''10.10.49.152'', port=15433)';
postgres=# EXECUTE DIRECT ON (datanode_3) 'ALTER NODE datanode_3 WITH (TYPE = ''datanode'', HOST = ''10.10.49.154'', PORT = 15432)';
postgres=# EXECUTE DIRECT ON (datanode_3) 'SELECT pgxc_pool_reload()';
postgres=# EXECUTE DIRECT ON (datanode_3) 'select * from pgxc_node';
Через координатор №1 рассказываем конфигурацию системы узлу coord2 сервера №2
postgres=# EXECUTE DIRECT ON (coord2) 'create node coord1 with (type=coordinator, host=''10.10.49.152'', port=5433)';
postgres=# EXECUTE DIRECT ON (coord2) 'create node datanode_1 with (type=datanode, host=''10.10.49.152'', port=15432)';
postgres=# EXECUTE DIRECT ON (coord2) 'create node datanode_2 with (type=datanode, host=''10.10.49.152'', port=15433)';
postgres=# EXECUTE DIRECT ON (coord2) 'create node datanode_3 with (type=datanode, host=''10.10.49.154'', port=15432)';
postgres=# EXECUTE DIRECT ON (coord2) 'ALTER NODE coord2 WITH (TYPE = ''coordinator'', HOST = ''10.10.49.154'', PORT = 5433)';
postgres=# EXECUTE DIRECT ON (coord2) 'SELECT pgxc_pool_reload()';
postgres=# EXECUTE DIRECT ON (coord2) 'select * from pgxc_node';

Добавляем Postgres-XL в автозагрузку. Для этого создаем файлы unit для systemd.
# touch /etc/systemd/system/postgres-xl-start.service
# chmod 664 /etc/systemd/system/postgres-xl-start.service
# nano /etc/systemd/system/postgres-xl-start.service
Содержимое файла:
[Unit]
Description=Claster Postgres XL Start
After=network.target

[Service]
#Type=notify
Type=oneshot
User=root
ExecStart=/usr/bin/start_postgres_xl.sh
#ExecStop=/usr/local/pgsql/bin/gtm_ctl stop -Z gtm -D /usr/local/pgsql/data_gtm
#TimeoutSec=20s

[Install]
WantedBy=multi-user.target
Файл /usr/bin/start_postgres_xl.sh должен содержать команды для запуска кластера Postgres-XL
# touch /usr/bin/start_postgres_xl.sh
# chmod +x /usr/bin/start_postgres_xl.sh
# nano /usr/bin/start_postgres_xl.sh
Для сервера №1 файл будет таким:
#! /bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
set -e
su - postgres -c '/usr/local/pgsql/bin/pg_ctl -Z coordinator start -D /usr/local/pgsql/data_coord1/' >>/usr/local/pgsql/data_coord1/logfile_coord 2>&1
su - postgres -c '/usr/local/pgsql/bin/pg_ctl -Z datanode start -D /usr/local/pgsql/data_datanode_1/' >>/usr/local/pgsql/data_datanode_1/logfile_datanode_1 2>&1
su - postgres -c '/usr/local/pgsql/bin/pg_ctl -Z datanode start -D /mnt/data_datanode_2/' >>/mnt/data_datanode_2/logfile_datanode_2 2>&1
su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm start -D /usr/local/pgsql/data_gtm/' >>/usr/local/pgsql/data_gtm/logfile_gtm 2>&1
exit 0
Для сервера №2 файл будет таким:
#! /bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
set -e
su - postgres -c '/usr/local/pgsql/bin/pg_ctl -Z coordinator start -D /usr/local/pgsql/data_coord/' >>/usr/local/pgsql/data_coord/logfile_coord 2>&1
su - postgres -c '/usr/local/pgsql/bin/pg_ctl -Z datanode start -D /usr/local/pgsql/data_datanode/' >>/usr/local/pgsql/data_datanode/logfile_datanode 2>&1
su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm start -D /usr/local/pgsql/data_gtm/' >>/usr/local/pgsql/data_gtm/logfile_gtm 2>&1
#su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm start -D /usr/local/pgsql/data_gtm/' >>/usr/local/pgsql/data_gtm/logfile_gtm 2>&1
exit 0
Перезагружаем сервис systemd:
# systemctl daemon-reload
Добавляем новый сервис в автозагрузку:
# systemctl enable postgres-xl-start
Теперь для старта сервиса (для старта всех узлов кластера на текущем сервере) теперь можно использовать команду:
# systemctl start postgres-xl-start

ПРИМЕЧАНИЕ.
Настроить корректный запуск резервного сервера GTM STANBY при старте системы не получилось.
После перезапуска серверов для запуска резервного GTM делаем на Сервере №2 для запуска GTM-STANBY
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm start -D /usr/local/pgsql/data_gtm/' >>/usr/local/pgsql/data_gtm/logfile_gtm 2>&1
Затем перегружаем основной GTM на Сервере №1
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm stop -D /usr/local/pgsql/data_gtm/'
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm start -D /usr/local/pgsql/data_gtm/' >>/usr/local/pgsql/data_gtm/logfile_gtm 2>&1

Проведем тестирование системы. Подключаемся к любому координатору и создадим пару таблиц. Одну с репликацией на все узлы Data Node, вторую с шардингом (распределением между узлами) и посмотрим как распределяются данные.
postgres=# CREATE TABLE log1 ( 
id SERIAL PRIMARY KEY, 
log_mess text,
log_date timestamp DEFAULT now()
) distribute by REPLICATION;
postgres=# CREATE TABLE log2 ( 
id SERIAL PRIMARY KEY, 
log_mess text,
log_date timestamp DEFAULT now()
) DISTRIBUTE BY HASH (id);
Заполним таблицы случайными числами:
INSERT INTO log1 (log_mess) SELECT s FROM generate_series(1, 100) s;
INSERT INTO log2 (log_mess) SELECT s FROM generate_series(1, 100) s;
Проанализируем выгрузку данных:
postgres=# explain analyze select count(*) from log1;
                                                 QUERY PLAN
-------------------------------------------------------------------------------------------------------------
 Remote Fast Query Execution  (cost=0.00..0.00 rows=0 width=0) (actual time=126.495..126.497 rows=1 loops=1)
   Node/s: datanode_3
 Planning time: 0.073 ms
 Execution time: 126.539 ms
(4 rows)

postgres=# explain analyze select count(*) from log2;
                                                                      QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=4.78..4.79 rows=1 width=0) (actual time=53.588..53.588 rows=1 loops=1)
   ->  Remote Subquery Scan on all (datanode_1,datanode_2,datanode_3)  (cost=0.00..4.42 rows=142 width=0) (actual time=52.319..53.393 rows=3 loops=1)
 Planning time: 15.856 ms
 Execution time: 66.150 ms
(4 rows)
Видим, что при запросе из таблицы log1 запрос идет только с одной ноды, так как данные везде одинаковы, а при запросе с log2 – со всех трех узлов, так как данные разделены по узлам.
Если подключится к узлу datanode_3 и запросить содержимое таблиц log1 и log2, то получим следующую картину:
$ psql -p 15432
postgres=# \d
             List of relations
 Schema |    Name     |   Type   |  Owner
--------+-------------+----------+----------
 public | log1        | table    | postgres
 public | log1_id_seq | sequence | postgres
 public | log2        | table    | postgres
 public | log2_id_seq | sequence | postgres
(4 rows)
postgres=# SELECT * FROM log1;
   id    | log_mess |          log_date
---------+----------+----------------------------
 2281101 | 1        | 2017-04-03 16:29:00.814566
 2281102 | 2        | 2017-04-03 16:29:00.814566
 2281103 | 3        | 2017-04-03 16:29:00.814566

2281199 | 99       | 2017-04-03 16:29:00.814566
 2281200 | 100      | 2017-04-03 16:29:00.814566
(100 rows)
postgres=# SELECT * FROM log2;
 id  | log_mess |          log_date
-----+----------+----------------------------
 262 | 8        | 2017-04-03 16:31:24.945303
 263 | 9        | 2017-04-03 16:31:24.945303
 267 | 13       | 2017-04-03 16:31:24.945303
 270 | 16       | 2017-04-03 16:31:24.945303
 271 | 17       | 2017-04-03 16:31:24.945303

350 | 96       | 2017-04-03 16:31:24.945303
 351 | 97       | 2017-04-03 16:31:24.945303
(40 rows)
Видим, что данные распределяются и реплицируются.


ПРИМЕЧАНИЕ 1:
При подключении к координатору у меня выводилось аварийное сообщение:
$ psql -p 5433
psql: FATAL:  Could not obtain a transaction ID from GTM. The GTM might have failed or lost connectivity
В логах координатора было множество сообщений:
ERROR:  Could not obtain a transaction ID from GTM. The GTM might have failed or lost connectivity
WARNING:  can not connect to GTM: В соединении отказано
WARNING:  can not connect to GTM: В соединении отказано
WARNING:  can not connect to GTM: В соединении отказано
Ошибка была в конфигурации серверов. Оказывается порт pooler_port у каждого узла кластера должен быть уникальным.

ПРИМЕЧАНИЕ 2:
Узел данных не позволит полностью очистить информацию, но ее можно перезаписать:
postgres=# alter node datanode1 WITH ( TYPE=datanode, HOST ='192.168.1.151', PORT=25432, PRIMARY=true);

ПРИМЕЧАНИЕ 3:
Можно создать таблицу, которая будет распределяться только на два узла данных:
CREATE TABLE test1
( id bigint NOT NULL, profile bigint NOT NULL,
  status integer NOT NULL, switch_date timestamp without time zone NOT NULL,
CONSTRAINT test1_id_pkey PRIMARY KEY (id)
) to node (datanode1, datanode2);

ПРИМЕЧАНИЕ 4:
Перевод с основного на резервный GTM
Остановили основной GTM, если он еще доступен
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm stop -D /usr/local/pgsql/data_gtm/'
Делаем резервный GTM основным
# nano /usr/local/pgsql/data_gtm/gtm.conf
Устанавливаем
startup = ACT
Запускаем его как основной
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm stop -D /usr/local/pgsql/data_gtm/'
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm start -D /usr/local/pgsql/data_gtm/' >>/usr/local/pgsql/data_gtm/logfile_gtm 2>&1
Устанавливаем переменную gtm_host с новым IP адресом GTM. У нас будет
gtm_host = '10.10.49.154' 
в следующих файлах:
Сервер №1
# nano /usr/local/pgsql/data_coord1/postgresql.conf
# nano /usr/local/pgsql/data_datanode_1/postgresql.conf
# nano /mnt/data_datanode_2/postgresql.conf
Сервере №2 
# nano /usr/local/pgsql/data_coord/postgresql.conf
# nano /usr/local/pgsql/data_datanode/postgresql.conf
Перезагружаем ноды, координаторы.
Сервер №1
# su - postgres -c 'pg_ctl stop -D /usr/local/pgsql/data_coord1 -Z coordinator'
# su - postgres -c 'pg_ctl stop -D /usr/local/pgsql/data_datanode_1 -Z datanode'
# su - postgres -c 'pg_ctl stop -D /mnt/data_datanode_2 -Z datanode'
# su - postgres -c 'pg_ctl start -D /usr/local/pgsql/data_coord1 -Z coordinator' >>/usr/local/pgsql/data_coord1/logfile_coord 2>&1
# su - postgres -c 'pg_ctl start -D /usr/local/pgsql/data_datanode_1 -Z datanode' >>/usr/local/pgsql/data_datanode_1/logfile_datanode_1 2>&1
# su - postgres -c 'pg_ctl start -D /mnt/data_datanode_2 -Z datanode' >>/mnt/data_datanode_2/logfile_datanode_2 2>&1
Сервер №2
# su - postgres -c 'pg_ctl stop -D /usr/local/pgsql/data_coord -Z coordinator' 
# su - postgres -c 'pg_ctl stop -D /usr/local/pgsql/data_datanode -Z datanode'
# su - postgres -c 'pg_ctl start -D /usr/local/pgsql/data_coord -Z coordinator' >>/usr/local/pgsql/data_coord/logfile_coord 2>&1
# su - postgres -c 'pg_ctl start -D /usr/local/pgsql/data_datanode -Z datanode' >>/usr/local/pgsql/data_datanode/logfile_datanode 2>&1
Затем снова перезапускаем основной GTM (на Сервере 2)
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm stop -D /usr/local/pgsql/data_gtm/'
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm start -D /usr/local/pgsql/data_gtm/' >>/usr/local/pgsql/data_gtm/logfile_gtm 2>&1
В файлах автозапуск на Сервере №1 комментируем строку
# nano /usr/bin/start_postgres_xl.sh
#su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm start -D /usr/local/pgsql/data_gtm/' >>/usr/local/pgsql/data_gtm/logfile_gtm 2>&1
В файле автозапуска на Сервере №2 эту же строку раскомментируем

ПРИМЕЧАНИЕ 5.
При необходимости перевести работу кластера на другой GTM необходимо:
1) Настроить будущий GTM, как GTM Standby
В файле конфигурации GTM (/usr/local/pgsql/data_gtm/gtm.conf) установить
startup = STANDBY 
и прописать настройки основного GTM, напрмимер:
active_host = '10.10.49.154' 
active_port = 6666   
2) Запустить будущий GTM, как GTM Standby.
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm start -D /usr/local/pgsql/data_gtm/' >>/usr/local/pgsql/data_gtm/logfile_gtm 2>&1
3) Перезапускаем основной GTM, так как он почему-то всегда валиться после запуска резервного
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm stop -D /usr/local/pgsql/data_gtm/'
# su - postgres -c '/usr/local/pgsql/bin/gtm_ctl -Z gtm start -D /usr/local/pgsql/data_gtm/' >>/usr/local/pgsql/data_gtm/logfile_gtm 2>&1
4) Дождаться, когда в логах GTM появится запись:
# tail  /usr/local/pgsql/data_gtm/gtm.log
26:1606874944:2017-04-15 14:53:37.152 MSK -LOG:  Copying node information from GTM active done.
LOCATION:  gtm_standby_restore_node, gtm_standby.c:231
27:1606874944:2017-04-15 14:53:37.152 MSK -LOG:  Restoring node information from the active-GTM succeeded.
LOCATION:  main, main.c:737
28:1606874944:2017-04-15 14:53:37.153 MSK -LOG:  Started to run as GTM-Standby.
LOCATION:  main, main.c:822
Значит синхронизация произошла.
5) Останавливаем основной GTM и делаем все так, как в ПРИМЕЧАНИИ №4



ССЫЛКИ
http://www.postgres-xl.org/ 
https://habrahabr.ru/post/253017/ 
https://habrahabr.ru/post/261457/ 
https://pgconf.ru/media2015c/sharp.pdf 
http://bonesmoses.org/2015/12/11/pg-phriday-postgres-xl-and-horizontal-scaling/ 


Комментариев нет:

Отправить комментарий