Skip to content

Commit

Permalink
Do not deop PS connections of config reload if connection strings are…
Browse files Browse the repository at this point in the history
… not changed
  • Loading branch information
Konstantin Knizhnik committed Nov 29, 2023
1 parent a6e6cb0 commit c6ac0a1
Showing 1 changed file with 40 additions and 26 deletions.
66 changes: 40 additions & 26 deletions pgxn/neon/libpagestore.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ typedef struct
static ShardMap* shard_map;
static LWLockId shard_map_lock;
static size_t shard_map_update_counter;
static bool config_updated;

typedef struct
{
Expand Down Expand Up @@ -113,7 +114,7 @@ psm_shmem_startup(void)
{
shard_map_lock = (LWLockId)GetNamedLWLockTranche("shard_map_lock");
shard_map->n_shards = 0;
shard_map->update_counter = 0;
shard_map->update_counter = 1; /* force update of shared map on forst access */
}
LWLockRelease(AddinShmemInitLock);
}
Expand Down Expand Up @@ -150,46 +151,65 @@ static shardno_t
load_shard_map(shardno_t shard_no, char* connstr)
{
shardno_t n_shards;

bool exclusive_lock = false;
LWLockAcquire(shard_map_lock, LW_SHARED);

while (shard_map->n_shards == 0 || shard_map_update_counter != shard_map->update_counter)
if (shard_map_update_counter != shard_map->update_counter || config_updated)
{
/* Close all existed connections */
for (shardno_t i = 0; i < max_attached_shard_no; i++)
{
if (page_servers[i].conn)
pageserver_disconnect(i);
}

/* Request new shard map from control plane under exclusive lock */
LWLockRelease(shard_map_lock);
LWLockAcquire(shard_map_lock, LW_EXCLUSIVE);
if (shard_map->n_shards == 0)
ParseConnString:
{
char const* shard_connstr = page_server_connstring;
char const* sep;
size_t connstr_len;
int i = 0;
bool shard_map_changed = false;
do
{
sep = strchr(shard_connstr, ',');
connstr_len = sep != NULL ? sep - shard_connstr : strlen(shard_connstr);
if (connstr_len == 0)
break; /* trailing comma */
if (shard_map->n_shards >= MAX_SHARDS)
if (i >= MAX_SHARDS)
elog(ERROR, "Too many shards");
if (connstr_len >= MAX_PS_CONNSTR_LEN)
elog(ERROR, "Connection string too long");
memcpy(shard_map->shard_connstr[shard_map->n_shards++], shard_connstr, connstr_len+1);
if (i >= shard_map->n_shards ||
strcmp(shard_map->shard_connstr[i], shard_connstr) != 0)
{
if (!exclusive_lock)
{
/* Retry under exclsuive lock */
LWLockRelease(shard_map_lock);
LWLockAcquire(shard_map_lock, LW_EXCLUSIVE);
exclusive_lock = true;
goto ParseConnString;
}
shard_map_changed = true;
memcpy(shard_map->shard_connstr[i], shard_connstr, connstr_len+1);
}
shard_connstr = sep + 1;
i += 1;
} while (sep != NULL);

if (shard_map->n_shards == 0)
if (i == 0)
elog(ERROR, "No shards were speciified");

shard_map->update_counter += 1;
if (shard_map_changed)
{
shard_map->update_counter += 1;
shard_map->n_shards = i;
}
}
shard_map_update_counter = shard_map->update_counter;
if (shard_map_update_counter != shard_map->update_counter)
{
for (shardno_t i = 0; i < max_attached_shard_no; i++)
{
if (page_servers[i].conn)
pageserver_disconnect(i);
}
shard_map_update_counter = shard_map->update_counter;
}
config_updated = false;
}
n_shards = shard_map->n_shards;
if (shard_no >= n_shards)
Expand Down Expand Up @@ -561,13 +581,7 @@ check_neon_id(char **newval, void **extra, GucSource source)
static void
AssignPageserverConnstring(const char *newval, void *extra)
{
if (shard_map)
{
/* Force releoading of shard map */
LWLockAcquire(shard_map_lock, LW_EXCLUSIVE);
shard_map->n_shards = 0;
LWLockRelease(shard_map_lock);
}
config_updated = true;
}

/*
Expand Down

0 comments on commit c6ac0a1

Please sign in to comment.