Der folgende Beitrag zeigt, wie man unter Windows 10 eine MySQL-Datenbank per PowerShell Skript automatisiert sichert.  Dabei werden mehrere Backups vorgehalten und abgelaufene Sicherungen automatisch gelöscht. Die MySQL-Dumps sind UTF8-kodiert und auf allen Plattformen zurücklesbar.

Vorsicht: Zerschossene Umlaute bei mysqldump.exe + PowerShell

Andere Skripts dieser Art schreiben zwar einen SQL-Dump, doch schaut man näher hin, sind die Umlaute zerschossen. 

Der Grund hierfür:
PowerShell kodiert den bereits UTF8-kodierten Stream von mysqldump.exe nochmals als UTF8, was das Ganze am Ende zuverlässig shreddert. Solche Backups sind nicht mehr oder nur unter großem Korrekturaufwand zurücklesbar.

Die Lösung für korrekte Zeichenkodierung in MySQL Backups per PowerShell

Der Trick ist nun der: Man startet mysqldump.exe aus PowerShell heraus in einem regulären Shell-Prozess. Somit bleibt alles sauber UTF8-kodiert, da PowerShell keinen Zugriff auf den Output-Stream hat.

Doch nun zum Backup-Skript:

# backup-mysql 1.0.1
#
# Backup a MySQL database.
#
# Run this from a Admin PowerShell, to enable local script execution:
# Set-ExecutionPolicy RemoteSigned
#
# (c)2020 Harald Schneider

# Config.start
#
$PATH_MYSQL = "C:\xampp\mysql\bin\" 
$PATH_ZIPTOOL = "C:\Program Files-Zip\" 
$PATH_BACKUP = "C:\xampp\custom\backup\" 

$HOLD_DAYS = 7

$MYSQL_USR = "root"
$MYSQL_PWD = "YOUR_PASSWORD_HERE"
$MYSQL_DB = "worktime"
#
# Config.end

$date = Get-Date 
$timestamp = "" + $date.year + "-" + $date.month + "-" + $date.day
$backupfile = $PATH_BACKUP + $MYSQL_DB + "_" + $timestamp +".sql" 
$backupzip = $PATH_BACKUP + $MYSQL_DB + "_" + $timestamp +".zip" 
 
echo ""
echo "Starting backup ..."

cd $PATH_MYSQL 

# Force mysqldump's output to stay UTF8 encoded by running it in a regular shell.
# So PowerShell cannot touch the stream. This is the way :)
# 
$CMD = '.\mysqldump.exe --force --opt --quote-names --skip-set-charset --default-character-set=utf8 -u"'+$MYSQL_USR+'" -p"'+$MYSQL_PWD+'" --databases '+$MYSQL_DB+' > '+$backupfile & cmd /c $CMD
 
cd $PATH_ZIPTOOL 
 
.z.exe a -tzip $backupzip $backupfile 

del $backupfile 
 
echo "Cleaning up ..."

cd $PATH_MYSQL 
$oldbackups = gci *.zip* 

for($i=0; $i -lt $oldbackups.count; $i++){ 
  if ($oldbackups[$i].CreationTime -lt $date.AddDays(-$HOLD_DAYS)){ 
      $oldbackups[$i] | Remove-Item -Confirm:$false 
  } 
}

Da die Backups komprimiert gespeichert werden, benötigen wir vorab 7-Zip, Download hier.

Standardmässig ist das Ausführen von PowerShell Scripts in Windows 10 aus Sicherheitsgründen abgeklemmt. Um die Sperre aufzuheben starten wir eine PowerShell per Rechtsklick als Admin und geben den folgenden Befehl ein:

Set-ExecutionPolicy RemoteSigned

Wir bestätigen mit A für “Alle”. Von nun an sind lokal erstellte Skripts erlaubt, aus dem Internet geladen Skripts jedoch nicht.

Windows 10: Die Konfiguration des PowerShell MySQL Backup-Skripts

Die verwendeten Konfigurations-Variablen haben die folgende Bedeutung:

  • PATH_MYSQL:
    Der Pfad zum “bin” Ordner des MySQL Datenbankservers. Hier befinden sich alle Tools, die MySQL mitbringt. Unter Anderem das von uns benötigte mysqldump.exe. Bitte auf den Backslash (“\”) am Ende achten.
  • PATH_ZIPTOOL:
    Der Pfad zur 7-Zip-Installation. Hier benötigen wir 7z.exe. Bitte auf den Backslash am Ende achten.
  • PATH_BACKUP:
    Der Pfad in dem unsere MySQL Backups gespeichert werden sollen, ebenfalls mit Backslash am Ende.
  • HOLD_DAYS:
    Die Anzahl der Tage nach denen Backups automatisch gelöscht werden.
  • MYSQL_USR und MYSQL_PWD
    Der Datenbank User und dessen Passwort.
  • MYSQL_DB:
    Der Name der zu sichernden MySQL Datenbank.

Das Skript speichern wir unter dem Namen “backup-mysql.ps1”.

Powershell Script im Windows Taskplaner (Aufgabenplaner) starten

Folgendes ist beim Anlegen des Tasks zu beachten:

Wir starten nicht das Skript direkt, sondern

powershell.exe

Als Parameter übergeben wir in einer einzigen Zeile den PowerShell Switch um die Execution-Policy zu ignorieren und den absoluten Pfad zum Script:

-ExecutionPolicy ByPass c:\xampp\custom\backup-mysql\backup-mysql.ps1

Das ist bereits alles – viel Spass beim Sichern :-)