This quick tutorial of how you can optimize the performance of a MySQL database with the mysqltuner script. This tool can be used for MySQL and MariaDB.

 

Install mysqltuner

The mysqltuner High-Performance MySQL Tuning Script is available as a package on Debian 10 and Ubuntu 20.04, install it with at:

$ sudo apt-get install mysqltuner

For other Distributions, download and install mysqltuner as described below:

$ cd /usr/local/bin
$ wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl $ mv mysqltuner.pl mysqltuner $chmod +x mysqltuner

Optimize MySQL Performance Run mysqltuner:

mysqltuner

Then enter root as the username and the MySQL root password. You will get an output similar to this:

root@server1:/# mysqltuner
>> MySQLTuner 1.7.2 - Major Hayden <[email protected]>
>> Bug reports, feature requests, and downloads at http://mysqltuner.com/
>> Run with '--help' for additional options and output filtering

[--] Skipped version check for MySQLTuner script
[OK] Logged in using credentials from debian maintenance account.
[OK] Currently running supported MySQL version 5.7.36-0ubuntu0.18.04.1
[OK] Operating on 64-bit architecture

-------- Log file Recommendations ------------------------------------------------------------------
[--] Log file: /var/log/mysql/error.log(262B)
[OK] Log file /var/log/mysql/error.log exists
[OK] Log file /var/log/mysql/error.log is readable.
[OK] Log file /var/log/mysql/error.log is not empty
[OK] Log file /var/log/mysql/error.log is smaller than 32 Mb
[!!] /var/log/mysql/error.log contains 1 warning(s).
[!!] /var/log/mysql/error.log contains 1 error(s).
[--] 0 start(s) detected in /var/log/mysql/error.log
[--] 0 shutdown(s) detected in /var/log/mysql/error.log

-------- Storage Engine Statistics -----------------------------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MEMORY +MRG_MYISAM +MyISAM +PERFORMANCE_SCHEMA
[--] Data in InnoDB tables: 1G (Tables: 859)
[--] Data in MyISAM tables: 77M (Tables: 2629)
[OK] Total fragmented tables: 0

-------- Security Recommendations ------------------------------------------------------------------
[OK] There are no anonymous accounts for any database users
[OK] All database users have passwords assigned
[!!] User 'dbuser_dhamma@%' hasn't specific host restriction.
[--] There are 612 basic passwords in the list.

-------- CVE Security Recommendations --------------------------------------------------------------
[OK] NO SECURITY CVE FOUND FOR YOUR VERSION

-------- Performance Metrics -----------------------------------------------------------------------
[--] Up for: 10d 4h 36m 54s (137K q [0.156 qps], 15K conn, TX: 467M, RX: 18M)
[--] Reads / Writes: 97% / 3%
[--] Binary logging is disabled
[--] Physical Memory : 985.1M
[--] Max MySQL memory : 400.4M
[--] Other process memory: 379.9M
[--] Total buffers: 240.0M global + 1.1M per thread (151 max threads)
[--] P_S Max memory usage: 72B
[--] Galera GCache Max memory usage: 0B
[OK] Maximum reached memory usage: 243.2M (24.69% of installed RAM)
[OK] Maximum possible memory usage: 400.4M (40.65% of installed RAM)
[OK] Overall possible memory usage with other process is compatible with memory available
[OK] Slow queries: 0% (0/137K)
[OK] Highest usage of available connections: 1% (3/151)
[OK] Aborted connections: 2.41% (377/15675)
[!!] name resolution is active : a reverse name resolution is made for each new connection and can reduce performance
[!!] Query cache may be disabled by default due to mutex contention.
[!!] Query cache efficiency: 0.0% (0 cached / 99K selects)
[OK] Query cache prunes per day: 0
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 7K sorts)
[OK] No joins without indexes
[!!] Temporary tables created on disk: 43% (1K on disk / 3K total)
[OK] Thread cache hit rate: 99% (3 created / 15K connections)
[!!] Table cache hit rate: 10% (2K open / 19K opened)
[OK] Open file limit used: 42% (2K/5K)
[OK] Table locks acquired immediately: 100% (40K immediate / 40K locks)

-------- Performance schema ------------------------------------------------------------------------
[--] Memory used by P_S: 72B
[--] Sys schema is installed.

-------- ThreadPool Metrics ------------------------------------------------------------------------
[--] ThreadPool stat is disabled.

-------- MyISAM Metrics ----------------------------------------------------------------------------
[!!] Key buffer used: 18.3% (12M used / 67M cache)
[OK] Key buffer size / total MyISAM indexes: 64.0M/9.3M
[OK] Read Key buffer hit rate: 99.3% (169K cached / 1K reads)
[OK] Write Key buffer hit rate: 100.0% (277 cached / 277 writes)

