Mysql

Aus Mikiwiki
Version vom 23. August 2014, 13:51 Uhr von Michi (Diskussion | Beiträge) (Datenbanksicherung)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

Mysql (auch: MySQL) ist einer der bekanntesten Datenbankserver, nicht zuletzt durch LAMP (Linux, Apache, Mysql, PHP). Daneben ist Mysql Bestandteil zahlreicher anderer Open Source-Produkte wie Drupal, Mediawiki, Wordpress oder Typo3 und kommt auch bei namhaften kommerziellen Nutzern zum Einsatz (z. B. Yahoo, NASA).

Der seit 1995 existierende Datenbankserver der schwedischen Firma Mysql AB wird sowohl unter einer kommerziellen Lizenz wie auch der GPL angeboten. Insgesamt elf Datenbank-Engines unterstützen jeweils einen Tabellentyp mit besonderen Eigenschaften - kein Tabellentyp beherrscht alle Fähigkeiten.

Installation

Microsoft Windows XP

Mysql Server 5.1 Community Server (Datei "mysql-5.1.30-win32.exe")

  • Datei "Setup.exe" ausführen
  • Setup type: Complete
  • Configure the MySQL Server now
  • Standard Configuration
  • Include Bin Directory in Windows PATH
  • Root password: root / Create an anonymous account

Mysql GUI Tools (Datei "mysql-gui-tools-5.0-r14-win32.msi") enthält Administrator, Mysql Toolkit und Query Browser

  • Setup type: Complete

Mysql Query Browser

  • Datei > Skript öffnen > Ausführen
  • Feldinhalte kopieren
  • Administrator

SUSE Linux

Es wird angenommen, dass der Apache2-Webserver bereits installiert ist. Als Wurzelverzeichnis des Apache2-Webservers wird "/srv/www/htdocs" verwendet.

Installation folgender Pakete über YaST:

  • mysql - enthält den eigentlichen Mysql-Server.
  • mysql-client - enthält die Client-Ptogramme (mysql, mysqladmin usw.) zur Administration von Mysql.
  • mysql-Max - enthält die Max-Version des Mysql-Servers, die u. a. InnoDB- und BDB-Tabellen unterstützt.
  • mysql-shared - enthält die shared libraries, die von manchen Programmen verwendet werden, um auf Mysql zuzugreifen.

Als Datenbankverzeichnis wird "/var/lib/mysql" verwendet.

Ebenfalls mit YaST installiert werden müssen folgende Pakete:

  • mod_php4-core - Metapaket für das alte PHP4-Layout
  • apache2-mod_php4 - PHP4 Module für Apache 2.0
  • phpMyAdmin - Administration von Mysql übers Netz
  • perl-DBI - das Perl Database Interface
  • perl-DBD-MySQL - Schnittstelle zur Mysql-Datenbank

Zudem müssen über YaST Online Update (YOU) die soeben installierten Pakete aktualisiert werden.

Nun muss Apache2 neu gestartet werden.

# /etc/init.d/apache2 restart

PHP4 testen durch Anlegen und Aufruf der Datei "phptest.php4".

 # vi /srv/www/htdocs/phptest.php4
 <?php phpinfo(); ?>

Aufruf der Datei über http://localhost/phptest.php4

Folgendes Programm zeigt eine Liste aller Mysql-Datenbanken an.

 # vi /srv/www/htdocs/mysql-test.php4

Aufruf der Datei über http://localhost/mysql-test.php4

Verwendung

Unklar: Um Mysql sofort zu starten.

# rcmysql start

Mysql starten

Starten des Mysql-Servers.

# /etc/init.d/mysql start

Testen, ob der Mysql-Server läuft.

# ps ax | grep mysqld

Um Mysql beim Bootvorgang automatisch zu starten (runlevels 2, 3, 5).

# insserv mysql

Setzen des Passworts "xxxxxx" für den Mysql-Benutzer "root".

# /usr/bin/mysqladmin -u root password 'xxxxxx'
# /usr/bin/mysqladmin -u root -h meister.site password 'xxxxxx'

