12 June 2011 Backup, MySQL, Powershell Robert Muehsig

Ich glaube es gibt keinen Zweifel, dass ein Backup immer eine gute Idee ist. Wer eine MySQL Datenbank nutzt, der kann dieses Backup natürlich mit Bordmitteln sichern oder auch über die Powershell erstellen lassen.

MySQL Datenbanken manuell sichern (mysqldump)

Um ein Dump (ein Backup) der gesamten Datenbank (oder nur Teile davon) ohne Powershell o.Ä. anzulegen, wird bei der Installation das Programm “mysqldump” mit ausgeliefert (Installationspfad auf Windows: C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqldump.exe)

Die wichtigstens Informationen über dieses Tool liefert wahrscheinlich die MySQL Doku: mysqldump

Dieses Programm wird später noch wichtig, wenn wir das Backup wieder einspielen wollen.

MySQL Datenbanken mit Powershell sichern

Das Vorgehen (und das Script) entspricht auf den tollen Knowledge-Base Artikel auf dieser Seite – ich werde also nur kurz mein Vorgehen wiedergeben.

Voraussetzungen

- Powershell (ab Win 2008 mit dabei)
- Den MySQL .NET Connector (gibt es z.B. hier http://www.mysql.de/products/connector/ )
(- mysqldump, das sollte allerdings ohnehin da sein).

Das Script

Das Powershell Script ist zu 99% dieses hier, allerdings hatte ich einen Bug (warum er bei mir auftrat und in seinem Script nicht keine Ahnung) und hatte entsprechend das Script angepasst.

Die ersten drei Einstellungen geben die Verbindungsdaten wieder. Der “Backupstorefolder” ist ein Ordner (welcher vorher angelegt werden muss!), in dem die MySQL Dumps gespeichert werden.

Es muss zudem (jedenfalls war es bei mir so) der Pfad zur mysqldump.exe Applikation angegeben werden.

Das Script geniert SQLs nach dem Schema “WOCHENTAG_Datenbank” und zusätzlich immer noch ein “latest_Datenbank” – die “latest_Datenbank” Files kann man also auch woanders sichern wenn man das möchte.

Das komplette Script:

# MySQL Database Backup Script
# -----------------------------
#
# This script will query a specified MySQL database and then create .sql backup files
# of all located databases.
#
# Use of this script is done entirely at your own risk.  No guarantee either direct
# or indirect is implied regarding the security, stability, reliability, impact or
# performance of this script.
#
# To configure this script, alter the values below.  Please do make any direct alterations
# to the script coding as this may result in undesired performance.
#

# Core settings - you will need to set these
$mysql_server = "localhost"
$mysql_user = "USER"
$mysql_password = "PASSWORD"
$backupstorefolder= "C:\_backup\"

# Extended Settings - you may not need to set these
$pathtomysqldump = "C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqldump.exe"
$latestbackupfolder = "C:\_backup\"



#--------------------------------------------------------

# Determine Today's Date Day (monday, tuesday etc)
$gd = get-date
$dayofweek = [string] $gd.DayOfWeek


# Connect to MySQL database 'information_schema'
[system.reflection.assembly]::LoadWithPartialName("MySql.Data")
$cn = New-Object -TypeName MySql.Data.MySqlClient.MySqlConnection
$cn.ConnectionString = "SERVER=$mysql_server;DATABASE=information_schema;UID=$mysql_user;PWD=$mysql_password"
$cn.Open()

# Query MySQL 
$cm = New-Object -TypeName MySql.Data.MySqlClient.MySqlCommand
$sql = "SELECT DISTINCT CONVERT(SCHEMA_NAME USING UTF8) AS dbName, CONVERT(NOW() USING UTF8) AS dtStamp FROM SCHEMATA ORDER BY dbName ASC"
$cm.Connection = $cn
$cm.CommandText = $sql
$dr = $cm.ExecuteReader() 

# Loop through MySQL Records
while ($dr.Read())
{
    # Start By Writing MSG to screen
    $dbname = [string]$dr.GetString(0)
    write-host "Backing up database: " $dr.GetString(0)
    
    # Set backup filename and check if exists, if so delete existing
    $backupfilename = $dayofweek + "_" + $dr.GetString(0) + ".sql"
    $backuppathandfile = $backupstorefolder + "" + $backupfilename
    If (test-path($backuppathandfile)) 
    {
        write-host "Backup file '" $backuppathandfile "' already exists.  Existing file will be deleted"
        Remove-Item $backuppathandfile
    }

    # Invoke backup Command. /c forces the system to wait to do the backup
    cmd /c " `"$pathtomysqldump`" --single-transaction -h $mysql_server -u $mysql_user -p$mysql_password $dbname > $backuppathandfile "
    If (test-path($backuppathandfile)) 
    {
        write-host "Backup created.  Presence of backup file verified"
    }
    
    # Handle LatestBackup functionality
    If (test-path($backuppathandfile)) 
    {
        $latestbackupfilenameandpath = $latestbackupfolder + "latest_" + $dbname + ".sql"
        &cmd /c "copy /y `"$backuppathandfile`" `"$latestbackupfilenameandpath`" "
        write-host "Backup file copied to latestbackup folder" 
    }

    # Write Space
    write-host " "
}
$cn.Close()

# END OF SCRIPT

 

MySQL Datenbanken Dump wieder einspielen

Hierbei muss man über die CMD gehen und der mysql.exe (ebenfalls im bin Verzeichnis der MySQL Installation) nach diesem Schema den SQL Dump übergeben. Die Datenbank muss vorher existieren (CREATE Database …)

mysql -u dbusername -p databasename < C:\path\to\backupname.sql

 

Das fertige Powershell kann man, wie z.B. in dem ursprünglichen Artikel über einen Scheduled Task starten lassen etc.

Als Tipp: Probiert vorher aus, ob eure Backup Strategie wirklich funktioniert Zwinkerndes Smiley


Written by Robert Muehsig

Software Developer - from Dresden, Germany, now living & working in Switzerland. Microsoft MVP & Web Geek.
Other Projects: KnowYourStack.com | ExpensiveMeeting | EinKofferVollerReisen.de

If you like the content and want to support me you could buy me a beer or a coffee via Litecoin or Bitcoin - thanks for reading!