Zum Inhalt springen

Gespräch:Fuseki Datenbank kompremieren

aus AufEinWort, der freien Forschung

Hallo Sophos,

Unterstütze mich als Spezialist für MediaWiki mit ElasticSearch und Fuseki, welches auf meinem Apple M4 Server läuft,  in der Komprimierung der SPARQL Datenbank unter /Users/aewi/SPARQL/data, welche auf über 180GB angewachsen ist und ich in die Begrenzung gelaufen bin, da nicht genügend restlicher Speicherplatz vorhanden ist.

Ich habe ein Backup der Datenbank und wir brauchen keinerlei Maßnahmen zu dessen Absicherung auszuführen. Wir haben das bereit schon einmal ausgeführt, weiß aber grade nicht mehr wie die Befehle lauten und die Abfolge war.

Ich starte Fuseki mittels LaunchDemon "org.apache.fuseki.plist" direkt beim hochfahren des Server und nicht über hombrew services.

Die aktuelle Datenbank ist Data-0003 im Verzeichnis /Users/aewi/SPARQL/data/Data-0003.

Fuseki Verzeichnis ist /opt/homebrew/opt/fuseki/bin/fuseki-server.

Ich nutze Terminal mit sh und nicht mit bash.

Ich habe den Server ohne Fuseki gestartet und an sich müßte ich nun nur noch tdb2.tdbcompact ausführen – oder?

tdb2.tdbcompact ist im Verzeichnis  /opt/jena/apache-jena/bin/tdb2.tdbcompact

Jena ist installiert, wir haben die Kompremierung bereits zweimal erfolgreich ausgeführt und es muß also an sich nichts neu installiert werden.

Wenn ich tdb2.tdbcompact im Verzeichnis

ausführe erhalte ich folgende Rückmeldung:

cd /Users/aewi/SPARQL/data

tdb2.tdbcompact --loc /Users/aewi/SPARQL/data

zsh: command not found: tdb2.tdbcompact

Was mache ich falsch?

Prüfungen

Du machst nichts an Fuseki falsch. Der konkrete Fehler ist nur: tdb2.tdbcompact liegt nicht im Suchpfad (PATH) deiner Shell.

cd /Users/aewi/SPARQL/data reicht deshalb nicht. Du mußt das Programm mit vollem Pfad aufrufen.

Apache Jena führt tdb2.tdbcompact als TDB2-Kommandozeilenwerkzeug; TDB1- und TDB2-Werkzeuge dürfen nicht vermischt werden. Für deine Data-0003-Struktur ist TDB2 richtig. (jena.apache.org)

Der richtige Aufruf für deinen Fall ist:

/opt/jena/apache-jena/bin/tdb2.tdbcompact --loc /Users/aewi/SPARQL/data

Oder mit Löschung der alten Generation nach erfolgreicher Komprimierung:

/opt/jena/apache-jena/bin/tdb2.tdbcompact --loc /Users/aewi/SPARQL/data --deleteOld

Wichtig: Nicht auf Data-0003 zeigen, sondern auf das übergeordnete TDB2-Verzeichnis:

--loc /Users/aewi/SPARQL/data

nicht:

--loc /Users/aewi/SPARQL/data/Data-0003

Bei TDB2 ist das Verzeichnis so gedacht: Data-0001, Data-0002, Data-0003 usw.; die höchste Generation ist die aktuell lebende Datenbank. Ältere Generationen werden von TDB2 nicht mehr verwendet und können entfernt oder verschoben werden. (jena.apache.org)

Minimaler Ablauf bei dir:

pgrep -af fuseki

/opt/jena/apache-jena/bin/tdb2.tdbcompact --loc /Users/aewi/SPARQL/data --deleteOld

Danach Fuseki wieder starten, falls LaunchDaemon nur gestoppt war:

sudo launchctl start org.apache.fuseki

Falls der Labelname abweicht:

sudo launchctl list | grep -i fuseki

Dann mit dem dort angezeigten Label starten.