Zum Aufruf von Phpmyadmin müssen in der Datei "config.inc.php" folgende Zeilen angepasst werden.

# vi /srv/www/htdocs/phpMyAdmin/config.inc.php
$cfg['PmaAbsoluteUri'] = 'http://10.0.5.2/phpMyAdmin/';
$cfg['Servers'][$i]['password']      = 'xxxxxx';

Aufruf von Phpmyadmin über http://localhost/phpMyAdmin/index.php

Mysql konfigurieren

Der Mysql-Server ist nach einer Standardinstallation in keiner Weise abgesichert.

Einloggen mit gesetztem Passwort.

$ mysql -u root -p
Enter password: xxxxxx
mysql>

Status anzeigen.

$ mysql
mysql> status

Danach über Phpmyadmin Anlegen der Datenbank "md" und darin der Tabelle "t001artist".

Neue Datenbank und Benutzer einrichten

Anlegen der Datenbank "md". Uneingeschränkte Freigabe für den Mysql-Benutzer "md". Uneingeschränkte Freigabe für den Benutzer "md" vom Rechner 10.0.5.4 aus:

$ mysql -u root -p xxx
mysql> create database md;
Query OK, 1 row affected (0.01 sec)
mysql> grant all on md.* to md@localhost identified by 'md';
Query OK, 0 rows affected (0.03 sec)
mysql> grant all on md.* to md@10.0.5.2 identified by 'md';
Query OK, 0 rows affected (0.00 sec)

Anzeige der Privilegien von Benutzer "md".

mysql> show grants for md@localhost;

Änderung des Passworts "md" von Benutzer "md" zu "xxxxxx".

$ mysqladmin -u md -p password 'xxxxxx'

Anlegen von Linux-Kennung "md" mit Kennung "md". Anlegen der PHP-Skripte unter "/home/md/public_html/php". Bei Aufruf eines PHP-Skriptes muss diese Linux-Kennung und ihr Passwort angegeben werden.

Datenbank "test_vote" anlegen (In der Standardeinstellung der MySQL-Zugriffsrechte ist es jedem Anwender auf einem lokalen Rechner erlaubt, mit "test" beginnende Datenbanken zu erstellen).

mysql> create database test_vote;
Query OK, 1 row affected (0.00 sec)

Tabelle "votelanguage" in der Datenbank "test_vote" anlegen.

mysql> use test_vote;
Database changed
mysql> create table votelanguage (
-> id     int not     null auto_increment,
-> choice tinyint not null,
-> ts     timestamp,
-> primary key (id));
Query OK, 0 rows affected (0.03 sec)

Damit wird eine Tabelle mit den drei Spalten "id", "choice" und "ts" angelegt.

Tabelle "title" in der Datenbank "test_books" ändern.

mysql> use test_books;
Database changed
mysql> alter table title change title title varchar(100) not null;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0

Einfügen von Inhalten in die Tabelle "title".

mysql> insert into author values ('1','Kofler M.');
Query OK, 1 row affected (0.00 sec)

oder

mysql> insert into publisher values ('1','Addison-Wesley'), ('2','apress');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

Indizes können auf drei Arten erzeugt werden.

mysql> create table title (titleID int not null auto_increment, \
       title varchar(120) not null, publisherID int not null, \
       primary key (titleID), index idxtitle (title));
mysql> create index idxtitle on title (title);
mysql> alter table title add index idxtitle (title);

Beschränkung des Index auf die ersten 16 Zeichen.

mysql> alter table title add index idxtitle (title(16));

Einrichtung einer Beispieldatenbank bei vorhandenen Zugriffsrechten.

$ mysqladmin -u root -p create mylibrary
Enter password: xxx
$ mysql -u root -p mylibrary < mylibrary.sql
Enter password: xxx

Mysql absichern