-------- InnoDB Metrics ----------------------------------------------------------------------------
[--] InnoDB is enabled.
[--] InnoDB Thread Concurrency: 0
[OK] InnoDB File per table is activated
[!!] InnoDB buffer pool / data size: 128.0M/1.7G
[!!] Ratio InnoDB log file size / InnoDB Buffer pool size (75 %): 48.0M * 2/128.0M should be equal 25%
[OK] InnoDB buffer pool instances: 1
[--] Number of InnoDB Buffer Pool Chunk : 1 for 1 Buffer Pool Instance(s)
[OK] Innodb_buffer_pool_size aligned with Innodb_buffer_pool_chunk_size & Innodb_buffer_pool_instances
[OK] InnoDB Read buffer efficiency: 99.42% (1247583 hits/ 1254813 total)
[!!] InnoDB Write Log efficiency: 69.69% (7543 hits/ 10823 total)
[OK] InnoDB log waits: 0.00% (0 waits / 3280 writes)

-------- AriaDB Metrics ----------------------------------------------------------------------------
[--] AriaDB is disabled.

-------- TokuDB Metrics ----------------------------------------------------------------------------
[--] TokuDB is disabled.

-------- XtraDB Metrics ----------------------------------------------------------------------------
[--] XtraDB is disabled.

-------- RocksDB Metrics ---------------------------------------------------------------------------
[--] RocksDB is disabled.

-------- Spider Metrics ----------------------------------------------------------------------------
[--] Spider is disabled.

-------- Connect Metrics ---------------------------------------------------------------------------
[--] Connect is disabled.

-------- Galera Metrics ----------------------------------------------------------------------------
[--] Galera is disabled.

-------- Replication Metrics -----------------------------------------------------------------------
[--] Galera Synchronous replication: NO
[--] No replication slave(s) for this server.
[--] This is a standalone server.

-------- Recommendations ---------------------------------------------------------------------------
General recommendations:
Control warning line(s) into /var/log/mysql/error.log file
Control error line(s) into /var/log/mysql/error.log file
Restrict Host for user@% to user@SpecificDNSorIp
Configure your accounts with ip or subnets only, then update your configuration with skip-name-resolve=1
When making adjustments, make tmp_table_size/max_heap_table_size equal
Reduce your SELECT DISTINCT queries which have no LIMIT clause
Increase table_open_cache gradually to avoid file descriptor limits
Read this before increasing table_open_cache over 64: http://bit.ly/1mi7c4C
Beware that open_files_limit (5000) variable
should be greater than table_open_cache (2000)
Variables to adjust:
query_cache_size (=0)
query_cache_type (=0)
query_cache_limit (> 1M, or use smaller result sets)
tmp_table_size (> 16M)
max_heap_table_size (> 16M)
table_open_cache (> 2000)
innodb_buffer_pool_size (>= 1G) if possible.
innodb_log_file_size * innodb_log_files_in_group should be equal to 1/4 of buffer pool size (=64M) if possible.

 

The script recommends adjusting or adding the following variables in the MySQL configuration file. On current Debian and Ubuntu versions, the file is /etc/mysql/mysql.conf.d/mysql.cnf for MySQL and /etc/mysql/mariadb.conf.d/50-server.cnf for MariaDB.Other common paths are just /etc/my.cnf and /etc/mysql/my.cnf, these are commonly used on older Linux versions and on CentOS.

Adjust MySQL configuration Open my.cnf file:

nano /etc/mysql/mysql.conf.d/mysql.cnf

and increase or set the variables in the [mysqld] section of the file. Mine looks now like this:

#
# The MySQL database server configuration file.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html


# Here is entries for some specific programs
# The following values assume you have at least 32M ram


[mysqld]
#
# * Basic Settings
#
user = mysql
# pid-file = /var/run/mysqld/mysqld.pid
# socket = /var/run/mysqld/mysqld.sock
# port = 3306
# datadir = /var/lib/mysql


# If MySQL is running as a replication slave, this should be
# changed. Ref https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_tmpdir
# tmpdir = /tmp
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = 127.0.0.1
mysqlx-bind-address = 127.0.0.1
#
# * Fine Tuning
#
key_buffer_size = 16M
# max_allowed_packet = 64M
# thread_stack = 256K


# thread_cache_size = -1


# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover-options = BACKUP


# max_connections = 151


# table_open_cache = 4000


#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
#
# Log all queries
# Be aware that this log type is a performance killer.
# general_log_file = /var/log/mysql/query.log
# general_log = 1
#
# Error log - should be very few entries.
#
log_error = /var/log/mysql/error.log
#
# Here you can see queries with especially long duration
# slow_query_log = 1
# slow_query_log_file = /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
# binlog_expire_logs_seconds = 2592000
max_binlog_size = 100M
# binlog_do_db = include_database_name
# binlog_ignore_db = include_database_name


query_cache_limit       = 1M
query_cache_size        = 16M
tmp_table_size.         = 64M
max_heap_table_size     = 32M

$ systemctl restart mysql

Run mysqltuner again after a few hours. Check if the values are fine now or if they have to be increased to a higher value.

 


Your link is almost ready.

12
Seconds
Please wait...