RunBefore y RunAfter mediante la herramienta Azure Application Consistent Snapshot
En este artículo se ofrece una guía para usar la funcionalidad --runbefore
y --runafter
de la herramienta Azure Application Consistent Snapshot que puede usar con Azure NetApp Files.
Introducción
AzAcSnap puede ejecutar comandos externos antes o después de su ejecución principal mediante las opciones --runbefore
o --runafter
respectivamente.
--runbefore
ejecuta un comando de shell antes de la ejecución principal de azacsnap y proporciona algunos de los parámetros de la línea de comandos de azacsnap al entorno de shell.
De forma predeterminada, azacsnap
espera hasta 30 segundos para que el comando de shell externo se complete antes de matar el proceso y volver a la ejecución normal de azacsnap.
Para invalidar este periodo de espera, debe agregar el número de segundos que se espere después de un carácter %
(por ejemplo, --runbefore "mycommand.sh%60"
esperará un máximo de 60 segundos para que mycommand.sh
completarse).
--runafter
ejecuta un comando de shell después de la ejecución principal de azacsnap y proporciona algunos de los parámetros de la línea de comandos de azacsnap al entorno de shell.
De forma predeterminada, azacsnap
espera hasta 30 segundos para que el comando de shell externo se complete antes de matar el proceso y volver a la ejecución normal de azacsnap.
Este retraso se puede invalidar agregando un número para esperar en segundos después de un %
carácter (por ejemplo, --runafter "mycommand.sh%60"
esperará hasta 60 segundos para mycommand.sh
completarse).
azacsnap
genera la siguiente lista de variables de entorno y las pasa al shell bifurcada para ejecutar los comandos proporcionados como parámetros en --runbefore
y --runafter
:
-
$azCommand
= la opción del comando pasada a -c (por ejemplo, copia de seguridad, prueba, etc.) -
$azConfigFileName
= nombre de archivo de la configuración. -
$azPrefix
= --valor del prefijo. -
$azRetention
= --valor de retención. -
$azSid
= --valor de dbsid. -
$azSnapshotName
= nombre de instantánea generado por azacsnap.
Nota:
Solo hay un valor para $azSnapshotName
en la opción --runafter
.
Ejemplo de uso para realizar copias de seguridad en Azure Blob Storage
Importante
Solo se proporcionan ejemplos con fines informativos. No garantizamos la precisión, integridad ni utilidad de ninguna información proporcionada. El uso de estos ejemplos está en su propio riesgo. No aceptamos ninguna responsabilidad por pérdida o daño que pueda surgir del uso de estos ejemplos. No ofrecemos compatibilidad con los ejemplos proporcionados en esta documentación.
Un ejemplo de uso de esta nueva característica es cargar una instantánea en Azure Blob con fines de archivado mediante la azcopy
herramienta (Copiar o mover datos a Azure Storage mediante AzCopy).
Script de shell para cargar en Azure Blob Storage
Este script de shell de ejemplo tiene una estrofa especial al final para evitar que AzAcSnap mate el comando externo debido al tiempo de espera descrito anteriormente. Esta estrofa permite ejecutar un comando de larga duración, como cargar archivos grandes con azcopy, sin que se detenga prematuramente.
Las instantáneas deben montarse en el sistema que hace la copia, con privilegios de solo lectura como mínimo. La ubicación base del punto de montaje para las instantáneas debe proporcionarse a la variable sourceDir
en el script.
La instantánea se carga como un único archivo mediante el tar
comando para crear un tarball de gzipped. Al colocar los archivos en un solo tarball, se mantienen los permisos y la propiedad del archivo; de lo contrario, la carga de los archivos pierde individualmente estos atributos.
cat snapshot-to-blob.sh
#!/bin/bash
# Utility to upload-to/list Azure Blob store.
# If run as snapshot-to-blob.sh will upload a gzipped tarball of the snapshot.
# If run as list-blobs.sh will list uploaded blobs.
# e.g. `ln -s snapshot-to-blob.sh list-blobs.sh`
# _START_ Change these
SAS_KEY_FILE="${HOME}/bin/blob-credentials.saskey"
# the snapshots need to be mounted locally for copying, put source directory here
SOURCE_DIR="/mnt/saphana1/hana_data_PR1/.snapshot"
# _END_ Change these
# _START_ AzCopy Settings
#Overrides where the job plan files (used for progress tracking and resuming) are stored, to avoid filling up a disk.
export AZCOPY_JOB_PLAN_LOCATION="${HOME}/.azcopy/plans/"
#Overrides where the log files are stored, to avoid filling up a disk.
export AZCOPY_LOG_LOCATION="${HOME}/.azcopy/logs/"
#If set, to anything, on-screen output will include counts of chunks by state
export AZCOPY_SHOW_PERF_STATES=true
# _END_ AzCopy Settings
# do not change any of the following
# Make sure we got some command line args
if [ "$(basename "$0")" = "snapshot-to-blob.sh" ] && ([ "$1" = "" ] || [ "$2" = "" ]); then
echo "Usage: $0 <SNAPSHOT_NAME> <PREFIX>"
exit 1
fi
# Make sure we can read the SAS key credential file.
if [ -r "${SAS_KEY_FILE}" ]; then
source "${SAS_KEY_FILE}"
else
echo "Credential file '${SAS_KEY_FILE}' not found, exiting!"
fi
# Assign the rest of the Global variables.
SNAPSHOT_NAME=$1
PREFIX=$2
BLOB_STORE="$(echo "${PORTAL_GENERATED_SAS}" | cut -f1 -d'?')"
BLOB_SAS_KEY="$(echo "${PORTAL_GENERATED_SAS}" | cut -f2 -d'?')"
ARCHIVE_LOG="logs/$(basename "$0").log"
# Archive naming (daily.1, daily.2, etc...)
DAY_OF_WEEK=$(date "+%u")
MONTH_OF_YEAR=$(date "+%m")
ARCHIVE_BLOB_TGZ="${PREFIX}.${DAY_OF_WEEK}.tgz"
#######################################
# Write to the log.
# Globals:
# None
# Arguments:
# LOG_MSG
#######################################
write_log(){
LOG_MSG=$1
date=$(date "+[%d/%h/%Y:%H:%M:%S %z]")
echo "$date ${LOG_MSG}" >> "${ARCHIVE_LOG}"
}
#######################################
# Run and Log the command.
# Globals:
# None
# Arguments:
# CMD_TO_RUN
#######################################
run_cmd(){
CMD_TO_RUN="${1}"
write_log "[RUNCMD] ${CMD_TO_RUN}"
bash -c "${CMD_TO_RUN}"
}
#######################################
# Check snapshot exists and then background the upload to Blob store.
# Globals:
# SOURCE_DIR
# SNAPSHOT_NAME
# ARCHIVE_LOG
# Arguments:
# None
#######################################
snapshot_to_blob(){
# Check SOURCE_DIR and SNAPSHOT_NAME exist
if [ ! -d "${SOURCE_DIR}/${SNAPSHOT_NAME}" ]; then
echo "${SOURCE_DIR}/${SNAPSHOT_NAME} not found, exiting!" | tee -a "${ARCHIVE_LOG}"
exit 1
fi
# background ourselves so AzAcSnap exits cleanly
echo "Backgrounding '$0 $@' to prevent blocking azacsnap"
echo "write_logging to ${ARCHIVE_LOG}"
{
trap '' HUP
# the script
upload_to_blob
list_blob >> "${ARCHIVE_LOG}"
} < /dev/null > /dev/null 2>&1 &
}
#######################################
# Upload to Blob store.
# Globals:
# SOURCE_DIR
# SNAPSHOT_NAME
# ARCHIVE_BLOB_TGZ
# BLOB_STORE
# BLOB_SAS_KEY
# ARCHIVE_LOG
# Arguments:
# None
#######################################
upload_to_blob(){
# Copy snapshot to blob store
echo "Starting upload of ${SNAPSHOT_NAME} to ${BLOB_STORE}/${ARCHIVE_BLOB_TGZ}" >> "${ARCHIVE_LOG}"
run_cmd "azcopy env ; cd ${SOURCE_DIR}/${SNAPSHOT_NAME} && tar zcvf - * | azcopy cp \"${BLOB_STORE}/${ARCHIVE_BLOB_TGZ}?${BLOB_SAS_KEY}\" --from-to PipeBlob && cd -"
echo "Completed upload of ${SNAPSHOT_NAME} ${BLOB_STORE}/${ARCHIVE_BLOB_TGZ}" >> "${ARCHIVE_LOG}"
# Complete
echo "Finished ($0 ${SNAPSHOT_NAME} ${PREFIX}) @ $(date "+%d-%h-%Y %H:%M")" >> "${ARCHIVE_LOG}"
echo "--------------------------------------------------------------------------------" >> "${ARCHIVE_LOG}"
# col 12345678901234567890123456789012345678901234567890123456789012345678901234567890
}
#######################################
# List contents of Blob store.
# Globals:
# BLOB_STORE
# BLOB_SAS_KEY
# Arguments:
# None
#######################################
list_blob(){
LOG_MSG="Current list of files stored in ${BLOB_STORE}"
write_log "${LOG_MSG}"
echo "${LOG_MSG}"
run_cmd "azcopy list \"${BLOB_STORE}?${BLOB_SAS_KEY}\" --properties LastModifiedTime "
}
# Log when script started.
write_log "Started ($0 ${SNAPSHOT_NAME} ${PREFIX}) @ $(date "+%d-%h-%Y %H:%M")"
# Check what this was called as ($0) and run accordingly.
case "$(basename "$0")" in
"snapshot-to-blob.sh" )
snapshot_to_blob
;;
"list-blobs.sh" )
list_blob
;;
*)
echo "Command '$0' not recognised!"
;;
esac
saskeyFile contiene la siguiente clave de SAS de ejemplo (el contenido ha cambiado por motivos de seguridad):
cat blob-credentials.saskey
# we need a generated SAS key, get this from the portal with read,add,create,write,list permissions
PORTAL_GENERATED_SAS="https://<targetstorageaccount>.blob.core.windows.net/<blob-store>?sp=racwl&st=2021-06-10T21:10:38Z&se=2021-06-11T05:10:38Z&spr=https&sv=2020-02-10&sr=c&sig=<key-material>"
Programación del script de shell
La siguiente entrada crontab es una sola línea y se ejecuta azacsnap
a las 12:05 a. m. Fíjese en la llamada a snapshot-to-blob.sh
que pasa el nombre y el prefijo de la instantánea:
5 0 * * * ( . ~/.bash_profile ; cd /home/azacsnap/bin ; ./azacsnap -c backup --volume data --prefix daily --retention 1 --configfile HANA.json --trim --ssl openssl --runafter 'env ; ./snapshot-to-blob.sh $azSnapshotName $azPrefix')
Restauración desde Azure Blob Storage
La restauración a partir de uno de estos archivos almacenados en Azure Blob Storage en un nivel alto es el siguiente:
- Vuelva a copiar el archivo de instantáneas en la máquina local. La ubicación de destino debe ser independiente de los archivos de base de datos y con capacidad suficiente para permitir el archivo de archivo y la extracción, por ejemplo
/var/tmp
.- Si crearon el archivo mediante el
--runafter
script de shell de ejemplo, posiblemente pueden extraer el tarball descomprimido directamente desde Azure Blob Storage en la ubicación de destino mediante una canalización de AzCopy para extraer, por ejemplo:cd ${TARGET_DIRECTORY}
azcopy cp "${BLOB_STORE}/${ARCHIVE_BLOB_TGZ}?${BLOB_SAS_KEY}" --from-to BlobPipe | tar zxvf -
- Si crearon el archivo mediante el
- Extraiga el contenido del archivo de instantáneas.
- Revise el contenido de la ubicación de destino después de extraer, comparando los permisos de archivo y la propiedad con los archivos de base de datos originales.
- Por ejemplo, haga .
ls -lR
- Por ejemplo, haga .
- Apague los procesos del servidor de bases de datos.
- Copie los archivos de la ubicación de destino restaurada a en el paso 1 de vuelta a su ubicación original.
- Continúe con el proceso de recuperación normal de la base de datos.