# XAMPP MariaDB Crash Recovery

This runbook covers an XAMPP MariaDB/MySQL instance that will not start after a Windows crash or power loss, especially when the error log reports Aria recovery failure.

The procedure is intended for the local LendCore installation:

- Server: MariaDB 10.4.x
- XAMPP path: `C:\xampp`
- Data directory: `C:\xampp\mysql\data`
- Database: `lendcore`
- Default port: `3306`

## Safety rules

1. Do not delete `ibdata1`, `ib_logfile0`, `ib_logfile1`, or any LendCore database directory.
2. Do not copy the clean XAMPP `backup` directory over the live data directory. That would replace current application data.
3. Stop every MySQL/MariaDB process before running `aria_chk`.
4. Make a complete filesystem copy of the data directory before changing anything.
5. Keep the SQL dump in `sqlbackup/` as an additional recovery option. See [DATABASE_BACKUP_CRON.md](DATABASE_BACKUP_CRON.md).

## 1. Confirm the failure

Open PowerShell as the same Windows user that runs XAMPP and inspect the server state:

```powershell
Get-Process mysqld,mariadbd -ErrorAction SilentlyContinue
Get-NetTCPConnection -LocalPort 3306 -ErrorAction SilentlyContinue
Get-Content 'C:\xampp\mysql\data\mysql_error.log' -Tail 180
```

The relevant failure normally contains messages similar to:

```text
Aria recovery failed. Please run aria_chk -r on all Aria tables and delete all aria_log.######## files
Plugin 'Aria' registration as a STORAGE ENGINE failed.
Could not open mysql.plugin table.
Failed to initialize plugins.
Aborting
```

If the error points to missing or corrupt InnoDB files, stop here and use a specialist recovery process. Do not apply this Aria procedure to an InnoDB failure.

## 2. Stop MySQL and check the port

Stop MySQL from the XAMPP Control Panel. Confirm that no server process remains:

```powershell
Get-Process mysqld,mariadbd -ErrorAction SilentlyContinue
Get-NetTCPConnection -LocalPort 3306 -ErrorAction SilentlyContinue
```

If a process remains, identify it before stopping it. Do not kill an unrelated database service.

## 3. Create a complete safety copy

Create a timestamped copy outside the live data directory. Ensure the copy completes with no failed files:

```powershell
$stamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$backup = "C:\xampp\mysql\data_before_repair_$stamp"
New-Item -ItemType Directory -Path $backup | Out-Null
robocopy 'C:\xampp\mysql\data' $backup /E /COPY:DAT /DCOPY:DAT /R:0 /W:0 /XJ
Write-Output "BACKUP_PATH=$backup"
Get-ChildItem $backup -Recurse -File | Measure-Object Length -Sum
```

Record the printed `BACKUP_PATH`. A nonzero Robocopy exit code can still mean a successful copy; verify that `FAILED` is `0` and that the file count and total size are plausible.

## 4. Preserve and remove only the corrupt Aria logs

The Aria logs are separate from the LendCore InnoDB data. Preserve them in the safety copy, then move the live copies out of the data directory:

```powershell
$archive = Join-Path $backup 'aria_logs_original'
New-Item -ItemType Directory -Path $archive -Force | Out-Null
Get-ChildItem 'C:\xampp\mysql\data\aria_log.*' -File | Move-Item -Destination $archive
```

Do not remove `aria_log_control` unless a later MariaDB-specific diagnostic explicitly requires it. The original corrupt log remains available in `$archive` and in the complete data copy.

## 5. Repair Aria indexes

Run the bundled MariaDB utility against all Aria index files:

```powershell
$tables = Get-ChildItem 'C:\xampp\mysql\data' -Recurse -Filter '*.MAI' |
    ForEach-Object FullName

foreach ($table in $tables) {
    Write-Output "REPAIR $table"
    & 'C:\xampp\mysql\bin\aria_chk.exe' `
        --datadir='C:\xampp\mysql\data' `
        --recover --force $table
    if ($LASTEXITCODE -ne 0) {
        Write-Output "ARIA_CHK_FAILED=$table"
    }
}
```

