mysql: Alle Konfigurationsoptionen anzeigen

Leider gibt es keine Option in mysql um sich alle konfigurierten Optionen anzeigen zu lassen.

Mittels folgendem Code kann man dies aber von mysql Abfragen:

{ echo -e "# MYSQL VARIABLES {{{1\n##\n# MYSQL `mysql -V|sed 's,^.*\(V.*\)\, for.*,\1,'` - By: `logname`@`hostname -f` on `date +%c`\n##"; for l in {a..z}; do echo '#'; mysql -NBe "SHOW GLOBAL VARIABLES LIKE '${l}%'" | sed 's,\t,^= ,' | column -ts^ | tr "\n" '@' | eval $(echo "sed '" "s,@\("{a..u}{a..z}"\),\n\n\1,;" "'") | eval $(echo "sed '" "s,@\(innodb_"{a..z}{a..z}"\),\n\n\1,;" "'") | tr '@' "\n" | sed 's,^,# ,g'; done; echo -e "#\n##\n# MYSQL VARIABLES }}}1"; } | tee ~/mysql-variables.log

Quelle: Mysql Export current configuration to a file

mysql Passwort zurücksetzen

Wenn man das root Passwort des mysql Servers vergessen hat, lässt sich dieses wie folgt zurücksetzen:

Zuerst muss man mysql beenden und dann manuell im „safe mode“ starten. Danach kann man sich mit root ohne Passwort anmelden:

/etc/init.d/mysqld stop
mysqld_safe --skip-grant-tables &
 
mysql -uroot

Nun kann das Passwort in mysql neu gesetzt werden:

USE mysql;
 
UPDATE USER SET password=PASSWORD("NeuesPasswort") WHERE USER='root';
 
FLUSH privileges;
 
quit

Zu guter leztzt muss man den manuell gestarteten mysql Prozess wieder killen und kann mysql normal starten. Danach ist ein Login mit dem neuen Passwort wieder möglich:

killall mysqld
 
/etc/init.d/mysqld start
 
mysql -u root -p

mysql: Datenbank-Replikation einrichten

Mittels der mysql Datenbank-Replizierung kann man eine automatisch aktualisierende Kopie einer oder mehreren Datenbanken auf einem anderen Server haben.

Dies hat zwei grosse Vorteile:

  • Man hat eine failover-Datenbank, falls die Haupt-DB down ist
  • Man kann die SELECT Abfragen auf mehren Hosts verteilen und hat so einen Lastausgleich.

Grundsätzliches

mysql sieht vor, dass es einen sog. "Master" Server gibt auf dem die Datenbanken verwaltet werden und ein- oder mehrere "Slave"-Server die immer eine aktuelle Kopie tragen. Allerdings ist es normalerweise nicht möglich updates auch auf dem slave-server zu machen, d.H. die slave server sind eigentlich nur für LESE-, nicht aber für Schreibzugriffe da.

Die Funktionsweise geht so, dass der MASTER-Server sämtliche Anweisungen in ein sog. binlog (mysql-bin) schreibt und an die SLAVES sendet. Der SLAVE schliesslich entscheidet mittels des Parameters "replicate-do-db", welche Datenbanken er repliziert.

Konfiguration

Master

Zuerst setzen wir in der my.cnf des Master-Hosts die folgenden Optionen:

[mysqld]
max_allowed_packet              = 16M
server-id                       = 1
log-bin                         = mysql-bin
expire_logs_days                = 7
max_binlog_size                 = 100M
innodb_flush_log_at_trx_commit  = 1
sync_binlog                     = 1
auto_increment_increment        = 1
auto_increment_offset           = 1

Und startet diesen (neu).

Hinweis: server-id
Die server-id kann eine beliebige Zahl sein, sie muss aber bei jedem Server unterschiedlich sein.
Damit man also nicht ausversehen zwei hosts die gleiche server-id zuweist, nimmt man am besten dessen IP-Adresse, entfernt die Punkte und nimmt das als server-id.

Wenn also z.B. ein Server die IP-Adresse: 192.168.1.100 hat, dann wäre dessen server-id: 1921681100

Nun wird ein Benutzer für den slave angelegt:

[root@MASTER ~]# mysql -uroot -p
mysql> GRANT REPLICATION SLAVE ON . TO 'slave'@'%' IDENTIFIED BY 'topsecret';

Slave

Auf dem slave müssen die folgenden Optionen gesetzt werden:

[mysqld]
server-id                       = 2
relay-log                       = mysqld-relay-bin
report-host                     = slave-server01
auto_increment_increment        = 2
auto_increment_offset           = 2
replicate-do-db                 = DB1
replicate-do-db                 = DB2
slave_max_allowed_packet        = 16M
read_only                       = 1
Hinweise

