diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/README.md b/docs/source/pages/Replicacao/pgpool_exemplo/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e5b9d452432d3301aa6aae853ae24887a5f3208a --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/README.md @@ -0,0 +1,33 @@ +# Replicação PosgreSQL utilizando pgpool2 + +Este diretório contém uma implantação de um cluster pgpool em Docker, utilizando +docker compose para fornecer a infraestrutura. + +A topologia desse sistema consiste em dois PSQL 16, que são os backends do +sistema de replicação e 3 nodos do pgpool, que atuarão como watchdogs. +O número de backends pode variar conforme necessário, assim como os nodos +watchdogs. No entanto, os watchdogs sempre devem estar em quantidade Ãmpar maior +ou igual a três, para que haja consenso na rede. + +Este exemplo foi adaptado da página oficial do pgpool: +https://www.pgpool.net/docs/latest/en/html/example-cluster.html + +Mas o código não está sucificientemente documentado, então recomendo que siga o +guia do link para entender como as coisas se encaixam, e como devem ser +executadas. + +## Executando a implantação +Para subir o sistema, basta utilizar o compose: +```bash +docker compose up -d +``` + +Após isso, alguns comandos devem ser executados para inicializar o sistema. +Este comando estão descritos em `notes.sh`, para entender a função deles, leia +o documentação préviamente citada. + + +## Liks úteis + +### Termos e visão geral de uma replicação pgpool2 +https://www.postgresql.fastware.com/postgresql-insider-ha-pgpool-ii \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/docker-compose.yml b/docs/source/pages/Replicacao/pgpool_exemplo/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..3f86fe584a10e627b92710ccc93442db3e6d8ab0 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/docker-compose.yml @@ -0,0 +1,125 @@ +services: + + pgpool-build: + build: + context: pgpool + network: host + image: my-pgpool:1 + entrypoint: ["echo", "Done."] + + + postgres-build: + build: + context: postgres + network: host + image: my-postgres:1 + entrypoint: ["echo", "Done."] + + + pgpool1: + depends_on: + - pgpool-build + + image: my-pgpool:1 + + hostname: pgpool1 + container_name: pgpool1 + + volumes: + - /etc/localtime:/etc/localtime:ro + + environment: + - NODE_ID=0 + + cap_add: + - NET_ADMIN + + networks: + - cluster_network + + + pgpool2: + depends_on: + - pgpool-build + + image: my-pgpool:1 + + hostname: pgpool2 + container_name: pgpool2 + + volumes: + - /etc/localtime:/etc/localtime:ro + + environment: + - NODE_ID=1 + + cap_add: + - NET_ADMIN + + networks: + - cluster_network + + + pgpool3: + depends_on: + - pgpool-build + + image: my-pgpool:1 + + hostname: pgpool3 + container_name: pgpool3 + + volumes: + - /etc/localtime:/etc/localtime:ro + + environment: + - NODE_ID=2 + + cap_add: + - NET_ADMIN + + networks: + - cluster_network + + + postgres1: + depends_on: + - postgres-build + + image: my-postgres:1 + + hostname: postgres1 + container_name: postgres1 + + volumes: + - /etc/localtime:/etc/localtime:ro + + networks: + - cluster_network + + environment: + - PRIMARY=true + + + postgres2: + depends_on: + - postgres-build + + image: my-postgres:1 + + hostname: postgres2 + container_name: postgres2 + + volumes: + - /etc/localtime:/etc/localtime:ro + + networks: + - cluster_network + + +networks: + cluster_network: + ipam: + driver: default + config: + - subnet: 172.20.0.0/16 diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/notes.sh b/docs/source/pages/Replicacao/pgpool_exemplo/notes.sh new file mode 100644 index 0000000000000000000000000000000000000000..e593d83821302d660f34210c7689f29402194700 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/notes.sh @@ -0,0 +1,37 @@ +# start psql +service postgresql start + +# start pgpool +pgpool + + + +# RUN ON PRIMARY +su postgres +psql + +SET password_encryption = 'scram-sha-256'; +CREATE ROLE pgpool WITH LOGIN; +CREATE ROLE repl WITH REPLICATION LOGIN; +GRANT pg_monitor TO pgpool; + +\password pgpool +\password repl +\password postgres + + +psql template1 -c "CREATE EXTENSION pgpool_recovery" + +psql -h 172.20.0.39 -p 9999 -U pgpool postgres -c "show pool_nodes" +pcp_watchdog_info -h 172.20.0.39 -p 9898 -U pgpool -W + +pcp_recovery_node -h 172.20.0.39 -p 9898 -U pgpool -n 1 -W + + +docker exec -u postgres -ti pgpool1 pgpool stop +docker exec -u postgres -ti pgpool2 pgpool stop +docker exec -u postgres -ti pgpool3 pgpool stop +docker exec -u postgres -ti pgpool1 pgpool +docker exec -u postgres -ti pgpool2 pgpool +docker exec -u postgres -ti pgpool3 pgpool + diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/.pcppass b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/.pcppass new file mode 100644 index 0000000000000000000000000000000000000000..ff1ab189dd02c4a29e5e3bc3b165b949b0f7a3b1 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/.pcppass @@ -0,0 +1 @@ +localhost:9898:pgpool:123mudar \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/.pgpass b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/.pgpass new file mode 100644 index 0000000000000000000000000000000000000000..5df0ab6102325280d5fcdd3c6554b8848e26b6a2 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/.pgpass @@ -0,0 +1,4 @@ +postgres1:5432:replication:repl:123mudar +postgres2:5432:replication:repl:123mudar +postgres1:5432:postgres:postgres:123mudar +postgres2:5432:postgres:postgres:123mudar \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/Dockerfile b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..cf6e245fd6b6697a5e6585458824bc37b617497a --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/Dockerfile @@ -0,0 +1,85 @@ +FROM debian:bookworm + +USER root +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +# Setup repository and install Install pgpool-2 +RUN apt-get install -y curl ca-certificates +RUN install -d /usr/share/postgresql-common/pgdg +RUN curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc +RUN sh -c 'echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" > /etc/apt/sources.list.d/pgdg.list' +RUN apt-get update +RUN apt-get -y install pgpool2 libpgpool2 postgresql-16-pgpool2 + +# Install SSH and other utils +RUN apt-get install -y keychain \ +openssh-server \ +arping \ +iproute2 \ +sudo \ +vim + +# Allow postgres user to run sudo w/o passwd +RUN echo 'postgres ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + +# Add the password for PCP +WORKDIR /etc/pgpool2 +RUN echo 'pgpool:89794b621a313bb59eed0d9f0f4e8205' >> pcp.conf + +# Copy conf files +COPY pgpool.conf pgpool.conf +COPY pool_hba.conf pool_hba.conf +RUN chown root:postgres pgpool.conf pool_hba.conf +RUN chmod 640 pgpool.conf pool_hba.conf + +# Create log dir +RUN mkdir /var/log/pgpool_log +RUN chown postgres:postgres /var/log/pgpool_log + +# Set credentials to login to psql +WORKDIR /var/lib/postgresql +COPY .pgpass .pgpass +RUN chown postgres:postgres .pgpass +RUN chmod 600 .pgpass + +# Setting scripts +WORKDIR /etc/pgpool2 +COPY scripts/failover.sh failover.sh +COPY scripts/follow_primary.sh follow_primary.sh +COPY scripts/escalation.sh escalation.sh +RUN chown postgres:postgres failover.sh follow_primary.sh escalation.sh +RUN chmod 550 failover.sh follow_primary.sh escalation.sh + +# Setting pool_passwd +WORKDIR /var/lib/postgresql +RUN echo "VerySecretKey" > .pgpoolkey +RUN chown postgres:postgres .pgpoolkey +RUN chmod 600 .pgpoolkey + +WORKDIR /etc/pgpool2 +RUN chmod 660 pool_passwd + +WORKDIR /var/lib/postgresql +RUN pg_enc -m -k .pgpoolkey -u pgpool 123mudar +RUN pg_enc -m -k .pgpoolkey -u postgres 123mudar + +# Set ssh keys and authorizations +WORKDIR /var/lib/postgresql/.ssh +COPY authorized_keys authorized_keys +COPY id_rsa_pgpool id_rsa_pgpool +COPY id_rsa_pgpool.pub id_rsa_pgpool.pub +RUN chmod 644 authorized_keys +RUN chmod 600 id_rsa_pgpool +RUN chmod 644 id_rsa_pgpool.pub +RUN chown postgres:postgres id_rsa_pgpool id_rsa_pgpool.pub authorized_keys + + +# Setup entrypoint +USER root +COPY entrypoint.sh /home/entrypoint.sh +WORKDIR /home +RUN chmod +x ./entrypoint.sh + +ENTRYPOINT ["/bin/sh", "-c" , "./entrypoint.sh"] diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/authorized_keys b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/authorized_keys new file mode 100644 index 0000000000000000000000000000000000000000..ce3aed042c0fd900daa35ade91a7475ee97cb691 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/authorized_keys @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC6+rAChjlbTGamRpX/Zlluy9CmMwt/MLSV1FQvKoT4pimOY+W353QUQu6QhP+w7fGJ0x6276wpAs623Li14ij6JuAbBEz3VYGlm6+eePfKU/TO59X3HGaAKAo1y7PEfpV+nHumDa/xvqpkLEgorc3QcloH9Ia7zEYdvYbuH1JDWqbyCUedTnC8PCeq38nA6E3hO9lmZVNrXH6CUbrmclLTwIv20lmPkv2OqcbL35hQ/tEwCdg67G4WFcMUPhJKiETnUKmW2H836yjIPYAvx1ikbL4N911G7veREAbrUkWxDB1EAN6YW/dxnS+JjgdAbQfChNeHXH/b7qN3KwX2cjcehA2jAJlFApW1KKNgm4UOIOFEIb9DpIpkiWGut20K0v6Yo7m5SE0IMS3MKc3WRbvtdVM8wOzMmRuMHBlGvX88lGVX96chtEk5RAW6cYYTGcSN6OZSZn6zi9seKCgzbgw5wq1PSGu+4gr08WyPzHHzfxr2Xbkbn9+rkiQAohx0W/E= \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/entrypoint.sh b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/entrypoint.sh new file mode 100644 index 0000000000000000000000000000000000000000..b4aef20f25e997db0eacb1b4c20af9ab1dc51899 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/entrypoint.sh @@ -0,0 +1,5 @@ +echo $NODE_ID > /etc/pgpool2/pgpool_node_id + +service ssh start + +sleep infinity diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/id_rsa_pgpool b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/id_rsa_pgpool new file mode 100644 index 0000000000000000000000000000000000000000..321a6d1d5785c433af778d825da6981a6d44b7dc --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/id_rsa_pgpool @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +-----END OPENSSH PRIVATE KEY----- diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/id_rsa_pgpool.pub b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/id_rsa_pgpool.pub new file mode 100644 index 0000000000000000000000000000000000000000..ce3aed042c0fd900daa35ade91a7475ee97cb691 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/id_rsa_pgpool.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC6+rAChjlbTGamRpX/Zlluy9CmMwt/MLSV1FQvKoT4pimOY+W353QUQu6QhP+w7fGJ0x6276wpAs623Li14ij6JuAbBEz3VYGlm6+eePfKU/TO59X3HGaAKAo1y7PEfpV+nHumDa/xvqpkLEgorc3QcloH9Ia7zEYdvYbuH1JDWqbyCUedTnC8PCeq38nA6E3hO9lmZVNrXH6CUbrmclLTwIv20lmPkv2OqcbL35hQ/tEwCdg67G4WFcMUPhJKiETnUKmW2H836yjIPYAvx1ikbL4N911G7veREAbrUkWxDB1EAN6YW/dxnS+JjgdAbQfChNeHXH/b7qN3KwX2cjcehA2jAJlFApW1KKNgm4UOIOFEIb9DpIpkiWGut20K0v6Yo7m5SE0IMS3MKc3WRbvtdVM8wOzMmRuMHBlGvX88lGVX96chtEk5RAW6cYYTGcSN6OZSZn6zi9seKCgzbgw5wq1PSGu+4gr08WyPzHHzfxr2Xbkbn9+rkiQAohx0W/E= \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/pcp.conf b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/pcp.conf new file mode 100644 index 0000000000000000000000000000000000000000..f9b54de04c50a6dafad9c010dceebc122df27bca --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/pcp.conf @@ -0,0 +1,29 @@ +# PCP Client Authentication Configuration File +# ============================================ +# +# This file contains user ID and his password for pgpool +# communication manager authentication. +# +# Note that users defined here do not need to be PostgreSQL +# users. These users are authorized ONLY for pgpool +# communication manager. +# +# File Format +# =========== +# +# List one UserID and password on a single line. They must +# be concatenated together using ':' (colon) between them. +# No spaces or tabs are allowed anywhere in the line. +# +# Example: +# postgres:e8a48653851e28c69d0506508fb27fc5 +# +# Be aware that there will be no spaces or tabs at the +# beginning of the line! although the above example looks +# like so. +# +# Lines beginning with '#' (pound) are comments and will +# be ignored. Again, no spaces or tabs allowed before '#'. + +# USERID:MD5PASSWD +pgpool:89794b621a313bb59eed0d9f0f4e8205 \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/pgpool.conf b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/pgpool.conf new file mode 100644 index 0000000000000000000000000000000000000000..17fb5c6283866b6ac9042c85b88967d2e53931b7 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/pgpool.conf @@ -0,0 +1,1036 @@ +# ---------------------------- +# pgPool-II configuration file +# ---------------------------- +# +# This file consists of lines of the form: +# +# name = value +# +# Whitespace may be used. Comments are introduced with "#" anywhere on a line. +# The complete list of parameter names and allowed values can be found in the +# pgPool-II documentation. +# +# This file is read on server startup and when the server receives a SIGHUP +# signal. If you edit the file on a running system, you have to SIGHUP the +# server for the changes to take effect, or use "pgpool reload". Some +# parameters, which are marked below, require a server shutdown and restart to +# take effect. +# + +#------------------------------------------------------------------------------ +# BACKEND CLUSTERING MODE +# Choose one of: 'streaming_replication', 'native_replication', +# 'logical_replication', 'slony', 'raw' or 'snapshot_isolation' +# (change requires restart) +#------------------------------------------------------------------------------ + +backend_clustering_mode = 'streaming_replication' + +#------------------------------------------------------------------------------ +# CONNECTIONS +#------------------------------------------------------------------------------ + +# - pgpool Connection Settings - + +#listen_addresses = 'localhost' + # Host name or IP address to listen on: + # '*' for all, '' for no TCP/IP connections + # (change requires restart) +#port = 5433 + # Port number + # (change requires restart) +#socket_dir = '/var/run/postgresql' + # Unix domain socket path + # The Debian package defaults to + # /var/run/postgresql + # (change requires restart) +#reserved_connections = 0 + # Number of reserved connections. + # Pgpool-II does not accept connections if over + # num_init_chidlren - reserved_connections. + + +# - pgpool Communication Manager Connection Settings - + +#pcp_listen_addresses = 'localhost' + # Host name or IP address for pcp process to listen on: + # '*' for all, '' for no TCP/IP connections + # (change requires restart) +#pcp_port = 9898 + # Port number for pcp + # (change requires restart) +#pcp_socket_dir = '/var/run/postgresql' + # Unix domain socket path for pcp + # The Debian package defaults to + # /var/run/postgresql + # (change requires restart) +#listen_backlog_multiplier = 2 + # Set the backlog parameter of listen(2) to + # num_init_children * listen_backlog_multiplier. + # (change requires restart) +#serialize_accept = off + # whether to serialize accept() call to avoid thundering herd problem + # (change requires restart) + +# - Backend Connection Settings - + +#backend_hostname0 = 'host1' + # Host name or IP address to connect to for backend 0 +#backend_port0 = 5432 + # Port number for backend 0 +#backend_weight0 = 1 + # Weight for backend 0 (only in load balancing mode) +#backend_data_directory0 = '/data' + # Data directory for backend 0 +#backend_flag0 = 'ALLOW_TO_FAILOVER' + # Controls various backend behavior + # ALLOW_TO_FAILOVER, DISALLOW_TO_FAILOVER + # or ALWAYS_PRIMARY +#backend_application_name0 = 'server0' + # walsender's application_name, used for "show pool_nodes" command +#backend_hostname1 = 'host2' +#backend_port1 = 5433 +#backend_weight1 = 1 +#backend_data_directory1 = '/data1' +#backend_flag1 = 'ALLOW_TO_FAILOVER' +#backend_application_name1 = 'server1' + +# - Authentication - + +#enable_pool_hba = off + # Use pool_hba.conf for client authentication +#pool_passwd = 'pool_passwd' + # File name of pool_passwd for md5 authentication. + # "" disables pool_passwd. + # (change requires restart) +#authentication_timeout = 1min + # Delay in seconds to complete client authentication + # 0 means no timeout. + +#allow_clear_text_frontend_auth = off + # Allow Pgpool-II to use clear text password authentication + # with clients, when pool_passwd does not + # contain the user password + +# - SSL Connections - + +#ssl = off + # Enable SSL support + # (change requires restart) +#ssl_key = 'server.key' + # SSL private key file + # (change requires restart) +#ssl_cert = 'server.crt' + # SSL public certificate file + # (change requires restart) +#ssl_ca_cert = '' + # Single PEM format file containing + # CA root certificate(s) + # (change requires restart) +#ssl_ca_cert_dir = '' + # Directory containing CA root certificate(s) + # (change requires restart) +#ssl_crl_file = '' + # SSL certificate revocation list file + # (change requires restart) + +#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' + # Allowed SSL ciphers + # (change requires restart) +#ssl_prefer_server_ciphers = off + # Use server's SSL cipher preferences, + # rather than the client's + # (change requires restart) +#ssl_ecdh_curve = 'prime256v1' + # Name of the curve to use in ECDH key exchange +#ssl_dh_params_file = '' + # Name of the file containing Diffie-Hellman parameters used + # for so-called ephemeral DH family of SSL cipher. +#ssl_passphrase_command='' + # Sets an external command to be invoked when a passphrase + # for decrypting an SSL file needs to be obtained + # (change requires restart) + +#------------------------------------------------------------------------------ +# POOLS +#------------------------------------------------------------------------------ + +# - Concurrent session and pool size - + +#num_init_children = 32 + # Number of concurrent sessions allowed + # (change requires restart) +#max_pool = 4 + # Number of connection pool caches per connection + # (change requires restart) + +# - Life time - + +#child_life_time = 5min + # Pool exits after being idle for this many seconds +#child_max_connections = 0 + # Pool exits after receiving that many connections + # 0 means no exit +#connection_life_time = 0 + # Connection to backend closes after being idle for this many seconds + # 0 means no close +#client_idle_limit = 0 + # Client is disconnected after being idle for that many seconds + # (even inside an explicit transactions!) + # 0 means no disconnection + + +#------------------------------------------------------------------------------ +# LOGS +#------------------------------------------------------------------------------ + +# - Where to log - + +#log_destination = 'stderr' + # Where to log + # Valid values are combinations of stderr, + # and syslog. Default to stderr. + +# - What to log - + +#log_line_prefix = '%m: %a pid %p: ' # printf-style string to output at beginning of each log line. + +#log_connections = off + # Log connections +#log_disconnections = off + # Log disconnections +#log_hostname = off + # Hostname will be shown in ps status + # and in logs if connections are logged +#log_statement = off + # Log all statements +#log_per_node_statement = off + # Log all statements + # with node and backend informations +#log_client_messages = off + # Log any client messages +#log_standby_delay = 'if_over_threshold' + # Log standby delay + # Valid values are combinations of always, + # if_over_threshold, none + +# - Syslog specific - + +#syslog_facility = 'LOCAL0' + # Syslog local facility. Default to LOCAL0 +#syslog_ident = 'pgpool' + # Syslog program identification string + # Default to 'pgpool' + +# - Debug - + +#log_error_verbosity = default # terse, default, or verbose messages + +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error + +#log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + +# This is used when logging to stderr: +#logging_collector = off + # Enable capturing of stderr + # into log files. + # (change requires restart) + +# -- Only used if logging_collector is on --- + +#log_directory = '/tmp/pgpool_logs' + # directory where log files are written, + # can be absolute +#log_filename = 'pgpool-%Y-%m-%d_%H%M%S.log' + # log file name pattern, + # can include strftime() escapes + +#log_file_mode = 0600 + # creation mode for log files, + # begin with 0 to use octal notation + +#log_truncate_on_rotation = off + # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. + +#log_rotation_age = 1d + # Automatic rotation of logfiles will + # happen after that (minutes)time. + # 0 disables time based rotation. +#log_rotation_size = 10MB + # Automatic rotation of logfiles will + # happen after that much (KB) log output. + # 0 disables size based rotation. +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +#pid_file_name = '/var/run/postgresql/pgpool.pid' + # PID file name + # Can be specified as relative to the" + # location of pgpool.conf file or + # as an absolute path + # (change requires restart) +#logdir = '/var/log/postgresql' + # Directory of pgPool status file + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONNECTION POOLING +#------------------------------------------------------------------------------ + +#connection_cache = on + # Activate connection pools + # (change requires restart) + + # Semicolon separated list of queries + # to be issued at the end of a session + # The default is for 8.3 and later +#reset_query_list = 'ABORT; DISCARD ALL' + # The following one is for 8.2 and before +#reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' + + +#------------------------------------------------------------------------------ +# REPLICATION MODE +#------------------------------------------------------------------------------ + +#replicate_select = off + # Replicate SELECT statements + # when in replication mode + # replicate_select is higher priority than + # load_balance_mode. + +#insert_lock = off + # Automatically locks a dummy row or a table + # with INSERT statements to keep SERIAL data + # consistency + # Without SERIAL, no lock will be issued +#lobj_lock_table = '' + # When rewriting lo_creat command in + # replication mode, specify table name to + # lock + +# - Degenerate handling - + +#replication_stop_on_mismatch = off + # On disagreement with the packet kind + # sent from backend, degenerate the node + # which is most likely "minority" + # If off, just force to exit this session + +#failover_if_affected_tuples_mismatch = off + # On disagreement with the number of affected + # tuples in UPDATE/DELETE queries, then + # degenerate the node which is most likely + # "minority". + # If off, just abort the transaction to + # keep the consistency + + +#------------------------------------------------------------------------------ +# LOAD BALANCING MODE +#------------------------------------------------------------------------------ + +#load_balance_mode = on + # Activate load balancing mode + # (change requires restart) +#ignore_leading_white_space = on + # Ignore leading white spaces of each query +#read_only_function_list = '' + # Comma separated list of function names + # that don't write to database + # Regexp are accepted +#write_function_list = '' + # Comma separated list of function names + # that write to database + # Regexp are accepted + # If both read_only_function_list and write_function_list + # is empty, function's volatile property is checked. + # If it's volatile, the function is regarded as a + # writing function. + +#primary_routing_query_pattern_list = '' + # Semicolon separated list of query patterns + # that should be sent to primary node + # Regexp are accepted + # valid for streaming replicaton mode only. + +#database_redirect_preference_list = '' + # comma separated list of pairs of database and node id. + # example: postgres:primary,mydb[0-4]:1,mydb[5-9]:2' + # valid for streaming replicaton mode only. + +#app_name_redirect_preference_list = '' + # comma separated list of pairs of app name and node id. + # example: 'psql:primary,myapp[0-4]:1,myapp[5-9]:standby' + # valid for streaming replicaton mode only. +#allow_sql_comments = off + # if on, ignore SQL comments when judging if load balance or + # query cache is possible. + # If off, SQL comments effectively prevent the judgment + # (pre 3.4 behavior). + +#disable_load_balance_on_write = 'transaction' + # Load balance behavior when write query is issued + # in an explicit transaction. + # + # Valid values: + # + # 'transaction' (default): + # if a write query is issued, subsequent + # read queries will not be load balanced + # until the transaction ends. + # + # 'trans_transaction': + # if a write query is issued, subsequent + # read queries in an explicit transaction + # will not be load balanced until the session ends. + # + # 'dml_adaptive': + # Queries on the tables that have already been + # modified within the current explicit transaction will + # not be load balanced until the end of the transaction. + # + # 'always': + # if a write query is issued, read queries will + # not be load balanced until the session ends. + # + # Note that any query not in an explicit transaction + # is not affected by the parameter except 'always'. + +#dml_adaptive_object_relationship_list= '' + # comma separated list of object pairs + # [object]:[dependent-object], to disable load balancing + # of dependent objects within the explicit transaction + # after WRITE statement is issued on (depending-on) object. + # + # example: 'tb_t1:tb_t2,insert_tb_f_func():tb_f,tb_v:my_view' + # Note: function name in this list must also be present in + # the write_function_list + # only valid for disable_load_balance_on_write = 'dml_adaptive'. + +#statement_level_load_balance = off + # Enables statement level load balancing + +#------------------------------------------------------------------------------ +# STREAMING REPLICATION MODE +#------------------------------------------------------------------------------ + +# - Streaming - + +#sr_check_period = 10 + # Streaming replication check period + # Disabled (0) by default +#sr_check_user = 'nobody' + # Streaming replication check user + # This is neccessary even if you disable streaming + # replication delay check by sr_check_period = 0 +#sr_check_password = '' + # Password for streaming replication check user + # Leaving it empty will make Pgpool-II to first look for the + # Password in pool_passwd file before using the empty password + +#sr_check_database = 'postgres' + # Database name for streaming replication check +#delay_threshold = 0 + # Threshold before not dispatching query to standby node + # Unit is in bytes + # Disabled (0) by default +#prefer_lower_delay_standby = off + # If delay_threshold is set larger than 0, Pgpool-II send to + # the primary when selected node is delayed over delay_threshold. + # If this is set to on, Pgpool-II send query to other standby + # delayed lower. + +# - Special commands - + +#follow_primary_command = '' + # Executes this command after main node failover + # Special values: + # %d = failed node id + # %h = failed node host name + # %p = failed node port number + # %D = failed node database cluster path + # %m = new main node id + # %H = new main node hostname + # %M = old main node id + # %P = old primary node id + # %r = new main port number + # %R = new main database cluster path + # %N = old primary node hostname + # %S = old primary node port number + # %% = '%' character + +#------------------------------------------------------------------------------ +# HEALTH CHECK GLOBAL PARAMETERS +#------------------------------------------------------------------------------ + +#health_check_period = 0 + # Health check period + # Disabled (0) by default +#health_check_timeout = 20 + # Health check timeout + # 0 means no timeout +#health_check_user = 'nobody' + # Health check user +#health_check_password = '' + # Password for health check user + # Leaving it empty will make Pgpool-II to first look for the + # Password in pool_passwd file before using the empty password + +#health_check_database = '' + # Database name for health check. If '', tries 'postgres' frist, +#health_check_max_retries = 0 + # Maximum number of times to retry a failed health check before giving up. +#health_check_retry_delay = 1 + # Amount of time to wait (in seconds) between retries. +#connect_timeout = 10000 + # Timeout value in milliseconds before giving up to connect to backend. + # Default is 10000 ms (10 second). Flaky network user may want to increase + # the value. 0 means no timeout. + # Note that this value is not only used for health check, + # but also for ordinary conection to backend. + +#------------------------------------------------------------------------------ +# HEALTH CHECK PER NODE PARAMETERS (OPTIONAL) +#------------------------------------------------------------------------------ +#health_check_period0 = 0 +#health_check_timeout0 = 20 +#health_check_user0 = 'nobody' +#health_check_password0 = '' +#health_check_database0 = '' +#health_check_max_retries0 = 0 +#health_check_retry_delay0 = 1 +#connect_timeout0 = 10000 + +#------------------------------------------------------------------------------ +# FAILOVER AND FAILBACK +#------------------------------------------------------------------------------ + +#failover_command = '' + # Executes this command at failover + # Special values: + # %d = failed node id + # %h = failed node host name + # %p = failed node port number + # %D = failed node database cluster path + # %m = new main node id + # %H = new main node hostname + # %M = old main node id + # %P = old primary node id + # %r = new main port number + # %R = new main database cluster path + # %N = old primary node hostname + # %S = old primary node port number + # %% = '%' character +#failback_command = '' + # Executes this command at failback. + # Special values: + # %d = failed node id + # %h = failed node host name + # %p = failed node port number + # %D = failed node database cluster path + # %m = new main node id + # %H = new main node hostname + # %M = old main node id + # %P = old primary node id + # %r = new main port number + # %R = new main database cluster path + # %N = old primary node hostname + # %S = old primary node port number + # %% = '%' character + +#failover_on_backend_error = on + # Initiates failover when reading/writing to the + # backend communication socket fails + # If set to off, pgpool will report an + # error and disconnect the session. + +#failover_on_backend_shutdown = off + # Initiates failover when backend is shutdown, + # or backend process is killed. + # If set to off, pgpool will report an + # error and disconnect the session. + +#detach_false_primary = off + # Detach false primary if on. Only + # valid in streaming replicaton + # mode and with PostgreSQL 9.6 or + # after. + +#search_primary_node_timeout = 5min + # Timeout in seconds to search for the + # primary node when a failover occurs. + # 0 means no timeout, keep searching + # for a primary node forever. + +#------------------------------------------------------------------------------ +# ONLINE RECOVERY +#------------------------------------------------------------------------------ + +#recovery_user = 'nobody' + # Online recovery user +#recovery_password = '' + # Online recovery password + # Leaving it empty will make Pgpool-II to first look for the + # Password in pool_passwd file before using the empty password + +#recovery_1st_stage_command = '' + # Executes a command in first stage +#recovery_2nd_stage_command = '' + # Executes a command in second stage +#recovery_timeout = 90 + # Timeout in seconds to wait for the + # recovering node's postmaster to start up + # 0 means no wait +#client_idle_limit_in_recovery = 0 + # Client is disconnected after being idle + # for that many seconds in the second stage + # of online recovery + # 0 means no disconnection + # -1 means immediate disconnection + +#auto_failback = off + # Dettached backend node reattach automatically + # if replication_state is 'streaming'. +#auto_failback_interval = 1min + # Min interval of executing auto_failback in + # seconds. + +#------------------------------------------------------------------------------ +# WATCHDOG +#------------------------------------------------------------------------------ + +# - Enabling - + +#use_watchdog = off + # Activates watchdog + # (change requires restart) + +# -Connection to up stream servers - + +#trusted_servers = '' + # trusted server list which are used + # to confirm network connection + # (hostA,hostB,hostC,...) + # (change requires restart) +#ping_path = '/bin' + # ping command path + # (change requires restart) + +# - Watchdog communication Settings - + +hostname0 = '' + # Host name or IP address of pgpool node + # for watchdog connection + # (change requires restart) +#wd_port0 = 9000 + # Port number for watchdog service + # (change requires restart) +#pgpool_port0 = 9999 + # Port number for pgpool + # (change requires restart) + +#hostname1 = '' +#wd_port1 = 9000 +#pgpool_port1 = 9999 + +#hostname2 = '' +#wd_port2 = 9000 +#pgpool_port2 = 9999 + +#wd_priority = 1 + # priority of this watchdog in leader election + # (change requires restart) + +#wd_authkey = '' + # Authentication key for watchdog communication + # (change requires restart) + +#wd_ipc_socket_dir = '/tmp' + # Unix domain socket path for watchdog IPC socket + # The Debian package defaults to + # /var/run/postgresql + # (change requires restart) + + +# - Virtual IP control Setting - + +#delegate_IP = '' + # delegate IP address + # If this is empty, virtual IP never bring up. + # (change requires restart) +#if_cmd_path = '/sbin' + # path to the directory where if_up/down_cmd exists + # If if_up/down_cmd starts with "/", if_cmd_path will be ignored. + # (change requires restart) +#if_up_cmd = '/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev eth0 label eth0:0' + # startup delegate IP command + # (change requires restart) +#if_down_cmd = '/usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev eth0' + # shutdown delegate IP command + # (change requires restart) +#arping_path = '/usr/sbin' + # arping command path + # If arping_cmd starts with "/", if_cmd_path will be ignored. + # (change requires restart) +#arping_cmd = '/usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I eth0' + # arping command + # (change requires restart) + +# - Behaivor on escalation Setting - + +#clear_memqcache_on_escalation = on + # Clear all the query cache on shared memory + # when standby pgpool escalate to active pgpool + # (= virtual IP holder). + # This should be off if client connects to pgpool + # not using virtual IP. + # (change requires restart) +#wd_escalation_command = '' + # Executes this command at escalation on new active pgpool. + # (change requires restart) +#wd_de_escalation_command = '' + # Executes this command when leader pgpool resigns from being leader. + # (change requires restart) + +# - Watchdog consensus settings for failover - + +#failover_when_quorum_exists = on + # Only perform backend node failover + # when the watchdog cluster holds the quorum + # (change requires restart) + +#failover_require_consensus = on + # Perform failover when majority of Pgpool-II nodes + # aggrees on the backend node status change + # (change requires restart) + +#allow_multiple_failover_requests_from_node = off + # A Pgpool-II node can cast multiple votes + # for building the consensus on failover + # (change requires restart) + + +#enable_consensus_with_half_votes = off + # apply majority rule for consensus and quorum computation + # at 50% of votes in a cluster with even number of nodes. + # when enabled the existence of quorum and consensus + # on failover is resolved after receiving half of the + # total votes in the cluster, otherwise both these + # decisions require at least one more vote than + # half of the total votes. + # (change requires restart) + +# - Watchdog cluster membership settings for quorum computation - + +#wd_remove_shutdown_nodes = off + # when enabled cluster membership of properly shutdown + # watchdog nodes gets revoked, After that the node does + # not count towards the quorum and consensus computations + +#wd_lost_node_removal_timeout = 0s + # Timeout after which the cluster membership of LOST watchdog + # nodes gets revoked. After that the node node does not + # count towards the quorum and consensus computations + # setting timeout to 0 will never revoke the membership + # of LOST nodes + +#wd_no_show_node_removal_timeout = 0s + # Time to wait for Watchdog node to connect to the cluster. + # After that time the cluster membership of NO-SHOW node gets + # revoked and it does not count towards the quorum and + # consensus computations + # setting timeout to 0 will not revoke the membership + # of NO-SHOW nodes + + +# - Lifecheck Setting - + +# -- common -- + +#wd_monitoring_interfaces_list = '' + # Comma separated list of interfaces names to monitor. + # if any interface from the list is active the watchdog will + # consider the network is fine + # 'any' to enable monitoring on all interfaces except loopback + # '' to disable monitoring + # (change requires restart) + +#wd_lifecheck_method = 'heartbeat' + # Method of watchdog lifecheck ('heartbeat' or 'query' or 'external') + # (change requires restart) +#wd_interval = 10 + # lifecheck interval (sec) > 0 + # (change requires restart) + +# -- heartbeat mode -- + +#heartbeat_hostname0 = '' + # Host name or IP address used + # for sending heartbeat signal. + # (change requires restart) +#heartbeat_port0 = 9694 + # Port number used for receiving/sending heartbeat signal + # Usually this is the same as heartbeat_portX. + # (change requires restart) +#heartbeat_device0 = '' + # Name of NIC device (such like 'eth0') + # used for sending/receiving heartbeat + # signal to/from destination 0. + # This works only when this is not empty + # and pgpool has root privilege. + # (change requires restart) + +#heartbeat_hostname1 = '' +#heartbeat_port1 = 9694 +#heartbeat_device1 = '' +#heartbeat_hostname2 = '' +#heartbeat_port2 = 9694 +#heartbeat_device2 = '' + +#wd_heartbeat_keepalive = 2 + # Interval time of sending heartbeat signal (sec) + # (change requires restart) +#wd_heartbeat_deadtime = 30 + # Deadtime interval for heartbeat signal (sec) + # (change requires restart) + +# -- query mode -- + +#wd_life_point = 3 + # lifecheck retry times + # (change requires restart) +#wd_lifecheck_query = 'SELECT 1' + # lifecheck query to pgpool from watchdog + # (change requires restart) +#wd_lifecheck_dbname = 'template1' + # Database name connected for lifecheck + # (change requires restart) +#wd_lifecheck_user = 'nobody' + # watchdog user monitoring pgpools in lifecheck + # (change requires restart) +#wd_lifecheck_password = '' + # Password for watchdog user in lifecheck + # Leaving it empty will make Pgpool-II to first look for the + # Password in pool_passwd file before using the empty password + # (change requires restart) + +#------------------------------------------------------------------------------ +# OTHERS +#------------------------------------------------------------------------------ +#relcache_expire = 0 + # Life time of relation cache in seconds. + # 0 means no cache expiration(the default). + # The relation cache is used for cache the + # query result against PostgreSQL system + # catalog to obtain various information + # including table structures or if it's a + # temporary table or not. The cache is + # maintained in a pgpool child local memory + # and being kept as long as it survives. + # If someone modify the table by using + # ALTER TABLE or some such, the relcache is + # not consistent anymore. + # For this purpose, cache_expiration + # controls the life time of the cache. +#relcache_size = 256 + # Number of relation cache + # entry. If you see frequently: + # "pool_search_relcache: cache replacement happend" + # in the pgpool log, you might want to increate this number. + +#check_temp_table = catalog + # Temporary table check method. catalog, trace or none. + # Default is catalog. + +#check_unlogged_table = on + # If on, enable unlogged table check in SELECT statements. + # This initiates queries against system catalog of primary/main + # thus increases load of primary. + # If you are absolutely sure that your system never uses unlogged tables + # and you want to save access to primary/main, you could turn this off. + # Default is on. +#enable_shared_relcache = on + # If on, relation cache stored in memory cache, + # the cache is shared among child process. + # Default is on. + # (change requires restart) + +#relcache_query_target = primary + # Target node to send relcache queries. Default is primary node. + # If load_balance_node is specified, queries will be sent to load balance node. +#------------------------------------------------------------------------------ +# IN MEMORY QUERY MEMORY CACHE +#------------------------------------------------------------------------------ +#memory_cache_enabled = off + # If on, use the memory cache functionality, off by default + # (change requires restart) +#memqcache_method = 'shmem' + # Cache storage method. either 'shmem'(shared memory) or + # 'memcached'. 'shmem' by default + # (change requires restart) +#memqcache_memcached_host = 'localhost' + # Memcached host name or IP address. Mandatory if + # memqcache_method = 'memcached'. + # Defaults to localhost. + # (change requires restart) +#memqcache_memcached_port = 11211 + # Memcached port number. Mondatory if memqcache_method = 'memcached'. + # Defaults to 11211. + # (change requires restart) +#memqcache_total_size = 64MB + # Total memory size in bytes for storing memory cache. + # Mandatory if memqcache_method = 'shmem'. + # Defaults to 64MB. + # (change requires restart) +#memqcache_max_num_cache = 1000000 + # Total number of cache entries. Mandatory + # if memqcache_method = 'shmem'. + # Each cache entry consumes 48 bytes on shared memory. + # Defaults to 1,000,000(45.8MB). + # (change requires restart) +#memqcache_expire = 0 + # Memory cache entry life time specified in seconds. + # 0 means infinite life time. 0 by default. + # (change requires restart) +#memqcache_auto_cache_invalidation = on + # If on, invalidation of query cache is triggered by corresponding + # DDL/DML/DCL(and memqcache_expire). If off, it is only triggered + # by memqcache_expire. on by default. + # (change requires restart) +#memqcache_maxcache = 400kB + # Maximum SELECT result size in bytes. + # Must be smaller than memqcache_cache_block_size. Defaults to 400KB. + # (change requires restart) +#memqcache_cache_block_size = 1MB + # Cache block size in bytes. Mandatory if memqcache_method = 'shmem'. + # Defaults to 1MB. + # (change requires restart) +#memqcache_oiddir = '/var/log/pgpool/oiddir' + # Temporary work directory to record table oids + # (change requires restart) +#cache_safe_memqcache_table_list = '' + # Comma separated list of table names to memcache + # that don't write to database + # Regexp are accepted +#cache_unsafe_memqcache_table_list = '' + # Comma separated list of table names not to memcache + # that don't write to database + # Regexp are accepted + +backend_clustering_mode = 'streaming_replication' + +listen_addresses = '*' +pcp_listen_addresses = '*' +port = 9999 + +sr_check_user = 'pgpool' +sr_check_password = '' + +health_check_period = 5 +health_check_timeout = 30 +health_check_user = 'pgpool' +health_check_password = '' +health_check_max_retries = 3 + +backend_hostname0 = 'postgres1' +backend_port0 = 5432 +backend_weight0 = 1 +backend_data_directory0 = '/var/lib/postgresql/16/main' +backend_flag0 = 'ALLOW_TO_FAILOVER' +backend_application_name0 = 'postgres1' + +backend_hostname1 = 'postgres2' +backend_port1 = 5432 +backend_weight1 = 1 +backend_data_directory1 = '/var/lib/postgresql/16/main' +backend_flag1 = 'ALLOW_TO_FAILOVER' +backend_application_name1 = 'postgres2' + +failover_command = '/etc/pgpool2/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S' +follow_primary_command = '/etc/pgpool2/follow_primary.sh %d %h %p %D %m %H %M %P %r %R' + +recovery_user = 'postgres' +recovery_password = '' +recovery_1st_stage_command = 'recovery_1st_stage' + +enable_pool_hba = on + +use_watchdog = on + +delegate_ip = '172.20.0.39' + +if_up_cmd = '/usr/bin/sudo /usr/sbin/ip addr add $_IP_$/16 dev eth0 label eth0:0' +if_down_cmd = '/usr/bin/sudo /usr/sbin/ip addr del $_IP_$/16 dev eth0' +arping_cmd = '/usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I eth0' + +if_cmd_path = '/usr/sbin' +arping_path = '/usr/sbin' + +hostname0 = 'pgpool1' +wd_port0 = 9000 +pgpool_port0 = 9999 + +hostname1 = 'pgpool2' +wd_port1 = 9000 +pgpool_port1 = 9999 + +hostname2 = 'pgpool3' +wd_port2 = 9000 +pgpool_port2 = 9999 + +wd_lifecheck_method = 'heartbeat' +wd_interval = 10 + +heartbeat_hostname0 = 'pgpool1' +heartbeat_port0 = 9694 +heartbeat_device0 = '' +heartbeat_hostname1 = 'pgpool2' +heartbeat_port1 = 9694 +heartbeat_device1 = '' +heartbeat_hostname2 = 'pgpool3' +heartbeat_port2 = 9694 +heartbeat_device2 = '' + +wd_heartbeat_keepalive = 2 +wd_heartbeat_deadtime = 30 + +wd_escalation_command = '/etc/pgpool2/escalation.sh' + +log_destination = 'stderr' +logging_collector = on +log_directory = '/var/log/pgpool_log' +log_filename = 'pgpool-%a.log' +log_truncate_on_rotation = on +log_rotation_age = 1d +log_rotation_size = 10MB diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/pool_hba.conf b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/pool_hba.conf new file mode 100644 index 0000000000000000000000000000000000000000..c160a43481acd3d84a04eaa23bc9a1946530ac20 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/pool_hba.conf @@ -0,0 +1,75 @@ +# pgpool Client Authentication Configuration File +# =============================================== +# +# The format rule in this file follows the rules in the PostgreSQL +# Administrator's Guide. Refer to chapter "Client Authentication" for a +# complete description. A short synopsis follows. +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which user names they can use, which databases they +# can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTION] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: "local" is a Unix-domain +# socket, "host" is either a plain or SSL-encrypted TCP/IP socket. +# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a +# plain TCP/IP socket. +# +# DATABASE can be "all", "sameuser", a database name, or a comma-separated +# list thereof. Note that "samegroup" like in PostgreSQL's pg_hba.conf +# file is not supported, since pgpool does not know which group a user +# belongs to. Also note that the database specified here may not exist in +# the backend PostgreSQL. pgpool will authenticate based on the database's +# name, not based on whether it exists or not. +# +# USER can be "all", a user name, or a comma-separated list thereof. In +# both the DATABASE and USER fields you can also write a file name prefixed +# with "@" to include names from a separate file. Note that a group name +# prefixed with "+" like in PostgreSQL's pg_hba.conf file is not supported +# because of the same reason as "samegroup" token. Also note that a user +# name specified here may not exist in the backend PostgreSQL. pgpool will +# authenticate based on the user's name, not based on whether he/she exists. +# +# CIDR-ADDRESS specifies the set of hosts the record matches. +# It is made up of an IP address and a CIDR mask that is an integer +# (between 0 and 32 (IPv4) that specifies the number of significant bits in +# the mask. Alternatively, you can write an IP address and netmask in +# separate columns to specify the set of hosts. +# +# METHOD can be "trust", "reject", "md5" , "scram-sha-256" or "pam". +# Note that "pam" sends passwords in clear text. +# +# OPTION is the name of the PAM service. Default service name is "pgpool" +# +# Database and user names containing spaces, commas, quotes and other special +# characters must be quoted. Quoting one of the keywords "all" or "sameuser" +# makes the name lose its special character, and just match a database or +# username with that name. +# +# This file is read on pgpool startup. If you edit the file on a running +# system, you have to restart the pgpool for the changes to take effect. + +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make pgpool listen +# on a non-local interface via the listen_addresses configuration parameter. +# + +# TYPE DATABASE USER CIDR-ADDRESS METHOD + +# "local" is for Unix domain socket connections only +local all all trust +# IPv4 local connections: +host all all 127.0.0.1/32 trust +host all all ::1/128 trust + +host all pgpool samenet scram-sha-256 +host all postgres samenet scram-sha-256 \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/scripts/escalation.sh b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/scripts/escalation.sh new file mode 100644 index 0000000000000000000000000000000000000000..6b58b69fb7781241533c9417434a7f7e9d6017d8 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/scripts/escalation.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# This script is run by wd_escalation_command to bring down the virtual IP on other pgpool nodes +# before bringing up the virtual IP on the new active pgpool node. + +set -o xtrace + +POSTGRESQL_STARTUP_USER=postgres +SSH_KEY_FILE=id_rsa_pgpool +SSH_OPTIONS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/${SSH_KEY_FILE}" +SSH_TIMEOUT=5 +PGPOOLS=(pgpool1 pgpool2 pgpool3) + +DEVICE=eth0 +VIP=172.20.0.39 + +for pgpool in "${PGPOOLS[@]}"; do + [ "$HOSTNAME" = "${pgpool}" ] && continue + + timeout ${SSH_TIMEOUT} ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@${pgpool} " + /usr/bin/sudo /usr/sbin/ip addr del ${VIP}/16 dev ${DEVICE} + " + if [ $? -ne 0 ]; then + echo ERROR: escalation.sh: failed to release VIP on ${pgpool}. + fi +done +exit 0 diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/scripts/failover.sh b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/scripts/failover.sh new file mode 100644 index 0000000000000000000000000000000000000000..25e843914f723eaf40a09a87296db81fb437ef22 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/scripts/failover.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# This script is run by failover_command. + +set -o xtrace + +# Special values: +# 1) %d = failed node id +# 2) %h = failed node hostname +# 3) %p = failed node port number +# 4) %D = failed node database cluster path +# 5) %m = new main node id +# 6) %H = new main node hostname +# 7) %M = old main node id +# 8) %P = old primary node id +# 9) %r = new main port number +# 10) %R = new main database cluster path +# 11) %N = old primary node hostname +# 12) %S = old primary node port number +# 13) %% = '%' character + +FAILED_NODE_ID="$1" +FAILED_NODE_HOST="$2" +FAILED_NODE_PORT="$3" +FAILED_NODE_PGDATA="$4" +NEW_MAIN_NODE_ID="$5" +NEW_MAIN_NODE_HOST="$6" +OLD_MAIN_NODE_ID="$7" +OLD_PRIMARY_NODE_ID="$8" +NEW_MAIN_NODE_PORT="$9" +NEW_MAIN_NODE_PGDATA="${10}" +OLD_PRIMARY_NODE_HOST="${11}" +OLD_PRIMARY_NODE_PORT="${12}" + +PGHOME=/usr/lib/postgresql/16 +REPL_SLOT_NAME=$(echo ${FAILED_NODE_HOST,,} | tr -- -. _) +POSTGRESQL_STARTUP_USER=postgres +SSH_KEY_FILE=id_rsa_pgpool +SSH_OPTIONS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/${SSH_KEY_FILE}" + + +echo failover.sh: start: failed_node_id=$FAILED_NODE_ID failed_host=$FAILED_NODE_HOST \ + old_primary_node_id=$OLD_PRIMARY_NODE_ID new_main_node_id=$NEW_MAIN_NODE_ID new_main_host=$NEW_MAIN_NODE_HOST + +## If there's no main node anymore, skip failover. +if [ $NEW_MAIN_NODE_ID -lt 0 ]; then + echo failover.sh: All nodes are down. Skipping failover. + exit 0 +fi + +## Test passwordless SSH +ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@${NEW_MAIN_NODE_HOST} ls /tmp > /dev/null + +if [ $? -ne 0 ]; then + echo failover.sh: passwordless SSH to ${POSTGRESQL_STARTUP_USER}@${NEW_MAIN_NODE_HOST} failed. Please setup passwordless SSH. + exit 1 +fi + +## If Standby node is down, skip failover. +if [ $OLD_PRIMARY_NODE_ID != "-1" -a $FAILED_NODE_ID != $OLD_PRIMARY_NODE_ID ]; then + + # If Standby node is down, drop replication slot. + ${PGHOME}/bin/psql -h ${OLD_PRIMARY_NODE_HOST} -p ${OLD_PRIMARY_NODE_PORT} postgres \ + -c "SELECT pg_drop_replication_slot('${REPL_SLOT_NAME}');" >/dev/null 2>&1 + + if [ $? -ne 0 ]; then + echo ERROR: failover.sh: drop replication slot \"${REPL_SLOT_NAME}\" failed. You may need to drop replication slot manually. + fi + + echo failover.sh: end: standby node is down. Skipping failover. + exit 0 +fi + +## Promote Standby node. +echo failover.sh: primary node is down, promote new_main_node_id=$NEW_MAIN_NODE_ID on ${NEW_MAIN_NODE_HOST}. + +ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@${NEW_MAIN_NODE_HOST} ${PGHOME}/bin/pg_ctl -D /etc/postgresql/16/main -w promote + +if [ $? -ne 0 ]; then + echo ERROR: failover.sh: promote failed + exit 1 +fi + +echo failover.sh: end: new_main_node_id=$NEW_MAIN_NODE_ID on ${NEW_MAIN_NODE_HOST} was successfully promoted to primary +exit 0 diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/scripts/follow_primary.sh b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/scripts/follow_primary.sh new file mode 100644 index 0000000000000000000000000000000000000000..02cf13644799426ce222c0fde63d5472cb359b7d --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/pgpool/scripts/follow_primary.sh @@ -0,0 +1,176 @@ +#!/bin/bash +# This script is run after failover_command to synchronize the Standby with the new Primary. +# First try pg_rewind. If pg_rewind failed, use pg_basebackup. + +set -o xtrace + +# Special values: +# 1) %d = node id +# 2) %h = hostname +# 3) %p = port number +# 4) %D = node database cluster path +# 5) %m = new primary node id +# 6) %H = new primary node hostname +# 7) %M = old main node id +# 8) %P = old primary node id +# 9) %r = new primary port number +# 10) %R = new primary database cluster path +# 11) %N = old primary node hostname +# 12) %S = old primary node port number +# 13) %% = '%' character + +NODE_ID="$1" +NODE_HOST="$2" +NODE_PORT="$3" +NODE_PGDATA="$4" +NEW_PRIMARY_NODE_ID="$5" +NEW_PRIMARY_NODE_HOST="$6" +OLD_MAIN_NODE_ID="$7" +OLD_PRIMARY_NODE_ID="$8" +NEW_PRIMARY_NODE_PORT="$9" +NEW_PRIMARY_NODE_PGDATA="${10}" + +PGHOME=/usr/lib/postgresql/16 +ARCHIVEDIR=/var/lib/postgresql/archivedir +REPLUSER=repl +PCP_USER=pgpool +PGPOOL_PATH=/usr/sbin +PCP_PORT=9898 +REPL_SLOT_NAME=$(echo ${NODE_HOST,,} | tr -- -. _) +POSTGRESQL_STARTUP_USER=postgres +SSH_KEY_FILE=id_rsa_pgpool +SSH_OPTIONS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/${SSH_KEY_FILE}" + +echo follow_primary.sh: start: Standby node ${NODE_ID} + +# Check the connection status of Standby +${PGHOME}/bin/pg_isready -h ${NODE_HOST} -p ${NODE_PORT} > /dev/null 2>&1 + +if [ $? -ne 0 ]; then + echo follow_primary.sh: node_id=${NODE_ID} is not running. skipping follow primary command + exit 0 +fi + +# Test passwordless SSH +ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@${NEW_PRIMARY_NODE_HOST} ls /tmp > /dev/null + +if [ $? -ne 0 ]; then + echo follow_main.sh: passwordless SSH to ${POSTGRESQL_STARTUP_USER}@${NEW_PRIMARY_NODE_HOST} failed. Please setup passwordless SSH. + exit 1 +fi + +RECOVERYCONF=${NODE_PGDATA}/myrecovery.conf + +# Synchronize Standby with the new Primary. +echo follow_primary.sh: pg_rewind for node ${NODE_ID} + +# Run checkpoint command to update control file before running pg_rewind +${PGHOME}/bin/psql -h ${NEW_PRIMARY_NODE_HOST} -p ${NEW_PRIMARY_NODE_PORT} postgres -c "checkpoint;" + +# Create replication slot "${REPL_SLOT_NAME}" +${PGHOME}/bin/psql -h ${NEW_PRIMARY_NODE_HOST} -p ${NEW_PRIMARY_NODE_PORT} postgres \ + -c "SELECT pg_create_physical_replication_slot('${REPL_SLOT_NAME}');" >/dev/null 2>&1 + +if [ $? -ne 0 ]; then + echo follow_primary.sh: create replication slot \"${REPL_SLOT_NAME}\" failed. You may need to create replication slot manually. +fi + +ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@${NODE_HOST} " + + set -o errexit + + ${PGHOME}/bin/pg_ctl -w -m f -D /etc/postgresql/16/main stop + + ${PGHOME}/bin/pg_rewind -D ${NODE_PGDATA} --source-server=\"user=${POSTGRESQL_STARTUP_USER} host=${NEW_PRIMARY_NODE_HOST} port=${NEW_PRIMARY_NODE_PORT} dbname=postgres\" + + [ -d \"${NODE_PGDATA}\" ] && rm -rf ${NODE_PGDATA}/pg_replslot/* + + cat > ${RECOVERYCONF} << EOT +primary_conninfo = 'host=${NEW_PRIMARY_NODE_HOST} port=${NEW_PRIMARY_NODE_PORT} user=${REPLUSER} application_name=${NODE_HOST} passfile='/var/lib/postgresql/.pgpass'' +recovery_target_timeline = 'latest' +primary_slot_name = '${REPL_SLOT_NAME}' +EOT + + sed -i -e \"\\\$ainclude_if_exists = '$(echo ${RECOVERYCONF} | sed -e 's/\//\\\//g')'\" \ + -e \"/^include_if_exists = '$(echo ${RECOVERYCONF} | sed -e 's/\//\\\//g')'/d\" /etc/postgresql/16/main/postgresql.conf + touch ${NODE_PGDATA}/standby.signal + + + ${PGHOME}/bin/pg_ctl -l /dev/null -w -D /etc/postgresql/16/main start + +" + +# If pg_rewind failed, try pg_basebackup +if [ $? -ne 0 ]; then + echo follow_primary.sh: end: pg_rewind failed. Try pg_basebackup. + + ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@${NODE_HOST} " + + set -o errexit + + [ -d \"${NODE_PGDATA}\" ] && rm -rf ${NODE_PGDATA} + [ -d \"${ARCHIVEDIR}\" ] && rm -rf ${ARCHIVEDIR}/* + ${PGHOME}/bin/pg_basebackup -h ${NEW_PRIMARY_NODE_HOST} -U $REPLUSER -p ${NEW_PRIMARY_NODE_PORT} -D ${NODE_PGDATA} -X stream + + cat > ${RECOVERYCONF} << EOT +primary_conninfo = 'host=${NEW_PRIMARY_NODE_HOST} port=${NEW_PRIMARY_NODE_PORT} user=${REPLUSER} application_name=${NODE_HOST} passfile='/var/lib/postgresql/.pgpass'' +recovery_target_timeline = 'latest' +primary_slot_name = '${REPL_SLOT_NAME}' +EOT + + sed -i -e \"\\\$ainclude_if_exists = '$(echo ${RECOVERYCONF} | sed -e 's/\//\\\//g')'\" \ + -e \"/^include_if_exists = '$(echo ${RECOVERYCONF} | sed -e 's/\//\\\//g')'/d\" /etc/postgresql/16/main/postgresql.conf + touch ${NODE_PGDATA}/standby.signal + + sed -i \ + -e \"s/#*port = .*/port = ${NODE_PORT}/\" \ + -e \"s@#*archive_command = .*@archive_command = 'cp \\\"%p\\\" \\\"${ARCHIVEDIR}/%f\\\"'@\" \ + /etc/postgresql/16/main/postgresql.conf + " + + if [ $? -ne 0 ]; then + + # drop replication slot + ${PGHOME}/bin/psql -h ${NEW_PRIMARY_NODE_HOST} -p ${NEW_PRIMARY_NODE_PORT} postgres \ + -c "SELECT pg_drop_replication_slot('${REPL_SLOT_NAME}');" >/dev/null 2>&1 + + if [ $? -ne 0 ]; then + echo ERROR: follow_primary.sh: drop replication slot \"${REPL_SLOT_NAME}\" failed. You may need to drop replication slot manually. + fi + + echo follow_primary.sh: end: pg_basebackup failed + exit 1 + fi + + # start Standby node on ${NODE_HOST} + ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@${NODE_HOST} $PGHOME/bin/pg_ctl -l /dev/null -w -D /etc/postgresql/16/main start + +fi + +# If start Standby successfully, attach this node +if [ $? -eq 0 ]; then + + # Run pcp_attact_node to attach Standby node to Pgpool-II. + ${PGPOOL_PATH}/pcp_attach_node -w -h localhost -U $PCP_USER -p ${PCP_PORT} -n ${NODE_ID} + + if [ $? -ne 0 ]; then + echo ERROR: follow_primary.sh: end: pcp_attach_node failed + exit 1 + fi + +else + + # If start Standby failed, drop replication slot "${REPL_SLOT_NAME}" + ${PGHOME}/bin/psql -h ${NEW_PRIMARY_NODE_HOST} -p ${NEW_PRIMARY_NODE_PORT} postgres \ + -c "SELECT pg_drop_replication_slot('${REPL_SLOT_NAME}');" >/dev/null 2>&1 + + if [ $? -ne 0 ]; then + echo ERROR: follow_primary.sh: drop replication slot \"${REPL_SLOT_NAME}\" failed. You may need to drop replication slot manually. + fi + + echo ERROR: follow_primary.sh: end: follow primary command failed + exit 1 +fi + +echo follow_primary.sh: end: follow primary command is completed successfully +exit 0 diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/postgres/.pgpass b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/.pgpass new file mode 100644 index 0000000000000000000000000000000000000000..5df0ab6102325280d5fcdd3c6554b8848e26b6a2 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/.pgpass @@ -0,0 +1,4 @@ +postgres1:5432:replication:repl:123mudar +postgres2:5432:replication:repl:123mudar +postgres1:5432:postgres:postgres:123mudar +postgres2:5432:postgres:postgres:123mudar \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/postgres/Dockerfile b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..2715e1f53ff1d31bb9c420640a18d4c076cb5d6d --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/Dockerfile @@ -0,0 +1,70 @@ +FROM debian:bookworm + +USER root +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +# Setup repository and install postgresql-16 +RUN apt-get install -y curl ca-certificates +RUN install -d /usr/share/postgresql-common/pgdg +RUN curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc +RUN sh -c 'echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" > /etc/apt/sources.list.d/pgdg.list' +RUN apt-get update +RUN apt-get -y install postgresql-16 + +# Install SSH for PSQL replication +USER root +RUN apt-get install -y keychain \ + openssh-server \ + arping \ + iproute2 \ + sudo \ + vim \ + # Install pgpool extensions for recovery + postgresql-16-pgpool2 + +# Conf PSQL for replication +USER postgres +WORKDIR /var/lib/postgresql +RUN mkdir archivedir +ENV WAL_DIR=/var/lib/postgresql/archivedir + + +# Copy conf files +USER root +WORKDIR /etc/postgresql/16/main +COPY pg_hba.conf pg_hba.conf +RUN chown postgres:postgres pg_hba.conf +RUN chmod 644 pg_hba.conf + +# Set pgpass +WORKDIR /var/lib/postgresql +COPY .pgpass .pgpass +RUN chown postgres:postgres .pgpass +RUN chmod 600 .pgpass + +# Set recovery and remote start scripts +WORKDIR /var/lib/postgresql/16/main +COPY ./scripts/pgpool_remote_start.sh pgpool_remote_start +COPY ./scripts/recovery_1st_stage.sh recovery_1st_stage +RUN chown postgres:postgres pgpool_remote_start recovery_1st_stage +RUN chmod 700 pgpool_remote_start recovery_1st_stage + +# Set ssh keys and authorizations +WORKDIR /var/lib/postgresql/.ssh +COPY authorized_keys authorized_keys +COPY id_rsa_pgpool id_rsa_pgpool +COPY id_rsa_pgpool.pub id_rsa_pgpool.pub +RUN chmod 644 authorized_keys +RUN chmod 600 id_rsa_pgpool +RUN chmod 644 id_rsa_pgpool.pub +RUN chown postgres:postgres id_rsa_pgpool id_rsa_pgpool.pub authorized_keys + +# Setup entrypoint +USER root +COPY entrypoint.sh /home/entrypoint.sh +WORKDIR /home +RUN chmod +x ./entrypoint.sh + +ENTRYPOINT ["/bin/sh", "-c" , "./entrypoint.sh"] diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/postgres/authorized_keys b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/authorized_keys new file mode 100644 index 0000000000000000000000000000000000000000..ce3aed042c0fd900daa35ade91a7475ee97cb691 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/authorized_keys @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC6+rAChjlbTGamRpX/Zlluy9CmMwt/MLSV1FQvKoT4pimOY+W353QUQu6QhP+w7fGJ0x6276wpAs623Li14ij6JuAbBEz3VYGlm6+eePfKU/TO59X3HGaAKAo1y7PEfpV+nHumDa/xvqpkLEgorc3QcloH9Ia7zEYdvYbuH1JDWqbyCUedTnC8PCeq38nA6E3hO9lmZVNrXH6CUbrmclLTwIv20lmPkv2OqcbL35hQ/tEwCdg67G4WFcMUPhJKiETnUKmW2H836yjIPYAvx1ikbL4N911G7veREAbrUkWxDB1EAN6YW/dxnS+JjgdAbQfChNeHXH/b7qN3KwX2cjcehA2jAJlFApW1KKNgm4UOIOFEIb9DpIpkiWGut20K0v6Yo7m5SE0IMS3MKc3WRbvtdVM8wOzMmRuMHBlGvX88lGVX96chtEk5RAW6cYYTGcSN6OZSZn6zi9seKCgzbgw5wq1PSGu+4gr08WyPzHHzfxr2Xbkbn9+rkiQAohx0W/E= \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/postgres/entrypoint.sh b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/entrypoint.sh new file mode 100644 index 0000000000000000000000000000000000000000..3027d088f296da24f0bb488f41b53ec13d915763 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/entrypoint.sh @@ -0,0 +1,16 @@ +service ssh start + +if [ -n "$PRIMARY" ]; +then + printf "%s\n" \ + "listen_addresses = '*'" \ + "archive_mode = on" \ + "archive_command = 'cp \"%p\" \"/var/lib/postgresql/archivedir/%f\"'" \ + "max_wal_senders = 10" \ + "max_replication_slots = 10" \ + "wal_level = replica" \ + "hot_standby = on" \ + "wal_log_hints = on" >> /etc/postgresql/16/main/postgresql.conf +fi + +sleep infinity \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/postgres/id_rsa_pgpool b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/id_rsa_pgpool new file mode 100644 index 0000000000000000000000000000000000000000..321a6d1d5785c433af778d825da6981a6d44b7dc --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/id_rsa_pgpool @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +-----END OPENSSH PRIVATE KEY----- diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/postgres/id_rsa_pgpool.pub b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/id_rsa_pgpool.pub new file mode 100644 index 0000000000000000000000000000000000000000..ce3aed042c0fd900daa35ade91a7475ee97cb691 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/id_rsa_pgpool.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC6+rAChjlbTGamRpX/Zlluy9CmMwt/MLSV1FQvKoT4pimOY+W353QUQu6QhP+w7fGJ0x6276wpAs623Li14ij6JuAbBEz3VYGlm6+eePfKU/TO59X3HGaAKAo1y7PEfpV+nHumDa/xvqpkLEgorc3QcloH9Ia7zEYdvYbuH1JDWqbyCUedTnC8PCeq38nA6E3hO9lmZVNrXH6CUbrmclLTwIv20lmPkv2OqcbL35hQ/tEwCdg67G4WFcMUPhJKiETnUKmW2H836yjIPYAvx1ikbL4N911G7veREAbrUkWxDB1EAN6YW/dxnS+JjgdAbQfChNeHXH/b7qN3KwX2cjcehA2jAJlFApW1KKNgm4UOIOFEIb9DpIpkiWGut20K0v6Yo7m5SE0IMS3MKc3WRbvtdVM8wOzMmRuMHBlGvX88lGVX96chtEk5RAW6cYYTGcSN6OZSZn6zi9seKCgzbgw5wq1PSGu+4gr08WyPzHHzfxr2Xbkbn9+rkiQAohx0W/E= \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/postgres/pg_hba.conf b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/pg_hba.conf new file mode 100644 index 0000000000000000000000000000000000000000..7de4f38ff1b80b71900e8066cefd3780c4e47f66 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/pg_hba.conf @@ -0,0 +1,136 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# ---------------------- +# Authentication Records +# ---------------------- +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: +# - "local" is a Unix-domain socket +# - "host" is a TCP/IP socket (encrypted or not) +# - "hostssl" is a TCP/IP socket that is SSL-encrypted +# - "hostnossl" is a TCP/IP socket that is not SSL-encrypted +# - "hostgssenc" is a TCP/IP socket that is GSSAPI-encrypted +# - "hostnogssenc" is a TCP/IP socket that is not GSSAPI-encrypted +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, a regular expression (if it starts with a slash (/)) +# or a comma-separated list thereof. The "all" keyword does not match +# "replication". Access to replication must be enabled in a separate +# record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", a +# regular expression (if it starts with a slash (/)) or a comma-separated +# list thereof. In both the DATABASE and USER fields you can also write +# a file name prefixed with "@" to include names from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", +# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". +# Note that "password" sends passwords in clear text; "md5" or +# "scram-sha-256" are preferred since they send encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# --------------- +# Include Records +# --------------- +# +# This file allows the inclusion of external files or directories holding +# more records, using the following keywords: +# +# include FILE +# include_if_exists FILE +# include_dir DIRECTORY +# +# FILE is the file name to include, and DIR is the directory name containing +# the file(s) to include. Any file in a directory will be loaded if suffixed +# with ".conf". The files of a directory are ordered by name. +# include_if_exists ignores missing files. FILE and DIRECTORY can be +# specified as a relative or an absolute path, and can be double-quoted if +# they contain spaces. +# +# ------------- +# Miscellaneous +# ------------- +# +# This file is read on server startup and when the server receives a +# SIGHUP signal. If you edit the file on a running system, you have to +# SIGHUP the server for the changes to take effect, run "pg_ctl reload", +# or execute "SELECT pg_reload_conf()". +# +# ---------------------------------- +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + + + + +# DO NOT DISABLE! +# If you change this first entry you will need to make sure that the +# database superuser can access the database using some other method. +# Noninteractive access to all databases is required during automatic +# maintenance (custom daily cronjobs, replication, and similar tasks). +# +# Database administrative login by Unix domain socket +local all postgres peer + +# TYPE DATABASE USER ADDRESS METHOD + +# "local" is for Unix domain socket connections only +local all all peer +# IPv4 local connections: +host all all 127.0.0.1/32 scram-sha-256 +# IPv6 local connections: +host all all ::1/128 scram-sha-256 +# Allow replication connections from localhost, by a user with the +# replication privilege. +local replication all peer +host replication all 127.0.0.1/32 scram-sha-256 +host replication all ::1/128 scram-sha-256 + +host all pgpool samenet scram-sha-256 +host all postgres samenet scram-sha-256 +host replication repl samenet scram-sha-256 \ No newline at end of file diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/postgres/postgresql.conf b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/postgresql.conf new file mode 100644 index 0000000000000000000000000000000000000000..68b3317d8fe0cf18ed45e313f12352a34f177e6f --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/postgresql.conf @@ -0,0 +1,822 @@ +# ----------------------------- +# PostgreSQL configuration file +# ----------------------------- +# +# This file consists of lines of the form: +# +# name = value +# +# (The "=" is optional.) Whitespace may be used. Comments are introduced with +# "#" anywhere on a line. The complete list of parameter names and allowed +# values can be found in the PostgreSQL documentation. +# +# The commented-out settings shown in this file represent the default values. +# Re-commenting a setting is NOT sufficient to revert it to the default value; +# you need to reload the server. +# +# This file is read on server startup and when the server receives a SIGHUP +# signal. If you edit the file on a running system, you have to SIGHUP the +# server for the changes to take effect, run "pg_ctl reload", or execute +# "SELECT pg_reload_conf()". Some parameters, which are marked below, +# require a server shutdown and restart to take effect. +# +# Any parameter can also be given as a command-line option to the server, e.g., +# "postgres -c log_connections=on". Some parameters can be changed at run time +# with the "SET" SQL command. +# +# Memory units: B = bytes Time units: us = microseconds +# kB = kilobytes ms = milliseconds +# MB = megabytes s = seconds +# GB = gigabytes min = minutes +# TB = terabytes h = hours +# d = days + + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +# The default values of these variables are driven from the -D command-line +# option or PGDATA environment variable, represented here as ConfigDir. + +data_directory = '/var/lib/postgresql/16/main' # use data in another directory + # (change requires restart) +hba_file = '/etc/postgresql/16/main/pg_hba.conf' # host-based authentication file + # (change requires restart) +ident_file = '/etc/postgresql/16/main/pg_ident.conf' # ident configuration file + # (change requires restart) + +# If external_pid_file is not explicitly set, no extra PID file is written. +external_pid_file = '/var/run/postgresql/16-main.pid' # write an extra PID file + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +#listen_addresses = 'localhost' # what IP address(es) to listen on; + # comma-separated list of addresses; + # defaults to 'localhost'; use '*' for all + # (change requires restart) +port = 5432 # (change requires restart) +max_connections = 100 # (change requires restart) +#reserved_connections = 0 # (change requires restart) +#superuser_reserved_connections = 3 # (change requires restart) +unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories + # (change requires restart) +#unix_socket_group = '' # (change requires restart) +#unix_socket_permissions = 0777 # begin with 0 to use octal notation + # (change requires restart) +#bonjour = off # advertise server via Bonjour + # (change requires restart) +#bonjour_name = '' # defaults to the computer name + # (change requires restart) + +# - TCP settings - +# see "man tcp" for details + +#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; + # 0 selects the system default +#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; + # 0 selects the system default +#tcp_keepalives_count = 0 # TCP_KEEPCNT; + # 0 selects the system default +#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; + # 0 selects the system default + +#client_connection_check_interval = 0 # time between checks for client + # disconnection while running queries; + # 0 for never + +# - Authentication - + +#authentication_timeout = 1min # 1s-600s +#password_encryption = scram-sha-256 # scram-sha-256 or md5 +#scram_iterations = 4096 +#db_user_namespace = off + +# GSSAPI using Kerberos +#krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' +#krb_caseins_users = off +#gss_accept_delegation = off + +# - SSL - + +ssl = on +#ssl_ca_file = '' +ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' +#ssl_crl_file = '' +#ssl_crl_dir = '' +ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' +#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers +#ssl_prefer_server_ciphers = on +#ssl_ecdh_curve = 'prime256v1' +#ssl_min_protocol_version = 'TLSv1.2' +#ssl_max_protocol_version = '' +#ssl_dh_params_file = '' +#ssl_passphrase_command = '' +#ssl_passphrase_command_supports_reload = off + + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +# - Memory - + +shared_buffers = 128MB # min 128kB + # (change requires restart) +#huge_pages = try # on, off, or try + # (change requires restart) +#huge_page_size = 0 # zero for system default + # (change requires restart) +#temp_buffers = 8MB # min 800kB +#max_prepared_transactions = 0 # zero disables the feature + # (change requires restart) +# Caution: it is not advisable to set max_prepared_transactions nonzero unless +# you actively intend to use prepared transactions. +#work_mem = 4MB # min 64kB +#hash_mem_multiplier = 2.0 # 1-1000.0 multiplier on hash table work_mem +#maintenance_work_mem = 64MB # min 1MB +#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem +#logical_decoding_work_mem = 64MB # min 64kB +#max_stack_depth = 2MB # min 100kB +#shared_memory_type = mmap # the default is the first option + # supported by the operating system: + # mmap + # sysv + # windows + # (change requires restart) +dynamic_shared_memory_type = posix # the default is usually the first option + # supported by the operating system: + # posix + # sysv + # windows + # mmap + # (change requires restart) +#min_dynamic_shared_memory = 0MB # (change requires restart) +#vacuum_buffer_usage_limit = 256kB # size of vacuum and analyze buffer access strategy ring; + # 0 to disable vacuum buffer access strategy; + # range 128kB to 16GB + +# - Disk - + +#temp_file_limit = -1 # limits per-process temp file space + # in kilobytes, or -1 for no limit + +# - Kernel Resources - + +#max_files_per_process = 1000 # min 64 + # (change requires restart) + +# - Cost-Based Vacuum Delay - + +#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) +#vacuum_cost_page_hit = 1 # 0-10000 credits +#vacuum_cost_page_miss = 2 # 0-10000 credits +#vacuum_cost_page_dirty = 20 # 0-10000 credits +#vacuum_cost_limit = 200 # 1-10000 credits + +# - Background Writer - + +#bgwriter_delay = 200ms # 10-10000ms between rounds +#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables +#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round +#bgwriter_flush_after = 512kB # measured in pages, 0 disables + +# - Asynchronous Behavior - + +#backend_flush_after = 0 # measured in pages, 0 disables +#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching +#maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching +#max_worker_processes = 8 # (change requires restart) +#max_parallel_workers_per_gather = 2 # limited by max_parallel_workers +#max_parallel_maintenance_workers = 2 # limited by max_parallel_workers +#max_parallel_workers = 8 # number of max_worker_processes that + # can be used in parallel operations +#parallel_leader_participation = on +#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate + # (change requires restart) + + +#------------------------------------------------------------------------------ +# WRITE-AHEAD LOG +#------------------------------------------------------------------------------ + +# - Settings - + +#wal_level = replica # minimal, replica, or logical + # (change requires restart) +#fsync = on # flush data to disk for crash safety + # (turning this off can cause + # unrecoverable data corruption) +#synchronous_commit = on # synchronization level; + # off, local, remote_write, remote_apply, or on +#wal_sync_method = fsync # the default is the first option + # supported by the operating system: + # open_datasync + # fdatasync (default on Linux and FreeBSD) + # fsync + # fsync_writethrough + # open_sync +#full_page_writes = on # recover from partial page writes +#wal_log_hints = off # also do full page writes of non-critical updates + # (change requires restart) +#wal_compression = off # enables compression of full-page writes; + # off, pglz, lz4, zstd, or on +#wal_init_zero = on # zero-fill new WAL files +#wal_recycle = on # recycle WAL files +#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers + # (change requires restart) +#wal_writer_delay = 200ms # 1-10000 milliseconds +#wal_writer_flush_after = 1MB # measured in pages, 0 disables +#wal_skip_threshold = 2MB + +#commit_delay = 0 # range 0-100000, in microseconds +#commit_siblings = 5 # range 1-1000 + +# - Checkpoints - + +#checkpoint_timeout = 5min # range 30s-1d +#checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0 +#checkpoint_flush_after = 256kB # measured in pages, 0 disables +#checkpoint_warning = 30s # 0 disables +max_wal_size = 1GB +min_wal_size = 80MB + +# - Prefetching during recovery - + +#recovery_prefetch = try # prefetch pages referenced in the WAL? +#wal_decode_buffer_size = 512kB # lookahead window used for prefetching + # (change requires restart) + +# - Archiving - + +#archive_mode = off # enables archiving; off, on, or always + # (change requires restart) +#archive_library = '' # library to use to archive a WAL file + # (empty string indicates archive_command should + # be used) +#archive_command = '' # command to use to archive a WAL file + # placeholders: %p = path of file to archive + # %f = file name only + # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +#archive_timeout = 0 # force a WAL file switch after this + # number of seconds; 0 disables + +# - Archive Recovery - + +# These are only used in recovery mode. + +#restore_command = '' # command to use to restore an archived WAL file + # placeholders: %p = path of file to restore + # %f = file name only + # e.g. 'cp /mnt/server/archivedir/%f %p' +#archive_cleanup_command = '' # command to execute at every restartpoint +#recovery_end_command = '' # command to execute at completion of recovery + +# - Recovery Target - + +# Set these only when performing a targeted recovery. + +#recovery_target = '' # 'immediate' to end recovery as soon as a + # consistent state is reached + # (change requires restart) +#recovery_target_name = '' # the named restore point to which recovery will proceed + # (change requires restart) +#recovery_target_time = '' # the time stamp up to which recovery will proceed + # (change requires restart) +#recovery_target_xid = '' # the transaction ID up to which recovery will proceed + # (change requires restart) +#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed + # (change requires restart) +#recovery_target_inclusive = on # Specifies whether to stop: + # just after the specified recovery target (on) + # just before the recovery target (off) + # (change requires restart) +#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID + # (change requires restart) +#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' + # (change requires restart) + + +#------------------------------------------------------------------------------ +# REPLICATION +#------------------------------------------------------------------------------ + +# - Sending Servers - + +# Set these on the primary and on any standby that will send replication data. + +#max_wal_senders = 10 # max number of walsender processes + # (change requires restart) +#max_replication_slots = 10 # max number of replication slots + # (change requires restart) +#wal_keep_size = 0 # in megabytes; 0 disables +#max_slot_wal_keep_size = -1 # in megabytes; -1 disables +#wal_sender_timeout = 60s # in milliseconds; 0 disables +#track_commit_timestamp = off # collect timestamp of transaction commit + # (change requires restart) + +# - Primary Server - + +# These settings are ignored on a standby server. + +#synchronous_standby_names = '' # standby servers that provide sync rep + # method to choose sync standbys, number of sync standbys, + # and comma-separated list of application_name + # from standby(s); '*' = all + +# - Standby Servers - + +# These settings are ignored on a primary server. + +#primary_conninfo = '' # connection string to sending server +#primary_slot_name = '' # replication slot on sending server +#hot_standby = on # "off" disallows queries during recovery + # (change requires restart) +#max_standby_archive_delay = 30s # max delay before canceling queries + # when reading WAL from archive; + # -1 allows indefinite delay +#max_standby_streaming_delay = 30s # max delay before canceling queries + # when reading streaming WAL; + # -1 allows indefinite delay +#wal_receiver_create_temp_slot = off # create temp slot if primary_slot_name + # is not set +#wal_receiver_status_interval = 10s # send replies at least this often + # 0 disables +#hot_standby_feedback = off # send info from standby to prevent + # query conflicts +#wal_receiver_timeout = 60s # time that receiver waits for + # communication from primary + # in milliseconds; 0 disables +#wal_retrieve_retry_interval = 5s # time to wait before retrying to + # retrieve WAL after a failed attempt +#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery + +# - Subscribers - + +# These settings are ignored on a publisher. + +#max_logical_replication_workers = 4 # taken from max_worker_processes + # (change requires restart) +#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers +#max_parallel_apply_workers_per_subscription = 2 # taken from max_logical_replication_workers + + +#------------------------------------------------------------------------------ +# QUERY TUNING +#------------------------------------------------------------------------------ + +# - Planner Method Configuration - + +#enable_async_append = on +#enable_bitmapscan = on +#enable_gathermerge = on +#enable_hashagg = on +#enable_hashjoin = on +#enable_incremental_sort = on +#enable_indexscan = on +#enable_indexonlyscan = on +#enable_material = on +#enable_memoize = on +#enable_mergejoin = on +#enable_nestloop = on +#enable_parallel_append = on +#enable_parallel_hash = on +#enable_partition_pruning = on +#enable_partitionwise_join = off +#enable_partitionwise_aggregate = off +#enable_presorted_aggregate = on +#enable_seqscan = on +#enable_sort = on +#enable_tidscan = on + +# - Planner Cost Constants - + +#seq_page_cost = 1.0 # measured on an arbitrary scale +#random_page_cost = 4.0 # same scale as above +#cpu_tuple_cost = 0.01 # same scale as above +#cpu_index_tuple_cost = 0.005 # same scale as above +#cpu_operator_cost = 0.0025 # same scale as above +#parallel_setup_cost = 1000.0 # same scale as above +#parallel_tuple_cost = 0.1 # same scale as above +#min_parallel_table_scan_size = 8MB +#min_parallel_index_scan_size = 512kB +#effective_cache_size = 4GB + +#jit_above_cost = 100000 # perform JIT compilation if available + # and query more expensive than this; + # -1 disables +#jit_inline_above_cost = 500000 # inline small functions if query is + # more expensive than this; -1 disables +#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if + # query is more expensive than this; + # -1 disables + +# - Genetic Query Optimizer - + +#geqo = on +#geqo_threshold = 12 +#geqo_effort = 5 # range 1-10 +#geqo_pool_size = 0 # selects default based on effort +#geqo_generations = 0 # selects default based on effort +#geqo_selection_bias = 2.0 # range 1.5-2.0 +#geqo_seed = 0.0 # range 0.0-1.0 + +# - Other Planner Options - + +#default_statistics_target = 100 # range 1-10000 +#constraint_exclusion = partition # on, off, or partition +#cursor_tuple_fraction = 0.1 # range 0.0-1.0 +#from_collapse_limit = 8 +#jit = on # allow JIT compilation +#join_collapse_limit = 8 # 1 disables collapsing of explicit + # JOIN clauses +#plan_cache_mode = auto # auto, force_generic_plan or + # force_custom_plan +#recursive_worktable_factor = 10.0 # range 0.001-1000000 + + +#------------------------------------------------------------------------------ +# REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +# - Where to Log - + +#log_destination = 'stderr' # Valid values are combinations of + # stderr, csvlog, jsonlog, syslog, and + # eventlog, depending on platform. + # csvlog and jsonlog require + # logging_collector to be on. + +# This is used when logging to stderr: +#logging_collector = off # Enable capturing of stderr, jsonlog, + # and csvlog into log files. Required + # to be on for csvlogs and jsonlogs. + # (change requires restart) + +# These are only used if logging_collector is on: +#log_directory = 'log' # directory where log files are written, + # can be absolute or relative to PGDATA +#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, + # can include strftime() escapes +#log_file_mode = 0600 # creation mode for log files, + # begin with 0 to use octal notation +#log_rotation_age = 1d # Automatic rotation of logfiles will + # happen after that time. 0 disables. +#log_rotation_size = 10MB # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. +#log_truncate_on_rotation = off # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. + +# These are relevant when logging to syslog: +#syslog_facility = 'LOCAL0' +#syslog_ident = 'postgres' +#syslog_sequence_numbers = on +#syslog_split_messages = on + +# This is only relevant when logging to eventlog (Windows): +# (change requires restart) +#event_source = 'PostgreSQL' + +# - When to Log - + +#log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + +#log_min_error_statement = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic (effectively off) + +#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements + # and their durations, > 0 logs only + # statements running at least this number + # of milliseconds + +#log_min_duration_sample = -1 # -1 is disabled, 0 logs a sample of statements + # and their durations, > 0 logs only a sample of + # statements running at least this number + # of milliseconds; + # sample fraction is determined by log_statement_sample_rate + +#log_statement_sample_rate = 1.0 # fraction of logged statements exceeding + # log_min_duration_sample to be logged; + # 1.0 logs all such statements, 0.0 never logs + + +#log_transaction_sample_rate = 0.0 # fraction of transactions whose statements + # are logged regardless of their duration; 1.0 logs all + # statements from all transactions, 0.0 never logs + +#log_startup_progress_interval = 10s # Time between progress updates for + # long-running startup operations. + # 0 disables the feature, > 0 indicates + # the interval in milliseconds. + +# - What to Log - + +#debug_print_parse = off +#debug_print_rewritten = off +#debug_print_plan = off +#debug_pretty_print = on +#log_autovacuum_min_duration = 10min # log autovacuum activity; + # -1 disables, 0 logs all actions and + # their durations, > 0 logs only + # actions running at least this number + # of milliseconds. +#log_checkpoints = on +#log_connections = off +#log_disconnections = off +#log_duration = off +#log_error_verbosity = default # terse, default, or verbose messages +#log_hostname = off +log_line_prefix = '%m [%p] %q%u@%d ' # special values: + # %a = application name + # %u = user name + # %d = database name + # %r = remote host and port + # %h = remote host + # %b = backend type + # %p = process ID + # %P = process ID of parallel group leader + # %t = timestamp without milliseconds + # %m = timestamp with milliseconds + # %n = timestamp with milliseconds (as a Unix epoch) + # %Q = query ID (0 if none or not computed) + # %i = command tag + # %e = SQL state + # %c = session ID + # %l = session line number + # %s = session start timestamp + # %v = virtual transaction ID + # %x = transaction ID (0 if none) + # %q = stop here in non-session + # processes + # %% = '%' + # e.g. '<%u%%%d> ' +#log_lock_waits = off # log lock waits >= deadlock_timeout +#log_recovery_conflict_waits = off # log standby recovery conflict waits + # >= deadlock_timeout +#log_parameter_max_length = -1 # when logging statements, limit logged + # bind-parameter values to N bytes; + # -1 means print in full, 0 disables +#log_parameter_max_length_on_error = 0 # when logging an error, limit logged + # bind-parameter values to N bytes; + # -1 means print in full, 0 disables +#log_statement = 'none' # none, ddl, mod, all +#log_replication_commands = off +#log_temp_files = -1 # log temporary files equal or larger + # than the specified size in kilobytes; + # -1 disables, 0 logs all temp files +log_timezone = 'Etc/UTC' + +# - Process Title - + +cluster_name = '16/main' # added to process titles if nonempty + # (change requires restart) +#update_process_title = on + + +#------------------------------------------------------------------------------ +# STATISTICS +#------------------------------------------------------------------------------ + +# - Cumulative Query and Index Statistics - + +#track_activities = on +#track_activity_query_size = 1024 # (change requires restart) +#track_counts = on +#track_io_timing = off +#track_wal_io_timing = off +#track_functions = none # none, pl, all +#stats_fetch_consistency = cache # cache, none, snapshot + + +# - Monitoring - + +#compute_query_id = auto +#log_statement_stats = off +#log_parser_stats = off +#log_planner_stats = off +#log_executor_stats = off + + +#------------------------------------------------------------------------------ +# AUTOVACUUM +#------------------------------------------------------------------------------ + +#autovacuum = on # Enable autovacuum subprocess? 'on' + # requires track_counts to also be on. +#autovacuum_max_workers = 3 # max number of autovacuum subprocesses + # (change requires restart) +#autovacuum_naptime = 1min # time between autovacuum runs +#autovacuum_vacuum_threshold = 50 # min number of row updates before + # vacuum +#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts + # before vacuum; -1 disables insert + # vacuums +#autovacuum_analyze_threshold = 50 # min number of row updates before + # analyze +#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum +#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table + # size before insert vacuum +#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze +#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum + # (change requires restart) +#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age + # before forced vacuum + # (change requires restart) +#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for + # autovacuum, in milliseconds; + # -1 means use vacuum_cost_delay +#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for + # autovacuum, -1 means use + # vacuum_cost_limit + + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Statement Behavior - + +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error +#search_path = '"$user", public' # schema names +#row_security = on +#default_table_access_method = 'heap' +#default_tablespace = '' # a tablespace name, '' uses the default +#default_toast_compression = 'pglz' # 'pglz' or 'lz4' +#temp_tablespaces = '' # a list of tablespace names, '' uses + # only default tablespace +#check_function_bodies = on +#default_transaction_isolation = 'read committed' +#default_transaction_read_only = off +#default_transaction_deferrable = off +#session_replication_role = 'origin' +#statement_timeout = 0 # in milliseconds, 0 is disabled +#lock_timeout = 0 # in milliseconds, 0 is disabled +#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled +#idle_session_timeout = 0 # in milliseconds, 0 is disabled +#vacuum_freeze_table_age = 150000000 +#vacuum_freeze_min_age = 50000000 +#vacuum_failsafe_age = 1600000000 +#vacuum_multixact_freeze_table_age = 150000000 +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_failsafe_age = 1600000000 +#bytea_output = 'hex' # hex, escape +#xmlbinary = 'base64' +#xmloption = 'content' +#gin_pending_list_limit = 4MB +#createrole_self_grant = '' # set and/or inherit + +# - Locale and Formatting - + +datestyle = 'iso, mdy' +#intervalstyle = 'postgres' +timezone = 'Etc/UTC' +#timezone_abbreviations = 'Default' # Select the set of available time zone + # abbreviations. Currently, there are + # Default + # Australia (historical usage) + # India + # You can create your own file in + # share/timezonesets/. +#extra_float_digits = 1 # min -15, max 3; any value >0 actually + # selects precise output mode +#client_encoding = sql_ascii # actually, defaults to database + # encoding + +# These settings are initialized by initdb, but they can be changed. +lc_messages = 'C.UTF-8' # locale for system error message + # strings +lc_monetary = 'C.UTF-8' # locale for monetary formatting +lc_numeric = 'C.UTF-8' # locale for number formatting +lc_time = 'C.UTF-8' # locale for time formatting + +#icu_validation_level = warning # report ICU locale validation + # errors at the given level + +# default configuration for text search +default_text_search_config = 'pg_catalog.english' + +# - Shared Library Preloading - + +#local_preload_libraries = '' +#session_preload_libraries = '' +#shared_preload_libraries = '' # (change requires restart) +#jit_provider = 'llvmjit' # JIT library to use + +# - Other Defaults - + +#dynamic_library_path = '$libdir' +#extension_destdir = '' # prepend path when loading extensions + # and shared objects (added by Debian) +#gin_fuzzy_search_limit = 0 + + +#------------------------------------------------------------------------------ +# LOCK MANAGEMENT +#------------------------------------------------------------------------------ + +#deadlock_timeout = 1s +#max_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_relation = -2 # negative values mean + # (max_pred_locks_per_transaction + # / -max_pred_locks_per_relation) - 1 +#max_pred_locks_per_page = 2 # min 0 + + +#------------------------------------------------------------------------------ +# VERSION AND PLATFORM COMPATIBILITY +#------------------------------------------------------------------------------ + +# - Previous PostgreSQL Versions - + +#array_nulls = on +#backslash_quote = safe_encoding # on, off, or safe_encoding +#escape_string_warning = on +#lo_compat_privileges = off +#quote_all_identifiers = off +#standard_conforming_strings = on +#synchronize_seqscans = on + +# - Other Platforms and Clients - + +#transform_null_equals = off + + +#------------------------------------------------------------------------------ +# ERROR HANDLING +#------------------------------------------------------------------------------ + +#exit_on_error = off # terminate session on any error? +#restart_after_crash = on # reinitialize after backend crash? +#data_sync_retry = off # retry or panic on failure to fsync + # data? + # (change requires restart) +#recovery_init_sync_method = fsync # fsync, syncfs (Linux 5.8+) + + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +# These options allow settings to be loaded from files other than the +# default postgresql.conf. Note that these are directives, not variable +# assignments, so they can usefully be given more than once. + +include_dir = 'conf.d' # include files ending in '.conf' from + # a directory, e.g., 'conf.d' +#include_if_exists = '...' # include file only if it exists +#include = '...' # include file + + +#------------------------------------------------------------------------------ +# CUSTOMIZED OPTIONS +#------------------------------------------------------------------------------ + +# Add settings for extensions here diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/postgres/scripts/pgpool_remote_start.sh b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/scripts/pgpool_remote_start.sh new file mode 100644 index 0000000000000000000000000000000000000000..18727be5996c32ac95dfd16e100cb77297966fa7 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/scripts/pgpool_remote_start.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# This script is run after recovery_1st_stage to start Standby node. + +set -o xtrace + +DEST_NODE_HOST="$1" +DEST_NODE_PGDATA="$2" + +PGHOME=/usr/lib/postgresql/16 +POSTGRESQL_STARTUP_USER=postgres +SSH_KEY_FILE=id_rsa_pgpool +SSH_OPTIONS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/${SSH_KEY_FILE}" + +echo pgpool_remote_start: start: remote start Standby node $DEST_NODE_HOST + +## Test passwordless SSH +ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@${DEST_NODE_HOST} ls /tmp > /dev/null + +if [ $? -ne 0 ]; then + echo ERROR: pgpool_remote_start: passwordless SSH to ${POSTGRESQL_STARTUP_USER}@${DEST_NODE_HOST} failed. Please setup passwordless SSH. + exit 1 +fi + +## Start Standby node +ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@${DEST_NODE_HOST} " + $PGHOME/bin/pg_ctl -l /var/log/postgresql/pg_ctl.log -w -D /etc/postgresql/16/main status + + if [ \$? -eq 0 ]; then + exit 0 + fi + + $PGHOME/bin/pg_ctl -l /var/log/postgresql/pg_ctl.log -w -D /etc/postgresql/16/main start +" + +if [ $? -ne 0 ]; then + echo ERROR: pgpool_remote_start: ${DEST_NODE_HOST} PostgreSQL start failed. + exit 1 +fi + +echo pgpool_remote_start: end: PostgreSQL on ${DEST_NODE_HOST} is started successfully. +exit 0 diff --git a/docs/source/pages/Replicacao/pgpool_exemplo/postgres/scripts/recovery_1st_stage.sh b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/scripts/recovery_1st_stage.sh new file mode 100644 index 0000000000000000000000000000000000000000..7e787a11223df09a1c906346976225dd23e9d086 --- /dev/null +++ b/docs/source/pages/Replicacao/pgpool_exemplo/postgres/scripts/recovery_1st_stage.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# This script is executed by "recovery_1st_stage" to recovery a Standby node. + +set -o xtrace + +PRIMARY_NODE_PGDATA="$1" +DEST_NODE_HOST="$2" +DEST_NODE_PGDATA="$3" +PRIMARY_NODE_PORT="$4" +DEST_NODE_ID="$5" +DEST_NODE_PORT="$6" +PRIMARY_NODE_HOST="$7" + +PGHOME=/usr/lib/postgresql/16 +ARCHIVEDIR=/var/lib/postgresql/archivedir +REPLUSER=repl +REPL_SLOT_NAME=$(echo ${DEST_NODE_HOST,,} | tr -- -. _) +POSTGRESQL_STARTUP_USER=postgres +SSH_KEY_FILE=id_rsa_pgpool +SSH_OPTIONS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/${SSH_KEY_FILE}" + +echo recovery_1st_stage: start: pg_basebackup for Standby node $DEST_NODE_ID + +## Test passwordless SSH +ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@${DEST_NODE_HOST} ls /tmp > /dev/null + +if [ $? -ne 0 ]; then + echo recovery_1st_stage: passwordless SSH to ${POSTGRESQL_STARTUP_USER}@${DEST_NODE_HOST} failed. Please setup passwordless SSH. + exit 1 +fi + + +RECOVERYCONF=${DEST_NODE_PGDATA}/myrecovery.conf + +## Create replication slot "${REPL_SLOT_NAME}" +${PGHOME}/bin/psql -h ${PRIMARY_NODE_HOST} -p ${PRIMARY_NODE_PORT} postgres \ + -c "SELECT pg_create_physical_replication_slot('${REPL_SLOT_NAME}');" >/dev/null 2>&1 + +if [ $? -ne 0 ]; then + echo ERROR: recovery_1st_stage: create replication slot \"${REPL_SLOT_NAME}\" failed. You may need to create replication slot manually. +fi + +## Execute pg_basebackup to recovery Standby node +ssh -T ${SSH_OPTIONS} ${POSTGRESQL_STARTUP_USER}@$DEST_NODE_HOST " + + set -o errexit + + [ -d \"${DEST_NODE_PGDATA}\" ] && rm -rf ${DEST_NODE_PGDATA} + [ -d \"${ARCHIVEDIR}\" ] && rm -rf ${ARCHIVEDIR}/* + + ${PGHOME}/bin/pg_basebackup -h $PRIMARY_NODE_HOST -U $REPLUSER -p $PRIMARY_NODE_PORT -D $DEST_NODE_PGDATA -X stream + + cat > ${RECOVERYCONF} << EOT +primary_conninfo = 'host=${PRIMARY_NODE_HOST} port=${PRIMARY_NODE_PORT} user=${REPLUSER} application_name=${DEST_NODE_HOST} passfile=/var/lib/postgresql/.pgpass' +recovery_target_timeline = 'latest' +primary_slot_name = '${REPL_SLOT_NAME}' +EOT + + sed -i -e \"\\\$ainclude_if_exists = '$(echo ${RECOVERYCONF} | sed -e 's/\//\\\//g')'\" \ + -e \"/^include_if_exists = '$(echo ${RECOVERYCONF} | sed -e 's/\//\\\//g')'/d\" /etc/postgresql/16/main/postgresql.conf + touch ${DEST_NODE_PGDATA}/standby.signal + + sed -i \ + -e \"s/#*port = .*/port = ${DEST_NODE_PORT}/\" \ + -e \"s@#*archive_command = .*@archive_command = 'cp \\\"%p\\\" \\\"${ARCHIVEDIR}/%f\\\"'@\" \ + /etc/postgresql/16/main/postgresql.conf +" + +if [ $? -ne 0 ]; then + + ${PGHOME}/bin/psql -h ${PRIMARY_NODE_HOST} -p ${PRIMARY_NODE_PORT} postgres \ + -c "SELECT pg_drop_replication_slot('${REPL_SLOT_NAME}');" >/dev/null 2>&1 + + if [ $? -ne 0 ]; then + echo ERROR: recovery_1st_stage: drop replication slot \"${REPL_SLOT_NAME}\" failed. You may need to drop replication slot manually. + fi + + echo ERROR: recovery_1st_stage: end: pg_basebackup failed. online recovery failed + exit 1 +fi + +echo recovery_1st_stage: end: recovery_1st_stage is completed successfully +exit 0