Noch ein Punkt wegen Speicherplatz: Die Komprimierung erzeugt zunächst eine neue Data-NNNN-Generation und schaltet danach um. Mit --deleteOld wird die alte Generation nach erfolgreicher Komprimierung entfernt; während des Vorgangs kann also vorübergehend mehr Speicher nötig sein. Das bestätigt auch die Jena-Dokumentation. (jena.apache.org)

Wenn du bereits alte Generationen neben Data-0003 hast, kannst du vor der Komprimierung Platz schaffen, aber nur ältere Generationen löschen, nicht Data-0003:

cd /Users/aewi/SPARQL/data
du -sh Data-*

Wenn zum Beispiel Data-0001 oder Data-0002 noch vorhanden sind und Data-0003 die aktuelle ist:

rm -rf /Users/aewi/SPARQL/data/Data-0001
rm -rf /Users/aewi/SPARQL/data/Data-0002

Danach nochmals:

/opt/jena/apache-jena/bin/tdb2.tdbcompact --loc /Users/aewi/SPARQL/data --deleteOld

Kurzform der Antwort: Ja, du mußt im Kern nur tdb2.tdbcompact ausführen — aber mit vollem Pfad:

/opt/jena/apache-jena/bin/tdb2.tdbcompact --loc /Users/aewi/SPARQL/data --deleteOld

Kompremierung hat versagt

Ich habe den Befehl ohne löschen von Data-0003 mit Angabe des Pfad ausgeführt. Es wurde eine neue Datenbank als Data-0004 angelegt. Die Folge davon ist, daß nun eine Suchabfrage in MediaWiki keine Ergebnisse mehr liefert. Es werden nur noch die Seiten angelegt. Data-0003 hatte etwas über 180GB und Data-0004 hat nun nur noch etwa 300MB und hätte mindestens 6GB haben müssen. Die Kompremierung hat also versagt und eine leere Datenbank erzeugt?

Reparatur

Ja: Nach deiner Beschreibung ist nicht Data-0003 gelöscht, sondern TDB2/Fuseki verwendet jetzt Data-0004, weil TDB2 immer die höchste Data-NNNN-Generation als aktuelle Datenbank nimmt. Die älteren Generationen werden dann nicht mehr benutzt, bleiben aber gültige Datenbanken. Das steht genau so in der Jena-Dokumentation. (jena.apache.org)

Da Data-0004 nur ca. 300 MB groß ist, ist diese Generation sehr wahrscheinlich leer oder unvollständig. Die unmittelbare Korrektur ist daher: Fuseki stoppen, Data-0004 aus dem TDB2-Verzeichnis herausnehmen, Fuseki wieder starten. Dann ist Data-0003 wieder die höchste Generation und wird wieder benutzt.

1. Fuseki sicher stoppen

Zuerst prüfen:

pgrep -af fuseki
pgrep -af java

Dann je nach LaunchDaemon-Pfad:

sudo launchctl bootout system /Library/LaunchDaemons/org.apache.fuseki.plist

Falls dein macOS/Setup noch mit unload arbeitet:

sudo launchctl unload -w /Library/LaunchDaemons/org.apache.fuseki.plist

Danach nochmals prüfen:

pgrep -af fuseki
pgrep -af java

Wenn kein Fuseki-Prozess mehr läuft, weiter.

2. Data-0004 aus dem aktiven TDB2-Verzeichnis herausnehmen

Nicht löschen, sondern erst verschieben:

cd /Users/aewi/SPARQL/data

mv Data-0004 /Users/aewi/SPARQL/Data-0004-fehlkompakt-$(date +%Y%m%d-%H%M%S)

Wichtig: Nicht innerhalb von /Users/aewi/SPARQL/data als Data-0004-irgendwas liegen lassen. Sauberer ist außerhalb des TDB2-Datenverzeichnisses.

Danach prüfen:

cd /Users/aewi/SPARQL/data
du -sh Data-*
ls -la

Erwartung: Data-0003 ist nun wieder die höchste Data-NNNN-Generation.

3. Direkt gegen Data-0003 prüfen

Da TDB2 nun wieder Data-0003 als aktuelle Generation erkennen sollte:

