MySQL keeps several distinct logs, and only the error log is on by default. On Debian and Ubuntu it lives at /var/log/mysql/error.log. On RHEL, CentOS, and Fedora it is /var/log/mysqld.log for Oracle MySQL, or /var/log/mariadb/mariadb.log for MariaDB. The path is controlled by the log_error system variable; check it with SHOW VARIABLES LIKE 'log_error';. The general query log and slow query log are off by default and must be enabled explicitly.
Quick Reference: MySQL Log File Paths
| Platform / Install method | Error log | General / slow log dir |
|---|---|---|
| Ubuntu / Debian (apt, MySQL) | /var/log/mysql/error.log | /var/log/mysql/ |
| Ubuntu / Debian (MariaDB) | /var/log/mysql/error.log | /var/log/mysql/ |
| RHEL / CentOS / Fedora (MySQL) | /var/log/mysqld.log | datadir (/var/lib/mysql/) |
| RHEL / CentOS (MariaDB) | /var/log/mariadb/mariadb.log | /var/lib/mysql/ |
| Amazon Linux (MariaDB) | /var/log/mariadb/mariadb.log | /var/lib/mysql/ |
| Homebrew (macOS, Apple Silicon) | /opt/homebrew/var/mysql/<host>.err | /opt/homebrew/var/mysql/ |
| Homebrew (macOS, Intel) | /usr/local/var/mysql/<host>.err | /usr/local/var/mysql/ |
Docker (official mysql/mariadb) | stderr (docker logs) | n/a unless mounted |
Empty log_error | stderr → systemd journal | — |
The four MySQL log types: error log (startup, shutdown, errors), general query log (every statement), slow query log (queries over long_query_time), and binary log (replication/recovery, at /var/lib/mysql/binlog.* by default).
How to View and Tail MySQL Logs
On Debian/Ubuntu:
sudo tail -f /var/log/mysql/error.log
On RHEL/CentOS (MySQL):
sudo tail -f /var/log/mysqld.log
Via the systemd journal when log_error is empty:
sudo journalctl -u mysql -f
sudo journalctl -u mariadb -f
Grep for errors:
sudo grep -iE 'error|\[ERROR\]' /var/log/mysql/error.log
In Docker:
docker logs -f <container>
Finding the Exact Path When It Varies
Ask the running server — this is the only reliable method:
SHOW VARIABLES LIKE 'log_error'; -- error log path
SHOW VARIABLES LIKE 'datadir'; -- base for relative paths
SHOW VARIABLES LIKE 'general_log%'; -- general_log (ON/OFF) + general_log_file
SHOW VARIABLES LIKE 'slow_query_log%'; -- slow_query_log + slow_query_log_file
SHOW VARIABLES LIKE 'log_output'; -- FILE, TABLE, or NONE
If log_output is TABLE, the general and slow logs are written to mysql.general_log and mysql.slow_log tables instead of files — query them with SQL. A relative log_error resolves against datadir.
Ubuntu / Debian Detail
Config is split across /etc/mysql/mysql.conf.d/mysqld.cnf (MySQL) or /etc/mysql/mariadb.conf.d/50-server.cnf (MariaDB). The error log defaults to /var/log/mysql/error.log. Edit, then restart:
sudo systemctl restart mysql # or: mariadb
RHEL / CentOS / Fedora Detail
The main config is /etc/my.cnf with drop-ins under /etc/my.cnf.d/. MySQL's log_error defaults to /var/log/mysqld.log; MariaDB uses /var/log/mariadb/mariadb.log. SELinux labels these with mysqld_log_t, so relocating logs requires semanage fcontext + restorecon.
Docker Detail
The official mysql and mariadb images log to stderr, so docker logs <container> shows the error log and there is no file inside the container by default. To persist files, mount a volume and point the config at it:
docker run -d --name db \
-e MYSQL_ROOT_PASSWORD=secret \
-v /host/mysql-log:/var/log/mysql \
mysql --log-error=/var/log/mysql/error.log
Enabling and Changing Logs
In a config file under [mysqld]:
[mysqld]
log_error = /var/log/mysql/error.log
log_output = FILE
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
general_log = 0
general_log_file = /var/log/mysql/general.log
general_log, slow_query_log, and their file paths can be toggled at runtime without a restart:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL general_log = 'OFF'; -- keep off in production; it is very verbose
log_error requires a restart to change.
Log Rotation
Debian/Ubuntu ship /etc/logrotate.d/mysql-server (or mariadb); RHEL ships /etc/logrotate.d/mysqld. A typical config:
/var/log/mysql/*.log {
daily
rotate 7
missingok
create 640 mysql adm
compress
sharedscripts
postrotate
test -x /usr/bin/mysqladmin && /usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf flush-logs
endscript
}
The postrotate runs mysqladmin flush-logs so MySQL reopens its files after the rename. Force a test run:
sudo logrotate -f /etc/logrotate.d/mysql-server
Common Errors You'll Find in MySQL Logs
[ERROR] Access denied for user 'x'@'host' (using password: YES)— wrong credentials or no grant for that host; fix withGRANT/CREATE USER.[ERROR] Can't start server: Bind on TCP/IP port: Address already in use— port 3306 is taken by another mysqld; stop the duplicate instance.[ERROR] InnoDB: Cannot allocate memory for the buffer pool—innodb_buffer_pool_sizeis larger than available RAM; lower it.[ERROR] Table './db/table' is marked as crashed— a MyISAM table needsREPAIR TABLEormyisamchk.[Warning] Aborted connection ... (Got timeout reading communication packets)— client timed out ormax_allowed_packetis too small for the payload.Disk is full writing '/var/lib/mysql/...'— the data volume is out of space; free space before writes stall.
Troubleshooting: Logs Missing or Empty
- Empty
log_error— with no path set, errors go to stderr/journal; checkjournalctl -u mysqlordocker logs. - Logging to tables — if
log_output = TABLE, querymysql.general_logandmysql.slow_loginstead of looking for files. - General/slow log off — both are disabled by default; enable them with the variables above before expecting output.
- Wrong path — a relative
log_errorresolves againstdatadir; always confirm withSHOW VARIABLES LIKE 'log_error';. - Permissions — files are owned by the
mysqluser (mode 640); usesudo. - Won't start — startup crashes log to the journal even when a file is configured, because mysqld fails before opening the file.
- Docker — no error.log inside the image unless you mounted a volume and set
--log-error; otherwise usedocker logs.