sql >> Base de Datos >  >> RDS >> PostgreSQL

Configuración y mantenimiento de la replicación de PostgreSQL con Ansible

La replicación es una función clave para la mayoría de las configuraciones y es compatible con la mayoría de las tecnologías de bases de datos del mercado. La comunidad de PostgreSQL introdujo la replicación en la versión 9.0 (llamada Streaming Replication o SR), desde entonces, la replicación en PostgreSQL ha evolucionado con características adicionales como la replicación en cascada, la decodificación lógica y varias optimizaciones más.

En este blog, veremos el uso del rol postgresql de Ansible desarrollado por "Demonware" (una bifurcación del rol "ANXS/postgresql"). Ya había hablado sobre el uso de la función "ANXS/postgresql" en mi blog anterior, pero no hablé de la función de replicación. El rol de Ansible "postgresql" agrega la capacidad de configurar la replicación de PostgreSQL mediante repmgr.

Acerca de Repmgr

Repmgr es una herramienta de línea de comandos de código abierto desarrollada y mantenida por 2ndQuadrant. La herramienta automatiza la mayoría de las tareas relacionadas con la gestión del clúster de replicación de PostgreSQL. A continuación se muestra la lista de tareas que se pueden realizar sin problemas con el comando repmgr y el demonio repmgrd.

  • Bootstrapping del clúster de replicación de PostgreSQL.
  • Realización de conmutación por error automática y conmutación manual de la instancia principal.
  • Adición y eliminación de instancias en espera (réplica de lectura).

Preparación del nodo del controlador

Prepare el nodo del controlador con el rol de Ansible PostgreSQL, playbooks, inventarios y replicación personalizada de PostgreSQL.

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

En la función descargada, hay dos archivos de variables predeterminados, main.yml y repmgr.yml. Sin embargo, Ansible considerará solo el archivo main.yml. Para hacer que Ansible también use el archivo repmgr.yml, estamos moviendo ambos archivos al directorio defaults/main.

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

Archivo de inventario de Ansible

Para la demostración, configuraremos el clúster de replicación de PostgreSQL en tres nodos. Creé tres máquinas virtuales CentOS vm-01, vm-02 y vm-03, todas ellas se enumeran en el grupo postgres_cluster en el archivo development.yaml.

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

Haga un ping de Ansible y asegúrese de que podamos llegar a todos los hosts del grupo 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"
}

Archivo de variables personalizadas

En el archivo de variables personalizadas custom-vars.yaml, definiremos lo siguiente:

  • Versión de PostgreSQL para instalar y codificación para usar
  • Al modificar la configuración de PostgreSQL para habilitar la replicación, modificaremos los parámetros como wal_level, max_wal_senders, max_replication_slots, hot_standby, archive_mode, archive_command
  • Crear los usuarios y la base de datos necesarios
  • Modificando el archivo pg_hba.conf para permitir la conexión necesaria desde la aplicación y la replicación repmgr
  • Algunas variables relacionadas con 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"

Las siguientes son algunas de las variables notables definidas en custom-vars.yaml:

  • postgresql_version:11 - Instala PostgreSQL versión 11
  • postgresql_ext_install_repmgr:yes:instala la extensión repmgr en el clúster de PostgreSQL
  • repmgr_target_group:"postgres_cluster":Repmgr funciona en los hosts definidos en el grupo "postgres_cluster" definido en el archivo de inventario
  • repmgr_master:"vm-03":el host vm-03 será la instancia principal de PostgreSQL, vm-01 y vm--02 se replicarán desde vm-03

Guía de Ansible

En el siguiente libro de jugadas postgres-play.yaml, asigné el rol postgresql contra el grupo host postgres_cluster. También he incluido el archivo de variables personalizadas custom-vars.yaml que tiene la configuración para PostgreSQL y repmgr.

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

Guía de ejecución de Ansible

Ahora hemos creado los siguientes artefactos de Ansible y estamos listos para ejecutar el libro de jugadas de Ansible.

  • roles/postgresql, directorio de funciones de Ansible.
  • custom-vars.yaml, archivo de variables de Ansible.
  • desarrollo.yaml, archivo de inventario de Ansible.
  • postgres-play.yam, archivo de libro de jugadas de Ansible.

Ejecute el siguiente comando ansible-playbook desde el nodo del controlador. Dado que el rol de postgresql espera el acceso sudo del controlador, estamos especificando la opción -K en el comando, que a su vez nos pide que ingresemos la contraseña SUDO del nodo del controlador.

$ 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

Verifique PLAY RECAP en la salida del comando y asegúrese de que el conteo fallido sea 0.

Comprobar la replicación de PostgreSQL

Con el siguiente comando repmgr cluster show, podemos verificar el estado del clúster de replicación de PostgreSQL. Muestra la función, el estado y la línea de tiempo de todas las instancias de PostgreSQL en el clúster de replicación.

$ 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

Del resultado del comando anterior, vm-03 es el principal y vm-01, vm02 son la instancia en espera que se replica desde el nodo ascendente vm-03. Todas las instancias de PostgreSQL están en estado de ejecución.

Comprobación de la vista pg_stat_replication en la vm-03 principal para confirmar que tanto la vm-01 como la vm-02 se replican correctamente.

$ 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)

Agregar otro nodo en espera al clúster

Para agregar otro nodo de PostgreSQL al clúster, solo tenemos que volver a ejecutar el libro de jugadas de Ansible después de agregar el host en particular en el inventario. En los pasos a continuación, agrego vm-04 a mi clúster de replicación Repmgr Postgresql existente.

  1. Agregar vm-04 al archivo de inventario de Ansiblevelopmeb
    $ cat development.yaml
    all:
      children:
        postgres_cluster:
          hosts:
            vm-01:
            vm-02:
            vm-03:
            vm-04:
          vars:
            ansible_user: "vagrant"
  2. Ejecutar libro de jugadas de Ansible
    $ 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. Verifique el clúster de replicación
    $ 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

Conclusión

Hasta ahora hemos visto cómo configurar el clúster de replicación Repmgr PostgreSQL usando Ansible. Una vez que se ha configurado el clúster repmgr, podemos usar el comando repmgr para realizar otro mantenimiento en el clúster de replicación, como realizar la conmutación por error y el cambio del nodo principal y configurar la replicación en cascada. Consulte la documentación de repmgr para obtener más detalles.