Posts Tagged ‘MySQL’

Sonntag, 25. November 2018

Neue MySQL-Spalte einer gefüllten Tabelle mit aufsteigenden Zahlenwerten füllen

Für ein Projekt habe ich mich heute einer vorzüglichen mehrsprachigen Länder-Liste bedient. Einziges Problem: Alle Tabellen in meiner Datenbankstruktur besitzen als Primary Key die Spalte id mit aufsteigenden Werten. Wie fügt man aufsteigende Werte in eine neue Spalte einer bestehenden MySQL-Tabelle ein, bevor man den Primary Key von der Spalte code entfernt und die Spalte id als Primary Key definiert? Ganz einfach:

SET @pos := 50;
UPDATE laender SET id = ( SELECT @pos := @pos + 1 ) ORDER BY code ASC;

Quelle: How to update a MySQL column with ascending numbers

Hinweis: Auf Grund von bereits bestehenden Verknüpfungen mit der ursprünglichen Länder-Tabelle (die aus knapp 20 Ländern bestand) entschied ich mich, die IDs für die bestehenden Länder zu übertragen. Deshalb startete ich für die vollständige Liste mit einem Primary Key von 50, um nicht mit den alten Keys in Konflikt zu geraten.

Tags: , , , , ,
Labels: IT, Web

Keine Kommentare | neuen Kommentar verfassen

Samstag, 4. August 2018

logrotate meldet „mysqladmin: connect to server at ‚localhost‘ failed“

/etc/cron.daily/logrotate:
mysqladmin: connect to server at 'localhost' failed
error: 'Access denied for user 'root'@'localhost' (using password: NO)'
error: error running shared postrotate script for '/var/log/mysql/mysql.log /var/log/mysql/mysql-slow.log /var/log/mysql/mariadb-slow.log /var/log/mysql/error.log '
run-parts: /etc/cron.daily/logrotate exited with return code 1

Hat man das root-Passwort angepasst (sprich: es ist nicht mehr leer, wie standardmässig vorgegeben), muss man das Passwort in der Datei /etc/mysql/debian.cnf ergänzen.

Die dort erfassten Parameter werden vom logrotate-Script unter /etc/logrotate.d/mysql-server eingelesen und zum Zugriff verwendet.

Quelle: MySQL logrotate error

Tags: ,
Labels: Linux

2 Kommentare | neuen Kommentar verfassen

Donnerstag, 22. März 2018

cacti benötigt die MySQL Zeitzonen-Datenbank

Vor kurzem habe ich meine cacti-Installation „gelüpft“. Leider kam es vorübergehend zu einem Showstopper, weil die Software nach einer MySQL Timezone database verlangt, welche ich nicht installiert hatte:

ERROR: Your MySQL TimeZone database is not populated. Please populate this database before proceeding.

Wieso das sonst sehr benutzerfreundliche cacti-Installationsscript diese Datenbank in so einem Fall nicht einfach nachinstalliert, wissen nur die Geier.

Es war also Handarbeit angesagt — nach etwas googlen kein Problem:

$ mysql -u root -p mysql < /usr/share/mysql/mysql_test_data_timezone.sql

Quelle: Upgrade problem MySQL Timezone

Die Empfehlung, dem cacti-Benutzer zudem noch die Leseberechtigung auf die Tabelle mysql.time_zone_name zu geben, war bei mir nicht nötig.

Offenbar gibt es bei MySQL auch einen eigenständigen Befehl, der die Sache installiert – getestet habe ich das aber nicht:

$ mysql_tzinfo_to_sql tz_dir

Quelle: 4.4.6 mysql_tzinfo_to_sql — Load the Time Zone Tables

Tags: , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 22. März 2018

mysqldump: MySQL-Benutzer hat keine Rechte, eine Tabelle zu sperren

Als ich kürzlich ein selten gebrauchtes Backup-Script ausführen wollte, kam ich folgende Fehlermeldung zu Gesicht:

mysqldump: Got error: 1044: "Access denied for user 'username'@'10.1.2.3' to database 'app_app'" when using LOCK TABLES

Die Lösung für das Problem ist eigentlich ganz simpel. Entweder über die mysql-Kommandozeile:

GRANT LOCK TABLES ON app_app.* TO 'username'@'10.1.2.3';
FLUSH PRIVILEGES;

