1173 Commits
Author SHA1 Message Date
Alexander KukushkinandGitHub 6f91f4f4e2 Release v3.0.3 (#2719)
* Bump version
* Bump pyright version and fix newly reported issues
* Update release notes
* Fix typos, extend release process desc
* Add readthedocs configuration file v2
* Fix Dockerfile.citus files
2023-06-22 10:46:02 +02:00
Alexander KukushkinandGitHub a00ffcb1a6 Update GUC's validator for PG16 beta1 (#2716)
Plenty of GUC's were added, and some removed.
`force_parallel_mode` was renamed to `debug_parallel_query`, but it is not worth special handling.
2023-06-21 09:58:29 +02:00
Alexander KukushkinandGitHub 9b01041175 Compatibility with python 3.11 (#2718)
now it checks that inside square brackets there is indeed IPv6.

In addition to that fix a little issue in the function itself so it returns exactly the same result as psycopg2.extensions.parse_dsn().

Close https://github.com/zalando/patroni/pull/2714
2023-06-21 09:48:55 +02:00
Alexander KukushkinandGitHub 2354f8f004 Fix a few concurrency bugs in Citus support (#2710)
- the `_in_fligh` attribute is accessed from multiple threads and must be protected with mutex when it is changed
- allow adding tasks for `_in_fligh.group` from the `sync_pg_dist_node()` method when timeout is reached. Not doing so might result is indefinite transaction if REST API request from worker node failed.
2023-06-12 07:52:46 +02:00
IsraelandGitHub bd951ccdef Add docstrings to patroni.async_executor (#2704)
References: PAT-120.
2023-06-09 14:07:06 +02:00
IsraelandGitHub e9f9e1cfad Add docstrings to patroni.exceptions (#2703) 2023-06-06 11:02:44 +03:00
IsraelandGitHub 4e52d4bb2e Add docstrings to patroni.collections (#2702) 2023-06-06 11:01:32 +03:00
IsraelandGitHub 0cf2083161 Add docstrings to patroni.__init__ (#2698)
References: PAT-111
2023-06-06 08:36:29 +02:00
IsraelandGitHub 4b960477bb Add docstrings to patroni.ctl (#2687)
References: PAT-90.
2023-06-06 08:21:59 +02:00
Polina BunginaandGitHub 21e92fd166 Add env vars for custom bin names (#2706) 2023-06-01 14:06:11 +02:00
IsraelandGitHub df18885f20 Extend Postgres GUCs validator (#2671)
* Use YAML files to validate Postgres GUCs through Patroni.

Patroni used to have a static list of Postgres GUCs validators in
`patroni.postgresql.validator`.

One problem with that approach, for example, is that it would not
allow GUCs from custom Postgres builds to be validated/accepted.

The idea that we had to work around that issue was to move the
validators from the source code to an external and extendable source.
With that Patroni will start reading the current validators from that
external source plus whatever custom validators are found.

From this commit onwards Patroni will read and parse all YAML files
that are found under the `patroni/postgresql/available_parameters`
directory to build its Postgres GUCs validation rules.

All the details about how this work can be found in the docstring
of the introduced function `_load_postgres_gucs_validators`.
2023-05-31 13:54:54 +02:00
IsraelandGitHub d11328020d Add support for custom Postgres binary names (#2692)
When using a custom Postgres distribution it may be the case that the Postgres binaries are compiled with different names other than the ones used by the community Postgres distribution.

With that in mind we implemented a new set of settings for Patroni, so the user is able to override the default binary names with custom binary names through the new section postgresql.bin_name in the local configuration.

References: PAT-17.
2023-05-30 13:57:57 +02:00
37fffa618f Refactor daemon entrypoints (#2697)
- abstract_main only creates Config object using the passed configfile
  and instantiates the passed daemon class
- common args parser is extracted into a separate func that is called
  from daemons' main funcs (specific args can be added afterwards)

Co-authored-by: Alexander Kukushkin <[email protected]>
2023-05-26 15:13:04 +02:00
Alexander KukushkinandGitHub 101ea10e98 Introduce Retry.ensure_deadline() method (#2694)
it helps to get rid of recurring patterns:
```python
retry.deadline = retry.stoptime - time.time()
if retry.deadline < XXX:
    raise Exception(...) or return False
```
2023-05-26 11:04:58 +02:00
Alexander KukushkinandGitHub af8e5f0d0f Refactor update_leader interface (#2690)
pass reference to a last known leader object in order to avoid obtaining it from the `AbstractDCS.cluster` cache.

This change is useful for Consul, Etcd3 and Zookeeper implementations.
2023-05-25 14:21:05 +02:00
Alexander KukushkinandGitHub 1c7bf2f59e Fix a problem with etcd3.update_leader() (#2693)
It didn't took into account the fact that we can get a new lease after changing a TTL. In this case we have to update the exiting leader key with the new lease.
To solve it we introduce the on transaction 'failure' callback. The whole workflow looks like (schematically):
```python
txn(
    compare=(old_value == self._name)),
    success=put(self.leader_path, self._name, self._lease),
    failure=txn(
        compare=(create_revision == '0'),
        success=put(self.leader_path, self._name, self._lease)
    )
)
```

The problem was introduced in d98d6d0b02c9cc67464a7b1b31b1c5570c26e12d
2023-05-25 10:01:43 +02:00
Alexander KukushkinandGitHub b4afc6830b Little fixes in etcd3 and kubernetes (#2689)
- Always pass etcd3 key revision as a string
- Make sure the leader key isn't unconditionally overwritten. It may happen that the leader heart-beat loop didn't run properly and the session has expired. In this case the leader may create a new session and a new leader key. But, there are chances that the other node already created a leader key and we don't want to overwrite it.
- Try to sync HA loops between nodes by adding 0.5 seconds to timeout on non-leader nodes
2023-05-24 10:54:26 +02:00
Polina BunginaandGitHub d1fdb45179 Make bootstrap.initdb optional (#2685) 2023-05-24 09:28:57 +02:00
6c8a3b0d25 Remove bootstrap.pg_hba (#2684)
* Remove bootstrap.pg_hba
* Extend docs for postgresql.pg_hba/pg_ident
* Add postgresql.pg_hba/pg_ident to dynamic config docs

---------

Co-authored-by: Alexander Kukushkin <[email protected]>
2023-05-24 09:01:56 +02:00
IsraelandGitHub 0ead20f6a4 Remove __str__ method from PatroniException. (#2688)
The `__str__` method was calling `repr` over the exception message,
which was causing `print` calls to render not so nicely, e.g.:

```
$ patronictl show-config
Error: 'Can not find suitable configuration of distributed configuration store\nAvailable implementations: consul, etcd, etcd3, exhibitor, kubernetes, raft, zookeeper'
```

By removing the `__str__` method we get a better rendering, e.g.:

```
$ patronictl show-config
Error: Can not find suitable configuration of distributed configuration store
Available implementations: consul, etcd, etcd3, exhibitor, kubernetes, raft, zookeeper
```

References: PAT-107.

Signed-off-by: Israel Barth Rubio <[email protected]>
2023-05-23 17:05:53 +02:00
Polina BunginaandGitHub e0a4a0c6a6 Fix pyright complaints about partner_addrs, change Citus repo URL in CI (#2682)
* Fix pyright complaints about partner_addrs
* Pin pyright version in workflow
* Change Citus repo URL in CI
2023-05-22 15:30:24 +02:00
Polina BunginaandGitHub 506b5bec48 Validate-config fixes (#2678)
- fix --validate-config not to error out if bin_dir is an empty string in the yaml config
- mention bin_dir optionality in the docs
- validate bin_dir even if it is not in the yaml config (add optional
  default value for Optional config params in validator)
- make rewind user optional
2023-05-15 13:40:22 +02:00
Alexander KukushkinandGitHub 66a0e44371 Enable pyright job for every commit (#2675)
And fix remaining issues that the job doesn't fail.
2023-05-15 11:38:40 +02:00
IsraelandGitHub fdcf8b1997 Add docstrings and type hints to patroni/api.py (#2648)
References: PAT-77
2023-05-12 15:38:59 +02:00
Alexander KukushkinandGitHub 7941c86775 Refactor write_sync_state() (#2669)
Make it return the new `SyncState` object in order to avoid reading the new cluster state in the Ha.process_sync_replication().

Now it is a small optimization, but it will become very handy in the quorum commit feature.
2023-05-11 09:58:15 +02:00
Alexander KukushkinandGitHub 13164daf28 More typing in sync.py (#2666)
- make parse_sync_standby_names() return NamedTuple instead of dict
- fix little issue in Postgresql.reset_cluster_info_state(), it should check global_config independently from cluster and cluster.config
2023-05-09 12:47:34 +02:00
Alexander KukushkinandGitHub 76b3b99de2 Enable pyright strict mode (#2652)
- added pyrightconfig.json with typeCheckingMode=strict
- added type hints to all files except api.py
- added type stubs for dns, etcd, consul, kazoo, pysyncobj and other modules
- added type stubs for psycopg2 and urllib3 with some little fixes
- fixes most of the issues reported by pyright
- remaining issues will be addressed later, along with enabling CI linting task
2023-05-09 09:38:00 +02:00
Polina BunginaandGitHub 1ac9b11f33 Remove watchdog from __DEFAULT_CONFIG (#2660) 2023-05-04 08:37:39 +02:00
Le DuaneandGitHub bebe6754fc Add before stop hook (#2642)
The two cases we have in mind are:
* In spite of following all best practices client-side, logical replication connections can sometimes hang the Postgres shutdown sequence. We'd like to sigterm any misbehaving logical replication connections which remain after x seconds. These will inevitably get killed anyway on master stop timeout.
* remove "role=master" label on current primary when not using k8s as DCS. Waiting until after Postgres fully stops can sometimes be too long for this.
* Pause pgbouncer connections before switchover

Close #2596
2023-04-27 13:07:32 +02:00
Matt BakerandGitHub ff6d728f07 Call initdb directly (#2633)
Previously it was called via `pg_ctl`, what required a special quoting of parameters passed to `initdb`.
Co-authored-by: Israel <[email protected]>
2023-04-24 09:35:39 +02:00
IsraelandGitHub 4f458baa0e Add docstrings and type annotations to patroni/psycopg.py (#2634)
References: PAT-72
2023-04-13 16:30:14 +02:00
IsraelandGitHub 7c0a565985 Add docstrings and type annotations to patroni/request.py (#2635)
References: PAT-73
2023-04-13 15:23:41 +02:00
IsraelandGitHub 782ebda77e Add docstrings and type annotations to patroni/log.py (#2636)
References: PAT-74
2023-04-13 14:32:37 +02:00
AndreyandGitHub 8a5d6ec74d Add "request_queue_size" option to REST API server (#2643)
Sets request queue size for TCP socket used by Patroni REST API. Once the queue is full, further requests get a "Connection denied" error. The default value is 5.
2023-04-12 10:25:14 +02:00
IsraelandGitHub 6ffc73946a Cover etcd3 in parse_dcs function (#2639)
Previous to this commit the `parse_dcs` function would fail with a `PatroniCtlException` if the user ever passed an `etcd3` URL through `--dcs-url` command-line option.

As a consequence, the only way of using `etcd3` in `patronictl` was by using a configuration file passed through `-c` command-line option.

This commit fixes that issue and allows `etcd3` to be used in `--dcs-url`.

References: PAT-91
Close #2638
2023-04-12 09:02:32 +02:00
Alexander KukushkinandGitHub e30d96a468 More use of CaseInsensitiveSet (#2631)
1. make `SyncHandler.current_state()` return `CaseInsensitiveSet` instead of `list` objects.
2. take `sync_node_count` and `sync_node_maxlag` from the `Postgresql._global_config` instead of passing them as arguments.
3. Make `AbstractDCS.write_sync_state()` accept any `Collection`-like objects.
2023-04-05 15:30:55 +02:00
Alexander KukushkinandGitHub 2c7b547a29 Introduce patroni.collections (#2629)
For now it implements:
- CaseInsensitiveDict()
- CaseInsensitiveSet()

Update `patroni.postgresql.sync.parse_sync_standby_names()` to use `CaseInsensitiveSet()` instead of `CaseInsensitiveDict()`
2023-04-03 11:19:08 +02:00
3fe2a7868a Ignore D401 in flake8-docstrings (#2627)
* Ignore D401 in flake8-docstrings
* Fix newly reported flake8 issues, ignore the old W503 rule
* rely on concatenation of adjecent strings
* Format behave scripts
* Reformat ha.py according to new rules

Co-authored-by: Alexander Kukushkin <[email protected]>
2023-04-03 09:52:22 +02:00
Alexander KukushkinandGitHub 6f357a4e17 Factor out global configuration into a dedicated class (#2628)
It will help to avoid code duplications.
2023-04-03 08:09:29 +02:00
IsraelandGitHub c549ea7d5c Add docstrings and type annotations to patroni/utils.py (#2624)
References: PAT-43
2023-03-30 08:36:13 +02:00
IsraelandGitHub 786f7eba97 Add docstrings and type annotations to patroni/validator.py (#2612)
References: PAT-42
2023-03-28 07:37:28 +02:00
Alexander KukushkinandGitHub f42bab5081 Improve behaviour of SyncState.matches() (#2619)
Previously it used to compare between the leader and sync_standbys, while in some cases (actually most of them) the leader should be excluded.
This commit makes `matches()` method flexible:
1. The leader will be included to comparison only if requested
2. checks will be performed as case insensitive (like PG does)

Besides that, everywhere in code start using `cluster.sync.matches()` instead of `name in cluster.sync.members`.
2023-03-28 07:36:45 +02:00
Alexander KukushkinandGitHub 39875f448c Release v3.0.2 (#2617)
- bump version
- update release notes
- update links to Postgres Slack
- simplify /sync health-check endpoint code
- update unit-tests to cover missing lines
2023-03-24 08:54:54 +01:00
IsraelandGitHub a1095e385c Handle patronictl edit-config diff pager in a more user friendly way (#2605)
`patronictl edit-config` requires a pager to show the diff output back to the user. It used to be hard-coded to use either `less` or `more`.

When these tools were not available in the host that would cause `patronictl` to face an exception in `ydiff` module and to show the stack trace in the console.

This PR changes `patronictl edit-config` command to behave like this:

- If `PAGER` environment variable is set, attempt to find the corresponding executable.
- If `PAGER` is not set or is set with an invalid executable, then attempt to use either `less` or `more` as it used to do.
- If no executable is find at all then throw a `PatroniCtlException` to show an user friendly message

Unit tests in `tests/test_ctl.py` were modified accordingly.

References: PAT-21
Close #2604
2023-03-23 13:43:48 +01:00
IsraelandGitHub 84353b88c9 Add docstrings and type annotations to patroni/daemon.py (#2610)
References: PAT-38
2023-03-23 13:41:16 +01:00
60723f5fa4 Add metric to report about sync standby replica status (#2615)
Close #2613

Co-authored-by: Alexander Kukushkin <[email protected]>
2023-03-23 09:32:29 +01:00
Alexander KukushkinandGitHub a8b90f0cd6 Make sure Cluster.sync is never empty (#2614)
It was possible to have it empty if the all cluster keys are missing in DCS. In this case the `Cluster` object was manually created with all values set to `None` or `[]` (including sync).
It already resulted in #2217, which is in fact wasn't a correct fix.

In order to solve it and reduce code duplication we introduce `Cluster.empty()` and `SyncState.empty()` methods, which will create corresponding empty objects and start using `Cluster.empty()` from all places where the empty `Cluster` object was manually created.
2023-03-22 16:41:41 +01:00
IsraelandGitHub 918674e7bb Document code in patroni/version.py (#2611)
References: PAT-39

Signed-off-by: Israel Barth Rubio <[email protected]>
2023-03-22 11:46:15 +01:00
Alexander KukushkinandGitHub ddac8683e6 Use config file as a fallback when all current etcd nodes failed (#2599)
If communication with etcd nodes failed it is logical to start from scratch, from nodes that are listed in the config. But, it could happen that config is in fact outdated and all nodes in the real cluster were replaced.

Previously we used to track whether config file was changed, which turned out not to work in all possible cases.
The new strategy is a bit more different - if communication with all nodes failed we will continue keeping the last know topology and at the same time will try to figure out the new one by merging two lists together, the cached list and the list from the config file.
2023-03-14 15:54:17 +01:00
Alexander KukushkinandGitHub c1bfb0e6d6 Remove python 2.7 support (#2571)
- get rid from 2.7 specific modules: `six`, `ipaddress`
- use Python3 unpacking operator
- use `shutil.which()` instead of `find_executable()`
2023-03-13 17:00:04 +01:00