Kategorien
MySQL PHP Symfony

Strato und MySQL: General error: 1709 Index column size too large. The maximum column size is 767 bytes.

Bei einem Kunden wurde mir folgende Fehlermeldung angezeigt, wenn ich versucht habe über Symfony die Datenbank erstellen zu lassen:

General error: 1709 Index column size too large. The maximum column size is 767 bytes.

Dies liegt daran, das Strato so komische Einstellung bei ihren Managed Hosting Packete wie z.B. das STRATO PowerWeb hat. Strato wird diese Einstellung leider nicht ändern, aber man kann in Symfony in der doctrine.yaml (config.yaml) das Charset ändern, dann funktioniert Symfony auch auf einem Strato Server:

doctrine:
    dbal:
        # configure these for your database server
        driver: 'pdo_mysql'
        server_version: '5.6'
        charset: utf8
        default_table_options:
            charset: utf8
            collate: utf8_general_ci
Kategorien
Amazon AWS Docker GIT MySQL PHP PHP 7 Projekte Redis Symfony

Projekt: baby-taschenrechner.de

Das gerade fertiggestellt Projekt baby-taschenrechner.de beschäftigt sich mit den Fragestellungen rund um die Entwicklung des eigenen Kindes:

  • Wie groß wird mein Kind werden in x-Jahren
  • Wie schwer wird mein Kind in x-Jahren
  • Ist mein Kind zu schwer/zu dünn
  • Welche Kleidergröße wird es wann tragen?

Die Webseite soll Eltern dabei helfen herauszufinden, wann sie welche Kleidergröße kaufen müssen, um im nahenden Winter/Sommer das passende zu Hause zu haben.

Eltern können so einschätzne, ob das Kind zu dünn oder zu dick ist  für ihr Alter/Größe/Gewicht-Verhältnis.

Für die Realiserung wurden folgende Technologien verwendet:

Symfony 3, Docker, MySQL, PHP, GIT, Google Material Design, Amazon AWS

Kategorien
MySQL

MySQL ProcessList unter Linux beobachten

Wenn man die Process List von MySQL sich ständig aktualisiert anzeigen lassen will, kann man den watch Lionux Befehl auf der Console dafür benutzen. Login, Host und Passwort müssen ggf. geändert werden:

watch -n 1 "mysql -u root --password='myPassword' -h localhost -s -e 'SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE 1 = 1;'"
Kategorien
MySQL Server Administration

MySQL Monitoriong der ProcessList / Queries mit einem Konsolen Befehl

Ein hilreicher Befehl für die problem-Analyse von MySQL Servern ist sich die ProcessList anzuschauen, um zu sehen, welche Quueries aktuell ausgeführt werden. Wenn man dies kombiniert mit dem watch Befehl und diesen 1 mal pro Sekunde neuladen lässt und auf die Queries reduziert, hat man eine guter Übersicht, was auf dem MySQL Server los ist und welche Queries problematisch seien könnten:

watch -n 1 "mysql -u root --password='XXX' -h localhost -s -e 'SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE Command=\"Query\";'"

Wichtig ist, den Befehl als root laufen zu lassen, um auch alle Queries zu sehen.

Mit Hilfe des Parameter -n kann man die Aktualisierungrate in Sekunden angeben.

Das MySQL root-Passwort ist zu ergänzen.

 

Ausgabe:

5361925476      user     localhost       NULL    Query   0       executing       SELECT * FROM xxx WHERE yyy

5361925477      user     localhost       NULL    Query   0       executing       UPDATE zzz WHERE zzz
Kategorien
MySQL

MySQL eigener Variablen in Query verwenden

Es ist sehr einfach möglich in MYSQL Variablen zu verwenden für MySQL Statements. Diese müssen definiert werden mit der SET Funktion und dem @-Prefix:

SET @a= 'a';

Und kann dann benutzt werden für die Dauer der DB-Session:

UPDATE my_table SET x = @a WHERE y = @a;

 

Kategorien
MySQL

History für MySQL Tabelle anlegen

Wenn man loggen will, wer wann und welche Änderungen an einer Tabelle „tabelle1“ gemacht hat, sollte man sich eine Tabelle namens „tabelle1_history“ und automatisch per MySQL Trigger auf Update und Delete Ereignisse reagieren:

Hinweis: __XYZ__ Platzhalter sind zu ersetzen

Trigger auf Update Aktionen

CREATE DEFINER=`__USER__`@`%` TRIGGER `__DB__`.`__TRIGGER_NAME_DEL__` BEFORE DELETE ON `__DB__`.`__TABLE__` FOR EACH ROW BEGIN
    insert into
        __DB__.__TABLE_HISTORY__
        (
        dataset_id,
        my_data1
        my_data2
        created_on
        created_by
        )

    VALUES (
        OLD.id,
        OLD.my_data1
        OLD.my_data2
        OLD.created_on,
        OLD.created_by
  );