… oder über phpMyAdmin, wo man dem zutreffenden Benutzer unter mysql > Tables > db ein Häkchen bei Lock_tables_priv setzt …

… den Datensatz speichert und danach die Benutzerprivilegien neu lädt, indem man im Menupunkt „SQL“ den Befehl „FLUSH PRIVILEGES“ eingibt und das Kommando ausführt.

Tags: , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Montag, 16. Mai 2016

MariaDB (MySQL) meldet „ERROR 1436 (HY000) at line 574: Thread stack overrun“

Damit die Migration von MySQL nach MariaDB sauber abläuft, ist es wichtig, nach der De-Installation von MySQL und der erfolgreichen Installation von MariaDB folgendes Kommando auszuführen (Anstoss war eine Fehlermeldung in mysql.log):

# mysql_upgrade
...
ERROR 1436 (HY000) at line 574: Thread stack overrun:  5904 bytes used of a 131072 byte stack, and 0 bytes needed.  Use 'mysqld --thread_stack=#' to specify a bigger stack.

Blöd nur, wenn diese Fehlermeldung erscheint. Nach einer kurzen Google-Suche stellte sich heraus, dass mein Konfigurationstuning in /etc/mysql/my.cnf einen Kollateralschaden verursacht hatte. In der Konfigurationsdatei hatte ich nämlich eingestellt:

...
[mysqld]
...
thread_stack		= 128K

Dieser Wert berechnet sich für jedes System basierend auf dessen Eigenschaften und es macht deshalb keinen Sinn, den Wert in my.cnf hartzukodieren, wie der Artikel MySQL error 1436: Thread stack overrun, with simple query aufzeigt.

Das Problem löste sich in Luft auf, indem ich den Eintrag auskommentierte …

#thread_stack		= 128K

… und den Datenbankserver neu startete:

# systemctl restart mysql

Tags: , , , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Montag, 16. Mai 2016

MariaDB (MySQL) meldet Errcode: 24 „Too many open files“

Vorgestern habe ich auf Grund von Performance-Problemen beim Umstieg auf cacti spine die Datenbank auf meinem Linux-Server ausgetauscht: Statt MySQL kommt nun MariaDB zum Einsatz.

Heute nun wurde ich auf einen Kollateralschaden aufmerksam. Jede Nacht lasse ich ein Script laufen, welches meine MySQL-Datenbanken sperrt (LOCK-ed) und die Datenbankdateien in ein Sicherungsverzeichnis kopiert. Mit tarsnap schreibe ich die Datenbankdateien dann weg in die Cloud und habe so versionierte Datenbankbackups.

Seit dem Wechsel und einigen Anpassungen an der MySQL-Konfiguration (my.cnf) traten bei der Verwendung des Scripts Probleme auf:

...
site_wedding
     /home/mysql/site_wedding.sql
mysqldump: Error: 'Out of resources when opening file '/tmp/#sql_4fde_2.MAD' (Errcode: 24 "Too many open files")' when trying to dump tablespaces
mysqldump: Got error: 23: "Out of resources when opening file './site_wedding/log.MYD' (Errcode: 24 "Too many open files")" when using LOCK TABLES
...

Und auch im mysql.log las ich:

...
May 16 06:30:02 ALPHA mysqld: 160516  6:30:02 [ERROR] Error in accept: Too many open files

Den Fehler behob ich mit folgenden Massnahmen:

Im Zuge des Performance-Tunings der Datenbank (für cacti spine) hatte ich folgende Zeilen in my.cnf eingefügt:

...
[mysqld]
...
open_files_limit	= 80000
...

Beim Starten der Datenbank mittels

# systemctl start mysql

fand sich im MySQL-Log folgender Eintrag:

...
May 16 12:55:45 ALPHA mysqld: 160516 12:55:45 [Warning] Could not increase number of max_open_files to more than 1024 (request: 80162)
...

Offenbar waren 1024 gleichzeitig geöffnete File Handles nicht ausreichend.

Ich nahm deshalb folgende Anpassung an /etc/security/limits.conf vor:

...
mysql hard nofile 102400
mysql soft nofile 102400

Quelle: How to permanently raise ulimit ‚open files‘ and MySQL ‚open_files_limit‘

Ein Neustart von MySQL löste das Problem aber nicht; die Fehlermeldung im Log blieb bestehen (eventuell muss man den Server neu starten, damit diese Limits aktiv werden?).

