Trying to optimize MySQL server
I copied a few files that I noticed should help. Let me know if there's anything else I should look for.
Here's the output from mysqltuner, followed by an output of my /etc/mysql/my.cnf file, and then my query_cache parameters..
[OK] Logged in using credentials from debian maintenance account.
>> MySQLTuner 1.6.4 - Major Hayden <major@mhtx.net>>> 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] Currently running supported MySQL version 5.1.73-0ubuntu0.10.04.1
[OK] Operating on 64-bit architecture
-------- Storage Engine Statistics -------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MRG_MYISAM
[--] Data in MyISAM tables: 4G (Tables: 325)
[--] Data in InnoDB tables: 29M (Tables: 71)
[!!] Total fragmented tables: 117
-------- Security Recommendations -------------------------------------------
[OK] There are no anonymous accounts for any database users
[OK] All database users have passwords assigned
[!!] User 'wp_admin@%' hasn't specific host restriction.
[!!] There is no basic password file list!
-------- CVE Security Recommendations ---------------------------------------
[--] Skipped due to --cvefile option undefined
-------- Performance Metrics -------------------------------------------------
[--] Up for: 2d 12h 29m 6s (6M q [31.379 qps], 125K conn, TX: 443B, RX: 1B)
[--] Reads / Writes: 98% / 2%
[--] Binary logging is disabled
[--] Total buffers: 186.0M global + 96.2M per thread (35 max threads)
[OK] Maximum reached memory usage: 3.0G (38.35% of installed RAM)
[OK] Maximum possible memory usage: 3.5G (44.35% of installed RAM)
[OK] Slow queries: 0% (40/6M)
[OK] Highest usage of available connections: 85% (30/35)
[OK] Aborted connections: 0.00% (4/125283)
[OK] Query cache efficiency: 69.9% (4M cached / 6M selects)
[!!] Query cache prunes per day: 89346
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 1M sorts)
[!!] Temporary tables created on disk: 49% (199K on disk / 400K total)
[OK] Thread cache hit rate: 99% (778 created / 125K connections)
[!!] Table cache hit rate: 0% (32 open / 20K opened)
[OK] Open file limit used: 4% (51/1K)
[OK] Table locks acquired immediately: 99% (2M immediate / 2M locks)
-------- MyISAM Metrics ------------------------------------------------------
[OK] Key buffer used: 100.0% (33M used / 33M cache)
[OK] Key buffer size / total MyISAM indexes: 32.0M/410.0M
[OK] Read Key buffer hit rate: 99.5% (1B cached / 7M reads)
[OK] Write Key buffer hit rate: 96.7% (781K cached / 26K writes)
-------- InnoDB Metrics ------------------------------------------------------
[--] InnoDB is enabled.
[!!] InnoDB buffer pool / data size: 8.0M/29.5M
[OK] InnoDB Used buffer: 100.00% (512 used/ 512 total)
[OK] InnoDB Read buffer efficiency: 96.06% (9790 hits/ 10192 total)
[!!] InnoDB Write buffer efficiency: 0.00% (0 hits/ 1 total)
[OK] InnoDB log waits: 0.00% (0 waits / 4 writes)
-------- ThreadPool Metrics --------------------------------------------------
[--] ThreadPool stat is disabled.
-------- AriaDB Metrics ------------------------------------------------------
[--] AriaDB is disabled.
-------- TokuDB Metrics ------------------------------------------------------
[--] TokuDB is disabled.
-------- Galera Metrics ------------------------------------------------------
[--] Galera is disabled.
-------- Replication Metrics -------------------------------------------------
[--] No replication slave(s) for this server.
[--] This is a standalone server..
-------- Recommendations -----------------------------------------------------
General recommendations:
Run OPTIMIZE TABLE to defragment tables for better performance
Restrict Host for user@% to user@SpecificDNSorIp
Enable the slow query log to troubleshoot bad queries
Increasing the query_cache size over 128M may reduce performance
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 (1024) variable
should be greater than table_open_cache ( 32)
Variables to adjust:
query_cache_size (> 128M) [see warning above]
tmp_table_size (> 16M)
max_heap_table_size (> 16M)
table_open_cache (> 32)
innodb_buffer_pool_size (>= 29M) if possible.</major@mhtx.net>
So I know there are a bunch of issues, but what could possibly help right now in terms of the most impact?
I read the Tuning your mysql database article and I'm not sure which ones to adjust.
Here's my /etc/mysql/my.cnf file:
#
# The MySQL database server configuration file.
#
# You can copy this to one of:
# - "/etc/mysql/my.cnf" to set global options,
# - "~/.my.cnf" to set user-specific options.
#
# 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
# This will be passed to all mysql clients
# It has been reported that passwords should be enclosed with ticks/quotes
# escpecially if they contain "#" chars...
# Remember to edit /etc/mysql/debian.cnf when changing the socket location.
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
# Here is entries for some specific programs
# The following values assume you have at least 32M ram
# This was formally known as [safe_mysqld]. Both versions are currently parsed.
[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0
[mysqld]
key_buffer = 720M
sort_buffer_size = 32M
read_buffer_size = 32M
read_rnd_buffer_size = 32M
myisam_sort_buffer_size = 160M
query_cache_size = 128M
#
# * Basic Settings
#
#
# * IMPORTANT
# If you make changes to these settings and your system uses apparmor, you may
# also need to also adjust /etc/apparmor.d/usr.sbin.mysqld.
#
user = mysql
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
skip-external-locking
#
# 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
#
# * Fine Tuning
#
key_buffer = 32M
max_allowed_packet = 1M
thread_stack = 128K
thread_cache_size = 8
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover = BACKUP
max_connections = 35
table_cache = 32
#thread_concurrency = 10
#
# * Query Cache Configuration
#
query_cache_limit = 1M
#query_cache_size = 16M
#
# * 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
log_error = /var/log/mysql/error.log
# 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
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
#
# * Security Features
#
# Read the manual, too, if you want chroot!
# chroot = /var/lib/mysql/
#
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
#
# ssl-ca=/etc/mysql/cacert.pem
# ssl-cert=/etc/mysql/server-cert.pem
# ssl-key=/etc/mysql/server-key.pem
[mysqldump]
quick
quote-names
max_allowed_packet = 16M
[mysql]
#no-auto-rehash # faster start of mysql but no tab completition
[isamchk]
key_buffer = 16M
#
# * IMPORTANT: Additional settings that can override those from this file!
# The files must end with '.cnf', otherwise they'll be ignored.
#
!includedir /etc/mysql/conf.d/
Also, is my querycachesize too big?
mysql> show variables like '%query_cache%';
+------------------------------+-----------+
| Variable_name | Value |
+------------------------------+-----------+
| have_query_cache | YES |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 134217728 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+-----------+
6 rows in set (0.00 sec)
I'm fairly inexperienced at this kind of stuff, so any recommendations would be greatly appreciated.
10 Replies
What does your Apache configuration look like, especially the "MaxClients" and/or "MaxRequestWorkers" setting under the "mpm_prefork" section? If it's anything higher than 25 (just an off-the-top-of-my-head number based on the size of your Linode and mysqltuner results), reduce it to 25 and see how it goes.
So should I try reducing MaxClients to 25? What about MaxRequestsPerChild?
prefork MPM
StartServers: number of server processes to start
MinSpareServers: minimum number of server processes which are kept spare
MaxSpareServers: maximum number of server processes which are kept spare
MaxClients: maximum number of server processes allowed to start
MaxRequestsPerChild: maximum number of requests a server process serves
MinSpareServers 6
MaxSpareServers 12
MaxClients 30
MaxRequestsPerChild 3000
So far, we know that:
MySQL uses a maximum of 3.5GB of RAM, based on your mysqltuner result.
That leaves 4.5GB of RAM for all the other things that run on your server.
30 Apache/PHP processes can use up to 4GB of RAM, assuming PHP's default memorylimit of 128MB per process. If you set your memorylimit higher, it may use even more RAM.
That's pretty close to the total amount of RAM you have, so if you have other things running on your server as well (such as a control panel, mail server, spam and virus filter, etc.) you might run out of RAM at some point.
Other (not RAM related) possibilities:
What is the KeepAlive setting in /etc/apache2/apache2.conf? It should be either off or a single-digit number, in order to kick out people who just connect and do nothing. Otherwise, if a few people open 30 connections and occupy all of your Apache processes, nobody else will be able to connect to your server until they leave.
Let's look more closely at the mysqltuner results. You have 4GB of data in MyISAM tables, but the key buffer is too small and the per-thread buffer (sort buffer + join buffer + read buffer) is too big. If you have a lot of simultaneous visitors, heavy I/O and locking might make your site unresponsive even if there's plenty of RAM to go around. Also consider using more InnoDB.
I've got KeepAlive set to off.
KeepAlive: Whether or not to allow persistent connections (more than
one request per connection). Set to "Off" to deactivate.
#
KeepAlive Off
What would you recommend setting the key buffer and per-thread buffers to?
[Tue Mar 01 09:31:52 2016] [notice] caught SIGTERM, shutting down
[Tue Mar 01 09:32:14 2016] [notice] Apache/2.2.14 (Ubuntu) PHP/5.4.39-1+deb.sury.org~lucid+2 configured – resuming normal operations
[Tue Mar 01 09:32:20 2016] [error] server reached MaxClients setting, consider raising the MaxClients setting
[Tue Mar 01 09:33:19 2016] [notice] caught SIGTERM, shutting down
[Tue Mar 01 09:33:40 2016] [notice] Apache/2.2.14 (Ubuntu) PHP/5.4.39-1+deb.sury.org~lucid+2 configured – resuming normal operations
[Tue Mar 01 09:33:46 2016] [error] server reached MaxClients setting, consider raising the MaxClients setting
[Tue Mar 01 09:35:34 2016] [notice] caught SIGTERM, shutting down
[Tue Mar 01 09:35:54 2016] [notice] Apache/2.2.14 (Ubuntu) PHP/5.4.39-1+deb.sury.org~lucid+2 configured – resuming normal operations
[Tue Mar 01 09:36:00 2016] [error] server reached MaxClients setting, consider raising the MaxClients setting
If you're hitting MaxClients, don't listen to Apache's suggestion about raising it. That error just means the MaxClients setting is doing its job. If reaching MaxClients coincides with crashing, it means MaxClients is already too high. Have you tried reducing it to 25 as I suggested before, or even 20 just to be safe?
As for MySQL, have you implemented my previous suggestion of increasing the global buffer size and reducing the per-thread buffer size? If so, has it changed the mysqltuner result in a noticeable way? Large per-thread buffers cause a lot of variability in memory usage. Your server's memory usage should be fairly stable 24/7, not spiking all the time.
I would like to implement your suggestion, but what would you recommend setting the global buffer size and per-thread buffer size to? I'm very inexperienced at this, so I'm not too sure what to do. Thanks again for all your help, I do appreciate it.
Try setting the key buffer size to 512M, and sort/join/read/rnd buffers to 4M each. Re-run mysqltuner and see if the maximum possible memory usage has been reduced.
The query cache size is okay. You also really should be using InnoDB instead of MyISAM, but let's not worry about it now.
[mysqld]
key_buffer = 720M
sort_buffer_size = 4M
read_buffer_size = 4M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 4M
query_cache_size = 128M
#
# * Basic Settings
#
#
# * IMPORTANT
# If you make changes to these settings and your system uses apparmor, you may
# also need to also adjust /etc/apparmor.d/usr.sbin.mysqld.
#
user = mysql
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
skip-external-locking
#
# 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
#
# * Fine Tuning
#
key_buffer = 512M
Is that what you meant? I changed the second key_buffer value under Fine Tuning to 512M, then changed the buffer sizes to 4M.
This is mysqltuner output:
>> MySQLTuner 1.6.4 - Major Hayden <major@mhtx.net>
>> 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] Currently running supported MySQL version 5.1.73-0ubuntu0.10.04.1
[OK] Operating on 64-bit architecture
-------- Storage Engine Statistics -------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MRG_MYISAM
[--] Data in MyISAM tables: 4G (Tables: 325)
[--] Data in InnoDB tables: 29M (Tables: 71)
[!!] Total fragmented tables: 116
-------- Security Recommendations -------------------------------------------
[OK] There are no anonymous accounts for any database users
[OK] All database users have passwords assigned
[!!] User 'wp_admin@%' hasn't specific host restriction.
[!!] There is no basic password file list!
-------- CVE Security Recommendations ---------------------------------------
[--] Skipped due to --cvefile option undefined
-------- Performance Metrics -------------------------------------------------
[--] Up for: 23h 32m 50s (5M q [62.312 qps], 153K conn, TX: 275B, RX: 589M)
[--] Reads / Writes: 99% / 1%
[--] Binary logging is disabled
[--] Total buffers: 186.0M global + 96.2M per thread (35 max threads)
[OK] Maximum reached memory usage: 2.6G (33.55% of installed RAM)
[OK] Maximum possible memory usage: 3.5G (44.35% of installed RAM)
[OK] Slow queries: 0% (12/5M)
[OK] Highest usage of available connections: 74% (26/35)
[OK] Aborted connections: 0.00% (0/153551)
[OK] Query cache efficiency: 88.3% (4M cached / 4M selects)
[!!] Query cache prunes per day: 31465
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 178K sorts)
[!!] Temporary tables created on disk: 45% (17K on disk / 37K total)
[OK] Thread cache hit rate: 99% (57 created / 153K connections)
[!!] Table cache hit rate: 0% (32 open / 4K opened)
[OK] Open file limit used: 4% (49/1K)
[OK] Table locks acquired immediately: 99% (457K immediate / 457K locks)
-------- MyISAM Metrics ------------------------------------------------------
[OK] Key buffer used: 100.0% (33M used / 33M cache)
[OK] Key buffer size / total MyISAM indexes: 32.0M/413.5M
[OK] Read Key buffer hit rate: 99.8% (273M cached / 627K reads)
[OK] Write Key buffer hit rate: 99.4% (153K cached / 929 writes)
-------- InnoDB Metrics ------------------------------------------------------
[--] InnoDB is enabled.
[!!] InnoDB buffer pool / data size: 8.0M/29.5M
[OK] InnoDB Used buffer: 100.00% (512 used/ 512 total)
[OK] InnoDB Read buffer efficiency: 95.97% (9510 hits/ 9909 total)
[!!] InnoDB Write buffer efficiency: 0.00% (0 hits/ 1 total)
[OK] InnoDB log waits: 0.00% (0 waits / 1 writes)
-------- ThreadPool Metrics --------------------------------------------------
[--] ThreadPool stat is disabled.
-------- AriaDB Metrics ------------------------------------------------------
[--] AriaDB is disabled.
-------- TokuDB Metrics ------------------------------------------------------
[--] TokuDB is disabled.
-------- Galera Metrics ------------------------------------------------------
[--] Galera is disabled.
-------- Replication Metrics -------------------------------------------------
[--] No replication slave(s) for this server.
[--] This is a standalone server..
-------- Recommendations -----------------------------------------------------
General recommendations:
Run OPTIMIZE TABLE to defragment tables for better performance
Restrict Host for user@% to user@SpecificDNSorIp
MySQL started within last 24 hours - recommendations may be inaccurate
Enable the slow query log to troubleshoot bad queries
Increasing the query_cache size over 128M may reduce performance
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 (1024) variable
should be greater than table_open_cache ( 32)
Variables to adjust:
query_cache_size (> 128M) [see warning above]
tmp_table_size (> 16M)
max_heap_table_size (> 16M)
table_open_cache (> 32)
innodb_buffer_pool_size (>= 29M) if possible.</major@mhtx.net>
Delete one of the key_buffer settings, it's a recipe for confusion.