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.
This commit is contained in:
cschantz
2025-12-10 22:33:19 -05:00
parent 4bd458e1c6
commit 915ef2236c
+40 -2
View File
@@ -264,6 +264,7 @@ check_innodb_errors() {
show_recovery_options() { show_recovery_options() {
local datadir="$1" local datadir="$1"
local current_recovery="${2:-0}" local current_recovery="${2:-0}"
local selected_database="${3:-}" # The database user wants to restore
print_banner "Recovery Options" print_banner "Recovery Options"
@@ -273,10 +274,26 @@ show_recovery_options() {
local corruption_detected="" local corruption_detected=""
local redo_incompatible="" local redo_incompatible=""
local memory_issue="" local memory_issue=""
local missing_from_selected_db=""
local missing_from_other_dbs=""
if [ -f "$error_log" ]; then if [ -f "$error_log" ]; then
if grep -qE "Cannot open tablespace|Tablespace.*missing|Tablespace.*was not found|Unable to open" "$error_log"; then if grep -qE "Cannot open tablespace|Tablespace.*missing|Tablespace.*was not found|Unable to open" "$error_log"; then
missing_files="yes" 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 fi
if grep -qE "Corrupted|Database page corruption" "$error_log"; then if grep -qE "Corrupted|Database page corruption" "$error_log"; then
corruption_detected="yes" corruption_detected="yes"
@@ -291,6 +308,27 @@ show_recovery_options() {
# Provide targeted guidance based on error type # Provide targeted guidance based on error type
if [ -n "$missing_files" ]; then 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" print_error "DIAGNOSIS: Missing or unopenable tablespace files"
echo "" echo ""
@@ -1431,8 +1469,8 @@ step5_create_dump() {
print_error "Failed to start second MySQL instance" print_error "Failed to start second MySQL instance"
echo "" echo ""
# Provide intelligent recovery guidance # Provide intelligent recovery guidance (pass selected database name)
show_recovery_options "$TEMP_DATADIR" "$FORCE_RECOVERY" show_recovery_options "$TEMP_DATADIR" "$FORCE_RECOVERY" "$DATABASE_NAME"
press_enter press_enter
return 1 return 1