你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
使用 Azure 应用程序一致性快照工具的 RunBefore 和 RunAfter
本文提供的指南介绍了如何使用可与 Azure NetApp 文件配合使用的 Azure 应用程序一致性快照工具的 --runbefore
和 --runafter
功能。
介绍
AzAcSnap 可以分别使用选项 --runbefore
或 --runafter
在主要执行之前或之后执行外部命令。
--runbefore
在主执行 azacsnap 之前运行 shell 命令,并向 shell 环境提供一些 azacsnap 命令行参数。
默认情况下,在终止进程并返回到 azacsnap 正常执行之前, azacsnap
等待外部 shell 命令完成最多 30 秒。
在 %
字符后添加一个等待秒数可替代此延迟(例如 --runbefore "mycommand.sh%60"
将等待最长 60 秒来让 mycommand.sh
完成)。
--runafter
在主执行 azacsnap 后运行 shell 命令,并向 shell 环境提供一些 azacsnap 命令行参数。
默认情况下,在终止进程并返回到 azacsnap 正常执行之前, azacsnap
等待外部 shell 命令完成最多 30 秒。
可以通过添加数字以秒为单位在字符后 %
等待(例如, --runafter "mycommand.sh%60"
最多等待 60 秒才能 mycommand.sh
完成)来重写此延迟。
azacsnap
生成以下环境变量列表,并将其传递给 shell 分支,以运行作为参数--runbefore
提供的命令,--runafter
-
$azCommand
= 传递给 -c 的命令选项(例如 backup、test 等)。 -
$azConfigFileName
= 配置文件名。 -
$azPrefix
= --prefix 值。 -
$azRetention
= --retention 值。 -
$azSid
= --dbsid 值。 -
$azSnapshotName
= azacsnap 生成的快照名。
注意
--runafter
选项中的 $azSnapshotName
只有一个值。
备份到 Azure Blob 存储的示例用法
重要
仅针对信息性目的提供了示例。 我们不能保证提供的任何信息的准确性、完整性或有用性。 这些示例的使用有你自己的风险。 对于这些示例可能引起的任何损失或损害,我们不接受任何责任。 我们不支持本文档中提供的示例。
此新功能的示例用法是使用azcopy
该工具(使用 AzCopy 将数据复制到Azure 存储),以便将快照上传到 Azure Blob 进行存档。
用于上传到 Azure Blob 存储的 Shell 脚本
此示例 shell 脚本在末尾具有特殊的存根,以防止 AzAcSnap 由于前面所述的超时而终止外部命令。 此 stanza 允许长时间运行的命令(例如使用 azcopy 上传大型文件),而无需过早停止运行。
需将快照装载到执行复制的系统中,并至少具有只读特权。 应将快照装入点的基位置提供给脚本中的 sourceDir
变量。
快照是使用 tar
命令创建 gzipped tarball 作为单个文件上传的。 将文件放入单个 tarball 会保留文件权限和所有权,否则上传文件会单独丢失这些属性。
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 包含以下示例 SAS 密钥(考虑到安全性,更改了内容):
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>"
计划 shell 脚本
以下 crontab 条目是一行,在上午 12:05 运行 azacsnap
。 请注意传递快照名和快照前缀的 snapshot-to-blob.sh
调用:
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')
从 Azure Blob 存储还原
从 Azure Blob 存储中存储的其中一个存档还原到高级别如下:
- 将快照存档复制回本地计算机。 目标位置应与数据库文件分开,并且有足够的容量来允许文件存档和提取,例如
/var/tmp
。- 如果他们使用
--runafter
示例 shell 脚本创建了存档,则可以使用 AzCopy 管道将 gzipped tarball 直接从 Azure Blob 存储提取到目标位置,例如:cd ${TARGET_DIRECTORY}
azcopy cp "${BLOB_STORE}/${ARCHIVE_BLOB_TGZ}?${BLOB_SAS_KEY}" --from-to BlobPipe | tar zxvf -
- 如果他们使用
- 提取快照存档的内容。
- 提取后查看目标位置的内容,将文件权限和所有权与原始数据库文件进行比较。
- 例如,请执行
ls -lR
。
- 例如,请执行
- 关闭数据库服务器进程。
- 将文件从还原到步骤 1 中还原的目标位置复制回其原始位置。
- 继续执行正常的数据库恢复过程。