Commit Graph
100 Commits
Author SHA1 Message Date
Alexander KukushkinandGitHub ed47224540 Improve behaviour of the insecure option (#2476)
It didn't worked correctly when client certificates are used for REST API requests.
2022-12-06 17:24:57 +01:00
Alexander KukushkinandGitHub c7a925a238 Switch from localkube to kind and/or k3d (#2465)
The only advantage of localkube was being a low weight. Anything else started creating only problems:
1. It is not properly maintained for many years.
2. It effectively worked only on Linux, but stopped on modern version due to changes in iptables.

Instead, we will use widely adoped tools like kind or k3s. The "kind-kind" is the default K8s context (see ~/.kube/config), but it could be overriden using `PATRONI_KUBERNETES_CONTEXT` environment variable. When executed from GH actions the context is set to k3d-k3s-default, because K3s is much faster to start.
2022-12-06 13:15:56 +01:00
Alexander KukushkinandGitHub 26244634ce Fix annoying exceptions on ssl socket shutdown (#2468)
The HAProxy is closing connections as soon as it got the HTTP Status code leaving no time for Patroni to properly shutdown SSL connection.

Close https://github.com/zalando/patroni/issues/2466
2022-12-06 11:57:12 +01:00
Alexander KukushkinandGitHub b47c50a788 Stick to the ubuntu-20.04 (#2472)
the ubuntu-latest is switching to 22.04 and discontinued support of python 2.7 and 3.6
2022-12-05 12:00:31 +01:00
Alexander KukushkinandGitHub 412d508023 Bugfix: raise ConfigParseError (#2463)
instead of returning error string
2022-11-28 11:44:06 +01:00
Alexander KukushkinandGitHub 53f89faaab Release v2.1.5 (#2462)
* bump version
* update release notes
* run some behave tests on v15
* automate release process by building/pushing packages on tag creation and release publication
2022-11-28 10:45:04 +01:00
Alexander KukushkinandGitHub 1b6e23ab6a Add Polina to maintainers (#2451)
and remove some old names
2022-11-10 10:22:42 +01:00
Alexander KukushkinandGitHub bda2bedf48 Make sure self.__retry_timeout is set (#2440)
The default value was None, which is the same as no timeout.
2022-10-25 14:14:16 +02:00
Alexander KukushkinandGitHub 5a21ffa3e4 Fix a little bug in check_logical_slots_readiness() (#2439)
If there is no `catalog_xmin` on physical slot on the primary the only further check that makes sense is whether the `hot_standby_feedback` is enabled.

Close https://github.com/zalando/patroni/issues/2438
2022-10-24 15:24:36 +02:00
Alexander KukushkinandGitHub 4ecaf445fa Introduce configurable timeout in TcpUtility (#2435)
the value is calculated based on the number of nodes and retry_timeout.

Close https://github.com/zalando/patroni/issues/2431
2022-10-24 10:30:28 +02:00
Alexander KukushkinandGitHub a293b77d25 Compatibility with prettytable 2.2.0+ (#2436)
`patronictl list` and `patronictl topology` didn't worked correctly starting from prettytable 2.2.0 (https://github.com/jazzband/prettytable/pull/104).
Example of wrong output:
```
+----------+-----------+---------+---------+----+-----------+
| Member   | Host      | Role    | State   | TL | Lag in MB |
+ Cluster: demo-cluster-1 (7155048679605235377) +-----------+
| node-2   | 10.2.0.21 | Leader  | running |  1 |           |
| + node-1 | 10.2.0.6  | Replica | running |  1 |         0 |
| + node-3 | 10.2.0.25 | Replica | running |  1 |         0 |
+----------+-----------+---------+---------+----+-----------+
```
2022-10-24 10:23:21 +02:00
Alexander KukushkinandGitHub 8f8e9c9b81 Inptroduce postgresql.proxy_address (#2437)
It will be written to member key in DCS as the `proxy_url` and could be used/useful for service discovery.
2022-10-24 10:23:06 +02:00
Alexander KukushkinandGitHub 580530b30f Behave tests on Windows (#2432)
Windows doesn't support `SIGTERM`, but our behave tests in majority of cases relying on Patroni graceful shutdown.
In order to emulate the behaviour we introduced the new REST API endpoint `POST /sigterm`. The endpoint works only on Windows and when `BEHAVE_DEBUG` environment variable is set.
Besides that some minor adjustments in behave tests were done. Mainly related to backslash-slash handling.

In addition to that improve test coverage on Windows by properly mocking access to filesystem and avoiding calling
 `subprocess.call()`. Specifically, symlink creation on Windows requires Admin privileges and there is no `true.exe`.
2022-10-21 12:24:24 +02:00
Alexander KukushkinandGitHub f4ae55b92a Remove 'enable_group_by_reordering' from GUC validator (#2426)
The feature was recently reverted.
2022-10-13 10:53:29 +02:00
Alexander KukushkinandGitHub 816b66311b A small fix in unit tests (#2427)
Not all external resources were properly mocked
2022-10-13 10:53:13 +02:00
Alexander KukushkinandGitHub 8a227aa743 Explicitly shut down SSL connection before socket (#2425)
This is handled by calling the unwrap() method on SSLSocket.
In addition to that simplify code that handles deferred handshakes.

Close https://github.com/zalando/patroni/issues/2424
2022-10-13 10:34:43 +02:00
Alexander KukushkinandGitHub 531063f676 Compatibility with kazoo-2.9.0 (#2428)
Now the select() method may raise `TypeError` and `IOError` exceptions if the socket is closed.
2022-10-13 09:18:06 +02:00
Alexander KukushkinandGitHub 7102346f87 Update release.sh (#2421)
in order to reflect the current release process
2022-09-27 09:43:38 +02:00
Alexander KukushkinandGitHub 6d8d1a2556 Make sure only sync node tries to grab the lock when switchover (#2406)
- We use `failover.leader` check as an indicator of switchover. The check on `failover.candidate` was unnecessary and incorrect.
- Add more unit-tests for switchover in sync mode

Close https://github.com/zalando/patroni/issues/2405
Co-authored-by: Polina Bungina <[email protected]>
2022-09-19 11:22:35 +02:00
Alexander KukushkinandGitHub 3e1076a574 Use replication credentials when checking leader status (#2165)
It could be that `remove_data_directory_on_diverged_timelines` is set, but there is no `rewind_credentials` defined and superuser access between nodes is not allowed.

Close https://github.com/zalando/patroni/issues/2162
2022-01-11 16:23:13 +01:00
Alexander KukushkinandGitHub cb3071adfb Annual cleanup (#2159)
-  Simplify setup.py: remove unneeded features and get rid of deprecation warnings
-  Compatibility with Python 3.10: handle `threading.Event.isSet()` deprecation
-  Make sure setup.py could run without `six`: move Patroni class and main function to the `__main__.py`. The `__init__.py` will have only a few functions used by the Patroni class and from the setup.py
2022-01-06 10:20:31 +01:00
Alexander KukushkinandGitHub bf354aeebd Compatibility with legacy psycopg2 (#2158)
For example, psycopg2 installed from Ubuntu 18.04 packages doesn't have `UndefinedFile` exception yet.
2022-01-06 10:14:50 +01:00
Alexander KukushkinandGitHub 01d40a4a13 Compatibility with latest psutil and setuptools (#2155)
Issues don't affect Patroni code, only unit-tests
2022-01-05 09:53:33 +01:00
Alexander KukushkinandGitHub 3cc14cc059 Unquote integers in validator (#2154)
Close https://github.com/zalando/patroni/issues/2150
2022-01-04 10:47:02 +01:00
Alexander KukushkinandGitHub a015e0e271 Fix bug with failover to cascading standby (#2138)
When figuring out which slots should be created on cascading standby we forgot to take into account that the leader might be absent.

Close: https://github.com/zalando/patroni/issues/2137
2021-12-21 11:20:35 +01:00
Alexander KukushkinandGitHub d2b681b07e Fix bug in the bootstrap standby-leader (#2144)
When starting postgres after bootstrap of the standby-leader the `follow()` method is used to always return `True`.
This behavior was changed in the #2054 in order to avoid hammering logs if postgres is failing to start.

Since now the method returns `None` if postgres didn't start accepting connections after 60s, the change broke the standby-leader bootstrap code.

As the solution, we will assume that the clone was successful if the `follow()` method returned anything different from `False`.
2021-12-21 11:20:06 +01:00
Alexander KukushkinandGitHub 63586f0477 Add ctl.keyfile_password support (#2145)
It compliments restapi.keyfile_password added in the #1825
2021-12-21 11:19:39 +01:00
Alexander KukushkinandGitHub 4215565cb4 Rearrange tests (#2146)
- remove codacy steps: they removed legacy organizations and there seems to be no easy way of installing codacy app to the Zalando GH.
- Don't run behave on MacOS: recently worker became way to slow
- Disable behave for combination of kubernetes and python 2.7
- Remove python 3.5 (it will be removed by GH from workers in January) and add 3.10
- Run behave with 3.6 and 3.9 instead of 3.5 and 3.8
2021-12-21 09:36:22 +01:00
Alexander KukushkinandGitHub dc9ff4cb8a Release 2.1.2 (#2136)
* Implement missing unit-tests
* Bump version
* Update release notes
2021-12-03 15:49:57 +01:00
Alexander KukushkinandGitHub d7dc3c2d96 Handle missing timelines in history file when deciding to rewind (#2120)
When restore_command is configured Postgres is trying to fetch/apply all possible WAL segments and also fetch history files in order to select the correct timeline. It could result in a situation where the new history file will be missing some timelines.

Example:
- node1 demotes/crashes on timeline 1
- node2 promotes to timeline 2 and archives `00000002.history` and crashes
- node1 recovers as a replica, "replays" `00000002.history` and promotes to timeline 3

As a result, the `00000003.history` will not have the line with timeline 2, because it never replayed any WAL segment from it.
The `pg_rewind` tool is supposed to correctly handle such case when rewinding node2 from node1, but Patroni when deciding whether the rewind should happen was searching for the exact timeline in the history file from the new primary.

The solution is to assume that rewind is required if the current replica timeline is missing.

In addition to that this PR makes sure that the primary isn't running in recovery before starting the procedure of rewind check.

Close https://github.com/zalando/patroni/issues/2118 and https://github.com/zalando/patroni/issues/2124
2021-12-02 11:35:30 +01:00
Alexander KukushkinandGitHub 63ee42a85c Clear event on the leader node when /status was updated (#2125)
Not doing so causing excessive HA loop runs with Zookeeper.
This moment wasn't fixed correctly in the #1875
2021-11-30 16:33:38 +01:00
Alexander KukushkinandGitHub d24051c31c Optimize case when we don't have permanent logical slots (#2121)
The unnecessary call of SlotsHandler.process_permanent_slots() results in one additional query to `pg_replication_slots` view every HA loop.
2021-11-30 14:20:55 +01:00
Alexander KukushkinandGitHub 31d7540cc5 Prefer members without nofailover when picking sync nodes (#2108)
Previously sync nodes were selected only based on replication lag and hence the node with `nofailover` tag had the same chances to become synchronous as any other node. That behavior was confusing and dangerous at the same time, because in case of failed primary the failover couldn't happen automatically.

Close https://github.com/zalando/patroni/issues/2089
2021-11-30 14:20:03 +01:00
Alexander KukushkinandGitHub 256a359a1e Fix a litle bug around psycopg 3.0 (#2123)
Cursor.execute now returns cursor itself, while in psycopg2 it was returning None
2021-11-19 16:29:39 +01:00
Alexander KukushkinandGitHub 17e523b175 Optimize checkpoint after promote (#2114)
1. Avoid doing CHECKPOINT if `pg_control` is already updated.
2. Explicitly call ensure_checkpoint_after_promote() right after the bootstrap finished successfully.
2021-11-19 14:33:24 +01:00
Alexander KukushkinandGitHub fce889cd04 Compatibility with psycopg 3.0 (#2088)
By default `psycopg2` is preferred. The `psycopg>=3.0` will be used only if `psycopg2` is not available or its version is too old.
2021-11-19 14:32:54 +01:00
Alexander KukushkinandGitHub edfe2a84e9 Fix a few issues with Patroni API (#2116)
1. The `client_address` tuple may have more than two elements in case of IPv6
2. Return `cluster_unlocked` only when the value is true and handle it respectively in the do_GET_metrics()
3. Return `cluster_unlocked` and `dcs_last_seen` even if Postgres isn't running/queries timing out

Close https://github.com/zalando/patroni/issues/2113
2021-11-12 15:02:53 +01:00
Alexander KukushkinandGitHub 00d125c512 Avoid unnecessary updates of the members ZNode. (#2115)
When deciding whether the ZNode should be updated we rely on the cached version of the cluster, which is updated only when members ZNodes are deleted/created or the `/status`, `/sync`, `/failover`, `/config`, or `/history` ZNodes are updated.

I.e. after the update of the current member ZNode succeeded the cache becomes stale and all further updates are always performed even if the value didn't change. In order to solve it, we introduce the new attribute in the Zookeeper class and will use it for memorizing the actual value and for later comparison.
2021-11-12 15:00:54 +01:00
Alexander KukushkinandGitHub fd1e0f1c1b BUGFIX: use_unix_socket_repl didn't work is some cases (#2103)
Specifically, if `postgresql.unix_socket_directories` is not set.
In this case Patroni is supposed to use only the port in the connection string, but the `get_replication_connection_cursor()` method defaulted to host='localhost'
2021-10-29 12:09:38 +02:00
Alexander KukushkinandGitHub 47ebda0d5d Fix a few issues in kubernetes.py (#2084)
1. Two `TypeError`-s raised from `ApiClient.request()` method
2. Use the _retry() wrapper function instead of callable object in the `_update_leader_with_retry()` when trying to workaround concurrent updates of the leader object.
2021-10-08 16:13:28 +02:00
Alexander KukushkinandGitHub 250328b84b Use cached role as a fallback when postgres is slow (#2082)
In some extreme cases Postgres could be so slow that the normal monitoring query doesn't finish in a few seconds. It results in
the exception being raised from the `Postgresql._cluster_info_state_get()` method, which could lead to the situation that postgres isn't demoted on time.
In order to make it reliable we will catch the exception and use the cached state of postgres (`is_running()` and `role`) to determine whether postgres is running as a primary.

Close https://github.com/zalando/patroni/issues/2073
2021-10-07 16:08:21 +02:00
Alexander KukushkinandGitHub 89388c2e4b Handle DCS exceptions when demoting (#2081)
While doing demote due to failure to update leader lock it could happen that DCS goes completely down and the get_cluster() call raise the exception.
Not being properly handled it results in postgres remaining stopped until DCS recovers.
2021-10-07 16:08:10 +02:00
Alexander KukushkinandGitHub d394b63c9f Release the leader lock when pg_controldata reports "shut down" (#2067)
Due to different reasons, it could happen that WAL archiving on the primary stuck or significantly delayed. If we try to do a switchover or shut it down, the shutdown will take forever and will not finish until the whole backlog of WALs is processed.
In the meantime, Patroni keeps updating the leader lock, which prevents other nodes from starting the leader race even if it is known that they received/applied all changes.

The `Database cluster state:` is changed to `"shut down"` after:
- all data is fsynced to disk and the latest checkpoint is written to WAL
- all streaming replicas confirmed that they received all changes (including the latest checkpoint)
- at the same time, the archiver process continues to do its job and the postmaster process is still running.

In order to solve this problem and make the switchover more reliable/fast in a case when `archive_command` is slow/failing, Patroni will remove the leader key immediately after `pg_controldata` started reporting PGDATA as `"shut down"` cleanly and it verified that there is at least one replica that received all changes. If there are no replicas that fulfill the condition the leader key isn't removed and the old behavior is retained, i.e. Patroni will keep updating it.
2021-10-05 10:55:35 +02:00
Alexander KukushkinandGitHub 1c2bf258d6 Allow switchover only to sync nodes when synchronous replication is on (#2076)
Close https://github.com/zalando/patroni/issues/2074
2021-10-04 16:23:45 +02:00
Alexander KukushkinandGitHub a431f50378 Check only sync nodes when assessing failover capabilities (#2065)
When synchronous_mode is enabled we should check only synchronous nodes in is_failover_possible().
2021-09-24 08:22:54 +02:00
Alexander KukushkinandGitHub fca724186e DCS.write_leader_optime() should update /status key (#2064)
This moment was forgotten in the failover logical slots implementation.
2021-09-24 08:22:20 +02:00
Alexander KukushkinandGitHub 258e7e24f4 Ensure pg_replication_slot_advance() doesn't timeout (#2060)
The bigger gap between the slot flush LSN and the LSN we want to advance to becomes more time it takes for the call to finish.
Once started failing the "lag" will grow more or less infinitely, that have the following negative side-effects:
1. Size of pg_wal on the replica will grow
2. Since the hot_standby_feedback is forcefully enabled, the primary will stop cleaning up dead tuples
I.e., we are not only in danger of running out of disk space, but also increasing chances of transaction wraparound to happen.

In order to mitigate it, we want to set the `statement_timeout` to 0 before calling `pg_replication_slot_advance()`.

Since the call is happening from the main HA loop and could take more than `loop_wait`, the next heartbeat run could be delayed.
There is also a possibility that the call could take longer than `ttl` and the member key/session in DCS for a given replica expires, but, the slot LSN in DCS is updated by the primary every `loop_wait` seconds. Hence, we don't expect that the slot_advance() call will take significantly longer than the `loop_wait` and therefore chances of the member key/session to expire are very low.
2021-09-17 16:39:39 +02:00
Alexander KukushkinandGitHub 7bd28250ca Skip temporary replication slots while doing slot management (#2055)
Starting from v10 `pg_basebackup` creates a temporary replication slot for WAL streaming and Patroni was trying to drop it because the slot name looks unknown. In order to fix it, we skip all temporary slots when querying `pg_stat_replication_slots` view.

Another option to solve the problem would be running `pg_basebackup` with `--slot=current_node_name` option, but unfortunately at the moment when `pg_basebackup` is executed, we don't yet know the major version (the `--slot` option was added in v9.6).

Ref: https://github.com/zalando/patroni/issues/2046#issuecomment-912521502
2021-09-17 14:44:54 +02:00
Alexander KukushkinandGitHub 21145d18d1 Delay the next attempt of recovery till next HA loop (#2054)
If Postgres crashed due to out of disk space (for example) and fails to start because of that Patroni is too eagerly trying to recover it and producing too many logs
2021-09-17 13:46:46 +02:00
Alexander KukushkinandGitHub 93efa91bbd Release 2.1.1 (#2039)
* Update release notes
* Bump version
* Improve unit-test coverage
2021-08-19 15:44:37 +02:00
Alexander KukushkinandGitHub db12051a5b Improve compatibility with latest minor releases (#2034)
The commit https://github.com/postgres/postgres/commit/93a0bf2390327a482ff37317f6e17547e735409e changed the behavior of `pg_settings.pending_restart`. Mostly it will not cause issues because usually people very rarely removing values from
the config, but one case is unique. If Patroni is restarted for an upgrade and it finds that Postgres is up and running, it rewrites
`postgresql.conf` and performs a reload. As a result, recovery parameters are removed from the config for Postgres v12+ and the `pending_restart` flag is falsely set. In order to partially mitigate the problem before it is fixed in Postgres we will skip recovery parameters when checking `pending_restart` flags in the `pg_settings`.

In addition to that, remove two parameters from the validator because they were reverted from Postgres v14.
2021-08-17 16:14:10 +02:00
Alexander KukushkinandGitHub ccfe30729e Skip NULLs in the pg_stat_replication (#2016)
Close https://github.com/zalando/patroni/issues/2014
2021-08-13 15:48:15 +02:00
Alexander KukushkinandGitHub c81391e314 Don't resolve cluster members when use_proxies is set (#2007)
Close https://github.com/zalando/patroni/issues/2006
2021-07-21 08:36:21 +02:00
Alexander KukushkinandGitHub 9288ce066b Reload REST API certificate only on SIGHUP (#2004)
And make sure that cert number is cached when the RestApiServer object is created.

Close https://github.com/zalando/patroni/issues/2003
2021-07-21 08:33:08 +02:00
Alexander KukushkinandGitHub f2309abc87 Release 2.1.0 (#1998)
* bump version
* update release notes
2021-07-06 10:19:22 +02:00
Alexander KukushkinandGitHub 62aa1333cd Implemented allowlist for REST API (#1959)
If configured, only IPs that matching rules would be allowed to call unsafe endpoints.
In addition to that, it is possible to automatically include IPs of members of the cluster to the list.
If neither of the above is configured the old behavior is retained.

Partially address https://github.com/zalando/patroni/issues/1734
2021-07-05 09:43:56 +02:00
Alexander KukushkinandGitHub b7a11232eb Track /status key updates (#1957)
The #1820 introduced a new key in DCS, named /status, which contains the leader optime and maybe flush LSN of logical slots.

In case of etcd3 and raft we should use updates of this key for syncing HA loop across nodes (before we were using /optime/leader).
2021-07-05 09:43:01 +02:00
Alexander KukushkinandGitHub 333d292eb3 Handle DNS issues in Raft implementation (#1960)
- Resolve Node IP for every connection attempt
- Handle exception with connection failures due to failed resolve
- Set PySyncObj DNS Cache timeouts aligned with `loop_wait` and `ttl`

In addition to that,  postpone the leader race for freshly started Raft nodes. It will help with the situation when the leader node was alone and demoted the Postgres and after that, the replica arrives, and quickly takes the leader lock without really performing the leader race.

Close https://github.com/zalando/patroni/issues/1930, https://github.com/zalando/patroni/issues/1931
2021-07-05 09:30:31 +02:00
Alexander KukushkinandGitHub 0ceb59b49d Write prev LSN to before checkpoint to optime if wal_achive=on (#1889)
The #1527 introduced a feature of updating `/optime/leader` with the location of the last checkpoint after the Postgres was shutdown cleanly.

If wal archiving is enabled, Postgres always switching the WAL file before writing the checkpoint shutdown record. Normally it is not an issue, but for databases without too much write activity it could lead to the situation that the visible replication lag becomes equal to the size of a single WAL file. In fact, the previous WAL file is mostly empty and contains only a few records.

Therefore it should be safe to report the LSN of the SWITCH record before the shutdown checkpoint.
In order to do that, Patroni first gets the output of the pg_controldata and based on it calls pg_waldump two times:
* The first call reads the checkpoint record (and verifies that this is really the shutdown checkpoint).
* The next call reads the previous record and in case if it is the 'xlog switch' (for 9.3 and 9.4) or 'SWITCH' (for 9.5+), the LSN
of the SWITCH record is written to the `/optime/leader`.

In case of any mismatch, failure to call pg_waldump or parse its output, the old behavior is retained, i.e. `Latest checkpoint location` from the pg_controldata is used.

Close https://github.com/zalando/patroni/issues/1860
2021-07-05 09:29:39 +02:00
Alexander KukushkinandGitHub 77382e75dc Compatibility with kazoo-2.7+ (#1982)
Old versions of `kazoo` immediately discarded all requests to Zookeeper if the connection is in the `SUSPENDED` state. This is absolutely fine because Patroni is handling retries on its own.
Starting from 2.7, kazoo started queueing requests instead of discarding and as a result, the Patroni HA  loop was getting stuck until the connection to Zookeeper is reestablished, causing no demote of the Postgres.
In order to return to the old behavior we override the `KazooClient._call()` method.

In addition to that, we ensure that the `Postgresql.reset_cluster_info_state()` method is called even if DCS failed (the order of calls was changed in the #1820).

Close https://github.com/zalando/patroni/issues/1981
2021-06-30 09:11:27 +02:00
Alexander KukushkinandGitHub 6616acff58 Postpone writing postgresql.conf when joining running Postgres 12+ (#1956)
When joining already running Postgres, Patroni ensures that config files are set according to expectations.
With recovery parameters converted to GUCs in Postgres v12 it became a little problem, because when the `Postgresql` object is being created it is not yet known where the given replica is supposed to stream from.
It resulted in postgresql.conf first being written without recovery parameters, and on the next run of HA loop Patroni noticing inconsistencies and updating the config one more time.

For Postgres v12 it is not a big issue, but for v13+ it resulted in interruption of streaming replication.
2021-06-30 09:11:12 +02:00
Alexander KukushkinandGitHub f3420e2db5 Compatibility with PostgreSQL 14 (#1926)
PostgreSQL 14 changed the behavior of replicas when certain parameters (like for example `max_connections`) are changed (increased): https://github.com/postgres/postgres/commit/15251c0a.
Instead of immediately exiting Postgres 14 pauses replication and waits for actions from the operator.

Since the `pg_is_wal_replay_paused()` returning `True` is the only indicator of such a change, Patroni on the replica will call the `pg_wal_replay_resume()`, which would cause either continue replication or shutdown (like previously).

So far Patroni was never calling `pg_wal_replay_resume()` on its own, therefore, to remain backward compatible it will call it only for PostgreSQL 14+.
2021-06-25 13:41:45 +02:00
Alexander KukushkinandGitHub 448d703733 Explicitely request cluster version when connecting to etcd via proxy (#1974)
Close https://github.com/zalando/patroni/issues/1971
2021-06-24 08:51:07 +02:00
Alexander KukushkinandGitHub f403719bb4 Reduce chattiness of Patroni logs (#1955)
1. When everything goes normal, only one line will be written for every run of HA loop (see examples):
```
INFO: no action. I am (postgresql0) the leader with the lock
INFO: no action. I am a secondary (postgresql1) and following a leader (postgresql0)
```

2. The `does not have lock` became a debug message.
3. The `Lock owner: postgresql0; I am postgresql1` will be shown only when stream doesn't look normal.
2021-06-22 09:13:30 +02:00
Alexander KukushkinandGitHub 03e71b6717 The /leader endpoint returns 200 if node holds the lock (#1917)
Promoting the standby cluster requires updating load-balancer health checks, which is not very convenient and easy to forget.
In order to solve it, we change the behavior of the `/leader` health-check endpoint. It will return 200 without taking into account whether PostgreSQL is running as the primary or the standby_leader.
2021-06-22 08:21:29 +02:00
Alexander KukushkinandGitHub e5bfd4f5ee Compatibility with psycopg2 2.9+ (#1970)
the autocommit = True is ignored in the `with connection` block
2021-06-17 14:29:10 +02:00
Alexander KukushkinandGitHub 2d504a4f0a Copy the logical slot over if advance failed due to the missing WAL (#1946)
It could happen that the replica for some reason is missing the WAL file required by the replication slot.
The nature of this phenomenon is a bit unclear, it might be that the WAL was recycled short before we copied the slot file, but, we still need a solution to this problem. If the `pg_replication_slot_advance()` fails with the `UndefinedFile` exception (requested WAL segment pg_wal/... has already been removed), the logical slot on the replica must be recreated.
2021-06-02 16:57:13 +02:00
Alexander KukushkinandGitHub eaa98e71e3 Fix bug with unix socket connections (#1933)
When the unix_socket_directories is not known Patroni was immediately going back to tcp connection via the localhost.

The bug was introduced in https://github.com/zalando/patroni/pull/1865
2021-05-10 09:53:25 +02:00
Alexander KukushkinandGitHub 99626a07f2 Fix issues with raft traffic encryption (#1919)
and run raft behave tests with encryption enabled.

Using the new `pysyncobj` release allowed us to get rid of a lot of hacks with accessing private properties and methods of the parent class and reduce the size of the `raft.py`.

Close https://github.com/zalando/patroni/issues/1746
2021-04-30 11:28:41 +02:00
Alexander KukushkinandGitHub 3ae459c6d5 Get rid of false warning about invalid parameter (#1908)
Despite all recovery parameters became GUCs in PostgreSQL 12, there are very good reasons to keep them separated in the Patroni internals.

While implementing PostgreSQL parameters validation in #1674 one little oversight occurred. The parameters validation happens before the recovery parameters are skipped from the list, which produces a false warning.

Close https://github.com/zalando/patroni/issues/1907
2021-04-20 09:40:22 +02:00
Alexander KukushkinandGitHub 51cda9fb6e Fix excessive HA loop runs with Zookeeper (#1875)
1. Commit 04b9fb9dd4 introduced additional conditions for updating cached version of the leader optime. It was required for implementing health-checks based on replication lag in the https://github.com/zalando/patroni/pull/1599.
  What in fact was forgotten, the event should be cleared after the new value of the optime was fetched. Not doing so results in running the HA loop more frequently than is required.
  
2. Don't watch for sync members.
  The watch for sync member(s) was introduced in order to give a signal to the leader that one of the members set the `nosync` tag to true.
  Since that time we have got a few more conditions that should be notified about, therefore instead of watching for all members of the cluster every cluster member checks whether the condition is met, and instead of updating ZNode performs delete+create.
  Since every member is already watching for new ZNodes to be created inside the $scope/members/, they automatically get notified about important changes, and therefore watching for sync members is redundant.

3. In addition to that, slightly increase watch timeout, it will keep HA loops in sync across all nodes in the cluster.
Close https://github.com/zalando/patroni/pull/1873
2021-03-29 08:08:26 +02:00
Alexander KukushkinandGitHub 9edbe7e3f7 Fix little issues with custom bootstrap (#1891)
1. Set hot_standby=off only when we do PITR
2. Restart postgres after PITR is done to avoid warnings
3. Address invalid config issue https://github.com/zalando/patroni/issues/1870#issuecomment-800088643
2021-03-29 08:06:12 +02:00
Alexander KukushkinandGitHub c7173aadd7 Failover logical slots (#1820)
Effectively, this PR consists of a few changes:

1. The easy part:
  In case of permanent logical slots are defined in the global configuration, Patroni on the primary will not only create them, but also periodically update DCS with the current values of `confirmed_flush_lsn` for all these slots.
  In order to reduce the number of interactions with DCS the new `/status` key was introduced. It will contain the json object with `optime` and `slots` keys. For backward compatibility the `/optime/leader` will be updated if there are members with old Patroni in the cluster.

2. The tricky part:
  On replicas that are eligible for a failover, Patroni creates the logical replication slot by copying the slot file from the primary and restarting the replica. In order to copy the slot file Patroni opens a connection to the primary with `rewind` or `superuser` credentials and calls `pg_read_binary_file()`  function.
  When the logical slot already exists on the replica Patroni periodically calls `pg_replication_slot_advance()` function, which allows moving the slot forward.

3. Additional requirements:
  In order to ensure that primary doesn't cleanup tuples from pg_catalog that are required for logical decoding, Patroni enables `hot_standby_feedback` on replicas with logical slots and on cascading replicas if they are used for streaming by replicas with logical slots.

4. When logical slots are copied from to the replica there is a timeframe when it could be not safe to use them after promotion. Right now there is no protection from promoting such a replica. But, Patroni will show the warning with names of the slots that might be not safe to use.

Compatibility.
The `pg_replication_slot_advance()` function is only available starting from PostgreSQL 11. For older Postgres versions Patroni will refuse to create the logical slot on the primary.

The old "permanent slots" feature, which creates logical slots right after promotion and before allowing connections, was removed.

Close: https://github.com/zalando/patroni/issues/1749
2021-03-25 16:18:23 +01:00
Alexander KukushkinandGitHub b341ab2e2f Release 2.0.2 (#1851)
* bump version
* update release notes
* implement missing unit-test
2021-02-22 12:28:19 +01:00
Alexander KukushkinandGitHub b698df374f Fix build (#1843)
run apt-get update before installing packages
2021-02-16 09:34:36 +01:00
Alexander KukushkinandGitHub 9f252d246e Improve handling of concurrent update error (#1796)
The old strategy was waiting for 1 second and hoping that we will get an update event from the WATCH connection.
Unfortunately, it didn't work well in practice. Instead, we will get the current value from the API by performing an explicit read request.

Close https://github.com/zalando/patroni/issues/1767
2021-02-11 15:55:05 +01:00
Alexander KukushkinandGitHub 39332c93ed Treat PATRONI_KUBERNETES_USE_ENDPOINTS env as boolean (#1832)
Close https://github.com/zalando/patroni/issues/1814
2021-02-03 09:44:59 +01:00
Alexander KukushkinandGitHub cdfc4ea50f Handle case with psutil cmdline() returning empty list (#1829)
Close https://github.com/zalando/patroni/issues/1828
2021-02-02 11:48:44 +01:00
Alexander KukushkinandGitHub 6bf205b190 Don't use bypass_api_service when running patronictl (#1830)
It could happen that the cluster role wither not configured or doesn't provide enough permissions. In this case bypass_api_service is ignored, but the warning is logged, which is rather annoying when patronictl is used.
Since the bypass_api_service is most useful for Patroni, we will simply ignore it when patronictl is used.
2021-02-02 11:47:46 +01:00
Alexander KukushkinandGitHub 8b5cb85536 Exit only if authentication explicitly failed (#1806)
It could happen that one of etcd servers is not accessible on Patroni start.
In this case Patroni was trying to perform authentication and exiting, while it should exit only if Etcd explicitly responded with the `AuthFailed` error.

Close https://github.com/zalando/patroni/issues/1805
2021-01-15 14:31:33 +01:00
Alexander KukushkinandGitHub a9f86aa195 Add compatibility with python-consul2 (#1812)
the good old python-consul is not maintained for a few years in a row, therefore someone forked under a different name, but package files are installed into the same location as for the old.

The API of both modules is mostly compatible therefore it wasn't hard to add the support of both modules in Patroni.

Taking into account that python-consul is not a direct requirement for Patroni, but extra, now the end-user has a choice what to install.

Close https://github.com/zalando/patroni/issues/1810
2021-01-15 14:30:48 +01:00
Alexander KukushkinandGitHub 4a8c4cfc53 Make tests more reliable (#1808)
1.  Fix flaky behave tests with zookeeper. First, install/start binaries (zookeeper/localkube) and only after that continue with installing requirements and running behave. Previously zookeeper didn't had enough time to start and tests sometimes were failing.
2.  Fix flaky raft tests. Despite observations of MacOS slowness, for some unknown reason the delete test with a very small timeout was not timing out, but succeeding, causing unit-tests to fail. The solution - do not rely on the actual timeout, but mock it.
2021-01-15 14:29:55 +01:00
Alexander KukushkinandGitHub 8446077fb3 Fixes around pg_rewind (#1794)
1. If the superuser name is different from postgres, the pg_rewind in the standby cluster was failing because the connection string didn't contain the database name.
2. Provide output if the single-user mode recovery failed.

Close https://github.com/zalando/patroni/pull/1736
2020-12-16 19:54:19 +01:00
Alexander KukushkinandGitHub 94b9f8fae6 Silence unhandled exceptions in Thread.run() during unit-tests (#1802)
Python 3.8 changed the way how exceptions raised from the Thread.run() method are handled.
It resulted in unit-tests showing a couple of warnings. They are not important and we just silence them.
2020-12-16 19:37:51 +01:00
Alexander KukushkinandGitHub df9cadcdc4 Handle AttributeError in etcd.py (#1801)
When the__del__() method is executed the python interpreter already unloaded some of the modules that are still used down the http.clear() method.
The only we could do in this case - silence some exceptions like ReferenceError, TypeError, AttributeError.

Close https://github.com/zalando/patroni/issues/1785
2020-12-16 19:23:56 +01:00
Alexander KukushkinandGitHub 9b263dc6c9 Move find_executable to utils (#1799)
We don't want to import the whole patroni.ctl into the patroni
2020-12-16 18:58:54 +01:00
Alexander KukushkinandGitHub 3a87d0e99b Implement missing validators for etcd3 and raft (#1798)
Close https://github.com/zalando/patroni/issues/1771
2020-12-16 18:44:58 +01:00
Alexander KukushkinandGitHub 89a15a2df4 Fix small issues with ignore-slots feature (#1797)
When there is no config key in DCS Patroni shouldn't try accessing ignore_slots, otherwise an exception is raised.

In addition to that implement missing unit-tests and fix linting issues in behave tests.
2020-12-16 18:10:12 +01:00
Alexander KukushkinandGitHub 61bf412ac6 Fix bug in the post_bootstrap method() (#1795)
The config.write_pgpass(r) should be called unconditionally, no matter whether the password defined in the config or not.

Close https://github.com/zalando/patroni/issues/1727
2020-12-16 17:33:44 +01:00
Alexander KukushkinandGitHub a43baece68 Submit coverage to codacy only if secret is available (#1791)
If PR is open from the external GH repo secrets are not set due to security reasons. It makes codacy coverage report to fail.
2020-12-14 15:49:37 +01:00
Alexander KukushkinandGitHub e3ef9ac306 Fix issues with zookeeper (#1792)
1. The `ttl` was incorrectly returned 1000 times higher then it should
2. The `watch()` method must return True if the parent method returned True. Not doing so resulted in the incorrect calculation of sleep time.
3. Move mock of exhibitor api to the features/environment.py. It simplifies testing with behave.
2020-12-14 15:12:57 +01:00
Alexander KukushkinandGitHub 1530ed0b9c Switch to GH actions (#1778)
it allows up to 20 parallel builds
2020-12-04 21:52:34 +01:00
Alexander KukushkinandGitHub e8e87bf0a1 Don't interrupt restart or promote if lost leader lock in pause (#1726)
In pause it is allowed to run postgres as master without lock.
2020-10-08 08:56:53 +02:00
Alexander KukushkinandGitHub 311e5ccc5b Release 2.0.1 (#1722)
* Bump version
* Update release notes
2020-10-01 15:18:53 +02:00
Alexander KukushkinandGitHub fa88d80c4f Apply master_start_timeout when executing crash recovery (#1720)
It is not very common, but the master Postgres might "crash" due to different reasons, like OOM, or out of disk space. Of course, there are chances that the current node holds some unreplicated data and therefore Patroni by default prefers to start Postgres on the leader node rather than doing a failover.

In order to be on the safe side Patroni always starts Postgres in recovery no matter whether the current node owns the leader lock or not. If the Postgres wasn't shut down cleanly, starting in recovery might fail, therefore in some cases as a workaround Patroni is executing a crash recovery by starting the postgres up in the single-user mode.

A few times we end up in the situation:
1. Master postgres crashed due to the out of disk space
2. Patroni starts crash recovery in a single-user mode
3. While doing crash-recovery Patroni keeps updating the leader lock

It makes Patroni stuck on step 3 and the manual intervention is required for recovering the cluster.

Patroni already has the option `master_start_timeout`, which controls for how long we let postgres stay in the `starting` state and after that Patroni might decide to release the leader lock if there are healthy replicas available which could take it over.

This PR makes the `master_start_timeout` option also work for crash recovery.
2020-09-30 08:04:27 +02:00
Alexander KukushkinandGitHub 2c5d62bf10 Workaround unittest bug and fix requirements (#1718)
* unittest bug: https://bugs.python.org/issue25532
* `urllib3[secure]` wrongly depends on `ipaddress` for python3, while in fact we don't need all dependencies of the `secure` extra, but only `ipaddress` for the `kubernetes` on python2.7 

Close https://github.com/zalando/patroni/issues/1717
Close https://github.com/zalando/patroni/issues/1709
2020-09-29 15:15:58 +02:00
Alexander KukushkinandGitHub 885d226dac Add support of raft bind_add and password (#1713)
Close https://github.com/zalando/patroni/issues/1705
2020-09-28 11:05:07 +02:00
Alexander KukushkinandGitHub fa6c396589 Fix bug in the get_guc_value() (#1712)
The `-D` parameter was forgotten.
2020-09-23 13:33:54 +02:00
Alexander KukushkinandGitHub 8a8409999d Change the behavior in pause (#1687)
1. Don't call bootstrap if PGDATA is missing/empty, because it might be for purpose, and someone/something working on it.
2. Consider postgres running as a leader in pause not healthy if pg_control sysid doesn't match with the /initialize key (empty initialize key will allow the "race" and the leader will "restore" initialize key).
3. Don't exit on sysid mismatch in pause, only log a warning.
4. Cover corner cases when Patroni started in pause with empty PGDATA and it was restored by somebody else
5. Empty string is a valid `recovery_target`.
2020-09-18 08:25:00 +02:00
Alexander KukushkinandGitHub 6706decc1c Fix hanging patronictl when RAFT is being used (#1697)
Close #1694
2020-09-16 14:03:40 +02:00