PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Configuration et maintenance de la réplication PostgreSQL avec Ansible

La réplication est une fonctionnalité clé pour la plupart des configurations et elle est prise en charge par la plupart des technologies de base de données sur le marché. La communauté PostgreSQL a introduit la réplication dans la version 9.0 (appelée Streaming Replication ou SR), depuis lors, la réplication dans PostgreSQL a évolué avec des fonctionnalités supplémentaires telles que la réplication en cascade, le décodage logique et plusieurs autres optimisations.

Dans ce blog, nous verrons comment utiliser le rôle Ansible postgresql tel que développé par "Demonware" (un fork du rôle "ANXS/postgresql"). J'avais déjà parlé d'utiliser le rôle "ANXS/postgresql" dans mon blog précédent mais je n'ai pas abordé la fonctionnalité de réplication. Le rôle Ansible "postgresql" ajoute la possibilité de configurer la réplication PostgreSQL à l'aide de repmgr.

À propos de Repmgr

Repmgr est un outil de ligne de commande open source développé et maintenu par 2ndQuadrant. L'outil automatise la plupart des tâches liées à la gestion du cluster de réplication PostgreSQL. Vous trouverez ci-dessous la liste des tâches qui peuvent être effectuées en douceur à l'aide de la commande repmgr et du démon repmgrd.

  • Amorcer le cluster de réplication PostgreSQL.
  • Effectuer un basculement automatique et un basculement manuel de l'instance principale
  • Ajout et suppression des instances de secours (réplica en lecture).

Préparer le nœud du contrôleur

Préparez le nœud de contrôleur avec le rôle Ansible PostgreSQL, les playbooks, les inventaires et la réplication PostgreSQL personnalisée.

$ mkdir demo
$ pushd demo
$ mkdir roles
$ git clone https://github.com/Demonware/postgresql roles/postgresql
$ pushd roles/postgresql
$ git checkout add-repmgr-extension

Dans le rôle téléchargé, il existe deux fichiers de variables par défaut, main.yml et repmgr.yml. Cependant, Ansible ne prendra en compte que le fichier main.yml. Pour qu'Ansible utilise également le fichier repmgr.yml, nous déplaçons les deux fichiers sous le répertoire defaults/main.

$ mkdir defaults/main
$ mv defaults/main.yml defaults/repmgr.yml defaults/main
$ popd

Fichier d'inventaire Ansible

Pour la démo, nous allons configurer le cluster de réplication PostgreSQL sur trois nœuds. J'ai créé trois machines virtuelles CentOS vm-01, vm-02 et vm-03, toutes répertoriées sous le groupe postgres_cluster dans le fichier development.yaml.

$ cat development.yaml
all:
  children:
    postgres_cluster:
      hosts:
        vm-01:
        vm-02:
        vm-03:
      vars:
        ansible_user: "vagrant"

Faites un ping Ansible et assurez-vous que nous pouvons atteindre tous les hôtes sous le groupe postgres_cluster.

$ ansible -i development.yaml -m ping  postgres_cluster
vm-01 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
vm-03 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
vm-02 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Fichier de variables personnalisées

Dans le fichier de variables personnalisées custom-vars.yaml, nous définirons les éléments suivants :

  • Version PostgreSQL à installer et encodage à utiliser
  • En modifiant la configuration de PostgreSQL pour activer la réplication, nous allons modifier les paramètres tels que wal_level, max_wal_senders, max_replication_slots, hot_standby, archive_mode, archive_command
  • Création des utilisateurs et de la base de données nécessaires
  • Modification du fichier pg_hba.conf pour permettre la connexion nécessaire depuis l'application et la réplication repmgr
  • Quelques variables liées à repmgr
$ cat custom-vars.yaml 
# Basic settings
postgresql_version: 11
postgresql_encoding: "UTF-8"
postgresql_locale: "en_US.UTF-8"
postgresql_ctype: "en_US.UTF-8"
postgresql_admin_user: "postgres"
postgresql_default_auth_method: "peer"
postgresql_listen_addresses: "*"
postgresql_wal_level: "replica"
postgresql_max_wal_senders: 10
postgresql_max_replication_slots: 10
postgresql_wal_keep_segments: 100
postgresql_hot_standby: on
postgresql_archive_mode: on
postgresql_archive_command: "/bin/true"
postgresql_shared_preload_libraries:
  - repmgr

postgresql_users:
  - name: "{{repmgr_user}}"
    pass: "password"
