Реконфигурация Pangolin из standalone инсталляции в кластер patroni#

В данном разделе описан процесс реконфигурации СУБД Pangolin из standalone инсталляции в patroni cluster, а так же рассмотрено подключение к кластеру дополнительных реплик.

Процесс реконфигурации Pangolin#

Процесс состоит из следующих разделов:

  • установка и настройка etcd;

  • установка patroni;

  • подключение к кластеру дополнительных реплик.

Установка и настройка etcd#

Необходимо устанавливать etcd той же версии, что устанавливается инсталлятором Pangolin. Узнать установленную версию etcd можно командой:

etcd --version

В кластерной конфигурации (patroni+etcd) etcd устанавливается из стандартных репозиториев ОС. Все действия по установке etcd выполняются под системным пользователем root. Для установки и настройки etcd выполните шаги:

  1. Проверьте наличие пакета etcd в репозиториях ОС:

    root ~ % yum info etcd
    Loaded plugins: product-id, search-disabled-repos
    Available Packages
    Name        : etcd
    Arch        : x86_64
    Version     : 3.3.11
    Release     : 2.el7
    Size        : 10 M
    Repo        : rhel-7-server-extras-rpms
    Summary     : A highly-available key value store for shared configuration
    URL         : https://github.com/etcd-io/etcd
    License     : ASL 2.0
    Description : A highly-available key value store for shared configuration.
    
  2. Установите пакет etcd:

    root ~ % yum -y install etcd
    
  3. Создайте конфигурационный файл для etcd. Файл будет создан в папке: /etc/etcd/etcd.conf:

    root ~ % install -m 644 <(cat <<EOF
    ETCD_NAME="$(hostname -s)"
    ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
    ETCD_ADVERTISE_CLIENT_URLS="http://$(hostname):2379"
    ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
    ETCD_INITIAL_ADVERTISE_PEER_URLS="http://$(hostname):2380"
    ETCD_INITIAL_CLUSTER_TOKEN="single"
    ETCD_INITIAL_CLUSTER="$(hostname -s)=http://$(hostname):2380"
    ETCD_INITIAL_CLUSTER_STATE="new"
    ETCD_DATA_DIR="/var/lib/etcd"
    ETCD_ELECTION_TIMEOUT="5000"
    ETCD_HEARTBEAT_INTERVAL="1000"
    ETCD_ENABLE_V2="true"
    EOF) /etc/etcd/etcd.conf
    
  4. После создания конфигурационного файла etcd, проверьте что заданы параметры:

    ETCD_NAME
    ETCD_ADVERTISE_CLIENT_URLS
    ETCD_INITIAL_ADVERTISE_PEER_URLS
    ETCD_INITIAL_CLUSTER
    

    Для каждого узла etcd данные параметры будут уникальные.

  5. Внесите правки в systemd-сервис для etcd. Создайте каталог:

    root ~ % mkdir /etc/systemd/system/etcd.service.d
    
  6. Создайте файл с изменениями для systemd-сервиса:

    root ~ % echo -e '[Service]\nExecStart=\nExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) ionice -c2 -n0 /usr/bin/etcd"' > /etc/systemd/system/etcd.service.d/override.conf
    
  7. Перечитайте конфигурацию systemd после изменения сервиса:

    root ~ % systemctl daemon-reload
    
  8. Включите сервис для автоматического запуска etcd после перезагрузки ОС:

    root ~ % systemctl enable etcd
    
  9. Запустите etcd:

    root ~ % systemctl start etcd
    
  10. Проверьте корректность запуска и состояния сервиса:

    root ~ % systemctl status etcd
    
    etcd.service - Etcd Server
    Loaded: loaded (/etc/systemd/system/etcd.service; enabled; vendor preset: disabled)
    Active: active (running) since Fri 2023-06-16 13:51:25 MSK; 1 months 3 days ago
    Main PID: 7723 (etcd)
    CGroup: /system.slice/etcd.service
    └─7723 /usr/bin/etcd
    
  11. Проверьте состояние кластера etcd:

    root ~ % health
    member {хеш} is healthy: got healthy result from <Адрес сервера>
    member {хеш} is healthy: got healthy result from <Адрес сервера>
    member {хеш} is healthy: got healthy result from <Адрес сервера>
    cluster is healthy
    
  12. Включите аутентификацию в etcd и добавьте необходимых пользователей и роли для работы patroni:

    root ~ % export ETCDCTL_API=2
    root ~ % etcdctl user add root
    root ~ % etcdctl user add patronietcd
    root ~ % etcdctl role add patroni
    root ~ % etcdctl role grant patroni -path '/service/*' -readwrite
    root ~ % etcdctl user grant patronietcd -roles patroni
    root ~ % etcdctl auth enable
    

