Azure アプリケーション整合性スナップショット ツールを使用した RunBefore と RunAfter
この記事では、Azure NetApp Files で使用できる Azure アプリケーション整合性スナップショット ツールの --runbefore
と --runafter
機能を実行するためのガイドを提供します。
はじめに
AzAcSnap では、--runbefore
または --runafter
オプションをそれぞれ使用して、メイン実行の前または後に外部コマンドを実行できます。
--runbefore
は、azacsnap のメイン実行の前にシェル コマンドを実行し、azacsnap コマンド ライン パラメーターの一部をシェル環境に提供します。
既定では、 azacsnap
は、外部シェル コマンドが完了するまで最大 30 秒待機してから、プロセスを強制終了し、azacsnap の通常の実行に戻ります。
この遅延をオーバーライドするには、%
文字の後に待機する数値 (秒数) を追加します (たとえば、--runbefore "mycommand.sh%60"
は、mycommand.sh
の完了を最大 60 秒待機します)。
--runafter
は、azacsnap のメイン実行後にシェル コマンドを実行し、azacsnap コマンド ライン パラメーターの一部をシェル環境に提供します。
既定では、 azacsnap
は、外部シェル コマンドが完了するまで最大 30 秒待機してから、プロセスを強制終了し、azacsnap の通常の実行に戻ります。
この遅延をオーバーライドするには、 %
文字の後に秒単位で待機する数値を追加します (たとえば、 --runafter "mycommand.sh%60"
は、 mycommand.sh
が完了するまで最大 60 秒待機します)。
azacsnap
は、環境変数の次のリストを生成し、それらをフォークされたシェルに渡して、 --runbefore
と --runafter
のパラメーターとして指定されたコマンドを実行します。
-
$azCommand
= -c に渡されるコマンド オプション (たとえば、バックアップ、テストなど)。 -
$azConfigFileName
= 構成ファイル名。 -
$azPrefix
= --prefix 値。 -
$azRetention
= --retention 値。 -
$azSid
= --dbsid 値。 -
$azSnapshotName
= azacsnap によって生成されるスナップショット名。
Note
--runafter
オプションには $azSnapshotName
の値しかありません。
Azure Blob Storage へのバックアップの使用例
重要
例は情報提供のみを目的として提供されています。 当社は、提供された情報の正確性、完全性、有用性を保証するものではありません。 これらの例の使用は、ご自身の責任で行ってください。 当社は、これらの例の使用によって生じる可能性のある損失または損害に対する一切の責任を負いません。 このドキュメントで提供されている例はサポートされていません。
この新機能の使用例は、 azcopy
ツール (Copy を使用するか、AzCopy を使用して Azure Storage にデータを移動) を使用して、アーカイブ目的でスナップショットを Azure Blob にアップロードすることです。
Azure Blob Storage にアップロードするシェル スクリプト
このシェル スクリプトの例では、前述のタイムアウトが原因で AzAcSnap が外部コマンドを強制終了しないように、最後に特別なスタンザがあります。 このスタンザを使用すると、azcopy を使用して大きなファイルをアップロードするなど、実行時間の長いコマンドを途中で停止することなく実行できます。
スナップショットは、少なくとも読み取り専用の権限を使用して、コピーを実行するシステムにマウントする必要があります。 スナップショットのマウント ポイントの基本場所は、スクリプト内の sourceDir
変数に提供される必要があります。
スナップショットは、 tar
コマンドを使用して gzipped tarball を作成することで、1 つのファイルとしてアップロードされます。 ファイルを 1 つの 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>"
シェル スクリプトのスケジュール設定
次の crontab エントリは 1 行で、午前 12 時 5 分に 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 Storage からの復元
Azure Blob Storage に格納されているこれらのアーカイブの概要を次に示します。
- スナップショット アーカイブをローカル コンピューターにコピーし直します。 ターゲットの場所は、データベース ファイルとは別の場所にし、ファイル アーカイブや抽出を可能にする十分な容量 (
/var/tmp
など) を使用する必要があります。-
--runafter
シェル スクリプトの例を使用してアーカイブを作成した場合、AzCopy パイプを使用してターゲットの場所に gzipped tarball を直接抽出し、次に例を示します。cd ${TARGET_DIRECTORY}
azcopy cp "${BLOB_STORE}/${ARCHIVE_BLOB_TGZ}?${BLOB_SAS_KEY}" --from-to BlobPipe | tar zxvf -
-
- スナップショット アーカイブの内容を抽出します。
- 抽出後にターゲットの場所の内容を確認し、ファイルのアクセス許可と所有権を元のデータベース ファイルと比較します。
- たとえば、
ls -lR
します。
- たとえば、
- データベース サーバープロセスをシャットダウンします。
- 手順 1 で復元したターゲットの場所から元の場所にファイルをコピーします。
- 通常のデータベース復旧プロセスに進みます。