If `mysql\columns_priv.MAI` fails with `aria_sort_buffer_size is too small`, use the safe recovery algorithm for that table:

```powershell
& 'C:\xampp\mysql\bin\aria_chk.exe' `
    --datadir='C:\xampp\mysql\data' `
    --safe-recover --force `
    'C:\xampp\mysql\data\mysql\columns_priv.MAI'
```

The repair may update Aria system-table indexes. It must not modify the LendCore InnoDB table data.

## 6. Start MariaDB and verify it

Start from the XAMPP Control Panel. If the control panel does not show a useful error, start it directly for diagnostics:

```powershell
& 'C:\xampp\mysql\bin\mysqld.exe' `
    --defaults-file='C:\xampp\mysql\bin\my.ini' --console
```

A successful startup ends with:

```text
mysqld.exe: ready for connections.
Version: '10.4.x-MariaDB' ... port: 3306
```

Leave this diagnostic process running while performing the checks, or stop it cleanly with `mysqladmin shutdown` before restarting from XAMPP.

Connect with explicit long-form options. This avoids PowerShell parsing problems with the short `-h127.0.0.1` form:

```powershell
& 'C:\xampp\mysql\bin\mysql.exe' `
    --protocol=TCP --host=localhost --port=3306 --user=root `
    -e "SELECT VERSION() AS server_version, @@datadir AS data_directory;"
```

## 7. Verify LendCore data

Check the schema and representative business tables without issuing writes:

```powershell
& 'C:\xampp\mysql\bin\mysql.exe' `
    --protocol=TCP --host=localhost --port=3306 --user=root `
    -e "SELECT COUNT(*) AS lendcore_tables FROM information_schema.tables WHERE table_schema='lendcore'; SHOW TABLES FROM lendcore;"
```

Then check row counts and table integrity:

```powershell
& 'C:\xampp\mysql\bin\mysql.exe' `
    --protocol=TCP --host=localhost --port=3306 --user=root `
    -e "SELECT 'users' AS table_name, COUNT(*) AS row_count FROM lendcore.users UNION ALL SELECT 'loans', COUNT(*) FROM lendcore.loans UNION ALL SELECT 'repayments', COUNT(*) FROM lendcore.repayments UNION ALL SELECT 'transactions', COUNT(*) FROM lendcore.transactions; CHECK TABLE lendcore.users, lendcore.loans, lendcore.repayments, lendcore.transactions;"
```

Expected results depend on the current data, but each `CHECK TABLE` result should be `status | OK`. Compare the row counts with the latest known backup or application reports when available.

## 8. Clean restart

After verification, stop a manually started server cleanly:

```powershell
& 'C:\xampp\mysql\bin\mysqladmin.exe' `
    --protocol=TCP --host=localhost --port=3306 --user=root shutdown
```

Start MySQL from the XAMPP Control Panel and confirm that port `3306` is listening. Do not start a second manual `mysqld.exe` while the XAMPP instance is running.

## If the repair does not work

- Do not repeat repair commands indefinitely.
- Preserve the live data directory and all repair logs.
- Restore the pre-repair filesystem copy only after stopping MariaDB completely.
- If MariaDB can start but tables are damaged, export any readable data immediately before further work.
- Restore the latest known-good SQL dump only as a last resort, because importing it can overwrite newer records.
- Escalate an InnoDB error to a database recovery specialist; do not delete or regenerate InnoDB files.

## Incident record

For each recovery, record:

- Date and time of the crash.
- Final error-log message.
- MariaDB/XAMPP version.
- Safety-copy path.
- Aria tables that required repair.
- Pre- and post-recovery row counts.
- Whether startup was verified from XAMPP or the command line.