Das Zugriffssystem von Mysql ist zweiphasig: Zuerst geht es nur darum, ob überhaupt eine Verbindung zu Mysql hergestellt werden darf (Tabelle "user"). Zur Anmeldung werden immer drei Angaben benötigt:

  • Benutzername (username): Darf 16 Zeichen lang sein. Unterscheidung zwischen Gross- und Kleinschreibung.
  • Passwort: Beliebige Länge. Unterscheidung zwischen Gross- und Kleinschreibung. Speicherung als 16 byte langer verschlüsselter Code.
  • Hostname: Name oder IP-Adresse des Rechners, auf dem der Mysql-Server läuft. Auf diese Angabe kann verzichtet werden, wenn Server und Client auf demselben Rechner laufen.

Wenn eine Verbindung hergestellt werden kann, wird die zweite Stufe der Zugriffskontrolle bei jedem einzelnen Datenbankbefehl angewendet (nacheinander die Tabellen "user", "db", "host", "tables_priv" und "columns_priv"): es wird überprüft, ob der Benutzer überhaupt Zugriff auf die Datenbank, die Tabelle und die Spalte hat bzw. diese ändern darf.

Wenn beim Mysql-Verbindungsaufbau keine anderen Parameter angegeben werden, wird als Benutzername der gerade aktuelle Loginname verwendet, als Passwort eine leere Zeichenkette und als Hostname "localhost".

 $ mysql -u user -h hostname -p
 Enter password: xxx

Wenn ein PHP-Skript die Verbindung zur Datenbank herstellt, ohne dabei mit "mysql_connect()" oder "mysql_pconnect" einen Benutzernamen anzugeben, wird als Benutzername der Name des accounts verwendet, unter dem der PHP-Interpreter ausgeführt wird (meist derselbe, unter dem auch Apache ausgeführt wird, z. B. "wwwrun").

Nach einer Neuinstallation gilt eine nicht durch Passwörter abgesicherte Standardeinstellung: Der Benutzer "root" des lokalen Systems (Hostname "localhost" oder "rechnername") hat uneingeschränkte Rechte. Alle Benutzer des lokalen Systems dürfen sich ohne Passwort bei MySQL anmelden, diese Benutzer haben aber keinerlei Rechte, dürfen aber ungeschützte Testdatenbanken (z. B. "test_xxx" anlegen). Eine Anmeldung von einem externen Rechner ist unmöglich.

Schnelle Absicherung

Setzen des Passworts für den Mysql-Benutzer "root". Der Name "localhost" gilt, wenn die lokale Verbindung über eine Socket-Datei erfolgt (der Regelfall), "10.0.5.2" gilt dagegen, wenn die lokale Verbindung über TCP/IP erfolgt (z. B. bei Java-Programmen).

# mysqladmin -u root -h 10.0.5.2 password xxx
# mysqladmin -u root -h localhost password xxx

Weiterhin ist vom lokalen Rechner aus ein Mysql-Verbindungsaufbau unter einem anderen Namen als "root" möglich, allerdings ohne Rechte. Um dies zu verhindern.

# mysql -p
Enter password: xxx
mysql> use mysql;
Database changed
mysql> delete from user where User=;
Query OK, 2 rows affected (0.05 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.02 sec)
mysql> exit

Jetzt kann sich nur noch der Benutzer "root" unter Angabe des Passworts bei Mysql anmelden.

Die Datenbank "mysql"

Die Datenbank "mysql" enthält sechs Tabellen, von denen fünf (die "grant-Tabellen") der die Verwaltung der Zugriffsrechte dienen:

  • user: regelt, wer (Benutzername) von welchem Rechner aus (Hostname) auf den Mysql-Server zugreifen darf. Die Tabelle enthält ausserdem globale Privilegien. Nach Neuinstallation Standardeinstellung.
  • db: Gibt an, welcher Benutzer auf welche Datenbanken zugreifen darf. Nach Neuinstallation Standardeinstellung.
  • host: Ergänzt die Tabelle "db" durch Informationen über den zulässigen Hostnamen (sofern dieser in "db" nicht angegeben wurde). Nach Neuinstallation leer.
  • tables_priv: Gibt an, welcher Benutzer auf welche Tabellen zugreifen darf. Nach Neuinstallation leer.
  • columns_priv: Gibt an, welcher Benutzer auf welche Spalten einer Tabelle zugreifen darf. Nach Neuinstallation leer.
  • func: Ermöglicht die Verwaltung von UDFs (user defined functions).

Administration und Server-Konfiguration

Die Server-Konfigurationsdateien:

  • "/etc/my.cnf" - globale Optionen (sowohl für "mysqld" als auch für Administrationswerkzeuge)
  • "~/.my.cnf" - benutzerspezifische Optionen (nur für Administrationswerkzeuge)

Die serverspezifischen Optionen in der Konfigurationsdatei beginnen mit der Zeile "[mysqld]", z. B.

 [mysqld]
 default-character-set = latin1-ch

Befehlszeilenorientierte Administrationswerkzeuge:

  • mysqlshow zur Anzeige der von Mysql verwalteten Datenbanken, Tabellen und Spalten
  • mysqladmin zum Ausführen von Administrationsbefehlen
  • mysqldump zum Anlegen einer Datenbanksicherung mit maximaler Portabilität
  • mysqlshow

Datenbanksicherung

  • mysqldump zur Sicherung bei laufendem Mysql-Server. Wiederherstellung mit mysql.
  • Kopieren der Datenbankverzeichnisse bei gestopptem Mysql-Server. Wiederherstellung durch Zurückkopieren des gesicherten Verzeichnisses. Möglich nur für Myisam-Tabellen.

Sicherung der Tabelle "record" aus der Datenbank "abc".

$ mysqldump -u root -p abc record

Sicherung der Datenbank "abc" in die Datei "/tmp/backup-abc.sql" (die Option "--opt" ist standardmässig aktiviert).

$ mysqldump -u root --password=xxx --opt abc > /tmp/backup-abc.sql
$ mysqldump -u root -p abc > /tmp/backup-abc.sql

Sicherung aller Datenbanken in die Datei "backup.sql" (die Option "--opt" ist standardmässig aktiviert).

$ mysqldump -u root --password=xxx --opt --all-databases > /tmp/backup.sql
$ mysqldump -u root -p --all-databases > /tmp/backup.sql

Alternativ kann eine Sicherung auch über phpMyAdmin im Menü "Export > Add drop table > Save as file > Go" durchgeführt werden.

Wiederherstellen aller Datenbanken aus der Datei "/tmp/backup.sql".

# mysql -u root -p < /tmp/backup.sql

Wiederherstellen der Datenbank "abc" aus der Datei "/tmp/backup-abc.sql".

# mysql -u root -p abc < /tmp/backup-abc.sql

Import und Export von Textdateien

  • Der SQL-Befehl "load data" liest eine Textdatei ein und überträgt den Inhalt in eine Tabelle.
$ mysql --local-infile=1 -u root -p
Enter password:
mysql> use md
mysql> load data local infile '/home/mik/public_html/md/cc3.txt'              \
         into table country fields terminated by '#' lines terminated by '\n' \
         ( countrycode, country );
  • mysqlimport
  • Der SQL-Befehl "select ... into outfile" schreibt das Ergebnis einer Abfrage in eine Textdatei.
  • mysqldump
  • In manchen Fällen kann mysql zum Text-, HTML- oder XML-Export eingesetzt werden.

Aktivierung der Session-Funktionen

Folgende Einstellungen in der Datei "php.ini" im Abschnitt "[Session]".

  • Pfadangabe
    session.save_path = /tmp
  • Beim Start einer Session wird ein Session-cookie verwendet, um die Session-ID auf dem Browser des Anwenders zu speichern.
    session.use_cookies = 1
  • Es ist nicht möglich, die Session-ID über die URL zu ermitteln:
    session.use_only_cookies = 1
  • Festlegen des cookie-Namens, in dem die Session gespeichert wird:
    session.name = PHPSESSID
  • Automatische Aktivierung einer Session. Mit dem Wert "1" ist die Session-Verwaltung nicht permanent aktiv und muss mit session_start() gestartet werden.
    session.auto_start = 0
  • Lebensdauer des clientseitig gespeicherten cookies. Mit dem Wert "0" bleibt das cookie solange gespeichert, bis der Webbrowser geschlossen wird.
    session.cookie_lifetime = 0
  • Festlegung, ob die Übertragung der Session-ID in der URL mäglich ist. Mit dem Wert "0" ist das nicht möglich.
    session.use_trans_sid = 0
# mysql_install_db
Installing all prepared tables
050501  0:21:28  /usr/sbin/mysqld-max: Shutdown Complete
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h meister.site password 'new-password'

# chown mysql -R /var/lib/mysql/mysql

Setzen des Passworts in Mysql.

# mysql -u root
mysql> update mysql.user set password=PASSWORD('xxxxxx') where User='root';
mysql> flush privileges;
mysql> quit

Monitoring

mtop und mytop sind Diagnosewerkzeuge, die über das Innenleben von Mysql berichten: Die Anzahl aktiver Benutzer und Abfragen, die Trefferhäufigkeit im Cache, eine Übersicht über lange laufende Abfragen und aktuell geöffnete Tabellen sowie Hinweise auf unterdimensionierte interne Puffer.

Check_mysql ist ein Plugin für den Allzweck-Monitor Nagios. Ähnliche Erweiterungen gibt es auch für andere Monitoring-Lösungen wie Zenoss, Zabbix, Open NMS oder Hyperic HQ.

Weiter geht innotop, das auf jeweils einer Bildschirmseite auch Aussagen über Deadlocks, wartende Transaktionen, die Performance der I/O-Operationen oder den Status einer Replikation präsentieren. Auch der SQL-Befehlstext einzelner Abfragen ist einsehbar. Das Werkzeug inspiziert bei Bedarf sogar mehrere Datenbanken gleichzeitig und killt im Bedarfsfall verdächtige Sitzungen. Allerdings werden nur Aussagen über den Tabellentyp Inno DB gemacht und auch nur als Momentaufnahme, also nicht über einen Zeitraum. Zudem werden nur Zahlenkolonnen und keine grafische Darstellung angeboten, und es gibt auch keinen Alarm beim Überschreiten bestimmter Schwellenwerte, und ebensowenig einen Hinweis, was in diesem oder jenem Fall zu tun wäre.

Der Monitoring und Advisory Service der Mysql-Bezahlvariante Enterprise DB will alle diese Beschränkungen aufheben und bietet reichlich grafische Aufbereitungen für die professionelle Überwachung - allerdings zu Preisen ab 1'600 Euro jährlich.

Zusätzlich gibt es Software, die offline den Status analysiert und Berichte erzeugt. Für Mysql gibt es die [http.//hackmysql.com/mysqlreport Hack Mysql Tools] oder die Maatkit Analysis Tools. Zum Zusammentragen von Daten über längere Zeiträume eignen sich RRD-Tool und Verwandte: Munin, Cacti oder Cricket.

Passwort von Mysql-Benutzer "root"

Wenn das Passwort für den Mysql-Benutzer "root" vergessen wurde oder der Benutzer gelöscht wurde kann es wie folgt wieder gesetzt werden:

1. Stoppen des laufenden mysqld auf Rechner "kanzler".

SUSE Linux:
# kill -15 $(cat /var/lib/mysql/kanzler.pid)

Ubuntu 7.04:
# kill -15 $(cat /var/run/mysqld/mysqld.pid)

2. Starten von Mysql wie folgt.

# mysqld --skip-grant-tables --user=root &

3. Setzen eines neuen Passworts für Mysql-Benutzer "root".

# mysql -u root
mysql> UPDATE mysql.user SET Password=PASSWORD('newpassword') WHERE user='root';
mysql> FLUSH PRIVILEGES;
mysql> quit
# mysqld --skip-grant-tables --user=root &
[1] 24737
060804 20:01:05  InnoDB: Started; log sequence number 0 43807807
060804 20:01:05 [Note] mysqld: ready for connections.
Version: '5.0.18'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  SUSE MySQL RPM
# mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 5.0.18

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> use mysql
mysql> INSERT INTO `user` ( `Host` , `User` , `Password` , `Select_priv` ,    \
         `Insert_priv` , `Update_priv` , `Delete_priv` , `Create_priv` ,       \
         `Drop_priv` , `Reload_priv` , `Shutdown_priv` , `Process_priv` ,      \
         `File_priv` , `Grant_priv` , `References_priv` , `Index_priv` ,       \
         `Alter_priv` , `Show_db_priv` , `Super_priv` ,                        \
         `Create_tmp_table_priv` , `Lock_tables_priv` , `Execute_priv` ,       \
         `Repl_slave_priv` , `Repl_client_priv` , `ssl_type` , `ssl_cipher` ,  \
         `x509_issuer` , `x509_subject` , `max_questions` , `max_updates` ,    \
         `max_connections` ) VALUES ('localhost', 'root', 'xxxxxx', 'Y', 'Y',  \
         'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', \
         'Y', 'Y', 'Y', 'Y', 'Y', , , , , '0', '0', '0');
Query OK, 1 row affected (0.02 sec)
# killall mysqld
# /etc/init.d/mysql start

4. Abschiessen von mysqld

# ps -ef | grep mysqld
root     18439 18293  0 16:19 pts/6    00:00:00 mysqld --skip-grant-tables 
  --user=root
# kill -15 18439

5. Starten von Mysql.

# /etc/init.d/mysql start

Nochmals

Wie kann ich mein Mysql-Root-Passwort zurücksetzen?

Wenn das Root-Passwort für den Mysql-Server vergessen wurde und es zurückgesetzt werden soll, kann wie folgt vorgegangen werden.

1. Schritt: Beenden des laufenden Mysql-Servers über das Init-Skript.

# /etc/init.d/mysql stop

2. Schritt: Starten des Mysql-Servers mit deaktivierter Passwort-Überprüfung und ohne Netzwerkunterstützung.

# mysqld --user=mysql --pid-file=/var/lib/mysql/mysqld.pid      \
    --socket=/var/lib/mysql/mysql.sock --datadir=/var/lib/mysql \
    --skip-grant-tables --skip-networking

3. Schritt: Jetzt kann das Passwort mit Hilfe von mysqldadmin geändert werden.

# mysqladmin -u root password "mynewpassword"

4. Schritt: Zum Schluss wird der Mysql-Server beendet und im normalen Modus wieder gestartet.

# kill `cat /var/lib/mysql/mysqld.pid`
# /etc/init.d/mysql start

Jetzt sollte eine Anmeldung mit dem neu gesetzten Passwort als Benutzer "root" möglich sein.

FAQ

Spaltenreihenfolge einer Tabelle ändern

In Tabelle "aaa" soll die Spalte "spalte1" verschoben werden, sodass sie nach Spalte "spalte2" erscheint.

ALTER TABLE aaa MODIFY COLUMN spalte1 decimal(10,0) NULL AFTER spalte2

Setzen des Wertes von "auto increment"

Setzen des Wertes 30 für die Tabelle "projekt.

ALTER TABLE projekt AUTO_INCREMENT = 30;

Kopieren von Datensätzen in dieselbe Tabelle

Folgender Befehl muss auf der Befehlszeile in der betreffenden Datenbank ausgeführt werden. Hier wird der Datensatz mit der ID 119 aus der Tabelle "neuerungen" in die temporäre Tabelle "tmp" kopiert, der Inhalt der Spalte "id" auf NULL gesetzt, der Inhalt von Spalte "modul" von "90" auf "91" gesetzt , der neue Tabelleninhalt in die Tabelle "neuerungen" eingefügt (wo er dank "aito increment" eine neue ID erhält), zum Schluss wird die temporäre Tabelle "tmp" gelöscht (um allenfalls dieselbe Aktion für einen weiteren datensatz durchzuführen).

SET @var = 119;
CREATE TEMPORARY TABLE tmp SELECT * FROM neuerungen WHERE id = @var;
UPDATE tmp SET id = NULL; 
UPDATE tmp SET modul = 91 WHERE modul = 90;
INSERT INTO neuerungen SELECT * FROM tmp;
DROP TABLE tmp;

Weblinks