Skip to content
Navigation

Type at least two characters. Search covers page titles, headings, tags and database names.

↑ ↓ to navigateEnter to openEsc to close0 pages
MySQLintermediate

MySQL Common Problems

Recurring MySQL failure modes — replication stops, lock wait timeouts, undo growth, connection limits — and what resolves each.

2 min readIntermediateUpdated Edit this page

Replication stopped

Replica_SQL_Running: No with an error in Last_SQL_Error. Common causes: a row that does not exist on the replica for an UPDATE, a duplicate key from a write made directly on the replica, or a schema difference.

Diagnose before acting — see the replication stopped playbook. Set super_read_only = ON on replicas to prevent the most common cause.

Lock wait timeout exceeded

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction. Another transaction holds a lock for longer than innodb_lock_wait_timeout (50 seconds by default).

SELECT trx_id, trx_state, trx_started, trx_rows_locked, trx_query
FROM information_schema.innodb_trx ORDER BY trx_started;

The blocking transaction is nearly always long-running application code holding a transaction open across an external call. Lower the timeout so failures are fast and visible, and fix the code.

Deadlocks

Detected and resolved automatically by rolling back one transaction; the application must retry. Enable innodb_print_all_deadlocks to see all of them rather than only the most recent in SHOW ENGINE INNODB STATUS.

Undo history growth

Disk usage climbing while row counts do not, and reads getting slower. The purge thread cannot remove old row versions because a transaction is still open.

SELECT count FROM information_schema.innodb_metrics WHERE name = 'trx_rseg_history_len';

Find and terminate the oldest open transaction, then prevent recurrence with application-level transaction deadlines.

Too many connections

ERROR 1040: Too many connections. Raising max_connections buys time and costs memory. Use ProxySQL to cap the total, and give background jobs their own smaller pool. See the too many connections playbook.

Table is full or disk full

Both the data directory and the binary log directory can fill. Binlogs are the usual surprise on a write-heavy server. Check binlog_expire_logs_seconds, confirm no replica still needs the old logs, and monitor both directories separately.

The query got slower after a data load

InnoDB samples index pages for cardinality estimates, and a bulk load can leave them stale.

ANALYZE TABLE orders;

If the plan is still wrong, the estimate rather than the query is the problem — raise innodb_stats_persistent_sample_pages for that table.

Character set and collation mismatch

A join between a utf8mb4_0900_ai_ci column and a utf8mb4_general_ci column cannot use an index on either, because the server must convert. It appears as an inexplicable full scan on a well-indexed column.

SELECT table_name, column_name, character_set_name, collation_name
FROM information_schema.columns
WHERE table_schema = 'shop' AND collation_name IS NOT NULL;

Keep one charset and collation across the whole schema.

Implicit type conversion

-- user_id is BIGINT; the string literal forces a conversion and drops the index.
SELECT * FROM orders WHERE customer_id = '4711';

MySQL will accept it, convert, and often scan. Match parameter types to column types in the application layer.