mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-24 08:30:37 +00:00
Add neon.safekeeper_connstrings GUC
This GUC is very similar to neon.safekeepers, but instead of being formatted as host:port, it is a Postgres connection string. The purpose for changing how we connect to safekeepers is so that we can pass various libpq SSL keyword parameters in the connection string. A future PR will remove the `neon.safekeepers` GUC. Signed-off-by: Tristan Partin <tristan@neon.tech>
This commit is contained in:
@@ -49,9 +49,9 @@ def test_safekeepers_reconfigure_reorder(
|
||||
old_sks = ""
|
||||
with closing(endpoint.connect()) as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("SHOW neon.safekeepers")
|
||||
cur.execute("SHOW neon.safekeeper_connstrings")
|
||||
res = cur.fetchone()
|
||||
assert res is not None, "neon.safekeepers GUC is set"
|
||||
assert res is not None, "neon.safekeeper_connstrings GUC is set"
|
||||
old_sks = res[0]
|
||||
|
||||
# Reorder safekeepers
|
||||
@@ -62,9 +62,9 @@ def test_safekeepers_reconfigure_reorder(
|
||||
|
||||
with closing(endpoint.connect()) as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("SHOW neon.safekeepers")
|
||||
cur.execute("SHOW neon.safekeeper_connstrings")
|
||||
res = cur.fetchone()
|
||||
assert res is not None, "neon.safekeepers GUC is set"
|
||||
assert res is not None, "neon.safekeeper_connstrings GUC is set"
|
||||
new_sks = res[0]
|
||||
|
||||
assert new_sks != old_sks, "GUC changes were applied"
|
||||
|
||||
@@ -14,7 +14,7 @@ from contextlib import closing
|
||||
from dataclasses import dataclass, field
|
||||
from functools import partial
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, cast
|
||||
|
||||
import psycopg2
|
||||
import psycopg2.errors
|
||||
@@ -685,7 +685,7 @@ class ProposerPostgres(PgProtocol):
|
||||
f"neon.timeline_id = '{self.timeline_id}'\n",
|
||||
f"neon.tenant_id = '{self.tenant_id}'\n",
|
||||
"neon.pageserver_connstring = ''\n",
|
||||
f"neon.safekeepers = '{safekeepers}'\n",
|
||||
f"neon.safekeeper_connstrings = '{safekeepers}'\n",
|
||||
f"listen_addresses = '{self.listen_addr}'\n",
|
||||
f"port = '{self.port}'\n",
|
||||
]
|
||||
@@ -1464,7 +1464,15 @@ class SafekeeperEnv:
|
||||
|
||||
def get_safekeeper_connstrs(self):
|
||||
assert self.safekeepers is not None, "safekeepers are not initialized"
|
||||
return ",".join([sk_proc.args[2] for sk_proc in self.safekeepers])
|
||||
|
||||
def to_connstring(proc: subprocess.CompletedProcess[Any]) -> str:
|
||||
"""
|
||||
Parse <host>:<port> string into Postgres connection string
|
||||
"""
|
||||
(host, port, *_) = cast("str", proc.args[2]).split(":")
|
||||
return f"host={host} port={port}"
|
||||
|
||||
return ",".join([to_connstring(sk_proc) for sk_proc in self.safekeepers])
|
||||
|
||||
def create_postgres(self):
|
||||
assert self.tenant_id is not None, "tenant_id is not initialized"
|
||||
@@ -2000,8 +2008,9 @@ def test_membership_api(neon_env_builder: NeonEnvBuilder):
|
||||
|
||||
def test_explicit_timeline_creation(neon_env_builder: NeonEnvBuilder):
|
||||
"""
|
||||
Test that having neon.safekeepers starting with g#n: with non zero n enables
|
||||
generations, which as a side effect disables automatic timeline creation.
|
||||
Test that having neon.safekeeper_connstrings starting with g#n: with non
|
||||
zero n enables generations, which as a side effect disables automatic
|
||||
timeline creation.
|
||||
|
||||
This is kind of bootstrapping test: here membership conf & timeline is
|
||||
created manually, later storcon will do that.
|
||||
@@ -2032,10 +2041,10 @@ def test_explicit_timeline_creation(neon_env_builder: NeonEnvBuilder):
|
||||
|
||||
def test_explicit_timeline_creation_storcon(neon_env_builder: NeonEnvBuilder):
|
||||
"""
|
||||
Test that having neon.safekeepers starting with g#n: with non zero n enables
|
||||
generations, which as a side effect disables automatic timeline creation.
|
||||
Like test_explicit_timeline_creation, but asks the storcon to
|
||||
create membership conf & timeline.
|
||||
Test that having neon.safekeeper_connstrings starting with g#n: with non
|
||||
zero n enables generations, which as a side effect disables automatic
|
||||
timeline creation. Like test_explicit_timeline_creation, but asks the
|
||||
storcon to create membership conf & timeline.
|
||||
"""
|
||||
neon_env_builder.num_safekeepers = 3
|
||||
neon_env_builder.storage_controller_config = {
|
||||
|
||||
@@ -711,10 +711,10 @@ async def run_quorum_sanity(env: NeonEnv):
|
||||
await quorum_sanity_single(env, [2, 3, 4], [1, 2, 3], [2, 3, 4], [2], False)
|
||||
|
||||
|
||||
# Test various combinations of membership configurations / neon.safekeepers
|
||||
# (list of safekeepers endpoint connects to) values / up & down safekeepers and
|
||||
# check that endpont can start and write data when we have quorum and can't when
|
||||
# we don't.
|
||||
# Test various combinations of membership configurations /
|
||||
# neon.safekeeper_connstrings (list of safekeeper connection strings) values /
|
||||
# up & down safekeepers and check that endpont can start and write data when we
|
||||
# have quorum and can't when we don't.
|
||||
def test_quorum_sanity(neon_env_builder: NeonEnvBuilder):
|
||||
neon_env_builder.num_safekeepers = 4
|
||||
env = neon_env_builder.init_start()
|
||||
|
||||
Reference in New Issue
Block a user