PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Configuração e manutenção da replicação PostgreSQL usando o Ansible


A replicação é um recurso fundamental para a maioria das configurações e é suportada pela maioria das tecnologias de banco de dados no mercado. A comunidade PostgreSQL introduziu a replicação na versão 9.0 (chamada Streaming Replication ou SR), desde então a replicação no PostgreSQL evoluiu com recursos adicionais como replicação em cascata, decodificação lógica e várias outras otimizações.

Neste blog, veremos como usar a função postgresql do Ansible conforme desenvolvida por “Demonware” (um fork da função “ANXS/postgresql”). Eu já havia falado sobre o uso da função “ANXS/postgresql” em meu blog anterior, mas não discuti o recurso de replicação. A função Ansible “postgresql” adiciona a capacidade de configurar a replicação do PostgreSQL usando repmgr.

Sobre Repmgr


Repmgr é uma ferramenta de linha de comando de código aberto desenvolvida e mantida pelo 2ndQuadrant. A ferramenta automatiza a maioria das tarefas relacionadas ao gerenciamento do cluster de replicação do PostgreSQL. Abaixo está a lista de tarefas que podem ser executadas sem problemas usando o comando repmgr e o daemon repmgrd.
  • Reinicializando o cluster de replicação do PostgreSQL.
  • Fazendo failover automático e alternância manual da instância primária.
  • Adicionar e remover instâncias em espera (réplica de leitura).

Preparando o nó do controlador


Prepare o nó do controlador com a função Ansible PostgreSQL, playbooks, inventários e replicação personalizada do PostgreSQL.
$ mkdir demo
$ pushd demo
$ mkdir roles
$ git clone https://github.com/Demonware/postgresql roles/postgresql
$ pushd roles/postgresql
$ git checkout add-repmgr-extension

Na função baixada, há dois arquivos de variáveis ​​padrão main.yml e arquivo repmgr.yml. No entanto, o Ansible considerará apenas o arquivo main.yml. Para fazer o Ansible também usar o arquivo repmgr.yml estamos movendo os dois arquivos para o diretório defaults/main.
$ mkdir defaults/main
$ mv defaults/main.yml defaults/repmgr.yml defaults/main
$ popd

Arquivo de inventário Ansible


Para a demonstração, configuraremos o cluster de replicação do PostgreSQL em três nós. Criei três VMs CentOS vm-01, vm-02 e vm-03, todas listadas no grupo postgres_cluster no arquivo development.yaml.
$ cat development.yaml
all:
  children:
    postgres_cluster:
      hosts:
        vm-01:
        vm-02:
        vm-03:
      vars:
        ansible_user: "vagrant"

Faça o ping do Ansible e verifique se conseguimos alcançar todos os hosts no 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"
}

Arquivo de variável personalizada


No arquivo de variável personalizada custom-vars.yaml, definiremos o seguinte:
  • Versão do PostgreSQL a ser instalada e codificação a ser usada
  • Modificando a configuração do PostgreSQL para habilitar a replicação, modificaremos os parâmetros como wal_level, max_wal_senders, max_replication_slots, hot_standby, archive_mode, archive_command
  • Criando os usuários e o banco de dados necessários
  • Modificando o arquivo pg_hba.conf para permitir a conexão necessária do aplicativo e a replicação repmgr
  • Algumas variáveis ​​relacionadas ao 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"

A seguir estão algumas das variáveis ​​notáveis ​​definidas em custom-vars.yaml:
  • postgresql_version:11 - Instala o PostgreSQL versão 11
  • postgresql_ext_install_repmgr:yes - Instala a extensão repmgr no cluster PostgreSQL
  • repmgr_target_group:"postgres_cluster" - Repmgr funciona nos hosts definidos no grupo "postgres_cluster" definido no arquivo de inventário
  • repmgr_master:"vm-03" - Host vm-03 será a instância primária do PostgreSQL, vm-01 e vm--02 serão replicados de vm-03

Manual do Ansible


No playbook postgres-play.yaml abaixo, atribuí a função postgresql ao grupo de hosts postgres_cluster. Também incluí o arquivo de variável personalizada custom-vars.yaml que tem a configuração para PostgreSQL e repmgr.
$ cat postgres-play.yaml 
- hosts: postgres_cluster
  become: yes
  vars_files:
    - ./custom-vars.yaml
  roles:
    - postgresql

Executando o Ansible Playbook


Agora criamos os seguintes artefatos do Ansible e estamos prontos para executar o playbook do Ansible.
  • roles/postgresql, diretório de funções do Ansible.
  • custom-vars.yaml, arquivo de variável Ansible.
  • development.yaml, arquivo de inventário do Ansible.
  • postgres-play.yam, arquivo de manual do Ansible.

Execute o comando ansible-playbook abaixo do nó do controlador. Como a função postgresql espera o acesso sudo do controlador, estamos especificando a opção -K no comando, que por sua vez nos pede para inserir a senha SUDO do nó do 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 o PLAY RECAP na saída do comando e certifique-se de que a contagem de falhas seja 0.

Verifique a replicação do PostgreSQL


Com o comando repmgr cluster show abaixo, podemos verificar o status do cluster de replicação do PostgreSQL. Ele mostra a função, o status, a linha do tempo de todas as instâncias do PostgreSQL no cluster de replicação.
$ 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

Da saída do comando acima, vm-03 é o primário e vm-01,vm02 são a instância em espera que está replicando do nó upstream vm-03. Todas as instâncias do PostgreSQL estão no estado de execução.

Verificando a visualização pg_stat_replication na vm-03 primária para confirmar que a vm-01 e a vm-02 estão replicando bem.
$ 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)

Adicionando outro nó de espera ao cluster


Para adicionar outro nó PostgreSQL ao cluster, basta executar novamente o playbook do Ansible após adicionar o host específico no inventário. Nas etapas abaixo, estou adicionando vm-04 ao meu cluster de replicação Repmgr Postgresql existente.
  1. Adicionando vm-04 ao arquivo de inventário do Ansible developmentmeb
    $ cat development.yaml
    all:
      children:
        postgres_cluster:
          hosts:
            vm-01:
            vm-02:
            vm-03:
            vm-04:
          vars:
            ansible_user: "vagrant"
  2. Execute o manual do 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. Verificar cluster de replicação
    $ 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

Conclusão


Até agora vimos como configurar o cluster de replicação Repmgr PostgreSQL usando o Ansible. Depois que o cluster repmgr for configurado, podemos usar o comando repmgr para fazer outras manutenções no cluster de replicação, como fazer failover e alternar o nó primário e configurar a replicação em cascata. Por favor, verifique a documentação do repmgr para mais detalhes.