diff --git a/AsbCloudDb/Setup db replication.md b/AsbCloudDb/Setup db replication.md new file mode 100644 index 00000000..f4a529af --- /dev/null +++ b/AsbCloudDb/Setup db replication.md @@ -0,0 +1,265 @@ +# Репликация данных PostgreSQL +## 1. Требования +1. Primary и Replica сервера должны принадлежать одной версии postgreSQL +2. Сервера должны иметь удаленный доступ + + +## 2. Настройка Primary-сервера +1. Открыть postgres.conf на редактирование + +``` +cd /etc/postgresql/15/main/ + +sudo nano postgresql.conf + ``` + + 2. В postgres.conf найти запись listen_addresses и добавить туда ip standby-сервера + + > listen_addresses = '*, ' + + 3. Открыть клиент для работы с postgres + + ``` + sudo -u postgres psql + ``` + + 4. Создать пользователя с атрибутом REPLICATION.
+ P.S: В данном примере создается пользователь с логином replicator и паролем q + + ``` + CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'q'; + ``` + + 5. Открыть на редактирование файл pg_hba.conf + ``` +cd /etc/postgresql/15/main/ + +sudo nano pg_hba.conf + ``` + + 6. Вставить в pg_hba.conf запись. + Запись вставлять после комментария "Allow replication connections from localhost..."
+ Данные для вставки записи:
+ - replicator - имя пользователя, созданного на предыдущем шаге
+- , например, 192.168.0.0/24 + ``` + host replication replicator 192.168.0.0/24 md5 + ``` + + 7. Рестарт сервера + ``` + sudo systemctl restart postgresql + ``` + + ## 3. Настройка replica-сервера + 1. Остановить сервер + ``` + sudo systemctl stop postgresql + ``` + + 2. Важно! Зайти под пользователем postgres + ``` + sudo su - postgres + ``` + + 3. Сделать резервную копию содержимого /var/lib/postgresql/15/main/ в папку main_old + ``` + cp -R /var/lib/postgresql/15/main/ /var/lib/postgresql/15/main_old/ + ``` + + 4. Удалить папку main + ``` + rm -rf /var/lib/postgresql/15/main/ + ``` + + 5. Используя утилиту basebackup создать базовую резервную копию с правами владения postgres (либо любого пользователя с соответствующими разрешениями). + + ``` + pg_basebackup -h -D /var/lib/postgresql/14/main/ -U replicator -P -v -R -X stream -C -S slaveslot1 + + где: /var/lib/postgresql/15/main/ - каталог replica-сервера + ``` + + 6. Убедиться, что в папке main созданы файлы standby.signal и postgresql.auto.conf. +``` +ls -ltrh /var/lib/postgresql/15/main/ +``` + +7. Запустить сервер +``` +systemctl start postgresql +``` + + ## 4. Проверка настроек + 1. Подсоединиться к primary-серверу + ``` +sudo -u postgres psql + ``` + + 2. На primary-сервере выполнить команду + ``` + SELECT * FROM pg_replication_slots; + ``` + + 3. Убедиться, что в представлении отображается слот репликации с именем slotslave1 + 4. На standby-сервере выпонить команду + ``` + SELECT * FROM pg_stat_wal_receiver; + ``` + 5. Убедиться, что появилась запись с ip primary-сервера + + 6. На primary - сервере проверить режим репликации. Он может быть синхронным или асинхронным. Для проверки необходимо выполнить команду + ``` + SELECT * FROM pg_stat_replication; + ``` + + 7. Для включения синхронного режима необходимо выполнить следующую команду + ``` + ALTER SYSTEM SET synchronous_standby_names TO '*'; + ``` + + 8. Сделать рестарт primary-сервера. + + 9. Внести запись в любую таблицу базы данных primary-сервера + 10. Убедиться, что соответствующая запись появилась в таблице базы данных standby-сервера + 11. Попытаться внести запись в таблицу базы данных standby-сервера. + 12. Убедиться, что операция завершилась с ошибкой + > cannot execute OPERATION in a read-only transaction + + + +## 5. Установка PgPool-II + + + 1. Установить на primary-сервер pgpool2 и postgresql-14-pgpool2 +``` +apt-get -y install pgpool2 postgresql-15-pgpool2 + +``` + 2. Установить на standby-сервер только postgresql-14-pgpool2 +``` +apt-get -y install postgresql-15-pgpool2 +``` +### Далее все настройки выполнить на primary-сервере + 3. Зайти на редактирование в конфигурационный файл pgpool2 + ``` + sudo nano /etc/pgpool2/pgpool.conf + ``` + 4. Задать параметры следующим образом: + ``` + backend_clustering_mode = 'streaming_replication' + listen_addresses = '*, ' + port = 9999 + ___ + backend_hostname0 = '' + backend_port0 = '<порт primary-сервера>' + backend_weight0 = 0 + backend_data_directory0 = '/var/lib/postgresql/14/main' + ___ + backend_hostname1 = '' + backend_port1 = '<порт primary-сервера>' + backend_weight1 = 1 + ___ + enable_pool_hba = on + log_statement = on + log_per_node_statement = on + pid_file_name = "pgpool.pid" + load_balance_mode = on + statement_level_load_balance = on + sr_check_period = 1 + sr_check_user = '<имя пользователя>' + sr_check_password = '<пароль пользователя>' + health_check_period = 10 + health_check_user = '<имя пользователя>' + health_check_password = '<пароль пользователя>' + ``` +5. Поскольку enable_pool_hba указан в режиме on, это значит, что Pgpool-II будет использовать pool_hba.conf для аутентификации клиента. Поэтому открываем на редактирование pool_hba.conf +``` +sudo nano /etc/pgpool2/pool_hba.conf +``` +6. Добавить строку +``` +host all all md5 +``` +7. Pgpool-II извлекает пароль пользователя из файла pool_passwd +``` +sudo nano /etc/pgpool2/pool_passwd +``` +Файл паролей представляет собой текстовый файл следующего формата: +``` +пользователь1:пароль1 +пользователь2:пароль2 +``` +Файл может содержать 3 типа паролей. Pgpool-II идентифицирует тип формата пароля по его префиксу, поэтому каждая запись пароля в pool_passwd должна иметь префикс формата пароля. + +- Обычный текст : пароль в текстовом формате с использованием префикса TEXT (например, TEXTmypassword ) . +- Зашифрованный пароль AES256 : зашифрованный пароль AES256, используя префикс AES (например, AESmzVzywsN1Z5GABhSAhwLSA== ) . +- Хешированный пароль MD5 : хешированный пароль MD5, используя префикс md5 (например, md5270e98c3db83dbc0e40f98d9bfe20972 ) . + +8. В примере в качестве пароля используется обычный текст (пароль q) +``` +postgres:TEXTq +``` +9. Запустить pgpool +``` +sudo pgpool -n +``` +10. Убедиться, что процесс успешно запущен и подключены 2 ноды с разными индексами. В данном примере для primary node установлен индекс 0, а для standBy ноды установден индекс 1 +``` + +2023-09-14 06:08:08.339: main pid 3941: LOG: find_primary_node: primary node is 0 +2023-09-14 06:08:08.339: main pid 3941: LOG: find_primary_node: standby node is 1 +2023-09-14 06:08:08.343: pcp_main pid 3977: LOG: PCP process: 3977 started +2023-09-14 06:08:08.343: sr_check_worker pid 3978: LOG: process started +2023-09-14 06:08:08.345: health_check pid 3979: LOG: process started +2023-09-14 06:08:08.349: health_check pid 3980: LOG: process started +2023-09-14 06:08:08.559: main pid 3941: LOG: pgpool-II successfully started. version 4.3.5 (tamahomeboshi) +2023-09-14 06:08:08.662: main pid 3941: LOG: node status[0]: 1 +2023-09-14 06:08:08.662: main pid 3941: LOG: node status[1]: 2 + +``` +11. При старте pgpool возможны следующие ошибки: +- файл pgpool_status не найден / нет прав +- pgpool стартует, но ноды имеют одинаковый индекс и балансировка идет только на первую ноду (как проверить балансировку указано ниже)
+ +Проблема решилась удалением файла pgpool_status, откуда pgpool пытался считывать статусы для нод. + +``` +cd /var/log/postgresql +rm -rf pgpool_status +sudo systemctl restart postgresql +sudo pgpool -n +``` + +## 6. Тестирование балансировки PgPool-II +1. При запущенном pgpool (он должен выводить логи), открыть еще один терминал. Зайти в базу, используя Pgpool-II на 9999-порте, выполнив команду +``` +psql -h -p 9999 -d postgres -U postgres +``` + +2. Выполнить команду +``` +show pool_nodes; +``` +3. Убедиться, что обе ноды находятся в статусе up, а балансировка установлена на standBy-сервере (load_balance_node = true) +``` + node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change +---------+--------------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- + 0 | 192.168.0.71 | 5432 | up | up | 0.000000 | primary | primary | 0 | false | 0 | | | 2023-09-14 06:36:16 + 1 | 192.168.0.72 | 5432 | up | up | 1.000000 | standby | standby | 0 | true | 0 | | | 2023-09-14 06:36:16 +(2 rows) + +``` +4. Выполнить команды Insert / Update / Delete (в качесве примера была внесена запись в таблицу public.t_company). Убедиться, что запрос приходит на primary-сервер (нода с индексом 0). + +``` +2023-09-14 07:04:31.800: DBeaver 23.1.2 - Main pid 4805: LOG: DB node id: 0 backend pid: 4814 statement: Execute: INSERT INTO public.t_company (id,caption,id_company_type) + VALUES ($1,$2,$3) + +``` +5. Выполинть команду Select. Убедиться, что запрос приходит на standBy-сервер (нода с индексом 1). +``` + +2023-09-14 07:53:19.275: DBeaver 23.1.2 - Main pid 5069: LOG: DB node id: 1 backend pid: 2745 statement: Execute: SELECT x.* FROM public.t_company x + +``` \ No newline at end of file