Ein wenig Recherche fügte dann zu Tage, dass man dem MySQL-Server via der systemd Service-Datei selber eine Maximalzahl an File Handles zuweisen kann.

Unter Debian findet sich die Service-Datei unter /etc/systemd/system/mysql.service, wo ich folgende Zeile einfügte:

...
[Service]
...
LimitNOFILE=infinity

Anschliessend musste ich folgenden Befehl ausführen, damit die Anpassungen von systemd zur Kenntnis genommen werden:

# systemctl stop mysql
Warning: mysql.service changed on disk. Run 'systemctl daemon-reload' to reload units.
# systemctl daemon-reload
# systemctl start mysql

Beim Neustart von MySQL erschien die Fehlermeldung im mysql.log erneut, dieses Mal aber mit einer deutlichen höheren Zahl an gleichzeitig geöffneten Dateien:

...
May 16 13:02:57 ALPHA mysqld: 160516 13:02:57 [Warning] Could not increase number of max_open_files to more than 65536 (request: 80162)
...

Good enough, dachte ich mir. Deshalb entschied ich mich, erneut my.cnf anzupassen:

...
[mysqld]
...
open_files_limit	= 60000
...

Noch einmal den Server neu starten, und gut war es:

# systemctl stop mysql
# systemctl start mysql

Bei der manuellen Ausführung des Scripts lief die Sause anschliessend durch, ohne zu stocken.

Tags: , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 17. Januar 2016

MySQL meldet Fehler 2049

Vor einigen Wochen habe ich im Zuge eines apt-get upgrade MySQL auf meinem Linux-Server zu Hause aktualisiert. Wie gelegentlich der Fall resultierte das Update in einem Kollateralschaden. In meinem PHP Error-Log las ich nach dem Update für einige meiner Web-Applikationen folgendes:

MySQL returned error #2049: Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)

Nach etwas Googeln stellte sich heraus, dass einige meiner MySQL-Benutzer ihr Passwort noch mit einem uralten MySQL-Hash in der Datenbank liegen hatten:

Support for pre-4.1 password hashes is removed in MySQL 5.7.5. This includes removal of the mysql_old_password authentication plugin and the OLD_PASSWORD() function.

Quelle: 6.1.2.4 Password Hashing in MySQL

Nachdem ich die Klartext-Passwörter im PHP-Code der Applikationen ausfindig gemacht hatte, änderte ich diese mittels phpMyAdmin in den MySQL-Benutzertabelle und verwendete dafür die PASSWORD()-Funktion.

Noch ein FLUSH PRIVILEGES, und die Web-Applikationen funktionierten wieder ohne Murren.

Tags: , , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 14. Dezember 2014

MySQL-Query auf Dev blitzschnell, in Prod extrem langsam

Am Freitag habe ich mich entschieden, eine bisher nur auf meinem lokalen Mac mini in einem Vagrant-Container laufende Web-Applikation auf meinen „produktiven“ Web-Server bei der Cyon GmbH zu verschieben.

Es handelt sich um eine Applikation, mit welcher Fragen einer Zertifizierungsprüfung mittels Multiple Choice beantwortet werden können. Eine Unterseite der Applikation berechnet aus dem Log der bisher getätigten Antworten Statistiken.

Nach einigen Minuten lief die Web-Applikation und der aktuellste MySQL-Dump war ebenfalls auf dem Server eingespielt. Doch dann kam das böse Erwachen: Beim Aufruf einer neuen Frage wartete ich unzählige Sekunden auf eine Antwort des Servers, bis die Ausführung des PHP-Scripts dann mit einem Timeout abbrach.

Was zum Teufel? Rasch war klar, dass ein SQL-Query zur Berechnung von Statistiken der Übeltäter war.

Auf Dev lief das MySQL-Query folgendermassen rasch durch:

[12-Dec-2014 13:22:18 Europe/Zurich] I - mysql->query() took 0.1694 secs in /var/www/apps/%APP%/inc/%APP%.class.php:343 for URI (Referer: unknown) from IP 192.168.1.1 with User Agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10"

Auf Prod hingegen loggte ich diesen Zeitwert:

[12-Dec-2014 12:40:18 Europe/Zurich] I - mysql->query() took 47.8917 secs in %PATH%%APP%.class.php:343 for URI <%URI%> (Referer: %REFERER%) from IP %IP% with User Agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10"

