Channel Apps

navigation

BlogAnleitungen/TutorialsLese-Log
📝 Artikel pro Kategorie: Android: (1) Datenbank: (6) Fediverse: (1) GrapheneOS: (1) Hubzilla: (14) Linux: (4) Nextcloud: (1) Terminal: (4) Tutorials: (13)

📚 Bücher pro Kategorie: Belletristik: (1) Holocaust: (2) Lese-Log: (8) Psychothriller: (2) Thriller: (3)
lima-city: Webhosting, Domains und Cloud

Hubzilla: Datenbank verkleinern und aufblähen verhindern

Ein Erfahrungsbericht

★Geschrieben von einem verwundertem Hubzilla-Admin★

Hinweis: Alle SQL-Operationen wurden mit Backup durchgeführt. Bitte immer zuerst ein Backup der Datenbank erstellen bevor man Eingriffe vornimmt.

Das Problem

Ich bin Hubzilla-Anfänger, meine Instanz habe ich Mitte Februar aufgesetzt. Nach ziemlich genau einem Monat hatte sie bereits eine Größe von über 3,4 GB, was ja jetzt nicht tragisch ist wenn man bedenkt was alles an importierten Inhalten als Blob gespeichert wird. Aber ich hab mir das mal hochgerechnet und dachte: In 6 Monaten ist so dann mein 20 GB-Datenbankspeicher voll.

Der Cron-Job schien also nicht das zu tun was man erwartet, OPTIMIZE TABLE in MySQL brachte auch nichts. Ich hatte im Admin-Menü eine Ablaufzeit von 4 Tagen eingestellt, mir schien logisch, jetzt niedriger eingestellt, desto eher werden Inhalte gelöscht – aber die Datenbank wuchs trotzdem unaufhörlich. Ich dachte, muss ich wohl den öffentlichen Stream deaktivieren, was ich aber auch nicht wollte.

Nach einer Recherche und Analyse habe ich wohl die Ursache gefunden. Und ich versuche das jetzt mal zu dokumentieren.

Die Ursache: Drei versteckte Probleme

Problem 1: Das Admin-Menü setzt den falschen Konfigurationsschlüssel
Im Admin-Menü unter /admin/site kann man eine Ablaufzeit für Inhalte einstellen. Ich hatte dort 4 Tage eingetragen – in der Überzeugung, dass alte Fremdinhalte oder eigene nach 4 Tagen gelöscht werden. Die Formulierung war mit nicht so ganz klar.
Was das Admin-Menü wirklich tut: Es setzt default_expire_days und active_expire_days. Der Expire-Daemon der für föderierte Fremdinhalte zuständig ist liest aber sys_expire_days – und dieser Wert war bei mir leer, also 0, somit „niemals löschen”.

Das kann man nur per Kommandozeile prüfen:
php util/config system sys_expire_days

Ergebnis: config[system][sys_expire_days] = (leer!)

Während im Admin-Menü alles korrekt aussah, hat der Daemon seit Wochen nichts gelöscht.

Problem 2: expire_limit war zu niedrig
Der Expire-Daemon löscht standardmäßig nur 5.000 Einträge pro Cron-Lauf. Bei einer Datenbank mit über 87.000 angesammelten Remote-Items hätte das Monate gedauert – vorausgesetzt sys_expire_days wäre überhaupt gesetzt gewesen.

Problem 3: InnoDB gibt Speicher nicht automatisch frei
Selbst wenn Einträge als gelöscht markiert werden, gibt MySQL/InnoDB den Speicherplatz nicht automatisch ans Betriebssystem zurück. Dafür ist OPTIMIZE TABLE nötig – aber das war ebenfalls deaktiviert.

Die Diagnose

Zuerst habe ich mir die größten Tabellen angeschaut:

SELECT table_name,
ROUND(data_length/1024/1024, 2) AS data_mb,
ROUND((data_length+index_length)/1024/1024, 2) AS total_mb
FROM information_schema.tables
WHERE table_schema = 'MEINE_DB'
ORDER BY (data_length+index_length) DESC LIMIT 10;

Ergebnis bei mir:
tabelle1.png

Gesamt: über 3,4 GB – und das auf einer kleinen privaten Einzel-Instanz nach 4 Wochen.
Dann habe ich geprüft wie viele Remote-Items sich angesammelt hatten:

SELECT COUNT(*) FROM item WHERE item_origin = 0;

-- Ergebnis: 87.633

SELECT COUNT(*) FROM item 
WHERE item_origin = 0 
AND created < DATE_SUB(NOW(), INTERVAL 5 DAY);

