Observação:
- Este tutorial requer acesso ao Oracle Cloud. Para se inscrever e obter uma conta grátis, consulte Conceitos Básicos do Oracle Cloud Infrastructure Free Tier.
- Ele usa valores de exemplo para credenciais, tenancy e compartimentos do Oracle Cloud Infrastructure. Ao concluir o laboratório, substitua esses valores pelos específicos do seu ambiente de nuvem.
Implante um cluster Postgres altamente disponível no Oracle Cloud Infrastructure
Introdução
Este tutorial descreve o design e a implementação do Postgres em uma configuração de HA usando Patroni e outros componentes. PostgreSQL não tem failover automático incorporado e mecanismo automático para adicionar o master com falha de volta ao cluster. Patroni é a nova solução de Alta Disponibilidade (HA) por idade para PostgreSQL com recursos nativos da nuvem e opções avançadas para failover/switchover e configuração de bootstrap e réplica automatizadas.
Patroni é um modelo para criar sua própria solução de HA personalizada usando o Python e para acessibilidade máxima, um armazenamento de configuração distribuído como etcd.
Abaixo estão algumas limitações com replicação de Postgres nativa e sua solução com Patroni:
Limitações na replicação de Postgres nativa | Soluções baseadas em Patroni |
---|---|
O mecanismo de replicação padrão não suporta failover automático. | Patroni fornece failover automático. |
O uso de ferramentas externas para failover pode precisar de esforço adicional para mantê-los ativos e em execução. | Patroni cuida do failover. |
Monitorar Postgres também pode ser um desafio. | Patroni tem um mecanismo incorporado que monitora o serviço Postgres. |
A adição automática do nó com falha de volta ao cluster requer habilidades avançadas de script. | A Patroni tem automação incorporada para trazer de volta um nó com falha para o cluster. |
Não é possível tratar os cenários de Cérebro Dividido. | Patroni com a ajuda do ETCD será capaz de escolher um novo líder. |
Outras soluções de HA PostgreSQL incluem:
- rep.
- PostgreSQL Failover Automático (PAF)
- Perspectiva
- pgPool-II
No entanto, o uso da Patroni com a implementação do Postgres simplifica significativamente o ciclo de vida geral do gerenciamento de cluster.
-
O ETCD é usado como armazenamento de configuração distribuído (DCS). Ele armazena o estado do cluster PostgreSQL. Quando há alterações no estado de qualquer nó PostgreSQL, Patroni atualiza a alteração de estado no armazenamento de chave/valor do ETCD. O ETCD usa essas informações para escolher o nó mestre e mantém o cluster UP e em execução.
-
pgBackrest é uma solução simples e confiável para backups automáticos. Vantagens do Pgbackrest:
- É uma ferramenta de backup físico e você pode fazer backups diferenciais, incrementais e completos
- Jobs paralelos podem ser configurados para fazer backups
- O backup pode ser obtido dos servidores stand-by
- WAL Assíncrono (Gravar Logs de Arquivamento Antecipado) - push e pull
- É possível configurar vários repositórios
- Opções de backup na nuvem para OCI/GCP/S3/Azure
-
O Balanceador de Carga da Rede do OCI é usado para comunicação com o nó Líder em vez de um HAProxy. O Balanceador de Carga de Rede do OCI (Oracle Cloud Infrastructure) que está sendo um serviço gerenciado é facilmente integrado a essa configuração.
Objetivo
Este tutorial lista uma solução viável de alto desempenho com alternativas potenciais para os clientes migrarem bancos de dados Postgres (da AWS ou de outros fornecedores de nuvem) para a OCI. Os principais requisitos são HA e migração de dados em tempo real.
Arquitetura
A arquitetura a seguir consiste em 3 servidores ETCD, 3 (Postgres + Patroni + Pgbackrest), bucket do Object Storage e Balanceador de Carga de Rede.
Recomendações
- Para HA: use 3 Servidores ETCD, 3 nós para PostgreSQL e coloque-os em diferentes Domínios de Disponibilidade.
- Para obter melhor throughput, crie volumes em blocos separados para arquivos de dados, temporários, andares e de log.
- Defina todos os parâmetros personalizados na seção de bootstrap
patroni.yaml
no momento da criação do cluster.
Configurar e instalar os componentes HA PostgreSQL
A configuração é dividida em duas partes:
- Provisionamento de Infraestrutura
- Instalação e configuração do software
Tarefa 1: Provisionar a infraestrutura
-
Crie VMs de computação:
- 3 Servidores ETCD
- 3 servidores para Postgres + Patroni (1 líder e 2 réplica)
-
Crie um Bucket do Object Storage para armazenar backups.
-
Crie um usuário da tenancy do OCI com acesso READ/WRITE no bucket do Object Store acima.
Tarefa 2: Instalar e configurar o software
-
Configurar ETCD.
-
Instale o ETCD em 3 servidores.
cd /tmp wget https://github.com/etcd-io/etcd/releases/download/v3.5.2/etcd-v3.5.2-linux-amd64.tar.gz tar xzvf /tmp/etcd-v3.5.2-linux-amd64.tar.gz cd etcd-v3.5.2-linux-amd64 cp etcdutl etcdctl etcd /usr/local/bin/ mkdir -p /etc/etcd mkdir -p /var/lib/etcd groupadd -f -g 1501 etcd useradd -c "etcd user" -d /var/lib/etcd -s /bin/false -g etcd -u 1501 etcd chown -R etcd:etcd /var/lib/etcd
-
Configure e inicie o ETCD em todos os 3 servidores.
Abaixo estão os detalhes do servidor ETCD:
| Hostname | IP Address | Availability Domain | | --- | --- | --- | | pg-etcd-01 | 192.0.2.4 | AD1 | | pg-etcd-02 | 192.0.2.5 | AD2 | | pg-etcd-03 | 192.0.2.6 | AD3 |
Observação: Modifique IPs de acordo com o requisito.
pg-etcd-01
vi /etc/etcd/etcd.conf ###Node1 ##192.0.2.4 ETCD_NAME="pg-etcd-01" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.4:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.4:2379" ETCD_LISTEN_PEER_URLS="http://192.0.2.4:2380,http://127.0.0.1:7001" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.4:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true"
pg-etcd-02
vi /etc/etcd/etcd.conf ##Node2 ##192.0.2.5 ETCD_NAME=" pg-etcd-02" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380,pg-etcd-02=http://192.0.2.5:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="existing" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.5:2380" ETCD_LISTEN_PEER_URLS="http://192.0.2.5:2380,http://127.0.0.1:7001" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.5:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.5:2379" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true"
pg-etcd-03
vi /etc/etcd/etcd.conf ##Node3 ##192.0.2.6 ETCD_NAME="pg-etcd-03" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380,pg-etcd-02=http://192.0.2.5:2380,pg-etcd-03=http://192.0.2.6:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="existing" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.6:2380" ETCD_LISTEN_PEER_URLS="http://192.0.2.6:2380,http://127.0.0.1:7001" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.6:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.6:2379" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true"
-
Adicione membros a pg-etcd-01.
etcdctl member add pg-etcd-02 --peer-urls=http://192.0.2.5:2380 etcdctl member add pg-etcd-03 --peer-urls=http://192.0.2.6:2380
-
Execute o comando a seguir para exibir a lista de membros.
etcdctl member list
-
Crie um serviço.
vi /etc/systemd/system/etcd.service [Unit] Description=Etcd Server After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify WorkingDirectory=/var/lib/etcd EnvironmentFile=-/etc/etcd/etcd.conf User=etcd # set GOMAXPROCS to number of processors ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/local/bin/etcd" Restart=on-failure LimitNOFILE=65536 IOSchedulingClass=best-effort IOSchedulingPriority=0 [Install] WantedBy=multi-user.target systemctl daemon-reload systemctl enable etcd
-
-
Instale o Postgres em todos os nós. Execute o seguinte script para instalar o Postgres:
-
Script de Instalação do Postgres
Observação: Para Replica, interrompa o postgresql e exclua o diretório de dados, pois ele será copiado do líder depois que a configuração Patroni for concluída.
/opt/pgsql/bin/pg_ctl -D /opt/pgsql/data/$MAJORVERSION stop cd /opt/pgsql/data/ rm *
-
-
Instalar extensões: pg_squeeze e pgaudit.
-
Instalar PGAUDIT
cd /usr/local/src/postgresql-12.6/contrib/ wget https://github.com/pgaudit/pgaudit/archive/refs/heads/REL_12_STABLE.zip unzip REL_12_STABLE.zip make install USE_PGXS=1 PG_CONFIG=/opt/pgsql/bin/pg_config
-
Instalar PG_SQUEEZE
cd /usr/local/src/postgresql-12.6/contrib/ wget https://github.com/cybertec-postgresql/pg_squeeze/archive/refs/heads/master.zip unzip master.zip make install USE_PGXS=1 PG_CONFIG=/opt/pgsql/bin/pg_config
-
-
Instale Patroni em todos os nós.
yum update –y yum -y install epel-release yum -y install python3 yum install -y python3-devel yum install -y psutils yum install -y gcc yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm yum install python3-psycopg2 pip3 install python-etcd pip3 install patroni
-
Instale e configure pgBackrest em todos os nós.
-
Instalar Pgbackrest
yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo yum install pgbackrest -y
-
Configurar Pgbackrest em todos os nós
/etc/pgbackrest.conf [global] repo1-type=s3 repo1-path=/backup repo1-s3-uri-style=path repo1-s3-region=us-ashburn-1 repo1-s3-endpoint=https://xxxxx0011.compat.objectstorage.us-ashburn-1.oraclecloud.com repo1-s3-key=0000000a90d57eddexxxxxa3dc7c4f700000ed2e6 repo1-s3-key-secret=1UhXj69xxxx1e6OyF+00000cccccyyyuuu= repo1-s3-bucket=pg_backup repo1-retention-full=10 log-level-console=info log-level-file=debug log-path=/var/log/pgbackrest/ [stanza-name] pg1-path=/opt/pgsql/data pg1-user=Postgres
-
Criar um arquivo bootstrap em todos os nós
vi /etc/patroni/boot_pgbackrest.sh #!/ usr / bin /env bash while getopts ": -:" optchar ; do [[ "${ optchar }" == "-" ]] || continue case "${ OPTARG }" in datadir =* ) DATA_DIR =${ OPTARG #*=} ;; scope =* ) SCOPE =${ OPTARG #*=} ;; esac done /bin/pgbackrest --stanza=$SCOPE --link-all restore
-
-
Configurar Patroni em todos os nós.
Nome do host Endereço IP Domínio de Disponibilidade pg-db-01 192.0.2.1 AD1 pg-db-02 192.0.2.2 AD2 pg-db-03 192.0.2.3 AD3 Observação: Modifique IPs de acordo com o requisito.
mkdir -p /etc/patroni mkdir -p /opt/pgsql/patroni chown postgres:postgres -R /opt/pgsql/patroni chmod 700 /opt/pgsql/patroni vi /etc/patroni/patroni.yml scope:pg-ha-cluster name:pg-db-01 namespace:/opt/pgsql/patroni/ ### restapi: listen: "192.0.2.1:8008" connect_address: "192.0.2.1:8008" ###ETCD Configuration etcd: hosts: "192.0.2.4:2379,192.0.2.5:2379, 192.0.2.6:2379" ###Bootstrap bootstrap: dcs: ttl: 120 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true use_slots: true parameters: archive_command: "pgbackrest --stanza=<stanza-name> archive-push %p" archive_mode: on archive_timeout: 900s log_file_mode: "0640" log_filename: postgresql-%u.log log_rotation_age: 1d log_truncate_on_rotation: "on" logging_collector: "on" max_connections: 2000 max_replication_slots: 10 max_wal_senders: 10 max_wal_size: 5GB max_worker_processes: 40 min_wal_size: 1GB wal_level: "replica" password_encryption: scram-sha-256 superuser_reserved_connections: 200 create_replica_methods: - pgbackrest pgbackrest: command: "/usr/bin/pgbackrest --stanza=<stanza-name> restore --delta --link-all" keep_data: True no_params: True recovery_conf: recovery_target_timeline: latest restore_command: '/usr/bin/pgbackrest --stanza=<stanza-name> archive-get %f %P' method: pgbackrest pgbackrest: command: /etc/patroni/boot_pgbackrest.sh keep_existing_recovery_conf: False recovery_conf: recovery_target_timeline: latest restore_command: '/usr/bin/pgbackrest --stanza=<stanza-name> archive-get %f %P' initdb: - encoding: UTF8 - data-checksums pg_hba: - host replication replicator 127.0.0.1/32 md5 - host replication replicator 192.0.2.1/32 md5 - host replication replicator 192.0.2.2/32 md5 - host replication replicator 192.0.2.3/32 md5 - host all all x.x.x.0/0 md5 users: admin: password: admin options: - createrole - createdb #####Local Postgresql Parameters postgresql: listen: "192.0.2.1:5432" connect_address: "192.0.2.1:5432" data_dir: /opt/pgsql/data pgpass: /opt/pgsql/patroni/pgpass authentication: replication: username: replicator password: password superuser: username: postgres password: password # rewind: # username: replicator # password: password parameters: unix_socket_directories: "/var/run/postgresql, /tmp" ###Any Tags tags: nofailover: false noloadbalance: false clonefrom: false nosync: false
Observação: Altere o IP para cada nó, respectivamente.
chmod 640 /etc/patroni/patroni.yml chown postgres:postgres -R /etc/patroni/patroni.yml
- Criar Serviço Patroni em todos os nós
vi /etc/systemd/system/patroni.service [Unit] Description=Runners to orchestrate a high-availability PostgreSQL - patroni After=syslog.target network.target [Service] Type=simple User=postgres Group=postgres # Read in configuration file if it exists, otherwise proceed EnvironmentFile=-/etc/patroni_env.conf WorkingDirectory=~ # Where to send early-startup messages from the server # This is normally controlled by the global default set by systemd # StandardOutput=syslog
# Pre-commands to start watchdog device # Uncomment if watchdog is part of your patroni setup #ExecStartPre=-/usr/bin/sudo /sbin/modprobe softdog #ExecStartPre=-/usr/bin/sudo /bin/chown postgres /dev/watchdog # Start the patroni process ExecStart=/usr/local/bin/patroni /etc/patroni/patroni.yml # Send HUP to reload from patroni.yml ExecReload=/bin/kill -s HUP $MAINPID # Only kill the patroni process, not its children, so it will gracefully stop postgres KillMode=process # Give a reasonable amount of time for the server to start up/shut down TimeoutSec=60 # Do not restart the service if it crashes, we want to manually inspect database on failure Restart=no [Install] WantedBy=multi-user.target sudo systemctl daemon-reload sudo systemctl enable patroni sudo systemctl start patroni sudo systemctl status patroni
Observação: Em nós de Réplica, configure o Patroni; no entanto, não inicie os serviços.
-
Execute o seguinte comando para ver o status do cluster Patroni no Mestre.
patronictl -c /etc/patroni/patroni.yml list [root@pg-db-01 ~]# /usr/local/bin/patronictl -c /etc/patroni/patroni.yml list +--------------+-------------+---------+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | + Cluster: pg-ha-cluster (7089354141421597068) --+----+-----------+ | pg-db-01 | 192.0.2.1 | Leader | running | 1 | | +--------------+-------------+---------+---------+----+-----------+
-
Crie Stanza e faça backup completo.
pgbackrest --stanza=<stanza-name> stanza-create pgbackrest --type=full --stanza= pgha --process-max=10 backup pgbackrest info
-
Inicie o Patroni nos nós da réplica e ele deve começar a recuperar automaticamente do Líder.
sudo systemctl start patroni sudo systemctl status patroni
- Execute o seguinte comando para ver o status do cluster:
patronictl -c /etc/patroni/patroni.yml list
O status deve ser o seguinte:
[root@pg-db-01 ~]# /usr/local/bin/patronictl -c /etc/patroni/patroni.yml list +--------------+-------------+---------+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | + Cluster: pg-ha-cluster (7089354141421597068) --+----+-----------+ | pg-db-01 | 192.0.2.1 | Leader | running | 2 | | | pg-db-02 | 192.0.2.2 | Replica | running |2 | 0 | | pg-db-03 | 192.0.2.3 | Replica | running | 2 | 0 | +--------------+-------------+---------+---------+----+-----------+
-
Por fim, configure os jobs cron para limpeza de log, backups etc.
crontab –e #Pgbackrest FULL Backup on Sunday @1AM 00 01 * * 0 postgres pgbackrest --type=full --stanza=ash1-adeprod1-pgcluster --process-max=10 backup &> /dev/null #Pgbackrest INC Backup on Mon-Sat @1AM 00 01 * * 1-6 postgres pgbackrest --type=diff --stanza=ash1-adeprod1-pgcluster --process-max=10 backup &> /dev/null #Delete PostgreSQL logs 08 * * * find /opt/pgsql/log/* -mtime +15 -exec rm {} \; &>/dev/null
Comandos Patroni Adicionais
-
Membros da lista
patronictl -c /etc/patroni/patroni.yml list
-
Failover/Reiniciar/Fazer Switchover
patronictl -c /etc/patroni/patroni.yml failover patronictl -c /etc/patroni/patroni.yml restart patronictl -c /etc/patroni/patroni.yml switchover
-
Atualizar parâmetro
patronictl -c /etc/patroni/patroni.yml edit-config -p log_directory='/opt/pgsql/log/' patronictl -c /etc/patroni/patroni.yml show-config
-
Recarregar
patronictl -c /etc/patroni/patroni.yml reload <cluster_name>
Links Relacionados
- Como Criar Instância do Linux
- Visão Geral do Bucket do Object Storage
- Criando Usuários do IAM
- Como criar o Balanceador de Carga de Rede
- Trabalhando com a chave do cliente
- PostgreSQL Fazer Download
- PostgresSQL Instalações
- Patroni
- Instalar Etcd
Confirmações
- Autores: Deepika Nayak, Shreyas Rane, Divya Das
Mais Recursos de Aprendizagem
Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal YouTube do Oracle Learning. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.
Para obter a documentação do produto, visite o Oracle Help Center.
Deploy a highly available Postgres cluster on Oracle Cloud Infrastructure
F74179-01
November 2022
Copyright © 2022, Oracle and/or its affiliates.