]> git.proxmox.com Git - pmg-api.git/commitdiff
fix #5189: cluster: avoid sync errors for statistics and quarantine
authorFriedrich Weber <f.weber@proxmox.com>
Thu, 22 Feb 2024 16:35:35 +0000 (17:35 +0100)
committerStoiko Ivanov <s.ivanov@proxmox.com>
Thu, 22 Feb 2024 21:10:07 +0000 (22:10 +0100)
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 <f.weber@proxmox.com>
src/PMG/DBTools.pm

index 6112566b414f6d03c90c8889af95bd5d70ac987b..8770d06554e1c9e90b5f6fa7f0ddc590d4efe687 100644 (file)
@@ -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 {