MSSQL und MariaDB Backup: Migration und Wiederherstellung Guide
Einleitung
Die Migration von Datenbanken zwischen verschiedenen Systemen ist eine kritische Aufgabe in der IT-Administration. Microsoft SQL Server (MSSQL) und MariaDB sind zwei der am häufigsten eingesetzten Datenbankmanagementsysteme in Unternehmen. Während MSSQL vorwiegend in Windows-Umgebungen verwendet wird, hat sich MariaDB als leistungsstarke Open-Source-Alternative etabliert.
Dieses Tutorial behandelt die vollständige Sicherung, Migration und Wiederherstellung von MSSQL- und MariaDB-Datenbanken. Sie lernen, wie Sie strukturierte Backups erstellen, Daten zwischen verschiedenen Systemen migrieren und diese erfolgreich wiederherstellen. Dies ist besonders relevant bei Systemumstellungen, Disaster Recovery oder der Migration von proprietären zu Open-Source-Lösungen.
Systemvoraussetzungen
Hardware-Anforderungen
| Komponente | MSSQL Minimum | MSSQL Empfohlen | MariaDB Minimum | MariaDB Empfohlen |
|---|---|---|---|---|
| CPU | 1.4 GHz x64 | 4+ Kerne, 2.0+ GHz | 1 GHz x64 | 4+ Kerne, 2.0+ GHz |
| RAM | 2 GB | 16+ GB | 512 MB | 8+ GB |
| Festplatte | 6 GB | 100+ GB SSD | 200 MB | 50+ GB SSD |
| Netzwerk | 1 Gbit/s | 10 Gbit/s | 100 Mbit/s | 1+ Gbit/s |
Unterstützte Betriebssysteme
MSSQL Server 2022
- Windows Server 2019/2022
- Windows 10/11 (für Entwicklung)
- Ubuntu 18.04/20.04/22.04 LTS
- Red Hat Enterprise Linux 8/9
- SUSE Linux Enterprise Server 15
MariaDB 10.11 LTS
- Windows Server 2019/2022
- Ubuntu 18.04/20.04/22.04 LTS
- Debian 10/11/12
- CentOS 7/8, Rocky Linux 8/9
- Red Hat Enterprise Linux 7/8/9
Benötigte Netzwerk-Ports
| Service | Port | Protokoll | Firewall | Beschreibung |
|---|---|---|---|---|
| MSSQL Server | 1433 | TCP | Ja | Standard SQL Server Port |
| MSSQL Browser | 1434 | UDP | Optional | Named Instances |
| MariaDB | 3306 | TCP | Ja | Standard MySQL/MariaDB Port |
| SSH | 22 | TCP | Ja | Remote Administration (Linux) |
| RDP | 3389 | TCP | Ja | Remote Administration (Windows) |
Vorbereitung
Windows-System vorbereiten
# System aktualisieren
sconfig
# Wählen Sie Option 6 für Windows Updates
# .NET Framework installieren (falls nicht vorhanden)
# Laden Sie .NET Framework 4.8 von der Microsoft-Website herunter
# PowerShell auf neueste Version aktualisieren
winget install Microsoft.PowerShell
# SQL Server Management Studio installieren (optional)
winget install Microsoft.SQLServerManagementStudio
Linux-System vorbereiten (Ubuntu/Debian)
# System aktualisieren
sudo apt update && sudo apt upgrade -y
# Benötigte Pakete installieren
sudo apt install -y curl wget gnupg2 software-properties-common \
apt-transport-https ca-certificates lsb-release unzip
# Tools für Backup und Migration
sudo apt install -y mysql-client-core-8.0 mssql-tools18
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc
Linux-System vorbereiten (RHEL/CentOS/Rocky)
# System aktualisieren
sudo dnf update -y
# EPEL Repository aktivieren
sudo dnf install -y epel-release
# Benötigte Pakete installieren
sudo dnf install -y curl wget gnupg2 unzip mysql
# Microsoft Repository für MSSQL Tools
sudo curl -o /etc/yum.repos.d/msprod.repo https://packages.microsoft.com/config/rhel/9/prod.repo
sudo dnf install -y mssql-tools18
MSSQL Server Installation und Konfiguration
MSSQL Server auf Windows installieren
# SQL Server 2022 Express herunterladen und installieren
# Besuchen Sie: https://www.microsoft.com/de-de/sql-server/sql-server-downloads
# Installation über Kommandozeile (nach Download)
.\SQLEXPR_x64_ENU.exe /Q /IACCEPTSQLSERVERLICENSETERMS /ACTION=install /FEATURES=SQLENGINE /INSTANCENAME=MSSQLSERVER /SQLSYSADMINACCOUNTS="BUILTIN\Administrators" /TCPENABLED=1
MSSQL Server auf Linux installieren
# Microsoft Repository hinzufügen (Ubuntu)
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
sudo add-apt-repository "$(wget -qO- https://packages.microsoft.com/config/ubuntu/22.04/mssql-server-2022.list)"
# MSSQL Server installieren
sudo apt update
sudo apt install -y mssql-server
# MSSQL Server konfigurieren
sudo /opt/mssql/bin/mssql-conf setup
# Edition wählen (2 für Express, kostenlos)
# SA Passwort festlegen (mindestens 8 Zeichen, Groß-, Kleinbuchstaben, Zahlen, Sonderzeichen)
MariaDB Server Installation
MariaDB auf Windows installieren
# MariaDB MSI Installer herunterladen von https://mariadb.org/download/
# Installation über GUI oder Silent Install:
msiexec /i mariadb-10.11.x-winx64.msi /quiet SERVICENAME=MariaDB PASSWORD=IhrSicheresPasswort
MariaDB auf Linux installieren
# MariaDB Repository hinzufügen (Ubuntu)
sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'
sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el,s390x] https://mirror.fritz.box/mariadb/repo/10.11/ubuntu jammy main'
# MariaDB installieren
sudo apt update
sudo apt install -y mariadb-server mariadb-client
# MariaDB sichern
sudo mysql_secure_installation
# Root-Passwort setzen
# Anonyme Benutzer entfernen
# Root-Remote-Login deaktivieren
# Test-Datenbank entfernen
Firewall-Konfiguration
Windows Firewall
# MSSQL Server Port freigeben
netsh advfirewall firewall add rule name="MSSQL Server" dir=in action=allow protocol=TCP localport=1433
# MariaDB Port freigeben (falls installiert)
netsh advfirewall firewall add rule name="MariaDB Server" dir=in action=allow protocol=TCP localport=3306
Linux Firewall (UFW – Ubuntu/Debian)
# UFW aktivieren
sudo ufw enable
# MSSQL Server Port freigeben
sudo ufw allow 1433/tcp comment "MSSQL Server"
# MariaDB Port freigeben
sudo ufw allow 3306/tcp comment "MariaDB Server"
# SSH Port sicherstellen
sudo ufw allow 22/tcp comment "SSH"
# Status prüfen
sudo ufw status verbose
Linux Firewall (firewalld – RHEL/CentOS)
# Firewalld starten und aktivieren
sudo systemctl start firewalld
sudo systemctl enable firewalld
# MSSQL Server Port freigeben
sudo firewall-cmd --permanent --add-port=1433/tcp
sudo firewall-cmd --permanent --add-port=3306/tcp
# Regeln laden
sudo firewall-cmd --reload
# Status prüfen
sudo firewall-cmd --list-all
Vollumfängliche Backup-Erstellung
MSSQL Server Backup
Vollständiges Backup erstellen
-- Testdatenbank erstellen (falls nicht vorhanden)
CREATE DATABASE TestDB;
GO
USE TestDB;
GO
-- Beispieltabelle und Daten erstellen
CREATE TABLE Employees (
ID INT IDENTITY(1,1) PRIMARY KEY,
FirstName NVARCHAR(50),
LastName NVARCHAR(50),
Email NVARCHAR(100),
HireDate DATETIME DEFAULT GETDATE()
);
INSERT INTO Employees (FirstName, LastName, Email)
VALUES ('Max', 'Mustermann', 'max@example.com'),
('Anna', 'Schmidt', 'anna@example.com'),
('Peter', 'Meyer', 'peter@example.com');
-- Vollständiges Backup erstellen
BACKUP DATABASE TestDB
TO DISK = 'C:\Backups\TestDB_Full.bak'
WITH FORMAT,
NAME = 'TestDB Full Backup',
DESCRIPTION = 'Vollständiges Backup der TestDB';
GO
Skript für automatisierte MSSQL Backups
# PowerShell Backup-Skript für MSSQL
param(
[Parameter(Mandatory=$true)]
[string]$DatabaseName,
[Parameter(Mandatory=$false)]
[string]$BackupPath = "C:\Backups",
[Parameter(Mandatory=$false)]
[string]$ServerInstance = "localhost"
)
# Backup-Verzeichnis erstellen falls nicht vorhanden
if (!(Test-Path $BackupPath)) {
New-Item -ItemType Directory -Path $BackupPath -Force
}
# Zeitstempel für Backup-Datei
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$backupFileName = "${DatabaseName}_Full_${timestamp}.bak"
$fullBackupPath = Join-Path $BackupPath $backupFileName
# SQL Query für Backup
$sqlQuery = @"
BACKUP DATABASE [$DatabaseName]
TO DISK = '$fullBackupPath'
WITH FORMAT,
NAME = '$DatabaseName Full Backup $timestamp',
DESCRIPTION = 'Automatisches vollständiges Backup';
"@
try {
# Backup ausführen
Invoke-Sqlcmd -ServerInstance $ServerInstance -Query $sqlQuery -QueryTimeout 0
Write-Host "Backup erfolgreich erstellt: $fullBackupPath" -ForegroundColor Green
# Backup-Informationen anzeigen
$backupInfo = Get-ChildItem $fullBackupPath
Write-Host "Backup-Größe: $([math]::Round($backupInfo.Length/1MB, 2)) MB"
} catch {
Write-Error "Fehler beim Erstellen des Backups: $($_.Exception.Message)"
}
MariaDB Backup
Vollständiges MariaDB Backup mit mysqldump
#!/bin/bash
# MariaDB Backup Script
# Konfiguration
DB_USER="root"
DB_PASSWORD="IhrPasswort"
DB_HOST="localhost"
DB_NAME="testdb"
BACKUP_DIR="/backup/mariadb"
DATE=$(date +"%Y%m%d_%H%M%S")
# Backup-Verzeichnis erstellen
mkdir -p $BACKUP_DIR
# Testdatenbank und Tabelle erstellen (falls nicht vorhanden)
mysql -u$DB_USER -p$DB_PASSWORD -h$DB_HOST -e "
CREATE DATABASE IF NOT EXISTS $DB_NAME;
USE $DB_NAME;
CREATE TABLE IF NOT EXISTS employees (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
email VARCHAR(100),
hire_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT IGNORE INTO employees (id, first_name, last_name, email) VALUES
(1, 'Max', 'Mustermann', 'max@example.com'),
(2, 'Anna', 'Schmidt', 'anna@example.com'),
(3, 'Peter', 'Meyer', 'peter@example.com');
"
# Vollständiges Backup erstellen
echo "Erstelle vollständiges Backup von $DB_NAME..."
mysqldump -u$DB_USER -p$DB_PASSWORD -h$DB_HOST \
--single-transaction \
--routines \
--triggers \
--events \
--hex-blob \
--opt \
$DB_NAME > "$BACKUP_DIR/${DB_NAME}_full_${DATE}.sql"
# Backup komprimieren
gzip "$BACKUP_DIR/${DB_NAME}_full_${DATE}.sql"
echo "Backup erfolgreich erstellt: $BACKUP_DIR/${DB_NAME}_full_${DATE}.sql.gz"
# Backup-Größe anzeigen
ls -lh "$BACKUP_DIR/${DB_NAME}_full_${DATE}.sql.gz"
MariaDB Binäres Backup mit Mariabackup
#!/bin/bash
# Mariabackup für konsistente Hot-Backups
BACKUP_USER="backup_user"
BACKUP_PASSWORD="backup_password"
BACKUP_DIR="/backup/mariadb/hot"
DATE=$(date +"%Y%m%d_%H%M%S")
FULL_BACKUP_DIR="$BACKUP_DIR/full_$DATE"
# Backup-Benutzer erstellen (einmalig)
mysql -uroot -p -e "
CREATE USER IF NOT EXISTS '$BACKUP_USER'@'localhost' IDENTIFIED BY '$BACKUP_PASSWORD';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO '$BACKUP_USER'@'localhost';
GRANT SELECT ON mysql.user TO '$BACKUP_USER'@'localhost';
FLUSH PRIVILEGES;
"
# Backup-Verzeichnis erstellen
mkdir -p $FULL_BACKUP_DIR
# Vollständiges Hot-Backup erstellen
echo "Erstelle vollständiges Hot-Backup..."
mariabackup --backup \
--target-dir=$FULL_BACKUP_DIR \
--user=$BACKUP_USER \
--password=$BACKUP_PASSWORD \
--host=localhost
# Backup für Wiederherstellung vorbereiten
echo "Bereite Backup für Wiederherstellung vor..."
mariabackup --prepare --target-dir=$FULL_BACKUP_DIR
echo "Hot-Backup erfolgreich erstellt in: $FULL_BACKUP_DIR"
du -sh $FULL_BACKUP_DIR
Datenbank-Migration zwischen MSSQL und MariaDB
MSSQL zu MariaDB Migration
Schema-Export aus MSSQL
-- Schema-Informationen aus MSSQL extrahieren
USE TestDB;
-- Tabellen-Schema exportieren
SELECT
TABLE_NAME,
COLUMN_NAME,
DATA_TYPE,
CHARACTER_MAXIMUM_LENGTH,
IS_NULLABLE,
COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_CATALOG = 'TestDB'
ORDER BY TABLE_NAME, ORDINAL_POSITION;
-- Indizes exportieren
SELECT
i.name AS IndexName,
t.name AS TableName,
c.name AS ColumnName,
i.is_unique
FROM sys.indexes i
INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
INNER JOIN sys.tables t ON i.object_id = t.object_id
WHERE t.name = 'Employees';
Migration Script (Python)
#!/usr/bin/env python3
"""
MSSQL zu MariaDB Migration Script
"""
import pyodbc
import mysql.connector
import pandas as pd
import sys
from datetime import datetime
class DatabaseMigration:
def __init__(self, mssql_conn_str, mariadb_config):
self.mssql_conn_str = mssql_conn_str
self.mariadb_config = mariadb_config
def connect_mssql(self):
"""MSSQL Verbindung herstellen"""
try:
conn = pyodbc.connect(self.mssql_conn_str)
print("✓ MSSQL Verbindung hergestellt")
return conn
except Exception as e:
print(f"✗ MSSQL Verbindungsfehler: {e}")
return None
def connect_mariadb(self):
"""MariaDB Verbindung herstellen"""
try:
conn = mysql.connector.connect(**self.mariadb_config)
print("✓ MariaDB Verbindung hergestellt")
return conn
except Exception as e:
print(f"✗ MariaDB Verbindungsfehler: {e}")
return None
def get_mssql_tables(self, mssql_conn):
"""Tabellenliste aus MSSQL abrufen"""
query = """
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
"""
cursor = mssql_conn.cursor()
cursor.execute(query)
tables = [row[0] for row in cursor.fetchall()]
cursor.close()
return tables
def convert_datatype(self, mssql_type, length=None):
"""MSSQL Datentyp zu MariaDB konvertieren"""
type_mapping = {
'int': 'INT',
'bigint': 'BIGINT',
'smallint': 'SMALLINT',
'tinyint': 'TINYINT',
'bit': 'BOOLEAN',
'decimal': 'DECIMAL',
'numeric': 'DECIMAL',
'money': 'DECIMAL(19,4)',
'float': 'DOUBLE',
'real': 'FLOAT',
'datetime': 'DATETIME',
'datetime2': 'DATETIME',
'smalldatetime': 'DATETIME',
'date': 'DATE',
'time': 'TIME',
'timestamp': 'TIMESTAMP',
'char': f'CHAR({length})' if length else 'CHAR(255)',
'varchar': f'VARCHAR({length})' if length else 'VARCHAR(255)',
'nchar': f'CHAR({length})' if length else 'CHAR(255)',
'nvarchar': f'VARCHAR({length})' if length else 'VARCHAR(255)',
'text': 'TEXT',
'ntext': 'TEXT',
'image': 'LONGBLOB',
'binary': f'BINARY({length})' if length else 'BINARY(255)',
'varbinary': f'VARBINARY({length})' if length else 'VARBINARY(255)'
}
return type_mapping.get(mssql_type.lower(), 'TEXT')
def migrate_table_schema(self, table_name, mssql_conn, mariadb_conn):
"""Tabellen-Schema migrieren"""
# Schema aus MSSQL lesen
schema_query = """
SELECT
COLUMN_NAME,
DATA_TYPE,
CHARACTER_MAXIMUM_LENGTH,
IS_NULLABLE,
COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ?
ORDER BY ORDINAL_POSITION
"""
mssql_cursor = mssql_conn.cursor()
mssql_cursor.execute(schema_query, table_name)
columns = mssql_cursor.fetchall()
mssql_cursor.close()
# CREATE TABLE Statement für MariaDB generieren
create_table = f"CREATE TABLE IF NOT EXISTS {table_name} (\n"
column_definitions = []
for col in columns:
col_name, data_type, max_length, is_nullable, default_val = col
mariadb_type = self.convert_datatype(data_type, max_length)
nullable = "NULL" if is_nullable == "YES" else "NOT NULL"
# Auto-Increment für IDENTITY Spalten
if data_type.lower() == 'int' and 'IDENTITY' in str(default_val):
mariadb_type += " AUTO_INCREMENT PRIMARY KEY"
nullable = "NOT NULL"
column_def = f" {col_name} {mariadb_type} {nullable}"
column_definitions.append(column_def)
create_table += ",\n".join(column_definitions) + "\n);"
# Tabelle in MariaDB erstellen
mariadb_cursor = mariadb_conn.cursor()
try:
mariadb_cursor.execute(create_table)
mariadb_conn.commit()
print(f"✓ Schema für Tabelle '{table_name}' erstellt")
except Exception as e:
print(f"✗ Fehler beim Erstellen der Tabelle '{table_name}': {e}")
finally:
mariadb_cursor.close()
def migrate_table_data(self, table_name, mssql_conn, mariadb_conn, batch_size=1000):
"""Tabellendaten migrieren"""
try:
# Daten aus MSSQL lesen
df = pd.read_sql(f"SELECT * FROM {table_name}", mssql_conn)
if df.empty:
print(f"⚠ Tabelle '{table_name}' ist leer")
return
# Spaltennamen für INSERT vorbereiten
columns = ', '.join(df.columns)
placeholders = ', '.join(['%s'] * len(df.columns))
mariadb_cursor = mariadb_conn.cursor()
# Daten in Batches einfügen
for i in range(0, len(df), batch_size):
batch = df.iloc[i:i+batch_size]
values = [tuple(row) for row in batch.values]
insert_query = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
mariadb_cursor.executemany(insert_query, values)
mariadb_conn.commit()
print(f"✓ {len(values)} Zeilen in '{table_name}' migriert (Batch {i//batch_size + 1})")
mariadb_cursor.close()
print(f"✓ Alle Daten für Tabelle '{table_name}' migriert ({len(df)} Zeilen)")
except Exception as e:
print(f"✗ Fehler bei der Datenmigration für '{table_name}': {e}")
# Hauptprogramm
if __name__ == "__main__":
# Verbindungsparameter
mssql_conn_str = (
"DRIVER={ODBC Driver 18 for SQL Server};"
"SERVER=localhost;"
"DATABASE=TestDB;"
"Trusted_Connection=yes;"
"TrustServerCertificate=yes;"
)
mariadb_config = {
'host': 'localhost',
'user': 'root',
'password': 'IhrPasswort',
'database': 'testdb_migrated',
'charset': 'utf8mb4'
}
# Migration starten
migration = DatabaseMigration(mssql_conn_str, mariadb_config)
# Verbindungen herstellen
mssql_conn = migration.connect_mssql()
mariadb_conn = migration.connect_mariadb()
if not mssql_conn or not mariadb_conn:
sys.exit(1)
try:
# Zieldatenbank erstellen
mariadb_cursor = mariadb_conn.cursor()
mariadb_cursor.execute("CREATE DATABASE IF NOT EXISTS testdb_migrated")
mariadb_cursor.execute("USE testdb_migrated")
mariadb_cursor.close()
# Tabellen abrufen und migrieren
tables = migration.get_mssql_tables(mssql_conn)
print(f"Gefundene Tabellen: {tables}")
for table in tables:
print(f"\n--- Migriere Tabelle: {table} ---")
migration.migrate_table_schema(table, mssql_conn, mariadb_conn)
migration.migrate_table_data(table, mssql_conn, mariadb_conn)
print("\n✓ Migration abgeschlossen!")
finally:
mssql_conn.close()
mariadb_conn.close()
MariaDB zu MSSQL Migration
#!/bin/bash
# MariaDB zu MSSQL Export Script
DB_USER="root"
DB_PASSWORD="IhrPasswort"
DB_NAME="testdb"
EXPORT_DIR="/tmp/migration"
mkdir -p $EXPORT_DIR
# Schema-kompatiblen Export erstellen
mysqldump -u$DB_USER -p$DB_PASSWORD \
--compatible=mssql \
--single-transaction \
--no-auto-rehash \
--skip-extended-insert \
--skip-comments \
$DB_NAME > "$EXPORT_DIR/${DB_NAME}_for_mssql.sql"
# Manuelle Nachbearbeitung für MSSQL-Kompatibilität
sed -i 's/AUTO_INCREMENT/IDENTITY(1,1)/g' "$EXPORT_DIR/${DB_NAME}_for_mssql.sql"
sed -i 's/ENGINE=InnoDB DEFAULT CHARSET=utf8mb4//g' "$EXPORT_DIR/${DB_NAME}_for_mssql.sql"
sed -i 's/`//g' "$EXPORT_DIR/${DB_NAME}_for_mssql.sql"
echo "Export für MSSQL vorbereitet: $EXPORT_DIR/${DB_NAME}_for_mssql.sql"
Dienste starten und konfigurieren
Windows Services
# MSSQL Server Service starten
Start-Service MSSQLSERVER
Set-Service MSSQLSERVER -StartupType Automatic
# SQL Server Browser (optional)
Start-Service SQLB