diff --git a/.travis.yml b/.travis.yml index 8472df598..98af2abed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,3 +32,14 @@ script: notifications: webhooks: https://galaxy.ansible.com/api/v1/notifications/ + +jobs: + include: + - language: python + python: 2.7 + env: IMAGE_NAME="centos:7-builded" + install: + - pip install ansible=="2.4.4.0" docker-py netaddr + - ln -s ${PWD} tests/docker/ANXS.postgresql + script: + - ansible-playbook -v -i tests/docker/hosts -e image_name=${IMAGE_NAME} tests/docker/replication.yml diff --git a/README.md b/README.md index d2f7f6e3a..4e8178363 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,10 @@ Including an example of how to use your role: - :no_entry: - Has reached End of Life (EOL) +#### Replication with repmgr + +There is initial support for setting up and running with replication managed by [repmgr](https://repmgr.org/). In it's current state it has only been tested with repmgr-4.2 and repmgr-5.0 on Centos 7 and requires Systemd. + #### Variables @@ -112,6 +116,36 @@ postgresql_user_privileges: db: foobar # database priv: "ALL" # privilege string format: example: INSERT,UPDATE/table:SELECT/anothertable:ALL role_attr_flags: "CREATEDB" # role attribute flags + +# Manage replication with repmgr (optional) +repmgr_target_group: "postgresql-db" +postgresql_ext_install_repmgr: yes +repmgr_user: repmgr +repmgr_database: repmgr +postgresql_wal_level: "replica" +postgresql_max_wal_senders: 10 +postgresql_max_replication_slots: 10 +postgresql_wal_keep_segments: 100 +postgresql_hot_standby: on +postgresql_archive_mode: on +postgresql_archive_command: "test ! -f /tmp/%f && cp %p /tmp/%f" +postgresql_shared_preload_libraries: + - repmgr + +postgresql_users: + - name: "{{repmgr_user}}" + pass: "password" + +postgresql_databases: + - name: {{repmgr_database}} + owner: "{{repmgr_user}}" + encoding: "UTF-8" + +postgresql_user_privileges: + - name: "{{repmgr_user}}" + db: {{repmgr_database}} + priv: "ALL" + role_attr_flags: "SUPERUSER,REPLICATION" ``` There's a lot more knobs and bolts to set, which you can find in the [defaults/main.yml](./defaults/main.yml) diff --git a/defaults/main.yml b/defaults/main.yml index 8b1057622..5b0026a96 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -6,6 +6,7 @@ postgresql_version_terse: "{{ postgresql_version | replace('.', '') }}" # Short postgresql_encoding: "UTF-8" postgresql_data_checksums: false postgresql_pwfile: "" +repmgr_primary: True # Default to True to work without repmgr postgresql_locale_parts: - "en_US" # Locale @@ -39,6 +40,7 @@ postgresql_database_owner: "{{ postgresql_admin_user }}" postgresql_ext_install_contrib: no postgresql_ext_install_dev_headers: no postgresql_ext_install_postgis: no +postgresql_ext_install_repmgr: no postgresql_ext_postgis_version: "2.5" # be careful: check whether the postgresql/postgis versions work together diff --git a/defaults/repmgr.yml b/defaults/repmgr.yml new file mode 100644 index 000000000..5ba932f03 --- /dev/null +++ b/defaults/repmgr.yml @@ -0,0 +1,116 @@ +# Role default overrides to work with replication +postgresql_wal_level: "replica" +postgresql_max_wal_senders: 10 +postgresql_max_replication_slots: 10 +postgresql_wal_keep_segments: 256 # Needs to be big enough for pg_basebackup to complete before this starts rotating files, 16MB each +postgresql_hot_standby: on +postgresql_archive_mode: off +postgresql_archive_command: "/bin/true" +postgresql_shared_preload_libraries: + - repmgr + +# Required configuration items +repmgr_target_group: "" +repmgr_user: "repmgr" +repmgr_database: "repmgr" +repmgr_conninfo: "host={{ansible_hostname}} user={{repmgr_user}} dbname={{repmgr_database}} connect_timeout=2" +repmgr_data_directory: "{{postgresql_data_directory}}" +repmgr_version: "4.2" + +# Optional configuration items +# + +# Repositories +repmgr_gpg_key_url: "https://dl.2ndquadrant.com/gpg-key.asc" +repmgr_baseurl: "https://dl.2ndquadrant.com/default/release/rpm/packages/centos/$releasever/$basearch/{{postgresql_version}}/" +repmgr_apt_repository: "deb [arch=amd64] https://dl.2ndquadrant.com/default/release/apt {{ ansible_distribution_release }}-2ndquadrant main" + +# Replication +repmgr_primary: False +repmgr_config_directory: "{{postgresql_conf_directory}}" +repmgr_replication_user: "{{repmgr_user}}" +repmgr_replication_type: "physical" +repmgr_location: "default" +repmgr_use_replication_slots: "no" +repmgr_witness_sync_interval: 15 +repmgr_use_primary_conninfo_password: "false" +repmgr_passfile: "/var/lib/pgsql/.pgpass" +repmgr_private_key_path: "/var/lib/pgsql/.ssh/id_rsa" +repmgr_public_key_path: "/var/lib/pgsql/.ssh/id_rsa.pub" +repmgr_ssh_key_bits: "2048" +repmgr_ssh_key_type: "rsa" + +# Logging +repmgr_log_level: "INFO" +repmgr_log_facility: "STDERR" +repmgr_log_file: "" +repmgr_log_status_interval: 300 + +# Notification +repmgr_event_notification_command: "" +repmgr_event_notifications: "" + +# Directories +repmgr_pg_bindir: "{{postgresql_bin_directory}}" +repmgr_repmgr_bindir: "{{postgresql_bin_directory}}" + +# Commands & options +repmgr_pg_ctl_options: "" +repmgr_pg_basebackup_options: "" +repmgr_rsync_options: "" +repmgr_tablespace_mapping: "" +repmgr_restore_command: "" +repmgr_archive_cleanup_command: "" +repmgr_recovery_min_apply_delay: "" +repmgr_ssh_options: "-o StrictHostKeyChecking=no" + +# Intervals & timeouts +repmgr_promote_check_timeout: 60 +repmgr_promote_check_interval: 1 +repmgr_primary_follow_timeout: 60 +repmgr_standby_follow_timeout: 15 +repmgr_shutdown_check_timeout: 60 +repmgr_standby_reconnect_timeout: 60 +repmgr_node_rejoin_timeout: 60 + +# Barman +repmgr_barman_server: "" +repmgr_barman_host: "" +repmgr_barman_config: "" +repmgr_repmgrd_pid_file: "" + +# Fail-over +repmgr_failover: "manual" +repmgr_standby_disconnect_on_failover: "false" +repmgr_primary_visibility_consensus: "false" +repmgr_priority: 100 +repmgr_reconnect_attempts: 6 +repmgr_reconnect_interval: 10 +repmgr_promote_command: "" +repmgr_follow_command: "" +repmgr_primary_notification_timeout: 60 +repmgr_repmgrd_standby_startup_timeout: 60 + +# Monitoring +repmgr_monitoring_history: "no" +repmgr_monitor_interval_secs: 2 +repmgr_degraded_monitoring_timeout: -1 +repmgr_async_query_timeout: 60 +repmgr_keep_history_days: 14 + +# Service commands +repmgr_service_start_command : "sudo systemctl start postgresql-{{postgresql_version}}" +repmgr_service_stop_command : "sudo systemctl stop postgresql-{{postgresql_version}}" +repmgr_service_restart_command : "sudo systemctl restart postgresql-{{postgresql_version}}" +repmgr_service_reload_command : "sudo systemctl reload postgresql-{{postgresql_version}}" +repmgr_service_promote_command : "" + +# Warning levels +repmgr_archive_ready_warning: 16 +repmgr_archive_ready_critical: 128 +repmgr_replication_lag_warning: 300 +repmgr_replication_lag_critical: 600 + +# Bi-Directional Replication +repmgr_bdr_local_monitoring_only: "false" +repmgr_bdr_recovery_timeout: 30 diff --git a/handlers/main.yml b/handlers/main.yml index 6e1db981f..4bfdd1a9c 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,3 +1,5 @@ +--- +# vim: set syntax=yaml expandtab shiftwidth=2 tabstop=2 softtabstop=2 autoindent smartindent: # file: postgresql/handlers/main.yml - name: restart postgresql @@ -5,3 +7,9 @@ name: "{{ postgresql_service_name }}" state: restarted enabled: yes + + - name: restart repmgr + service: + name: "repmgr{{postgresql_version}}" + state: restarted + enabled: yes diff --git a/tasks/databases.yml b/tasks/databases.yml index 65d7525c3..d181b4eba 100644 --- a/tasks/databases.yml +++ b/tasks/databases.yml @@ -19,7 +19,7 @@ become: yes become_user: "{{postgresql_admin_user}}" with_items: "{{postgresql_databases}}" - when: postgresql_databases|length > 0 + when: postgresql_databases|length > 0 and repmgr_primary - name: PostgreSQL | Add extensions to the databases become: yes @@ -33,6 +33,7 @@ - "{{ postgresql_database_extensions }}" - extensions register: result + when: repmgr_primary - name: PostgreSQL | Add hstore to the databases with the requirement become: yes diff --git a/tasks/extensions.yml b/tasks/extensions.yml index e7baac77c..2ec5a2169 100644 --- a/tasks/extensions.yml +++ b/tasks/extensions.yml @@ -6,3 +6,5 @@ when: postgresql_ext_install_dev_headers - import_tasks: extensions/postgis.yml when: postgresql_ext_install_postgis +- import_tasks: extensions/repmgr.yml + when: postgresql_ext_install_repmgr and ansible_service_mgr == 'systemd' diff --git a/tasks/extensions/configure_repmgr.yml b/tasks/extensions/configure_repmgr.yml new file mode 100644 index 000000000..51a19a619 --- /dev/null +++ b/tasks/extensions/configure_repmgr.yml @@ -0,0 +1,149 @@ +- name: Repmgr | Update configuration (repmgr.conf) + template: + src: "repmgr.conf-{{ repmgr_version[:3] }}.j2" + dest: "{{postgresql_conf_directory}}/repmgr.conf" + owner: "{{ postgresql_service_user }}" + group: "{{ postgresql_service_group }}" + mode: 0640 + notify: restart repmgr + +- name: Repmgr | Ensure systemd drop-in directory exists + file: + path: "/etc/systemd/system/repmgr{{postgresql_version}}.service.d/" + state: directory + mode: 0755 + +- name: Repmgr | Update drop-in + template: + src: "repmgr.custom.conf.j2" + dest: "/etc/systemd/system/repmgr{{postgresql_version}}.service.d/custom.conf" + +- name: Repmgr | Allow passwordless restarts with postgres user + template: + src: "sudoers.postgresql.j2" + dest: "/etc/sudoers.d/postgresql" + mode: 0640 + +- name: Repmgr | Update .pgpass for postgres user + template: + src: "pgpass.j2" + dest: "{{repmgr_passfile}}" + owner: "{{ postgresql_service_user }}" + group: "{{ postgresql_service_group }}" + mode: 0400 + trim_blocks: no + +- name: Repmgr | Generate ssh keypair for postgres user + command: "ssh-keygen -b {{repmgr_ssh_key_bits}} -t {{repmgr_ssh_key_type}} -f {{repmgr_private_key_path}} -N ''" + args: + creates: "{{repmgr_private_key_path}}" + become: yes + become_user: "{{ postgresql_service_user }}" + when: repmgr_primary + +- name: Repmgr | Slurp ssh public key + slurp: + src: "{{repmgr_public_key_path}}" + register: ssh_public_key + when: repmgr_primary + +- name: Repmgr | Slurp ssh private key + slurp: + src: "{{repmgr_private_key_path}}" + register: ssh_private_key + when: repmgr_primary + +- name: Repmgr | Update authorized_keys for postgres user + authorized_key: + user: postgres + state: present + key: "{% for host, vars in hostvars.items() if 'repmgr_primary' in vars and vars['repmgr_primary'] == True %}{{ vars['ssh_public_key']['content'] | b64decode }}{% endfor %}" + +- name: Repmgr | Update public ssh key for postgres user + copy: + content: "{% for host, vars in hostvars.items() if 'repmgr_primary' in vars and vars['repmgr_primary'] == True %}{{ vars['ssh_public_key']['content'] | b64decode }}{% endfor %}" + dest: "{{repmgr_public_key_path}}" + owner: "{{ postgresql_service_user }}" + group: "{{ postgresql_service_group }}" + mode: 0644 + +- name: Repmgr | Update private ssh key for postgres user + copy: + content: "{% for host, vars in hostvars.items() if 'repmgr_primary' in vars and vars['repmgr_primary'] == True %}{{ vars['ssh_private_key']['content'] | b64decode }}{% endfor %}" + dest: "{{repmgr_private_key_path}}" + owner: "{{ postgresql_service_user }}" + group: "{{ postgresql_service_group }}" + mode: 0600 + +- name: Repmgr | Check cluster status + command: "{{postgresql_bin_directory}}/repmgr -f {{postgresql_conf_directory}}/repmgr.conf cluster show" + become: yes + become_user: "{{ postgresql_service_user }}" + changed_when: repmgr_cluster_show.rc != 0 + register: repmgr_cluster_show + ignore_errors: True + +- name: Repmgr | Register as primary + command: "{{postgresql_bin_directory}}/repmgr -f {{postgresql_conf_directory}}/repmgr.conf primary register" + become: yes + become_user: "{{ postgresql_service_user }}" + when: repmgr_primary and not ansible_hostname in repmgr_cluster_show.stdout and not "primary" in repmgr_cluster_show.stdout + +- name: Repmgr | Ensure postgresql slave is stopped before clone + service: + name: "postgresql-{{postgresql_version}}" + state: stopped + when: not repmgr_primary and not ansible_hostname in repmgr_cluster_show.stdout and not "standby" in repmgr_cluster_show.stdout + +- name: Repmgr | Clone standby + command: "{{postgresql_bin_directory}}/repmgr -F -h {% for host, vars in hostvars.items() if 'repmgr_primary' in vars and vars['repmgr_primary'] == True %}{{ host }}{% endfor %} -U repmgr -d repmgr -f {{postgresql_conf_directory}}/repmgr.conf standby clone" + become: yes + become_user: "{{ postgresql_service_user }}" + when: not repmgr_primary and not ansible_hostname in repmgr_cluster_show.stdout and not "standby" in repmgr_cluster_show.stdout + +- name: Repmgr | Ensure postgresql slave is running after clone + service: + name: "postgresql-{{postgresql_version}}" + state: started + when: not repmgr_primary + +- name: Repmgr | Wait for Postgres + wait_for: + timeout: 2 + delegate_to: localhost + +- name: Repmgr | Register standby + command: "{{postgresql_bin_directory}}/repmgr -F -h {% for host, vars in hostvars.items() if 'repmgr_primary' in vars and vars['repmgr_primary'] == True %}{{ host }}{% endfor %} -U repmgr -d repmgr -f {{postgresql_conf_directory}}/repmgr.conf standby register" + become: yes + become_user: "{{ postgresql_service_user }}" + when: not repmgr_primary and not ansible_hostname in repmgr_cluster_show.stdout and not "standby" in repmgr_cluster_show.stdout + +- name: Repmgr | Verify cluster functionality + command: "{{postgresql_bin_directory}}/repmgr -F -h {% for host, vars in hostvars.items() if 'repmgr_primary' in vars and vars['repmgr_primary'] == True %}{{ host }}{% endfor %} -U repmgr -d repmgr -f {{postgresql_conf_directory}}/repmgr.conf cluster crosscheck" + become: yes + become_user: "{{ postgresql_service_user }}" + +- name: Repmgr | Ensure repmgrd is running + service: + name: "repmgr{{postgresql_version}}" + state: started + enabled: yes + when: repmgr_monitoring_history == "true" or repmgr_failover == "automatic" + +- name: Repmgr | Ensure crontab is installed + package: + name: crontabs + when: repmgr_monitoring_history == "true" or repmgr_failover == "automatic" + +- name: Repmgr | Ensure crond is running + service: + name: "crond" + state: started + enabled: yes + +- name: Repmgr | Setup cluster monitoring history cleanup + copy: + content: "{{postgresql_bin_directory}}/repmgr -f {{postgresql_conf_directory}}/repmgr.conf cluster cleanup --keep-history={{repmgr_keep_history_days}}" + dest: "/etc/cron.daily/repmgr_cleanup" + mode: 0755 + when: repmgr_monitoring_history == "true" or repmgr_failover == "automatic" diff --git a/tasks/extensions/detect_repmgr_primary.yml b/tasks/extensions/detect_repmgr_primary.yml new file mode 100644 index 000000000..a19fc030c --- /dev/null +++ b/tasks/extensions/detect_repmgr_primary.yml @@ -0,0 +1,31 @@ +- name: Repmgr | Detect primary + shell: "set -o pipefail ; {{ postgresql_bin_directory }}/repmgr -f {{ postgresql_conf_directory }}/repmgr.conf cluster show | grep primary | cut -d '|' -f 2 | sed 's/\ //g'" + register: repmgr_primary_check + become: yes + become_user: postgres + ignore_errors: True + +- name: Repmgr | Declare as primary for existing installation + set_fact: + repmgr_primary: True + register: repmgr_existing_installation_detected + when: "repmgr_primary_check.rc == 0 and repmgr_primary_check.stdout == ansible_hostname" + +- name: Repmgr | Share state between hosts + delegate_to: localhost + delegate_facts: True + set_fact: + repmgr_primary_declared: True + when: "repmgr_existing_installation_detected is not skipped" + +- name: Repmgr | Declare as primary for new installation + set_fact: + repmgr_primary: "{{ True if ansible_hostname == ansible_play_hosts[0] or inventory_hostname == ansible_play_hosts[0] else False }}" + when: "hostvars['localhost'].get('repmgr_primary_declared', false) != true" + +- debug: + var: repmgr_primary + +- debug: + var: repmgr_primary_check + verbosity: 1 diff --git a/tasks/extensions/repmgr.yml b/tasks/extensions/repmgr.yml new file mode 100644 index 000000000..5f8f5cc20 --- /dev/null +++ b/tasks/extensions/repmgr.yml @@ -0,0 +1,38 @@ +# file: postgresql/tasks/extensions/contrib.yml + +- name: PostgreSQL | Extensions | Add 2nd Quadrant repo gpg key | apt + apt_key: + url: "{{repmgr_gpg_key_url}}" + when: ansible_pkg_mgr == "apt" + +- name: PostgreSQL | Extensions | Add 2nd Quadrant repo for repmgr | apt + apt_repository: + repo: "{{repmgr_apt_repository}}" + filename: 2ndquadrant-dl-default-release + when: ansible_pkg_mgr == "apt" + +- name: PostgreSQL | Extensions | Make sure the postgres repmgr extensions are installed | apt + apt: + name: "postgresql-{{postgresql_version}}-repmgr" + state: present + update_cache: yes + cache_valid_time: "{{apt_cache_valid_time | default (3600)}}" + when: ansible_pkg_mgr == "apt" + notify: + - restart postgresql + +- name: PostgreSQL | Extensions | Add 2nd Quadrant repo for repmgr | yum + yum_repository: + name: "2ndquadrant-dl-default-release-pg{{postgresql_version}}" + description: "2ndQuadrant packages (PG{{postgresql_version}}) for $releasever - $basearch" + baseurl: "{{ repmgr_baseurl }}" + gpgkey: "{{ repmgr_gpg_key_url }}" + when: ansible_pkg_mgr == "yum" or ansible_pkg_mgr == "dnf" + +- name: PostgreSQL | Extensions | Make sure the postgres repmgr extensions are installed | yum + yum: + name: "repmgr{{postgresql_version}}-{{repmgr_version}}" + state: present + when: ansible_pkg_mgr == "yum" + notify: + - restart postgresql diff --git a/tasks/main.yml b/tasks/main.yml index 116015a59..d2a23de22 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -30,6 +30,10 @@ - import_tasks: extensions.yml tags: [postgresql, postgresql-extensions] +- import_tasks: extensions/detect_repmgr_primary.yml + when: postgresql_ext_install_repmgr and ansible_service_mgr == 'systemd' + tags: [postgresql, postgresql-extensions] + - import_tasks: fdw.yml tags: [postgresql, postgresql-fdw] @@ -52,5 +56,9 @@ when: monit_protection is defined and monit_protection == true tags: [postgresql, postgresql-monit] +- import_tasks: extensions/configure_repmgr.yml + when: postgresql_ext_install_repmgr and ansible_service_mgr == 'systemd' + tags: [postgresql, postgresql-extensions] + - import_tasks: check_pg_version_mismatch.yml tags: [postgresql, postgresql-version-mismatch] diff --git a/tasks/schemas.yml b/tasks/schemas.yml index 01b050318..a666c9c8a 100644 --- a/tasks/schemas.yml +++ b/tasks/schemas.yml @@ -13,4 +13,4 @@ become: yes become_user: "{{ postgresql_admin_user }}" with_items: "{{ postgresql_database_schemas }}" - when: postgresql_databases|length > 0 + when: postgresql_databases|length > 0 and repmgr_primary diff --git a/tasks/users.yml b/tasks/users.yml index 12e2c9f2a..4b38e57bf 100644 --- a/tasks/users.yml +++ b/tasks/users.yml @@ -17,4 +17,4 @@ become: yes become_user: "{{postgresql_admin_user}}" with_items: "{{postgresql_users}}" - when: postgresql_users|length > 0 + when: postgresql_users|length > 0 and repmgr_primary diff --git a/tasks/users_privileges.yml b/tasks/users_privileges.yml index 94aaea245..8c9794b73 100644 --- a/tasks/users_privileges.yml +++ b/tasks/users_privileges.yml @@ -13,4 +13,4 @@ become: yes become_user: "{{postgresql_admin_user}}" with_items: "{{postgresql_user_privileges}}" - when: postgresql_users|length > 0 + when: postgresql_users|length > 0 and repmgr_primary diff --git a/templates/pgpass.j2 b/templates/pgpass.j2 new file mode 100644 index 000000000..abeae8f5e --- /dev/null +++ b/templates/pgpass.j2 @@ -0,0 +1,4 @@ +{% for server in groups[repmgr_target_group] | sort %} +{{ server }}:{{postgresql_port}}:{{repmgr_database}}:{{repmgr_user}}:{% for user in postgresql_users if user['name'] == repmgr_user %}{{user['pass']}}{% endfor %} +{{ server }}:{{postgresql_port}}:replication:{{repmgr_replication_user}}:{% for user in postgresql_users if user['name'] == repmgr_user %}{{user['pass']}}{% endfor %} +{% endfor %} diff --git a/templates/repmgr.conf-4.2.j2 b/templates/repmgr.conf-4.2.j2 new file mode 100644 index 000000000..55fe99fd3 --- /dev/null +++ b/templates/repmgr.conf-4.2.j2 @@ -0,0 +1,394 @@ +# {{ ansible_managed }} +################################################### +# repmgr sample configuration file +################################################### + +# Some configuration items will be set with a default value; this +# is noted for each item. Where no default value is shown, the +# parameter will be treated as empty or false. + +# ============================================================================= +# Required configuration items +# ============================================================================= +# +# repmgr and repmgrd require the following items to be explicitly configured. + + +node_id='{{ repmgr_node_id if repmgr_node_id is defined else range(1, 2147483647) | random(seed=ansible_hostname) }}' # A unique integer greater than zero +node_name='{{ansible_hostname}}' # An arbitrary (but unique) string; we recommend + # using the server's hostname or another identifier + # unambiguously associated with the server to avoid + # confusion. Avoid choosing names which reflect the + # node's current role, e.g. "primary" or "standby1", + # as roles can change and it will be confusing if + # the current primary is called "standby1". + +conninfo='{{repmgr_conninfo}}' # Database connection information as a conninfo string. + # All servers in the cluster must be able to connect to + # the local node using this string. + # + # For details on conninfo strings, see: + # https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING + # + # If repmgrd is in use, consider explicitly setting + # "connect_timeout" in the conninfo string to determine + # the length of time which elapses before a network + # connection attempt is abandoned; for details see: + # https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT + +data_directory='{{repmgr_data_directory}}' # The node's data directory. This is needed by repmgr + # when performing operations when the PostgreSQL instance + # is not running and there's no other way of determining + # the data directory. + + +# ============================================================================= + +# Optional configuration items +# ============================================================================= + + +#------------------------------------------------------------------------------ +# Server settings +#------------------------------------------------------------------------------ + +config_directory='{{repmgr_config_directory}}' # If configuration files are located outside the data + # directory, specify the directory where the main + # postgresql.conf file is located. + +#------------------------------------------------------------------------------ +# Replication settings +#------------------------------------------------------------------------------ + +replication_user='{{repmgr_replication_user}}' # User to make replication connections with, if not set defaults + # to the user defined in "conninfo". + +replication_type='{{repmgr_replication_type}}' # Must be one of 'physical' or 'bdr'. + +location='{{repmgr_location}}' # arbitrary string defining the location of the node; this + # is used during failover to check visibilty of the + # current primary node. See the 'repmgrd' documentation + # in README.md for further details. + +use_replication_slots='{{repmgr_use_replication_slots}}' # whether to use physical replication slots + # NOTE: when using replication slots, + # 'max_replication_slots' should be configured for + # at least the number of standbys which will connect + # to the primary. + +#------------------------------------------------------------------------------ +# Witness server settings +#------------------------------------------------------------------------------ + +witness_sync_interval={{repmgr_witness_sync_interval}} # interval (in seconds) to synchronise node records + # to the witness server + +#------------------------------------------------------------------------------ +# Logging settings +#------------------------------------------------------------------------------ +# +# Note that logging facility settings will only apply to `repmgrd` by default; +# `repmgr` will always write to STDERR unless the switch `--log-to-file` is +# supplied, in which case it will log to the same destination as `repmgrd`. +# This is mainly intended for those cases when `repmgr` is executed directly +# by `repmgrd`. + +log_level={{repmgr_log_level}} # Log level: possible values are DEBUG, INFO, NOTICE, + # WARNING, ERROR, ALERT, CRIT or EMERG + +log_facility={{repmgr_log_facility}} # Logging facility: possible values are STDERR, or for + # syslog integration, one of LOCAL0, LOCAL1, ..., LOCAL7, USER + +{{ '' if repmgr_log_file else '#' }}log_file='{{repmgr_log_file}}' # STDERR can be redirected to an arbitrary file +log_status_interval={{repmgr_log_status_interval}} # interval (in seconds) for repmgrd to log a status message + + +#------------------------------------------------------------------------------ +# Event notification settings +#------------------------------------------------------------------------------ + +# event notifications can be passed to an arbitrary external program +# together with the following parameters: +# +# %n - node ID +# %e - event type +# %s - success (1 or 0) +# %t - timestamp +# %d - details +# +# the values provided for "%t" and "%d" will probably contain spaces, +# so should be quoted in the provided command configuration, e.g.: +# +# event_notification_command='/path/to/some/script %n %e %s "%t" "%d"' +# +# By default, all notifications will be passed; the notification types +# can be filtered to explicitly named ones, e.g.: +# +# event_notifications=primary_register,standby_register + +{{ '' if repmgr_event_notification_command else '#' }}event_notification_command='{{repmgr_event_notification_command}}' # An external program or script which + # can be executed by the user under which + # repmgr/repmgrd are run. + +{{ '' if repmgr_event_notifications else '#' }}event_notifications='{{repmgr_event_notifications}}' # A commas-separated list of notification + # types + +#------------------------------------------------------------------------------ +# Environment/command settings +#------------------------------------------------------------------------------ + +pg_bindir='{{repmgr_pg_bindir}}' # Path to PostgreSQL binary directory (location + # of pg_ctl, pg_basebackup etc.). Only needed + # if these files are not in the system $PATH. + # + # Debian/Ubuntu users: you will probably need to + # set this to the directory where `pg_ctl` is located, + # e.g. /usr/lib/postgresql/9.6/bin/ + # + # *NOTE* "pg_bindir" is only used when repmgr directly + # executes PostgreSQL binaries; any user-defined scripts + # *must* be specified with the full path + +repmgr_bindir='{{repmgr_repmgr_bindir}}' # Path to repmgr binary directory (location of the repmgr + # binary. Only needed if the repmgr executable is not in + # the system $PATH or the path defined in "pg_bindir". + +use_primary_conninfo_password={{repmgr_use_primary_conninfo_password}} # explicitly set "password" in recovery.conf's + # "primary_conninfo" parameter using the value contained + # in the environment variable PGPASSWORD +passfile='{{repmgr_passfile}}' # path to .pgpass file to include in "primary_conninfo" +#------------------------------------------------------------------------------ +# external command options +#------------------------------------------------------------------------------ +# +# Options which can be passed to external commands invoked by repmgr/repmgrd. +# +# Examples: +# +# pg_ctl_options='-s' +# pg_basebackup_options='--label=repmgr_backup' +# rsync_options=--archive --checksum --compress --progress --rsh="ssh -o \"StrictHostKeyChecking no\"" +# ssh_options=-o "StrictHostKeyChecking no" + +{{ '' if repmgr_pg_ctl_options else '#' }}pg_ctl_options='{{repmgr_pg_ctl_options}}' # Options to append to "pg_ctl" +{{ '' if repmgr_pg_basebackup_options else '#' }}pg_basebackup_options='{{repmgr_pg_basebackup_options}}' # Options to append to "pg_basebackup" +{{ '' if repmgr_rsync_options else '#' }}rsync_options='{{repmgr_rsync_options}}' # Options to append to "rsync" +ssh_options='{{repmgr_ssh_options}}' # Options to append to "ssh" + + + +#------------------------------------------------------------------------------ +# "standby clone" settings +#------------------------------------------------------------------------------ +# +# These settings apply when cloning a standby ("repmgr standby clone"). +# +# Examples: +# +# tablespace_mapping=/path/to/original/tablespace=/path/to/new/tablespace +# restore_command = 'cp /path/to/archived/wals/%f %p' + +{{ '' if repmgr_tablespace_mapping else '#' }}tablespace_mapping='{{repmgr_tablespace_mapping}}' # Tablespaces can be remapped from one + # file system location to another. This + # parameter can be provided multiple times. + +{{ '' if repmgr_restore_command else '#' }}restore_command='{{repmgr_restore_command}}' # This will be placed in the recovery.conf file generated + # by repmgr. + +{{ '' if repmgr_archive_cleanup_command else '#' }}archive_cleanup_command='{{repmgr_archive_cleanup_command}}' # This will be placed in the recovery.conf file generated + # by repmgr. Note we recommend using Barman for managing + # WAL archives (see: https://www.pgbarman.org ) + +{{ '' if repmgr_recovery_min_apply_delay else '#' }}recovery_min_apply_delay={{repmgr_recovery_min_apply_delay}} # If provided, "recovery_min_apply_delay" in recovery.conf + # will be set to this value (PostgreSQL 9.4 and later). + + +#------------------------------------------------------------------------------ +# "standby promote" settings +#------------------------------------------------------------------------------ + +# These settings apply when instructing a standby to promote itself to the +# new primary ("repmgr standby promote"). + +promote_check_timeout={{repmgr_promote_check_timeout}} # The length of time (in seconds) to wait + # for the new primary to finish promoting +promote_check_interval={{repmgr_promote_check_interval}} # The interval (in seconds) to check whether + # the new primary has finished promoting + + +#------------------------------------------------------------------------------ +# "standby follow" settings +#------------------------------------------------------------------------------ + +# These settings apply when instructing a standby to follow the new primary +# ("repmgr standby follow"). + +primary_follow_timeout={{repmgr_primary_follow_timeout}} # The max length of time (in seconds) to wait + # for the new primary to become available +standby_follow_timeout={{repmgr_standby_follow_timeout}} # The max length of time (in seconds) to wait + # for the standby to connect to the primary + + +#------------------------------------------------------------------------------ +# "standby switchover" settings +#------------------------------------------------------------------------------ + +# These settings apply when switching roles between a primary and a standby +# ("repmgr standby switchover"). + +shutdown_check_timeout={{repmgr_shutdown_check_timeout}} # The max length of time (in seconds) to wait for the demotion + # candidate (current primary) to shut down +standby_reconnect_timeout={{repmgr_standby_reconnect_timeout}} # The max length of time (in seconds) to wait + # for the demoted standby to reconnect to the promoted + # primary (note: this value should be equal to or greater + # than that set for "node_rejoin_timeout") + +#------------------------------------------------------------------------------ +# "node rejoin" settings +#------------------------------------------------------------------------------ + +# These settings apply when reintegrating a node into a replication cluster +# with "repmgrd_node_rejoin" + +node_rejoin_timeout={{repmgr_node_rejoin_timeout}} # The maximum length of time (in seconds) to wait for + # the node to reconnect to the replication cluster + +#------------------------------------------------------------------------------ +# Barman options +#------------------------------------------------------------------------------ + +{{ '' if repmgr_barman_server else '#' }}barman_server='{{repmgr_barman_server}}' # The barman configuration section +{{ '' if repmgr_barman_host else '#' }}barman_host='{{repmgr_barman_host}}' # The host name of the barman server +{{ '' if repmgr_barman_config else '#' }}barman_config='{{repmgr_barman_config}}' # The Barman configuration file on the + # Barman server (needed if the file is + # in a non-standard location) + +#------------------------------------------------------------------------------ +# Failover and monitoring settings (repmgrd) +#------------------------------------------------------------------------------ +# +# These settings are only applied when repmgrd is running. Values shown +# are defaults. + +{{ '' if repmgr_repmgrd_pid_file else '#' }}repmgrd_pid_file={{repmgr_repmgrd_pid_file}} # Path of PID file to use for repmgrd; if not set, a PID file will + # be generated in a temporary directory specified by the environment + # variable $TMPDIR, or if not set, in "/tmp". This value can be overridden + # by the command line option "-p/--pid-file"; the command line option + # "--no-pid-file" will force PID file creation to be skipped. +failover={{repmgr_failover}} # one of 'automatic', 'manual'. + # determines what action to take in the event of upstream failure + # + # 'automatic': repmgrd will automatically attempt to promote the + # node or follow the new upstream node + # 'manual': repmgrd will take no action and the node will require + # manual attention to reattach it to replication + # (does not apply to BDR mode) + +priority={{repmgr_priority}} # indicate a preferred priority for promoting nodes; + # a value of zero prevents the node being promoted to primary + # (default: 100) + +reconnect_attempts={{repmgr_reconnect_attempts}} # Number of attempts which will be made to reconnect to an unreachable + # primary (or other upstream node) +reconnect_interval={{repmgr_reconnect_interval}} # Interval between attempts to reconnect to an unreachable + # primary (or other upstream node) +{{ '' if repmgr_promote_command else '#' }}promote_command={{repmgr_promote_command}} # command repmgrd executes when promoting a new primary; use something like: + # + # repmgr standby promote -f /etc/repmgr.conf + # +{{ '' if repmgr_follow_command else '#' }}follow_command={{repmgr_follow_command}} # command repmgrd executes when instructing a standby to follow a new primary; + # use something like: + # + # repmgr standby follow -f /etc/repmgr.conf -W --upstream-node-id=%n + # +primary_notification_timeout={{repmgr_primary_notification_timeout}} # Interval (in seconds) which repmgrd on a standby + # will wait for a notification from the new primary, + # before falling back to degraded monitoring +repmgrd_standby_startup_timeout={{repmgr_repmgrd_standby_startup_timeout}} # Interval (in seconds) which repmgrd on a standby will wait + # for the the local node to restart and become ready to accept connections after + # executing "follow_command" (defaults to the value set in "standby_reconnect_timeout") + +monitoring_history={{repmgr_monitoring_history}} # Whether to write monitoring data to the "montoring_history" table +monitor_interval_secs={{repmgr_monitor_interval_secs}} # Interval (in seconds) at which to write monitoring data +degraded_monitoring_timeout={{repmgr_degraded_monitoring_timeout}} # Interval (in seconds) after which repmgrd will terminate if the + # server being monitored is no longer available. -1 (default) + # disables the timeout completely. +async_query_timeout={{repmgr_async_query_timeout}} # Interval (in seconds) which repmgrd will wait before + # cancelling an asynchronous query. + +#------------------------------------------------------------------------------ +# service control commands +#------------------------------------------------------------------------------ +# +# repmgr provides options to override the default pg_ctl commands +# used to stop, start, restart, reload and promote the PostgreSQL cluster +# +# NOTE: These commands must be runnable on remote nodes as well for switchover +# to function correctly. +# +# If you use sudo, the user repmgr runs as (usually 'postgres') must have +# passwordless sudo access to execute the command. +# +# For example, to use systemd, you can set +# +# service_start_command = 'sudo systemctl start postgresql-9.6' +# (...) +# +# and then use the following sudoers configuration: +# +# # this is required when running sudo over ssh without -t: +# Defaults:postgres !requiretty +# postgres ALL = NOPASSWD: /usr/bin/systemctl stop postgresql-9.6, \ +# /usr/bin/systemctl start postgresql-9.6, \ +# /usr/bin/systemctl restart postgresql-9.6 +# +# Debian/Ubuntu users: use "sudo pg_ctlcluster" to execute service control commands. +# +# For more details, see: https://repmgr.org/docs/4.1/configuration-service-commands.html + +service_start_command ='{{repmgr_service_start_command }}' +service_stop_command ='{{repmgr_service_stop_command }}' +service_restart_command ='{{repmgr_service_restart_command }}' +service_reload_command ='{{repmgr_service_reload_command }}' +{{ '' if repmgr_service_promote_command else '#' }}service_promote_command ='{{repmgr_service_promote_command }}' # This parameter is intended for systems which provide a + # package-level promote command, such as Debian's + # "pg_ctlcluster". *IMPORTANT*: it is *not* a substitute + # for "promote_command"; do not use "repmgr standby promote" + # (or a script which executes "repmgr standby promote") here. + +#------------------------------------------------------------------------------ +# Status check thresholds +#------------------------------------------------------------------------------ + +# Various warning/critical thresholds used by "repmgr node check". + +archive_ready_warning={{repmgr_archive_ready_warning}} # repmgr node check --archive-ready +archive_ready_critical={{repmgr_archive_ready_critical}} # + # Numbers of files pending archiving via PostgreSQL's + # "archive_command" configuration parameter. If + # files can't be archived fast enough, or the archive + # command is failing, the buildup of files can + # cause various issues, such as server shutdown being + # delayed until all files are archived, or excessive + # space being occupied by unarchived files. + # + # Note that these values will be checked when executing + # "repmgr standby switchover" to warn about potential + # issues with shutting down the demotion candidate. + +replication_lag_warning={{repmgr_replication_lag_warning}} # repmgr node check --replication-lag +replication_lag_critical={{repmgr_replication_lag_critical}} # + # Note that these values will be checked when executing + # "repmgr standby switchover" to warn about potential + # issues with shutting down the demotion candidate. + + +#------------------------------------------------------------------------------ +# BDR monitoring options +#------------------------------------------------------------------------------ + +bdr_local_monitoring_only={{repmgr_bdr_local_monitoring_only}} # Only monitor the local node; no checks will be + # performed on the other node +bdr_recovery_timeout={{repmgr_bdr_recovery_timeout}} # If a BDR node was offline and has become available + # maximum length of time in seconds to wait for the + # node to reconnect to the cluster diff --git a/templates/repmgr.conf-4.2.orig b/templates/repmgr.conf-4.2.orig new file mode 100644 index 000000000..32c326ab3 --- /dev/null +++ b/templates/repmgr.conf-4.2.orig @@ -0,0 +1,393 @@ +################################################### +# repmgr sample configuration file +################################################### + +# Some configuration items will be set with a default value; this +# is noted for each item. Where no default value is shown, the +# parameter will be treated as empty or false. + +# ============================================================================= +# Required configuration items +# ============================================================================= +# +# repmgr and repmgrd require the following items to be explicitly configured. + + +#node_id= # A unique integer greater than zero +#node_name='' # An arbitrary (but unique) string; we recommend + # using the server's hostname or another identifier + # unambiguously associated with the server to avoid + # confusion. Avoid choosing names which reflect the + # node's current role, e.g. "primary" or "standby1", + # as roles can change and it will be confusing if + # the current primary is called "standby1". + +#conninfo='' # Database connection information as a conninfo string. + # All servers in the cluster must be able to connect to + # the local node using this string. + # + # For details on conninfo strings, see: + # https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING + # + # If repmgrd is in use, consider explicitly setting + # "connect_timeout" in the conninfo string to determine + # the length of time which elapses before a network + # connection attempt is abandoned; for details see: + # https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT + +#data_directory='' # The node's data directory. This is needed by repmgr + # when performing operations when the PostgreSQL instance + # is not running and there's no other way of determining + # the data directory. + + +# ============================================================================= + +# Optional configuration items +# ============================================================================= + + +#------------------------------------------------------------------------------ +# Server settings +#------------------------------------------------------------------------------ + +#config_directory='' # If configuration files are located outside the data + # directory, specify the directory where the main + # postgresql.conf file is located. + +#------------------------------------------------------------------------------ +# Replication settings +#------------------------------------------------------------------------------ + +#replication_user='repmgr' # User to make replication connections with, if not set defaults + # to the user defined in "conninfo". + +#replication_type=physical # Must be one of 'physical' or 'bdr'. + +#location=default # arbitrary string defining the location of the node; this + # is used during failover to check visibilty of the + # current primary node. See the 'repmgrd' documentation + # in README.md for further details. + +#use_replication_slots=no # whether to use physical replication slots + # NOTE: when using replication slots, + # 'max_replication_slots' should be configured for + # at least the number of standbys which will connect + # to the primary. + +#------------------------------------------------------------------------------ +# Witness server settings +#------------------------------------------------------------------------------ + +#witness_sync_interval=15 # interval (in seconds) to synchronise node records + # to the witness server + +#------------------------------------------------------------------------------ +# Logging settings +#------------------------------------------------------------------------------ +# +# Note that logging facility settings will only apply to `repmgrd` by default; +# `repmgr` will always write to STDERR unless the switch `--log-to-file` is +# supplied, in which case it will log to the same destination as `repmgrd`. +# This is mainly intended for those cases when `repmgr` is executed directly +# by `repmgrd`. + +#log_level=INFO # Log level: possible values are DEBUG, INFO, NOTICE, + # WARNING, ERROR, ALERT, CRIT or EMERG + +#log_facility=STDERR # Logging facility: possible values are STDERR, or for + # syslog integration, one of LOCAL0, LOCAL1, ..., LOCAL7, USER + +#log_file='' # STDERR can be redirected to an arbitrary file +#log_status_interval=300 # interval (in seconds) for repmgrd to log a status message + + +#------------------------------------------------------------------------------ +# Event notification settings +#------------------------------------------------------------------------------ + +# event notifications can be passed to an arbitrary external program +# together with the following parameters: +# +# %n - node ID +# %e - event type +# %s - success (1 or 0) +# %t - timestamp +# %d - details +# +# the values provided for "%t" and "%d" will probably contain spaces, +# so should be quoted in the provided command configuration, e.g.: +# +# event_notification_command='/path/to/some/script %n %e %s "%t" "%d"' +# +# By default, all notifications will be passed; the notification types +# can be filtered to explicitly named ones, e.g.: +# +# event_notifications=primary_register,standby_register + +#event_notification_command='' # An external program or script which + # can be executed by the user under which + # repmgr/repmgrd are run. + +#event_notifications='' # A commas-separated list of notification + # types + +#------------------------------------------------------------------------------ +# Environment/command settings +#------------------------------------------------------------------------------ + +#pg_bindir='' # Path to PostgreSQL binary directory (location + # of pg_ctl, pg_basebackup etc.). Only needed + # if these files are not in the system $PATH. + # + # Debian/Ubuntu users: you will probably need to + # set this to the directory where `pg_ctl` is located, + # e.g. /usr/lib/postgresql/9.6/bin/ + # + # *NOTE* "pg_bindir" is only used when repmgr directly + # executes PostgreSQL binaries; any user-defined scripts + # *must* be specified with the full path + +#repmgr_bindir='' # Path to repmgr binary directory (location of the repmgr + # binary. Only needed if the repmgr executable is not in + # the system $PATH or the path defined in "pg_bindir". + +#use_primary_conninfo_password=false # explicitly set "password" in recovery.conf's + # "primary_conninfo" parameter using the value contained + # in the environment variable PGPASSWORD +#passfile='' # path to .pgpass file to include in "primary_conninfo" +#------------------------------------------------------------------------------ +# external command options +#------------------------------------------------------------------------------ +# +# Options which can be passed to external commands invoked by repmgr/repmgrd. +# +# Examples: +# +# pg_ctl_options='-s' +# pg_basebackup_options='--label=repmgr_backup' +# rsync_options=--archive --checksum --compress --progress --rsh="ssh -o \"StrictHostKeyChecking no\"" +# ssh_options=-o "StrictHostKeyChecking no" + +#pg_ctl_options='' # Options to append to "pg_ctl" +#pg_basebackup_options='' # Options to append to "pg_basebackup" +#rsync_options='' # Options to append to "rsync" +ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh" + + + +#------------------------------------------------------------------------------ +# "standby clone" settings +#------------------------------------------------------------------------------ +# +# These settings apply when cloning a standby ("repmgr standby clone"). +# +# Examples: +# +# tablespace_mapping=/path/to/original/tablespace=/path/to/new/tablespace +# restore_command = 'cp /path/to/archived/wals/%f %p' + +#tablespace_mapping='' # Tablespaces can be remapped from one + # file system location to another. This + # parameter can be provided multiple times. + +#restore_command='' # This will be placed in the recovery.conf file generated + # by repmgr. + +#archive_cleanup_command='' # This will be placed in the recovery.conf file generated + # by repmgr. Note we recommend using Barman for managing + # WAL archives (see: https://www.pgbarman.org ) + +#recovery_min_apply_delay= # If provided, "recovery_min_apply_delay" in recovery.conf + # will be set to this value (PostgreSQL 9.4 and later). + + +#------------------------------------------------------------------------------ +# "standby promote" settings +#------------------------------------------------------------------------------ + +# These settings apply when instructing a standby to promote itself to the +# new primary ("repmgr standby promote"). + +#promote_check_timeout=60 # The length of time (in seconds) to wait + # for the new primary to finish promoting +#promote_check_interval=1 # The interval (in seconds) to check whether + # the new primary has finished promoting + + +#------------------------------------------------------------------------------ +# "standby follow" settings +#------------------------------------------------------------------------------ + +# These settings apply when instructing a standby to follow the new primary +# ("repmgr standby follow"). + +#primary_follow_timeout=60 # The max length of time (in seconds) to wait + # for the new primary to become available +#standby_follow_timeout=15 # The max length of time (in seconds) to wait + # for the standby to connect to the primary + + +#------------------------------------------------------------------------------ +# "standby switchover" settings +#------------------------------------------------------------------------------ + +# These settings apply when switching roles between a primary and a standby +# ("repmgr standby switchover"). + +#shutdown_check_timeout=60 # The max length of time (in seconds) to wait for the demotion + # candidate (current primary) to shut down +#standby_reconnect_timeout=60 # The max length of time (in seconds) to wait + # for the demoted standby to reconnect to the promoted + # primary (note: this value should be equal to or greater + # than that set for "node_rejoin_timeout") + +#------------------------------------------------------------------------------ +# "node rejoin" settings +#------------------------------------------------------------------------------ + +# These settings apply when reintegrating a node into a replication cluster +# with "repmgrd_node_rejoin" + +#node_rejoin_timeout=60 # The maximum length of time (in seconds) to wait for + # the node to reconnect to the replication cluster + +#------------------------------------------------------------------------------ +# Barman options +#------------------------------------------------------------------------------ + +#barman_server='' # The barman configuration section +#barman_host='' # The host name of the barman server +#barman_config='' # The Barman configuration file on the + # Barman server (needed if the file is + # in a non-standard location) + +#------------------------------------------------------------------------------ +# Failover and monitoring settings (repmgrd) +#------------------------------------------------------------------------------ +# +# These settings are only applied when repmgrd is running. Values shown +# are defaults. + +#repmgrd_pid_file= # Path of PID file to use for repmgrd; if not set, a PID file will + # be generated in a temporary directory specified by the environment + # variable $TMPDIR, or if not set, in "/tmp". This value can be overridden + # by the command line option "-p/--pid-file"; the command line option + # "--no-pid-file" will force PID file creation to be skipped. +#failover=manual # one of 'automatic', 'manual'. + # determines what action to take in the event of upstream failure + # + # 'automatic': repmgrd will automatically attempt to promote the + # node or follow the new upstream node + # 'manual': repmgrd will take no action and the node will require + # manual attention to reattach it to replication + # (does not apply to BDR mode) + +#priority=100 # indicate a preferred priority for promoting nodes; + # a value of zero prevents the node being promoted to primary + # (default: 100) + +#reconnect_attempts=6 # Number of attempts which will be made to reconnect to an unreachable + # primary (or other upstream node) +#reconnect_interval=10 # Interval between attempts to reconnect to an unreachable + # primary (or other upstream node) +#promote_command= # command repmgrd executes when promoting a new primary; use something like: + # + # repmgr standby promote -f /etc/repmgr.conf + # +#follow_command= # command repmgrd executes when instructing a standby to follow a new primary; + # use something like: + # + # repmgr standby follow -f /etc/repmgr.conf -W --upstream-node-id=%n + # +#primary_notification_timeout=60 # Interval (in seconds) which repmgrd on a standby + # will wait for a notification from the new primary, + # before falling back to degraded monitoring +#repmgrd_standby_startup_timeout=60 # Interval (in seconds) which repmgrd on a standby will wait + # for the the local node to restart and become ready to accept connections after + # executing "follow_command" (defaults to the value set in "standby_reconnect_timeout") + +#monitoring_history=no # Whether to write monitoring data to the "montoring_history" table +#monitor_interval_secs=2 # Interval (in seconds) at which to write monitoring data +#degraded_monitoring_timeout=-1 # Interval (in seconds) after which repmgrd will terminate if the + # server being monitored is no longer available. -1 (default) + # disables the timeout completely. +#async_query_timeout=60 # Interval (in seconds) which repmgrd will wait before + # cancelling an asynchronous query. + +#------------------------------------------------------------------------------ +# service control commands +#------------------------------------------------------------------------------ +# +# repmgr provides options to override the default pg_ctl commands +# used to stop, start, restart, reload and promote the PostgreSQL cluster +# +# NOTE: These commands must be runnable on remote nodes as well for switchover +# to function correctly. +# +# If you use sudo, the user repmgr runs as (usually 'postgres') must have +# passwordless sudo access to execute the command. +# +# For example, to use systemd, you can set +# +# service_start_command = 'sudo systemctl start postgresql-9.6' +# (...) +# +# and then use the following sudoers configuration: +# +# # this is required when running sudo over ssh without -t: +# Defaults:postgres !requiretty +# postgres ALL = NOPASSWD: /usr/bin/systemctl stop postgresql-9.6, \ +# /usr/bin/systemctl start postgresql-9.6, \ +# /usr/bin/systemctl restart postgresql-9.6 +# +# Debian/Ubuntu users: use "sudo pg_ctlcluster" to execute service control commands. +# +# For more details, see: https://repmgr.org/docs/4.1/configuration-service-commands.html + +#service_start_command = '' +#service_stop_command = '' +#service_restart_command = '' +#service_reload_command = '' +#service_promote_command = '' # This parameter is intended for systems which provide a + # package-level promote command, such as Debian's + # "pg_ctlcluster". *IMPORTANT*: it is *not* a substitute + # for "promote_command"; do not use "repmgr standby promote" + # (or a script which executes "repmgr standby promote") here. + +#------------------------------------------------------------------------------ +# Status check thresholds +#------------------------------------------------------------------------------ + +# Various warning/critical thresholds used by "repmgr node check". + +#archive_ready_warning=16 # repmgr node check --archive-ready +#archive_ready_critical=128 # + # Numbers of files pending archiving via PostgreSQL's + # "archive_command" configuration parameter. If + # files can't be archived fast enough, or the archive + # command is failing, the buildup of files can + # cause various issues, such as server shutdown being + # delayed until all files are archived, or excessive + # space being occupied by unarchived files. + # + # Note that these values will be checked when executing + # "repmgr standby switchover" to warn about potential + # issues with shutting down the demotion candidate. + +#replication_lag_warning=300 # repmgr node check --replication-lag +#replication_lag_critical=600 # + # Note that these values will be checked when executing + # "repmgr standby switchover" to warn about potential + # issues with shutting down the demotion candidate. + + +#------------------------------------------------------------------------------ +# BDR monitoring options +#------------------------------------------------------------------------------ + +#bdr_local_monitoring_only=false # Only monitor the local node; no checks will be + # performed on the other node +#bdr_recovery_timeout # If a BDR node was offline and has become available + # maximum length of time in seconds to wait for the + # node to reconnect to the cluster diff --git a/templates/repmgr.conf-5.0.j2 b/templates/repmgr.conf-5.0.j2 new file mode 100644 index 000000000..883d77bea --- /dev/null +++ b/templates/repmgr.conf-5.0.j2 @@ -0,0 +1,448 @@ +################################################### +# repmgr sample configuration file +################################################### + +# Some configuration items will be set with a default value; this +# is noted for each item. Where no default value is shown, the +# parameter will be treated as empty or false. +# +# repmgr parses its configuration file in the same way as PostgreSQL itself +# does. In particular, strings must be enclosed in single quotes (although +# simple identifiers may be provided as-is). +# +# For details on the configuration file format see the documentation at: +# +# https://repmgr.org/docs/current/configuration-file.html#CONFIGURATION-FILE-FORMAT +# +# ============================================================================= +# Required configuration items +# ============================================================================= +# +# repmgr and repmgrd require the following items to be explicitly configured. + + +node_id='{{ repmgr_node_id if repmgr_node_id is defined else range(1, 2147483647) | random(seed=ansible_hostname) }}' # A unique integer greater than zero +node_name='{{ansible_hostname}}' # An arbitrary (but unique) string; we recommend + # using the server's hostname or another identifier + # unambiguously associated with the server to avoid + # confusion. Avoid choosing names which reflect the + # node's current role, e.g. 'primary' or 'standby1', + # as roles can change and it will be confusing if + # the current primary is called 'standby1'. + # The string's maximum length is 63 characters and it should + # contain only printable ASCII characters. + +conninfo='{{repmgr_conninfo}}' # Database connection information as a conninfo string. + # All servers in the cluster must be able to connect to + # the local node using this string. + # + # For details on conninfo strings, see: + # https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + # + # If repmgrd is in use, consider explicitly setting + # "connect_timeout" in the conninfo string to determine + # the length of time which elapses before a network + # connection attempt is abandoned; for details see: + # https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT + +data_directory='{{repmgr_data_directory}}' # The node's data directory. This is needed by repmgr + # when performing operations when the PostgreSQL instance + # is not running and there's no other way of determining + # the data directory. + + +# ============================================================================= +# Optional configuration items +# ============================================================================= + + +#------------------------------------------------------------------------------ +# Server settings +#------------------------------------------------------------------------------ + +config_directory='{{repmgr_config_directory}}' # If configuration files are located outside the data + # directory, specify the directory where the main + # postgresql.conf file is located. + +#------------------------------------------------------------------------------ +# Replication settings +#------------------------------------------------------------------------------ + +replication_user='{{repmgr_replication_user}}' # User to make replication connections with, if not set + # defaults to the user defined in "conninfo". + +replication_type='{{repmgr_replication_type}}' # Must be one of "physical" or "bdr". + # NOTE: "bdr" can only be used with BDR 2.x + +location='{{repmgr_location}}' # An arbitrary string defining the location of the node; this + # is used during failover to check visibility of the + # current primary node. For further details see: + # https://repmgr.org/docs/current/repmgrd-network-split.html + +use_replication_slots='{{repmgr_use_replication_slots}}' # whether to use physical replication slots + # NOTE: when using replication slots, + # 'max_replication_slots' should be configured for + # at least the number of standbys which will connect + # to the primary. + +#------------------------------------------------------------------------------ +# Witness server settings +#------------------------------------------------------------------------------ + +witness_sync_interval={{repmgr_witness_sync_interval}} # interval (in seconds) to synchronise node records + # to the witness server + +#------------------------------------------------------------------------------ +# Logging settings +#------------------------------------------------------------------------------ +# +# Note that logging facility settings will only apply to `repmgrd` by default; +# `repmgr` will always write to STDERR unless the switch `--log-to-file` is +# supplied, in which case it will log to the same destination as `repmgrd`. +# This is mainly intended for those cases when `repmgr` is executed directly +# by `repmgrd`. + +log_level='{{repmgr_log_level}}' # Log level: possible values are DEBUG, INFO, NOTICE, + # WARNING, ERROR, ALERT, CRIT or EMERG + +log_facility='{{repmgr_log_facility}}' # Logging facility: possible values are STDERR, or for + # syslog integration, one of LOCAL0, LOCAL1, ..., LOCAL7, USER + +{{ '' if repmgr_log_file else '#' }}log_file='{{repmgr_log_file}}' # STDERR can be redirected to an arbitrary file +log_status_interval={{repmgr_log_status_interval}} # interval (in seconds) for repmgrd to log a status message + + +#------------------------------------------------------------------------------ +# Event notification settings +#------------------------------------------------------------------------------ + +# event notifications can be passed to an arbitrary external program +# together with the following parameters: +# +# %n - node ID +# %e - event type +# %s - success (1 or 0) +# %t - timestamp +# %d - details +# +# the values provided for "%t" and "%d" will probably contain spaces, +# so should be quoted in the provided command configuration, e.g.: +# +# event_notification_command='/path/to/some/script %n %e %s "%t" "%d"' +# +# By default, all notifications will be passed; the notification types +# can be filtered to explicitly named ones, e.g.: +# +# event_notifications=primary_register,standby_register + +{{ '' if repmgr_event_notification_command else '#' }}event_notification_command='{{repmgr_event_notification_command}}' # An external program or script which + # can be executed by the user under which + # repmgr/repmgrd are run. + +{{ '' if repmgr_event_notifications else '#' }}event_notifications='{{repmgr_event_notifications}}' # A commas-separated list of notification + # types + +#------------------------------------------------------------------------------ +# Environment/command settings +#------------------------------------------------------------------------------ + +pg_bindir='{{repmgr_pg_bindir}}' # Path to PostgreSQL binary directory (location + # of pg_ctl, pg_basebackup etc.). Only needed + # if these files are not in the system $PATH. + # + # Debian/Ubuntu users: you will probably need to + # set this to the directory where `pg_ctl` is located, + # e.g. /usr/lib/postgresql/9.6/bin/ + # + # *NOTE* "pg_bindir" is only used when repmgr directly + # executes PostgreSQL binaries; any user-defined scripts + # *must* be specified with the full path + +repmgr_bindir='{{repmgr_repmgr_bindir}}' # Path to repmgr binary directory (location of the repmgr + # binary. Only needed if the repmgr executable is not in + # the system $PATH or the path defined in "pg_bindir". + +use_primary_conninfo_password={{repmgr_use_primary_conninfo_password}} # explicitly set "password" in "primary_conninfo" + # using the value contained in the environment variable + # PGPASSWORD +passfile='{{repmgr_passfile}}' # path to .pgpass file to include in "primary_conninfo" + +#------------------------------------------------------------------------------ +# external command options +#------------------------------------------------------------------------------ +# +# Options which can be passed to external commands invoked by repmgr/repmgrd. +# +# Examples: +# +# pg_ctl_options='-s' +# pg_basebackup_options='--label=repmgr_backup' +# rsync_options=--archive --checksum --compress --progress --rsh="ssh -o \"StrictHostKeyChecking no\"" +# ssh_options=-o "StrictHostKeyChecking no" + +{{ '' if repmgr_pg_ctl_options else '#' }}pg_ctl_options='{{repmgr_pg_ctl_options}}' # Options to append to "pg_ctl" +{{ '' if repmgr_pg_basebackup_options else '#' }}pg_basebackup_options='{{repmgr_pg_basebackup_options}}' # Options to append to "pg_basebackup" +{{ '' if repmgr_rsync_options else '#' }}rsync_options='{{repmgr_rsync_options}}' # Options to append to "rsync" +ssh_options='{{repmgr_ssh_options}}' # Options to append to "ssh" + + + +#------------------------------------------------------------------------------ +# "standby clone" settings +#------------------------------------------------------------------------------ +# +# These settings apply when cloning a standby ("repmgr standby clone"). +# +# Examples: +# +# tablespace_mapping='/path/to/original/tablespace=/path/to/new/tablespace' +# restore_command = 'cp /path/to/archived/wals/%f %p' + +{{ '' if repmgr_tablespace_mapping else '#' }}tablespace_mapping='{{repmgr_tablespace_mapping}}' # Tablespaces can be remapped from one + # file system location to another. This + # parameter can be provided multiple times. + +{{ '' if repmgr_restore_command else '#' }}restore_command='{{repmgr_restore_command}}' # This will be included in the recovery configuration + # generated by repmgr. + +{{ '' if repmgr_archive_cleanup_command else '#' }}archive_cleanup_command='{{repmgr_archive_cleanup_command}}' # This will be included in the recovery configuration + # generated by repmgr. Note we recommend using Barman for + # managing WAL archives (see: https://www.pgbarman.org ) + +{{ '' if repmgr_recovery_min_apply_delay else '#' }}recovery_min_apply_delay={{repmgr_recovery_min_apply_delay}} # If provided, "recovery_min_apply_delay" will be set to + # this value (PostgreSQL 9.4 and later). + + +#------------------------------------------------------------------------------ +# "standby promote" settings +#------------------------------------------------------------------------------ + +# These settings apply when instructing a standby to promote itself to the +# new primary ("repmgr standby promote"). + +promote_check_timeout={{repmgr_promote_check_timeout}} # The length of time (in seconds) to wait + # for the new primary to finish promoting +promote_check_interval={{repmgr_promote_check_interval}} # The interval (in seconds) to check whether + # the new primary has finished promoting + + +#------------------------------------------------------------------------------ +# "standby follow" settings +#------------------------------------------------------------------------------ + +# These settings apply when instructing a standby to follow the new primary +# ("repmgr standby follow"). + +primary_follow_timeout={{repmgr_primary_follow_timeout}} # The max length of time (in seconds) to wait + # for the new primary to become available +standby_follow_timeout={{repmgr_standby_follow_timeout}} # The max length of time (in seconds) to wait + # for the standby to connect to the primary + + +#------------------------------------------------------------------------------ +# "standby switchover" settings +#------------------------------------------------------------------------------ + +# These settings apply when switching roles between a primary and a standby +# ("repmgr standby switchover"). + +shutdown_check_timeout={{repmgr_shutdown_check_timeout}} # The max length of time (in seconds) to wait for the demotion + # candidate (current primary) to shut down +standby_reconnect_timeout={{repmgr_standby_reconnect_timeout}} # The max length of time (in seconds) to wait + # for the demoted standby to reconnect to the promoted + # primary (note: this value should be equal to or greater + # than that set for "node_rejoin_timeout") +#wal_receive_check_timeout=30 # The max length of time (in seconds) to wait for the walreceiver + # on the standby to flush WAL to disk before comparing location + # with the shut-down primary + +#------------------------------------------------------------------------------ +# "node rejoin" settings +#------------------------------------------------------------------------------ + +# These settings apply when reintegrating a node into a replication cluster +# with "repmgrd_node_rejoin" + +node_rejoin_timeout={{repmgr_node_rejoin_timeout}} # The maximum length of time (in seconds) to wait for + # the node to reconnect to the replication cluster + +#------------------------------------------------------------------------------ +# Barman options +#------------------------------------------------------------------------------ + +{{ '' if repmgr_barman_server else '#' }}barman_server='{{repmgr_barman_server}}' # The barman configuration section +{{ '' if repmgr_barman_host else '#' }}barman_host='{{repmgr_barman_host}}' # The host name of the barman server +{{ '' if repmgr_barman_config else '#' }}barman_config='{{repmgr_barman_config}}' # The Barman configuration file on the + # Barman server (needed if the file is + # in a non-standard location) + +#------------------------------------------------------------------------------ +# Failover and monitoring settings (repmgrd) +#------------------------------------------------------------------------------ +# +# These settings are only applied when repmgrd is running. Values shown +# are defaults. + +failover='{{repmgr_failover}}' # one of 'automatic', 'manual'. + # determines what action to take in the event of upstream failure + # + # 'automatic': repmgrd will automatically attempt to promote the + # node or follow the new upstream node + # 'manual': repmgrd will take no action and the node will require + # manual attention to reattach it to replication + # (does not apply to BDR mode) + +priority={{repmgr_priority}} # indicates a preferred priority for promoting nodes; + # a value of zero prevents the node being promoted to primary + # (default: 100) + +#connection_check_type=ping # How to check availability of the upstream node; valid options: + # 'ping': use PQping() to check if the node is accepting connections + # 'connection': execute a throwaway query on the current connection +reconnect_attempts={{repmgr_reconnect_attempts}} # Number of attempts which will be made to reconnect to an unreachable + # primary (or other upstream node) +reconnect_interval={{repmgr_reconnect_interval}} # Interval between attempts to reconnect to an unreachable + # primary (or other upstream node) +{{ '' if repmgr_promote_command else '#' }}promote_command='{{repmgr_promote_command}}' # command repmgrd executes when promoting a new primary; use something like: + # + # repmgr standby promote -f /etc/repmgr.conf + # +{{ '' if repmgr_follow_command else '#' }}follow_command='{{repmgr_follow_command}}' # command repmgrd executes when instructing a standby to follow a new primary; + # use something like: + # + # repmgr standby follow -f /etc/repmgr.conf -W --upstream-node-id=%n + # +primary_notification_timeout={{repmgr_primary_notification_timeout}} # Interval (in seconds) which repmgrd on a standby + # will wait for a notification from the new primary, + # before falling back to degraded monitoring +repmgrd_standby_startup_timeout={{repmgr_repmgrd_standby_startup_timeout}} # Interval (in seconds) which repmgrd on a standby will wait + # for the the local node to restart and become ready to accept connections after + # executing "follow_command" (defaults to the value set in "standby_reconnect_timeout") + +monitoring_history={{repmgr_monitoring_history}} # Whether to write monitoring data to the "montoring_history" table +monitor_interval_secs={{repmgr_monitor_interval_secs}} # Interval (in seconds) at which to write monitoring data +degraded_monitoring_timeout={{repmgr_degraded_monitoring_timeout}} # Interval (in seconds) after which repmgrd will terminate if the + # server(s) being monitored are no longer available. -1 (default) + # disables the timeout completely. +async_query_timeout={{repmgr_async_query_timeout}} # Interval (in seconds) which repmgrd will wait before + # cancelling an asynchronous query. +{{ '' if repmgr_repmgrd_pid_file else '#' }}repmgrd_pid_file={{repmgr_repmgrd_pid_file}} # Path of PID file to use for repmgrd; if not set, a PID file will + # be generated in a temporary directory specified by the environment + # variable $TMPDIR, or if not set, in "/tmp". This value can be overridden + # by the command line option "-p/--pid-file"; the command line option + # "--no-pid-file" will force PID file creation to be skipped. + # Note: there is normally no need to set this, particularly if + # repmgr was installed from packages. +standby_disconnect_on_failover={{repmgr_standby_disconnect_on_failover}} # If "true", in a failover situation wait for all standbys to + # disconnect their WAL receivers before electing a new primary + # (PostgreSQL 9.5 and later only; repmgr user must be a superuser for this) +#sibling_nodes_disconnect_timeout=30 # If "standby_disconnect_on_failover" is true, the maximum length of time + # (in seconds) to wait for other standbys to confirm they have disconnected their + # WAL receivers +primary_visibility_consensus={{repmgr_primary_visibility_consensus}} # If "true", only continue with failover if no standbys have seen + # the primary node recently. *Must* be the same on all nodes. +#failover_validation_command='' # Script to execute for an external mechanism to validate the failover + # decision made by repmgrd. One or both of the following parameter placeholders + # should be provided, which will be replaced by repmgrd with the appropriate + # value: %n (node_id), %a (node_name). *Must* be the same on all nodes. +#election_rerun_interval=15 # if "failover_validation_command" is set, and the command returns + # an error, pause the specified amount of seconds before rerunning the election. + # + # The following items are relevant for repmgrd running on the primary, + # and will be ignored on non-primary nodes +#child_nodes_check_interval=5 # Interval (in seconds) to check for attached child nodes (standbys) +#child_nodes_connected_min_count=-1 # Minimum number of child nodes which must remain connected, otherwise + # disconnection command will be triggered +#child_nodes_disconnect_min_count=-1 # Minimum number of disconnected child nodes required to execute disconnection command + # (ignored if "child_nodes_connected_min_count" set) +#child_nodes_disconnect_timeout=30 # Interval between child node disconnection and disconnection command execution +#child_nodes_disconnect_command='' # Command to execute if child node disconnection detected + +#------------------------------------------------------------------------------ +# service control commands +#------------------------------------------------------------------------------ +# +# repmgr provides options to override the default pg_ctl commands +# used to stop, start, restart, reload and promote the PostgreSQL cluster +# +# These options are useful when PostgreSQL has been installed from a package +# which provides OS-level service commands. In environments using an init system +# such as systemd, which keeps track of the state of various services, it is +# essential that the service commands are correctly configured and pg_ctl is +# not executed directly. +# +# NOTE: These commands must be runnable on remote nodes as well for switchover +# to function correctly. +# +# If you use sudo, the user repmgr runs as (usually 'postgres') must have +# passwordless sudo access to execute the command. +# +# For example, to use systemd, you can set +# +# service_start_command = 'sudo systemctl start postgresql-9.6' +# (...) +# +# and then use the following sudoers configuration: +# +# # this is required when running sudo over ssh without -t: +# Defaults:postgres !requiretty +# postgres ALL = NOPASSWD: /usr/bin/systemctl stop postgresql-9.6, \ +# /usr/bin/systemctl start postgresql-9.6, \ +# /usr/bin/systemctl restart postgresql-9.6 +# +# Debian/Ubuntu users: use "sudo pg_ctlcluster" to execute service control commands. +# +# For more details, see: https://repmgr.org/docs/current/configuration-service-commands.html + +service_start_command ='{{repmgr_service_start_command }}' +service_stop_command ='{{repmgr_service_stop_command }}' +service_restart_command ='{{repmgr_service_restart_command }}' +service_reload_command ='{{repmgr_service_reload_command }}' +{{ '' if repmgr_service_promote_command else '#' }}service_promote_command ='{{repmgr_service_promote_command }}' # This parameter is intended for systems which provide a + # package-level promote command, such as Debian's + # "pg_ctlcluster". *IMPORTANT*: it is *not* a substitute + # for "promote_command"; do not use "repmgr standby promote" + # (or a script which executes "repmgr standby promote") here. + +# Used by "repmgr service (start|stop)" to control repmgrd +# +#repmgrd_service_start_command = '' +#repmgrd_service_stop_command = '' + +#------------------------------------------------------------------------------ +# Status check thresholds +#------------------------------------------------------------------------------ + +# Various warning/critical thresholds used by "repmgr node check". + +archive_ready_warning={{repmgr_archive_ready_warning}} # repmgr node check --archive-ready +archive_ready_critical={{repmgr_archive_ready_critical}} # + # Numbers of files pending archiving via PostgreSQL's + # "archive_command" configuration parameter. If + # files can't be archived fast enough, or the archive + # command is failing, the buildup of files can + # cause various issues, such as server shutdown being + # delayed until all files are archived, or excessive + # space being occupied by unarchived files. + # + # Note that these values will be checked when executing + # "repmgr standby switchover" to warn about potential + # issues with shutting down the demotion candidate. + +replication_lag_warning={{repmgr_replication_lag_warning}} # repmgr node check --replication-lag +replication_lag_critical={{repmgr_replication_lag_critical}} # + # Note that these values will be checked when executing + # "repmgr standby switchover" to warn about potential + # issues with shutting down the demotion candidate. + + +#------------------------------------------------------------------------------ +# BDR monitoring options +#------------------------------------------------------------------------------ + +bdr_local_monitoring_only={{repmgr_bdr_local_monitoring_only}} # Only monitor the local node; no checks will be + # performed on the other node +bdr_recovery_timeout={{repmgr_bdr_recovery_timeout}} # If a BDR node was offline and has become available + # maximum length of time in seconds to wait for the + # node to reconnect to the cluster + diff --git a/templates/repmgr.conf-5.0.orig b/templates/repmgr.conf-5.0.orig new file mode 100644 index 000000000..bbba1cd55 --- /dev/null +++ b/templates/repmgr.conf-5.0.orig @@ -0,0 +1,448 @@ +################################################### +# repmgr sample configuration file +################################################### + +# Some configuration items will be set with a default value; this +# is noted for each item. Where no default value is shown, the +# parameter will be treated as empty or false. +# +# repmgr parses its configuration file in the same way as PostgreSQL itself +# does. In particular, strings must be enclosed in single quotes (although +# simple identifiers may be provided as-is). +# +# For details on the configuration file format see the documentation at: +# +# https://repmgr.org/docs/current/configuration-file.html#CONFIGURATION-FILE-FORMAT +# +# ============================================================================= +# Required configuration items +# ============================================================================= +# +# repmgr and repmgrd require the following items to be explicitly configured. + + +#node_id= # A unique integer greater than zero +#node_name='' # An arbitrary (but unique) string; we recommend + # using the server's hostname or another identifier + # unambiguously associated with the server to avoid + # confusion. Avoid choosing names which reflect the + # node's current role, e.g. 'primary' or 'standby1', + # as roles can change and it will be confusing if + # the current primary is called 'standby1'. + # The string's maximum length is 63 characters and it should + # contain only printable ASCII characters. + +#conninfo='' # Database connection information as a conninfo string. + # All servers in the cluster must be able to connect to + # the local node using this string. + # + # For details on conninfo strings, see: + # https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING + # + # If repmgrd is in use, consider explicitly setting + # "connect_timeout" in the conninfo string to determine + # the length of time which elapses before a network + # connection attempt is abandoned; for details see: + # https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT + +#data_directory='' # The node's data directory. This is needed by repmgr + # when performing operations when the PostgreSQL instance + # is not running and there's no other way of determining + # the data directory. + + +# ============================================================================= +# Optional configuration items +# ============================================================================= + + +#------------------------------------------------------------------------------ +# Server settings +#------------------------------------------------------------------------------ + +#config_directory='' # If configuration files are located outside the data + # directory, specify the directory where the main + # postgresql.conf file is located. + +#------------------------------------------------------------------------------ +# Replication settings +#------------------------------------------------------------------------------ + +#replication_user='repmgr' # User to make replication connections with, if not set + # defaults to the user defined in "conninfo". + +#replication_type='physical' # Must be one of "physical" or "bdr". + # NOTE: "bdr" can only be used with BDR 2.x + +#location='default' # An arbitrary string defining the location of the node; this + # is used during failover to check visibility of the + # current primary node. For further details see: + # https://repmgr.org/docs/current/repmgrd-network-split.html + +#use_replication_slots=no # whether to use physical replication slots + # NOTE: when using replication slots, + # 'max_replication_slots' should be configured for + # at least the number of standbys which will connect + # to the primary. + +#------------------------------------------------------------------------------ +# Witness server settings +#------------------------------------------------------------------------------ + +#witness_sync_interval=15 # interval (in seconds) to synchronise node records + # to the witness server + +#------------------------------------------------------------------------------ +# Logging settings +#------------------------------------------------------------------------------ +# +# Note that logging facility settings will only apply to `repmgrd` by default; +# `repmgr` will always write to STDERR unless the switch `--log-to-file` is +# supplied, in which case it will log to the same destination as `repmgrd`. +# This is mainly intended for those cases when `repmgr` is executed directly +# by `repmgrd`. + +#log_level='INFO' # Log level: possible values are DEBUG, INFO, NOTICE, + # WARNING, ERROR, ALERT, CRIT or EMERG + +#log_facility='STDERR' # Logging facility: possible values are STDERR, or for + # syslog integration, one of LOCAL0, LOCAL1, ..., LOCAL7, USER + +#log_file='' # STDERR can be redirected to an arbitrary file +#log_status_interval=300 # interval (in seconds) for repmgrd to log a status message + + +#------------------------------------------------------------------------------ +# Event notification settings +#------------------------------------------------------------------------------ + +# event notifications can be passed to an arbitrary external program +# together with the following parameters: +# +# %n - node ID +# %e - event type +# %s - success (1 or 0) +# %t - timestamp +# %d - details +# +# the values provided for "%t" and "%d" will probably contain spaces, +# so should be quoted in the provided command configuration, e.g.: +# +# event_notification_command='/path/to/some/script %n %e %s "%t" "%d"' +# +# By default, all notifications will be passed; the notification types +# can be filtered to explicitly named ones, e.g.: +# +# event_notifications=primary_register,standby_register + +#event_notification_command='' # An external program or script which + # can be executed by the user under which + # repmgr/repmgrd are run. + +#event_notifications='' # A commas-separated list of notification + # types + +#------------------------------------------------------------------------------ +# Environment/command settings +#------------------------------------------------------------------------------ + +#pg_bindir='' # Path to PostgreSQL binary directory (location + # of pg_ctl, pg_basebackup etc.). Only needed + # if these files are not in the system $PATH. + # + # Debian/Ubuntu users: you will probably need to + # set this to the directory where `pg_ctl` is located, + # e.g. /usr/lib/postgresql/9.6/bin/ + # + # *NOTE* "pg_bindir" is only used when repmgr directly + # executes PostgreSQL binaries; any user-defined scripts + # *must* be specified with the full path + +#repmgr_bindir='' # Path to repmgr binary directory (location of the repmgr + # binary. Only needed if the repmgr executable is not in + # the system $PATH or the path defined in "pg_bindir". + +#use_primary_conninfo_password=false # explicitly set "password" in "primary_conninfo" + # using the value contained in the environment variable + # PGPASSWORD +#passfile='' # path to .pgpass file to include in "primary_conninfo" + +#------------------------------------------------------------------------------ +# external command options +#------------------------------------------------------------------------------ +# +# Options which can be passed to external commands invoked by repmgr/repmgrd. +# +# Examples: +# +# pg_ctl_options='-s' +# pg_basebackup_options='--label=repmgr_backup' +# rsync_options=--archive --checksum --compress --progress --rsh="ssh -o \"StrictHostKeyChecking no\"" +# ssh_options=-o "StrictHostKeyChecking no" + +#pg_ctl_options='' # Options to append to "pg_ctl" +#pg_basebackup_options='' # Options to append to "pg_basebackup" +#rsync_options='' # Options to append to "rsync" +ssh_options='-q -o ConnectTimeout=10' # Options to append to "ssh" + + + +#------------------------------------------------------------------------------ +# "standby clone" settings +#------------------------------------------------------------------------------ +# +# These settings apply when cloning a standby ("repmgr standby clone"). +# +# Examples: +# +# tablespace_mapping='/path/to/original/tablespace=/path/to/new/tablespace' +# restore_command = 'cp /path/to/archived/wals/%f %p' + +#tablespace_mapping='' # Tablespaces can be remapped from one + # file system location to another. This + # parameter can be provided multiple times. + +#restore_command='' # This will be included in the recovery configuration + # generated by repmgr. + +#archive_cleanup_command='' # This will be included in the recovery configuration + # generated by repmgr. Note we recommend using Barman for + # managing WAL archives (see: https://www.pgbarman.org ) + +#recovery_min_apply_delay= # If provided, "recovery_min_apply_delay" will be set to + # this value (PostgreSQL 9.4 and later). + + +#------------------------------------------------------------------------------ +# "standby promote" settings +#------------------------------------------------------------------------------ + +# These settings apply when instructing a standby to promote itself to the +# new primary ("repmgr standby promote"). + +#promote_check_timeout=60 # The length of time (in seconds) to wait + # for the new primary to finish promoting +#promote_check_interval=1 # The interval (in seconds) to check whether + # the new primary has finished promoting + + +#------------------------------------------------------------------------------ +# "standby follow" settings +#------------------------------------------------------------------------------ + +# These settings apply when instructing a standby to follow the new primary +# ("repmgr standby follow"). + +#primary_follow_timeout=60 # The max length of time (in seconds) to wait + # for the new primary to become available +#standby_follow_timeout=15 # The max length of time (in seconds) to wait + # for the standby to connect to the primary + + +#------------------------------------------------------------------------------ +# "standby switchover" settings +#------------------------------------------------------------------------------ + +# These settings apply when switching roles between a primary and a standby +# ("repmgr standby switchover"). + +#shutdown_check_timeout=60 # The max length of time (in seconds) to wait for the demotion + # candidate (current primary) to shut down +#standby_reconnect_timeout=60 # The max length of time (in seconds) to wait + # for the demoted standby to reconnect to the promoted + # primary (note: this value should be equal to or greater + # than that set for "node_rejoin_timeout") +#wal_receive_check_timeout=30 # The max length of time (in seconds) to wait for the walreceiver + # on the standby to flush WAL to disk before comparing location + # with the shut-down primary + +#------------------------------------------------------------------------------ +# "node rejoin" settings +#------------------------------------------------------------------------------ + +# These settings apply when reintegrating a node into a replication cluster +# with "repmgrd_node_rejoin" + +#node_rejoin_timeout=60 # The maximum length of time (in seconds) to wait for + # the node to reconnect to the replication cluster + +#------------------------------------------------------------------------------ +# Barman options +#------------------------------------------------------------------------------ + +#barman_server='' # The barman configuration section +#barman_host='' # The host name of the barman server +#barman_config='' # The Barman configuration file on the + # Barman server (needed if the file is + # in a non-standard location) + +#------------------------------------------------------------------------------ +# Failover and monitoring settings (repmgrd) +#------------------------------------------------------------------------------ +# +# These settings are only applied when repmgrd is running. Values shown +# are defaults. + +#failover='manual' # one of 'automatic', 'manual'. + # determines what action to take in the event of upstream failure + # + # 'automatic': repmgrd will automatically attempt to promote the + # node or follow the new upstream node + # 'manual': repmgrd will take no action and the node will require + # manual attention to reattach it to replication + # (does not apply to BDR mode) + +#priority=100 # indicates a preferred priority for promoting nodes; + # a value of zero prevents the node being promoted to primary + # (default: 100) + +#connection_check_type=ping # How to check availability of the upstream node; valid options: + # 'ping': use PQping() to check if the node is accepting connections + # 'connection': execute a throwaway query on the current connection +#reconnect_attempts=6 # Number of attempts which will be made to reconnect to an unreachable + # primary (or other upstream node) +#reconnect_interval=10 # Interval between attempts to reconnect to an unreachable + # primary (or other upstream node) +#promote_command= # command repmgrd executes when promoting a new primary; use something like: + # + # repmgr standby promote -f /etc/repmgr.conf + # +#follow_command= # command repmgrd executes when instructing a standby to follow a new primary; + # use something like: + # + # repmgr standby follow -f /etc/repmgr.conf -W --upstream-node-id=%n + # +#primary_notification_timeout=60 # Interval (in seconds) which repmgrd on a standby + # will wait for a notification from the new primary, + # before falling back to degraded monitoring +#repmgrd_standby_startup_timeout=60 # Interval (in seconds) which repmgrd on a standby will wait + # for the the local node to restart and become ready to accept connections after + # executing "follow_command" (defaults to the value set in "standby_reconnect_timeout") + +#monitoring_history=no # Whether to write monitoring data to the "montoring_history" table +#monitor_interval_secs=2 # Interval (in seconds) at which to write monitoring data +#degraded_monitoring_timeout=-1 # Interval (in seconds) after which repmgrd will terminate if the + # server(s) being monitored are no longer available. -1 (default) + # disables the timeout completely. +#async_query_timeout=60 # Interval (in seconds) which repmgrd will wait before + # cancelling an asynchronous query. +#repmgrd_pid_file= # Path of PID file to use for repmgrd; if not set, a PID file will + # be generated in a temporary directory specified by the environment + # variable $TMPDIR, or if not set, in "/tmp". This value can be overridden + # by the command line option "-p/--pid-file"; the command line option + # "--no-pid-file" will force PID file creation to be skipped. + # Note: there is normally no need to set this, particularly if + # repmgr was installed from packages. +#standby_disconnect_on_failover=false # If "true", in a failover situation wait for all standbys to + # disconnect their WAL receivers before electing a new primary + # (PostgreSQL 9.5 and later only; repmgr user must be a superuser for this) +#sibling_nodes_disconnect_timeout=30 # If "standby_disconnect_on_failover" is true, the maximum length of time + # (in seconds) to wait for other standbys to confirm they have disconnected their + # WAL receivers +#primary_visibility_consensus=false # If "true", only continue with failover if no standbys have seen + # the primary node recently. *Must* be the same on all nodes. +#failover_validation_command='' # Script to execute for an external mechanism to validate the failover + # decision made by repmgrd. One or both of the following parameter placeholders + # should be provided, which will be replaced by repmgrd with the appropriate + # value: %n (node_id), %a (node_name). *Must* be the same on all nodes. +#election_rerun_interval=15 # if "failover_validation_command" is set, and the command returns + # an error, pause the specified amount of seconds before rerunning the election. + # + # The following items are relevant for repmgrd running on the primary, + # and will be ignored on non-primary nodes +#child_nodes_check_interval=5 # Interval (in seconds) to check for attached child nodes (standbys) +#child_nodes_connected_min_count=-1 # Minimum number of child nodes which must remain connected, otherwise + # disconnection command will be triggered +#child_nodes_disconnect_min_count=-1 # Minimum number of disconnected child nodes required to execute disconnection command + # (ignored if "child_nodes_connected_min_count" set) +#child_nodes_disconnect_timeout=30 # Interval between child node disconnection and disconnection command execution +#child_nodes_disconnect_command='' # Command to execute if child node disconnection detected + +#------------------------------------------------------------------------------ +# service control commands +#------------------------------------------------------------------------------ +# +# repmgr provides options to override the default pg_ctl commands +# used to stop, start, restart, reload and promote the PostgreSQL cluster +# +# These options are useful when PostgreSQL has been installed from a package +# which provides OS-level service commands. In environments using an init system +# such as systemd, which keeps track of the state of various services, it is +# essential that the service commands are correctly configured and pg_ctl is +# not executed directly. +# +# NOTE: These commands must be runnable on remote nodes as well for switchover +# to function correctly. +# +# If you use sudo, the user repmgr runs as (usually 'postgres') must have +# passwordless sudo access to execute the command. +# +# For example, to use systemd, you can set +# +# service_start_command = 'sudo systemctl start postgresql-9.6' +# (...) +# +# and then use the following sudoers configuration: +# +# # this is required when running sudo over ssh without -t: +# Defaults:postgres !requiretty +# postgres ALL = NOPASSWD: /usr/bin/systemctl stop postgresql-9.6, \ +# /usr/bin/systemctl start postgresql-9.6, \ +# /usr/bin/systemctl restart postgresql-9.6 +# +# Debian/Ubuntu users: use "sudo pg_ctlcluster" to execute service control commands. +# +# For more details, see: https://repmgr.org/docs/current/configuration-service-commands.html + +#service_start_command = '' +#service_stop_command = '' +#service_restart_command = '' +#service_reload_command = '' +#service_promote_command = '' # This parameter is intended for systems which provide a + # package-level promote command, such as Debian's + # "pg_ctlcluster". *IMPORTANT*: it is *not* a substitute + # for "promote_command"; do not use "repmgr standby promote" + # (or a script which executes "repmgr standby promote") here. + +# Used by "repmgr service (start|stop)" to control repmgrd +# +#repmgrd_service_start_command = '' +#repmgrd_service_stop_command = '' + +#------------------------------------------------------------------------------ +# Status check thresholds +#------------------------------------------------------------------------------ + +# Various warning/critical thresholds used by "repmgr node check". + +#archive_ready_warning=16 # repmgr node check --archive-ready +#archive_ready_critical=128 # + # Numbers of files pending archiving via PostgreSQL's + # "archive_command" configuration parameter. If + # files can't be archived fast enough, or the archive + # command is failing, the buildup of files can + # cause various issues, such as server shutdown being + # delayed until all files are archived, or excessive + # space being occupied by unarchived files. + # + # Note that these values will be checked when executing + # "repmgr standby switchover" to warn about potential + # issues with shutting down the demotion candidate. + +#replication_lag_warning=300 # repmgr node check --replication-lag +#replication_lag_critical=600 # + # Note that these values will be checked when executing + # "repmgr standby switchover" to warn about potential + # issues with shutting down the demotion candidate. + + +#------------------------------------------------------------------------------ +# BDR monitoring options +#------------------------------------------------------------------------------ + +#bdr_local_monitoring_only=false # Only monitor the local node; no checks will be + # performed on the other node +#bdr_recovery_timeout # If a BDR node was offline and has become available + # maximum length of time in seconds to wait for the + # node to reconnect to the cluster + \ No newline at end of file diff --git a/templates/repmgr.custom.conf.j2 b/templates/repmgr.custom.conf.j2 new file mode 100644 index 000000000..6671cd012 --- /dev/null +++ b/templates/repmgr.custom.conf.j2 @@ -0,0 +1,3 @@ +[Service] +# Location of repmgr conf file: +Environment=REPMGRDCONF={{postgresql_conf_directory}}/repmgr.conf diff --git a/templates/sudoers.postgresql.j2 b/templates/sudoers.postgresql.j2 new file mode 100644 index 000000000..9273387ef --- /dev/null +++ b/templates/sudoers.postgresql.j2 @@ -0,0 +1,6 @@ +# this is required when running sudo over ssh without -t: +Defaults:postgres !requiretty +postgres ALL = NOPASSWD: /usr/bin/systemctl stop postgresql-{{postgresql_version}}, \ + /usr/bin/systemctl start postgresql-{{postgresql_version}}, \ + /usr/bin/systemctl restart postgresql-{{postgresql_version}}, \ + /usr/bin/systemctl reload postgresql-{{postgresql_version}} diff --git a/tests/docker/group_vars/postgresql.yml b/tests/docker/group_vars/postgresql.yml index 2949e5cb2..6dd3c6084 100644 --- a/tests/docker/group_vars/postgresql.yml +++ b/tests/docker/group_vars/postgresql.yml @@ -7,6 +7,10 @@ postgresql_databases: - name: foobar owner: baz + - name: repmgr + owner: "repmgr" + encoding: "UTF-8" + # NOTE: postgresql >= 10 does not accept unencrypted passwords postgresql_users: - name: baz @@ -19,6 +23,10 @@ postgresql_users: - name: zabaz + - name: "repmgr" + pass: "repmgr" + encrypted: true # required with postgres >= 10 and ansible <= 2.6 + postgresql_database_schemas: - database: foobar state: present @@ -29,6 +37,11 @@ postgresql_user_privileges: - name: baz db: foobar + - name: "repmgr" + db: repmgr + priv: "ALL" + role_attr_flags: "SUPERUSER,REPLICATION" + postgresql_ext_install_contrib: true # These do not work everywhere, but should be included ASAP diff --git a/tests/docker/replication.yml b/tests/docker/replication.yml new file mode 100644 index 000000000..c54b3ba52 --- /dev/null +++ b/tests/docker/replication.yml @@ -0,0 +1,112 @@ +# replication.yml +--- +# vim: set syntax=yaml expandtab shiftwidth=2 tabstop=2 softtabstop=2 autoindent: + +- hosts: localhost + become: false + gather_facts: false + tasks: + - name: Build or pull image if needed + docker_image: + name: "{{ image_name.split(':')[0] }}" + tag: "{{ image_name.split(':')[1] }}" + dockerfile: "Dockerfile.{{ image_name | replace(':', '.') }}" + path: "{{ 'images' if 'builded' in image_name else '' }}" + force: "{{ force_build_image | default(false) }}" + + - name: Create docker network + docker_network: + name: replication + + - name: Run docker machines for testing PostgreSQL role + docker_container: + name: "postgresql-10-1" + hostname: "postgresql-10-1" + image: "{{ image_name }}" + command: "/sbin/init" + state: started + privileged: true + networks: + - name: replication + + - name: Run docker machines for testing PostgreSQL role 2 + docker_container: + name: "postgresql-10-2" + hostname: "postgresql-10-2" + image: "{{ image_name }}" + command: "/sbin/init" + state: started + privileged: true + networks: + - name: replication + + - name: Add new machines into postgresql inventory group + add_host: + name: "postgresql-10-{{ item }}" + ansible_connection: docker + ansible_user: root + ansible_python_interpreter: python + groups: postgresql + postgresql_version: 10 + changed_when: false + with_items: + - 1 + - 2 + +- hosts: postgresql + become: false + gather_facts: true + vars_files: + # are these paths relative to the playbook path? + - ../../defaults/repmgr.yml + tasks: + - name: install ssh + package: + name: openssh + state: present + - name: install ssh-client + package: + name: openssh-clients + state: present + - name: install ssh-server + package: + name: openssh-server + state: present + - name: install cron + package: + name: cronie + state: present + - name: ensure sshd is running + systemd: + name: sshd + state: started + - name: ensure cron is running + systemd: + name: crond + state: started + + - import_role: + name: ANXS.postgresql + vars: + # see tests/docker/group_vars/postgresql.yml for more configuration + repmgr_target_group: "postgresql" + postgresql_version: 10 + postgresql_ext_install_repmgr: yes + postgresql_listen_addresses: + - "*" + #- "localhost" + #- "{{ ansible_default_ipv4.address }}" + postgresql_pg_hba_custom: + - type: host + database: repmgr + user: "repmgr" + address: "0.0.0.0/0" + #address: "{{ ansible_default_ipv4['network'] }}/{{ [ansible_default_ipv4['network'], ansible_default_ipv4['netmask']] | join('/') | ipaddr('prefix') }}" + method: "md5" + comment: "" + - type: host + database: replication + user: "repmgr" + address: "0.0.0.0/0" + method: "md5" + comment: ""