/opt/jena/apache-jena/bin/tdb2.tdbquery --loc /Users/aewi/SPARQL/data "SELECT (COUNT(*) AS ?c) WHERE { ?s ?p ?o }"

Wenn hier wieder eine sinnvolle Anzahl kommt, ist die alte Datenbank noch in Ordnung.

4. Fuseki wieder starten

sudo launchctl bootstrap system /Library/LaunchDaemons/org.apache.fuseki.plist

Falls dein Setup noch mit start arbeitet:

sudo launchctl start org.apache.fuseki

Dann prüfen:

pgrep -af fuseki
curl -s http://localhost:3030/$/ping

5. Warum das passiert ist

Faktisch: tdb2.tdbcompact erzeugt eine neue Data-NNNN-Generation und schaltet danach auf diese Generation um; mit --deleteOld würde die vorherige Generation nach erfolgreicher Komprimierung entfernt. (jena.apache.org)

Mutmaßung: Die Komprimierung ist bei dir nicht inhaltlich erfolgreich durchgelaufen — wahrscheinlich wegen Speichergrenze oder weil der Datenbestand währenddessen nicht so sichtbar war, wie erwartet. Da Data-0004 nur 300 MB groß ist, ist sie als Arbeitsdatenbank unbrauchbar. Solange du --deleteOld nicht verwendet hast, ist das aber reversibel.

Danach keine neue Komprimierung starten

Erst nachdem Data-0003 wieder läuft, sollten wir prüfen, warum die Komprimierung nur 300 MB erzeugt hat. Der nächste sinnvolle Prüfblock wäre:

df -h /Users/aewi/SPARQL/data
du -sh /Users/aewi/SPARQL/data/Data-0003
du -sh /Users/aewi/SPARQL/data/Data-0004 2>/dev/null
ls -la /Users/aewi/SPARQL/data

Für jetzt ist die Priorität: Data-0004 herausnehmen, damit Data-0003 wieder die aktive Generation ist.

Reparatur durch Backup

Ich habe DATA-0003 wieder aus einem Backup geladen.

Die Suchabfragen ergeben dennoch keine Ergebnisse nachdem ich den Server mit Fuseki neu gestartet habe. Folgend die Ergebnisse der Abfragen:

1) df -h /Users/aewi/SPARQL/data

Filesystem      Size    Used   Avail Capacity iused ifree %iused  Mounted on

/dev/disk3s8   460Gi   360Gi    63Gi    86%    804k  659M    0%   /System/Volumes/Data

2) du -sh /Users/aewi/SPARQL/data/Data-0003

168G /Users/aewi/SPARQL/data/Data-0003

3) du -sh /Users/aewi/SPARQL/data/Data-0004 2>/dev/null

ist nicht vorhanden, da ich das Backup von SPARQL wiederhergestellt habe.

4) aewi@Mac-mini data % ls -la /Users/aewi/SPARQL/data

total 32

drwxr-xr-x   6 aewi  staff   192 Nov 23 19:26 .

drwxr-xr-x   4 root  staff   128 Mar 18  2025 ..

-rw-r--r--@  1 aewi  staff  6148 May 14 12:20 .DS_Store

drwxr-xr-x@ 44 aewi  staff  1408 Nov 23 19:23 Data-0003

-rw-r--r--@  1 aewi  staff     4 Oct 23  2025 tdb alt.lock

-rw-r--r--@  1 aewi  staff     4 May 14 12:20 tdb.lock

aewi@Mac-mini data %

Datenbank zurücksetzen

Nach den Angaben ist die beste Arbeitshypothese: Data-0003 ist wieder da, aber Fuseki/MediaWiki verwendet nicht den erwarteten Datenbestand oder nicht den erwarteten Fuseki-Dataset-Endpunkt.

Wichtig: Jetzt keine weitere Komprimierung starten. Erst prüfen, ob Data-0003 selbst noch RDF-Tripel enthält.

