共用方式為


使用 Azure 應用程式 一致快照集工具執行 RunBefore 和 RunAfter

本文提供一個指南,讓您能夠搭配 Azure NetApp Files 使用 --runbefore Azure 應用程式 一致快照集工具的 和 --runafter 功能。

簡介

AzAcSnap 可以在主要執行之前或之後,使用 選項--runbefore--runafter或分別執行外部命令。

--runbefore 會在主要執行 azacsnap 之前執行殼層命令,並將一些 azacsnap 命令行參數提供給殼層環境。 根據預設, azacsnap 等候最多 30 秒,讓外部殼層命令在終止進程並返回 azacsnap 正常執行之前完成。 藉由在字元後面 % 加上數位以秒為單位等候,即可覆寫此延遲(例如, --runbefore "mycommand.sh%60" 最多等候 60 秒 mycommand.sh 才能完成)。

--runafter 在主要執行 azacsnap 之後執行殼層命令,並將一些 azacsnap 命令行參數提供給殼層環境。 根據預設, azacsnap 等候最多 30 秒,讓外部殼層命令在終止進程並返回 azacsnap 正常執行之前完成。 藉由在字元後面 % 加上數位以秒為單位等候,即可覆寫此延遲(例如, --runafter "mycommand.sh%60" 最多等候 60 秒才能 mycommand.sh 完成)。

azacsnap會產生下列環境變數清單,並將其傳遞給分支的殼層,以執行提供給 和--runafter的參數--runbefore命令:

  • $azCommand = 傳遞至 -c 的命令選項(例如備份、測試等)。
  • $azConfigFileName = 組態檔名。
  • $azPrefix = --prefix 值。
  • $azRetention = --retention 值。
  • $azSid = --dbsid 值。
  • $azSnapshotName = azacsnap 所產生的快照集名稱。

注意

選項中--runafter只有的值$azSnapshotName

備份至 Azure Blob 記憶體的範例用法

重要

範例僅供參考之用。 我們不保證提供的任何信息的正確性、完整性或有用性。 使用這些範例的風險在於您自己的風險。 我們不接受因使用這些範例而產生的任何損失或損害的任何責任。 我們不支援本檔中提供的範例。

這項新功能的範例使用方式是使用 azcopy 此工具將快照集上傳至 Azure Blob 以進行封存目的(使用 AzCopy 將數據複製到 Azure 儲存體)。

上傳至 Azure Blob 記憶體的殼層腳本

此範例殼層腳本在結尾有特殊的存根,以防止 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>"

排程殼層腳本

下列 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 記憶體中儲存的其中一個封存進行還原,如下所示:

  1. 將快照集封存複製到本機計算機。 目標位置應該與資料庫檔案分開,且容量足以允許檔案封存和擷取,例如 /var/tmp
    1. 如果他們使用 --runafter 範例殼層腳本建立封存,則他們可能會使用 AzCopy 管道將 gzipped tarball 直接從 Azure Blob 儲存器擷取到目標位置,例如:
      1. cd ${TARGET_DIRECTORY}
      2. azcopy cp "${BLOB_STORE}/${ARCHIVE_BLOB_TGZ}?${BLOB_SAS_KEY}" --from-to BlobPipe | tar zxvf -
  2. 擷取快照集封存的內容。
  3. 在擷取、比較檔案許可權和擁有權與源文件之後,檢閱目標位置的內容。
    1. 例如,執行 ls -lR
  4. 關閉資料庫伺服器進程。
  5. 將步驟 1 還原的目標位置中的檔案複製到其原始位置。
  6. 繼續進行一般資料庫復原程式。

下一步