auto_increment_increment und auto_increment_offset
Diese Parameter sollten idealerweise einen anderen Wert haben als alle anderen Server, da es sonst Probleme bei den AUTO-INCREMENT Werten geben könnte.

replicate-do-db
Hier wird angeben welche Datenbanken repliziert werden.
ACHTUNG: Für jede Datenbank muss zwingend eine neue Zeile verwendet werden! So etwas wie: „replicate-do-db = DB1, DB2“ würde nicht funktionieren!

slave_max_allowed_packet
Dieser Wert darf beim slave nicht kleiner sein als die Einstellung: read_buffer_size auf dem Server, sonst kann es zu Problemen kommen

Nun kann man auch den slave starten.

Allerdings müssen nun zuerst die Initial-Daten auf den SLAVE geladen werden.
Dazu erstellen wir auf dem master ein mysqldump:

[root@MASTER ~] mysqldump -uroot -p --master-data --databases DB1 DB2 > slave.sql

Dieses slave.sql wird nun auf den SLAVE Server kopiert und eingespielt, nachdem zuvor die SLAVE-Replikation gestoppt wurde:

[root@SLAVE ~] mysql -uroot -p
mysql> SLAVE STOP;
mysql> quit
 
[root@SLAVE ~] mysql -uroot -p < slave.sql
[root@SLAVE ~] mysql -uroot -p
mysql> CHANGE MASTER TO MASTER_HOST='master-server', MASTER_USER='slave', MASTER_PASSWORD='topsecret';
mysql> SLAVE START;
mysql> SHOW SLAVE STATUS \G;
mysql> quit

Im SLAVE STAUS kann man nun sehen ob die Replikation läuft:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Slave-Replikation kaputt?
Es kann ab und zu vorkommen, dass die Replikation auf den slave nicht mehr funktioniert.

Dann reicht es aber, den letzten Schritt (mysqldump auf master laden und auf slave einspielen) zu wiederholen und alles sollte wieder laufen.

Falls das nicht funktioniert muss man auf dem master vor dem dump die Tabellen locken:

[root@SLAVE ~] mysql -e 'slave stop;'
 
[root@MASTER ~] mysql -uroot -p
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS \G
mysql> SYSTEM mysqldump -uroot -p --master-data --databases DB1 DB2 > slave.sql
mysql> UNLOCK TABLES;
mysql> quit

Danach auf dem slave einfügen und MASTER_LOG_FILE / MASTER_LOG_POS mit den Werten aus der Ausgabe vom master füllen:

[root@SLAVE ~] mysql -uroot -p < slave.sql
[root@SLAVE ~] mysql -uroot -p
mysql> CHANGE MASTER TO MASTER_HOST='master-server', MASTER_USER='slave', MASTER_PASSWORD='topsecret', MASTER_LOG_FILE='mysql-bin.000000', MASTER_LOG_POS='00000000';
mysql> SLAVE START;
mysql> SHOW SLAVE STATUS \G
mysql> quit
[root@SLAVE ~] mysql -e 'show slave status\G'

Troubleshooting

Slaves klonen

Hat man mehrere slaves und einer fällt aus der Synchronisation (etwa weil ausersehenen auf den slave geschrieben wurde), kann man diesen von einem anderen klonen:

[root@SLAVE1 ~] systemctl stop mysql
[root@SLAVE1 ~] cp -pvR /var/lib/mysql /var/lib/mysql.bak
[root@SLAVE1 ~] rsync -ahv --delere slave2:/var/lib/mysql/ /var/lib/mysql/
[root@SLAVE1 ~] cp -v /var/lib/mysql.bak/data/auto.cnf /var/lib/mysql.bak/data/auto.cnf
[root@SLAVE1 ~] systemctl start mysql
Achtung gleiche UUID

Nebst der server_id, welche einen slave eindeutig kennzeichnet, generiert mysql noch eine UUID für jeden slave, welche in der Datei: auto.cnf im mysql Datenverzeichnis abgelegt wird.
Diese darf beim synchronisieren nicht mit kopiert-, bzw. muss danach entweder gelöscht (danngeneriert mysql eine neue) oder vom Backup rüber kopiert werden.
Ansonsten bekommt man die Meldung: „Slave I/O thread: Failed reading log event“.

Quellen

apache: An einer mySQL Datenbank authentifizieren

Die Methode mit .htaccess/.htpasswd ist vielen bekannt um ein Verzeichnis per passwort zu schützen – Und dies geht mit dem apache-modul: mod_auth_mysql auch über eine mysql Datenbank!