postgresql_databases:
  - name: "{{repmgr_database}}"
    owner: "{{repmgr_user}}"
    encoding: "UTF-8"
postgresql_user_privileges:
  - name: "{{repmgr_user}}"
    db: "{{repmgr_database}}"
    priv: "ALL"
    role_attr_flags: "SUPERUSER,REPLICATION"
postgresql_pg_hba_custom:
  - { type: "host", database: "all", user: "all", address: "192.168.0.0/24", method: "md5" }
  - { type: "host", database: "replication", user: "repmgr", address: "192.168.0.0/24", method: "md5" }  
  - { type: "host", database: "replication", user: "repmgr", address: "127.0.0.1/32", method: "md5" }  

# repmgr related variables
postgresql_ext_install_repmgr: yes
repmgr_target_group: "postgres_cluster"
repmgr_target_group_hosts: "{{ groups[repmgr_target_group] }}"
repmgr_master: "vm-03"

Voici quelques-unes des variables notables définies dans custom-vars.yaml :

  • postgresql_version :11 - Installe PostgreSQL version 11
  • postgresql_ext_install_repmgr :oui - Installe l'extension repmgr sur le cluster PostgreSQL
  • repmgr_target_group :"postgres_cluster" - Repmgr fonctionne sur les hôtes définis sous le groupe "postgres_cluster" défini dans le fichier d'inventaire
  • repmgr_master :"vm-03" - L'hôte vm-03 sera l'instance principale de PostgreSQL, vm-01 et vm--02 se répliqueront à partir de vm-03

Livret Ansible

Dans le playbook postgres-play.yaml ci-dessous, j'ai attribué le rôle postgresql au groupe d'hôtes postgres_cluster. J'ai également inclus le fichier de variables personnalisées custom-vars.yaml qui a la configuration pour PostgreSQL et repmgr.

$ cat postgres-play.yaml 
- hosts: postgres_cluster
  become: yes
  vars_files:
    - ./custom-vars.yaml
  roles:
    - postgresql

Exécution d'Ansible Playbook

Nous avons maintenant créé les artefacts Ansible suivants et nous sommes prêts à exécuter le playbook Ansible.

  • roles/postgresql, répertoire des rôles Ansible.
  • custom-vars.yaml, fichier de variables Ansible.
  • development.yaml, fichier d'inventaire Ansible.
  • postgres-play.yam, fichier de livre de lecture Ansible.

Exécutez la commande ansible-playbook ci-dessous à partir du nœud du contrôleur. Étant donné que le rôle postgresql attend l'accès sudo du contrôleur, nous spécifions l'option -K dans la commande, qui à son tour nous demande d'entrer le mot de passe SUDO du nœud du contrôleur.

$ ansible-playbook -Ki development.yaml postgres-play.yaml 
SUDO password: 

PLAY [postgres_cluster] ********************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************************************************
ok: [vm-01]
ok: [vm-02]
ok: [vm-03]
...
...
PLAY RECAP *********************************************************************************************************************************************************************************************************************************************************************
vm-01                      : ok=41   changed=4    unreachable=0    failed=0
vm-02                      : ok=41   changed=5    unreachable=0    failed=0
vm-03                      : ok=43   changed=5    unreachable=0    failed=0

Vérifiez PLAY RECAP dans la sortie de la commande et assurez-vous que le nombre d'échecs est 0.

Vérifier la réplication PostgreSQL

Avec la commande repmgr cluster show ci-dessous, nous pouvons vérifier l'état du cluster de réplication PostgreSQL. Il montre le rôle, le statut, la chronologie de toutes les instances PostgreSQL dans le cluster de réplication.

$ sudo -u postgres /usr/pgsql-11/bin/repmgr -f /etc/postgresql/11/data/repmgr.conf cluster show
 ID | Name  | Role    | Status    | Upstream | Location | Priority | Timeline | Connection string                                     
----+-------+---------+-----------+----------+----------+----------+----------+--------------------------------------------------------
 1  | vm-01 | standby |   running | vm-03    | default  | 100      | 1        | host=vm-01 user=repmgr dbname=repmgr connect_timeout=2
 2  | vm-02 | standby |   running | vm-03    | default  | 100      | 1        | host=vm-02 user=repmgr dbname=repmgr connect_timeout=2
 3  | vm-03 | primary | * running |          | default  | 100      | 1        | host=vm-03 user=repmgr dbname=repmgr connect_timeout=2

