Wiederherstellen von MySQL Zugängen

Es folgt ein recht alter Hut. Mir ist nur gerade mal aufgefallen, das ich den folgenden Weg MySQL Zugänge anzulegen, wenn man die Zugangsdaten eines MySQL Servers vergessen oder versehentlich gelöscht hat, noch nie hier niedergeschrieben habe.

Es geht im großenn und ganzen darum, das man zunächst den MySQL Daemon beendet, ohne Zugangstabellen zu laden wieder startet, den gewünschten Zugang anlegt und nach einem Neustart des Daemons, dieses Mal mit Zugangstabellen, diesen User dann für die weiteren Schritte verwenden kann.

Zunächst ein kurzer Sicherheitshinweis: Für die folgenden Schritte empfiehlt es sich den MySQL Daemon nur von localhost/127.0.0.1 erreichbar zu machen, da für einen kurzen Zeitraum jedermann ohne Passwort administrativ auf den Server connecten kann. Um ganz sicher zu gehen, kann man auch noch einen anderen Port wählen um lokalen Schabernack zu unterbinden.

Das Vorgehen ist wie folgt:

  1. Beenden des MySQL Daemons
  2. Starten des MySQL Daemons ohne Zugriffstabellen:
    mysqld_safe --skip-grant-tables &
  3. Nun kann sich root ohne Passwort in die Datenbank "mysql" einloggen:
    mysql -uroot mysql
  4. Passwort neu setzen:
    UPDATE user SET password=PASSWORD("abcd") WHERE user="root";
    Das neue Passwort wäre nun "abcd". Es kann natürlich gesetzt werden wie immer es sein soll.
  5. (Optional) Zugriffsrechte neu einlesen:
    FLUSH PRIVILEGES;
  6. Da man sich immernoch ohne Passwort einloggen kann, sind alle mysql Prozesse zu beenden; notfalls zu killen (nur, wenn das init Script es per "stop" nicht schafft alles was MySQL ist zu beenden). Besonders gilt das für die mysql_safe Instanz (prüfen ob noch was läuft per "ps waux | grep -i mysql").
  7. Abschliessend MySQL wieder ganz normal starten.

Man hat so das Passwort des Users "root" wieder auf den in Punkt 4 verwendeten Wert gesetzt. Da dieses ja _der_ administrative User ist, können alle weiteren Korrekturen im ganz normalen, sicherem MySQL Kontext behoben werden.
Wenn man einen anderen User als "root" für seine administrativen Arbeiten verwendet, muss man selbstverständlich diesen in Punkt 3 und 4 statt "root" verwenden.

Teilen per: TwitterEmail


MySQL Fehler unter Ubuntu "'Can't create table '/tmp/#sql7c49_2f_0' (errno: -1)' on query."

Ich hatte heute auf einem MySQL Slave Server den folgenden Fehler bei der Replikation von einem Master MySQL Server:

mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: www.xxx.yyy.zzz
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: db.002174
Read_Master_Log_Pos: 342719703
Relay_Log_File: mysqld-relay-bin.000003
Relay_Log_Pos: 6458545
Relay_Master_Log_File: db.002170
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1005
Last_Error: Error 'Can't create table '/tmp/#sql7c49_2f_0' (errno: -1)' on query. Default database: 'live'. Query: 'create temporary table tmp_gen_table like tmp_to_gen_neu'
Skip_Counter: 0
Exec_Master_Log_Pos: 620120976
Relay_Log_Space: 4109869668
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
1 row in set (0.09 sec)

Ich musste recht lange suchen. Die o.g. Datei (/tmp/#sql7c49_2f_0.ibd) wurde zwar von mysql:mysql angelegt, jedoch war sie 0 byte groß. Im MySQL - Log fand ich nur den o.g. Fehler wieder. Also schaute ich im syslog und wurde fündig:

Jan 28 12:55:22 db kernel: [495131.291630] audit(1264679722.493:141): type=1503 operation="file_lock" requested_mask="wk::" denied_mask="k::" name="/tmp/#sql7c49_2f_0.ibd" pid=7924 profile="/usr/sbin/mysqld" namespace="default"

Das kenne ich inzwischen: Eine Zeile mit so komischen "requested_mask="wk::"" - Rechten kommt meistens, wenn eine Applikation an apparmor scheitert. Ich habe also der Datei /etc/apparmor.d/usr.sbin.mysqld die folgenden Zeilen hinzugefügt:

/usr/sbin/mysqld {
...
/tmp/ r,
/tmp/** rwk,
}

Schon geht's!
Ich fand es sehr überraschend, das das /tmp - Verzeichnis (in meinem Oldschool-Linux-Hinterkopf immer als das "jeder darf - Verzeichnis" abgelegt) ebenfalls einer eigenen Zeile in der apparmor-Konfiguration bedarf. Noch verwunderlicher finde ich, das dieses unter Ubuntu (8.04 - Hardy Heron) nicht standardmäßig dort aufgenommen wurde. Immerhin ist tmpdir=/tmp die Standardeinstellung unter dieser Ubuntu-Version.


Teilen per: TwitterEmail


Neue MySQL "moves"

Ich habe heute gleich drei neue MySQL Kniffe gelernt!

Die sind zwar sicher fast jedem, der sich oberflächlich mit MySQL beschäftigt hat klar, aber ich kannte sie zuvor nicht. Dabei sind sie seeeehr hilfreich bei meiner täglichen Arbeit.

Auszugebende Felder auswählen

Will man nur ein paar Felder einer Datenbanktabelle ausgegeben bekommen, oder in einer bestimmten Reihenfolge, so kann man das mit folgendem select Befehl tun:

select feld1,feld4,feld3 from datenbank.tabelle;

oder, für einen speziellen Datensatz

select feld1,feld4,feld3 from datenbank.tabelle where feld1='wert';

Hashes erzeugen

Man kann MySQL direkt anweisen, aus einem String einen Hash zu erzeugen. Hat man z.B. keine Ahnung, mit welchem Algorithmus (MD5,SHA,Crypt, ...) eine Applikation ein Passwort in einer Datenbank abgelegt hat, kann man das wie folgt herausfinden:

  1. Anzeigen des Hash - z.B.  "select User,Host,Password from mysql.user where User='root';"
  2. Generieren eines Hashes per "select PASSWORD('DasPasswortDesUsers');"
  3. Ist der Hash gleich dem im Feld Password aus dem ersten Befehl, hat man den Algorithmus.

Es gibt auch noch die Hashfunktionen MD5, SHA, etc. Diese generiert man dann per MD5('pass');, SHA('pass);, usw.

Änderung der Passwortgenerierung zwischen den MySQL Versionen

Zunächst sollte man sich mal diesen Artikel durchlesen.

Mit MySQL 4.1 wurde eine neue Methode zur Passwortgenerierung eingeführt.

Hat man noch Datenbanken aus früheren Versionen, kann man diesen Hash mit der MySQL Funktion OLD_PASSWORD (wie in Tipp 2 dieses Artikels beschrieben) generieren.

Teilen per: TwitterEmail