-- Ergebnis: 64.727 (hätten längst gelöscht sein sollen!)
64.727 Items die laut meiner Admin-Einstellung hätten gelöscht sein sollen – aber nie gelöscht wurden.

Die Lösung

Schritt 1:

Die fehlenden Konfigurationswerte über SSH setzen
cd /pfad/zu/hubzilla

DER wichtigste Befehl – das war die Hauptursache:
php util/config system sys_expire_days 30

Expire-Limit erhöhen damit der Daemon schneller arbeitet:
php util/config system expire_limit 50000

OPTIMIZE automatisch nach dem Löschen ausführen:
php util/config system optimize_items 1

Lieferberichte deaktivieren (für mich unnötig, frisst Platz):
php util/config system disable_dreport 1

Zur Kontrolle aller Werte:
php util/config system | grep -i expire

-- Ausgabe SSH:
php util/config system | grep -i expire

config[system][register_expire] = 3d
config[system][default_expire_days] = 30
config[system][active_expire_days] = 30
config[system][last_expire_day] = 24
config[system][expire_limit] = 50000
config[system][sys_expire_days] = 30

Schritt 2: Den Expire-Daemon manuell anstoßen

Da sich ein Rückstau angesammelt hatte, habe ich den Daemon manuell mehrfach ausgeführt:

php Zotlabs/Daemon/Master.php Expire

Mehrfach wiederholen bis sich kaum noch etwas ändert

Schritt 3: Cache und Lieferberichte leeren


TRUNCATE TABLE cache;
TRUNCATE TABLE dreport;

Der Cache wird automatisch neu befüllt – das Leeren ist völlig sicher.

Schritt 4: Bereits gelöschte Items physisch entfernen


DELETE FROM item WHERE item_deleted = 1 LIMIT 50000;
DELETE FROM item WHERE item_pending_remove = 1 LIMIT 50000;

Schritt 5: OPTIMIZE ausführen


OPTIMIZE TABLE item;
OPTIMIZE TABLE term;
OPTIMIZE TABLE iconfig;
OPTIMIZE TABLE cache;
OPTIMIZE TABLE dreport;

Hinweis: information_schema zeigt bei InnoDB oft veraltete Größen. Die echte Größe prüft man so (mit eigenem Datenbanknamen anpassen):

SELECT table_name,
ROUND(data_length/1024/1024, 2) AS data_mb,
ROUND(data_free/1024/1024, 2) AS free_mb
FROM information_schema.tables
WHERE table_schema = 'MEINE_DB'
ORDER BY data_length DESC LIMIT 10;

Das Ergebnis

tabelle2.png

Über 2,6 GB eingespart – mehr als 75% Reduktion

Warum passiert das überhaupt?

Hubzilla ist ein föderiertes Netzwerk. Jeder Hub speichert Beiträge aus dem gesamten Fediverse lokal – ähnlich wie ein E-Mail-Server alle empfangenen Mails speichert. Ohne Ablaufeinstellung wächst die Datenbank unbegrenzt.
Das Problem: Die Ablaufeinstellung im Admin-Menü (default_expire_days) und der tatsächlich wirksame Konfigurationsschlüssel (sys_expire_days) sind zwei verschiedene Dinge. Keine Ahnung warum das so ist, aber es ist zumindest ein Dokumentationsproblem, grade für unbedarfte Admins. Man liest ja auch oft von eben diesem Problem der sich aufblähenden Datenbank.

Langfristige Empfehlungen

Diese Einstellungen sollte man setzen:

Remote-Inhalte nach 30 Tagen löschen
php util/config system sys_expire_days 30

Schnellere Bereinigung
php util/config system expire_limit 50000 

Automatisch Speicher freigeben
php util/config system optimize_items 1 

Lieferberichte deaktivieren
php util/config system disable_dreport 1 

Und regelmäßig prüfen:
php util/config system | grep -i expire

Fazit

Das Admin-Menü von Hubzilla suggeriert eine funktionierende Ablaufkonfiguration, die in Wirklichkeit den falschen Konfigurationsschlüssel setzt. Ohne dieses Wissen kann eine Hubzilla-Instanz über Jahre hinweg unkontrolliert wachsen, obwohl man glaubt alles richtig konfiguriert zu haben.

Übrigens zum Schluss am besten im Admin-Menü die Ablaufzeit auch auf 30 Tage stellen damit alles synchron ist.

Ich hoffe dieser Bericht hilft anderen Hubzilla-Admins die das gleiche Problem haben. Aber zum Schluß nochmal der Hinweis: Ohne Backup der Datenbank keine Befehle einfach nach tippen.
🕷️ 0 Aufrufe