Trigger auf Delete Aktionen

CREATE DEFINER=`__USER__`@`%` TRIGGER `__DB__`.`__TRIGGER_NAME_UPDATE__` BEFORE UPDATE ON `__DB__`.`__TABLE__` FOR EACH ROW BEGIN
        insert into
        __DB__.__TABLE_HISTORY__
        (
        dataset_id,
        my_data1
        my_data2
        created_on
        created_by
        )

    VALUES (
        OLD.id,
        OLD.my_data1
        OLD.my_data2
        OLD.created_on,
        OLD.created_by
  );
Kategorien
MySQL

MySQL Update Deadlock InnoDB

Ein kniffeliges Problem ist letztens aufgetreten bei einer partitionierten MySQL Datenbank. Es kam immer wieder bei hoher Last zu Deadlock Meldungen seitens MySQL. Immer waren 2 Queries davon betroffen, die dieselbe Form hatten:

--Query1:
UPDATE myTable SET createdOn='2016-05-23 16:08:29', foo='y' WHERE id=1
--Query2:
UPDATE myTable SET createdOn='2016-05-23 16:08:29', foo='x' WHERE id=2

Im MySQL Error Log war ein solcher Eintrag zu finden:

mysql tables in use 1, locked 1
LOCK WAIT 106 lock struct(s), heap size 8400, 53 row lock(s)

Tip: Mit der Systemvariablen innodb_print_all_deadlocks (ab MySQL 5.5) kann man Deadlocks in InnoDB in das MySQL Error Log loggen und besser debuggen.

Eigentlich sollte es bei den beiden Queires nicht zu einem Deadlock kommen, da beide nur jeweils ein Row-Level Lock auf ihrer jeweilige Zeile haben sollten.

Dies ist auch der Fall, wenn es einen Index auf der Spalte id gibt. In diesem Fall allerdings war durch die Partitionierung der Primary (Unique) Index auf  2 Spalten gelegt worden (kombinierten Index): id und createdOn.

Dadurch, dass der Index auf beiden Soalten gelegt worden ist, kam es zu den dem Dealocks. Die Lösung war, das createdOn aus dem Update Statement zu entfernen, weil es an der Stelle auch keinen Sinn gemacht hat.

Kategorien
MySQL Server Administration

Importieren und Exportieren alle MySQL Datenbanken unter Windows und Mac

Unter Windows kann man mit einem Befehl sehr leicht alle Daten exportieren in MySQL mit mysqldump:

cd C:\xampp\mysql\bin
mysqldump.exe -u root -p --opt --all-databases --verbose > C:\export.sql

 

Erläuterung:

 –opt:  Export alle DBs, ohne „system“ databases wie mysql, information_schema, performance_schema und test

 –verbose: um log Meldungen anzuzeigen auf dem Bildschirm, es sind nicht viele, so dass die Performance nicht beeinflusst wird großartig

Kategorien
MySQL

MySQL Spalte kopieren innerhalb desselben Datensatzes

Wenn man bspw. eine Spalte inserted einfügen will und diese inital mit dem schon vorhandenen last_change Werten ausstatten will, kann man folgenden Code benutzen:

UPDATE table_name dt1, table_name dt2 SET dt1.inserted = dt2.last_change WHERE dt1.id = dt2.id
Kategorien
MySQL

Importieren/Exportieren großer MySQL Datenbanken unter Xampp

Beim Importieren großer Datenmengen unter Xampp stößt man über den Weg von phpMyAdmin schnell auf Grenzen der Skriptlaufzeit oder auf Performance-Grenzen:

Fatal error: Maximum execution time exceeded

Diese kann zwar angepasst werden, aber ein solcher Import kann Stunden dauern. Der Import über die Konsole ist um den Faktor 10 schneller. Statt einer Stunde benötigt man damit nur ein paar Minuten und hat keine Probleme mit der Skriptlaufzeit oder ähnlichem. Am schnellsten und unkompliziertesten ist ein Import über die MySQL-Konsole:

  • einfach im Xampp Control Panel auf shell klicken und dann in der Konsole die folgenden Befehle eingeben:
mysql -u root -p

Passwort eingeben oder einfachmit ENTER bestätigen, wenn kein passwort festgelegt wurde. Root ist der Benutzer der Datenbank, kann abweichen. Dann die Datenbank auswählen, die importiert werden soll, ggf. vorher anlegen, wenn diese nicht existent.