Questo documento mostra come configurare i flussi di lavoro di backup pianificati e coerenti con le applicazioni e di recupero point-in-time (PITR) per i database autogestiti in esecuzione su istanze di macchine virtuali (VM) Linux di Compute Engine.
Quando esegui il backup dei workload di database stateful, come IBM Db2, SAP HANA, MySQL o PostgreSQL, gli snapshot standard coerenti con gli arresti anomali creati da Backup e RE possono acquisire il database mentre le transazioni sono ancora in corso. Queste transazioni incomplete possono danneggiare i dati, lasciare le tabelle in stati incoerenti e richiedere lunghe routine di riparazione del database in caso di ripristino da arresto anomalo. I backup coerenti con le applicazioni risolvono questi problemi integrandosi con l'agente guest della VM per mettere in stato di quiescenza il database e, facoltativamente, bloccare il file system prima di creare uno snapshot.
Prima di iniziare
Completa le seguenti attività prima di configurare i backup coerenti con le applicazioni.
Ruoli obbligatori
Per ottenere le autorizzazioni necessarie per configurare i backup coerenti con le applicazioni, chiedi all'amministratore di concederti i seguenti ruoli IAM nel progetto:
-
Per configurare e gestire i piani di backup:
Backup e DR Backup User (
roles/backupdr.backupUser) -
Per gestire le istanze Compute Engine:
Compute Instance Admin (v1) (
roles/compute.instanceAdmin.v1) -
Per accedere ai secret di Secret Manager dagli script:
Secret Manager Secret Accessor (
roles/secretmanager.secretAccessor)
Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.
Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.
Prerequisiti
Nella Google Cloud console, nella pagina di selezione del progetto, seleziona o crea un Google Cloud progetto.
Verifica che la fatturazione sia attivata per il tuo progetto.
Abilita le API Backup e RE e Secret Manager.
Assicurati che i dati del database e i file di log siano archiviati su dischi permanenti standard standard. I volumi Google Cloud Hyperdisk non supportano le operazioni di svuotamento dell'ambiente guest.
Se prevedi di configurare il recupero point-in-time, configura il database in modo da archiviare i log delle transazioni e di ripristino su un Persistent Disk dedicato e separato, ad esempio montato in
/db2/ACT/log_archive.
Utilizza il framework di svuotamento dell'ambiente guest bring-your-own-script (BYOS)
Backup e RE utilizza il framework di svuotamento dell'ambiente guest Bring-Your-Own-Script (BYOS) per mettere in stato di quiescenza il database prima di acquisire uno snapshot. L'ambiente guest si basa su due script che si trovano nella directory /etc/google/snapshots/ dell'istanza VM Linux:
- Script pre-snapshot (
/etc/google/snapshots/pre.sh): viene eseguito prima dell'acquisizione dello snapshot. Questo script deve mettere in stato di quiescenza le operazioni del database e può, facoltativamente, bloccare il file system. - Script post-snapshot (
/etc/google/snapshots/post.sh): viene eseguito dopo l'acquisizione dello snapshot. Questo script deve, facoltativamente, sbloccare il file system e riprendere le operazioni del database.
Per saperne di più sui modelli di script specifici del database, consulta Esamina gli script di esempio per tipo di database.
(Facoltativo) Blocca e sblocca i file system
Il blocco del file system utilizzando l'utilità Linux standard fsfreeze è facoltativo e non obbligatorio. La messa in stato di quiescenza del database garantisce la coerenza delle transazioni a livello di applicazione. Tuttavia, se hai bisogno di una coerenza aggiuntiva a livello di file system, puoi includere facoltativamente i seguenti comandi di blocco e sblocco del file system negli script.
Assicurati che gli script pre.sh e post.sh sulla VM siano configurati per gestire il blocco facoltativo del file system per i volumi di log senza sospendere le operazioni del database.
Aggiungi istruzioni di blocco del file system a pre.sh
Se scegli di bloccare i file system, aggiungi la seguente logica di rilevamento e blocco alla fine dello script pre.sh dopo aver messo in stato di quiescenza il database:
# 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
Aggiungi istruzioni di sblocco del file system a post.sh
Se blocchi i file system in pre.sh, aggiungi la seguente logica di sblocco all'inizio dello script post.sh prima di riprendere il database:
# 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
Recupera le credenziali in modo dinamico con Secret Manager
Evita di codificare le credenziali o le password statiche del database all'interno degli script della shell. Utilizza invece Secret Manager per recuperare le credenziali in modo dinamico in fase di runtime. Sostituisci le variabili delle password statiche negli script con la seguente logica:
# 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
Sostituisci SECRET_NAME con il nome del secret in Secret Manager.
Esamina gli script di esempio per tipo di database
I seguenti esempi forniscono implementazioni pre.sh e post.sh per i motori di database supportati in esecuzione su istanze Linux.
IBM Db2
Script pre-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
Script post-snapshot (/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
Script pre-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
Script post-snapshot (/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
Script pre-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
Script post-snapshot (/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
Sostituisci quanto segue:
DBSID: l'identificatore di sistema (SID) SAP HANA in maiuscolo.DBADM: l'utente del sistema operativo amministratore SAP HANA (ad esempio<sid>adm).HDB_KEY: la chiave dell'archivio utenti SAP HANA configurata per l'accesso al database.
SAP ASE
Script pre-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
Script post-snapshot (/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."
Sostituisci quanto segue:
OS_USER: l'utente del sistema operativo che esegue SAP ASE (ad esempiosybase).SYB_SERVER_NAME: il nome del server SAP ASE.SYB_USER: l'utente del database con le autorizzazioni per mettere in stato di quiescenza i database.SYB_PASSWORD: la password dell'utente del database (o recuperala in modo dinamico con Secret Manager).DATABASE_LIST: un elenco separato da virgole dei database da mettere in stato di quiescenza.
SAP IQ
Script pre-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
Script post-snapshot (/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."
Sostituisci quanto segue:
OS_USER: l'utente del sistema operativo che esegue SAP IQ (ad esempiosybiq).DB_NAME: il nome del database SAP IQ.DB_USER: l'utente del database con privilegi DBA.DB_PASSWORD: la password dell'utente del database (o recuperala in modo dinamico con Secret Manager).ENGINE_NAME: il nome del motore del database SAP IQ.
SAP MaxDB
Script pre-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
Script post-snapshot (/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."
Sostituisci quanto segue:
DBSID: l'identificatore di sistema (SID) SAP MaxDB in maiuscolo.OS_USER: l'utente del sistema operativo che esegue MaxDB (ad esempiosdba).DBM_USER: l'utente di Database Manager (DBM).DBM_PASSWORD: la password dell'utente DBM (o utilizza una chiave DBM archiviata:-k KEY_NAME).
PostgreSQL
Script pre-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
Script post-snapshot (/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."
Sostituisci quanto segue:
OS_USER: l'utente del sistema operativo che esegue PostgreSQL (ad esempiopostgres).PG_HOME: il percorso della directory di installazione di PostgreSQL.DB_USER: l'utente del database PostgreSQL con privilegi di superutente.PORT_NUMBER: il numero di porta su cui è in ascolto PostgreSQL (impostazione predefinita:5432).DB_NAME: il nome del database a cui connettersi.
MySQL
Script pre-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
Script post-snapshot (/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."
Sostituisci quanto segue:
DB_USER: l'utente del database MySQL con privilegi amministrativi.DB_PASSWORD: la password del database MySQL (o recuperala in modo dinamico con Secret Manager).PORT_NUMBER: il numero di porta su cui è in ascolto MySQL (impostazione predefinita:3306).
MariaDB
Script pre-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
Script post-snapshot (/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
Sostituisci quanto segue:
DB_USER: l'utente del database MariaDB con privilegi amministrativi.DB_PASSWORD: la password del database MariaDB (o recuperala in modo dinamico con Secret Manager).PORT_NUMBER: il numero di porta su cui è in ascolto MariaDB (impostazione predefinita:3306).
Esegui il deployment degli script di svuotamento dell'ambiente guest
Dopo aver preparato gli script pre.sh e post.sh per il database, eseguine il deployment nell'istanza VM Linux:
Connettiti all'istanza VM Linux che esegue il database autogestito utilizzando SSH.
Crea la directory
/etc/google/snapshots/se non esiste già:sudo mkdir -p /etc/google/snapshotsSalva gli script
pre.shepost.shpersonalizzati nella directory/etc/google/snapshots/dell'istanza VM.Assicurati che gli script abbiano le autorizzazioni di esecuzione:
sudo chmod 755 /etc/google/snapshots/pre.sh /etc/google/snapshots/post.sh
Abilita l'agente guest per gli snapshot
Per consentire a Backup e RE di eseguire gli script pre-snapshot e post-snapshot, abilita l'integrazione degli snapshot nell'ambiente guest di Compute Engine sull'istanza VM Linux:
Connettiti all'istanza VM Linux che esegue il database autogestito utilizzando SSH (se non è già connessa).
Apri il file di configurazione dell'ambiente guest in un editor di testo:
sudo nano /etc/default/instance_configs.cfgAggiungi o modifica le seguenti impostazioni nella sezione
[Snapshots]per abilitare gli snapshot:[Snapshots] enabled = true timeout_in_seconds = 120Riavvia l'agente guest sull'istanza VM per applicare le modifiche:
sudo systemctl restart google-guest-agent
Configura il piano di backup
Ora che l'istanza VM è configurata con gli script di svuotamento dell'ambiente guest e l'agente guest è abilitato per gli snapshot, configura un piano di backup nella Google Cloud console:
Nella Google Cloud console, vai alla pagina Backup e DR.
Dal menu di navigazione, seleziona Piani di backup.
Fai clic su Crea piano di backup o seleziona un piano di backup esistente e fai clic su Modifica.
Nei passaggi di configurazione di Backup dell'istanza, individua le opzioni di coerenza.
Seleziona l'opzione Abilita coerenza dell'applicazione.
Salva e applica il piano di backup all'istanza VM. In base alla pianificazione, il piano di backup attiva l'agente guest per eseguire lo script
pre.sh, acquisire lo snapshot ed eseguire lo scriptpost.sh.
Configura il backup Persistent Disk per il recupero point-in-time del database
Per i database autogestiti come Db2 e SAP HANA, puoi configurare backup standalone dei Persistent Disk per acquisire i log di archivio del database, consentendo il recupero point-in-time. Se non hai bisogno del recupero point-in-time, puoi saltare a Disabilita gli script di svuotamento dell'ambiente guest.
Best practice per i backup dei log di recupero point-in-time
Frequenza: configura la pianificazione del piano di backup per questo disco di log dedicato in modo che sia uguale alla granularità dei log di recupero point-in-time, ad esempio ogni 15 minuti o ogni ora.
Ottimizzazione dei costi: l'archiviazione di snapshot frequenti può aumentare i costi di archiviazione. Per ridurre al minimo il sovraccarico, configura il periodo di conservazione minimo e il periodo di immutabilità del vault corrispondente al tempo minimo consentito che soddisfi comunque la finestra di recupero point-in-time.
Recupera un database autogestito in un momento specifico
Se hai configurato backup regolari delle VM insieme a backup dei log dei Persistent Disk dedicati, segui questa procedura per ripristinare il database in un momento specifico. Se non hai configurato backup dei log dedicati o non hai bisogno del recupero point-in-time, consulta Ripristina un'istanza Compute Engine da un vault di backup per ripristinare direttamente la VM e passa a Esegui attività post-ripristino.
Flusso di lavoro di recupero
Ripristina la VM di base: seleziona il backup dell'istanza (immagine macchina) dal vault di backup che precede l'ora di recupero di destinazione. Ripristinalo seguendo le procedure di ripristino standard di Compute Engine. Per istruzioni, consulta Ripristina un'istanza Compute Engine da un vault di backup.
Se non hai configurato backup dei log dedicati o non hai bisogno del recupero point-in-time, passa al passaggio 4.
Collega i dischi di log: identifica e ripristina gli snapshot dei dischi di log pertinenti acquisiti fino all'ora di recupero di destinazione. Collega questi dischi appena creati all'istanza ripristinata.
Esegui il roll-forward del database: connettiti all'istanza ripristinata utilizzando SSH ed esegui il comando di roll-forward specifico del database, ad esempio
ROLLFORWARD DATABASEin Db2, utilizzando i log che si trovano sui dischi permanenti appena collegati.Esegui attività post-ripristino: esegui tutti i passaggi specifici del database necessari per mettere online l'applicazione.
Disabilita gli script di svuotamento dell'ambiente guest
Per rimuovere gli script di svuotamento dell'ambiente guest personalizzati e disabilitare la coerenza dell'applicazione:
Annulla l'assegnazione del piano di backup all'istanza: nella Google Cloud console, vai alla pagina Backup e DR, individua l' istanza VM in Risorse protette e annulla l'assegnazione o elimina l'associazione del piano di backup.
Rimuovi gli script di svuotamento dell'ambiente guest: connettiti all'istanza VM Linux utilizzando SSH e rimuovi gli script di svuotamento dell'ambiente guest personalizzati:
sudo rm -f /etc/google/snapshots/pre.sh /etc/google/snapshots/post.shDisabilita l'integrazione degli snapshot nell'agente guest: apri
/etc/default/instance_configs.cfgsull'istanza VM, impostaenabled = falsein[Snapshots], e riavvia l'agente guest:sudo systemctl restart google-guest-agent