Contents
- Configuring Locations and File Names of Logs
- Configuring Authentication for Logrotate
- Configuring Logrotate
- Testing Log Rotation
- Logrotate in Ansible
Unix and Linux distributions offer the logrotate
utility, which makes it very easy to rotate log files. This page will describe how to configure log rotation for the error log, general query log, and the slow query log.
Configuring Locations and File Names of Logs
The first step is to configure the locations and file names of logs. To make the log rotation configuration easier, it can be best to put these logs in a dedicated log directory.
We will need to configure the following:
- The error log location and file name is configured with the
log_error
system variable. - The general query log location and file name is configured with the
general_log_file
system variable. - The slow query log location and file name is configured with the
slow_query_log_file
system variable.
If you want to enable the general query log and slow query log immediately, then you will also have to configure the following:
- The general query log is enabled with the
general_log
system variable. - The slow query log is enabled with the
slow_query_log
system variable.
These options can be set in a server option group in an option file prior to starting up the server. For example, if we wanted to put our log files in /var/log/mysql/
, then we could configure the following:
[mariadb] ... log_error=/var/log/mysql/mariadb.err general_log general_log_file=/var/log/mysql/mariadb.log slow_query_log slow_query_log_file=/var/log/mysql/mariadb-slow.log long_query_time=5
We will also need to create the relevant directory:
sudo mkdir /var/log/mysql/ sudo chown mysql:mysql /var/log/mysql/ sudo chmod 0770 /var/log/mysql/
If you are using SELinux, then you may also need to set the SELinux context for the directory. See SELinux: Setting the File Context for Log Files for more information. For example:
sudo semanage fcontext -a -t mysqld_log_t "/var/log/mysql(/.*)?" sudo restorecon -Rv /var/log/mysql
After MariaDB is restarted, it will use the new log locations and file names.
Configuring Authentication for Logrotate
The logrotate
utility needs to be able to authenticate with MariaDB in order to flush the log files.
The easiest way to allow the logrotate
utility to authenticate with MariaDB is to configure the root@localhost
user account to use unix_socket
authentication.
MariaDB starting with 10.4
In MariaDB 10.4 and later, the root@localhost
user account is configured to use unix_socket
authentication by default, so this part can be skipped in those versions.
MariaDB until 10.3
In MariaDB 10.3 and before, a user account is only able to have one authentication method at a time. In these versions, this means that once you enable unix_socket
authentication for the root@localhost
user account, you will no longer be able to use a password to log in with that user account. The user account will only be able to use unix_socket
authentication.
In MariaDB 10.3 and before, you need to install the unix_socket plugin before you can configure the root@localhost
user account to use it. For example:
INSTALL SONAME 'auth_socket';
After the plugin is installed, the root@localhost
user account can be configured to use unix_socket
authentication. How this is done depends on the version of MariaDB.
MariaDB starting with 10.2
In MariaDB 10.2 and later, the root@localhost
user account can be altered to use unix_socket
authentication with the ALTER USER
statement. For example:
ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket;
MariaDB until 10.1
In MariaDB 10.1 and before, the root@localhost
user account can be altered to use unix_socket
authentication with the GRANT
statement. For example:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED VIA unix_socket WITH GRANT OPTION;
Configuring Logrotate
At this point, we can configure the logrotate
utility to rotate the log files.
On many systems, the primary logrotate
configuration file is located at the following path:
/etc/logrotate.conf
And the logrotate
configuration files for individual services are located in the following directory:
/etc/logrotate.d/
We can create a logrotate
configuration file for MariaDB by executing the following command in a shell:
$ sudo tee /etc/logrotate.d/mariadb <<EOF /var/log/mysql/* { su mysql mysql missingok create 660 mysql mysql notifempty daily minsize 1M # only use with logrotate >= 3.7.4 maxsize 100M # only use with logrotate >= 3.8.1 rotate 30 # dateext # only use if your logrotate version is compatible with below dateformat # dateformat .%Y-%m-%d-%H-%M-%S # only use with logrotate >= 3.9.2 compress delaycompress sharedscripts olddir archive/ createolddir 770 mysql mysql # only use with logrotate >= 3.8.9 postrotate # just if mysqld is really running if test -x /usr/bin/mysqladmin && /usr/bin/mysqladmin ping &>/dev/null then /usr/bin/mysqladmin --local flush-error-log flush-engine-log flush-general-log flush-slow-log fi endscript } EOF
You may have to modify this configuration file to use it on your system, depending on the specific version of the logrotate
utility that is installed. See the description of each configuration directive below to determine which logrotate
versions support that configuration directive.
Each specific configuration directive does the following:
missingok
: This directive configures it to ignore missing files, rather than failing with an error.create 660 mysql mysql
: This directive configures it to recreate the log files after log rotation with the specified permissions and owner.notifempty
: This directive configures it to skip a log file during log rotation if it is empty.daily
: This directive configures it to rotate each log file once per day.minsize 1M
: This directive configures it to skip a log file during log rotation if it is smaller than 1 MB. This directive is only available withlogrotate
3.7.4 and later.maxsize 100M
: This directive configures it to rotate a log file more frequently than daily if it grows larger than 100 MB. This directive is only available withlogrotate
3.8.1 and later.rotate 30
: This directive configures it to keep 30 old copies of each log file.dateext
: This directive configures it to use the date as an extension, rather than just a number. This directive is only available withlogrotate
3.7.6 and later.dateformat .%Y-%m-%d-%H-%M-%S
: This directive configures it to use this date format string (as defined by the format specification forstrftime
) for the date extension configured by thedateext
directive. This directive is only available withlogrotate
3.7.7 and later. Support for%H
is only available withlogrotate
3.9.0 and later. Support for%M
and%S
is only available withlogrotate
3.9.2 and later.compress
: This directive configures it to compress the log files withgzip
.delaycompress
: This directive configures it to delay compression of each log file until the next log rotation. If the log file is compressed at the same time that it is rotated, then there may be cases where a log file is being compressed while the MariaDB server is still writing to the log file. Delaying compression of a log file until the next log rotation can prevent race conditions such as these that can happen between the compression operation and the MariaDB server’s log flush operation.olddir archive/
: This directive configures it to archive the rotated log files in/var/log/mysql/archive/
.createolddir 770 mysql mysql
: This directive configures it to create the directory specified by theolddir
directive with the specified permissions and owner, if the directory does not already exist. This directive is only available withlogrotate
3.8.9 and later.sharedscripts
: This directive configures it to run thepostrotate
script just once, rather than once for each rotated log file.postrotate
: This directive configures it to execute a script after log rotation. This particular script executes themysqladmin
utility, which executes theFLUSH
statement, which tells the MariaDB server to flush its various log files. When MariaDB server flushes a log file, it closes its existing file handle and reopens a new one. This ensure that MariaDB server does not continue writing to a log file after it has been rotated. This is an important component of the log rotation process.
If our system does not have logrotate
3.8.9 or later, which is needed to support the createolddir
directive, then we will also need to create the relevant directory specified by the olddir
directive:
sudo mkdir /var/log/mysql/archive/ sudo chown mysql:mysql /var/log/mysql/archive/ sudo chmod 0770 /var/log/mysql/archive/
Testing Log Rotation
We can test log rotation by executing the logrotate
utility with the --force
option. For example:
sudo logrotate --force /etc/logrotate.d/mariadb
Keep in mind that under normal operation, the logrotate
utility may skip a log file during log rotation if the utility does not believe that the log file needs to be rotated yet. For example:
- If you set the
notifempty
directive mentioned above, then it will be configured to skip a log file during log rotation if the log file is empty. - If you set the
daily
directive mentioned above, then it will be configured to only rotate each log file once per day. - If you set the
minsize 1M
directive mentioned above, then it will be configured to skip a log file during log rotation if the log file size is smaller than 1 MB.
However, when running tests with the --force
option, the logrotate
utility does not take these options into consideration.
After a few tests, we can see that the log rotation is indeed working:
$ sudo ls -l /var/log/mysql/archive/ total 48 -rw-rw---- 1 mysql mysql 440 Mar 31 15:31 mariadb.err.1 -rw-rw---- 1 mysql mysql 138 Mar 31 15:30 mariadb.err.2.gz -rw-rw---- 1 mysql mysql 145 Mar 31 15:28 mariadb.err.3.gz -rw-rw---- 1 mysql mysql 1007 Mar 31 15:27 mariadb.err.4.gz -rw-rw---- 1 mysql mysql 1437 Mar 31 15:32 mariadb.log.1 -rw-rw---- 1 mysql mysql 429 Mar 31 15:31 mariadb.log.2.gz -rw-rw---- 1 mysql mysql 439 Mar 31 15:28 mariadb.log.3.gz -rw-rw---- 1 mysql mysql 370 Mar 31 15:27 mariadb.log.4.gz -rw-rw---- 1 mysql mysql 3915 Mar 31 15:32 mariadb-slow.log.1 -rw-rw---- 1 mysql mysql 554 Mar 31 15:31 mariadb-slow.log.2.gz -rw-rw---- 1 mysql mysql 569 Mar 31 15:28 mariadb-slow.log.3.gz -rw-rw---- 1 mysql mysql 487 Mar 31 15:27 mariadb-slow.log.4.gz
Logrotate in Ansible
Let’s see an example of how to configure logrotate in Ansible.
First, we’ll create a couple of tasks in our playbook:
- name: Create mariadb_logrotate_old_dir file: path: "{{ mariadb_logrotate_old_dir }}" owner: mysql group: mysql mode: '770' state: directory - name: Configure logrotate template: src: "../templates/logrotate.j2" dest: "/etc/logrotate.d/mysql"
The first task creates a directory to store the old, compressed logs, and set proper permissions.
The second task uploads logrotate configuration file into the proper directory, and calls it mysql
. As you can see the original name is different, and it ends with the .j2
extension, because it is a Jinja 2 template.
The file will look like the following:
{{ mariadb_log_dir }}/* { su mysql mysql missingok create 660 mysql mysql notifempty daily minsize 1M {{ mariadb_logrotate_min_size }} maxsize 100M {{ mariadb_logrotate_max_size }} rotate {{ mariadb_logrotate_old_dir }} dateformat .%Y-%m-%d-%H-%M-%S # only use with logrotate >= 3.9.2 compress delaycompress sharedscripts olddir archive/ createolddir 770 mysql mysql # only use with logrotate >= 3.8.9 postrotate # just if mysqld is really running if test -x /usr/bin/mysqladmin && /usr/bin/mysqladmin ping &>/dev/null then /usr/bin/mysqladmin --local flush-error-log flush-engine-log flush-general-log flush-slow-log fi endscript }
The file is very similar to the file shown above, which is obvious because we’re still uploading a logrotate configuration file. Ansible is just a tool we’ve chosen to do this.
However, both in the tasks and in the template, we used some variables. This allows to use different paths and rotation parameters for different hosts, or host groups.
If we have a group host called mariadb
that contains the default configuration for all our MariaDB servers, we can define these variables in a file called group_vars/mariadb.yml
:
# MariaDB writes its logs here mariadb_log_dir: /var/lib/mysql/logs # logrotate configuration mariadb_logrotate_min_size: 500M mariadb_logrotate_max_size: 1G mariadb_logrotate_old_files: 7 mariadb_logrotate_old_dir: /var/mysql/old-logs
After setting up logrotate in Ansible, you may want to deploy it to a non-production server and test it manually as explained above. Once you’re sure that it works fine on one server, you can be confident in the new Ansible tasks and deploy them on all servers.
For more information on how to use Ansible to automate MariaDB configuration, see Ansible and MariaDB.
Overview
I find far too often that MySQL error and slow query logs are unaccounted for. Setting up log rotation helps make the logs manageable in the event that they start to fill up and can help make your troubleshooting of issues more efficient.
Setup
All steps in the examples below are run as the root user. The first step is to setup a user that will perform the log rotation. It is recommended to only give enough access to the MySQL user for the task that it is performing.
Create Log Rotate MySQL User
mysql > CREATE USER 'log_rotate'@'localhost' IDENTIFIED BY '<ENTER PASSWORD HERE>'; mysql > GRANT RELOAD,SUPER ON *.* to 'log_rotate'@'localhost'; mysql > FLUSH PRIVILEGES;</pre>
The next step is to setup the MySQL authentication config as root. Here are two methods to set this up. The first method will be the more secure method of storing your MySQL credentials using mysql_config_editor as the credentials are stored encrypted. But this first method is only available with Oracle MySQL or Percona MySQL client greater than 5.5. It is not available with Maria DB MySQL client. Method 2 can be used with pretty much any setup but is less secure as the password is stored in plain text.
Method 1
bash # mysql_config_editor set --login-path=logrotate --host=localhost --user=log_rotate --port 3306 --password
Method 2
bash # vi /root/.my.cnf [client] user=log_rotate password='<ENTER PASSWORD HERE>' bash # chmod 600 /root/.my.cnf
Now we will test to make sure this is working as expected
Method 1
bash # mysqladmin --login-path=logrotate ping
Method 2
bash # mysqladmin ping
The paths for the error and slow query log will need to be gathered in order to place them in the logrotate config file
Method 1
bash # mysql --login-path=logrotate -e "show global variables like 'slow_query_log_file'" bash # mysql --login-path=logrotate -e "show global variables like 'log_error'"
Method 2
bash # mysql -e "show global variables like 'slow_query_log_file'" bash # mysql -e "show global variables like 'log_error'"
Finally we will create the log rotation file with the following content. Make sure to update your error and slow query log paths to match the paths gathered in previous steps. Start by opening up the editor for a new mysql logrotate file in the /etc/logrotate.d directory.
Method 1 Content
bash # vi /etc/logrotate.d/mysql /var/lib/mysql/error.log /var/lib/mysql/slow.queries.log { create 600 mysql mysql daily rotate 30 missingok compress sharedscripts postrotate if test -x /usr/bin/mysqladmin && env HOME=/root /usr/bin/mysqladmin --login-path=logrotate ping > /dev/null 2>&1 then env HOME=/root/ /usr/bin/mysql --login-path=logrotate -e 'select @@global.long_query_time into @lqt_save; set global long_query_time=2000; set global slow_query_log=0; select sleep(2); FLUSH ERROR LOGS; FLUSH SLOW LOGS;select sleep(2); set global [email protected]_save; set global slow_query_log=1;' > /var/log/mysqladmin.flush-logs 2>&1 fi endscript }
Method 2 Content
bash # vi /etc/logrotate.d/mysql /var/lib/mysql/error.log /var/lib/mysql/slow.queries.log { create 600 mysql mysql daily rotate 30 missingok compress sharedscripts postrotate if test -x /usr/bin/mysqladmin && env HOME=/root /usr/bin/mysqladmin ping > /dev/null 2>&1 then env HOME=/root/ /usr/bin/mysql -e 'select @@global.long_query_time into @lqt_save; set global long_query_time=2000; set global slow_query_log=0; select sleep(2); FLUSH ERROR LOGS; FLUSH SLOW LOGS;select sleep(2); set global [email protected]_save; set global slow_query_log=1;' > /var/log/mysqladmin.flush-logs 2>&1 fi endscript }
Validation
For final validation force a log rotate. Update the path in the ls command to match the path of the logs gathered earlier.
bash # logrotate --force /etc/logrotate.d/mysql bash # ls -al /var/lib/mysql
Want to talk with an expert? Schedule a call with our team to get the conversation started.
I am a Junior DBA at Mydbops. This is my first blog professionally, I would like to brief my encounter with Log-rotate in first few weeks of my work, Hope it will help other beginners as well. This Blog will cover the following sections.
-
Introduction to Log-rotate
-
Issues Faced
-
Solutions (Fix for the above issues)
-
Best practices
-
How to configure the Log-rotate
-
Operation of Log-rotate
-
Files responsible for the Log_rotate utility.
-
1.0. Introduction to Log-rotate:
-
Log-rotate is a utility and it plays an important role in retaining the right information generated by process. We have several log files in our system and it keeps growing day by day.
-
As an administrator, We have to properly manage the log files with customised configurations and retention policies depending upon the use cases. To avoid un-necessary disk occupancy.
-
After configuring this Log-rotate, We can Overview the log files easily as the current file will be less size and readable ( with split ). We can also easily track the pattern of logging by the volume of logs generated.
2.0 Issues Faced:
Below are the two main problems related to MySQL Logs we usually face on the servers managed.
-
Improper Configuration of MySQL Audit logs.
The scenario is, Audit logs are internally rotated by MySQL(MariaDB Plugin) and a minimum of 2-3 logs will be generated each day. So standard Log-rotate configuration with stating name won’t work. So They had to use the wildcard operator at the end of the file name (*). Which made all the logs to repeatedly compress again and again.These Audit logs were ended up in corruption. We have to re-configure the log-rotate with optimal configuration.
-
MySQL error logs are not rotated properly.
Another problem is, Though the MySQL error log is rotated, MySQL kept writing to the old file while new file being empty. This can cause confusion and delay in troubleshooting issues at times
3.0. Solutions:
Herewith, I have shared the fixes made for the above 2 issues.
-
Fix 1: Improper Configuration of MySQL Audit logs.
-
Using olddir option, We can move all the Old logs into that mentioned directory with compression.
-
Note: The directory given in the olddir must be already there.
-
/data/audit-log/mysql-audit.log/* {
create 600 mysql mysql
notifempty
daily
rotate 365
dateext
missingok
compress
copytruncate
olddir /data/audit/old_logs
}
-
Fix 2: MySQL error logs are not rotated properly.
-
In MySQL, after every rotation, either the MySQL have to flush the logs or we have to use the copytruncate method. Using this copytruncate option, the Log-rotate daemon will copy the file to another new file and truncate the old file. So this will solve the problem.
-
Note: There is the possibility to lose some milliseconds of logs when using copytruncate. The suggestion is schedule the non-traffic time for rotation in “/etc/cron.d/”
-
/var/lib/mysql/mysqld.log {
su mysql mysql
create 600 mysql mysql
notifempty
daily
rotate 5
missingok
compress
copytruncate
postrotate
# just if mysqld is really running
if test -x /usr/bin/mysqladmin &&
/usr/bin/mysqladmin ping &>/dev/null
then
/usr/bin/mysqladmin flush-logs
fi
endscript
}
-
For better understanding about the Log-rotate, operation and how to configure the Log-rotate, Check the below section also.
4.0. Best Practices:
4.1. Configuration file:
-
The Log-rotate can be configured in the 2 different places.
-
One is within “/etc/logrotate.conf” file
-
Other is create a Log-rotate file inside the “/etc/logrotate.d/” directory.
-
-
Let’s see one simple example- Rotate the slow log of MySQL
- This file is placed at /etc/logrotate.d/mysql
/var/lib/mysql/slow_log {
create 640 mysql mysql
hourly
dateext
rotate 5
compress
olddir /var/lib/mysql/old_slowlogs
postrotate
# just if mysqld is really running
if test -x /usr/bin/mysqladmin &&
/usr/bin/mysqladmin ping &>/dev/null
then
/usr/bin/mysqladmin flush-logs
fi
endscript
}
-
The definitions for the above options are explained in the operation section.
4.2. Operations:
-
Normally, Log-rotate systematically rotates and archive the system logs.
-
By default, it will rotate once a day using a cron scheduler ‘/etc/cron.daily/logrotate’ (or) else it will rotate depending on which option is mentioned in the configuration, it is actually a shell script.
-
Some of the configuration options are given below,
-
Daily – Rotate the file daily.
-
Hourly – Rotate the file hourly. [Other options – Weekly, Yearly]
-
Size – Log file will Rotate when it reached the mentioned size.
-
Dateext – Rotated files will get the extension of the date [yyyymmdd]
-
Rotate <n> – ‘n’ number of files to keep in the server
-
Create perm – Create the new file in the mentioned permission
-
Compress – Compress the rotated files. [uses gzip compression]
-
Copytruncate – Copy the active file to another one and truncate the active file.
-
Olddir <dir> – The rotated files will be sent to the mentioned directory if that directory is already present.
-
Postrotate – Actions mentioned inside this section will execute after the each and every rotate takes place
-
Endscript – Used to end the Postrotate, Last action etc…
-
-
For the MySQL slow log above configuration, the log file will rotate hourly. Rotate will keep 5 Log files. The new file will be created in the name of ‘slow_log’, the old file will be converted to ‘slow_log.1’.
- This process will continue and the old file changes its name by ‘slow_log.2’, ‘slow_log.3’, . . . etc.
-
Let’s see the output of the above Log-rotate for slow-log configuration
-rw-r-----. 1 mysql mysql 371 Jan 21 13:01 slow_log-2019012114.gz
-rw-r-----. 1 mysql mysql 361 Jan 21 14:01 slow_log-2019012115.gz
-rw-r-----. 1 mysql mysql 372 Jan 21 15:01 slow_log-2019012116.gz
-rw-r-----. 1 mysql mysql 360 Jan 21 16:01 slow_log-2019012117.gz
-rw-r-----. 1 mysql mysql 369 Jan 21 17:01 slow_log-2019012118.gz
-rw-r-----. 1 mysql mysql 596 Jan 21 18:01 slow_log
-
Since the dateext option was used, the rotated files get the extension of date format and compress option is to compress the rotated file with gzip and It keeps 5 slow_logs.
-
The “/var/lib/logrotate/status” file will be created, when the /etc/cron.daily/logrotate runs. It records the date and time when the log files are rotated. (i.e) logs for Log-rotate.
-
The executable file of Log-rotate is “/usr/sbin/logrotate”.
-
Log-rotate has many configurations. So we can customize it to get the desired rotated output.
-
Actions to be taken while you using hourly in the config file are clearly explained the below section.
Changes have to done while using the hourly option:
Steps To be Followed:
- Configure logrotate config at /etc/logrotate.d/
- Configure the logrotate with the above config in /etc/cron.hourly
- Setup the cron.hourly in /etc/cron.d/
Step 1:
- We have already completed Step 1, /etc/logrotate.d/mysql is saved as given in example above.
Step 2:
-
By default, Log-rotate will happen daily. But if you are using hourly in your Log-rotate, below actions have to be taken.
-
Copy Log-rotate file from cron.daily to cron.hourly
cp /etc/cron.daily/logrotate /etc/cron.hourly/
-
Inside the /etc/cron.hourly/logrotate, specify the Log-rotate file in the below-highlighted area
!/bin/sh
/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.d/mysql
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"fi
exit 0
Step 3:
-
Save the rotate time below in the file at cron.d. say, /etc/cron.d/0hourly
01 * * * * root /etc/cron.hourly
-
After all the modifications done, restart the cron service.
sudo systemctl restart crond
The above steps can also be applicable for the weekly or yearly options.
5.0. Conclusion:
Proper configuration of Log-rotate for log files helps us to keep up the database hygiene, It will also provide better readability when troubleshooting the issue.
For better utilization of logs, We can use log pull and aggregation tools such as using Logstash, Datadog etc.
Published by Vignesh Prabhu
Working as a MySQL Junior DBA in MYDBOPS.
Interested to learn and share the things about Linux and MySQL.
View all posts by Vignesh Prabhu
Published
January 30, 2019January 31, 2019
MySQL Server generates several logs that can help you monitor the activities of the server. However, once these logs are enabled, they can grow in size and start taking up too much disk space. This is why it’s important to have an automated way of archiving and preserving MySQL log files for a certain duration, as well as deleting the old ones. In this blog post, we describe some best practices for setting up and managing MySQL error logs, general logs and slow query logs for your MySQL deployments.
Setting Up MySQL Server Logging
Let’s look at how to setup the following 3 types of logs:
Error Log
Logs all the problems encountered during starting, running, or stopping mysqld. This log can be enabled by having the following option in /etc/my.cnf file:
- log_error=/var/log/mysql/mysqld.log
General Query Log
Logs established client connections and statements received from clients. This log can be enabled by having the following option in /etc/my.cnf file:
- general_log=ON
- general_log_file=/var/log/mysql/general.log
Slow Query Log
Logs queries that took more than long_query_time seconds to execute. This log can be enabled by the following option in /etc/my.cnf file:
- slow_query_log=ON
- slow_query_log_file=/var/log/mysql/mysql-slowquery.log
Setting Up Criteria For Log Rotation
As an example, let’s have some criteria for managing general MySQL query logs. We can come up with a suitable set of criteria for log management by asking the following questions:
Q: What is the maximum size that the log file can grow?
A: Let’s say it can grow up to 300 MB after which it needs to be rotated and compressed.
Q: What is the frequency that you want the log file to be rotated?
A: We can say that we want logs to be rotated on a daily basis.
Q: How many old log files you want to retain?
A: We would like to retain the last 30 log files.
Based on the above criteria, the overall disk space required for general query log management is about 1.2 GB. Assuming a 90% compression ratio – we will have 30 compressed log files of size 30 MB each and a live log file of about 300 MB.
Managing MySQL Server Logs: Rotate, Compress, Retain & DeleteClick To Tweet
Managing The Logs Using Linux logrotate Utility
logrotate is a Linux utility that helps with the efficient administration of log files and provides options for automatic rotation, compression, and removal of log files. The criteria established above can be configured for logrotate utility by creating a configuration file in the /etc/logrotate.d folder.
Let’s call this configuration file mysqlgeneral and the contents of the file will be:
/var/log/mysql/general.log{
compress
dateext
maxsize 300M
copytruncate
maxage 365
dateformat -%Y%m%d%s
daily
rotate 30
notifempty
}
With the above options for logrotate, the general query logs get rotated either on a daily basis or when the log file size exceeds 300 MB. The old logs are compressed and 30 such files will be preserved. Log rotation will be skipped if the log file is empty due to the setting ‘notifempty’.
The ‘copytruncate’ option is to ensure that current log file is never deleted during rotation and only its contents get truncated. This is important since some applications expect that the log file is always available and it’s not possible to delete the log without stopping the application first.
Now that the log rotation configuration is set for the general query log, the logrotate utility has to be run so that the above configuration is executed. This is typically done through a cron job. We can set this to be running every hour by placing the logrotate script in /etc/cron.hourly directory:
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
So, with a few simple steps, we have set up log rotation for MySQL general logs based on our criteria. The same approach can be followed for MySQL error logs and slow query logs as well. Check out these other posts to learn more about optimizing your MySQL deployments:
- Calculating InnoDB Buffer Pool Size for your MySQL Server
- MySQL Tutorial – Configuring and Managing SSL On Your MySQL Server
- MySQL High Availability Framework Explained – Part I: Introduction
Журналы событий — первый и самый простой инструмент для определения статуса системы и выявления ошибок. Основных логов в MySQL четыре:
- Error Log — стандартный лог ошибок, которые собираются во время работы сервера (в том числе start и stop);
- Binary Log — лог всех команд изменения БД, нужен для репликации и бэкапов;
- General Query Log — основной лог запросов;
- Slow Query Log — лог медленных запросов.
Лог ошибок
Этот журнал содержит все ошибки, которые произошли во время работы сервера, включая критические ошибки, а также остановки, включения сервера и предупреждения (warnings). С него нужно начать в случае сбоя системы. По умолчанию все ошибки выводятся в консоль (stderr), также можно записывать ошибки в syslog (по умолчанию в Debian) или отдельный лог-файл:
log_error=/var/log/mysql/mysql_error.log |
Рекомендуем держать этот журнал включенным для быстрого определения ошибок. А для понимания, что значит та или иная ошибка, в MySQL присутствует утилита perror:
shell> perror 13 64 OS error code 13: Permission denied OS error code 64: Machine is not on the network |
Бинарный (он же двоичный) лог
В бинарный лог записываются все команды изменения базы данных, пригодится для репликации и восстановления.
Включается так:
log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 5 max_binlog_size = 500M |
Учтите, что если вы не собираетесь масштабировать систему и реализовывать отказоустойчивость, то бинарный лог лучше не включать. Он требователен к ресурсам и снижает производительность системы.
Лог запросов
В этом журнале содержатся все полученные SQL-запросы, информация о подключениях клиентов. Может пригодиться для анализа индексов и оптимизации, а также выявления ошибочных запросов:
general_log_file = /var/log/mysql/mysql.log <b>general_log = 1</b> |
Также его можно включить/отключить во время работы сервера MySQL:
SET GLOBAL general_log = ‘ON‘; SET GLOBAL general_log = ‘OFF‘; |
Лог медленных запросов
Журнал пригодится для определения медленных, то есть неэффективных запросов. Подробнее читайте в этой статье.
Просмотр логов
Для просмотра логов на Debian (Ubuntu) нужно выполнить:
# Лог ошибок tail -f /var/log/syslog <span class=«comment»> #Лог запросов </span>tail -f /var/log/mysql/mysql.log <span class=«comment»> # Лог медленных запросов </span>tail -f /var/log/mysql/mysql-slow.log |
Ротация логов
Не забывайте сжимать (архивировать, ротировать) файлы логов, чтобы они занимали меньше места на сервере. Для этого используйте утилиту logrotate, отредактировав файл конфигурации /etc/logrotate.d/mysql-server:
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 |
# — I put everything in one block and added sharedscripts, so that mysql gets <span class=«comment»> # flush-logs’d only once. </span># Else the binary logs would automatically increase by n times every day. <span class=«comment»> # — The error log is obsolete, messages go to syslog now. </span><b>/var/log/mysql.log /var/log/mysql/mysql.log /var/log/mysql/mysql-slow.log</b> { daily rotate 7 missingok create 640 mysql adm compress sharedscripts postrotate test -x /usr/bin/mysqladmin || exit 0 <span class=«comment»> # If this fails, check debian.conf! </span> MYADMIN=«/usr/bin/mysqladmin —defaults-file=/etc/mysql/debian.cnf» if [ -z «`$MYADMIN ping 2>/dev/null`» ]; then <span class=«comment»> # Really no mysqld or rather a missing debian-sys-maint user? </span> <span class=«comment»> # If this occurs and is not an error please report a bug. </span> <span class=«comment»> #if ps cax | grep -q mysqld; then </span> if killall -q -s0 -umysql mysqld; then exit 1 fi else $MYADMIN flush-logs fi endscript } |
DDL Log
MySQL также ведет лог языка описания данных. В него собираются данные операций типа DROP_TABLE and ALTER_TABLE. Лог используется для восстановления после сбоев, которые произошли во время выполнения таких операций. DDL Log — бинарный файл, не предназначенный для чтения пользователем, поэтому не модифицируйте и не удаляйте его.
Самое главное
Всегда включайте лог ошибок, используйте лог запросов для проверки соединения приложения с базой данных, проверки запросов и работы memcached. Лог медленных запросов пригодится для оптимизации работы MySQL.
https://github.com/midnight47/
Всем привет! Заметка будет краткой, так как не хочу открывать лишние вкладки, для того чтобы вспомнить, где и как включать логи. Ниже будет описание о том, какие логи есть (кратко) и как их включить (емко).
Лог ошибок — Error Log
Если необходимо понять, по какой причине не запускается MySql сервер — error log вам в помощь. Там же еще можно прочесть сообщения о том,
По умолчанию все ошибки выводятся в консоль (stderr), в Debian ошибки пишутся в syslog, но по хорошему было бы неплохо вести этот лог в отдельном файле, а именно:
/var/log/mysql/mysql_error.log
Как его перенести?
открыв файл /etc/mysql/my.conf я нашел следующую строчку:
Error logging goes to syslog due to /etc/mysql/conf.d/mysqld_safe_syslog.cnf.
Ок, полез в файл /etc/mysql/conf.d/mysqld_safe_syslog.cnf — там следующее содержимое:
[mysqld_safe] syslog
Поняв, что все льется в syslog, я закомментировал syslog и добавил следующую строку:
log_error=/var/log/mysql/mysql_error.log
Все, логи пишутся куда нужно, и я спокоен.
ps.: Для того, чтобы понять что означают те или иные ошибки, можно воспользоваться такой штукой, как perror.
Двоичный («bin’арный») лог.
В этот лог записываются все команды изменения БД, и нужен он для репликации и восстановления. Включать его не рекомендуется, если никакой репликации не планируется, так как он требователен к ресурсам.
Включается он в файле /etc/mysql/my.conf, там нужно разкомментрировать следующие строки:
log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 5 max_binlog_size = 500M
Подробнее:
- log_bin — расположение;
- expire_logs_days — срок жизни;
- max_binlog_size — максимальный размер файла.
Лог медленных запросов — mysql-slow.log.
Он будет содержать в себе запросы, которые очень нуждаются в оптимизации. По умолчанию он отключен, включается в том же /etc/mysql/my.cnf.
Если версия MySql у вас < 5.7, то в нужно исправить следующие настройки:
log_slow_queries = /var/log/mysql/mysql-slow.log long_query_time = 1
Если версия MySql у вас > или = 5.7, то нужно исправить следующие настройки:
slow_query_log = /var/log/mysql/mysql-slow.log long_query_time = 1
Подробнее:
- log_slow_queries (slow_query_log) — путь к файлу настроек;
- long_query_time — минимальное время выполнения запроса в секундах, после которого он считается медленным.
Лог всех запросов.
Пригодиться он опять же для оптимизации и выявления ошибочных запросов, так как записывает все запросы. по умолчанию отключен. Включаем там же: /etc/mysql/my.cnf.
Настройки нужно исправить на подобные:
general_log_file = /var/log/mysql/mysql.log general_log = 1
Подробнее:
- general_log_file — месторасположение
- general_log — включение лога
Включить этот лог «на лету», без перезагрузки, мы можем и из консоли «mysql»:
SET GLOBAL general_log = 'ON'; SET GLOBAL general_log = 'OFF';
Не забываем про logrotate.
Дополнено 04/12/2017…
Как я и обещал в какой-то другой статье — «возможно статья будет дополняться».
Во первых про LogRotate, приведу скрипт который используется у меня:
cat /etc/logrotate.d/mysql-server # - 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 }
Как вы уже поняли, он стандартный, и он прекрасно справляется со своей работой.
Нагрузка на БД
Кроме того у меня возникал вопрос: «Скажите пожалуйста какими командами в SSH вычисляется нагрузка на БД ?«..
Собственно все это можно посмотреть хоть в phpmyadmin, но так же никто не запрещает воспользоваться консольным клиентом MySQL, который так и называется: mysql
Для того, чтобы в него попасть, необходимо ввести следующую команду, а после пароль
[[email protected] ]# mysql -u root -p -h localhost Enter password: Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 7926 Server version: 5.0.45 Source distribution Type 'help;' or 'h' for help. Type 'c' to clear the buffer. mysql>
все, вы в него попали
Там мне были полезны две команды:
show status — команда предоставляет информацию по состоянию сервера.
Пример ее вывода
mysql> show status; +-----------------------------------------------+-------------+ | Variable_name | Value | +-----------------------------------------------+-------------+ | Aborted_clients | 0 | | Aborted_connects | 1 | | Binlog_cache_disk_use | 0 | | Binlog_cache_use | 0 | | Binlog_stmt_cache_disk_use | 0 | | Binlog_stmt_cache_use | 0 | | Bytes_received | 272 | | Bytes_sent | 509 | | Com_admin_commands | 0 | | Com_assign_to_keycache | 0 | | Com_alter_db | 0 | | Com_alter_db_upgrade | 0 | | Com_alter_event | 0 | | Com_alter_function | 0 | | Com_alter_procedure | 0 | | Com_alter_server | 0 | | Com_alter_table | 0 | | Com_alter_tablespace | 0 | | Com_alter_user | 0 | | Com_analyze | 0 | | Com_begin | 0 | | Com_binlog | 0 | | Com_call_procedure | 0 | | Com_change_db | 0 | | Com_change_master | 0 | | Com_check | 0 | | Com_checksum | 0 | | Com_commit | 0 | | Com_create_db | 0 | | Com_create_event | 0 | | Com_create_function | 0 | | Com_create_index | 0 | | Com_create_procedure | 0 | | Com_create_server | 0 | | Com_create_table | 0 | | Com_create_trigger | 0 | | Com_create_udf | 0 | | Com_create_user | 0 | | Com_create_view | 0 | | Com_dealloc_sql | 0 | | Com_delete | 0 | | Com_delete_multi | 0 | | Com_do | 0 | | Com_drop_db | 0 | | Com_drop_event | 0 | | Com_drop_function | 0 | | Com_drop_index | 0 | | Com_drop_procedure | 0 | | Com_drop_server | 0 | | Com_drop_table | 0 | | Com_drop_trigger | 0 | | Com_drop_user | 0 | | Com_drop_view | 0 | | Com_empty_query | 0 | | Com_execute_sql | 0 | | Com_flush | 0 | | Com_get_diagnostics | 0 | | Com_grant | 0 | | Com_ha_close | 0 | | Com_ha_open | 0 | | Com_ha_read | 0 | | Com_help | 0 | | Com_insert | 0 | | Com_insert_select | 0 | | Com_install_plugin | 0 | | Com_kill | 0 | | Com_load | 0 | | Com_lock_tables | 0 | | Com_optimize | 0 | | Com_preload_keys | 0 | | Com_prepare_sql | 0 | | Com_purge | 0 | | Com_purge_before_date | 0 | | Com_release_savepoint | 0 | | Com_rename_table | 0 | | Com_rename_user | 0 | | Com_repair | 0 | | Com_replace | 0 | | Com_replace_select | 0 | | Com_reset | 0 | | Com_resignal | 0 | | Com_revoke | 0 | | Com_revoke_all | 0 | | Com_rollback | 0 | | Com_rollback_to_savepoint | 0 | | Com_savepoint | 0 | | Com_select | 1 | | Com_set_option | 0 | | Com_signal | 0 | | Com_show_binlog_events | 0 | | Com_show_binlogs | 0 | | Com_show_charsets | 0 | | Com_show_collations | 0 | | Com_show_create_db | 0 | | Com_show_create_event | 0 | | Com_show_create_func | 0 | | Com_show_create_proc | 0 | | Com_show_create_table | 0 | | Com_show_create_trigger | 0 | | Com_show_databases | 0 | | Com_show_engine_logs | 0 | | Com_show_engine_mutex | 0 | | Com_show_engine_status | 0 | | Com_show_events | 0 | | Com_show_errors | 0 | | Com_show_fields | 0 | | Com_show_function_code | 0 | | Com_show_function_status | 0 | | Com_show_grants | 0 | | Com_show_keys | 0 | | Com_show_master_status | 0 | | Com_show_open_tables | 0 | | Com_show_plugins | 0 | | Com_show_privileges | 0 | | Com_show_procedure_code | 0 | | Com_show_procedure_status | 0 | | Com_show_processlist | 1 | | Com_show_profile | 0 | | Com_show_profiles | 0 | | Com_show_relaylog_events | 0 | | Com_show_slave_hosts | 0 | | Com_show_slave_status | 0 | | Com_show_status | 1 | | Com_show_storage_engines | 0 | | Com_show_table_status | 0 | | Com_show_tables | 0 | | Com_show_triggers | 0 | | Com_show_variables | 0 | | Com_show_warnings | 0 | | Com_slave_start | 0 | | Com_slave_stop | 0 | | Com_stmt_close | 0 | | Com_stmt_execute | 0 | | Com_stmt_fetch | 0 | | Com_stmt_prepare | 0 | | Com_stmt_reprepare | 0 | | Com_stmt_reset | 0 | | Com_stmt_send_long_data | 0 | | Com_truncate | 0 | | Com_uninstall_plugin | 0 | | Com_unlock_tables | 0 | | Com_update | 0 | | Com_update_multi | 0 | | Com_xa_commit | 0 | | Com_xa_end | 0 | | Com_xa_prepare | 0 | | Com_xa_recover | 0 | | Com_xa_rollback | 0 | | Com_xa_start | 0 | | Compression | OFF | | Connection_errors_accept | 0 | | Connection_errors_internal | 0 | | Connection_errors_max_connections | 0 | | Connection_errors_peer_address | 0 | | Connection_errors_select | 0 | | Connection_errors_tcpwrap | 0 | | Connections | 5 | | Created_tmp_disk_tables | 0 | | Created_tmp_files | 6 | | Created_tmp_tables | 0 | | Delayed_errors | 0 | | Delayed_insert_threads | 0 | | Delayed_writes | 0 | | Flush_commands | 1 | | Handler_commit | 0 | | Handler_delete | 0 | | Handler_discover | 0 | | Handler_external_lock | 0 | | Handler_mrr_init | 0 | | Handler_prepare | 0 | | Handler_read_first | 0 | | Handler_read_key | 0 | | Handler_read_last | 0 | | Handler_read_next | 0 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 0 | | Handler_rollback | 0 | | Handler_savepoint | 0 | | Handler_savepoint_rollback | 0 | | Handler_update | 0 | | Handler_write | 0 | | Innodb_buffer_pool_dump_status | not started | | Innodb_buffer_pool_load_status | not started | | Innodb_buffer_pool_pages_data | 323 | | Innodb_buffer_pool_bytes_data | 5292032 | | Innodb_buffer_pool_pages_dirty | 0 | | Innodb_buffer_pool_bytes_dirty | 0 | | Innodb_buffer_pool_pages_flushed | 1 | | Innodb_buffer_pool_pages_free | 7866 | | Innodb_buffer_pool_pages_misc | 2 | | Innodb_buffer_pool_pages_total | 8191 | | Innodb_buffer_pool_read_ahead_rnd | 0 | | Innodb_buffer_pool_read_ahead | 0 | | Innodb_buffer_pool_read_ahead_evicted | 0 | | Innodb_buffer_pool_read_requests | 2642 | | Innodb_buffer_pool_reads | 324 | | Innodb_buffer_pool_wait_free | 0 | | Innodb_buffer_pool_write_requests | 1 | | Innodb_data_fsyncs | 5 | | Innodb_data_pending_fsyncs | 0 | | Innodb_data_pending_reads | 0 | | Innodb_data_pending_writes | 0 | | Innodb_data_read | 5378048 | | Innodb_data_reads | 336 | | Innodb_data_writes | 5 | | Innodb_data_written | 34304 | | Innodb_dblwr_pages_written | 1 | | Innodb_dblwr_writes | 1 | | Innodb_have_atomic_builtins | ON | | Innodb_log_waits | 0 | | Innodb_log_write_requests | 0 | | Innodb_log_writes | 1 | | Innodb_os_log_fsyncs | 3 | | Innodb_os_log_pending_fsyncs | 0 | | Innodb_os_log_pending_writes | 0 | | Innodb_os_log_written | 512 | | Innodb_page_size | 16384 | | Innodb_pages_created | 0 | | Innodb_pages_read | 323 | | Innodb_pages_written | 1 | | Innodb_row_lock_current_waits | 0 | | Innodb_row_lock_time | 0 | | Innodb_row_lock_time_avg | 0 | | Innodb_row_lock_time_max | 0 | | Innodb_row_lock_waits | 0 | | Innodb_rows_deleted | 0 | | Innodb_rows_inserted | 0 | | Innodb_rows_read | 0 | | Innodb_rows_updated | 0 | | Innodb_num_open_files | 5 | | Innodb_truncated_status_writes | 0 | | Innodb_available_undo_logs | 128 | | Key_blocks_not_flushed | 0 | | Key_blocks_unused | 13396 | | Key_blocks_used | 0 | | Key_read_requests | 0 | | Key_reads | 0 | | Key_write_requests | 0 | | Key_writes | 0 | | Last_query_cost | 0.000000 | | Last_query_partial_plans | 0 | | Max_used_connections | 1 | | Not_flushed_delayed_rows | 0 | | Open_files | 16 | | Open_streams | 0 | | Open_table_definitions | 67 | | Open_tables | 60 | | Opened_files | 115 | | Opened_table_definitions | 0 | | Opened_tables | 0 | | Performance_schema_accounts_lost | 0 | | Performance_schema_cond_classes_lost | 0 | | Performance_schema_cond_instances_lost | 0 | | Performance_schema_digest_lost | 0 | | Performance_schema_file_classes_lost | 0 | | Performance_schema_file_handles_lost | 0 | | Performance_schema_file_instances_lost | 0 | | Performance_schema_hosts_lost | 0 | | Performance_schema_locker_lost | 0 | | Performance_schema_mutex_classes_lost | 0 | | Performance_schema_mutex_instances_lost | 0 | | Performance_schema_rwlock_classes_lost | 0 | | Performance_schema_rwlock_instances_lost | 0 | | Performance_schema_session_connect_attrs_lost | 0 | | Performance_schema_socket_classes_lost | 0 | | Performance_schema_socket_instances_lost | 0 | | Performance_schema_stage_classes_lost | 0 | | Performance_schema_statement_classes_lost | 0 | | Performance_schema_table_handles_lost | 0 | | Performance_schema_table_instances_lost | 0 | | Performance_schema_thread_classes_lost | 0 | | Performance_schema_thread_instances_lost | 0 | | Performance_schema_users_lost | 0 | | Prepared_stmt_count | 0 | | Qcache_free_blocks | 1 | | Qcache_free_memory | 16759680 | | Qcache_hits | 0 | | Qcache_inserts | 0 | | Qcache_lowmem_prunes | 0 | | Qcache_not_cached | 1 | | Qcache_queries_in_cache | 0 | | Qcache_total_blocks | 1 | | Queries | 8 | | Questions | 3 | | Select_full_join | 0 | | Select_full_range_join | 0 | | Select_range | 0 | | Select_range_check | 0 | | Select_scan | 0 | | Slave_heartbeat_period | | | Slave_last_heartbeat | | | Slave_open_temp_tables | 0 | | Slave_received_heartbeats | | | Slave_retried_transactions | | | Slave_running | OFF | | Slow_launch_threads | 0 | | Slow_queries | 0 | | Sort_merge_passes | 0 | | Sort_range | 0 | | Sort_rows | 0 | | Sort_scan | 0 | | Ssl_accept_renegotiates | 0 | | Ssl_accepts | 0 | | Ssl_callback_cache_hits | 0 | | Ssl_cipher | | | Ssl_cipher_list | | | Ssl_client_connects | 0 | | Ssl_connect_renegotiates | 0 | | Ssl_ctx_verify_depth | 0 | | Ssl_ctx_verify_mode | 0 | | Ssl_default_timeout | 0 | | Ssl_finished_accepts | 0 | | Ssl_finished_connects | 0 | | Ssl_server_not_after | | | Ssl_server_not_before | | | Ssl_session_cache_hits | 0 | | Ssl_session_cache_misses | 0 | | Ssl_session_cache_mode | NONE | | Ssl_session_cache_overflows | 0 | | Ssl_session_cache_size | 0 | | Ssl_session_cache_timeouts | 0 | | Ssl_sessions_reused | 0 | | Ssl_used_session_cache_entries | 0 | | Ssl_verify_depth | 0 | | Ssl_verify_mode | 0 | | Ssl_version | | | Table_locks_immediate | 70 | | Table_locks_waited | 0 | | Table_open_cache_hits | 0 | | Table_open_cache_misses | 0 | | Table_open_cache_overflows | 0 | | Tc_log_max_pages_used | 0 | | Tc_log_page_size | 0 | | Tc_log_page_waits | 0 | | Threads_cached | 0 | | Threads_connected | 1 | | Threads_created | 1 | | Threads_running | 1 | | Uptime | 147542 | | Uptime_since_flush_status | 147542 | +-----------------------------------------------+-------------+ 341 rows in set (0,00 sec)
Подробное описание команды
Команда SHOW STATUS предоставляет информацию по состоянию сервера (как mysqladmin extended-status). Приведенные выше переменные состояния имеют следующие значения:
- Aborted_clients — Количество соединений, отмененных по причине отключения клиента без надлежащего закрытия соединения. See Раздел A.2.9, «Коммуникационные ошибки / Оборванные соединения».
- Aborted_connects — Количество неудачных попыток подсоединения к серверу MySQL. See Раздел A.2.9, «Коммуникационные ошибки / Оборванные соединения».
- Bytes_received — Количество байтов, полученных от всех клиентов.
- Bytes_sent — Количество байтов, отправленных всем клиентам.
- Com_xxx — Количество запусков каждой команды xxx.
- Connections — Количество попыток подсоединения к серверу MySQL.
- Created_tmp_tables — Количество неявных временных таблиц на диске, созданных во время выполнения операторов.
- Created_tmp_tables — Количество неявных временных таблиц в памяти, созданных во время выполнения операторов.
- Created_tmp_files — Количество созданных временных файлов mysqld.
- Delayed_insert_threads — Количество используемых потоков вставки данных в режиме insert delayed.
- Delayed_writes — Количество строк, вставленных при помощи команды INSERT DELAYED.
- Delayed_errors — Количество записанных при помощи команды INSERT DELAYED строк, в которых произошли какие-либо ошибки (возможно, duplicate key).
- Flush_commands — Количество запущенных команд FLUSH.
- Handler_commit — Количество внутренних команд COMMIT.
- Handler_delete — Количество удалений строки из таблицы.
- Handler_read_first — Количество считываний из индекса первой записи. Если это значение высокое, то, по всей вероятности, сервер осуществляет много полных индексных сканирований, например, SELECT col1 FROM foo, предполагая, что col1 проиндексирован.
- Handler_read_key — Количество запросов на чтение строки, основанных на ключе. Высокое значение переменной говорит о том, что ваши запросы и таблицы проиндексированы надлежащим образом.
- Handler_read_next — Количество запросов на чтение следующей строки в порядке расположения ключей. Это значение будет увеличиваться, если производится запрос индексного столбца с ограничением по размеру. Значение также увеличивается во время проведения индексного сканирования.
- Handler_read_prev — Количество запросов на чтение предыдущей строки в порядке расположения ключей. В большинстве случаев используется для оптимизации ORDER BY … DESC.
- Handler_read_rnd — Количество запросов на чтение строки, основанных на фиксированной позиции. Значение будет высоким, если выполняется много запросов, требующих сортировки результатов.
- Handler_read_rnd_next — Количество запросов на чтение следующей строки из файла данных. Данное значение будет высоким, если производится много сканирований таблиц. Обычно это означает, что ваши таблицы не проиндексированы надлежащим образом или ваши запросы не используют преимущества индексов.
- Handler_rollback — Количество внутренних команд ROLLBACK.
- Handler_update — Количество запросов на обновление строки в таблице.
- Handler_write — Количество запросов на вставку строки в таблицу.
- Key_blocks_used — Количество используемых блоков в кэше ключей.
- Key_read_requests — Количество запросов на чтение блока ключей из кэша.
- Key_reads — Количество физических считываний блока ключей с диска.
- Key_write_requests — Количество запросов на запись блока ключей в кэш.
- Key_writes — Количество физических записей блоков ключей на диск.
- Max_used_connections — Максимальное количество одновременно используемых соединений.
- Not_flushed_key_blocks — Блоки ключей в кэше ключей, которые были изменены, но еще не записаны на диск.
- Not_flushed_delayed_rows — Количество строк, стоящих в очереди на запись в запросах INSERT DELAY.
- Open_tables — Количество открытых таблиц.
- Open_files — Количество открытых файлов.
- Open_streams — Количество открытых потоков (в основном используется для журналирования).
- Opened_tables — Количество открывавшихся таблиц.
- Rpl_status — Статус отказобезопасной репликации (еще не используется).
- Select_full_join — Количество соединений без ключей (если это значение равно 0, необходимо внимательно проверить индексы своих таблиц).
- Select_full_range_join — Количество соединений, где был использован поиск по диапазону в справочной таблице.
- Select_range — Количество соединений, в которых использовались диапазоны в первой таблице. (Обычно это значение не критично, даже если оно велико)
Select_scan — Количество соединений, в которых проводилось первое сканирование первой таблицы. - Select_range_check — Количество соединений без ключей, в которых проверка использования ключей производится после каждой строки (если это значение равно 0, необходимо внимательно проверить индексы своих таблиц).
- Questions — Количество запросов, направленных на сервер.
- Slave_open_temp_tables — Количество временных таблиц, открытых в настоящий момент потоком подчиненного компьютера.
- Slave_running — Содержит значение ON, если это подчиненный компьютер, подключенный к головному компьютеру.
- Slow_launch_threads — Количество потоков, создание которых заняло больше, чем указано в slow_launch_time.
- Slow_queries — Количество запросов, обработка которых заняла больше времени, чем long_query_time. See Раздел 4.9.5, «Журнал медленных запросов».
- Sort_merge_passes — Количество объединений, осуществленных алгоритмом сортировки. Если это значение велико, следует увеличить sort_buffer_size.
- Sort_range — Количество сортировок, которые осуществлялись в диапазонах.
- Sort_rows — Количество отсортированных строк.
- Sort_scan — Количество сортировок, осуществленных путем сканирования таблицы.
- ssl_xxx — Переменные, используемые SSL; еще не реализовано.
- Table_locks_immediate — Количество запросов на немедленную блокировку таблицы. Доступно начиная с версии 3.23.33.
- Table_locks_waited — Количество запросов, когда немедленная блокировка не могла быть осуществлена и требовалось время на ожидание. Если это значение велико, и у вас есть проблемы с производительностью, сначала необходимо оптимизировать свои запросы, а затем либо разделить таблицы, либо использовать репликацию. Доступно начиная с версии 3.23.33.
- Threads_cached — Количество потоков в кэше потоков.
- Threads_connected — Количество открытых в настоящий момент соединений.
- Threads_created — Количество потоков, созданных для управления соединениями.
- Threads_running — Количество не простаивающих потоков.
- Uptime — Время в секундах, в течение которого сервер находится в работе.
Некоторые примечания к приведенной выше информации:
- Если значение Opened_tables велико, возможно, что значение переменной table_cache слишком мало.
- Если значение Key_reads велико, возможно, что значение переменной key_buffer_size слишком мало. Частоту неуспешных обращений к кэшу можно вычислить так: Key_reads/Key_read_requests.
- Если значение Handler_read_rnd велико, возможно, поступает слишком много запросов, требующих от MySQL полного сканирования таблиц или у вас есть соединения, которые не используют ключи надлежащим образом.
- Если значение Threads_created велико, возможно, необходимо увеличить значение переменной thread_cache_size. Частоту успешных обращений к кэшу можно вычислить при помощи Threads_created/Connections.
- Если значение Created_tmp_disk_tables велико, возможно, необходимо увеличить значение переменной tmp_table_size, чтобы временные таблицы располагались в памяти, а не на жестком диске.
show processlist — показывает, какие потоки запущены в настоящий момент. Пример ее вывода:
mysql> show processlist; +----+------+-----------+------+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+------+---------+------+-------+------------------+ | 4 | root | localhost | NULL | Query | 0 | init | show processlist | +----+------+-----------+------+---------+------+-------+------------------+ 1 row in set (0,00 sec)
Подробное описание команды
Команда SHOW [FULL] PROCESSLIST показывает, какие потоки запущены в настоящий момент. Эту информацию также можно получить при помощи команды mysqladmin processlist. Если у вас привилегия SUPER, можно просматривать все потоки, в противном случае — только свои потоки. See Раздел 4.5.5, «Синтаксис команды KILL». Если не используется параметр FULL, будут показаны только первые 100 символов каждого запроса.
Начиная с 4.0.12, MySQL сообщает имя хоста для TCP/IP соединений как имя_хоста:клиентский_порт с тем, чтобы было проще понять, какой клиент чем занят.
Эта команда очень полезна, если выдается сообщение об ошибке ‘too many connections’ (слишком много соединений) и необходимо выяснить, что происходит. MySQL резервирует одно дополнительное соединение для клиента с привилегией SUPER, чтобы у вас всегда была возможность войти в систему и произвести проверку (предполагается, что вы не станете раздавать эту привилегию всем своим пользователям).
Некоторые состояния обычно можно увидеть в mysqladmin processlist.
- Checking table — Поток осуществляет [автоматическую] проверку таблицы.
- Closing tables — Означает, что поток записывает измененные данные таблиц на диск и закрывает использующиеся таблицы. Выполнение этой операции должно произойти быстро. Если на нее уходит значительное время, убедитесь, что диск не переполнен или что диск не используется слишком интенсивно.
- Connect Out — Подчиненный компьютер, подсоединенный к головному компьютеру.
- Copying to tmp table on disk — Набор временных результатов превысил tmp_table_size, и теперь поток изменяет таблицу временных данных, расположенную в памяти, на дисковую таблицу, чтобы сохранить память.
- Creating tmp table — Поток создает временную таблицу, чтобы хранить часть результатов для запроса.
- deleting from main table — При запуске первой части удаления нескольких таблиц удаление производится только начиная с первой таблицы.
- deleting from reference tables — При запуске второй части удаления нескольких таблиц удаляются совпадающие строки из других таблиц.
- Flushing tables — Поток запускает команду FLUSH TABLES и ожидает, пока все потоки закроют свои таблицы.
- Killed — Кто-то направил команду на закрытие потока, и поток будет закрыт при следующей проверке флага закрытия. Флаг проверяется при каждом основном цикле в MySQL, но в некоторых случаях закрытие потока может занять некоторое время. Если поток заблокирован другим потоком, закрытие будет произведено сразу после того, как другой поток снимет блокировку.
- Sending data — Поток обрабатывает строки для оператора SELECT, а также направляет данные клиенту.
- Sorting for group — Поток осуществляет сортировку в соответствии с GROUP BY.
- Sorting for order — Поток осуществляет сортировку в соответствии с ORDER BY.
- Opening tables — Это просто означает, что поток пытается открыть таблицу. Такая процедура осуществляется довольно быстро, если что-либо не мешает открытию. Например, команды ALTER TABLE или LOCK TABLE могут помешать открытию таблицы, пока выполнение команды не будет завершено.
- Removing duplicates — Запрос использовал команду SELECT DISTINCT таким образом, что MySQL не смог произвести оптимизацию на начальном этапе. Поэтому MySQL перед отправкой результатов клиенту должен выполнить дополнительное удаление всех дублирующихся строк.
- Reopen table — Поток заблокировал таблицу, но обнаружил, что после блокировки структура таблицы изменилась. Он снял блокировку, закрыл таблицу и теперь пытается повторно ее открыть.
- Repair by sorting — Код восстановления использует сортировку для создания индексов.
- Repair with keycache — Код восстановления использует создание ключей один за другим, через кэш ключей. Это намного медленнее, чем Repair by sorting.
- Searching rows for update — Поток осуществляет первую фазу — производит поиск всех совпадающих строк, чтобы затем обновить их. Это действие
необходимо выполнить, если команда UPDATE изменяет индекс, который используется для поиска указанных строк. - Sleeping — Поток ожидает, когда клиент направит ему новую команду.
- System lock — Поток ожидает получения внешней системной блокировки таблицы. Если не используется несколько серверов mysqld, которые получают доступ к одним и тем же таблицам, системную блокировку можно отключить при помощи параметра —skip-external-locking.
- Upgrading lock — Обработчик INSERT DELAYED пытается заблокировать таблицу, чтобы вставить строки.
- Updating — Поток производит поиск строк, которые необходимо обновить, и обновляет их.
- User Lock — Поток ожидает GET_LOCK().
- Waiting for tables — Поток получил уведомление, что структура таблицы изменилась, и ему необходимо повторно открыть таблицу, чтобы получить новую структуру. Чтобы повторно открыть таблицу, он должен подождать, пока ее не закроют все остальные потоки. Это уведомление выдается, если другой поток воспользовался командой FLUSH TABLES или к таблице была применена одна из следующих команд: FLUSH TABLES table_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE или OPTIMIZE TABLE. Обработчик INSERT DELAYED завершил работу со всеми вставками и ожидает новые.
Большинство состояний — это очень быстрые операции. Если потоки остаются в любом из этих состояний на протяжении большого количества секунд, то, возможно, возникла какая-то проблема, которую следует устранить.
Существует еще несколько состояний, не упомянутых выше, но большинство из них полезны только для поиска ошибок в mysqld.
Описания я взял с руководства, возможно немного не актуального, но на первых парах описаны все основные моменты. Остальное — смотрим полные версии руководства.
Источники:
- https://ruhighload.com/post/бла-бла-бла-1
- https://ruhighload.com/post/бла-бла-бла-2
- https://dev.mysql.com/doc/refman/5.7/en/perror.html
- https://unixforum.org/index.php?showtopic=92923
- http://www.arininav.ru/mysql/show-status.html
- http://www.arininav.ru/mysql/show-processlist.html
Logrotate takes care of log files generated by the systems through automatic rotation, compression, removal and mailing of log files; Most of the UNIX and Linux distribution offer logrotate utility. In this post we have explained how to configure log rotation for the error log, general query log, and the slow query log. You can use logrotate to handle log files daily / weekly / monthly / when it grows too large. We usually schedule logrotate as daily cron job, The logrotate utility needs to be able to authenticate with MariaDB in order to flush the log files. The easiest way to allow the logrotate utility to authenticate (in MariaDB 10.4) with MariaDB is to configure the root@localhost user account to use unix_socket authentication. In MariaDB 10.3 and before, you need to install the unix_socket plugin before you can configure the root@localhostuser account to use it. For example:
INSTALL SONAME 'auth_socket';
After the plugin is installed, the root@localhost user account can be configured to use unix_socket authentication.
Starting with MariaDB 10.2
ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket;
MariaDB until 10.1
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED VIA unix_socket WITH GRANT OPTION;
Configuring MariaDB Log Files and Locations
To keep log rotation configuration simple, please accommodate MariaDB logs in a dedicated log directory. We have explained below the configuration of same below:
- error_log – The error log filename and location
- general_query_log – The general query log filename and location
- slow_query_log – The slow query log filename and location
We have have accommodated MariaDB logs in /var/log/mysql , then we could configure the following:
[mariadb] ... log_error=/var/log/mysql/mariadb.err general_log general_log_file=/var/log/mysql/mariadb.log slow_query_log slow_query_log_file=/var/log/mysql/mariadb-slow.log long_query_time=1
We will also need to create the relevant directory:
sudo mkdir /var/log/mysql/ sudo chown mysql:mysql /var/log/mysql/ sudo chmod 0770 /var/log/mysql/
In case if you are using SELinux, then you may also need to set the SELinux context for the directory:
sudo semanage fcontext -a -t mysqld_log_t "/var/log/mysql(/.*)?" sudo restorecon -Rv /var/log/mysql
Configuring Logrotate
On many systems, the primary logrotate configuration file is located at the following path:
- /etc/logrotate.conf
And the logrotate configuration files for individual services are located in the following directory:
- /etc/logrotate.d/
We can create a logrotate configuration file for MariaDB with the following command:
sudo tee /etc/logrotate.d/mariadb <<EOF /var/log/mysql/* { missingok create 660 mysql mysql notifempty daily minsize 1M # only use with logrotate >= 3.7.4 maxsize 100M # only use with logrotate >= 3.8.1 rotate 30 # dateext # only use if your logrotate version is compatible with below dateformat # dateformat .%Y-%m-%d-%H-%M-%S # only use with logrotate >= 3.9.2 compress delaycompress sharedscripts olddir archive/ createolddir 770 mysql mysql # only use with logrotate >= 3.8.9 postrotate # just if mysqld is really running if test -x /usr/bin/mysqladmin && /usr/bin/mysqladmin ping &>/dev/null then /usr/bin/mysqladmin --local flush-error-log flush-engine-log flush-general-log flush-slow-log fi endscript EOF
Each specific configuration directive does the following:
Logrotate configuration option | Description |
---|---|
missingok | This directive configures it to ignore missing files, rather than failing with an error. |
create 660 mysql mysql | This directive configures it to recreate the log files after log rotation with the specified permissions and owner. |
notifempty | This directive configures it to skip a log file during log rotation if it is empty. |
daily | This directive configures it to rotate each log file once per day. |
minsize 1M | This directive configures it to skip a log file during log rotation if it is smaller than 1 MB. This directive is only available with logrotate 3.7.4 and later. |
maxsize 100M | This directive configures it to rotate a log file more frequently than daily if it grows larger than 100 MB. This directive is only available with logrotate 3.8.1 and later. |
rotate 30 | This directive configures it to keep 30 old copies of each log file. |
dateext | This directive configures it to use the date as an extension, rather than just a number. This directive is only available with logrotate 3.7.6 and later. |
dateformat .%Y-%m-%d-%H-%M-%S | This directive configures it to use this date format string (as defined by the format specification for strftime) for the date extension configured by the dateext directive. This directive is only available with logrotate 3.7.7 and later. Support for %H is only available with logrotate 3.9.0 and later. Support for %M and %S is only available with logrotate 3.9.2 and later. |
compress | This directive configures it to compress the log files with gzip. |
delaycompress | This directive configures it to delay compression of each log file until the next log rotation. If the log file is compressed at the same time that it is rotated, then there may be cases where a log file is being compressed while the MariaDB server is still writing to the log file. Delaying compression of a log file until the next log rotation can prevent race conditions such as these that can happen between the compression operation and the MariaDB server’s log flush operation. |
olddir archive/ | This directive configures it to archive the rotated log files in /var/log/mysql/archive/. |
createolddir 770 mysql mysql | This directive configures it to create the directory specified by the olddir directive with the specified permissions and owner, if the directory does not already exist. This directive is only available with logrotate 3.8.9 and later. |
sharedscripts | This directive configures it to run the postrotate script just once, rather than once for each rotated log file. |
postrotate | This directive configures it to execute a script after log rotation. This particular script executes the mysqladmin utility, which executes the FLUSH statement, which tells the MariaDB server to flush its various log files. When MariaDB server flushes a log file, it closes its existing file handle and reopens a new one. This ensure that MariaDB server does not continue writing to a log file after it has been rotated. This is an important component of the log rotation process. |
If our system does not have logrotate 3.8.9 or later, which is needed to support the createolddir directive, then we will also need to create the relevant directory specified by the olddir directive:
sudo mkdir /var/log/mysql/archive/ sudo chown mysql:mysql /var/log/mysql/archive/ sudo chmod 0770 /var/log/mysql/archive/
How to test and confirm logrotate is working ?
We can test log rotation by executing the logrotate utility with the –force option. For example:
sudo logrotate --force /etc/logrotate.d/mariadb
Keep in mind that under normal operation, the logrotate utility may skip a log file during log rotation if the utility does not believe that the log file needs to be rotated yet. For example:
- If you set the notifempty directive mentioned above, then it will be configured to skip a log file during log rotation if the log file is empty.
- If you set the daily directive mentioned above, then it will be configured to only rotate each log file once per day.
- If you set the minsize 1M directive mentioned above, then it will be configured to skip a log file during log rotation if the log file size is smaller than 1 MB.
However, when running tests with the –force option, the logrotate utility does not take these options into consideration.
References
- logrotate- https://linux.die.net/man/8/logrotate
- MariaDB logrotate – https://mariadb.com/kb/en/rotating-logs-on-unix-and-linux/
Join the DZone community and get the full member experience.
Join For Free
MySQL Server generates several logs that can help you monitor the activities of the server. However, once these logs are enabled, they can grow in size and start taking up too much disk space. This is why it’s important to have an automated way of archiving and preserving MySQL log files for a certain duration, as well as deleting the old ones. In this blog post, we describe some best practices for setting up and managing MySQL error logs, general logs and slow query logs for your MySQL deployments.
Setting Up MySQL Server Logging
Let’s look at how to set up the following 3 types of logs:
Error Log
Logs all the problems encountered during starting, running, or stopping mysqld. This log can be enabled by having the following option in /etc/my.cnf file:
- log_error=/var/log/mysql/mysqld.log
General Query Log
Logs established client connections and statements received from clients. This log can be enabled by having the following option in /etc/my.cnf file:
- general_log=ON
- general_log_file=/var/log/mysql/general.log
Slow Query Log
Logs queries that took more than long_query_time seconds to execute. This log can be enabled by the following option in /etc/my.cnf file:
- slow_query_log=ON
- slow_query_log_file=/var/log/mysql/mysql-slowquery.log
Setting Up Criteria For Log Rotation
As an example, let’s have some criteria for managing general MySQL query logs. We can come up with a suitable set of criteria for log management by asking the following questions:
Q: What is the maximum size that the log file can grow?
A: Let’s say it can grow up to 300 MB after which it needs to be rotated and compressed.
Q: What is the frequency that you want the log file to be rotated?
A: We can say that we want logs to be rotated on a daily basis.
Q: How many old log files you want to retain?
A: We would like to retain the last 30 log files.
Based on the above criteria, the overall disk space required for general query log management is about 1.2 GB. Assuming a 90 percent compression ratio — we will have 30 compressed log files of size 30 MB each and a live log file of about 300 MB.
Managing The Logs Using Linux logrotate Utility
logrotate is a Linux utility that helps with the efficient administration of log files and provides options for automatic rotation, compression, and removal of log files. The criteria established above can be configured for logrotate utility by creating a configuration file in the /etc/logrotate.d folder.
Let’s call this configuration file mysqlgeneral and the contents of the file will be:
/var/log/mysql/general.log{
compress
dateext
maxsize 300M
copytruncate
maxage 365
dateformat -%Y%m%d%s
daily
rotate 30
notifempty
}
With the above options for logrotate, the general query logs get rotated either on a daily basis or when the log file size exceeds 300 MB. The old logs are compressed and 30 such files will be preserved. Log rotation will be skipped if the log file is empty due to the setting ‘notifempty’.
The ‘copytruncate’ option is to ensure that current log file is never deleted during rotation and only its contents get truncated. This is important since some applications expect that the log file is always available and it’s not possible to delete the log without stopping the application first.
Now that the log rotation configuration is set for the general query log, the logrotate utility has to be run so that the above configuration is executed. This is typically done through a cron job. We can set this to be running every hour by placing the logrotate script in /etc/cron.hourly directory:
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
So, with a few simple steps, we have set up log rotation for MySQL general logs based on our criteria. The same approach can be followed for MySQL error logs and slow query logs as well. Check out these other posts to learn more about optimizing your MySQL deployments:
- Calculating InnoDB Buffer Pool Size for your MySQL Server
- MySQL Tutorial – Configuring and Managing SSL On Your MySQL Server
- MySQL High Availability Framework Explained – Part I: Introduction
MySQL
Log rotation
Database
Published at DZone with permission of Prasad Nagaraj, DZone MVB.
See the original article here.
Opinions expressed by DZone contributors are their own.
MySQL Server generates several logs that can help you monitor the activities of the server. However, once these logs are enabled, they can grow in size and start taking up too much disk space. This is why it’s important to have an automated way of archiving and preserving MySQL log files for a certain duration, as well as deleting the old ones. In this blog post, we describe some best practices for setting up and managing MySQL error logs, general logs and slow query logs for your MySQL deployments.
Setting Up MySQL Server Logging
Let’s look at how to setup the following 3 types of logs:
Error Log
Logs all the problems encountered during starting, running, or stopping mysqld. This log can be enabled by having the following option in /etc/my.cnf file:
- log_error=/var/log/mysql/mysqld.log
General Query Log
Logs established client connections and statements received from clients. This log can be enabled by having the following option in /etc/my.cnf file:
- general_log=ON
- general_log_file=/var/log/mysql/general.log
Slow Query Log
Logs queries that took more than long_query_time seconds to execute. This log can be enabled by the following option in /etc/my.cnf file:
- slow_query_log=ON
- slow_query_log_file=/var/log/mysql/mysql-slowquery.log
Setting Up Criteria For Log Rotation
As an example, let’s have some criteria for managing general MySQL query logs. We can come up with a suitable set of criteria for log management by asking the following questions:
Q: What is the maximum size that the log file can grow?
A: Let’s say it can grow up to 300 MB after which it needs to be rotated and compressed.
Q: What is the frequency that you want the log file to be rotated?
A: We can say that we want logs to be rotated on a daily basis.
Q: How many old log files you want to retain?
A: We would like to retain the last 30 log files.
Based on the above criteria, the overall disk space required for general query log management is about 1.2 GB. Assuming a 90% compression ratio “ we will have 30 compressed log files of size 30 MB each and a live log file of about 300 MB.
Managing The Logs Using Linux logrotate Utility
logrotate is a Linux utility that helps with the efficient administration of log files and provides options for automatic rotation, compression, and removal of log files. The criteria established above can be configured for logrotate utility by creating a configuration file in the /etc/logrotate.d folder.
Let’s call this configuration file mysqlgeneral and the contents of the file will be:
/var/log/mysql/general.log{
compress
dateext
maxsize 300M
copytruncate
maxage 365
dateformat -%Y%m%d%s
daily
rotate 30
notifempty
}
With the above options for logrotate, the general query logs get rotated either on a daily basis or when the log file size exceeds 300 MB. The old logs are compressed and 30 such files will be preserved. Log rotation will be skipped if the log file is empty due to the setting notifempty’.
The copytruncate’ option is to ensure that current log file is never deleted during rotation and only its contents get truncated. This is important since some applications expect that the log file is always available and it’s not possible to delete the log without stopping the application first.
Now that the log rotation configuration is set for the general query log, the logrotate utility has to be run so that the above configuration is executed. This is typically done through a cron job. We can set this to be running every hour by placing the logrotate script in /etc/cron.hourly directory:
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
So, with a few simple steps, we have set up log rotation for MySQL general logs based on our criteria. The same approach can be followed for MySQL error logs and slow query logs as well. Check out these other posts to learn more about optimizing your MySQL deployments:
- Calculating InnoDB Buffer Pool Size for your MySQL Server
- MySQL Tutorial “ Configuring and Managing SSL On Your MySQL Server
- MySQL High Availability Framework Explained “ Part I: Introduction
ScaleGrid offers a fully managed MongoDB, MySQL, PostgreSQL and Redis on AWS, Azure, and DigitalOcean. Bring your own cloud account or host with us. Deploy standalone, replica sets or shards.