Die Möglichkeiten dieser Methode sind fast unerschröpflich, so kann z.B. ein Forum einen Verzeichnisschutz implementiert haben, bei dem man sich automatisch mit seinem normalen Foren-Login anmelden kann, usw.

Und so gehts:

Erst mal muss das mod_auth_mysql installiert werden, z.B. bei CentOS mittels:

yum install mod_auth_mysql

Dann legt man im zu schützenden Verzeichnis einfach ein normales .htaccess file an mit folgendem Inhalt:

AuthName "SeitenName"
AuthType Basic
AuthMySQLHost <DB_HOST>
AuthMySQLUser <DB_USER>
AuthMySQLPassword <DB_PASSWORT>
 
AuthMySQLDB <DB>
AuthMySQLUserTable <USER_TABELLE>
AuthMySQLNameField <FELD_NAME>
AuthMySQLPasswordField <FELD_PASSWORT>
AuthMySQLPwEncryption <passwort Verschlüsselung, z.B. md5>
AuthMySQLEnable On
AuthMySQLUserCondition "<ggf. weitere Kontitionen>"
require valid-user

Hier ist noch ein Beispiel, wie man das ganze auch auf Gruppenberechtigungen ausdehnen kann:

AuthName "YourSite"
AuthType Basic
 
# Database settings:
AuthMySQLHost localhost
AuthMySQLUser dbuser
AuthMySQLPassword dbpass
AuthMySQLDB dbname
 
# User table
AuthMySQLUserTable users
AuthMySQLNameField users.name
AuthMySQLPasswordField users.pass
 
# User Roles tables
AuthMySQLGroupTable "users, users_roles"
AuthMySQLGroupField users_role.rid
 
# Where clauses
AuthMySQLUserCondition "users.status = 1 and users.access <> 0"
AuthMySQLGroupCondition "users.uid = users_roles.uid AND users_roles.rid > 2"
 
# Do it to it!
AuthMySQLPwEncryption md5
AuthMySQLEnable On
require valid-user

Und wenn alles klappt kann man sich dann mit den Login-Daten aus der Datenbank anmelden! 😉

Quelle: [http://drupal.org/node/156547|drupal.org: Sharing authentication with HTTP-Auth]

postfix-mysql: queue file write error / Temporary lookup failure

Nachdem ich mein Postfix für die Verwendung mit mysql Tabellen konfiguriert hatte, bekam ich auf einmal beinahe täglich mails, die den Text: "451 4.3.0 Error: queue file write error" und/oder: "Temporary lookup failure" enthielten:

Transcript of session follows.
 
 Out: 220 mail.domain.tld ESMTP Postfix
 In:  EHLO [X.X.X.X]
 Out: 250-mail.domain.tld
 Out: 250-PIPELINING
 Out: 250-SIZE 10240000
 Out: 250-VRFY
 Out: 250-ETRN
 Out: 250-AUTH PLAIN LOGIN
 Out: 250-AUTH=PLAIN LOGIN
 Out: 250-ENHANCEDSTATUSCODES
 Out: 250-8BITMIME
 Out: 250 DSN
 In:  AUTH PLAIN XXXXXXXXXXXXXXXXXXXXXXX
 Out: 235 2.0.0 Authentication successful
 In:  MAIL FROM:<sender@example.org> SIZE=1037
 Out: 250 2.1.0 Ok
 In:  RCPT TO:<empfaenger@example.org>
 Out: 250 2.1.5 Ok
 In:  DATA
 Out: 354 End data with <CR><LF>.<CR><LF>
 Out: 451 4.3.0 Error: queue file write error
 
Session aborted, reason: lost connection

Zwar schien alles zu funktionieren und die mails kamen auch immer noch rein, ich wollte jedoch der Meldung nachgehen.

Im maillog wurde ich dann fündig, denn folgende Fehlermeldung tauchte ziemlich oft auf:

warning: mysql query failed: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=

Dies kam davon, weil ich die postfix Datenbank noch auf dem alten Server angelegt hatte und auf dem der Zeichensatz: latin1_swedish_ci standardmässig eingestellt war, beim neuen Server war jedoch UTF8 standard.

Das Problem kann man dann lösen, wenn man die Postfix Datenbank wie folgt konvertiert:

Login auf mysql:

mysql -uroot -p

dann für jede Tabelle:

ALTER TABLE tbl_name CHARACTER SET utf8 COLLATE utf8_general_ci;

und für jedes Textfeld:

ALTER TABLE tbl_name MODIFY email varchar(255) CHARACTER SET utf8;

Quelle