Inhaltsverzeichnis

dbcopy - inkrementelle Datenbankkopie

Möchte man die Datenbank sichern oder auf einem zweiten System zur Verfügung haben stößt man bei Verwendung von mysqldump auf Schwierigkeiten (Systemlast, Zeitprobleme des vzlogger) die mit dbcopy umgangen werden können.

Dbcopy ist Teil einer VZ-Standardinstallation und unter /var/www/volkszaehler.org/vendor/bin/ zu finden. Es hat sein eigenes Repository auf github. Die Kopie ist in der Standardinstallation unter /var/www/volkszaehler.org/vendor/andig/dbcopy/ abgelegt.

Für das kopieren der Daten ist eine zweite, verfügbare Datenbankapplikation Grundvoraussetzung. Sie sollte SQL-Kompatibel sein. Am zuverlässigsten ist daher eine weitere MySQL-Installation die über Netzwerkwerk erreichbar ist, z.B. bei einem Webhoster.
Alternativ bieten sich aber auch die DB eines NAS (z.B. Maria-DB auf Synology) oder SQLite an. SQLite ist als Backuplösung besonders interessant weil die Datenbank in einer einzelnen Datei abgelegt wird die einfach kopiert (Voll-Backup) werden kann.
Seit neustem kann man die Daten aber auch auf eine Influx-DB übertragen.

Installation

In der Standardinstallation ist dbcopy über php direkt nutzbar.

php /var/www/volkszaehler.org/vendor/bin/dbcopy copy
In älteren Versionen lautet das Schlüsselwort backup statt copy.

Möchte man dbcopy von der Kommandozeile aus starten muss erst die Berechtigung gesetzt werden:

sudo chmod +x /var/www/volkszaehler.org/vendor/bin/dbcopy

Sollte dbcopy doch nicht auf dem System verfügbar sein kann das mit

git clone git://github.com/andig/dbcopy

nachgeholt werden. Um Einsatzbereitschaft herzustellen müssen die Abhängigkeiten aufgelöst werden

cd dbcopy
sudo composer install

MySQL

Bei der MYSQL-Datenbankapplikaion muss eine Datenbank und ein Nutzer mit ausreichenden Rechten angelegt werden. Insbesondere ist darauf zu achten das der User Schreibrechte hat und auch von außerhalb zugreifen darf. Manche Webhoster lassen allerdings nur localhost-Zugriffe auf MySQL zu.

SQLite

Kann auch als zweite Datenbankapplikation auf dem selben System installiert werden.

sudo apt-get install sqlite3 php-sqlite3

Influx

Hier dient dbcopy allein der Konvertierung. Das Ziel wird hier in einem getrennte Abschnitt definiert und die Übertragung mit dem Schlüsselwort influx angestoßen.

Konfiguration

In älteren Versionen lautete die Konfigurationsdatei dbcopy.json. Die Syntax ist anders, der Inhalt aber nahezu identisch.

Es empfiehlt sich nicht die Konfigurationsdatei /var/www/volkszaehler.org/etc/dbcopy.dist.yaml direkt zu ändern. Das kann bei späteren Updates der Middleware zu Problemen führen. Daher:

sudo cp /var/www/volkszaehler.org/etc/dbcopy.dist.yaml /etc/dbcopy.yaml

Und

sudo nano /etc/dbcopy.yaml
Wenn nicht explizit angegeben verwendet dbcopy die Konfiguration aus dem eigenen oder aktuellen Verzeichnis!
Deshalb dbcopy mit dem Parameter -c aufrufen.
/etc/dbcopy.yaml
# DATABASE DEFINITION
source:
  driver: pdo_mysql
  host: localhost
  user: vz
  password: demo
  dbname: volkszaehler

target:
  driver: pdo_sqlite
  host: localhost
  user: root
  password: raspberry
  dbname: volkszaehler_backup
  path: sqlite.db3		# path is only used if driver = pdo_sqlite
 
# influxdb target database connection
influx:
  dsn: influxdb://localhost:8086
  dbname: volkszaehler
  measurement: data
 
# TABLE DEFINITION
# ----------------
# tables will be processed in the order they are mentioned:
#		- foreign keys on target will be dropped
#		- if a table is not listed here, it will not be touched
# transfer mode
#		skip:		table will not be copied
#		copy:		entire table will be truncated on target and copied from source
#		pk:			selective copy by primary key. only data not present on target
# 					will be copied from source.
tables:
  entities: copy
  properties: copy
  entities_in_aggregator: copy
  data: pk
  aggregate: skip