Eine Verlangsamung von mehr als dem 200-fachen!

Als erstes prüfte ich die Versionen der Datenbank-Software:

Dev

-- Server version	5.6.21-1~dotdeb.1

Prod

-- Server version	5.5.40-cll

Ich verwendete also eine Zehntelsversion bessere Datenbank.

Anschliessend liess ich mir das Query sowohl in Dev als auch in der Produktion „erklären“ (EXPLAIN):

Dev

EXPLAIN-localhost

Prod

EXPLAIN-cyon

Der Unterschied: Auf Prod führte MySQL ein „Dependent Subquery“ aus, auf Dev „nur“ (?) ein „Subquery“. War das das Problem?

Da mir EXPLAIN hier nun wirklich nicht weiterhalf, wendete ich mich Google zu. Folgende zwei Stackexchange-Artikel erheischten meine Aufmerksamkeit:

Beim Lesen der Antworten kam mir plötzlich die Idee: Vielleicht sind INDEXe deine Freunde? Ich wählte die Spalte Questions-id (`Questions-id` varchar(64) NOT NULL, CLSIDs enthaltend) aus und versah sie mit einem Index.

Und siehe da, beim nächstem Aufruf der Web-Seite wurde folgender Zeitwert registriert:

[12-Dec-2014 23:33:09 Europe/Zurich] I - mysql->query() took 0.0412 secs in %PATH%%APP%.class.php:343 for URI <%URI%> (Referer: %REFERER%) from IP %IP% with User Agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10"

Der zusätzliche Index auf einer Spalte auf hat mein Performance-Problem zu meiner vollsten Zufriedenheit gelöst. Wieso der Index aber in Version 5.6 von MySQL nicht mehr benötigt wird, ist mir derzeit noch ein Rätsel. Wahrscheinlich haben die Entwickler die Subquery-Performance in dieser Version stark verbessert?

Tags: , , , , , , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 10. Juli 2014

MySQL meldet „Using unique option prefix X instead of Y is deprecated“

Warning: Using unique option prefix database instead of databases is deprecated and will be removed in a future release.
Please use the full name instead.

MySQL reklamiert dies, weil die Namen einiger Argumente und Konfigurationsparameter in den kommenden Releases umbenannt werden.

Im Script zur Sicherung meiner Datenbanken war die Anpassung simpel:

...
$MYSQLDUMP --user=$USER --password=$PW --database $DATABASE > "$DUMPFILE"
...

… wurde zu …

...
$MYSQLDUMP --user=$USER --password=$PW --databases $DATABASE > "$DUMPFILE"
...

Man beachte, dass in der ursprünglichen Version der Parameter databases noch im Singular (database) aufgeführt war.

Denkanstoss: Thread: Using unique option prefix pass instead of password is deprecated

Tags: ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 29. Juni 2014

PHP kann unter Mac OS X nicht mit MySQL kommunizieren

Da war ich am Donnerstag in den beeindruckenden neuen Räumlichkeiten meines ehemaligen Arbeitgebers Liip und nahm am Hackday teil, wo ich mich anfänglich mit der Konfiguration von Docker befasste — und war dann auf meinem MacBook Air in einem anderen Zusammenhang mit Verbindungsproblemen zwischen PHP und der MySQL-Datenbank konfrontiert.

PHPs mysqli meldete:

Error: 2002 - No such file or directory

Das Problem lag gemäss dieser Diskussion auf Stack Overflow darin begründet, dass ich nach dem Upgrade auf Mavericks die mitgelieferte php.ini unter /etc/php.ini verwendete, welche für Mac OS X nicht anwendbare Standardwerte für die Verbindung zu MySQL enthielt.

Nachdem ich die Einträge

...
pdo_mysql.default_socket=/var/mysql/mysql.sock
mysql.default_socket = /var/mysql/mysql.sock
mysqli.default_socket = /var/mysql/mysql.sock
...

in

...
pdo_mysql.default_socket=/tmp/mysql.sock
mysql.default_socket = /tmp/mysql.sock
mysqli.default_socket = /tmp/mysql.sock
...

geändert hatte und Apache mittels

# apachectl graceful

neugestartet hatte, sprach PHP problemlos mit MySQL.

Solche Handstände sind künftig nicht mehr nötig, da ich nun endlich meine Vagrant-Installation vom Mac mini hier auf das MacBook transferiert habe.

Tags: , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen