blog.bartlweb - a technologist's external brain

Thema: MySQL

Logrotate-Fehler für MySQL unter Ubuntu

Nach dem Wiederherstellen meines Backups der MySQL-Dateien auf einer neuen Installation von Ubuntu habe ich die folgende Fehlermeldung von logrotate erhalten.

/etc/cron.daily/logrotate:
error: error running shared postrotate script for '/var/log/mysql.log /var/log/mysql/mysql.log /var/log/mysql/mysql-slow.log '
run-parts: /etc/cron.daily/logrotate exited with return code 1

Ursache

Der Fehler liegt in den Zugangsdaten des MySQL-Users debian-sys-maint. Logrotate benötigt Zugriff auf die MySQL-Datenbank und versucht dies über den vorher genannten User. Die Lösung liegt dabei entweder im Wiederherstellen der Datei /etc/mysql/debian.cnf der alten Installation oder im Anpassen des Passworts für den MySQL-Benutzer.

Lösung

Ermitteln Sie zunächst das Passwort des Benutzers debian-sys-maint in der Datei /etc/mysql-maint. Danach können Sie dieses über die folgenden Befehle in MySQL neu setzen.

MySQL Datenbank in UTF-8 konvertieren

Um eine Datenbank im laufenden Betrieb in UTF-8 zu konvertieren bedarf es einiger Anpassungen. Das folgende PHP-Skript erleichtert die Konvertierung.

<?php
 
/* settings */
 
$db = 'test';
$db_host = 'localhost';
$db_username = 'username';
$db_password = 'password';
 
/* action */
 
// connect to db
$dbconection = mysql_connect($db_host, $db_username, $db_password);
if(!$dbconection) {
    echo "Error: Database connection to host '" . $db_host . "' can't be established!" . "<br/><br/>";
    exit(0);
} else {
    echo "Database connection to host '" . $db_host . "' established!" . "<br/><br/>";
}
mysql_select_db($db);
 
// convert
$result = mysql_query('show tables');
if($result) {
    
    echo "Database '" . $db . "' selected!" . "<br/><br/>";  
 
    // convert tables
    if(mysql_num_rows($result)) {
        while($tables = mysql_fetch_array($result)) {
            foreach ($tables as $key => $value) {
                $query = "ALTER TABLE " . $value . " CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;";
                mysql_query($query);
                if (mysql_error()) {
                    echo mysql_error() . "<br/>";
                    echo "ERROR: " . $query . "<br/>";
                } else {
                    echo "SUCCESS: " . $query . "<br/>";
                }
            }
        }
    }
 
    // set collation to utf8
    $query = "ALTER DATABASE dev_aopwebsites DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";
    mysql_query($query);
    if (mysql_error()) {
        echo mysql_error() . "<br/>";
        echo "<br/><br/>" . "ERROR: " . $query . "<br/>";
    } else {
        echo "<br/><br/>". "SUCCESS: " . $query . "<br/>";
    }
 
    echo "<br/><br/><br/>" . "SUCCESS!" . "<br/>";
 
} else {
    echo "<br/><br/><br/>" . "ERROR - Database '" . $db . "' not found!" . "<br/>";
}
 
?>

MySQL Datenbank per Skript sichern

Das folgende Skript sichert eine oder mehrer Datenbanken mittels mysqldump als tar.gz-Dateien. Beachten Sie, dass der Datenbank-Benutzer für das Backup-Skript die folgenden Rechte benötigt: SHOW DATABASES, SELECT, LOCK TABLES, RELOAD.

#!/bin/sh
 
# configure databases
CONF_DB_DATABASE[0]="db1"
CONF_DB_DATABASE[1]="db2"
CONF_DB_DATABASE[2]="db3"
 
# settings
CONF_DB_USER="backup"
CONF_DB_PASSWORD="password"
CONF_DB_HOST="localhost"
CONF_OUTPUT_FILENAME="_`date +%d%m%Y`"
CONF_OUTPUT_DIR="/mnt/backup/mysqldump/"
CONF_OUTPUT_DIR_CLEAN="true"
CONF_TMP_DIR="/tmp/"
 
# clean up output dir
if [ $CONF_OUTPUT_DIR_CLEAN = "true" ]
    then rm $CONF_OUTPUT_DIR*.tar.gz
fi
 
# backup databases
for db in "${CONF_DB_DATABASE[@]}";
do
 
    mysqldump -u $CONF_DB_USER -p$CONF_DB_PASSWORD -h $CONF_DB_HOST $db > $CONF_TMP_DIR$db$CONF_OUTPUT_FILENAME.sql
 
    tar cfz $CONF_OUTPUT_DIR$db$CONF_OUTPUT_FILENAME.tar.gz -C $CONF_TMP_DIR $db$CONF_OUTPUT_FILENAME.sql  >> /dev/null 2>&1
    rm $CONF_TMP_DIR$db$CONF_OUTPUT_FILENAME.sql
 
