Mich hat das gleiche Schicksal ereilt wie dich.
Nach einiger Recherche habe ich mich für einen (hoffentlich) extrem zukunftssicheren Weg entschieden:
Ich bin von InfluxDB auf TimescaleDB (eine leistungsstarke Zeitreihen-Erweiterung für PostgreSQL) in Kombination mit Scribe umgestiegen.
Aktuell laufen InfluxDB und TimescaleDB bei mir parallel.
Ich stelle nun Stück für Stück meine Grafana-Dashboards um.
Sobald alles läuft, wird InfluxDB einfach gelöscht.
Falls du den gleichen Weg gehen möchtest, hier mein Setup und wie die Migration der Altdaten klappt.
Mein Setup (Die benötigten Komponenten)
- TimescaleDB (Add-on): Einfach direkt über den Home Assistant Add-on Store installieren.
- Scribe (via HACS): Diese Integration schiebt die aktuellen Sensordaten von Home Assistant in die TimescaleDB.
Hinweis: Man kann zwar auch den normalen Home Assistant Recorder direkt auf TimescaleDB umleiten,
aber die Lösung via Scribe finde ich deutlich sauberer und flexibler.
- pgAdmin (Add-on): Perfekt, um direkt einen Blick in die Datenbank zu werfen. Wenn man aus der SQL-Welt kommt, ist Postgres (im Gegensatz zu InfluxDB) ein Traum zu bedienen.
Die Migration der Altdaten (Docker zu Docker)
Um Netzwerkprobleme zu vermeiden, habe ich die Daten mit dem Tool Outflux direkt innerhalb von Home Assistant OS (HAOS) von Docker-Container zu Docker-Container migriert.
Outflux ist zwar schon etwas älter, aber für die alte InfluxDB-Struktur einfach ausentwickelt und läuft grundsolide.
Gerade bei sehr großen Tabellen benötigt InfluxDB bei der Abfrage extrem viel RAM – da ist TimescaleDB deutlich effizienter.
Da das TimescaleDB-Add-on bei jeder regulären Installation die identische interne ID nutzt, lautet der Hostname im Docker-Netzwerk immer 77b2833f-timescaledb.
Der finale Migrationsbefehl im Terminal sieht so aus:
bash
./outflux migrate INFLUX_BUCKET
–chunk-size 1000
–batch-size 1000
–input-server=“http://<INFLUXDB_IP>:8086”
–input-user=“dein_influx_user”
–input-password=“dein_influx_passwort”
–output-connection=“user=POSTGRES_USER password=POSTGRES_PWD host=77b2833f-timescaledb port=5432 dbname=homeassistant sslmode=disable”
–schema-strategy=create-if-not-exists
Wichtig: Datenstrukturen & Grafana
Nach dem Import wirst du feststellen, dass Outflux die Daten 1:1 spiegelt.
Es entstehen in TimescaleDB einzelne Tabellen, die nach den Einheiten deiner Sensoren benannt sind (z. B. A, V, W, °C…).
Das musst du beim Wechsel beachten:
- Zwei verschiedene Strukturen:
Outflux legt die alten Daten in den Einheiten-Tabellen ab. Die neuen, aktuellen Daten von Scribe landen in einer anderen, eigenen Tabellenstruktur.
- Zusammenführung:
In Grafana musst du die SQL-Abfragen so aufbauen, dass sie Daten aus beiden Strukturen kombinieren.
Da es sich hier um echtes Standard-SQL handelt, findet man im Netz glücklicherweise zu jeder Frage sofort die passende Lösung.
- Alternative:
Man könnte die alten Outflux-Tabellen in der Datenbank auch direkt in die neue Scribe-Struktur konvertieren. I
ch tendiere aber klar dazu, das flexibel über Grafana zu lösen. Das hat für mich aber erst einmal Zeit.
Mein Fazit:
Die Migration hat zwar ordentlich Zeit gedauert, lief aber absolut fehlerfrei durch.
Das Schöne an diesem Weg ist:
Sollte beim ersten Mal etwas schiefgehen, kannst du die TimescaleDB jederzeit einfach leeren und den Outflux-Befehl neu starten.
Keine Panik vor Datenverlust – durch den Parallelbetrieb geht nichts verloren und es entstehen keine Zeitlücken!
Ergänzung:
TimeScaleDB nutzt eine Komprimierung um massive Speicherpaltz zu sparen(macht influx auch).
Für die aktuellen Daten macht das Scribe alles sauber.
Die alten Daten musst du selber komprimieren.
Mit dem Script werden die komprimierungsregeln für alle hyper_tables erstellt
Das ist der Kern und für die alten Influx Tabellen perfekt. states_raw ist von scibe, der macht das alles selber.
timescaledb.compress_segmentby = ''entity_id'',
timescaledb.compress_orderby = ''time DESC''
DO $$
DECLARE
t text;
BEGIN
FOR t IN
SELECT hypertable_name
FROM timescaledb_information.hypertables
WHERE hypertable_name <> 'states_raw'
LOOP
EXECUTE format(
'ALTER TABLE %I SET (
timescaledb.compress,
timescaledb.compress_segmentby = ''entity_id'',
timescaledb.compress_orderby = ''time DESC''
)',
t
);
END LOOP;
END $$;
Für die Komprimierung habe ich eine Prozedure angelegt die das im Hintergrund gemacht hat.
Ist ja eine einmalige Sache nur für diese Altdaten. Hat bei mir so 93 Prozent komprimiert, war schon echt klasse und ca 2-3 besser als Influx(bei mir).
Scripe macht das mit einer policy die 2 mal am Tag schaut ob was zu tun ist