Установка patroni#

В patroni содержится часть доработок, поэтому устанавливать его следует из дистрибутива Pangolin.

В рамках инструкции дистрибутив Pangolin будет распакован в /tmp/pangolin_distr.

Примечание:

Состав дистрибутива Pangolin описан в документе «Руководство по установке», раздел «Состав дистрибутива».

Шаги для установки patroni:

  1. Создайте каталоги, необходимые для установки и конфигурирования patroni (под системным пользователем root):

    root ~ % install -d -o postgres -g postgres -m 700 /etc/patroni /usr/patroni
    
  2. Добавьте systemd-сервис для patroni (под системным пользователем root). Создайте systemd-сервис /etc/systemd/system/patroni.service:

    Внимание!

    Обязательно внимательно отнестись к переменным окружения указанным в параметрах "Environment"

    Сервис patroni не запустится если будут указаны некорректные пути!

    root ~ % cat > /etc/systemd/system/patroni.service <<EOF
    [Unit]
    Description=Runners to orchestrate a high-availability PostgreSQL
    After=syslog.target network.target
    
    [Service]
    Type=simple
    User=postgres
    Group=postgres
    
    Environment="LD_LIBRARY_PATH=$(su - postgres -c 'echo $PGHOME' | grep usr)/lib"
    Environment="PG_PLUGINS_PATH=$(su - postgres -c 'echo $PGHOME' | grep usr)/lib"
    Environment="PATRONI_LIBRARY_PATH=/usr/patroni/patroni_venv/lib/postgresql_se_libs"
    Environment="PATRONI_PLUGINS_PATH=/usr/patroni/patroni_venv/lib/postgresql_se_libs"
    Environment="PYTHONPATH=/usr/patroni/patroni_venv/lib/python3/site-packages:/usr/patroni/patroni_venv/lib64/python3/site-packages:/usr/patroni/patroni_venv/lib/python3.6/site-packages:/usr/patroni/patroni_venv/lib64/python3.6/site-packages"
    
    PermissionsStartOnly=true
    ExecStartPre=-/bin/mkdir -p /var/run/postgresql
    ExecStartPre=/bin/chown -R postgres:postgres /var/run/postgresql
    
    WorkingDirectory=/usr/patroni
    ExecStart=/usr/patroni/patroni_venv/bin/patroni_bin/patroni.bin /etc/patroni/postgres.yml
    Restart=on-failure
    KillMode=process
    
    StartLimitInterval=0
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
  3. Перечитайте конфигурацию systemd после добавления нового сервиса:

    root ~ % systemctl daemon-reload
    
  4. Дальнейшие действия удобнее выполнять под системным пользователем postgres. Переключитесь на системного пользователя postgres:

    root ~ % su - postgres
    
  5. Перейдите в каталог /usr/patroni:

    postgres ~ % cd /usr/patroni
    
  6. Создайте виртуальное окружение для python:

    postgres ~ % python3 -m venv patroni_venv
    
  7. Выставьте корректные права:

    postgres ~ % chmod 700 patroni_venv
    
  8. Активируйте виртуальное окружение:

    postgres ~ % source patroni_venv/bin/activate
    
  9. Обновите pip:

    postgres ~ % python -m pip install --upgrade pip
    
  10. Установите в виртуальное окружение необходимый (в зависимости от дистрибутива Linux) список модулей python:

    postgres ~ % python -m pip install -r /tmp/pangolin_distr/installer/roles/checkup/files/requirements.txt
    

    Требования Red Hat Enterprise Linux:

    • urllib3==1.25.9;

    • PyYAML==5.3.1;

    • six==1.15.0;

    • kazoo==2.8.0;

    • psycopg2-binary==2.8.4;

    • flake8==3.7.9;

    • python-dateutil==2.8.1;

    • boto==2.49.0;

    • requests==2.23.0;

    • python-etcd==0.4.5;

    • click==7.1.2;

    • prettytable==0.7.2;

    • psutil==5.7.3;

    • cdiff==1.0;

    • python-daemon==2.2.4;

    • setuptools-rust==1.1.1.

    Требования ALT Linux:

    • urllib3==1.25.9;

    • PyYAML==5.4.1;

    • six==1.12.0;

    • kazoo==2.8.0;

    • psycopg2-binary==2.8.4;

    • flake8;

    • python-dateutil==2.7.3;

    • boto==2.49.0;

    • requests==2.23.0;

    • python-etcd;

    • click==6.7;

    • prettytable==2.2.1;

    • psutil==5.8.0;

    • cdiff==1.0;

    • python-daemon==2.3.0.

  11. Распакуйте архив с бинарными файлами patroni и дополнительными библиотеками:

    postgres ~ % tar xpf /tmp/pangolin_distr/patroni/patroni.tar.gz -C /usr/patroni/patroni_venv/bin
    
    postgres ~ % tar xpf /tmp/pangolin_distr/patroni/postgresql_se_libs.tar.gz -C /usr/patroni/patroni_venv/lib
    
    postgres ~ % cp /tmp/pangolin_distr/patroni/se_version /usr/patroni/patroni_venv/bin
    
  12. Создайте скрипт, который будет использоваться patroni при перезагрузке кластера для перезагрузки pgbouncer (reload):

    postgres ~ % install -o postgres -g postgres -m 500 <(cat <<EOF
    #!/bin/sh
    
    sudo systemctl restart pgbouncer
    EOF) /etc/patroni/reload_pgbouncer.sh
    
  13. Создайте основной конфигурационный файл patroni /etc/patroni/postgres.yml. В инструкции ниже представлен скрипт генерации postgres.yml на основе уже существующих переменных окружения ($HOSTNAME; $CLNAME; $PGHOME; $PGDATA) системного пользователя postgres. Параметры СУБД необходимо перенести в конфигурационный файл postgres.yml вручную из уже существующих pg_hba.conf и postgresql.conf (которые расположены в $PGDATA) в соответствии с назначением секций конфигурационного файла postgres.yml.

    Файл postgres.yml состоит из следующих блоков:

    • restapi – укажите настройки для доступа к API самого patroni (hash пароля можно создать через команду pg_auth_password enc);

    • etcd – укажите данные для доступа к etcd, пользователь: patronietcd (был создан при настройке etcd) и пароль (захешировать можно через pg_auth_password enc);

    • bootstrap – параметры из данного блока записываются в etcd /<namespace>/<scope>/config только при первом старте patroni-кластера, поэтому их так же необходимо заполнить на основе текущих конфигурационных файлов PostgreSQL;

    • postgresql – исправьте записи на основе конфигурационного файла postgresql.conf;

    • pg_hba – исправьте записи на основе конфигурационного файла pg_hba.conf;

    • tags – оставьте без изменения, как в скрипте генерации, для обычного использования достаточно выставить все параметры блока tags в false;

    • scope – необходимо указать имя кластера (cluster), в name имя текущего сервера (hostname).

    Скрипт генерации postgres.yml:

    postgres ~ % install -o postgres -g postgres -m 600 <(cat <<EOF
    scope: $CLNAME
    name: $HOSTNAME
    
    restapi:
    listen: {IP-адрес}:{Порт}
    connect_address: $HOSTNAME:{Порт}
    authentication:
    username: patroniyml
    password: HASH_PASSWORD_WRITE_HERE
    
    etcd:
    host: $HOSTNAME:{Порт}
    
        username: patronietcd
        password: HASH_PASSWORD_WRITE_HERE
    
    bootstrap:
    dcs:
    ttl: 130
    retry_timeout: 60
    loop_wait: 10
    maximum_lag_on_failover: 1048576
    synchronous_mode: true
    synchronous_mode_strict: false
    postgresql:
    parameters:
    max_connections: '45'
    max_locks_per_transaction: '100'
    max_worker_processes: '16'
    max_prepared_transactions: '12'
    wal_level: 'replica'
    wal_log_hints: on
    track_commit_timestamp: off
    use_pg_rewind: true
    use_slots: true
    
        initdb:
        - encoding: UTF8
        - data-checksums
    
    postgresql:
    listen: {IP-адрес}:{Порт}
    bin_dir: $PGHOME/bin
    connect_address: $HOSTNAME:{Порт}
    data_dir: $PGDATA
    create_replica_methods:
    - basebackup
    basebackup:
    format: plain
    wal-method: fetch
    authentication:
    replication:
    username: patroni
    database: replication
    superuser:
    username: patroni
    parameters:
    
            archive_mode: 'off'
            archive_command: '$PGHOME/bin/pg_probackup archive-push -B /pgarclogs/$(echo $PGHOME | grep -o '[[:digit:].]*') --instance $CLNAME --wal-file-path=%p --wal-file-name=%f --compress --overwrite -j 4 --batch-size=100'
            authentication_proxy: '1'
            authentication_port: '5544'
            auth_activity_period: '60'
            archive_timeout: '180'
            autovacuum_work_mem: '162MB'
            checkpoint_completion_target: '0.9'
            checkpoint_timeout: '1800'
            #debug_print_parse: 'True'
            #debug_print_rewritten: 'True'
            #debug_print_plan: 'True'
            default_statistics_target: '100' # by default
            effective_cache_size: '3910MB'
            effective_io_concurrency: '300' # set to 200 if SSD drives are used
            fsync: 'on'
            full_page_writes: 'on'
            hot_standby: 'on'
            hot_standby_feedback: 'on'
            listen_addresses: {IP-адрес}
            syslog_facility: 'LOCAL3'
            syslog_ident: 'postgres'
            syslog_sequence_numbers: 'on'
            syslog_split_messages: 'off'
            log_checkpoints: 'True'
            log_connections: 'True'
            log_destination: 'stderr'
            log_directory: '/pgerrorlogs'
            log_disconnections: 'True'
            log_file_mode: 0644
            log_filename: 'postgresql-%Y-%m-%d_%H%M%S.log'
            log_line_prefix: '%t [%p]: [%l-1] app=%a,user=%u,db=%d,client=%h '
            log_lock_waits: 'on'
            log_min_duration_statement: '5000'
            log_min_error_statement: 'WARNING'
            log_replication_commands: 'on'
            log_rotation_age: '1440'
            log_rotation_size: '100MB'
            log_statement: 'none'
            log_temp_files: '0'
            log_truncate_on_rotation: 'True'
            logging_collector: 'True'
            client_min_messages: 'notice'
            log_timezone: 'Europe/Moscow'
            datestyle: 'iso, mdy'
            timezone: 'Europe/Moscow'
            lc_messages: 'en_US.utf8'
            lc_monetary: 'en_US.utf8'
            lc_numeric: 'en_US.utf8'
            lc_time: 'en_US.utf8'
            default_text_search_config: 'pg_catalog.english'
            maintenance_work_mem: '325MB'
            max_parallel_workers: '4'
            max_parallel_workers_per_gather: '2'
            max_replication_slots: '10'
            max_standby_archive_delay: '30s'
            max_standby_streaming_delay: '30s'
            max_wal_senders: '10'
            max_wal_size: '4GB'
            min_wal_size: '2GB'
            monitoring_ldap_servers: '^ldap-address.server.local$'
            pgaudit.log: 'ddl, role, connection, misc_set'
            password_encryption: 'scram-sha-256'
            password_policy.deny_default: 'off'
            password_policy.reuse_time: '365 days'
            password_policy.in_history: '4'
            password_policy.max_age: '0'
            password_policy.min_age: '0'
            password_policy.grace_login_limit: '0'
            password_policy.grace_login_time_limit: '3 days'
            password_policy.expire_warning: '7 days'
            password_policy.lockout: 'on'
            password_policy.lockout_duration: '24 hours'
            password_policy.max_failure: '6'
            password_policy.failure_count_interval: '0'
            password_policy.check_syntax: 'on'
            password_policy.min_length: '16'
            password_policy.min_length: '16'
            password_policy.illegal_values: 'on'
            password_policy.alpha_numeric: '3'
            password_policy.min_alpha_chars: '0'
            password_policy.min_special_chars: '1'
            password_policy.min_uppercase: '1'
            password_policy.min_lowercase: '0'
            password_policy.max_rpt_chars: '0'
            password_policy.track_login: 'off'
            password_policy.max_inactivity: '0'
            password_policy.use_password_strength_estimator: 'on'
            password_policy.password_strength_estimator_score: '3'
            password_policy.deduplicate_ssl_no_ssl_fail_auth_attepmts: 'on'
            password_policy.allow_hashed_password: 'off'
            psql_encrypt_password: 'on'
            password_policies_enable: 'on'
            pg_hint_plan.parse_messages: 'warning'
            pg_hint_plan.debug_print: 'off'
            pg_hint_plan.message_level: 'debug'
            cron.database_name: 'postgres'
            cron.max_running_jobs: '3'
    
            installer.cluster_type: 'standalone-patroni-etcd-pgbouncer'
    
            port: {Порт}
            random_page_cost: '2.0'
            search_path: 'ext'
            shared_buffers: '4GB'
            shared_preload_libraries: 'auto_explain,pg_stat_statements,pg_cron,pg_hint_plan,pg_pathman'
    
            superuser_reserved_connections: '4'
    
            synchronous_commit: 'on'
            unix_socket_directories: '/var/run/postgresql/'
            wal_buffers: '16MB'
            wal_keep_segments: '500'
            wal_receiver_status_interval: '1s'
            wal_sync_method: 'fsync'
            work_mem: '16384kB'
            ssl: 'on'
            ssl_cert_file: /home/postgres/ssl/$(hostname -s).crt
            ssl_key_file: /home/postgres/ssl/$(hostname -s).key
            ssl_ca_file: /home/postgres/ssl/root.crt
    
            is_tde_on: 'off'
    
        pg_hba:
            - hostssl all postgres {IP-адрес}/{Порт} cert
            - hostssl all postgres $PGHOST/{Порт} cert
    
            - host all patroni {IP-адрес}/{Порт} scram-sha-256
            - host all patroni $PGHOST/{Порт} scram-sha-256
    
            - host replication patroni {IP-адрес}/{Порт} scram-sha-256
            - host replication patroni $PGHOST/{Порт} scram-sha-256
    
    
    tags:
    nofailover: false
    noloadbalance: false
    clonefrom: false
    nosync: false
    EOF) /etc/patroni/postgres.yml
    
  14. Создайте пользователя для работы репликации в СУБД Pangolin с паролем согласно парольной политике:

    CREATE USER patroni WITH ENCRYPTED PASSWORD 'PASSWORD_WRITE_HERE';
    

    Парольная политика по умолчанию:

    • длина 16 символов;

    • минимум 3 цифры;

    • минимум 1 спецсимвол;

    • минимум 1 заглавная буква.

  15. Отключите срок действия пароля и выставьте лимит подключений:

    ALTER ROLE patroni LOGIN SUPERUSER REPLICATION VALID UNTIL 'infinity' CONNECTION LIMIT 5;
    
  16. Добавьте пользователей, созданных в предыдущем пункте, в криптохранилище Pangolin:

    postgres ~ % pg_auth_config add -h $HOSTNAME -p {Порт} -U patroni -d postgres
    
    postgres ~ % pg_auth_config add -h $HOSTNAME -p {Порт} -U patroni -d replication
    
    postgres ~ % pg_auth_config add -h localhost -p {Порт} -U patroni -d postgres
    
    postgres ~ % pg_auth_config add -h localhost -p {Порт} -U patroni -d replication
    
  17. Для репликации и корректной работы patroni необходимо добавить дополнительные правила в pg_hba.conf:

    postgres ~ % cat >> $PGDATA/pg_hba.conf <<EOF
    host all patroni {IP-адрес}/{Порт} scram-sha-256
    host all patroni $PGHOST/{Порт} scram-sha-256
    
    host replication patroni {IP-адрес}/{Порт} scram-sha-256
    host replication patroni $PGHOST/{Порт} scram-sha-256
    EOF
    
  18. Выполните перезагрузку (reload) Pangolin:

    postgres ~ % psql -c 'SELECT pg_reload_conf()'
    
  19. Включите сервис patroni (под системным пользователем root) для автоматического запуска после перезагрузки ОС:

    root ~ % systemctl enable patroni
    
  20. Запустите сервис:

    root ~ % systemctl start patroni
    
  21. Проверьте корректность запуска и состояния сервиса:

    root ~ % systemctl status patroni
    patroni.service - Runners to orchestrate a high-availability PostgreSQL
    Loaded: loaded (/etc/systemd/system/patroni.service; enabled; vendor preset: disabled)
    Active: active (running) since Fri 2023-06-16 13:56:19 MSK; 1 months 3 days ago
    Main PID: 17880 (patroni.bin)
    CGroup: /system.slice/patroni.service
    ├─17880 /usr/patroni/patroni_venv/bin/patroni_bin/patroni.bin /etc/patroni/postgres.yml
    ├─29197 /usr/pangolin-5.4.0/bin/postgres -D /pgdata/05/data/ --config-file=/pgdata/05/data/postgresql.conf --listen_addresses=0.0.0.0 -...
    ├─29200 postgres: clustername: logger
    ├─29202 postgres: clustername: idle sessions terminator
    ├─29203 postgres: clustername: checkpointer
    ├─29204 postgres: clustername: background writer
    ├─29205 postgres: clustername: walwriter
    ├─29206 postgres: clustername: authproc
    ├─29207 postgres: clustername: autovacuum launcher
    ├─29208 postgres: clustername: stats collector
    ├─29209 postgres: clustername: password policy cache
    ├─29210 postgres: clustername: pg_cron launcher
    ├─29211 postgres: clustername: file system checker
    ├─29212 postgres: clustername: performance insights
    ├─29218 postgres: clustername: logical replication launcher
    ├─29309 postgres: clustername: patroni postgres {IP-адрес}(51604) idle
    └─29314 postgres: clustername: walsender patroni {IP-адрес}(53336) streaming 0/C000000
    
  22. При первом запуске patroni должен определить запущенный экземпляр СУБД Pangolin и создать конфигурацию в etcd. Пример конфигурации в etcd:

    root ~ % etcdctl -u root:ENTER_PASSWORD_HERE ls -r /
    Password:
    /service
    /service/clustername
    /service/clustername/config
    /service/clustername/status
    /service/clustername/members
    /service/clustername/members/srv-0-1
    /service/clustername/initialize
    /service/clustername/leader
    