In der Datei werden Quelle („source“) und kurz darunter Ziel („target“) festgelegt. Im folgenden sind die einzelnen Parameter erklärt:

driver: pdo_mysql
Die Schnittstelle zwischen PHP und der Datenbank. Standardmäßig läuft der Volkszähler mit einer MySQL-Datenbank (pdo_mysql), in der Beispielkonfiguration ist eine SQLite-Datenbank als Ziel vorgesehen, dementsprechend ist eine andere Schnittstelle nötig (pdo_sqlite).

host: localhost
Die Host- oder IP-Adresse des Rechners auf dem die Datenbank läuft. Standardmäßig ist es das selbes System, daher localhost.

user: vz
Benutzername der Datenbank, für SQLite nicht nötig.

password: demo
Passwort des Benutzers der Datenbank, für SQLite nicht nötig.

dbname: volkszaehler
Name der Datenbank, für SQLite nicht nötig.

path: sqlite.db3
Name der Datei bei SQLite, für MySQL nicht nötig.


Unter „table“ wird definiert welche und wie die Tabellen der Datenbank gehandhabt werden.

Vorne die Bezeichnung der einzelnen Tabellen. In der Beispielkonfiguration sind bereits alle Tabellen einer Volkszähler-Datenbank aufgeführt.
Hinter dem Doppelpunkt die Aktion die jeweils ausgeführt werden soll

copy
Bedeutet die Tabelle in der Ziel-Datenbank wird geleert und aus der Quelle neu beschrieben. Ein derart kopierte Tabelle ist keine „echtes“ Backup!

pk
Die Tabelle im Ziel wird mit neuen Datensätzen aus der Quelle ergänzt. Datensätze die in der Quelle gelöscht wurden bleiben im Ziel erhalten. Heißt aber auch das Änderungen an den Datensätzen nicht übernommen werden! Ist auf dem primären System vzcompress im Einsatz und auf dem sekundären System ebenfalls gewünscht, müsste das lokal wiederholt werden.

skip
Datensätze der Tabelle werden nicht kopiert. Für Aggregationswerte ist es sinnvoller sie aus data neu zu generieren als die redundaten Daten nochmal zu speichern. Möchte man die Tabelle aggregate ebenfalls sichern „skip“ in „pk“ ändern.

Zieldatenbank erstellen

/var/www/volkszaehler.org/vendor/bin/dbcopy create -c /etc/dbcopy.yaml
Das erzeugen von SQLite-Datenbanken schlug in einer alten Version fehl. Falls es Probleme gibt bitte die neuste Version aus den git holen.

Daten kopieren

/var/www/volkszaehler.org/vendor/bin/dbcopy copy -c /etc/dbcopy.yaml

Erfolgreiche Kopie:

entities: copying 9 rows (overwrite)
 [============================] 100%    1 sec/1 sec    9 rows

properties: copying 66 rows (overwrite)
 [============================] 100%    1 sec/1 sec    66 rows

entities_in_aggregator: copying 7 rows (overwrite)
 [============================] 100%    1 sec/1 sec    7 rows

data: copying 2258 rows (partial copy)
 [============================] 100%  40 secs/40 secs  2261 rows

aggregate: skipping

Cronjob

Wenn die manuelle Kopie erfolgreich war kann ein cronjob eingerichtet werden. Z.B. täglich:

0 2 * * * /usr/bin/php /var/www/volkszaehler.org/vendor/bin/dbcopy copy -c /etc/dbcopy.yaml > /dev/null

Restore

Um eine Sicherung wiederherzustellen eine Konfiguration anlegen bei der Ziel und Quelle vertauscht sind. Der User vz hat allerdings nicht genügend Rechte.
Deshalb user: vz-admin mit password: secure verwenden.

Während des Restore dürfen auf keinen Fall neue Daten ankommen, das wird zu doppelte IDs und Abbruch führen. Daher alle Quellen stoppen die direkt oder indirekt auf die Datenbank zugreifen: Vzlogger, Scripte, ESP32, Cronjobs (aggregate), etc.

Wenn beim Backup die Aggreagtionstabelle ausgelassen wurde sollte diese vor Inbetriebnahme der Cronjobs erstmals neu aufgebaut werden.

php /var/www/volkszaehler.org/bin/aggregate run -m full -l day -l hour -l minute

Das kann bei einer entsprechend großen Datenbank einige Stunden dauern und doppelte Ausführung des Sripts (per cron) würde zu Fehlern führen.