Wie man das Koha „auto increment“ Problem lösen kann
By zefanja
Wir verwenden [Koha für unsere Bibliothek][1], eine sehr mächtige und [tolle Open Source Software][2]. Auf Mailingliste des Projekts hatte ich bereits vom „Koha auto increment“ – Problem gelesen und hoffte, dass es uns nicht betraf. Doch vor einigen Wochen kam einer unserer Mitarbeiter der Schulbibliothek zu mir und gab mir ein Buch, dass sich nicht zurückgeben ließ. Jedes mal, wenn man versuchte, das besagte Buch zurückzugeben, bekam man folgende Fehlermeldung:
Unter Mehr → Über Koha im Reiter „Systeminformationen“ konnte ich dann sehen, dass einige Bücher von diesem Problem betroffen waren.
Doch worin liegt eigentlich das Problem? Wie konnte es dazu kommen?
Das Problem
Im Koha Wiki gibt es zu diesem Datenbankproblem eine [eigene Wiki-Seite][3]. Koha verschiebt Einträge zwischen Datenbanktabellen, wenn man z.B. einen Benutzer oder ein Buch löscht. Das gleiche passiert mit Ausleihen. Die Einträge in diesen Tabellen haben eine eindeutige ID, welche normalerweise automatisch hochgezählt wird (auto increment). Das Problem ist allerdings, dass MySQL diese Zähler nur im Arbeitsspeicher speichert und nicht auf der Festplatte. Dies tritt nur auf, wenn Einträge gelöscht werden. Ein Beispiel:
- Ich erstelle einen neuen bibliographischen Eintrag (z.B. ein Buch). Es wird u.a. in der Tabelle biblio gespeichert. Der Eintrag bekommt die ID 1. Der nächste Wert für die ID müsste also 2 sein.
- Jetzt lösche ich dieses Buch wieder. Der Eintrag wird in die Tabelle deletedbiblio verschoben. In der Tabelle biblio gibt es jetzt keinen Eintrag mehr.
- Ich starte den MySQL-Server neu. Dadurch wird der interne Zähler für die IDs zurückgesetzt.
- Nun lege ich ein neues Buch an. Es bekommt nicht die ID 2, sondern 1, weil es ja keinen Eintrag mehr in der Tabelle biblio gibt.
- Wenn ich jetzt dieses Buch lösche, wird es zwar aus der Tabelle gelöscht, aber nicht in die Tabelle deletedbiblio verschoben, da es dort schon einen Eintrag mit dieser ID gibt. Die Folge ist, dass in diesem Fall mein Eintrag für immer verloren ist.
Das passiert wie gesagt nicht nur mit bibliographischen Einträgen, sondern auch mit Ausleihen, Benutzern etc. Aus diesem Grund warnt Koha in den aktuellen Versionen vor dem Problem. Damit ist es aber noch nicht behoben.
Das Koha „auto increment“ Problem reparieren
Um zukünftig einen Datenverlust zu vermeiden, bringen wir MySQL bei, die IDs nicht zurückzusetzen, v.a. nicht auf einen Wert, den wir schon einmal verwendet haben. Dazu öffnen wir die Datei /etc/mysql/my.cnf
oder /etc/mysql/mariadb.conf.d/50-server.cnf
(wir verwenden einen Ubuntu 16.04 [LXD Container][4] mit MariaDB) und ergänzen im Abschnitt [mysqld]
folgende Zeile:
init-file=/var/lib/mysql/init-file_koha.sql ``` Dann erstellen wir eben diese Datei mit ``` $ sudo nano /var/lib/mysql/init-file_koha.sql ``` und kopieren den folgenden Inhalt in die Datei: ``` USE koha_DB_Name; SET @new_AI_borrowers = ( SELECT GREATEST( IFNULL( ( SELECT MAX(borrowernumber) FROM borrowers ), 0 ), IFNULL( ( SELECT MAX(borrowernumber) FROM deletedborrowers ), 0 ) ) + 1 ); SET @sql = CONCAT( 'ALTER TABLE borrowers AUTO_INCREMENT = ', @new_AI_borrowers ); PREPARE st FROM @sql; EXECUTE st; SET @new_AI_biblio = ( SELECT GREATEST( IFNULL( ( SELECT MAX(biblionumber) FROM biblio ), 0 ), IFNULL( ( SELECT MAX(biblionumber) FROM deletedbiblio ), 0 ) ) + 1 ); SET @sql = CONCAT( 'ALTER TABLE biblio AUTO_INCREMENT = ', @new_AI_biblio ); PREPARE st FROM @sql; EXECUTE st; SET @new_AI_biblioitems = ( SELECT GREATEST( IFNULL( ( SELECT MAX(biblioitemnumber) FROM biblioitems ), 0 ), IFNULL( ( SELECT MAX(biblioitemnumber) FROM deletedbiblioitems ), 0 ) ) + 1 ); SET @sql = CONCAT( 'ALTER TABLE biblioitems AUTO_INCREMENT = ', @new_AI_biblioitems ); PREPARE st FROM @sql; EXECUTE st; SET @new_AI_items = ( SELECT GREATEST( IFNULL( ( SELECT MAX(itemnumber) FROM items ), 0 ), IFNULL( ( SELECT MAX(itemnumber) FROM deleteditems ), 0 ) ) + 1 ); SET @sql = CONCAT( 'ALTER TABLE items AUTO_INCREMENT = ', @new_AI_items ); PREPARE st FROM @sql; EXECUTE st; SET @new_AI_issues = ( SELECT GREATEST( IFNULL( ( SELECT MAX(issue_id) FROM issues ), 0 ), IFNULL( ( SELECT MAX(issue_id) FROM old_issues ), 0 ) ) + 1 ); SET @sql = CONCAT( 'ALTER TABLE issues AUTO_INCREMENT = ', @new_AI_issues ); PREPARE st FROM @sql; EXECUTE st; SET @new_AI_reserves = ( SELECT GREATEST( IFNULL( ( SELECT MAX(reserve_id) FROM reserves ), 0 ), IFNULL( ( SELECT MAX(reserve_id) FROM old_reserves ), 0 ) ) + 1 ); SET @sql = CONCAT( 'ALTER TABLE reserves AUTO_INCREMENT = ', @new_AI_reserves ); PREPARE st FROM @sql; EXECUTE st; ``` > **Wichtig:** In der ersten Zeile müssen wir unbedingt _koha\_DB\_Name_ mit dem Datenbanknamen unserer Koha-Installation ersetzen. In der Regel ist das _koha\_name\_der\_koha\_instanz_, also z.B. _koha_library_. Zum Schluss starten wir noch MySQL bzw. MariaDB neu: ``` $ sudo service mysql restart ``` ### Fehlerhafte Datensätze aufräumen Nun haben wir zwar verhindert, dass das Problem wieder auftritt, aber es sind immer noch unserer alten Datensätze vorhanden. Ein Weg ist, die entsprechenden Einträge aus den _deleted*_ Tabellen zu löschen. Damit verliert man vielleicht ein paar statistische Informationen, aber auf die können wir in unserer kleinen Schulbibliothek verzichten. Sonst haben wir bisher keine negativen Auswirkungen feststellen können. Um die „fehlerhaften“ Datensätze zu löschen, müssen wir uns zuerst an unserem Koha-Server anmelden. Dann loggen wir uns in die MySQL-Konsole ein mit ``` $ sudo mysql -p koha_datenbankname Enter password: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 115 Server version: MariaDB Ubuntu 16.04 Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [koha_datenbankname]> ``` Oben im Screenshot sieht man, dass unsere fehlerhaften Datensätzen in den Tabellen _biblio_ und _deletedbiblio_ sind. Die IDs sind doppelt und wir löschen die IDs aus einer der beiden Tabellen, konkret aus _deletedbiblio_. Wir überprüfen zuerst, welche Datensätze betroffen sind: ``` MariaDB [koha_datenbankname]> SELECT * FROM deletedbiblio WHERE biblionumber IN (*hier die IDs aus dem Webinterface kopieren*); ``` Wenn wir die Datensätze wirklich löschen wollen ändern wir den Befehl leicht ab: ``` MariaDB [koha_datenbankname]> DELETE FROM deletedbiblio WHERE biblionumber IN (*hier die IDs aus dem Webinterface kopieren*); ``` Falls es z.B. auch problematische Datensätze mit den Ausleihen gibt, würde der Befehl so lauten: ``` MariaDB [koha_datenbankname]> DELETE FROM old_issues WHERE issue_id IN (*hier die IDs aus dem Webinterface kopieren); ``` Nun zeigt Koha keine fehlerhaften Datensätze mehr an: ### Fazit Wenn man dieses Problem in seiner Koha-Installation hat, ist es sehr ratsam dieses Problem zu lösen. Allerdings gibt es verschiedene Ansätze. Der oben beschriebene Weg ist ein schneller Fix, der aber unter Umständen nicht für jede Installation in Frage kommt. Seitens Koha wird noch an einem Skript gearbeitet, dass das Problem später automatisch beheben soll. Trotz diesem Datenbankproblem haben wir den Umstieg auf Koha bisher nicht bereut. Es ist und bleibt eine tolle Software, die sicher ihre Einarbeitungszeit braucht, aber der Gewinn, die Flexibilität und die damit gewonnen Freiheiten sind scheinbar grenzenlos.Setzt du Koha ein? Welche Erfahrungen hast du bisher gemacht?
[1]: https://zefanjas.de/umstieg-von-littera-zu-koha-teil-1/ [2]: https://zefanjas.de/5-grossartige-open-source-programme-die-wir-in-unserer-schule-einsetzen/ [3]: https://wiki.koha-community.org/wiki/DBMS_auto_increment_fix [4]: https://zefanjas.de/5-gruende-warum-wir-lxd-verwenden/