MySQL / MariaDB Logs
MySQL and MariaDB produce four distinct log types. Understanding which log to check for a given problem saves significant time. The error log for crashes; slow query for performance; general log for debugging; binary log for replication.
MySQL Error Log
Records startup/shutdown messages, critical errors, and warnings. Default: /var/log/mysql/error.log (Debian) or /var/log/mysqld.log (RHEL). Set via log_error in my.cnf.
# Normal startup 2025-04-10T14:22:03.123456Z 0 [Note] mysqld: ready for connections. Version: '8.0.36' # InnoDB crash recovery 2025-04-10T14:21:58.001234Z 0 [Warning] InnoDB: Database was not shut down normally! Starting crash recovery. 2025-04-10T14:21:58.099000Z 0 [Note] InnoDB: Completed initialization of buffer pool # Aborted connection 2025-04-10T15:05:22.456789Z 42 [Warning] Aborted connection 42 to db: 'myapp' user: 'webapp' host: '10.0.0.5' (Got an error reading communication packets) # Replication error 2025-04-10T16:00:01.000000Z 0 [ERROR] Slave SQL: Could not execute Delete_rows event on table mydb.users; Can't find record in 'users', Error_code: 1032
Error Log Fields
| Field | Example | Meaning |
|---|---|---|
| Timestamp | 2025-04-10T14:22:03.123456Z | UTC timestamp in ISO 8601. The Z = UTC. Microsecond precision in MySQL 8.0+. |
| Thread ID | 0 / 42 | MySQL connection thread ID. Thread 0 = server process itself. Non-zero = specific client connection. |
| Level | [Note] [Warning] [ERROR] | Note = informational. Warning = non-fatal, investigate. ERROR = serious, requires DBA action. |
| Subsystem | InnoDB, Server | MySQL component that generated the message. |
Slow Query Log
Captures queries exceeding long_query_time (default 10s). Enable with slow_query_log = ON in my.cnf. Invaluable for performance tuning — this is the first place to look when your app feels slow.
# Time: 2025-04-10T16:30:01.123456Z # User@Host: webapp[webapp] @ [10.0.0.5] Id: 1042 # Query_time: 8.234567 Lock_time: 0.000123 Rows_sent: 1 Rows_examined: 2847650 use myapp_production; SET timestamp=1712766601; SELECT u.*, COUNT(o.id) as order_count FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE u.created_at > '2024-01-01' GROUP BY u.id ORDER BY order_count DESC LIMIT 20;
Slow Query Header Fields
| Field | Meaning | Action Threshold |
|---|---|---|
| Query_time | Total wall-clock execution time in seconds. Includes lock wait and actual execution. | >1s = review; >5s = urgent |
| Lock_time | Seconds spent waiting for table/row locks. High = lock contention between queries. | >0.1s = investigate contention |
| Rows_sent | Number of rows returned to the client. | Context-dependent |
| Rows_examined | Rows scanned to produce result. Full table scans = full table size here. | Ratio >100:1 vs Rows_sent = likely missing index |
| Rows_affected | Rows modified (INSERT/UPDATE/DELETE). | Context-dependent |
| Bytes_sent | Total bytes returned to client. Large = SELECT * or wide result sets. | >1MB per query = review projection |
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log — sort by total time, top 10.Or use pt-query-digest (Percona Toolkit) for fingerprinting and percentile statistics:
pt-query-digest /var/log/mysql/mysql-slow.log
General Query Log
Logs every statement received, including auth events. Warning: on a busy production server this generates enormous files and significant I/O overhead. Use only temporarily for debugging specific issues.
2025-04-10T17:00:00.000000Z 42 Connect webapp@localhost on myapp using TCP/IP 2025-04-10T17:00:00.001234Z 42 Query SET NAMES utf8mb4 2025-04-10T17:00:00.002345Z 42 Query SELECT * FROM sessions WHERE id = 'abc123' AND expires_at > NOW() 2025-04-10T17:00:00.003456Z 42 Query UPDATE sessions SET last_seen = NOW() WHERE id = 'abc123' 2025-04-10T17:00:00.004567Z 42 Quit
General Log Event Types
| Event | Meaning |
|---|---|
| Connect | Client established connection. Format: user@host on database using protocol. |
| Query | SQL statement executed. Full statement text logged. |
| Prepare / Execute | Prepared statement created (Prepare), then run (Execute). ID links them. |
| Init DB | USE database_name — active schema changed. |
| Quit | Client disconnected cleanly. |
| Kill | KILL command issued to terminate another connection or query. |
| Refresh | FLUSH statement or equivalent administrative reset. |
Binary Log
Records all data changes. Essential for replication and point-in-time recovery (PITR). Binary format — read with mysqlbinlog.
# Read binary log as human-readable text mysqlbinlog /var/lib/mysql/binlog.000123 # Filter by time range mysqlbinlog --start-datetime="2025-04-10 16:00:00" --stop-datetime="2025-04-10 17:00:00" binlog.000123 # ROW format output (row-based replication) # at 1456 #250410 17:30:00 server id 1 end_log_pos 1789 ### UPDATE `myapp`.`users` ### WHERE @1=42 @2='old@email.com' ### SET @1=42 @2='new@email.com'
ROW — logs actual row changes. Verbose but safe. Recommended for production.
MIXED — uses STATEMENT by default, falls back to ROW for unsafe statements.