Fix early MySQL instance shutdown bug in error checking
The check_innodb_errors() function was using an overly broad error pattern "\[ERROR\].*InnoDB" that matched warnings about missing tables in OTHER databases, triggering premature shutdown even when the selected database was healthy. Changes: 1. Refactored check_innodb_errors() to accept optional database name parameter 2. Split error patterns into CRITICAL (always fail) and DATABASE_SPECIFIC - Critical errors: memory, plugin init, redo log corruption (always fail) - Database-specific errors: only fail if they mention the selected database 3. Removed the too-broad "\[ERROR\].*InnoDB" pattern 4. Updated both calls to check_innodb_errors() to pass DATABASE_NAME This allows the script to: - Succeed when other databases have issues (as they should be ignored) - Only fail for actual problems with the selected database - Properly attempt dump creation on the second instance Fixes the 2-second gap between "ready for connections" and unexpected shutdown. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1079,6 +1079,7 @@ detect_recovery_level_from_errors() {
|
||||
check_innodb_errors() {
|
||||
local error_log="$1"
|
||||
local check_recent="${2:-no}" # "yes" = only check recent errors, "no" = full check
|
||||
local selected_db="${3:-}" # Database name to filter on (optional)
|
||||
|
||||
if [ ! -f "$error_log" ]; then
|
||||
return 0 # No error log yet, assume OK
|
||||
@@ -1087,17 +1088,22 @@ check_innodb_errors() {
|
||||
local errors_found=0
|
||||
local critical_errors=()
|
||||
|
||||
# InnoDB critical error patterns
|
||||
local error_patterns=(
|
||||
# CRITICAL error patterns that ALWAYS fail (not specific to any database)
|
||||
# These indicate fundamental InnoDB corruption or system issues
|
||||
local critical_patterns=(
|
||||
"InnoDB: Corrupted"
|
||||
"InnoDB: Database page corruption"
|
||||
"InnoDB: Unable to open"
|
||||
"InnoDB: Cannot allocate memory"
|
||||
"InnoDB: Tablespace.*missing"
|
||||
"InnoDB: Redo log.*corrupt"
|
||||
"InnoDB:.*redo log.*incompatible"
|
||||
"InnoDB: Plugin initialization aborted"
|
||||
"\[ERROR\].*InnoDB"
|
||||
)
|
||||
|
||||
# DATABASE-SPECIFIC error patterns
|
||||
# These only cause failure if they mention the selected database
|
||||
local db_patterns=(
|
||||
"InnoDB: Unable to open"
|
||||
"InnoDB: Tablespace.*missing"
|
||||
)
|
||||
|
||||
# If checking recent errors, only look at last 50 lines
|
||||
@@ -1108,8 +1114,8 @@ check_innodb_errors() {
|
||||
log_content=$(cat "$error_log" 2>/dev/null)
|
||||
fi
|
||||
|
||||
# Check each pattern
|
||||
for pattern in "${error_patterns[@]}"; do
|
||||
# Check CRITICAL patterns first (always fail if found)
|
||||
for pattern in "${critical_patterns[@]}"; do
|
||||
if echo "$log_content" | grep -qE "$pattern"; then
|
||||
local error_line=$(echo "$log_content" | grep -E "$pattern" | tail -1)
|
||||
critical_errors+=("$error_line")
|
||||
@@ -1117,6 +1123,19 @@ check_innodb_errors() {
|
||||
fi
|
||||
done
|
||||
|
||||
# Check DATABASE-SPECIFIC patterns only if they mention the selected database
|
||||
if [ -n "$selected_db" ]; then
|
||||
for pattern in "${db_patterns[@]}"; do
|
||||
# Create pattern that checks both for the error pattern AND the database name
|
||||
# The error message will contain backticks like: `database_name`.`table_name`
|
||||
if echo "$log_content" | grep -qE "$pattern.*\`${selected_db}\`"; then
|
||||
local error_line=$(echo "$log_content" | grep -E "$pattern.*\`${selected_db}\`" | tail -1)
|
||||
critical_errors+=("$error_line")
|
||||
errors_found=$((errors_found + 1))
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -n "$errors_found" ] && [ "$errors_found" -gt 0 ]; then
|
||||
print_error "InnoDB errors detected in $error_log:"
|
||||
for err in "${critical_errors[@]}"; do
|
||||
@@ -1767,9 +1786,10 @@ start_second_instance() {
|
||||
sleep 2
|
||||
|
||||
# Check for InnoDB errors in the error log
|
||||
# Pass the selected database name so we only fail on relevant errors
|
||||
echo ""
|
||||
print_info "Checking InnoDB startup status..."
|
||||
if ! check_innodb_errors "$datadir/mysql.err" "yes"; then
|
||||
if ! check_innodb_errors "$datadir/mysql.err" "yes" "$DATABASE_NAME"; then
|
||||
print_error "InnoDB initialization encountered errors"
|
||||
echo ""
|
||||
print_warning "Attempting to shut down second instance..."
|
||||
@@ -1813,8 +1833,8 @@ start_second_instance() {
|
||||
print_error "Second MySQL instance failed to start"
|
||||
echo ""
|
||||
|
||||
# Check for InnoDB errors
|
||||
if ! check_innodb_errors "$datadir/mysql.err" "no"; then
|
||||
# Check for InnoDB errors (pass selected database for filtering)
|
||||
if ! check_innodb_errors "$datadir/mysql.err" "no" "$DATABASE_NAME"; then
|
||||
echo ""
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user