Schedule icon
Query icon
OutputValues icon
Log icon
If icon
SlackIncomingWebhook icon
Pause icon
Fail icon

MySQL Redo Logging Disabled Recovery Guard

Detect a MySQL server running with InnoDB redo logging off, re-enable it behind a dry-run and approval gate, then re-read the status variable to prove it.

Categories
DataInfrastructure

ALTER INSTANCE DISABLE INNODB REDO_LOG exists to make a bulk load faster. It is meant to be switched back on the moment the load finishes. Left off, the server runs with no crash recovery at all. An unclean shutdown loses committed transactions. The server will not even restart cleanly in that state. Nothing warns you, because every query and every commit behaves normally right up until the power cuts. This guard reads the Innodb_redo_log_enabled status variable, turns redo logging back on behind a gate, then proves crash recovery is really back.

This blueprint was created by zkasuran.

Safety

  • This flow only ever turns redo logging ON. ALTER INSTANCE ENABLE INNODB REDO_LOG is the only write it can issue, so it has no path to disabling redo logging on a healthy server. That is why it is safe to leave on a schedule.
  • Read-only by default. dry_run is true and auto_remediate is false, so a plain run reports what it found.
  • The write happens only when auto_remediate is true and dry_run is false. Even then it waits for a human to resume the Pause with approved set true. An unanswered gate reads as not approved.
  • The run passes only when a second read of the status variable returns ON.
  • The honest caveat, stated in the alert as well as here: enabling redo logging now does not retroactively protect anything written while it was off. If the server crashed during that window the damage already exists. The finding is worth reporting even after the fix, because it tells an operator there was an unprotected window.

How it works

  1. detect (io.kestra.plugin.jdbc.mysql.Query) reads Innodb_redo_log_enabled from performance_schema.global_status. OFF means redo logging is disabled.
  2. compute (io.kestra.plugin.core.output.OutputValues) turns that into a finding count. A server with no such status variable predates MySQL 8.0.21, cannot disable redo logging at all, so it reports zero findings rather than a false positive.
  3. log_status (io.kestra.plugin.core.log.Log) records the observed value, the finding count and the mode.
  4. have_finding (io.kestra.plugin.core.flow.If) ends with a clean log when redo logging is on. Otherwise alert_redo_disabled posts to Slack in every mode, including dry run.
  5. mode (io.kestra.plugin.core.flow.If) enters remediation only when auto_remediate is true and dry_run is false. Otherwise report_only logs what would run.
  6. approval_gate (io.kestra.plugin.core.flow.Pause) holds the run for a human. Re-enabling redo logging makes the next checkpoint flush pages that were never logged, so an operator picks the moment.
  7. remediate_enable runs ALTER INSTANCE ENABLE INNODB REDO_LOG with allowFailure: true, so a refused statement does not short circuit the gate.
  8. reverify re-reads the same status variable. verify_result fails the run through io.kestra.plugin.core.execution.Fail when it is not ON, then report_unprotected_window posts the fix plus the window that stays unprotected.

What you get

  • A detector for a server with no crash recovery, a state that produces no error, no warning, no slow query. Every commit looks normal until an unclean shutdown.
  • A fix that can only move the server in the safe direction. There is no input, branch or mode that disables redo logging.
  • A real verification step. The run passes only when the status variable reads ON after the change.
  • A failure that names the usual cause. A connecting user without INNODB_REDO_LOG_ENABLE has its ALTER INSTANCE refused, which the re-read catches instead of the run reporting success.
  • Slack alerts when redo logging is off, when the fix lands (with the unprotected window spelled out) and on any failure.

Who it's for

  • Platform engineers who load MySQL in bulk and disable redo logging to speed it up, where one failed or interrupted load leaves the switch off.
  • DBAs who inherit a server and want proof that crash recovery is actually on rather than assumed.
  • Teams running MySQL on a host where power loss or an OOM kill is a real event, who cannot afford to find out about this after the restart fails.

Why orchestrate this with Kestra

MySQL will not tell you that redo logging is off. There is no warning in the error log after the initial statement, no alert, nothing in a normal health check. Kestra adds what is missing. It reads the status variable on a schedule, gates the fix behind dry run and human approval, re-reads the variable so a hopeful fix becomes a verified one, raises the finding in Slack even after the fix because the unprotected window is itself the news.

Tested end to end

Run on Kestra 2.0.5 against MySQL 8.0.46, with ALTER INSTANCE DISABLE INNODB REDO_LOG used to create the degraded state and the mysql client used to confirm the status variable before and after every run.

  • Detector can fail: the same server reported zero findings with redo logging on and exactly one finding with it off. Both reads matched SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled' taken from the mysql client at the same moment.
  • Dry run on the degraded server detected the finding, alerted, changed nothing. The status variable read OFF before and after.
  • Remediate with approval turned redo logging back on. The re-read returned ON and the mysql client agreed.
  • Declining the gate left redo logging off, confirmed from the client.
  • Re-verify can fail: with a user that holds SELECT on performance_schema but not INNODB_REDO_LOG_ENABLE, the ALTER INSTANCE was refused, allowFailure let the run continue, the re-read still said OFF and the run failed rather than reporting success.
  • An unreachable host failed the detect step and fired the Slack alert through the errors block.

Prerequisites

MySQL 8.0.21 or newer reachable over JDBC. The connecting user needs SELECT on performance_schema to read the status variable, plus the INNODB_REDO_LOG_ENABLE privilege to turn redo logging back on. A read-only user still runs the detector.

Secrets

  • MYSQL_USERNAME: MySQL user, read when use_secret_auth is true.
  • MYSQL_PASSWORD: password for that user.
  • SLACK_WEBHOOK_URL: used by the alerts and the errors block.
  • In Kestra OSS, provide each secret as a base64-encoded environment variable prefixed SECRET_.

Inputs

Name Type Default Description
mysql_url STRING jdbc:mysql://localhost:3306/ JDBC URL of the MySQL server to guard.
use_secret_auth BOOL true Read credentials from secrets. Set false only for inline test credentials.
mysql_username STRING root Username used only when use_secret_auth is false.
mysql_password STRING `` Password used only when use_secret_auth is false.
dry_run BOOL true Report without turning redo logging back on.
auto_remediate BOOL false Run the ALTER INSTANCE behind the approval gate when dry_run is false.

Quick start

  1. Set MYSQL_USERNAME, MYSQL_PASSWORD and SLACK_WEBHOOK_URL as namespace secrets.
  2. Import this flow.
  3. Run it with mysql_url pointed at the server. The default dry run tells you whether crash recovery is on.
  4. To fix a server that reports OFF, run again with dry_run false and auto_remediate true, then resume the paused execution with approved true.
  5. Enable the schedule once you trust it. Safe mode is pinned in the trigger inputs, so the scheduled run reports and never writes until you change that.

How to extend

  • Drop the Pause for a staging server where the checkpoint flush cost does not matter, keeping the dry-run gate.
  • Add a second detector read of Innodb_redo_log_read_only to catch a server that came up in a read-only redo state.
  • Open a ticket from the alert branch for an environment where a change record is required before any ALTER INSTANCE.
  • Point one copy of the flow at each MySQL instance and record which host each scheduled copy guards in the flow labels.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.