Citus auf SmartOS übersetzen

In Patroni Cluster im Container hatte ich ja schon mit Patroni in SmartOS Zonen experimentiert. Mit der Version 3.0 unterstützt Patroni ja jetzt auch Citus, was den Aufbau von Sharded Postgres Clustern deutlich vereinfachen sollte. Gerade war ja auch der Citus Con, auf dem Alexander Kukushkin einen schönen Vortrag zu dem Thema gehalten hat

Citus Con 2023 Youtube Stream

Ich bin auf Citus aufmerksam geworden, weil es "unter" der Britischen Corona Site im Einsatz war/ist und dort extreme Requestzahlen ermöglicht hat.

Die Citus Architektur ist relativ einfach. Ein "Coordinator" nimmt Requests entgegen und teilt sie auf die "Worker" oder Shards auf.

Citus Architekturdiagramm von der Citus Dokumentationsseite

Ein wichtiger Faktor bei Datenbanken, die mit Shards arbeiten, ist das sogenannte "Rebalancing". Dies muß durchgeführt werden, wenn Shards hinzukommen oder entfernt werden. Dabei werden die Daten auf den Shards etwas umverteilt, damit sich die Last wieder möglichst gleich verteilen kann. Bei Citus ist das Rebalancing im laufenden Betrieb möglich.

Mit Patroni ist es relativ einfach möglich, das obige Konstrukt "hochausfallsicher" zu gestalten. Konkret werden damit Coordinator und Worker jeweils als HA-Pärchen ausgerollt und von Patroni ein Failover zwischen den jeweiligen Clusterknoten organisiert, wenn einer ausfallen sollte.

In der oben aufgeführten Patroni Dokumentation sieht das dann z. B. so aus (wobei sogar drei Knoten für den Coordinator Cluster verwendet werden):

postgres@coord1:~$ patronictl list demo
+ Citus cluster: demo ----------+--------------+---------+----+-----------+
| Group | Member  | Host        | Role         | State   | TL | Lag in MB |
+-------+---------+-------------+--------------+---------+----+-----------+
|     0 | coord1  | 172.27.0.10 | Replica      | running |  1 |         0 |
|     0 | coord2  | 172.27.0.6  | Sync Standby | running |  1 |         0 |
|     0 | coord3  | 172.27.0.4  | Leader       | running |  1 |           |
|     1 | work1-1 | 172.27.0.8  | Sync Standby | running |  1 |         0 |
|     1 | work1-2 | 172.27.0.2  | Leader       | running |  1 |           |
|     2 | work2-1 | 172.27.0.5  | Sync Standby | running |  1 |         0 |
|     2 | work2-2 | 172.27.0.7  | Leader       | running |  1 |           |
+-------+---------+-------------+--------------+---------+----+-----------+

Wenn man Citus für SmartOS übersetzen möchte (natürlich wird SmartOS (noch) nicht bei den unterstützten Betriebssystemen aufgeführt), gelingt das zunächst nicht, weil der Übersetzungsvorgang (wir erinnern uns: configure, make, make install) mit einem Fehler abbricht

commands/multi_copy.c: In function 'CreateLocalColocatedIntermediateFile':
commands/multi_copy.c:2695:24: error: 'S_IRUSR' undeclared (first use in this function)
2695 |  const int fileMode = (S_IRUSR | S_IWUSR);

Das läßt sich aber beheben, in dem man #include "sys/stat.h" zu den Includes am Anfang von multi_copy.c hinzufügt. Danach übersetzt Citus ohne weitere Probleme auf SmartOS und kann mit make install installiert werden.

Danach sollte es dann auch in der Liste der verfügbaren Postgres Extensions (\dx) auftauchen. Es kann aber leider nicht dynamisch geladen werden sondern erfordert einen Neustart der Datenbank, nachdem man es in der postgresql.conf unter shared_preload_libraries = 'citus' aufgeführt hat. Z. B. so

echo "shared_preload_libraries = 'citus'" >> citus/coordinator/postgresql.conf
echo "shared_preload_libraries = 'citus'" >> citus/worker1/postgresql.conf
echo "shared_preload_libraries = 'citus'" >> citus/worker2/postgresql.conf