Bei der mySQL Installation musste ich erst einige Startschwierigkeiten beseitigen, bevor ich nun auch mit der Konfiguration anfangen konnte…
Ein großer Dank gilt meinem Linux-Kollegen, der mir durch die Schwierigkeiten der RPM-Abhängigkeiten geholfen hat.
Also kurz zur Erläuterung, die Linux-Kollegen haben in Ihrem Standard-Image immer Postfix enthalten, leider beinhaltet dieses Postfix Paket auch die mySQL-Libs in einer Uralt-Version 5.1.73. Welche sich nicht so einfach entfernen oder aktualisieren lassen…
RPM -U hat uns dann letztendlich – nach der Beseitigung anderer technischer Probleme – geholfen und wir konnten alle Pakete der mySQL Installation sauber installieren bzw aktualisieren, so dass wir nun folgenden Stand haben.
rpm -qa | grep mysql mysql-community-server-5.7.9-1.el6.x86_64 mysql-community-common-5.7.9-1.el6.x86_64 mysql-community-libs-compat-5.7.9-1.el6.x86_64 mysql-community-libs-5.7.9-1.el6.x86_64 mysql-community-client-5.7.9-1.el6.x86_64
Dies ist unsere Ausgangslage und kommen somit nun zur Konfiguration und Einrichtung:
Gemäß Dokumentation auf den mySQL Developer Seiten findet sich nach der Installation folgende Datei-Strukur auf dem Server:
Files or Resources |
Location |
---|---|
Client programs and scripts | /usr/bin |
mysqld server | /usr/sbin |
Configuration file | /etc/my.cnf |
Data directory | /var/lib/mysql |
Error log file | For RHEL, Oracle Linux, CentOS or Fedora platforms: /var/log/mysqld.log
For SLES: |
Value of secure_file_priv |
/var/lib/mysql-files |
System V init script | For RHEL, Oracle Linux, CentOS or Fedora platforms: /etc/init.d/mysqld
For SLES: |
Systemd service | For RHEL, Oracle Linux, CentOS or Fedora platforms: mysqld
For SLES: |
Pid file | /var/run/mysql/mysqld.pid |
Unix manual pages | /usr/share/man |
Include (header) files | /usr/include/mysql |
Libraries | /usr/lib/mysql |
Socket | /var/lib/mysql/mysql.sock |
Miscellaneous support files (for example, error messages and character set files) | /usr/share/mysql |
Die mySQL Konfigurationdatei my.cnf finden wir also im Ordner /etc und hat dann auf einem RedHat 6 System folgende standardmäßigen Inhalt:
# For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html [mysqld] # # Remove leading # and set to the amount of RAM for the most important data # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%. # innodb_buffer_pool_size = 128M # # Remove leading # to turn on a very important data integrity option: logging # changes to the binary log between backups. # log_bin # # Remove leading # to set options mainly useful for reporting servers. # The server defaults are faster for transactions and fast SELECTs. # Adjust sizes as needed, experiment to find the optimal values. # join_buffer_size = 128M # sort_buffer_size = 2M # read_rnd_buffer_size = 2M datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid
Dieser Inhalt kann selbstverständlich jederzeit an die eigenen Bedürfnisse angepasst werden.
Nach erfolgreicher mySQL Installation muss man nun die Datenbank erstmalig starten:
service mysqld start
Initializing MySQL database: [ OK ]
Starting mysqld: [ OK ]
Im Rahmen der mySQL Installation und dem Starten der Engine wurde auch ein mySQL-Root User (‘root’@’localhost’) angelegt, mittels des Befehls
grep 'temporary password' /var/log/mysqld.log
kann man sich nun das automatisch vergebene Password anzeigen lassen. der erste Schritt zu einer sicheren mySQL Installation ist nun sich anzumelden und dass Passwort des root-Users zu ändern, hierzu melden wir uns an der Datenbank-Engine an:
mysql -uroot -p ALTER USER 'root'@'localhost' IDENTIFIED BY 'MeinAdminPasswort2015!';
Achtung!
Standardmäßig ist das “Validate Password”-Plugin installiert/aktiviert, dadurch müssen Passwörter eine gewisse Komplexibiliät aufweisen.
Passwörter müssen mindestens einen Großbuchstaben, einen Kleinbuchstaben, eine Ziffer und ein Sonderzeichen enthalten und das Passwort muss eine Gesamtlänge von mindestens 8 Zeichen aufweisen.
Im Vergleich zu alten mySQL Installationen muss die neue Datenbank Engine nicht extra (mittels mysql_secure_installation-Skript ) gesichert werden, heißt es gibt keine test-Datenbank mehr und auch keinen Anonymen Login. Das Skript an sich gibt es noch und kann nach wie vor die mySQL Installation sicher(er) machen.
automatisches Starten des Dienste beim Systemstart
Damit nun der mySQL Datenbankserver beim Booten automatisch gestartet wird, nehmen wir noch folgende Konfigurationsschritte vor und überprüfen anschließend das Ergebnis (welches dann so aussehen sollte).
chkconfig mysqld on chkconfig --list | grep mysqld mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Nun bin ich im Grunde auch schon durch mit der mySQL-Installation und Einrichtung. Ab jetzt kann der mySQL Server genutzt werden und für die jeweiligen Applikationen User und Datenbanken angelegt werden.
ABER um einen stabilen Betrieb für einen mySQL-Server gewährleisten zu können, fehlen zumindest noch zwei wichtige Themen:
- Log-Rotation
- Backup
Log-Rotation
Auf kleinen mySQL-Maschinen fällt es vielleicht nicht so sehr auf, aber auf etwas größeren mySQL Installationen (auf denen mehr Last ist bzw die Datenbanken größer sind) werden die Logs schnell unübersichtlich und schwer lesbar. Daher empfehle ich/wir die Nutzung eines Skriptes, welches die Logs in regelmäßigen Abständen “abschneidet” und somit “klein” hält. In früheren mySQL Server Versionen wurde kein Skript für eben dieses Log-Rotate mitgeliefert, mittlerweile hat sich dies geändert.
Meine RedHat6 mySQL Installation hat bereits eigenständig eine Datei unter /etc/logrotate.d abgelegt und somit wird automatisch ein entsprechendes Aufrufen, Abschneiden der Logs initiert, zusätzlich befindet sich dieses Skript im Ordner /usr/share/mysql.
# The log file name and location can be set in # /etc/my.cnf by setting the "log-error" option # in either [mysqld] or [mysqld_safe] section as # follows: # # [mysqld] # log-error=/var/lib/mysql/mysqld.log # # In case the root user has a password, then you # have to create a /root/.my.cnf configuration file # with the following content: # # [mysqladmin] # password = # user= root # # where "" is the password. # # ATTENTION: The /root/.my.cnf file should be readable # _ONLY_ by root ! /var/lib/mysql/mysqld.log { # create 600 mysql mysql notifempty daily rotate 5 missingok compress postrotate # just if mysqld is really running if test -x /usr/bin/mysqladmin && \ /usr/bin/mysqladmin ping &>/dev/null then /usr/bin/mysqladmin flush-logs fi endscript }
Backup
Natürlich müssen mySQL Installationen und deren Datenbanken auch regelmäßig gesichert werden, hierzu liefert mySQL ein Tool namens mysqldump mit, welches sich sehr gut für die meisten Systeme und Anforderungen eignet.
Wir starten aber erst einmal damit einen Backup-User anzulegen, dieser erhält nur Rechte um Backups auszuführen.
CREATE USER 'backup'@'localhost' IDENTIFIED BY 'secret'; GRANT SELECT, SHOW VIEW, RELOAD, REPLICATION CLIENT, EVENT, TRIGGER ON *.* TO 'backup'@'localhost'; GRANT LOCK TABLES ON *.* TO 'backup'@'localhost'; FLUSH PRIVILEGES;
Dann benötigen wir ein Skript, welches uns das backup erstellt… Hierzu haben wir zweierlei Möglichkeiten
Kurz und knapp
num=$(( ($(date "+%H") + 4 ) / 4)) /usr/bin/mysqldump -u DBUSERNAME -pDBPASSWORD DBNAME > /PATH/backup${num}.sql
hier gefunden (Dank an fedorqui)
oder etwas ausführlicher (Dank an Django für sein großartiges mySQL Backup-Skript)
#!/bin/bash ################################################################################## # Script-Name : mysqldump.sh # # Description : Datenbank-Dump der kompletten (alle Tabellen) unserer # # MySQL-Datenbank nach /root/mysql/dumps # # Drei Datensicherungen werden aufgehoben, ältere werden gelöscht. # # # # # # # # Last update : 13.05.2013 # # Version : 0.01 # ################################################################################## ################################################################################## # H I S T O R Y # ################################################################################## # Version : 0.01 # # Description : initial release # # ------------------------------------------------------------------------------ # # Version : x.xx # # Description : <Description> # ################################################################################## # Source function library. . /etc/init.d/functions # Definition der systemindividuellen Variablen # Script-Name. SCRIPT_NAME='mysqldump' # Backup-Verzeichnis. DIR_TARGET='/var/lib/mysql/backup' DUMP_FILES="$DIR_TARGET/*.sql" # Mail-Empfänger MAIL_RECIPIENT='dlde-ats-dbs-mysql@atos.net' # Status-Mail versenden? [J|N]. MAIL_STATUS='N' # Datenbankdefinitionen DB_HOST="127.0.0.1" DB_USER="backup" DB_SECRET="ccQPFMN7Yc6rmiGn!" # Variablen MYSQLDUMP_COMMAND=`command -v mysqldump` TOUCH_COMMAND=`command -v touch` RM_COMMAND=`command -v rm` PROG_SENDMAIL=`command -v sendmail` CAT_COMMAND=`command -v cat` DATE_COMMAND=`command -v date` MKDIR_COMMAND=`command -v mkdir` FILE_NAME='/'$SCRIPT_NAME'.'`$DATE_COMMAND '+%Y-%m-%d-%H%M%S'`'.sql' FILE_LOCK='/tmp/'$SCRIPT_NAME'.lock' FILE_LOG='/var/log/'$SCRIPT_NAME'.log' FILE_LAST_LOG='/tmp/'$SCRIPT_NAME'.log' FILE_MAIL='/tmp/'$SCRIPT_NAME'.mail' VAR_HOSTNAME=`uname -n` VAR_SENDER='root@'$VAR_HOSTNAME VAR_EMAILDATE=`$DATE_COMMAND '+%a, %d %b %Y %H:%M:%S (%Z)'` # Functionen function log() { echo $1 echo `$DATE_COMMAND '+%Y/%m/%d %H:%M:%S'` " INFO:" $1 >>${FILE_LAST_LOG} } function movelog() { $CAT_COMMAND $FILE_LAST_LOG >> $FILE_LOG $RM_COMMAND -f $FILE_LAST_LOG $RM_COMMAND -f $FILE_LOCK } function sendmail() { case "$1" in 'STATUS') MAIL_SUBJECT='Status execution '$SCRIPT_NAME' script.' ;; *) MAIL_SUBJECT='ERROR while execution '$SCRIPT_NAME' script !!!' ;; esac $CAT_COMMAND <<MAIL >$FILE_MAIL Subject: $MAIL_SUBJECT Date: $VAR_EMAILDATE From: $VAR_SENDER To: $MAIL_RECIPIENT MAIL $CAT_COMMAND $FILE_LAST_LOG >> $FILE_MAIL $PROG_SENDMAIL -f $VAR_SENDER -t $MAIL_RECIPIENT < $FILE_MAIL $RM_COMMAND -f $FILE_MAIL } # Main. log "" log "+-------------------------------------------------------------------------------+" log "| .................... Start des MySQL-Datenbank-Dumps ........................ |" log "+-------------------------------------------------------------------------------+" log "" log "Das Datenbank-Backupscript wurde mit folgenden Parametern aufgerufen:" log "" log "SCRIPT_NAME : $SCRIPT_NAME" log "ZIEL-VERZEICHNIS: $DIR_TARGET" log "MAIL_EMPFÄNGER : $MAIL_RECIPIENT" log "MAIL_STATUS : $MAIL_STATUS" log "" # Prüfung ob alle benötigten Programme und Befehle vorhanden sind. if [ ! -s "$MYSQLDUMP_COMMAND" ]; then log "Prüfen, ob das Programm '$MYSQLDUMP_COMMAND' vorhanden ist.................[FEHLER]" sendmail ERROR movelog exit 10 else log "Prüfen, ob das Programm '$MYSQLDUMP_COMMAND' vorhanden ist.................[ OK ]" fi if [ ! -s "$TOUCH_COMMAND" ]; then log "Prüfen, ob das Programm '$TOUCH_COMMAND' vorhanden ist.........................[FEHLER]" sendmail ERROR movelog exit 11 else log "Prüfen, ob das Programm '$TOUCH_COMMAND' vorhanden ist.........................[ OK ]" fi if [ ! -s "$RM_COMMAND" ]; then log "Prüfen, ob das Programm '$RM_COMMAND' vorhanden ist............................[FEHLER]" sendmail ERROR movelog exit 12 else log "Prüfen, ob das Programm '$RM_COMMAND' vorhanden ist............................[ OK ]" fi if [ ! -s "$CAT_COMMAND" ]; then log "Prüfen, ob das Programm '$CAT_COMMAND' vorhanden ist..........................[FEHLER]" sendmail ERROR movelog exit 13 else log "Prüfen, ob das Programm '$CAT_COMMAND' vorhanden ist...........................[ OK ]" fi if [ ! -s "$DATE_COMMAND" ]; then log "Prüfen, ob das Programm '$DATE_COMMAND' vorhanden ist...........................[FEHLER]" sendmail ERROR movelog exit 14 else log "Prüfen, ob das Programm '$DATE_COMMAND' vorhanden ist..........................[ OK ]" fi if [ ! -s "$MKDIR_COMMAND" ]; then log "Prüfen, ob das Programm '$MKDIR_COMMAND' vorhanden ist..........................[FEHLER]" sendmail ERROR movelog exit 15 else log "Prüfen, ob das Programm '$MKDIR_COMMAND' vorhanden ist.........................[ OK ]" fi if [ ! -s "$PROG_SENDMAIL" ]; then log "Prüfen, ob das Programm '$PROG_SENDMAIL' vorhanden ist.................[FEHLER]" sendmail ERROR movelog exit 16 else log "Prüfen, ob das Programm '$PROG_SENDMAIL' vorhanden ist.................[ OK ]" fi if [ ! -e "$FILE_LOCK" ]; then log "Prüfen, ob das Programm nicht bereits oder noch läuft......................[ OK ]" $TOUCH_COMMAND $FILE_LOCK else log "Prüfen, ob das Programm nicht bereits oder noch läuft......................[FEHLER]" log "" log "FEHLER: Das Script läuft bereits bzw. immer noch, oder die LOCK-Datei" log "existiert noch von einem früheren Programmaufruf!" log "" sendmail ERROR movelog exit 20 fi if [ ! -d "$DIR_TARGET" ]; then log "Prüfen, ob Zielverzeichnis existiert.......................................[FEHLER]" log "" log " INFO: Erstelle Zielverzeichnis!" log " INFO: --> "$DIR_TARGET log "" $MKDIR_COMMAND -p $DIR_TARGET else log "Prüfen, ob Zielverzeichnis existiert.......................................[ OK ]" fi if [ "$UID" -ne 0 ]; then log "Prüfen, ob das Script mit root-Rechten gestartet wurde.......................[FEHLER]" log "" sendmail ERROR movelog exit 21 else log "Prüfen, ob das Script mit root-Rechten gestartet wurde.....................[ OK ]" fi # Start dumping. log "" log "+-------------------------------------------------------------------------------+" log "| .................... Start des Datenbank-Dumps .............................. |" log "+-------------------------------------------------------------------------------+" log "" log "$MYSQLDUMP_COMMAND -h "$DB_HOST" -u "$DB_USER" --all-databases --events > $DIR_TARGET$FILE_NAME" $MYSQLDUMP_COMMAND -h $DB_HOST -u $DB_USER --password=$DB_SECRET --all-databases --events > $DIR_TARGET$FILE_NAME if [ "$?" != 0 ]; then log "" $RM_COMMAND -f $FILE_LOCK sendmail ERROR movelog exit 99 else log "" log "+-------------------------------------------------------------------------------+" log "| ........................ Datenbank-Dump beendet ............................. |" log "+-------------------------------------------------------------------------------+" log "" fi # Bis auf die letzten drei Datenbankbackups alle anderen Dateien löschen. cd $DIR_TARGET/ (ls $DUMP_FILES -t|head -n 3;ls $DUMP_FILES )|sort|uniq -u|xargs rm if [ "$?" != "0" ]; then log "alte Datenbanksicherungen aus Zielverzeichnis $DIR_TARGET gelöscht....[FEHLER]" log "" sendmail ERROR movelog exit 69 else log "alte Datenbanksicherungen aus Zielverzeichnis $DIR_TARGET gelöscht....[ OK ]" log "" fi # Finish syncing. log "+-------------------------------------------------------------------------------+" log "| ..................... Ende des MySQL-Datenbank-Dumps ........................ |" log "+-------------------------------------------------------------------------------+" log "" # Status eMail versenden if [ $MAIL_STATUS = 'J' ]; then sendmail STATUS fi # Temporäres Logfile permanent sichern movelog exit 0
Jetzt nur noch einen passenden Cronjob dafür erstellen, wann auch immer das Backup erstellt werden soll.
Und natürlich alles testen. 😉
Björn arbeitet auch weiterhin aus Mexiko als Senior Consultant – Microsoft Data Platform und Cloud für die Kramer&Crew in Köln. Auch der Community bleibt er aus der neuen Heimat treu, er engagiert sich auf Data Saturdays oder in unterschiedlichen Foren. Er interessiert sich neben den Themen rund um den SQL Server, Powershell und Azure SQL für Science-Fiction, Backen 😉 und Radfahren.