fix(cluster): node-lokale Tabellen aus Drift-Hash entfernen — v1.2.89
network_interfaces + ip_addresses standen in confighash hashSpec, aber in cluster_replication.go localOnlyTables (= nicht repliziert, node-spezifische IPs). Dadurch waren die config_hash-Werte zweier Nodes ZWANGSLÄUFIG dauerhaft verschieden → Drift-Banner, das kein Resync beheben konnte. Beide Tabellen aus dem Hash entfernt; Drift erkennt jetzt nur noch wirklich replizierte Service-Config. Muss auf BEIDEN Nodes installiert sein (gleicher hashSpec für vergleichbare Hashes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -71,33 +71,16 @@ var hashSpec = []hashTable{
|
|||||||
|
|
||||||
{Name: "ntp_pools", MigrationDefault: true},
|
{Name: "ntp_pools", MigrationDefault: true},
|
||||||
|
|
||||||
// network_interfaces + ip_addresses werden seit 0030 repliziert —
|
// network_interfaces + ip_addresses sind BEWUSST NICHT im Drift-Hash.
|
||||||
// VLAN/Bridge/Bond-Definitionen und Gateway-IPs müssen auf dem Secondary
|
// Sie stehen in cluster_replication.go localOnlyTables, werden also NICHT
|
||||||
// für Failover bereitstehen. Ethernet-IPs werden im Secondary-Renderer
|
// repliziert und sind per Design node-spezifisch (jede Node hat eigene
|
||||||
// herausgefiltert (eth0 = cloud-init / Keepalived).
|
// Mgmt-/Host-IPs, z.B. utm-1=.6, utm-2=.8). Würde man sie hashen, wäre
|
||||||
|
// der config_hash zwischen zwei Nodes ZWANGSLÄUFIG dauerhaft verschieden
|
||||||
|
// → Drift-Banner, das kein Resync je beheben kann (Resync kopiert nur
|
||||||
|
// replizierte Tabellen). Migration 0030 wollte sie zwar replizieren,
|
||||||
|
// localOnlyTables schließt sie aber weiter aus → wir hashen sie nicht.
|
||||||
//
|
//
|
||||||
// ip_addresses.interface_id ist ein node-lokaler Autoincrement-PK, der
|
// static_routes, dns_settings, ntp_settings bleiben ebenfalls node-spezifisch.
|
||||||
// zwischen zwei unabhängigen DBs divergiert (utm-1: eth0=6, utm-2: eth0=1).
|
|
||||||
// Wir hashen daher semantisch: address + prefix + flags + interface_name
|
|
||||||
// statt interface_id — sonst False-Positive-Drift auf logisch identischen Nodes.
|
|
||||||
{Name: "network_interfaces"},
|
|
||||||
{Name: "ip_addresses", CustomSQL: `
|
|
||||||
SELECT COALESCE(md5(string_agg(rh, '|' ORDER BY rh)), '')
|
|
||||||
FROM (
|
|
||||||
SELECT md5(jsonb_build_object(
|
|
||||||
'address', ia.address,
|
|
||||||
'prefix', ia.prefix,
|
|
||||||
'is_vip', ia.is_vip,
|
|
||||||
'active', ia.active,
|
|
||||||
'vip_priority', ia.vip_priority,
|
|
||||||
'description', ia.description,
|
|
||||||
'iface', ni.name
|
|
||||||
)::text) AS rh
|
|
||||||
FROM ip_addresses ia
|
|
||||||
JOIN network_interfaces ni ON ia.interface_id = ni.id
|
|
||||||
) sub`},
|
|
||||||
|
|
||||||
// static_routes, dns_settings, ntp_settings bleiben node-spezifisch.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// hashSQL rendert die SHA-Input-SQL für eine Tabelle.
|
// hashSQL rendert die SHA-Input-SQL für eine Tabelle.
|
||||||
|
|||||||
Reference in New Issue
Block a user