From 915ef2236c23894032707e86de815690ea56c445 Mon Sep 17 00:00:00 2001 From: cschantz Date: Wed, 10 Dec 2025 22:33:19 -0500 Subject: [PATCH] Add smart detection for missing files from other databases Automatically detects when missing tablespace errors are unrelated to the selected database and recommends Force Recovery Level 1. Changes: - Added selected_database parameter to show_recovery_options() - Detects if missing files are from selected DB vs other DBs - Shows clear recommendation when missing files are ONLY from other databases - Explains that Force Recovery Level 1 is safe and correct for selective restore - Prevents user confusion when restoring single DB from full backup Use case: When user restores ibdata1 + single database (e.g., amea_wp) from a full backup, ibdata1 contains metadata for all databases. Script now detects this and says: 'SMART DETECTION: Missing files are from OTHER databases, not amea_wp' 'Your selected database amea_wp appears to have all files!' 'RECOMMENDED ACTION: Use Force Recovery Level 1' This eliminates confusion and guides users to the correct solution. --- modules/backup/mysql-restore-to-sql.sh | 42 ++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/modules/backup/mysql-restore-to-sql.sh b/modules/backup/mysql-restore-to-sql.sh index ebdd69a..21f83f8 100755 --- a/modules/backup/mysql-restore-to-sql.sh +++ b/modules/backup/mysql-restore-to-sql.sh @@ -264,6 +264,7 @@ check_innodb_errors() { show_recovery_options() { local datadir="$1" local current_recovery="${2:-0}" + local selected_database="${3:-}" # The database user wants to restore print_banner "Recovery Options" @@ -273,10 +274,26 @@ show_recovery_options() { local corruption_detected="" local redo_incompatible="" local memory_issue="" + local missing_from_selected_db="" + local missing_from_other_dbs="" if [ -f "$error_log" ]; then if grep -qE "Cannot open tablespace|Tablespace.*missing|Tablespace.*was not found|Unable to open" "$error_log"; then missing_files="yes" + + # Check if missing files are from the selected database or other databases + if [ -n "$selected_database" ]; then + if grep -q "was not found at \./$selected_database/" "$error_log"; then + missing_from_selected_db="yes" + fi + # Check if any missing files are NOT from the selected database + while IFS= read -r line; do + if ! echo "$line" | grep -q "\./$selected_database/"; then + missing_from_other_dbs="yes" + break + fi + done < <(grep "was not found at" "$error_log") + fi fi if grep -qE "Corrupted|Database page corruption" "$error_log"; then corruption_detected="yes" @@ -291,6 +308,27 @@ show_recovery_options() { # Provide targeted guidance based on error type if [ -n "$missing_files" ]; then + # Smart detection: if missing files are ONLY from other databases (not the selected one) + if [ -z "$missing_from_selected_db" ] && [ -n "$missing_from_other_dbs" ] && [ -n "$selected_database" ]; then + print_warning "SMART DETECTION: Missing files are from OTHER databases, not '$selected_database'" + echo "" + print_success "Your selected database '$selected_database' appears to have all files!" + echo "" + print_warning "RECOMMENDED ACTION: Use Force Recovery Level 1" + echo "" + echo "The ibdata1 file contains references to databases you didn't restore." + echo "Force Recovery Level 1 will:" + echo " ✓ Ignore missing databases (safe - you don't have them anyway)" + echo " ✓ Start MySQL successfully" + echo " ✓ Allow you to dump '$selected_database' with NO data loss" + echo "" + echo "This is the CORRECT approach for selective database restoration." + echo "" + print_info "Re-run this script and select Force Recovery Level 1 in Step 4" + echo "" + return 0 + fi + print_error "DIAGNOSIS: Missing or unopenable tablespace files" echo "" @@ -1431,8 +1469,8 @@ step5_create_dump() { print_error "Failed to start second MySQL instance" echo "" - # Provide intelligent recovery guidance - show_recovery_options "$TEMP_DATADIR" "$FORCE_RECOVERY" + # Provide intelligent recovery guidance (pass selected database name) + show_recovery_options "$TEMP_DATADIR" "$FORCE_RECOVERY" "$DATABASE_NAME" press_enter return 1