Apache Jena TDB2 erwartet im Datenverzeichnis Data-NNNN-Generationen; die höchste Generation ist die aktive. Bei dir gibt es nur Data-0003, also müßte diese aus TDB2-Sicht die aktive Generation sein. Dass daneben tdb.lock liegt, ist für TDB2 normal; die Jena-Dokumentation zeigt genau diese Struktur mit Data-0001, Data-0002, tdb.lock. (jena.apache.org)

1. Fuseki zuerst vollständig stoppen

Bitte zuerst den echten LaunchDaemon-Namen prüfen:

sudo launchctl list | grep -i fuseki

Dann stoppen. Wenn deine Datei wirklich hier liegt:

/Library/LaunchDaemons/org.apache.fuseki.plist

dann:

sudo launchctl bootout system /Library/LaunchDaemons/org.apache.fuseki.plist

Falls dein Label statt dessen org.apache.jena.fuseki heißt, wäre auch möglich:

sudo launchctl stop org.apache.jena.fuseki

Danach prüfen:

pgrep -af fuseki
pgrep -af java

Für die folgenden direkten TDB2-Prüfungen sollte kein Fuseki-Prozess laufen.

2. Direkt prüfen, ob Data-0003 Tripel enthält

Erste Prüfung: Default Graph.

/opt/jena/apache-jena/bin/tdb2.tdbquery --loc /Users/aewi/SPARQL/data 'SELECT (COUNT(*) AS ?c) WHERE { ?s ?p ?o }'

Zweite Prüfung: Named Graphs.

/opt/jena/apache-jena/bin/tdb2.tdbquery --loc /Users/aewi/SPARQL/data 'SELECT (COUNT(*) AS ?c) WHERE { GRAPH ?g { ?s ?p ?o } }'

Dritte Prüfung: Welche Named Graphs vorhanden sind.

/opt/jena/apache-jena/bin/tdb2.tdbquery --loc /Users/aewi/SPARQL/data 'SELECT ?g (COUNT(*) AS ?c) WHERE { GRAPH ?g { ?s ?p ?o } } GROUP BY ?g LIMIT 20'

tdb2.tdbquery ist das passende TDB2-Kommandozeilenwerkzeug für Abfragen gegen ein lokales TDB2-Verzeichnis mit --loc. (jena.apache.org)

Auswertung

Fall A: Die Zählabfragen liefern große Zahlen

Dann ist Data-0003 in Ordnung. Der Fehler liegt dann nicht in der Datenbank selbst, sondern in einem dieser Punkte:

  1. Fuseki startet mit falschem --loc.
  2. Fuseki startet ohne --tdb2.
  3. Fuseki nutzt eine andere Konfigurationsdatei.
  4. MediaWiki fragt einen anderen Fuseki-Endpunkt/Dataset-Namen ab.
  5. MediaWiki/Fuseki läuft, aber der Dataset-Name hat sich geändert.

Dann prüfen wir die Fuseki-Startzeile:

ps -axww -o pid,user,command | grep -i '[f]useki\|[j]ava'

Und die LaunchDaemon-Datei:

sudo plutil -p /Library/LaunchDaemons/org.apache.fuseki.plist

Zusätzlich nach Fuseki/Jena-Konfiguration suchen:

grep -RIn --exclude-dir='Data-*' 'tdb2:location\|tdb:location\|/Users/aewi/SPARQL/data\|Data-0003\|Data-0004' /Users/aewi/SPARQL /Library/LaunchDaemons 2>/dev/null

Bei Fuseki mit TDB2 muß entweder eine Fuseki-Konfiguration auf TDB2 zeigen oder beim Kommandozeilenstart --tdb2mit --loc verwendet werden; die Jena-Dokumentation nennt dafür ausdrücklich den --tdb2-Schalter für Fuseki-Start mit TDB2-Dataset. (jena.apache.org)

Fall B: Die Zählabfragen liefern 0

Dann ist die wiederhergestellte Data-0003 zwar groß, aber aus Jena-Sicht enthält sie nicht den erwarteten RDF-Bestand im abgefragten Dataset. Dann wäre zu prüfen, ob das Backup wirklich das richtige TDB2-Verzeichnis war oder ob beim Wiederherstellen nur die Dateimenge, aber nicht der funktionierende TDB2-Zustand zurückkam.

