Files
Scripts/tomi.sh
2025-08-30 13:23:28 +02:00

222 lines
7.4 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
#
# Script to backup (export), restore (import), or restore-and-rename a SAP HANA schema.
# It automatically detects the number of available CPU threads to optimize operations.
# Designed for both interactive use and cronjob automation.
#
# ETomi 2025
# --- Configuration ---
hdbsql_path="/usr/sap/hdbclient/hdbsql"
# -- HANA Secure User Store Key --
user_key="CRONKEY"
# --- Validation ---
for cmd in hdbsql hdbuserstore tar gzip nproc pv mkdir chmod date; do
tool_path="$(dirname "$hdbsql_path")/$cmd"
if ! command -v $cmd &> /dev/null && [ ! -f "$tool_path" ]; then
echo "❌ Error: Required command '$cmd' is not found in your PATH or at '$tool_path'."
exit 1
fi
done
if [ "$#" -lt 2 ]; then
echo "❌ Error: Not enough arguments."
echo ""
echo "Usage: $0 <action> <arguments...>"
echo ""
echo "Actions:"
echo " setup-key <key_name> - Interactively create a secure user store key"
echo " backup <schema> <path> [--compress] [--timestamp] - Export a schema, optionally compress and/or add a timestamp"
echo " restore <schema> <path> - Import a schema from a path"
echo " restore-rename <schema> <new_schema> <path> - Import and rename a schema"
exit 1
fi
action=$1
threads=$(nproc --all)
# --- Functions ---
confirm_action() {
if [ "$TERM" != "dumb" ] && [ -t 0 ]; then
read -p "❓ Are you sure you want to proceed with the '$1' operation? (y/n): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "🛑 Operation cancelled by user."
exit 1
fi
fi
}
execute_sql() {
local command_to_run=$1
local action_name=$2
echo "⚙️ Executing SQL: $command_to_run"
$hdbsql_path -U $user_key "$command_to_run"
if [ $? -ne 0 ]; then
echo "❌ Failure! The '$action_name' command failed. Please check the logs."
exit 1
fi
}
# --- Main Logic ---
# The setup-key action is handled first as it doesn't need all global variables.
if [ "$action" == "setup-key" ]; then
if [ "$#" -ne 2 ]; then
echo "❌ Error: Invalid arguments for 'setup-key'."
echo "Usage: $0 setup-key <key_name>"
exit 1
fi
key_name=$2
hdbuserstore_path="$(dirname "$hdbsql_path")/hdbuserstore"
echo "--- Interactive Secure User Store Key Setup ---"
read -p "Enter HANA host [localhost]: " hdb_host
hdb_host=${hdb_host:-localhost}
read -p "Enter instance number [00]: " hdb_instance
hdb_instance=${hdb_instance:-00}
hdb_port="3${hdb_instance}15"
read -p "Enter tenant database name [NDB]: " hdb_tenant
hdb_tenant=${hdb_tenant:-NDB}
read -p "Enter database user [SYSTEM]: " hdb_user
hdb_user=${hdb_user:-SYSTEM}
read -sp "Enter password for '$hdb_user': " hdb_pass
echo ""
if [ -z "$hdb_pass" ]; then
echo "❌ Error: Password cannot be empty."
exit 1
fi
connection_string="${hdb_host}:${hdb_port}@${hdb_tenant}"
echo "-------------------------------------"
echo "Key Name: $key_name"
echo "Connection String: $connection_string"
echo "Database User: $hdb_user"
echo "-------------------------------------"
confirm_action "create key '$key_name'"
echo "▶️ Creating secure store key..."
$hdbuserstore_path SET "$key_name" "$connection_string" "$hdb_user" "$hdb_pass"
if [ $? -eq 0 ]; then
echo "✅ Success! Key '$key_name' created. You can now set 'user_key=\"$key_name\"' at the top of this script."
else
echo "❌ Failure! Could not create key '$key_name'. Please check the details and try again."
exit 1
fi
exit 0
fi
# --- Actions (Backup/Restore) ---
echo " Detected $threads available CPU threads to use for the operation."
case "$action" in
backup)
if [ "$#" -lt 3 ] || [ "$#" -gt 5 ]; then
echo "❌ Error: Invalid arguments for 'backup'."
echo "Usage: $0 backup <schema_name> <path> [--compress] [--timestamp]"
exit 1
fi
schema=$2
path=$3
compress_flag=false
timestamp_flag=false
# Loop through optional arguments to handle any order
for arg in "${@:4}"; do
case "$arg" in
--compress)
compress_flag=true
;;
--timestamp)
timestamp_flag=true
;;
*)
echo "❌ Error: Invalid option '$arg'. Valid options are '--compress' or '--timestamp'."
exit 1
;;
esac
done
# Add timestamp to path if flag is set
if [ "$timestamp_flag" = true ]; then
timestamp=$(date +'%Y%m%d_%H%M%S')
path="${path}_${timestamp}"
fi
echo " Creating backup directory: $path"
mkdir -p "$path" && chmod 777 "$path"
if [ $? -ne 0 ]; then
echo "❌ Failure! Could not create or set permissions for directory '$path'."
exit 1
fi
echo "▶️ Starting BACKUP (EXPORT) for schema '$schema' to '$path'..."
sql_command="EXPORT \"$schema\".\"*\" AS BINARY INTO '$path' WITH REPLACE THREADS $threads;"
execute_sql "$sql_command" "$action"
echo "✅ SQL Export completed successfully."
if [ "$compress_flag" = true ]; then
echo "▶️ Compressing backup directory: $path"
archive_file="${path}.tar.gz"
total_size=$(du -sb "$path" | awk '{print $1}')
tar cf - -C "$(dirname "$path")" "$(basename "$path")" | pv -s "$total_size" | gzip > "$archive_file"
if [ $? -eq 0 ]; then
echo "✅ Compression successful: $archive_file"
echo "🗑️ Removing original backup directory..."
rm -rf "$path"
else
echo "❌ Failure! Compression failed."
exit 1
fi
fi
;;
restore)
if [ "$#" -ne 3 ]; then
echo "❌ Error: Invalid arguments for 'restore'."
echo "Usage: $0 restore <schema_name> <path>"
exit 1
fi
schema=$2
path=$3
confirm_action "restore"
echo "▶️ Starting RESTORE (IMPORT) for schema '$schema' from '$path'..."
sql_command="IMPORT \"$schema\".\"*\" AS BINARY FROM '$path' WITH IGNORE EXISTING THREADS $threads;"
execute_sql "$sql_command" "$action"
echo "✅ Success! The '$action' operation completed."
;;
restore-rename)
if [ "$#" -ne 4 ]; then
echo "❌ Error: Invalid arguments for 'restore-rename'."
echo "Usage: $0 restore-rename <schema_name> <new_schema_name> <path>"
exit 1
fi
schema=$2
new_schema=$3
path=$4
confirm_action "restore-rename"
echo "▶️ Starting RESTORE & RENAME for schema '$schema' from '$path' to '$new_schema'..."
sql_command="IMPORT \"$schema\".\"*\" AS BINARY FROM '$path' WITH IGNORE EXISTING THREADS $threads RENAME SCHEMA \"$schema\" TO \"$new_schema\";"
execute_sql "$sql_command" "$action"
echo "✅ Success! The '$action' operation completed."
;;
*)
echo "❌ Error: Invalid action '$action'."
echo "Valid actions are 'backup', 'restore', 'restore-rename', or 'setup-key'."
exit 1
;;
esac
exit 0