D'après la sortie de la commande ci-dessus, vm-03 est l'instance principale et vm-01,vm02 sont l'instance de secours se répliquant à partir du nœud en amont vm-03. Toutes les instances PostgreSQL sont en cours d'exécution.

Vérification de la vue pg_stat_replication sur la vm-03 principale pour confirmer que la vm-01 et la vm-02 se répliquent correctement.

$ sudo -iu postgres /usr/pgsql-11/bin/psql -h vm-03 -c 'select * from pg_stat_replication'
Password for user postgres: 
 pid  | usesysid | usename | application_name |  client_addr  | client_hostname | client_port |         backend_start         | backend_xmin |   state   | sent_lsn  | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | replay_lag | sync_priority | sync_state 
------+----------+---------+------------------+---------------+-----------------+-------------+-------------------------------+--------------+-----------+-----------+-----------+-----------+------------+-----------+-----------+------------+---------------+------------
 8480 |    16384 | repmgr  | vm-02            | 192.168.0.122 |                 |       59972 | 2019-07-18 09:04:44.315859+00 |              | streaming | 0/A000870 | 0/A000870 | 0/A000870 | 0/A000870  |           |           |            |             0 | async
 8481 |    16384 | repmgr  | vm-01            | 192.168.0.121 |                 |       35598 | 2019-07-18 09:04:44.336693+00 |              | streaming | 0/A000870 | 0/A000870 | 0/A000870 | 0/A000870  |           |           |            |             0 | async
(2 rows)

Ajout d'un autre nœud de secours au cluster

Pour ajouter un autre nœud PostgreSQL au cluster, nous devons simplement réexécuter le playbook Ansible après avoir ajouté l'hôte particulier dans l'inventaire. Dans les étapes ci-dessous, j'ajoute vm-04 à mon cluster de réplication Repmgr Postgresql existant.

  1. Ajout de vm-04 au fichier d'inventaire Ansible developmeb
    $ cat development.yaml
    all:
      children:
        postgres_cluster:
          hosts:
            vm-01:
            vm-02:
            vm-03:
            vm-04:
          vars:
            ansible_user: "vagrant"
  2. Exécuter Ansible playbook
    $ ansible-playbook -Ki development.yaml postgres-play.yaml
    SUDO password:
    
    PLAY [postgres_cluster] ********************************************************************************************************************************************************************************************************************************************************
    
    TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************************************************
    ok: [vm-01]
    ok: [vm-04]
    ok: [vm-03]
    ok: [vm-02]
    ...
    ...
    RUNNING HANDLER [postgresql : restart postgresql] ******************************************************************************************************************************************************************************************************************************
    changed: [vm-04]
    changed: [vm-02]
    changed: [vm-01]
    changed: [vm-03]
    
    PLAY RECAP *********************************************************************************************************************************************************************************************************************************************************************
    vm-01                      : ok=41   changed=4    unreachable=0    failed=0
    vm-02                      : ok=41   changed=5    unreachable=0    failed=0
    vm-03                      : ok=43   changed=5    unreachable=0    failed=0
    vm-04                      : ok=46   changed=32   unreachable=0    failed=0
  3. Vérifier le cluster de réplication
    $ sudo -u postgres /usr/pgsql-11/bin/repmgr -f /etc/postgresql/11/data/repmgr.conf cluster show
     ID | Name  | Role    | Status    | Upstream | Location | Priority | Timeline | Connection string                                     
    ----+-------+---------+-----------+----------+----------+----------+----------+--------------------------------------------------------
     1  | vm-01 | standby |   running | vm-03    | default  | 100      | 1        | host=vm-01 user=repmgr dbname=repmgr connect_timeout=2
     2  | vm-02 | standby |   running | vm-03    | default  | 100      | 1        | host=vm-02 user=repmgr dbname=repmgr connect_timeout=2
     3  | vm-03 | primary | * running |          | default  | 100      | 1        | host=vm-03 user=repmgr dbname=repmgr connect_timeout=2
     4  | vm-04 | standby |   running | vm-03    | default  | 100      | 1        | host=vm-04 user=repmgr dbname=repmgr connect_timeout=2

Conclusion

Jusqu'à présent, nous avons vu comment configurer le cluster de réplication Repmgr PostgreSQL à l'aide d'Ansible. Une fois le cluster repmgr configuré, nous pouvons utiliser la commande repmgr pour effectuer d'autres opérations de maintenance sur le cluster de réplication, telles que le basculement et le basculement du nœud principal et la configuration de la réplication en cascade. Veuillez consulter la documentation de repmgr pour plus de détails.