From c8fa62e42412c92c97fd143a18a7704e4894193b Mon Sep 17 00:00:00 2001 From: Friedrich Weber Date: Thu, 22 Feb 2024 17:35:35 +0100 Subject: [PATCH] fix #5189: cluster: avoid sync errors for statistics and quarantine After restoring a backup from a cluster on a fresh node with statistics, and then creating a cluster, the following can happen (node 1 being master and node 2 being a node): `ClusterInfo` on node 1 has no record about the last-synchronized `CStatistic` row id of node 2. Thus, pmgmirror on node 1 initializes the record with -1 and tries to synchronize *all* `CStatistic` rows with cid 2 from node 2. But (some of) these rows may already exist on cid 1, because they were part of the backup, so pmgmirror on node 1 triggers a Postgres unique constraint violation, statistics synchronization on node 1 fails, and node 1 remains in the "synchronizing" state. Fix this as follows: When a new node is added to a cluster, the master now initializes its `ClusterInfo` record of the last-synchronized `CStatistic` row id for that node cid with the maximum row id that exists in the local `CStatistic` for that node cid, or with -1 if the local `CStatistic` has no row for that node cid. This is valid because the newly-added node copies the master's `CStatistic` table during cluster join. Do the same for the `CMailStore` table, where a similar sync error could happen e.g. if the table has rows for both node cids, node 2 is shut down and manually deleted from the cluster.conf, the maxcid is manually reset to 1, and a fresh node is joined to the cluster and gets assigned cid 2. Signed-off-by: Friedrich Weber --- src/PMG/DBTools.pm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/PMG/DBTools.pm b/src/PMG/DBTools.pm index 6112566..8770d06 100644 --- a/src/PMG/DBTools.pm +++ b/src/PMG/DBTools.pm @@ -1132,6 +1132,14 @@ sub update_master_clusterinfo { $dbh->do ("INSERT INTO ClusterInfo (cid, name, ivalue) select $clientcid, 'lastmt_$table', " . "EXTRACT(EPOCH FROM now())::INTEGER"); } + + my @lastid_tables = ('CStatistic', 'CMailStore'); + + for my $table (@lastid_tables) { + $dbh->do("INSERT INTO ClusterInfo (cid, name, ivalue) " . + "SELECT $clientcid, 'lastid_$table', COALESCE (max (rid), -1) FROM $table " . + "WHERE cid = $clientcid"); + } } sub update_client_clusterinfo { -- 2.39.5