Skip to content

Commit

Permalink
Release 2.1.3 (patroni#2219)
Browse files Browse the repository at this point in the history
* Implement missing unit-tests
* Bump version
* Update release notes
  • Loading branch information
Alexander Kukushkin authored Feb 18, 2022
1 parent aa91557 commit 333d41d
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 3 deletions.
66 changes: 66 additions & 0 deletions docs/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,72 @@
Release notes
=============

Version 2.1.3
-------------

**New features**

- Added support for encrypted TLS keys for ``patronictl`` (Alexander Kukushkin)

It could be configured via ``ctl.keyfile_password`` or the ``PATRONI_CTL_KEYFILE_PASSWORD`` environment variable.

- Added more metrics to the /metrics endpoint (Alexandre Pereira)

Specifically, ``patroni_pending_restart`` and ``patroni_is_paused``.

- Make it possible to specify multiple hosts in the standby cluster configuration (Michael Banck)

If the standby cluster is replicating from the Patroni cluster it might be nice to rely on client-side failover which is available in ``libpq`` since PostgreSQL v10. That is, the ``primary_conninfo`` on the standby leader and ``pg_rewind`` setting ``target_session_attrs=read-write`` in the connection string. The ``pgpass`` file will be generated with multiple lines (one line per host), and instead of calling ``CHECKPOINT`` on the primary cluster nodes the standby cluster will wait for ``pg_control`` to be updated.

**Stability improvements**

- Compatibility with legacy ``psycopg2`` (Alexander)

For example, the ``psycopg2`` installed from Ubuntu 18.04 packages doesn't have the ``UndefinedFile`` exception yet.

- Restart ``etcd3`` watcher if all Etcd nodes don't respond (Alexander)

If the watcher is alive the ``get_cluster()`` method continues returning stale information even if all Etcd nodes are failing.

- Don't remove the leader lock in the standby cluster while paused (Alexander)

Previously the lock was maintained only by the node that was running as a primary and not a standby leader.

**Bugfixes**

- Fixed bug in the standby-leader bootstrap (Alexander)

Patroni was considering bootstrap as failed if Postgres didn't start accepting connections after 60 seconds. The bug was introduced in the 2.1.2 release.

- Fixed bug with failover to a cascading standby (Alexander)

When figuring out which slots should be created on cascading standby we forgot to take into account that the leader might be absent.

- Fixed small issues in Postgres config validator (Alexander)

Integer parameters introduced in PostgreSQL v14 were failing to validate because min and max values were quoted in the validator.py

- Use replication credentials when checking leader status (Alexander)

It could be that the ``remove_data_directory_on_diverged_timelines`` is set, but there is no ``rewind_credentials`` defined and superuser access between nodes is not allowed.

- Fixed "port in use" error on REST API certificate replacement (Ants Aasma)

When switching certificates there was a race condition with a concurrent API request. If there is one active during the replacement period then the replacement will error out with a port in use error and Patroni gets stuck in a state without an active API server.

- Fixed a bug in cluster bootstrap if passwords contain ``%`` characters (Bastien Wirtz)

The bootstrap method executes the ``DO`` block, with all parameters properly quoted, but the ``cursor.execute()`` method didn't like an empty list with parameters passed.

- Fixed the "AttributeError: no attribute 'leader'" exception (Hrvoje Milković)

It could happen if the synchronous mode is enabled and the DCS content was wiped out.

- Fix bug in divergence timeline check (Alexander)

Patroni was falsely assuming that timelines have diverged. For pg_rewind it didn't create any problem, but if pg_rewind is not allowed and the ``remove_data_directory_on_diverged_timelines`` is set, it resulted in reinitializing the former leader.


Version 2.1.2
-------------

Expand Down
2 changes: 1 addition & 1 deletion patroni/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ def _set_section_values(section, params):
_set_section_values('restapi', ['listen', 'connect_address', 'certfile', 'keyfile', 'keyfile_password',
'cafile', 'ciphers', 'verify_client', 'http_extra_headers',
'https_extra_headers', 'allowlist', 'allowlist_include_members'])
_set_section_values('ctl', ['insecure', 'cacert', 'certfile', 'keyfile'])
_set_section_values('ctl', ['insecure', 'cacert', 'certfile', 'keyfile', 'keyfile_password'])
_set_section_values('postgresql', ['listen', 'connect_address', 'config_dir', 'data_dir', 'pgpass', 'bin_dir'])
_set_section_values('log', ['level', 'traceback_level', 'format', 'dateformat', 'max_queue_size',
'dir', 'file_size', 'file_num', 'loggers'])
Expand Down
2 changes: 1 addition & 1 deletion patroni/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.1.2'
__version__ = '2.1.3'
3 changes: 2 additions & 1 deletion tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ def setUp(self):
'krbsrvname': 'postgres', 'pgpass': os.path.join(data_dir, 'pgpass0'),
'listen': '127.0.0.2, 127.0.0.3:5432', 'connect_address': '127.0.0.2:5432',
'authentication': {'superuser': {'username': 'foo', 'password': 'test'},
'replication': {'username': '', 'password': 'rep-pass'}},
'replication': {'username': '', 'password': 'rep-pass'},
'rewind': {'username': 'rewind', 'password': 'test'}},
'remove_data_directory_on_rewind_failure': True,
'use_pg_rewind': True, 'pg_ctl_timeout': 'bla',
'parameters': self._PARAMETERS,
Expand Down
5 changes: 5 additions & 0 deletions tests/test_rewind.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ def test__get_local_timeline_lsn(self):
@patch.object(Postgresql, 'start', Mock())
def test_execute(self, mock_checkpoint):
self.r.execute(self.leader)
with patch.object(Postgresql, 'major_version', PropertyMock(return_value=130000)):
self.r.execute(self.leader)
with patch.object(MockCursor, 'fetchone', Mock(side_effect=Exception)):
self.r.execute(self.leader)

with patch.object(Rewind, 'pg_rewind', Mock(return_value=False)):
mock_checkpoint.side_effect = ['1', '', '', '']
self.r.execute(self.leader)
Expand Down

0 comments on commit 333d41d

Please sign in to comment.