Files
Scripts/backup/backup.sh
2025-09-09 17:21:49 +02:00

178 lines
6.5 KiB
Bash
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ==============================================================================
# SAP HANA Backup Script
#
# Performs schema exports and/or tenant backups for a SAP HANA database.
# Designed to be executed via a cronjob.
# Reads all settings from the backup.conf file in the same directory.
# ==============================================================================
# --- Configuration and Setup ---
# Find the script's own directory to locate the config file
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
CONFIG_FILE="${SCRIPT_DIR}/backup.conf"
# Check for config file and source it
if [[ -f "$CONFIG_FILE" ]]; then
source "$CONFIG_FILE"
else
echo "❌ Error: Configuration file not found at '${CONFIG_FILE}'"
exit 1
fi
# Check if hdbsql executable exists
if [[ ! -x "$HDBSQL_PATH" ]]; then
echo "❌ Error: hdbsql not found or not executable at '${HDBSQL_PATH}'"
exit 1
fi
# Calculate threads to use (half of the available cores, but at least 1)
TOTAL_THREADS=$(nproc --all)
THREADS=$((TOTAL_THREADS / 2))
if [[ "$THREADS" -eq 0 ]]; then
THREADS=1
fi
# --- Functions ---
# Performs a binary export of a specific schema.
perform_schema_export() {
echo "⬇️ Starting schema export for '${SCHEMA_NAME}'..."
local timestamp
timestamp=$(date +%Y%m%d_%H%M%S)
local export_base_dir="${BACKUP_BASE_DIR}/schema"
local export_path="${export_base_dir}/${SCHEMA_NAME}_${timestamp}"
local query_export_path="$export_path" # Default path for the EXPORT query
# NEW: If compression is enabled, export to a temporary directory
if [[ "$COMPRESS_SCHEMA" == "true" ]]; then
export_path="${export_base_dir}/tmp/${SCHEMA_NAME}_${timestamp}"
query_export_path="$export_path"
echo " Compression enabled. Using temporary export path: ${export_path}"
fi
local archive_file="${export_base_dir}/${SCHEMA_NAME}_${timestamp}.tar.gz"
# Create the target directory if it doesn't exist
mkdir -p "$(dirname "$export_path")"
# Construct and execute the EXPORT query
local query="EXPORT \"${SCHEMA_NAME}\".\"*\" AS BINARY INTO '${query_export_path}' WITH REPLACE THREADS ${THREADS};"
# We redirect stdout and stderr to /dev/null for cleaner cron logs.
"$HDBSQL_PATH" -U "$USER_KEY" "$query" > /dev/null 2>&1
local exit_code=$?
if [[ "$exit_code" -eq 0 ]]; then
echo " ✅ Successfully exported schema '${SCHEMA_NAME}'."
# NEW: Conditional compression logic
if [[ "$COMPRESS_SCHEMA" == "true" ]]; then
echo " 🗜️ Compressing exported files..."
# Use -C to change directory, ensuring the archive doesn't contain the 'tmp' path
tar -czf "$archive_file" -C "$(dirname "$export_path")" "$(basename "$export_path")"
local tar_exit_code=$?
if [[ "$tar_exit_code" -eq 0 ]]; then
echo " ✅ Successfully created archive '${archive_file}'."
echo " 🧹 Cleaning up temporary directory..."
rm -rf "$export_path"
# Clean up the tmp parent if it's empty
rmdir --ignore-fail-on-non-empty "$(dirname "$export_path")"
echo " ✨ Cleanup complete."
else
echo " ❌ Error: Failed to compress '${export_path}'."
fi
else
echo " Compression disabled. Raw export files are located at '${export_path}'."
fi
else
echo " ❌ Error: Failed to export schema '${SCHEMA_NAME}' (hdbsql exit code: ${exit_code})."
fi
}
# Performs a full backup of the tenant database.
perform_tenant_backup() {
echo "⬇️ Starting tenant backup..."
local timestamp
timestamp=$(date +%Y%m%d_%H%M%S)
local backup_base_dir="${BACKUP_BASE_DIR}/tenant"
local backup_path_prefix
local backup_target_dir
# NEW: Determine backup path based on compression setting
if [[ "$COMPRESS_TENANT" == "true" ]]; then
backup_target_dir="${backup_base_dir}/tmp"
backup_path_prefix="${backup_target_dir}/backup_${timestamp}"
echo " Compression enabled. Using temporary backup path: ${backup_path_prefix}"
else
backup_target_dir="$backup_base_dir"
backup_path_prefix="${backup_target_dir}/backup_${timestamp}"
fi
# Create the target directory if it doesn't exist
mkdir -p "$backup_target_dir"
# The USER_KEY must be configured to connect to the desired tenant database.
local query="BACKUP DATA USING FILE ('${backup_path_prefix}')"
# We redirect stdout and stderr to /dev/null for cleaner cron logs.
"$HDBSQL_PATH" -U "$USER_KEY" "$query" > /dev/null 2>&1
local exit_code=$?
if [[ "$exit_code" -eq 0 ]]; then
echo " ✅ Successfully initiated tenant backup with prefix '${backup_path_prefix}'."
# NEW: Conditional compression logic
if [[ "$COMPRESS_TENANT" == "true" ]]; then
local archive_file="${backup_base_dir}/backup_${timestamp}.tar.gz"
echo " 🗜️ Compressing backup files..."
# The backup creates multiple files starting with the prefix. We compress the whole temp dir.
# Using -C and '.' ensures we archive the contents of the directory, not the directory itself.
tar -czf "$archive_file" -C "$backup_target_dir" .
local tar_exit_code=$?
if [[ "$tar_exit_code" -eq 0 ]]; then
echo " ✅ Successfully created archive '${archive_file}'."
echo " 🧹 Cleaning up temporary directory..."
rm -rf "$backup_target_dir"
echo " ✨ Cleanup complete."
else
echo " ❌ Error: Failed to compress backup files in '${backup_target_dir}'."
fi
fi
else
echo " ❌ Error: Failed to initiate tenant backup (hdbsql exit code: ${exit_code})."
fi
}
# --- Main Execution ---
echo "⚙️ Starting HANA backup process..."
# Ensure the base directory exists
mkdir -p "$BACKUP_BASE_DIR"
case "$BACKUP_TYPE" in
schema)
perform_schema_export
;;
tenant)
perform_tenant_backup
;;
all)
perform_schema_export
echo "" # Add a newline for better readability
perform_tenant_backup
;;
*)
echo " ❌ Error: Invalid BACKUP_TYPE '${BACKUP_TYPE}' in config. Use 'schema', 'tenant', or 'all'."
;;
esac
echo "📦 Backup process complete."
echo "👋 Exiting."