Skip to content

fix(recover mysql): script + accept any separator in container name #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions recovery-docker-mysql.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ BACKUPDIR="/backup/mysql"

# Display a numbered list of containers from the backup directory
echo "Available containers:"
CONTAINERS=($(for file in "$BACKUPDIR"/*.sql.gz; do IFS='-' read -r CONTAINER _ <<< "$(basename "$file" .sql.gz)"; echo "$CONTAINER"; done | sort -u))
mapfile -t CONTAINERS < <(docker ps --format '{{.Names}}:{{.Image}}' | grep 'mysql\|mariadb' | cut -d":" -f1)
for ((i=0; i<${#CONTAINERS[@]}; i++)); do
echo "$((i+1)). ${CONTAINERS[$i]}"
done

# Prompt the user to select a container
read -p "Enter the number of the container: " CONTAINER_NUMBER
read -r -p "Enter the number of the container: " CONTAINER_NUMBER
if [[ ! $CONTAINER_NUMBER =~ ^[0-9]+$ || $CONTAINER_NUMBER -lt 1 || $CONTAINER_NUMBER -gt ${#CONTAINERS[@]} ]]; then
echo "Invalid input. Please enter a valid container number."
exit 1
Expand All @@ -22,13 +22,18 @@ CONTAINER=${CONTAINERS[$((CONTAINER_NUMBER-1))]}

# Display a numbered list of databases for the selected container
echo "Available databases in container $CONTAINER:"
DATABASES=($(for file in "$BACKUPDIR"/*.sql.gz; do IFS='-' read -r FILE_CONTAINER FILE_DATABASE _ <<< "$(basename "$file" .sql.gz)"; if [ "$FILE_CONTAINER" == "$CONTAINER" ]; then echo "$FILE_DATABASE"; fi>
mapfile -t DATABASES < <(for file in "$BACKUPDIR"/"$CONTAINER"*sql.gz; do
filename=$(basename "$file" .sql.gz)
db_part=${filename#"$CONTAINER"[^[:alnum:]]} # Remove container prefix and any separator
db_name=${db_part:0:-13} # Remove timestamp and its separator
echo "$db_name"
done | sort -u)
for ((i=0; i<${#DATABASES[@]}; i++)); do
echo "$((i+1)). ${DATABASES[$i]}"
done

# Prompt the user to select a database
read -p "Enter the number of the database: " DATABASE_NUMBER
read -r -p "Enter the number of the database: " DATABASE_NUMBER
if [[ ! $DATABASE_NUMBER =~ ^[0-9]+$ || $DATABASE_NUMBER -lt 1 || $DATABASE_NUMBER -gt ${#DATABASES[@]} ]]; then
echo "Invalid input. Please enter a valid database number."
exit 1
Expand All @@ -39,7 +44,12 @@ DATABASENAME=${DATABASES[$((DATABASE_NUMBER-1))]}

# Display a numbered list of timestamps for the selected container and database
echo "Available timestamps for container $CONTAINER and database $DATABASENAME:"
TIMESTAMPS=($(for file in "$BACKUPDIR"/*.sql.gz; do IFS='-' read -r FILE_CONTAINER FILE_DATABASE FILE_TIMESTAMP _ <<< "$(basename "$file" .sql.gz)"; if [ "$FILE_CONTAINER" == "$CONTAINER" ] && [ "$FILE_DAT>
mapfile -t TIMESTAMPS < <(for file in "$BACKUPDIR"/"$CONTAINER"*"$DATABASENAME"*sql.gz; do
filename=$(basename "$file" .sql.gz)
# Extract timestamp (12 digits) from the end of filename
timestamp=${filename:(-12)}
echo "$timestamp"
done | sort -u)
for ((i=0; i<${#TIMESTAMPS[@]}; i++)); do
# Manually split and format the timestamp as YYYY-MM-DD HH:mm
YEAR=${TIMESTAMPS[$i]:0:4}
Expand All @@ -52,7 +62,7 @@ for ((i=0; i<${#TIMESTAMPS[@]}; i++)); do
done

# Prompt the user to select a timestamp
read -p "Enter the number of the timestamp: " TIMESTAMP_NUMBER
read -r -p "Enter the number of the timestamp: " TIMESTAMP_NUMBER
if [[ ! $TIMESTAMP_NUMBER =~ ^[0-9]+$ || $TIMESTAMP_NUMBER -lt 1 || $TIMESTAMP_NUMBER -gt ${#TIMESTAMPS[@]} ]]; then
echo "Invalid input. Please enter a valid timestamp number."
exit 1
Expand All @@ -65,18 +75,18 @@ TIMESTAMP=${TIMESTAMPS[$((TIMESTAMP_NUMBER-1))]}
FILENAME="$CONTAINER-$DATABASENAME-$TIMESTAMP.sql.gz"

# Set the MySQL password in the MYSQL_PWD variable
MYSQL_PWD=$(docker exec $CONTAINER env | grep MYSQL_ROOT_PASSWORD | cut -d"=" -f2)
MYSQL_PWD=$(docker exec "$CONTAINER" env | grep MYSQL_ROOT_PASSWORD | cut -d"=" -f2)

# Display confirmation prompt
read -p "Confirm recovery of DB $DATABASENAME in Container $CONTAINER from $TIMESTAMP_FORMATTED? (yes/y): " CONFIRMATION
if [[ ! $CONFIRMATION =~ ^[Yy][Ee][Ss]|[Yy]$ ]]; then
read -r -p "Confirm recovery of DB $DATABASENAME in Container $CONTAINER from $TIMESTAMP_FORMATTED? (yes/y): " CONFIRMATION
if [[ ! $CONFIRMATION =~ ^([Yy][Ee][Ss]|[Yy])$ ]]; then
echo "Recovery canceled by user."
exit 1
fi

# Execute the desired command and capture the output
OUTPUT=$(zcat "$BACKUPDIR/$FILENAME" | docker exec -i $CONTAINER /usr/bin/mysql -u root --password=$MYSQL_PWD $DATABASENAME 2>&1)
OUTPUT=$(zcat "$BACKUPDIR/$FILENAME" | docker exec -i "$CONTAINER" /usr/bin/mysql -u root --password="$MYSQL_PWD" "$DATABASENAME" 2>&1)

# Display the output
echo "Output of MySQL command:"
echo "$OUTPUT"
echo "$OUTPUT"