done

MySQL-Datenbanken mittels Skript sichern

Das folgende Shell-Skript sichert eine Datenbank mit Hilfe von mysqldump als mit Datum versehene tar.gz-Datei. Somit kann mit Hilfe eines Cronjobs die Datenbank z.B. einmal täglich gesichert werden.

Shell-Skript

#!/bin/sh
 
CONF_DB_DATABASE = "mydb"
CONF_DB_USER = "user"
CONF_DB_PASSWORD = "password"
CONF_DB_HOST = "localhost"
CONF_OUTPUT_FILENAME = "mydb_`date +%m%d%Y`"
CONF_OUTPUT_DIR = "/mnt/backup/mysql/"
CONF_TMP_DIR = "/tmp/"
 
mysqldump -u $CONF_DB_USER -p$CONF_DB_PASSWORD -h $CONF_DB_HOST $CONF_DB_DATABASE > $CONF_TMP_DIR$CONF_OUTPUT_FILENAME.sql
tar cfz $CONF_OUTPUT_DIR$CONF_OUTPUT_FILENAME.tar.gz -C $CONF_TMP_DIR $CONF_OUTPUT_FILENAME.sql  >> /dev/null 2>&1
rm $CONF_TMP_DIR$CONF_OUTPUT_FILENAME.sql

Performance von mysqldump optimieren

Bei großen Datenbanken kann mysqldump unter Umständen sehr lange für das Backup benötigen. Über die folgenden Paramter der MySQL-Konfigurationsdatei my.cnf können Sie die Performance von mysql und mysqldump optimieren. Achtung: die hier angegebenen Werte sind Beispielwerte, Sie sollten diese entsprechend des verfügbaren Arbeitsspeichers bemessen.

[mysqldump]
max_allowed_packet = 64M
[mysqld]
key_buffer_size = 256M
max_allowed_packet = 128M
read_buffer_size = 512K
myisam_sort_buffer_size = 8M
 
 
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
innodb_buffer_pool_size = 256M
# Set ..._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 64M

die Verwendung von mysqldump

Neben PHP-basierten Tools wie phpMyAdmin oder MysqlDumper lassen sich Datenbanken auch bequem per Kommandozeile und dem von MySQL mitgelieferten Tool mysqldump backupen und auch wieder herstellen. Bei der so generierten Datei handelt es sich immer um Standard-SQL-Befehle und können daher jederzeit mit beliebigen Tools wieder in die Datenbank eingespielt werden.

Backup erstellen

mysqldump -u [Benutzername] -p[Password] -h [Datenbankserver] --verbose [Datenbank] > [Datei]

Hinweis: Der nicht vorhandene Abstand bei -p[Password] ist korrekt. Sie können auch nur den Parameter -p angeben um das Passwort erst nach Aufforderung einzugeben.

MySQL Root Passwort setzen

Standardmäßig ist nach der Installation von MySQL kein Passowrt für den Benutzer Root gesetzt. Dies stellt nicht nur ein Sicherheitsrisiko dar sondern viele Anwendung stellen ohne Passwort auch keine Verbinung zum SQL-Server her. Mit ein paar Konsolenbefehlen ist das Passwort aber schnell gesetzt:

mysql -u root mysql> use mysql;
mysql> update user set Password=password('neues_passwort') where user='root';
mysql> flush privileges;
mysql> quit

Mysql Error 1153 – Got a packet bigger than ‘max_allowed_packet’ bytes

Meistens tritt dieser Fehler beim Importieren von zu großen Datenbankdumps über die Kommandozeile auf. Schuld ist ein zu klein gesetzter Wert der Einstellung "max_allowed_packet".

Konfiguration ändern

Ändern Sie dazu die Konfiguration von MySQL in der Konfigurationsdatei "my.cnf".

max_allowed_packet = xxM

Einstellung temporär ändern

Die Einstellung kann auch mittels SQL-Befehl geändert werden und gilt dann bis zum Neustart des SQL-Servers.

SET GLOBAL max_allowed_packet=1000000000;

MySQL Datadir unter Ubuntu Linux verschieben

1. Datenbanken kopieren

cp -R /var/lib/mysql /my/dir

2. mysql-Settings anpassen

vi /etc/mysql/my.cnf

datadir= /my/dir

3. apparmor-Settings anpassen

vi /etc/appamor.d/usr.sbin.mysqld

/my/dir/ r,
/my/dir/** rwk,

4. Dienste neustarten

/etc/init.d/apparmor restart
/etc/init.d/mysql restart