patroni.postgresql.config module
- class patroni.postgresql.config.ConfigHandler(postgresql: Postgresql, config: Dict[str, Any])
Bases:
object- CMDLINE_OPTIONS = <CaseInsensitiveDict{'listen_addresses': (None, <function _false_validator>, 90100), 'port': (None, <function _false_validator>, 90100), 'cluster_name': (None, <function _false_validator>, 90500), 'wal_level': ('hot_standby', <patroni.validator.EnumValidator object>, 90100), 'hot_standby': ('on', <function _bool_is_true_validator>, 90100), 'max_connections': (100, <patroni.validator.IntValidator object>, 90100), 'max_wal_senders': (10, <patroni.validator.IntValidator object>, 90100), 'wal_keep_segments': (8, <patroni.validator.IntValidator object>, 90100), 'wal_keep_size': ('128MB', <patroni.validator.IntValidator object>, 130000), 'max_prepared_transactions': (0, <patroni.validator.IntValidator object>, 90100), 'max_locks_per_transaction': (64, <patroni.validator.IntValidator object>, 90100), 'track_commit_timestamp': ('off', <function _bool_validator>, 90500), 'max_replication_slots': (10, <patroni.validator.IntValidator object>, 90400), 'max_worker_processes': (8, <patroni.validator.IntValidator object>, 90400), 'wal_log_hints': ('on', <function _bool_validator>, 90400)} at 7fceff66c7d0>
- _RECOVERY_PARAMETERS = <CaseInsensitiveSet('archive_cleanup_command', 'pause_at_recovery_target', 'primary_conninfo', 'primary_slot_name', 'promote_trigger_file', 'recovery_end_command', 'recovery_min_apply_delay', 'recovery_target', 'recovery_target_action', 'recovery_target_inclusive', 'recovery_target_lsn', 'recovery_target_name', 'recovery_target_time', 'recovery_target_timeline', 'recovery_target_xid', 'restore_command', 'standby_mode', 'trigger_file') at 7fceff76b100>
- _check_primary_conninfo(primary_conninfo: Dict[str, Any], wanted_primary_conninfo: Dict[str, Any]) bool
- static _handle_wal_buffers(old_values: Dict[Any, Tuple[Any, ...]], changes: CaseInsensitiveDict) None
- static _pgpass_content(record: Dict[str, Any]) str | None
Generate content of pgpassfile based on connection parameters.
Note
In case if
hostis a comma separated string we generate one line per host.- Parameters:
record –
dictobject with connection parameters.- Returns:
a string with generated content of pgpassfile or
Noneif there is nopassword.
- _read_recovery_params() Tuple[CaseInsensitiveDict | None, bool]
Read current recovery parameters values.
Note
We query Postgres only if we detected that Postgresql was restarted or when at least one of the following files was updated:
postgresql.conf;postgresql.auto.conf;passfilethat is used in theprimary_conninfo.
- Returns:
a tuple with two elements:
CaseInsensitiveDictobject with current values of recovery parameters, orNoneif no configuration files were updated;Trueif new values of recovery parameters were queried,Falseotherwise.
- _read_recovery_params_pre_v12() Tuple[CaseInsensitiveDict | None, bool]
- property _recovery_parameters_to_compare: CaseInsensitiveSet
- _write_recovery_params(fd: ConfigWriter, recovery_params: CaseInsensitiveDict) None
- build_recovery_params(member: Leader | Member | None) CaseInsensitiveDict
- check_recovery_conf(member: Leader | Member | None) Tuple[bool, bool]
Returns a tuple. The first boolean element indicates that recovery params don’t match and the second is set to True if the restart is required in order to apply new values
- config_writer(filename: str) Iterator[ConfigWriter]
Create
ConfigWriterobject and set permissions on a filename.- Parameters:
filename – path to a config file.
- Yields:
ConfigWriterobject.
- property effective_configuration: CaseInsensitiveDict
It might happen that the current value of one (or more) below parameters stored in the controldata is higher than the value stored in the global cluster configuration.
Example: max_connections in global configuration is 100, but in controldata Current max_connections setting: 200. If we try to start postgres with max_connections=100, it will immediately exit. As a workaround we will start it with the values from controldata and set pending_restart to true as an indicator that current values of parameters are not matching expectations.
- format_dsn(params: Dict[str, Any]) str
Format connection string from connection parameters.
Note
only parameters from the below list are considered and values are escaped.
- Parameters:
params –
dictobject with connection parameters.- Returns:
a connection string in a format “key1=value2 key2=value2”
- get_server_parameters(config: Dict[str, Any]) CaseInsensitiveDict
- load_current_server_parameters() None
Read GUC’s values from
pg_settingswhen Patroni is joining the the postgres that is already running.
- property pg_version: int
Current full postgres version if instance is running, major version otherwise.
We can only use
postgres --versionoutput if major version there equals to the one in data directory. If it is not the case, we should use major version from thePG_VERSIONfile.
- replace_pg_hba() bool | None
Replace pg_hba.conf content in the PGDATA if hba_file is not defined in the postgresql.parameters and pg_hba is defined in postgresql configuration section.
- Returns:
True if pg_hba.conf was rewritten.
- replace_pg_ident() bool | None
Replace pg_ident.conf content in the PGDATA if ident_file is not defined in the postgresql.parameters and pg_ident is defined in the postgresql section.
- Returns:
True if pg_ident.conf was rewritten.
- resolve_connection_addresses() None
Calculates and sets local and remote connection urls and options.
- This method sets:
Postgresql.connection_stringattribute, which is later written to the member key in DCS asconn_url.ConfigHandler.local_replication_addressattribute, which is used for replication connections to local postgres.ConnectionPool.conn_kwargsattribute, which is used for superuser connections to local postgres.
Note
If there is a valid directory in
postgresql.parameters.unix_socket_directoriesin the Patroni configuration andpostgresql.use_unix_socketand/orpostgresql.use_unix_socket_replare set toTrue, we respectively use unix sockets for superuser and replication connections to local postgres.If there is a requirement to use unix sockets, but nothing is set in the
postgresql.parameters.unix_socket_directories, we omit ahostin connection parameters relying on the ability oflibpqto connect via some default unix socket directory.If unix sockets are not requested we “switch” to TCP, preferring to use
localhostif it is possible to deduce that Postgres is listening on a local interface address.Otherwise we just used the first address specified in the
listen_addressesGUC.
- save_configuration_files(check_custom_bootstrap: bool = False) bool
copy postgresql.conf to postgresql.conf.backup to be able to retrieve configuration files - originally stored as symlinks, those are normally skipped by pg_basebackup - in case of WAL-E basebackup (see http://comments.gmane.org/gmane.comp.db.postgresql.wal-e/239)
- set_file_permissions(filename: str) None
Set permissions of file filename according to the expected permissions.
Note
Use original umask if the file is not under PGDATA, use PGDATA permissions otherwise.
- Parameters:
filename – path to a file which permissions might need to be adjusted.
- set_synchronous_standby_names(value: str | None) bool | None
Updates synchronous_standby_names and reloads if necessary. :returns: True if value was updated.
- property synchronous_standby_names: str | None
Get
synchronous_standby_namesvalue configured by the user.- Returns:
value of
synchronous_standby_namesin the Patroni configuration, if any, otherwiseNone.
- write_pgpass(record: Dict[str, Any]) Dict[str, str]
Maybe creates
_passfilebased on connection parameters.- Parameters:
record –
dictobject with connection parameters.- Returns:
a copy of environment variables, that will include
PGPASSFILEin case if the file was written.
- write_postgresql_conf(configuration: CaseInsensitiveDict | None = None) None
- write_recovery_conf(recovery_params: CaseInsensitiveDict) None
- patroni.postgresql.config._conninfo_dsn_parse(dsn: str) Dict[str, str] | None
>>> r = _conninfo_dsn_parse(" host = 'host' dbname = db\\ name requiressl=1 ") >>> r == {'dbname': 'db name', 'host': 'host', 'requiressl': '1'} True >>> _conninfo_dsn_parse('requiressl = 0\\') == {'requiressl': '0'} True >>> _conninfo_dsn_parse("host=a foo = '") is None True >>> _conninfo_dsn_parse("host=a foo = ") is None True >>> _conninfo_dsn_parse("1") is None True
- patroni.postgresql.config._conninfo_parse(value: str) Dict[str, str] | None
Very simple equivalent of psycopg2.extensions.parse_dsn introduced in 2.7.0. Exists just for compatibility with 2.5.4+.
>>> r = _conninfo_parse('postgresql://foo/postgres') >>> r == {'dbname': 'postgres', 'host': 'foo'} True >>> r = _conninfo_parse(" host = 'host' dbname = db\\ name requiressl=1 ") >>> r == {'dbname': 'db name', 'host': 'host', 'sslmode': 'require'} True >>> _conninfo_parse('requiressl = 0\\') == {'sslmode': 'prefer'} True
- patroni.postgresql.config._conninfo_uri_parse(dsn: str) Dict[str, str]
>>> r = _conninfo_uri_parse('postgresql://u%2Fse:pass@:%2f123/db%2Fsdf?application_name=mya%2Fpp&ssl=true') >>> r == {'application_name': 'mya/pp', 'dbname': 'db/sdf', 'sslmode': 'require', 'password': 'pass', 'port': '/123', 'user': 'u/se'} True >>> r = _conninfo_uri_parse('postgresql://u%2Fse:pass@[::1]/db%2Fsdf?application_name=mya%2Fpp&ssl=true') >>> r == {'application_name': 'mya/pp', 'dbname': 'db/sdf', 'host': '::1', 'sslmode': 'require', 'password': 'pass', 'user': 'u/se'} True
- patroni.postgresql.config.get_param_diff(old_value: Any, new_value: Any, vartype: str | None = None, unit: str | None = None) Dict[str, str]
Get a dictionary representing a single PG parameter’s value diff.
- Parameters:
old_value – current
strparameter value.new_value –
strvalue of the parameter after a restart.vartype – the target type to parse old/new_value. See
vartypeargument ofmaybe_convert_from_base_unit().unit – unit of old/new_value. See
base_unitargument ofmaybe_convert_from_base_unit().
- Returns:
a
dictobject that contains two keys:old_valueandnew_valuewith their values casted tostrand converted from base units (if possible).
- patroni.postgresql.config.parse_dsn(value: str) Dict[str, str] | None
Compatibility layer on top of function from psycopg2/psycopg3, which parses connection strings. In this function sets the sslmode, ‘gssencmode’, and channel_binding to prefer and sslnegotiation to postgres if they are not present in the connection string. This is necessary to simplify comparison of the old and the new values.
>>> r = parse_dsn('postgresql://foo/postgres') >>> r == {'dbname': 'postgres', 'host': 'foo', 'sslmode': 'prefer', 'gssencmode': 'prefer', 'channel_binding': 'prefer', 'sslnegotiation': 'postgres'} True >>> r = parse_dsn(" host = 'host' dbname = db\\ name requiressl=1 ") >>> r == {'dbname': 'db name', 'host': 'host', 'sslmode': 'require', 'gssencmode': 'prefer', 'channel_binding': 'prefer', 'sslnegotiation': 'postgres'} True >>> parse_dsn('requiressl = 0\\') == {'sslmode': 'prefer', 'gssencmode': 'prefer', 'channel_binding': 'prefer', 'sslnegotiation': 'postgres'} True >>> parse_dsn('foo=bar') == {'foo': 'bar', 'sslmode': 'prefer', 'gssencmode': 'prefer', 'channel_binding': 'prefer', 'sslnegotiation': 'postgres'} True
- patroni.postgresql.config.read_recovery_param_value(value: str) str | None
>>> read_recovery_param_value('') is None True >>> read_recovery_param_value("'") is None True >>> read_recovery_param_value("''a") is None True >>> read_recovery_param_value('a b') is None True >>> read_recovery_param_value("'''") is None True >>> read_recovery_param_value("'\\") is None True >>> read_recovery_param_value("'a' s#") is None True >>> read_recovery_param_value("'\\'''' #a") "''" >>> read_recovery_param_value('asd') 'asd'