If you are a web developer, you need to refer to various log files, in order to debug your application or improve its performance. Logs is the best place to start troubleshooting. Concerning the famous MySQLdatabase server (or MariaDB server), you need to refer to the following log files:
- The Error Log. It contains information about errors that occur while the server is running (also server start and stop)
- The General Query Log. This is a general record of what mysqld is doing (connect, disconnect, queries)
- The Slow Query Log. Ιt consists of "slow" SQL statements (as indicated by its name).
This article does not refer to The Binary Log. This requires very high standards server hardware and is useful only in special cases (e.g. replication, master - slaves setup, certain data recovery operations). Οtherwise, it is just a "performance killer".
The official documentation about MySQL logs is available here.
Enable logs from MySQL configuration
Logging parameters are located under [mysqld] section.
Edit MySQL configuration file:
1
| nano /etc/mysql/my .cnf |
This is the default setup for Logging and Replication . In other distributions the structure may be different, but you can always use MySQL server parameters:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # * Logging and Replication # # Both location gets rotated by the cronjob. # Be aware that this log type is a performance killer. # As of 5.1 you can enable the log at runtime! #general_log_file = /var/log/mysql/mysql.log #general_log = 1 # # Error logging goes to syslog due to /etc/mysql/conf.d/mysqld_safe_syslog.cnf. # # Here you can see queries with especially long duration #log_slow_queries = /var/log/mysql/mysql-slow.log #long_query_time = 2 #log-queries-not-using-indexes # # The following can be used as easy to replay backup logs or for replication. # note: if you are setting up a replication slave, see README.Debian about # other settings you may need to change. #server-id = 1 #log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 10 max_binlog_size = 100M #binlog_do_db = include_database_name #binlog_ignore_db = include_database_name |
All log files are NOT enabled by default MySQL setup (except the error log on Windows). Default Debian setup sends Error log to syslog. The other log files are not enabled.
Error Log
Error Log goes to syslog due to /etc/mysql/conf.d/mysqld_safe_syslog.cnf, which contains the following:
1
2
| [mysqld_safe] syslog |
This is the recommended method. If, for some reason, you do not want Error log to go to syslog, comment the above lines in /etc/mysql/conf.d/mysqld_safe_syslog.cnf or completely remove this file. Then, add in /etc/mysql/my.cnf the following lines:
1
2
3
4
5
| [mysqld_safe] log_error=/var/log/mysql/mysql_error.log [mysqld] log_error=/var/log/mysql/mysql_error.log |
General Query Log
To enable General Query Log, uncomment (or add) the relevant lines
1
2
| general_log_file = /var/log/mysql/mysql.log general_log = 1 |
Slow Query Log
To enable Slow Query Log, uncomment (or add) the relevant lines
1
2
3
| log_slow_queries = /var/log/mysql/mysql-slow.log long_query_time = 2 log-queries-not-using-indexes |
Restart MySQL server after changes
This method requires a server restart.
1
| service mysql restart |
or, using systemd
1
| systemctl restart mysql.service |
Enable logs at runtime
Since MySQL 5.1 you can enable and disable logs at runtime.
To enable logs at runtime, login to mysql client (
mysql -u root -p
) and give:
1
2
| SET GLOBAL general_log = 'ON'; SET GLOBAL slow_query_log = 'ON'; |
To disable logs at runtime, login to mysql client (
mysql -u root -p
) and give:
1
2
| SET GLOBAL general_log = 'OFF'; SET GLOBAL slow_query_log = 'OFF'; |
This method works on any platform and does not require a server restart.
Display log results
Error log
With the above settings, you can display Error log using
1
| tail -f /var/log/syslog |
REMARK: If you do not specify Error log file, MySQL keeps Error log at data dir (usually /var/lib/mysql in a file named {host_name}.err).
General Query log
With the above settings, you can display General log using
1
| tail -f /var/log/mysql/mysql .log |
REMARK: If you do not define General log file, MySQL keeps General log at data dir (usually /var/lib/mysqlin a file named {host_name}.log).
Slow Query log
With the above settings, you can display Slow Query log using
1
| tail -f /var/log/mysql/mysql-slow .log |
REMARK: If you do not specify Slow Query log file, MySQL keeps Slow Query log at data dir (usually /var/lib/mysql in a file named {host_name}-slow.log).
Log rotation
Do NOT ever forget to rotate logs. Otherwise, log files may become huge.
In Debian (and Debian derivatives as Ubuntu etc) log rotation using logrotate is already present after initial server setup ("Debian packages pre-configuration").
1
| nano /etc/logrotate.d/mysql-server |
in other distributions, some changes may be needed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| # - I put everything in one block and added sharedscripts, so that mysql gets # flush-logs'd only once. # Else the binary logs would automatically increase by n times every day. # - The error log is obsolete, messages go to syslog now. /var/log/mysql.log /var/log/mysql/mysql.log /var/log/mysql/mysql-slow.log { daily rotate 7 missingok create 640 mysql adm compress sharedscripts postrotate test -x /usr/bin/mysqladmin || exit 0 # If this fails, check debian.conf! MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf" if [ -z "`$MYADMIN ping 2>/dev/null`" ]; then # Really no mysqld or rather a missing debian-sys-maint user? # If this occurs and is not a error please report a bug. #if ps cax | grep -q mysqld; then if killall -q -s0 -umysql mysqld; then exit 1 fi else $MYADMIN flush-logs fi endscript } |
Check out your server configuration
TIP: Use
show variables like '%log%';
to examine your server variables related to log files
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
| root@cosmos ~ # mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 144332 Server version: 5.5.31-0+wheezy1 (Debian) Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show variables like '%log%'; +-----------------------------------------+--------------------------------+ | Variable_name | Value | +-----------------------------------------+--------------------------------+ | back_log | 50 | | binlog_cache_size | 32768 | | binlog_direct_non_transactional_updates | OFF | | binlog_format | STATEMENT | | binlog_stmt_cache_size | 32768 | | expire_logs_days | 10 | | general_log | OFF | | general_log_file | /var/lib/mysql/cosmos.log | | innodb_flush_log_at_trx_commit | 1 | | innodb_locks_unsafe_for_binlog | OFF | | innodb_log_buffer_size | 8388608 | | innodb_log_file_size | 5242880 | | innodb_log_files_in_group | 2 | | innodb_log_group_home_dir | ./ | | innodb_mirrored_log_groups | 1 | | log | OFF | | log_bin | OFF | | log_bin_trust_function_creators | OFF | | log_error | | | log_output | FILE | | log_queries_not_using_indexes | OFF | | log_slave_updates | OFF | | log_slow_queries | OFF | | log_warnings | 1 | | max_binlog_cache_size | 18446744073709547520 | | max_binlog_size | 104857600 | | max_binlog_stmt_cache_size | 18446744073709547520 | | max_relay_log_size | 0 | | relay_log | | | relay_log_index | | | relay_log_info_file | relay-log.info | | relay_log_purge | ON | | relay_log_recovery | OFF | | relay_log_space_limit | 0 | | slow_query_log | OFF | | slow_query_log_file | /var/lib/mysql/cosmos-slow.log | | sql_log_bin | ON | | sql_log_off | OFF | | sync_binlog | 0 | | sync_relay_log | 0 | | sync_relay_log_info | 0 | +-----------------------------------------+--------------------------------+ 41 rows in set (0.00 sec) |
Server variables official documentation is available here.
When to enable logs
Using default MySQL setup, all log files are NOT enabled (except the error log on Windows). Default Debiansetup sends Error log to syslog.
Actually, there many situations where log files can provide solutions to critical problems:
- Always enable Error log.
- Enable General query log (preferably at runtime) when you want to
- check that your application handles correctly MySQL database connection (a common mistake is to connect multiple times to MySQL from a single script)
- monitor executed queries from your application
- test memcached (or similar software), checking out if a query was executed or memcached has handled the request
- Enable Slow Query log (preferably from MySQL configuration file for a short period of time, e.g. 2-3 days) when your application performance is reduced for some reason and you should detect the slow queries.
Example
Here is an example of MySQL General query log:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| 131021 17:43:50 43 Connect root@localhost as anonymous on pnet_blog 43 Init DB pnet_blog 43 Query SELECT count(id) as total_posts FROM posts WHERE date_published is not null AND date_published <= '20131021144350' 43 Query SELECT * FROM posts WHERE date_published is not null AND date_published <= '20131021144350' ORDER BY date_published DESC LIMIT 0,10 44 Connect root@localhost as anonymous on pnet_blog 44 Query SELECT id, title, impressions FROM tips WHERE date_published IS NOT NULL AND date_published <= '20131021144350' ORDER BY date_published DESC LIMIT 0, 10 44 Quit 43 Quit 131021 17:44:28 45 Connect root@localhost as anonymous on pnet_blog 45 Init DB pnet_blog 45 Query SELECT * FROM posts WHERE url='how-and-when-to-enable-mysql-logs' 45 Query UPDATE posts SET impressions=impressions+1 WHERE id='41' 45 Query SELECT url, post_title FROM posts WHERE date_published IS NOT NULL AND date_published < '20131020150000' ORDER BY date_published DESC LIMIT 0,1 45 Query SELECT url, post_title FROM posts WHERE date_published IS NOT NULL AND date_published > '20131020150000' ORDER BY date_published ASC LIMIT 0,1 45 Query SELECT * FROM posts WHERE date_published is not null AND date_published <= '20131021144428' AND date_published >= '20130421144428' ORDER BY impressions DESC LIMIT 0,10 46 Connect root@localhost as anonymous on pnet_blog 46 Query SELECT id, title, impressions FROM tips WHERE date_published IS NOT NULL AND date_published <= '20131021144428' ORDER BY date_published DESC LIMIT 0, 10 46 Quit 45 Quit
|
0 comments:
Post a Comment