In diesem Dokument erfahren Sie, wie Sie geplante, anwendungskonsistente Sicherungen und Workflows für die Wiederherstellung zu einem bestimmten Zeitpunkt (Point-in-Time Recovery, PITR) für selbstverwaltete Datenbanken konfigurieren, die auf Linux-VM-Instanzen in Compute Engine ausgeführt werden.
Wenn Sie zustandsorientierte Datenbankarbeitslasten wie IBM Db2, SAP HANA, MySQL oder PostgreSQL sichern, können standardmäßige absturzkonsistente Snapshots, die von Backup und DR erstellt werden, die Datenbank erfassen, während Transaktionen noch ausgeführt werden. Diese unvollständigen Transaktionen können Daten beschädigen, Tabellen in inkonsistenten Zuständen hinterlassen und bei der Wiederherstellung nach einem Absturz langwierige Datenbankreparaturroutinen erfordern. Anwendungskonsistente Sicherungen beheben diese Probleme, indem sie in den VM-Gast-Agent eingebunden werden, um die Datenbank stillzulegen und optional das Dateisystem einzufrieren, bevor ein Snapshot erstellt wird.
Hinweis
Führen Sie die folgenden Aufgaben aus, bevor Sie anwendungskonsistente Sicherungen konfigurieren.
Erforderliche Rollen
Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen für das Projekt zuzuweisen, damit Sie die nötigen Berechtigungen für die Konfiguration anwendungskonsistenter Sicherungen haben:
-
Zum Konfigurieren und Verwalten von Sicherungsplänen:
Backup and DR Backup User (
roles/backupdr.backupUser) -
Zum Verwalten von Compute Engine-Instanzen:
Compute Instance Admin (v1) (
roles/compute.instanceAdmin.v1) -
Für den Zugriff auf Secret Manager-Secrets über Skripts:
Secret Manager Secret Accessor (
roles/secretmanager.secretAccessor)
Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.
Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.
Vorbereitung
Wählen Sie in der Google Cloud Console auf der Seite für die Projektauswahl ein Projekt vonGoogle Cloud aus oder erstellen Sie eines.
Prüfen Sie, ob die Abrechnung für Ihr Projekt aktiviert ist.
Informationen dazu, wie Sie prüfen, ob die Abrechnung aktiviert ist
Aktivieren Sie die Backup and DR API und die Secret Manager API.
Achten Sie darauf, dass Ihre Datenbankdaten und Logdateien auf nichtflüchtigen Standardspeichern gespeichert sind. Google Cloud Hyperdisk-Volumes unterstützen keine Gast-Flush-Vorgänge.
Wenn Sie die Wiederherstellung zu einem bestimmten Zeitpunkt konfigurieren möchten, konfigurieren Sie Ihre Datenbank so, dass ihre Transaktions- und Redo-Logs auf einer dedizierten, separaten Persistent Disk archiviert werden, die beispielsweise unter
/db2/ACT/log_archivebereitgestellt wird.
BYOS-Gast-Flush-Framework (Bring-Your-Own-Script) verwenden
Backup und DR verwendet das BYOS-Framework (Bring-Your-Own-Script) für die Gast-Flush-Funktion, um die Datenbank vor dem Erstellen eines Snapshots in den Ruhezustand zu versetzen. Die Gastumgebung basiert auf zwei Skripts, die sich im Verzeichnis /etc/google/snapshots/ auf Ihrer Linux-VM-Instanz befinden:
- Pre-Snapshot-Skript (
/etc/google/snapshots/pre.sh): Wird ausgeführt, bevor der Snapshot erstellt wird. Dieses Skript muss Datenbankvorgänge stilllegen und kann optional das Dateisystem einfrieren. - Post-Snapshot-Skript (
/etc/google/snapshots/post.sh): Wird nach dem Erstellen des Snapshots ausgeführt. Dieses Skript muss optional das Dateisystem wieder freigeben und die Datenbankvorgänge fortsetzen.
Weitere Informationen zu datenbankspezifischen Scriptvorlagen finden Sie unter Beispielscripts nach Datenbanktyp prüfen.
Optional: Dateisysteme einfrieren und wieder freigeben
Das Einfrieren des Dateisystems mit dem Linux-Standarddienstprogramm fsfreeze ist optional und nicht obligatorisch. Durch das Stilllegen der Datenbank wird die Transaktionskonsistenz auf Anwendungsebene sichergestellt. Wenn Sie jedoch zusätzliche Konsistenz auf Dateisystemebene benötigen, können Sie optional die folgenden Befehle zum Einfrieren und Aufheben des Einfrierens des Dateisystems in Ihre Skripts einfügen.
Achten Sie darauf, dass die Skripts pre.sh und post.sh auf der VM so konfiguriert sind, dass das optionale Einfrieren des Dateisystems für Log-Volumes ohne Unterbrechung der Datenbankvorgänge möglich ist.
Anweisungen zum Einfrieren des Dateisystems zu pre.sh hinzufügen
Wenn Sie Dateisysteme einfrieren möchten, fügen Sie am Ende des pre.sh-Skripts nach dem Stilllegen der Datenbank die folgende Erkennungs- und Einfrierlogik hinzu:
# Discover local writeable mount points
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
# FREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
if ! sudo fsfreeze -f "$mnt"; then
logger "Error: Failed to freeze $mnt. Cleaning up..."
# Attempt emergency thaw
for thaw_mnt in $MOUNT_POINTS; do sudo fsfreeze -u "$thaw_mnt" 2>/dev/null; done
# Add your database-specific resume/cleanup commands here before exiting
exit 1
fi
logger "Filesystem $mnt is frozen."
done
Anleitung zum Aufheben des Einfrierens des Dateisystems zu „post.sh“ hinzufügen
Wenn Sie Dateisysteme in pre.sh einfrieren, fügen Sie am Anfang des post.sh-Skripts die folgende Logik zum Aufheben des Einfrierens hinzu, bevor Sie die Datenbank fortsetzen:
# Discover local writeable mount points
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
# UNFREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
sudo fsfreeze -u "$mnt"
logger "Filesystem $mnt is unfrozen."
done
Anmeldedaten dynamisch mit Secret Manager abrufen
Vermeiden Sie es, statische Datenbankanmeldedaten oder Passwörter in Ihren Shell-Skripts hartzucodieren. Verwenden Sie stattdessen Secret Manager, um Anmeldedaten zur Laufzeit dynamisch abzurufen. Ersetzen Sie statische Passwortvariablen in Ihren Skripts durch die folgende Logik:
# Fetch the database password from Secret Manager dynamically
DBPASSWORD=$(gcloud secrets versions access latest \
--secret="SECRET_NAME" \
--format='get(payload.data)' | tr -d '\n')
if [ $? -ne 0 ]; then
logger "Critical Error: Unable to fetch the password from Secret Manager."
exit 1
fi
Ersetzen Sie SECRET_NAME durch den Namen des Secrets in Secret Manager.
Beispielskripts nach Datenbanktyp ansehen
Die folgenden Beispiele enthalten pre.sh- und post.sh-Implementierungen für unterstützte Datenbank-Engines, die auf Linux-Instanzen ausgeführt werden.
IBM Db2
Skript vor dem Snapshot (/etc/google/snapshots/pre.sh)
#!/bin/bash
# Location: /etc/google/snapshots/pre.sh
# 1. Define Mount Points for the Database
MOUNT_POINTS=("DATA_MOUNT_POINT" "LOG_MOUNT_POINT")
logger "BYOS Framework: Starting pre-snapshot script."
# 2. QUIESCE DATABASE (Generic Hook)
# Replace with DB-specific command (e.g., 'db2 set write suspend')
logger "Suspending Database I/O..."
# [INSERT DB QUIESCE COMMAND HERE]
# 3. FREEZE FILESYSTEMS (Optional)
for mnt in "${MOUNT_POINTS[@]}"; do
if ! sudo fsfreeze -f "$mnt"; then
logger "Error: Failed to freeze $mnt."
# Attempt emergency thaw
for thaw_mnt in "${MOUNT_POINTS[@]}"; do sudo fsfreeze -u "$thaw_mnt" 2>/dev/null; done
# [INSERT DB RESUME COMMAND HERE]
exit 1
fi
logger "Filesystem $mnt is frozen."
done
Post-Snapshot-Skript (/etc/google/snapshots/post.sh)
#!/bin/bash
# Location: /etc/google/snapshots/post.sh
MOUNT_POINTS=("DATA_MOUNT_POINT" "LOG_MOUNT_POINT")
logger "BYOS Framework: Starting post-snapshot script."
# 1. UNFREEZE FILESYSTEMS (Optional)
for mnt in "${MOUNT_POINTS[@]}"; do
sudo fsfreeze -u "$mnt"
logger "Filesystem $mnt is unfrozen."
done
# 2. RESUME DATABASE (Generic Hook)
# Replace with DB-specific command (e.g., 'db2 set write resume')
logger "Resuming Database I/O..."
# [INSERT DB RESUME COMMAND HERE]
logger "BYOS Framework: Cleanup complete."
Oracle
Skript vor dem Snapshot (/etc/google/snapshots/pre.sh)
sudo mkdir -p /etc/google/snapshots
sudo tee /etc/google/snapshots/pre.sh > /dev/null << 'EOF'
#!/bin/bash
# Place Oracle (ASM) into hot backup mode before Backup and DR captures disks
su - oracle -c "sqlplus -s / as sysdba" << 'SQL'
WHENEVER SQLERROR EXIT FAILURE;
ALTER DATABASE BEGIN BACKUP;
EXIT;
SQL
if [ $? -ne 0 ]; then
echo "Error: Failed to place Oracle in backup mode. Aborting snapshot." >&2
exit 1
fi
EOF
sudo chmod 750 /etc/google/snapshots/pre.sh
Post-Snapshot-Skript (/etc/google/snapshots/post.sh)
sudo tee /etc/google/snapshots/post.sh > /dev/null << 'EOF'
#!/bin/bash
# Release Oracle from backup mode and archive current redo log to +FRA
su - oracle -c "sqlplus -s / as sysdba" << 'SQL'
WHENEVER SQLERROR EXIT FAILURE;
ALTER DATABASE END BACKUP;
ALTER SYSTEM ARCHIVE LOG CURRENT;
EXIT;
SQL
if [ $? -ne 0 ]; then
echo "Warning: Failed to execute ALTER DATABASE END BACKUP." >&2
exit 1
fi
EOF
sudo chmod 750 /etc/google/snapshots/post.sh
SAP HANA
Skript vor dem Snapshot (/etc/google/snapshots/pre.sh)
#!/bin/bash
# Location: /etc/google/snapshots/pre.sh
DISK_ARG="$1"
# 1. Configuration & Discovery
DBSID="DBSID"
DBADM="DBADM"
ID_FILE="/tmp/hana_snapshot_id_$DBSID"
HDB_KEY="HDB_KEY"
if [[ "$DISK_ARG" == "," ]] || [[ "$DISK_ARG" == "1/0" ]] || [[ "$DISK_ARG" == "sda" ]]; then
# Dynamically discover all local writeable mount points for full VM image consistency
# Filters out pseudo, temporary, and read-only filesystems
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "SAP HANA Full VM BYOS: Starting pre-snapshot script for $DBSID."
# 2. QUIESCE DATABASE (Create SAP HANA Snapshot)
logger "SAP HANA Full VM BYOS: Creating database snapshot..."
# Determine HANA Version
# Versions 2.0+ use 'FOR FULL SYSTEM' syntax
HANAVERSION=$(su - $DBADM -c "HDB version" | grep "version:" | awk '{print $2}' | cut -d'.' -f1)
if [ "$HANAVERSION" = "1" ]; then
SQL="BACKUP DATA CREATE SNAPSHOT COMMENT 'SNAPSHOT_$(date +%Y%m%d)'"
else
SQL="BACKUP DATA FOR FULL SYSTEM CREATE SNAPSHOT COMMENT 'SNAPSHOT_$(date +%Y%m%d)'"
fi
# Execute the snapshot command via hdbsql
su - $DBADM -c "hdbsql -j -U $HDB_KEY \"$SQL\""
if [ $? -ne 0 ]; then
logger "Error: Failed to create SAP HANA snapshot."
exit 1
fi
# Retrieve the BACKUP_ID for the prepared snapshot
ID=$(su - $DBADM -c "hdbsql -j -t -U $HDB_KEY \"SELECT BACKUP_ID FROM M_BACKUP_CATALOG WHERE STATE_NAME = 'prepared' ORDER BY SYS_START_TIME DESC\"" | head -n 2 | tr -d '"' | tail -n 1)
if [ -z "$ID" ]; then
logger "Error: Could not retrieve BACKUP_ID for prepared snapshot."
exit 1
fi
echo "$ID" > "$ID_FILE"
logger "SAP HANA Full VM BYOS: Database snapshot prepared with ID $ID."
fi
Post-Snapshot-Skript (/etc/google/snapshots/post.sh)
#!/bin/bash
# Location: /etc/google/snapshots/post.sh
DISK_ARG="$1"
# 1. Configuration & Discovery
DBSID="DBSID"
DBADM="DBADM"
ID_FILE="/tmp/hana_snapshot_id_$DBSID"
HDB_KEY="HDB_KEY"
if [[ "$DISK_ARG" == "," ]] || [[ "$DISK_ARG" == "1/0" ]] || [[ "$DISK_ARG" == "sda" ]]; then
# Discover all local writeable mount points to perform unfreeze
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "SAP HANA Full VM BYOS: Starting post-snapshot script for $DBSID."
# 3. RESUME DATABASE (Close SAP HANA Snapshot)
if [ -f "$ID_FILE" ]; then
ID=$(cat "$ID_FILE")
logger "SAP HANA Full VM BYOS: Closing database snapshot ID $ID..."
# Determine HANA version for correct syntax
HANAVERSION=$(su - $DBADM -c "HDB version" | grep "version:" | awk '{print $2}' | cut -d'.' -f1)
if [ "$HANAVERSION" = "1" ]; then
SQL="BACKUP DATA CLOSE SNAPSHOT BACKUP_ID $ID SUCCESSFUL 'SNAPSHOT_COMPLETED'"
else
SQL="BACKUP DATA FOR FULL SYSTEM CLOSE SNAPSHOT BACKUP_ID $ID SUCCESSFUL 'SNAPSHOT_COMPLETED'"
fi
# Execute the close snapshot command
RESULT=$(su - $DBADM -c "hdbsql -j -U $HDB_KEY \"$SQL\"")
if [ $? -ne 0 ]; then
logger "Error: Failed to close SAP HANA snapshot. $RESULT"
else
logger "SAP HANA Full VM BYOS: Database snapshot closed successfully."
fi
# Cleanup the temporary ID file
rm -f "$ID_FILE"
else
logger "Error: Snapshot ID file not found. Manual intervention required to close HANA snapshot."
fi
logger "SAP HANA Full VM BYOS: Cleanup complete."
else
MOUNT_POINTS="/hanabackup"
for mnt in $MOUNT_POINTS; do
sudo fsfreeze -u "$mnt"
logger "Filesystem $mnt is unfrozen."
done
fi
Ersetzen Sie Folgendes:
DBSID: die SAP HANA-System-ID (SID) in Großbuchstaben.DBADM: der Betriebssystemnutzer des SAP HANA-Administrators (z. B.<sid>adm).HDB_KEY: der für den Datenbankzugriff konfigurierte SAP HANA-Userstore-Schlüssel.
SAP ASE
Skript vor dem Snapshot (/etc/google/snapshots/pre.sh)
#!/bin/bash
# Location: /etc/google/snapshots/pre.sh
# 1. Configuration
OSUSER="OS_USER"
SYB_SERVER="SYB_SERVER_NAME"
SYB_USER="SYB_USER"
SYB_PASS="SYB_PASSWORD"
SYB_DBLIST="DATABASE_LIST"
TAG_NAME="SNAPSHOT_$(date +%Y%m%d)"
MANIFEST_DIR="/var/tmp/sybase_manifests" # Directory for manifest files
# 2. Discovery
# Dynamically discover local writeable mount points
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "Sybase Full VM BYOS: Starting pre-snapshot script."
# 3. QUIESCE DATABASE
mkdir -p "$MANIFEST_DIR"
chown $OSUSER "$MANIFEST_DIR"
logger "Sybase Full VM BYOS: Quiescing databases: $SYB_DBLIST..."
# Command logic from act_sybase_pre.sh
# We use 'hold' to suspend activity and create the manifest file
su - $OSUSER -c "isql -U$SYB_USER -P$SYB_PASS -S$SYB_SERVER -X --retserverror" <<EOF
quiesce database $TAG_NAME hold $SYB_DBLIST for external dump to '$MANIFEST_DIR/manifest_$TAG_NAME.dat' with override
go
exit
EOF
if [ $? -ne 0 ]; then
logger "Error: Failed to quiesce Sybase databases."
exit 1
fi
# 4. FREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
if ! sudo fsfreeze -f "$mnt"; then
logger "Error: Failed to freeze $mnt."
# Attempt emergency thaw
for thaw_mnt in $MOUNT_POINTS; do sudo fsfreeze -u "$thaw_mnt" 2>/dev/null; done
# Release the database quiesce
su - $OSUSER -c "isql -U$SYB_USER -P$SYB_PASS -S$SYB_SERVER -X" <<EOF
quiesce database $TAG_NAME release
go
exit
EOF
exit 1
fi
logger "Filesystem $mnt is frozen."
done
Post-Snapshot-Skript (/etc/google/snapshots/post.sh)
#!/bin/bash
# Location: /etc/google/snapshots/post.sh
# 1. Configuration
OSUSER="OS_USER"
SYB_SERVER="SYB_SERVER_NAME"
SYB_USER="SYB_USER"
SYB_PASS="SYB_PASSWORD"
TAG_NAME="SNAPSHOT_$(date +%Y%m%d)"
MANIFEST_DIR="/var/tmp/sybase_manifests"
# 2. Discovery
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "Sybase Full VM BYOS: Starting post-snapshot script."
# 3. UNFREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
sudo fsfreeze -u "$mnt"
logger "Filesystem $mnt is unfrozen."
done
# 4. RESUME DATABASE
logger "Sybase Full VM BYOS: Releasing databases for tag $TAG_NAME..."
# Command logic from act_sybase_post.sh
su - $OSUSER -c "isql -U$SYB_USER -P$SYB_PASS -S$SYB_SERVER -X" <<EOF
use master
go
quiesce database $TAG_NAME release
go
exit
EOF
if [ $? -ne 0 ]; then
logger "Error: Failed to release Sybase databases."
else
logger "Sybase Full VM BYOS: Databases released successfully."
# Cleanup manifest
rm -f "$MANIFEST_DIR/manifest_$TAG_NAME.dat"
fi
logger "Sybase Full VM BYOS: Cleanup complete."
Ersetzen Sie Folgendes:
OS_USER: der Betriebssystemnutzer, der SAP ASE ausführt (z. B.sybase).SYB_SERVER_NAME: der SAP ASE-Servername.SYB_USER: der Datenbanknutzer mit Berechtigungen zum Deaktivieren von Datenbanken.SYB_PASSWORD: das Passwort des Datenbanknutzers (oder dynamisch mit Secret Manager abrufen).DATABASE_LIST: eine durch Kommas getrennte Liste der Datenbanken, die in den Ruhezustand versetzt werden sollen.
SAP IQ
Skript vor dem Snapshot (/etc/google/snapshots/pre.sh)
#!/bin/bash
# Location: /etc/google/snapshots/pre.sh
# 1. Configuration
OSUSER="OS_USER"
DB_NAME="DB_NAME"
CONN_STR="uid=DB_USER;pwd=DB_PASSWORD;dbn=$DB_NAME;eng=ENGINE_NAME"
BKP_DIR="/var/tmp/sybaseiq_bkp"
FULL_BKP_FILE="$BKP_DIR/FULL_VIR_DEC"
# 2. Discovery
# Dynamically discover all local writeable mount points for full VM consistency
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "SybaseIQ Full VM BYOS: Starting pre-snapshot script."
# 3. QUIESCE DATABASE (Virtual Decoupled Backup)
mkdir -p "$BKP_DIR"
chown $OSUSER "$BKP_DIR"
logger "SybaseIQ Full VM BYOS: Preparing virtual decoupled backup..."
# Execute the quiesce command logic from act_sybaseiq_pre.sh
su -m $OSUSER -c "dbisql -nogui -c '$CONN_STR' \"BACKUP DATABASE FULL VIRTUAL DECOUPLED TO '$FULL_BKP_FILE'\""
if [ $? -ne 0 ]; then
logger "Error: Failed to freeze (not able to take full_vir_dec backup)."
exit 1
fi
# 4. FREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
if ! sudo fsfreeze -f "$mnt"; then
logger "Error: Failed to freeze $mnt."
# Attempt emergency thaw
for thaw_mnt in $MOUNT_POINTS; do sudo fsfreeze -u "$thaw_mnt" 2>/dev/null; done
# Cleanup quiesce file as backup is invalid
rm -f "$FULL_BKP_FILE"
exit 1
fi
logger "Filesystem $mnt is frozen."
done
Post-Snapshot-Skript (/etc/google/snapshots/post.sh)
#!/bin/bash
# Location: /etc/google/snapshots/post.sh
# 1. Configuration
OSUSER="OS_USER"
DB_NAME="DB_NAME"
CONN_STR="uid=DB_USER;pwd=DB_PASSWORD;dbn=$DB_NAME;eng=ENGINE_NAME"
BKP_DIR="/var/tmp/sybaseiq_bkp"
FULL_BKP_FILE="$BKP_DIR/FULL_VIR_DEC"
INC_BKP_FILE="$BKP_DIR/INC_BKP"
# 2. Discovery
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "SybaseIQ Full VM BYOS: Starting post-snapshot script."
# 3. UNFREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
sudo fsfreeze -u "$mnt"
logger "Filesystem $mnt is unfrozen."
done
# 4. RESUME DATABASE (Post-Snapshot Cleanup)
logger "SybaseIQ Full VM BYOS: Performing incremental since full backup..."
# Logic from act_sybaseiq_post.sh to finish the decoupled sequence
su -m $OSUSER -c "dbisql -nogui -c '$CONN_STR' \"BACKUP DATABASE INCREMENTAL SINCE FULL TO '$INC_BKP_FILE'\""
if [ $? -ne 0 ]; then
logger "Error: Failed post-quiesce incremental backup."
fi
# Remove temporary files created during quiesce
rm -f "$FULL_BKP_FILE"*
logger "SybaseIQ Full VM BYOS: Cleanup complete."
Ersetzen Sie Folgendes:
OS_USER: der Betriebssystemnutzer, der SAP IQ ausführt (z. B.sybiq).DB_NAME: der Name der SAP IQ-Datenbank.DB_USER: Der Datenbanknutzer mit DBA-Berechtigungen.DB_PASSWORD: das Passwort des Datenbanknutzers (oder dynamisch mit Secret Manager abrufen).ENGINE_NAME: der Name der SAP IQ-Datenbank-Engine.
SAP MaxDB
Skript vor dem Snapshot (/etc/google/snapshots/pre.sh)
#!/bin/bash
# Location: /etc/google/snapshots/pre.sh
# 1. Configuration
DBSID="DBSID"
OSUSER="OS_USER"
MAXDB_KEY="-user DBM_USER,DBM_PASSWORD"
AUTOLOG_TMPLT="LOG_BACKUP"
# 2. Discovery
# Dynamically discover all local writeable mount points for full VM consistency
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "MaxDB Full VM BYOS: Starting pre-snapshot script for $DBSID."
# 3. QUIESCE DATABASE
# Optional: Trigger a log backup first to ensure point-in-time recovery readiness
logger "MaxDB Full VM BYOS: Triggering log backup..."
su -m $OSUSER -c "dbmcli -d $DBSID $MAXDB_KEY -uUTL -c backup_start $AUTOLOG_TMPLT LOG"
# Suspend logwriter to quiesce the database
logger "MaxDB Full VM BYOS: Suspending logwriter..."
su -m $OSUSER -c "dbmcli -d $DBSID $MAXDB_KEY -uUTL -c util_execute suspend logwriter"
if [ $? -ne 0 ]; then
logger "Error: Failed to suspend MaxDB logwriter."
exit 1
fi
# 4. FREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
if ! sudo fsfreeze -f "$mnt"; then
logger "Error: Failed to freeze $mnt."
# Attempt emergency thaw
for thaw_mnt in $MOUNT_POINTS; do sudo fsfreeze -u "$thaw_mnt" 2>/dev/null; done
# Resume the logwriter as the backup is no longer consistent
su -m $OSUSER -c "dbmcli -d $DBSID $MAXDB_KEY -uUTL -c util_execute resume logwriter"
exit 1
fi
logger "Filesystem $mnt is frozen."
done
Post-Snapshot-Skript (/etc/google/snapshots/post.sh)
#!/bin/bash
# Location: /etc/google/snapshots/post.sh
# 1. Configuration
DBSID="DBSID"
OSUSER="OS_USER"
MAXDB_KEY="-user DBM_USER,DBM_PASSWORD"
# 2. Discovery
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "MaxDB Full VM BYOS: Starting post-snapshot script for $DBSID."
# 3. UNFREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
sudo fsfreeze -u "$mnt"
logger "Filesystem $mnt is unfrozen."
done
# 4. RESUME DATABASE
logger "MaxDB Full VM BYOS: Resuming logwriter..."
su -m $OSUSER -c "dbmcli -d $DBSID $MAXDB_KEY -uUTL -c util_execute resume logwriter"
if [ $? -ne 0 ]; then
logger "Error: Failed to resume MaxDB logwriter."
else
logger "MaxDB Full VM BYOS: Logwriter resumed successfully."
fi
logger "MaxDB Full VM BYOS: Cleanup complete."
Ersetzen Sie Folgendes:
DBSID: die SAP MaxDB-System-ID (SID) in Großbuchstaben.OS_USER: der Betriebssystemnutzer, der MaxDB ausführt (z. B.sdba).DBM_USER: der Database Manager-Nutzer (DBM).DBM_PASSWORD: das DBM-Nutzerpasswort (oder einen gespeicherten DBM-Schlüssel verwenden:-k KEY_NAME).
PostgreSQL
Skript vor dem Snapshot (/etc/google/snapshots/pre.sh)
#!/bin/bash
# 1. Configuration
OSUSER="OS_USER"
PG_HOME="PG_HOME"
DBUSER="DB_USER"
PORT=PORT_NUMBER
DBNAME="DB_NAME"
FIFO="/tmp/pg_backup_fifo_$PORT"
PID_FILE="/tmp/pg_backup_pid_$PORT"
ACT_JOBNAME="SNAPSHOT_$(date +%Y%m%d%H%M%S)"
# 2. Discovery
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
export PATH=$PG_HOME/bin:$PATH
logger "PostgreSQL Full VM BYOS: Starting pre-snapshot script."
# 3. QUIESCE DATABASE (Session-Bound)
rm -f "$FIFO"
mkfifo "$FIFO"
chown "$OSUSER" "$FIFO"
su "$OSUSER" -c "psql -p $PORT -U $DBUSER -d $DBNAME -f $FIFO" > /tmp/pg_backup_output.log 2>&1 &
echo $! > "$PID_FILE"
psql_version=$(su "$OSUSER" -c "psql --version" | awk '{print $3}' | cut -d'.' -f1)
if [ "$psql_version" -ge 15 ]; then
CMD="SELECT pg_backup_start('$ACT_JOBNAME');"
else
CMD="SELECT pg_start_backup('$ACT_JOBNAME');"
fi
echo "$CMD" > "$FIFO"
sleep 2
# 4. FREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
if ! sudo fsfreeze -f "$mnt"; then
logger "Error: Failed to freeze $mnt. Cleaning up..."
for thaw_mnt in $MOUNT_POINTS; do sudo fsfreeze -u "$thaw_mnt" 2>/dev/null; done
echo "SELECT pg_backup_stop(); exit;" > "$FIFO"
rm -f "$FIFO" "$PID_FILE"
exit 1
fi
logger "Filesystem $mnt is frozen."
done
Post-Snapshot-Skript (/etc/google/snapshots/post.sh)
#!/bin/bash
PORT=PORT_NUMBER
FIFO="/tmp/pg_backup_fifo_$PORT"
PID_FILE="/tmp/pg_backup_pid_$PORT"
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "PostgreSQL Full VM BYOS: Starting post-snapshot script."
# 1. UNFREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
sudo fsfreeze -u "$mnt"
logger "Filesystem $mnt is unfrozen."
done
# 2. RESUME DATABASE (Close Session)
if [ -p "$FIFO" ]; then
logger "PostgreSQL Full VM BYOS: Closing backup session via FIFO..."
echo "SELECT pg_backup_stop(); SELECT pg_stop_backup(); exit;" > "$FIFO"
if [ -f "$PID_FILE" ]; then
wait "$(cat "$PID_FILE")" 2>/dev/null
fi
rm -f "$FIFO" "$PID_FILE"
logger "PostgreSQL Full VM BYOS: Database session closed."
else
logger "Error: FIFO not found. Session may have terminated unexpectedly."
fi
logger "PostgreSQL Full VM BYOS: Cleanup complete."
Ersetzen Sie Folgendes:
OS_USER: der Betriebssystemnutzer, der PostgreSQL ausführt (z. B.postgres).PG_HOME: der Pfad zum PostgreSQL-Installationsverzeichnis.DB_USER: der PostgreSQL-Datenbanknutzer mit Superuser-Berechtigungen.PORT_NUMBER: die Portnummer, auf der PostgreSQL auf Anfragen wartet (Standard:5432).DB_NAME: Der Name der Datenbank, zu der eine Verbindung hergestellt werden soll.
MySQL
Skript vor dem Snapshot (/etc/google/snapshots/pre.sh)
#!/bin/bash
# 1. Configuration
DBUSER="DB_USER"
DBPASSWORD="DB_PASSWORD"
PORTNO=PORT_NUMBER
SOCKET_FILE="/var/run/mysqld/mysqld.sock"
MYSQL_PATH="/usr/bin/mysql"
FIFO="/tmp/mysql_backup_fifo_$PORTNO"
PID_FILE="/tmp/mysql_backup_pid_$PORTNO"
# 2. Discovery
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "MySQL Full VM BYOS: Starting pre-snapshot script."
# 3. QUIESCE DATABASE (Session-Bound Lock)
rm -f "$FIFO"
mkfifo "$FIFO"
$MYSQL_PATH -u"$DBUSER" -p"$DBPASSWORD" -S"$SOCKET_FILE" -P"$PORTNO" < "$FIFO" > /tmp/mysql_backup_output.log 2>&1 &
echo $! > "$PID_FILE"
logger "MySQL Full VM BYOS: Issuing FLUSH TABLES WITH READ LOCK..."
echo "FLUSH TABLES WITH READ LOCK; SELECT SLEEP(86400);" > "$FIFO"
sleep 2
# 4. FREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
if ! sudo fsfreeze -f "$mnt"; then
logger "Error: Failed to freeze $mnt. Cleaning up..."
for thaw_mnt in $MOUNT_POINTS; do sudo fsfreeze -u "$thaw_mnt" 2>/dev/null; done
kill $(cat "$PID_FILE") 2>/dev/null
rm -f "$FIFO" "$PID_FILE"
exit 1
fi
logger "Filesystem $mnt is frozen."
done
Post-Snapshot-Skript (/etc/google/snapshots/post.sh)
#!/bin/bash
PORTNO=PORT_NUMBER
FIFO="/tmp/mysql_backup_fifo_$PORTNO"
PID_FILE="/tmp/mysql_backup_pid_$PORTNO"
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "MySQL Full VM BYOS: Starting post-snapshot script."
# 1. UNFREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
sudo fsfreeze -u "$mnt"
logger "Filesystem $mnt is unfrozen."
done
# 2. RESUME DATABASE (Unlock)
if [ -f "$PID_FILE" ]; then
logger "MySQL Full VM BYOS: Releasing locks..."
kill $(cat "$PID_FILE") 2>/dev/null
rm -f "$FIFO" "$PID_FILE"
logger "MySQL Full VM BYOS: Locks released and session closed."
else
logger "Error: PID file not found. Lock may have been lost prematurely."
fi
logger "MySQL Full VM BYOS: Cleanup complete."
Ersetzen Sie Folgendes:
DB_USER: der MySQL-Datenbanknutzer mit Administratorberechtigungen.DB_PASSWORD: das Passwort der MySQL-Datenbank (oder dynamisch mit Secret Manager abrufen).PORT_NUMBER: die Portnummer, auf der MySQL auf eingehende Verbindungen wartet (Standard:3306).
MariaDB
Skript vor dem Snapshot (/etc/google/snapshots/pre.sh)
#!/bin/bash
# Location: /etc/google/snapshots/pre.sh
# 1. Configuration
DBUSER="DB_USER"
DBPASSWORD="DB_PASSWORD"
PORTNO=PORT_NUMBER
SOCKET_FILE="/var/run/mysqld/mysqld.sock"
MARIADB_PATH="/usr/bin/mariadb" # or /usr/bin/mysql
SRV_TYPE="Master" # Set to "Slave" for standby nodes
FIFO="/tmp/mariadb_backup_fifo_$PORTNO"
PID_FILE="/tmp/mariadb_backup_pid_$PORTNO"
STARTPOS_FILE="/tmp/STARTPOS_FILE_$PORTNO.txt"
# 2. Discovery
# Dynamically discover all local writeable mount points for full VM consistency
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "MariaDB Full VM BYOS: Starting pre-snapshot script."
# 3. QUIESCE DATABASE (Session-Bound)
# Create a FIFO to hold the session open
rm -f "$FIFO"
mkfifo "$FIFO"
# Start a background mariadb session that reads from the FIFO
# This keeps the session (and locks) active until the process is killed
$MARIADB_PATH -u"$DBUSER" -p"$DBPASSWORD" -S"$SOCKET_FILE" -P"$PORTNO" < "$FIFO" > /tmp/mariadb_backup_output.log 2>&1 &
echo $! > "$PID_FILE"
# Prepare quiesce query (Logic from act_mariadb_pre.sh)
if [ "$SRV_TYPE" != "Slave" ]; then
# Primary node: lock all tables
logger "MariaDB Full VM BYOS: Issuing FLUSH TABLES WITH READ LOCK..."
echo "FLUSH TABLES WITH READ LOCK; SELECT SLEEP(86400);" > "$FIFO"
# Capture master status for PITR/replication info
$MARIADB_PATH -u"$DBUSER" -p"$DBPASSWORD" -S"$SOCKET_FILE" -P"$PORTNO" -e "SHOW MASTER STATUS;" > "$STARTPOS_FILE"
else
# Replica node: stop the slave thread
logger "MariaDB Full VM BYOS: Issuing STOP SLAVE..."
echo "STOP SLAVE; SELECT SLEEP(86400);" > "$FIFO"
# Capture slave status
$MARIADB_PATH -u"$DBUSER" -p"$DBPASSWORD" -S"$SOCKET_FILE" -P"$PORTNO" -e "SHOW SLAVE STATUS \G;" > "$STARTPOS_FILE"
fi
# Wait a brief moment to ensure the command is processed
sleep 2
# 4. FREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
if ! sudo fsfreeze -f "$mnt"; then
logger "Error: Failed to freeze $mnt. Cleaning up..."
# Attempt emergency thaw
for thaw_mnt in $MOUNT_POINTS; do sudo fsfreeze -u "$thaw_mnt" 2>/dev/null; done
# Kill the background session to release locks
kill $(cat "$PID_FILE") 2>/dev/null
rm -f "$FIFO" "$PID_FILE"
exit 1
fi
logger "Filesystem $mnt is frozen."
done
Post-Snapshot-Skript (/etc/google/snapshots/post.sh)
#!/bin/bash
# Location: /etc/google/snapshots/post.sh
# 1. Configuration
PORTNO=PORT_NUMBER
SRV_TYPE="Master"
DBUSER="DB_USER"
DBPASSWORD="DB_PASSWORD"
SOCKET_FILE="/var/run/mysqld/mysqld.sock"
MARIADB_PATH="/usr/bin/mariadb"
FIFO="/tmp/mariadb_backup_fifo_$PORTNO"
PID_FILE="/tmp/mariadb_backup_pid_$PORTNO"
# 2. Discovery
MOUNT_POINTS=$(findmnt -n -l -o TARGET -t xfs,ext4,ext3,ext2,btrfs)
logger "MariaDB Full VM BYOS: Starting post-snapshot script."
# 3. UNFREEZE FILESYSTEMS (Optional)
for mnt in $MOUNT_POINTS; do
sudo fsfreeze -u "$mnt"
logger "Filesystem $mnt is unfrozen."
done
# 4. RESUME DATABASE
if [ -f "$PID_FILE" ]; then
logger "MariaDB Full VM BYOS: Resuming database operations..."
# Kill the background sleep process to automatically release session-bound locks
kill $(cat "$PID_FILE") 2>/dev/null
# For slave nodes, explicitly ensure replication is started
if [ "$SRV_TYPE" = "Slave" ]; then
$MARIADB_PATH -u"$DBUSER" -p"$DBPASSWORD" -S"$SOCKET_FILE" -P"$PORTNO" -e "START SLAVE;"
fi
rm -f "$FIFO" "$PID_FILE"
logger "MariaDB Full VM BYOS: Cleanup complete."
else
logger "Error: PID file not found. Database state might be inconsistent."
fi
Ersetzen Sie Folgendes:
DB_USER: der MariaDB-Datenbanknutzer mit Administratorberechtigungen.DB_PASSWORD: das Passwort der MariaDB-Datenbank (oder dynamisch mit Secret Manager abrufen).PORT_NUMBER: die Portnummer, auf der MariaDB auf Anfragen wartet (Standard:3306).
Guest-Flush-Skripts bereitstellen
Nachdem Sie die Skripts pre.sh und post.sh für Ihre Datenbank vorbereitet haben, stellen Sie sie auf der Linux-VM-Instanz bereit:
Stellen Sie über SSH eine Verbindung zur Linux-VM-Instanz her, auf der Ihre selbstverwaltete Datenbank ausgeführt wird.
Erstellen Sie das Verzeichnis
/etc/google/snapshots/, falls es noch nicht vorhanden ist:sudo mkdir -p /etc/google/snapshotsSpeichern Sie Ihre benutzerdefinierten
pre.sh- undpost.sh-Skripts im Verzeichnis/etc/google/snapshots/auf der VM-Instanz.Prüfen Sie, ob die Skripts Ausführungsberechtigungen haben:
sudo chmod 755 /etc/google/snapshots/pre.sh /etc/google/snapshots/post.sh
Gast-Agent für Snapshots aktivieren
Damit Backup und DR Pre- und Post-Snapshot-Skripts ausführen können, müssen Sie die Snapshot-Integration in der Compute Engine-Gastumgebung auf Ihrer Linux-VM-Instanz aktivieren:
Stellen Sie über SSH eine Verbindung zur Linux-VM-Instanz her, auf der Ihre selbstverwaltete Datenbank ausgeführt wird (falls noch nicht verbunden).
Öffnen Sie die Konfigurationsdatei für die Gastumgebung in einem Texteditor:
sudo nano /etc/default/instance_configs.cfgFügen Sie im Abschnitt
[Snapshots]die folgenden Einstellungen hinzu oder ändern Sie sie, um Snapshots zu aktivieren:[Snapshots] enabled = true timeout_in_seconds = 120Starten Sie den Gast-Agent auf der VM-Instanz neu, um die Änderungen zu übernehmen:
sudo systemctl restart google-guest-agent
Sicherungsplan konfigurieren
Nachdem die VM-Instanz mit den Guest-Flush-Skripts konfiguriert und der Gast-Agent für Snapshots aktiviert wurde, konfigurieren Sie einen Sicherungsplan in der Google Cloud Console:
Rufen Sie in der Google Cloud Console die Seite Backup und DR auf.
Wählen Sie im Navigationsmenü Sicherungspläne aus.
Klicken Sie auf Sicherungsplan erstellen oder wählen Sie einen vorhandenen Sicherungsplan aus und klicken Sie auf Bearbeiten.
Suchen Sie unter den Konfigurationsschritten für die Instanzsicherung nach den Konsistenzoptionen.
Wählen Sie die Option Anwendungskonsistenz aktivieren aus.
Speichern Sie den Sicherungsplan und wenden Sie ihn auf Ihre VM-Instanz an. Der Sicherungsplan löst den Gast-Agenten aus, um das
pre.sh-Script auszuführen, den Snapshot zu erstellen und daspost.sh-Script auszuführen.
Persistent Disk-Sicherung für die Wiederherstellung der Datenbank zu einem bestimmten Zeitpunkt konfigurieren
Für selbstverwaltete Datenbanken wie Db2 und SAP HANA können Sie eigenständige Persistent Disk-Sicherungen konfigurieren, um Datenbankarchivlogs zu erfassen und eine Wiederherstellung zu einem bestimmten Zeitpunkt zu ermöglichen. Wenn Sie keine Wiederherstellung zu einem bestimmten Zeitpunkt benötigen, können Sie mit Guest-Flush-Skripts deaktivieren fortfahren.
Best Practices für Logsicherungen zur Wiederherstellung zu einem bestimmten Zeitpunkt
Häufigkeit: Konfigurieren Sie den Zeitplan für den Sicherungsplan für dieses dedizierte Loglaufwerk so, dass er der Granularität des Logs für die Wiederherstellung zu einem bestimmten Zeitpunkt entspricht, z. B. alle 15 Minuten oder stündlich.
Kostenoptimierung: Das Speichern häufiger Snapshots kann die Speicherkosten erhöhen. Um den Aufwand zu minimieren, konfigurieren Sie die Mindestaufbewahrungsdauer und die entsprechende Unveränderlichkeitsdauer des Vaults auf die minimal zulässige Zeit, die noch Ihrem Wiederherstellungsfenster zu einem bestimmten Zeitpunkt entspricht.
Selbstverwaltete Datenbank zu einem bestimmten Zeitpunkt wiederherstellen
Wenn Sie regelmäßige VM-Sicherungen zusammen mit dedizierten Persistent Disk-Logsicherungen konfiguriert haben, gehen Sie so vor, um Ihre Datenbank zu einem bestimmten Zeitpunkt wiederherzustellen. Wenn Sie keine dedizierten Log-Sicherungen konfiguriert haben oder keine Wiederherstellung zu einem bestimmten Zeitpunkt benötigen, lesen Sie den Abschnitt Compute Engine-Instanz aus einem Backup Vault wiederherstellen, um Ihre VM direkt wiederherzustellen, und fahren Sie mit Aufgaben nach der Wiederherstellung ausführen fort.
Wiederherstellungsworkflow
Basis-VM wiederherstellen: Wählen Sie die Instanzsicherung (Maschinen-Image) aus dem Backup Vault aus, die vor der Zielwiederherstellungszeit liegt. Stellen Sie sie gemäß den Standardverfahren für die Wiederherstellung von Compute Engine wieder her. Eine Anleitung finden Sie unter Compute Engine-Instanz aus einem Backup Vault wiederherstellen.
Wenn Sie keine dedizierten Log-Sicherungen konfiguriert haben oder keine Wiederherstellung zu einem bestimmten Zeitpunkt benötigen, fahren Sie mit Schritt 4 fort.
Protokolllaufwerke anhängen: Identifizieren und stellen Sie die relevanten Protokolllaufwerk-Snapshots wieder her, die bis zum Zielwiederherstellungszeitpunkt erfasst wurden. Hängen Sie diese neu erstellten Laufwerke an die wiederhergestellte Instanz an.
Datenbank aktualisieren: Stellen Sie über SSH eine Verbindung zur wiederhergestellten Instanz her und führen Sie den datenbankspezifischen Aktualisierungsbefehl aus, z. B.
ROLLFORWARD DATABASEin Db2. Verwenden Sie dazu die Logs auf den neu angehängten nichtflüchtigen Speichern.Aufgaben nach der Wiederherstellung ausführen: Führen Sie alle datenbankspezifischen Schritte aus, die erforderlich sind, um die Anwendung online zu schalten.
Guest-Flush-Skripts deaktivieren
So entfernen Sie die benutzerdefinierten Guest-Flush-Skripts und deaktivieren die Anwendungskonsistenz:
Zuweisung des Sicherungsplans zu Ihrer Instanz aufheben: Rufen Sie in der Google Cloud Console die Seite Backup und DR auf, suchen Sie unter Geschützte Ressourcen nach Ihrer VM-Instanz und heben Sie die Zuweisung des Sicherungsplans auf oder löschen Sie die Verknüpfung.
Guest-Flush-Skripts entfernen: Stellen Sie über SSH eine Verbindung zu Ihrer Linux-VM-Instanz her und entfernen Sie die benutzerdefinierten Guest-Flush-Skripts:
sudo rm -f /etc/google/snapshots/pre.sh /etc/google/snapshots/post.shSnapshot-Integration im Gast-Agent deaktivieren: Öffnen Sie
/etc/default/instance_configs.cfgauf Ihrer VM-Instanz, legen Sieenabled = falseunter[Snapshots]fest und starten Sie den Gast-Agent neu:sudo systemctl restart google-guest-agent
Nächste Schritte
- Sicherungspläne erstellen und verwalten
- Sicherungs- und Wiederherstellungsjobs überwachen
- Compute Engine-Instanzen sichern
- Compute Engine-Instanzen wiederherstellen
- Nichtflüchtige Speicher sichern
- Nichtflüchtige Speicher wiederherstellen