Добавление реплики в существующий кластер etcd#

Процесс добавления новых реплик в существующий кластер можно разделить на этапы:

  • установка etcd на реплике (как в разделе «Установка и настройка etcd»);

  • установка patroni на реплике (как в разделе «Установка Patroni»);

  • добавление реплики в существующий кластер etcd;

  • подготовка конфигурации и запуск patroni на реплике;

  • проверка.

Добавление новых узлов в кластер предполагает наличие на них:

  • СУБД Pangolin;

  • Patroni;

  • etcd.

Для включения узла в существующий кластер необходимо на этот узел установить и сконфигурировать etcd:

  1. На лидер-сервере переведите patroni в maintenance mode (под системным пользователем postgres):

    postgres ~ % patronictl -c /etc/patroni/postgres.yml pause $CLNAME
    
  2. Проверьте состояние кластера - должно быть Maintenance mode: on:

    postgres ~ % patronictl -c /etc/patroni/postgres.yml list
    + Cluster: testcl {cluster_name} 
     -------+--------------+---------+----+-----------+
    | Member             | Host                    | Role         | State   | TL | Lag in MB |
    +--------------------+-------------------------+--------------+---------+----+-----------+
    | srv-0-1            | srv-0-1:5433            | Leader       | running |  3 |           |
    +--------------------+-------------------------+--------------+---------+----+-----------+
    Maintenance mode: on
    
  3. Если etcd был уже запущен ранее, необходимо его остановить, удалить старые данные и привести конфигурационный файл /etc/etcd/etcd.conf к виду, как указано в разделе «Установка и настройка etcd». Остановите сервис:

    root ~ % systemctl stop etcd
    
  4. Удалите старые данные:

    root ~ % rm -rf /var/lib/etcd/*
    
  5. Добавьте новый узел в конфигурацию etcd (выполнять можно на любом узле, под любым пользователем):

    root ~ % ETCDCTL_API=2 etcdctl -u root:ENTER_PASSWORD_HERE member add srv-02 http://srv-02:2380
    Added member named srv-02 with ID {cluster_id} to cluster
    
    ETCD_NAME="srv-02"
    ETCD_INITIAL_CLUSTER="srv-01=http://srv-01:2380,srv-02=http://srv-02:2380"
    ETCD_INITIAL_CLUSTER_STATE="existing"
    

    Имена серверов srv-01 и srv-02 используются в качестве примера.

  6. Далее, на новом узле, в конфигурационном файле /etc/etcd/etcd.conf необходимо исправить переменные ETCD_NAME; ETCD_INITIAL_CLUSTER; ETCD_INITIAL_CLUSTER_STATE (/etc/etcd/etcd.conf) на актуальные. Запустите etcd на реплике (под системным пользователем root):

    root ~ % systemctl start etcd
    
  7. Проверьте корректность запуска и состояния сервиса:

    root ~ % systemctl status etcd
    
    etcd.service - Etcd Server
    Loaded: loaded (/etc/systemd/system/etcd.service; enabled; vendor preset: disabled)
    Active: active (running) since Fri 2023-06-16 13:51:25 MSK; 1 months 3 days ago
    Main PID: {PID} (etcd)
    CGroup: /system.slice/etcd.service
    └─7723 /usr/bin/etcd
    
  8. Проверьте состояние кластера etcd:

    root ~ % health
    member 29b4998c1831f0fd is healthy: got healthy result from <Адрес сервера>
    member caf7160f0f0dbe48 is healthy: got healthy result from <Адрес сервера>
    member fab56994fa5b7990 is healthy: got healthy result from <Адрес сервера>
    cluster is healthy
    
  9. Проверьте включение нового сервера в существующий кластер etcd:

    root ~ % etcdctl member list
    431edddd4d2a5184: name=srv-01 peerURLs=http://srv-01:2380 clientURLs=http://srv-01:2379 isLeader=true
    79a1e10b178b9510: name=srv-02 peerURLs=http://srv-02:2380 clientURLs=http://srv-02:2379 isLeader=false
    

    Имена серверов srv-01 и srv-02 используются в качестве примера.

Подготовка конфигурации и запуск patroni на реплике#

После установки Patroni необходимо провести дополнительное конфигурирование:

  • удалить старые данные БД;

  • конфигурационный файл /etc/patroni/postgres.yml привести к виду как указано в разделе «Установка patroni».

Внимание!

Операция деструктивная, необходимо убедится на правильном ли сервере мы выполняем команду!

На остановленном patroni выполните шаги:

  1. Остановите сервис:

    root ~ % systemctl stop patroni
    
  2. Для удаления старых данных (под системным пользователем postgres), необходимо определить, где располагаются каталоги data и tablespaces:

    postgres ~ % echo $PGDATA
    /pgdata/04/data
    
  3. Очистите данные:

    postgres ~ % rm -rf /pgdata/04/data/*
    postgres ~ % rm -rf /pgdata/04/tablespaces/*
    

    /pgdata/04 представлена в качестве примера, в реальности путь до каталогов data и tablespaces может быть другим.

  4. В секции scope конфигурационного файла (/etc/patroni/postgres.yml) укажите корректное имя существующего кластера, к которому будет подключаться реплика.

  5. Запустите сервис patroni (под системным пользователем root):

    root ~ % systemctl start patroni
    
  6. Проверьте корректность запуска и состояния сервиса:

        root ~ % systemctl status patroni
        patroni.service - Runners to orchestrate a high-availability PostgreSQL
        Loaded: loaded (/etc/systemd/system/patroni.service; enabled; vendor preset: disabled)
        Active: active (running) since Fri 2023-06-16 13:56:19 MSK; 1 months 3 days ago
        Main PID: 17880 (patroni.bin)
        CGroup: /system.slice/patroni.service
        ├─17880 /usr/patroni/patroni_venv/bin/patroni_bin/patroni.bin /etc/patroni/postgres.yml
        ├─29197 /usr/pangolin-5.4.0/bin/postgres -D /pgdata/05/data/ --config-file=/pgdata/05/data/postgresql.conf --listen_addresses=0.0.0.0 -...
        ├─29200 postgres: clustername: logger
        ├─29202 postgres: clustername: idle sessions terminator
        ├─29203 postgres: clustername: checkpointer
        ├─29204 postgres: clustername: background writer
        ├─29205 postgres: clustername: walwriter
        ├─29206 postgres: clustername: authproc
        ├─29207 postgres: clustername: autovacuum launcher
        ├─29208 postgres: clustername: stats collector
        ├─29209 postgres: clustername: password policy cache
        ├─29210 postgres: clustername: pg_cron launcher
        ├─29211 postgres: clustername: file system checker
        ├─29212 postgres: clustername: performance insights
        ├─29218 postgres: clustername: logical replication launcher
        ├─29309 postgres: clustername: patroni postgres 127.0.0.1(51604) idle
        └─29314 postgres: clustername: walsender patroni <IP-адрес>(53336) streaming 0/C000000
        ```
    
  7. Проверьте, появилась ли в etcd запись для добавляемой реплики:

    root ~ % etcdctl -u root:ENTER_PASSWORD_HERE ls /service/clustername/members
    Password:
    /service/clustername/members/srv-01
    /service/clustername/members/srv-02
    
  8. Проверьте корректность включения реплики в кластер:

    root ~ % etcdctl member list
    431edddd4d2a5184: name=srv-01 peerURLs=http://srv-01:{Порт}clientURLs=http://srv-01:{Порт} isLeader=true
    79a1e10b178b9510: name=srv-02 peerURLs=http://srv-02:{Порт} clientURLs=http://srv-02:{Порт} isLeader=false