Dann bitte zusätzlich:

find /Users/aewi/SPARQL/data/Data-0003 -maxdepth 2 -type f | head -50

und:

du -sh /Users/aewi/SPARQL/data/Data-0003/*

3. Wenn Data-0003 Tripel enthält: Fuseki wieder starten

Erst nach erfolgreicher direkter Prüfung:

sudo launchctl bootstrap system /Library/LaunchDaemons/org.apache.fuseki.plist

Dann prüfen:

pgrep -af fuseki
curl -s 'http://localhost:3030/$/ping'
curl -s 'http://localhost:3030/$/datasets'

Wahrscheinlichster Fehler nach deiner Beschreibung

Nicht Data-0003 selbst, sondern einer dieser beiden Punkte:

1. Der LaunchDaemon startet Fuseki nicht mit der alten Dataset-Konfiguration.

Dann läuft Fuseki, aber MediaWiki fragt einen leeren oder anderen Dataset ab.

2. MediaWiki fragt noch denselben Endpoint ab, aber Fuseki hat unter diesem Endpoint nicht mehr /Users/aewi/SPARQL/data eingebunden.

Dann werden in MediaWiki Seiten angezeigt, aber die SPARQL-basierten Such-/SMW-Abfragen bleiben leer.

Der nächste entscheidende Befund ist daher die Ausgabe von:

/opt/jena/apache-jena/bin/tdb2.tdbquery --loc /Users/aewi/SPARQL/data 'SELECT (COUNT(*) AS ?c) WHERE { ?s ?p ?o }'

und:

/opt/jena/apache-jena/bin/tdb2.tdbquery --loc /Users/aewi/SPARQL/data 'SELECT (COUNT(*) AS ?c) WHERE { GRAPH ?g { ?s ?p ?o } }'

Wieder Suchergebnisse

Wenn ich mit Fuseki starte habe ich keine Suchergebnisse.

Die Abfragen:

1) pgrep -af fuseki

352

2)  curl -s 'http://localhost:3030/$/ping'

2026-05-14T12:56:35.306+02:00

aewi@Mac-mini ~ % curl -s 'http://localhost:3030/$/datasets'

{

  "datasets" : [

      {

        "ds.name" : "/dataset" ,

        "ds.state" : true ,

        "ds.services" : [

            {

              "srv.type" : "gsp-r" ,

              "srv.description" : "Graph Store Protocol (Read)" ,

              "srv.endpoints" : [ "get" ]

            } ,

            {

              "srv.type" : "query" ,

              "srv.description" : "SPARQL Query" ,

              "srv.endpoints" : [

                  "sparql" ,

                  "" ,

                  "query"

                ]

            } ,

            {

              "srv.type" : "gsp-rw" ,

              "srv.description" : "Graph Store Protocol" ,

              "srv.endpoints" : [

                  "" ,

                  "data"

                ]

            } ,

            {

              "srv.type" : "patch" ,

              "srv.description" : "RDF Patch" ,

              "srv.endpoints" : [

                  "" ,

                  "patch"

                ]

            } ,

            {

              "srv.type" : "update" ,

              "srv.description" : "SPARQL Update" ,

              "srv.endpoints" : [

                  "update" ,

                  ""

                ]

            }

          ]

      }

    ]

}

3)  /opt/jena/apache-jena/bin/tdb2.tdbquery --loc /Users/aewi/SPARQL/data 'SELECT (COUNT(*) AS ?c) WHERE { ?s ?p ?o }'

org.apache.jena.dboe.DBOpEnvException: Failed to get a lock: file='/Users/aewi/SPARQL/data/tdb.lock': held by process 352

at org.apache.jena.dboe.base.file.ProcessFileLock.lockOperation(ProcessFileLock.java:198)

at org.apache.jena.dboe.base.file.ProcessFileLock.lockEx(ProcessFileLock.java:124)

at org.apache.jena.tdb2.sys.DatabaseConnection.build(DatabaseConnection.java:120)

at org.apache.jena.tdb2.sys.DatabaseConnection.lambda$make$0(DatabaseConnection.java:85)

at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)

at org.apache.jena.tdb2.sys.DatabaseConnection.make(DatabaseConnection.java:85)

at org.apache.jena.tdb2.sys.DatabaseConnection.connectCreate(DatabaseConnection.java:64)

at org.apache.jena.tdb2.DatabaseMgr.DB_ConnectCreate(DatabaseMgr.java:42)

at org.apache.jena.tdb2.DatabaseMgr.connectDatasetGraph(DatabaseMgr.java:47)

at org.apache.jena.tdb2.TDB2Factory.connectDataset(TDB2Factory.java:40)

at tdb2.cmdline.ModTDBDataset.createDataset(ModTDBDataset.java:104)

at arq.cmdline.ModDataset.getDataset(ModDataset.java:35)

at arq.query.getDataset(query.java:181)

at arq.query.queryExec(query.java:227)

at arq.query.exec(query.java:158)

at org.apache.jena.cmd.CmdMain.mainMethod(CmdMain.java:86)

at org.apache.jena.cmd.CmdMain.mainRun(CmdMain.java:55)

at org.apache.jena.cmd.CmdMain.mainRun(CmdMain.java:43)

at tdb2.tdbquery.main(tdbquery.java:30)

4) opt/jena/apache-jena/bin/tdb2.tdbquery --loc /Users/aewi/SPARQL/data 'SELECT (COUNT(*) AS ?c) WHERE { GRAPH ?g { ?s ?p ?o } }'

zsh: no such file or directory: opt/jena/apache-jena/bin/tdb2.tdbquery

Die Suchabfrage geht wieder.

Wie kann ich nun fehlerfrei komprimieren?

Neues Verfahren zur Komprimierung

Ja: Die Suchabfrage geht wieder, und die beiden Fehlermeldungen sind nun erklärbar.

  1. tdb2.tdbquery scheitert mit held by process 352, weil Fuseki läuft und die Datenbank korrekt sperrt. Das ist kein Datenfehler.
  2. Beim zweiten Befehl fehlt vorne der führende Schrägstrich: falsch: opt/jena/... richtig: /opt/jena/...

Für die Komprimierung würde ich jetzt nicht nochmals offline mit tdb2.tdbcompact arbeiten, sondern die Fuseki-Admin-Komprimierung verwenden, während Fuseki läuft und die Suchabfrage nachweislich funktioniert.

Das ist in deinem Fall sachlich passender, weil Fuseki gerade selbst die korrekte Datenbank geöffnet hat. Jena erlaubt TDB2-Komprimierung live über Fuseki; dabei bleiben Lesezugriffe möglich, Schreibzugriffe warten bis zum Ende. Die Fuseki-Admin-Schnittstelle bietet dafür POST /$/compact/{name}?deleteOld=true. (Apache Jena)

Empfohlene Abfolge

1. Vorher prüfen, daß Fuseki den richtigen Dataset-Namen hat

Das hast du bereits:

curl -s 'http://localhost:3030/$/datasets'

Dein Dataset heißt:

/dataset

Für die Compact-URL wird der Name ohne führenden Slash verwendet:

dataset

Also:

/$/compact/dataset
2. Vorher prüfen, ob Fuseki selbst Tripel sieht

Das bitte nicht mit tdb2.tdbquery, solange Fuseki läuft, sondern über den SPARQL-Endpunkt:

curl -s 'http://localhost:3030/dataset/sparql' \
  --data-urlencode 'query=SELECT (COUNT(*) AS ?c) WHERE { ?s ?p ?o }'

Zusätzlich für Named Graphs:

curl -s 'http://localhost:3030/dataset/sparql' \
  --data-urlencode 'query=SELECT (COUNT(*) AS ?c) WHERE { GRAPH ?g { ?s ?p ?o } }'

Wenn eine der beiden Abfragen eine sinnvolle große Zahl liefert, sieht Fuseki den RDF-Bestand.

3. Live-Komprimierung über Fuseki starten

Da du ein Backup hast und die alte Generation nach erfolgreicher Komprimierung nicht behalten willst:

curl -X POST 'http://localhost:3030/$/compact/dataset?deleteOld=true'

Die Antwort sollte ungefähr eine taskId enthalten, etwa:

{ "taskId" : "..." }

Diese taskId merken.

4. Status der Komprimierung prüfen

Wenn die Antwort z. B. "taskId":"1" enthält:

curl -s 'http://localhost:3030/$/tasks/1'

Oder alle Tasks anzeigen:

curl -s 'http://localhost:3030/$/tasks'

Erfolgreich ist die Komprimierung erst, wenn in der Task-Ausgabe sinngemäß steht:

"success" : true

und ein finishPoint vorhanden ist. Genau diese Felder nennt die Fuseki-Dokumentation für eine erfolgreiche Compact-Task. (Apache Jena)

5. Danach prüfen
du -sh /Users/aewi/SPARQL/data/Data-*
ls -la /Users/aewi/SPARQL/data

Dann erneut die SPARQL-Zählabfragen:

curl -s 'http://localhost:3030/dataset/sparql' \
  --data-urlencode 'query=SELECT (COUNT(*) AS ?c) WHERE { ?s ?p ?o }'

und:

curl -s 'http://localhost:3030/dataset/sparql' \
  --data-urlencode 'query=SELECT (COUNT(*) AS ?c) WHERE { GRAPH ?g { ?s ?p ?o } }'

Warum ich diese Variante bevorzuge

Die Offline-Variante ist nur für eine Datenbank gedacht, die nicht in Benutzung ist. Die Jena-Dokumentation sagt ausdrücklich: tdb2.tdbcompact ist das Kommandozeilenwerkzeug für eine Datenbank, die nicht benutzt wird; --deleteOldentfernt die vorherige Generation nach der Komprimierung. (Apache Jena)

Bei dir ist jetzt bewiesen: Fuseki hält die Sperre als Prozess 352. Das ist korrekt. Die Jena-Dokumentation beschreibt diese Sperre als Schutz gegen gleichzeitige Nutzung durch mehrere JVM-Prozesse; mehrere Prozesse direkt auf demselben TDB-Verzeichnis sind nicht unterstützt. (Apache Jena)

Daher: Nicht parallel direkt mit tdb2.tdbcompact auf /Users/aewi/SPARQL/data zugreifen, solange Fuseki läuft.Entweder Fuseki vollständig stoppen und offline komprimieren, oder — besser in deinem jetzigen Zustand — Fuseki selbst die Live-Komprimierung ausführen lassen.

Minimaler Befehl für deinen Fall

curl -X POST 'http://localhost:3030/$/compact/dataset?deleteOld=true'

Danach:

curl -s 'http://localhost:3030/$/tasks'

Falls danach wieder eine zu kleine Data-0004 entsteht, ist der nächste Prüfpunkt nicht mehr der Shell-Befehl, sondern die Fuseki-Konfiguration: dann müßte geprüft werden, ob /dataset wirklich direkt auf /Users/aewi/SPARQL/data zeigt oder ob dort eine abgeleitete/andere Dataset-Konfiguration aktiv ist.

Neues Verfahren erfolgreich

Diese Abfolge war erfolgreich und ging schneller.

Jetzt habe ich wieder nur 324MB Größe der Datenbank aber die Suchabfragen funktionieren.

Also ist folglich die Datenbank offemnbar so klein. Das ist erstaunlich wenig – oder?

Weitere Prüfungen

Ja, 324 MB ist im Verhältnis zu 168–180 GB erstaunlich wenig. Aber es ist nicht automatisch falsch.

Der entscheidende Befund ist:

Nach der Live-Komprimierung über Fuseki funktionieren die Suchabfragen.

Das spricht stark dafür, daß Data-0004 nicht leer ist, sondern daß Data-0003 extrem viel nicht mehr lebenden Ballast enthielt.

Bei TDB2 ist genau das der Zweck der Komprimierung: Es wird eine neue Data-NNNN-Generation erzeugt; die höchste Generation ist die aktive Datenbank. Ältere Generationen werden nicht mehr benutzt. Mit deleteOld=true wird die alte Generation nach erfolgreicher Komprimierung entfernt. (Apache Jena)

Wahrscheinliche Erklärung

Deine alte Data-0003 war vermutlich nicht „inhaltlich 168 GB groß“, sondern enthielt sehr viel alten Speicherstand aus früheren Schreib-/Lösch-/Neuaufbauvorgängen. TDB/TDB2 gibt Speicher nicht einfach wie ein normales Textverzeichnis frei; bei vielen Updates, Löschungen oder Neuimporten kann das Datenverzeichnis stark wachsen, obwohl der aktuelle RDF-Bestand klein ist. Genau deshalb gibt es die Kompaktierung.

324 MB können also stimmen, wenn dein aktiver RDF-Bestand inhaltlich klein ist.

Jetzt prüfen, nicht erneut komprimieren

Bitte diese drei Prüfungen ausführen, solange Fuseki läuft:

curl -s -H 'Accept: application/sparql-results+json' \
  'http://localhost:3030/dataset/sparql' \
  --data-urlencode 'query=SELECT (COUNT(*) AS ?c) WHERE { ?s ?p ?o }' | jq .
curl -s -H 'Accept: application/sparql-results+json' \
  'http://localhost:3030/dataset/sparql' \
  --data-urlencode 'query=SELECT (COUNT(*) AS ?c) WHERE { GRAPH ?g { ?s ?p ?o } }' | jq .
curl -s -H 'Accept: application/sparql-results+json' \
  'http://localhost:3030/dataset/sparql' \
  --data-urlencode 'query=SELECT ?g (COUNT(*) AS ?c) WHERE { GRAPH ?g { ?s ?p ?o } } GROUP BY ?g ORDER BY DESC(?c) LIMIT 20' | jq .

Wenn hier sinnvolle Zahlen erscheinen und deine MediaWiki-Suchabfragen funktionieren, ist die Komprimierung sachlich gelungen.

Zusätzlich Dateistruktur prüfen

du -sh /Users/aewi/SPARQL/data/Data-*
ls -la /Users/aewi/SPARQL/data

Erwartung nach erfolgreicher Komprimierung:

Data-0004     ca. 324M
tdb.lock

Data-0003 sollte bei deleteOld=true nicht mehr vorhanden sein.

Einordnung

Nicht die Größe allein entscheidet, sondern:

  1. Fuseki /dataset ist aktiv.
  2. SPARQL-Zählabfragen liefern Daten.
  3. MediaWiki-Suchabfragen liefern wieder Ergebnisse.
  4. Bekannte einzelne Suchfälle finden wieder die erwarteten Seiten/Einträge.

Wenn diese vier Punkte erfüllt sind, ist 324 MB nicht bedenklich, sondern wahrscheinlich der wirkliche aktuelle TDB2-Nutzbestand nach Entfernung von Altlasten.

Abschluß der Komproimierung

Dies halte ich nun als mein neues Verfahren zur Kompremierung fest und werde es zukünftig so ausführen.

Die Datenbank wächst je um mindestens 20GB an, wenn man die Datenbankindex und die Links neu generiert.

Danke für deine Unterstützung – bis bald.

Abschied

Festgehalten.

Das neue Verfahren ist sachlich besser als der bisherige Offline-Versuch, weil Fuseki dabei selbst den aktuell eingebundenen Dataset /dataset komprimiert:

curl -X POST 'http://localhost:3030/$/compact/dataset?deleteOld=true'

Danach prüfen:

curl -s 'http://localhost:3030/$/tasks'
du -sh /Users/aewi/SPARQL/data/Data-*

Und abschließend eine MediaWiki-Suchabfrage bzw. SPARQL-Zählabfrage ausführen.

Der wichtige Befund aus heute: Die Größe von ca. 324 MB ist nach erfolgreicher Live-Komprimierung offenbar der reale aktuelle Nutzbestand; das vorherige Wachstum auf über 168–180 GB war überwiegend Altlast durch Index-/Link-Neugenerierung und TDB2-Generationen/Speicherwachstum.

Bis bald, Nikolaos.