I'm searching for 3 days already and can't find out, why my MySQL server uses so much CPU. For example, when I run a query to SELECT like 100 rows from one of the tables, the CPU goes from 0 to 50%, or when I take a value from one of the tables and INSERT a row in another table, the CPU goes from 0 to 10-30%. Currently, it uses 170MB, I've tried with a clean one and the CPU was under 1% all the time. Queries are not slow, they finish the job in under 0.05 seconds, but still use ~30% CPU. If I have over 30 people on the website and they all do that the website slows down really bad. That didn't happen until some time ago so maybe I made something wrong somewhere while working on the project.
Here is MySQLTuner's result:
>> MySQLTuner 1.7.0 - 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] Logged in using credentials from debian maintenance account.
[OK] Currently running supported MySQL version 5.5.52-0+deb7u1
[OK] Operating on 64-bit architecture
-------- Storage Engine Statistics --------------------------------------------- --------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MEMORY +MRG_MYISAM +My ISAM +PERFORMANCE_SCHEMA
[--] Data in MyISAM tables: 23K (Tables: 10)
[--] Data in InnoDB tables: 218M (Tables: 18)
[OK] Total fragmented tables: 0
-------- Security Recommendations ---------------------------------------------- --------------------
[OK] There are no anonymous accounts for any database users
[OK] All database users have passwords assigned
[--] There are 612 basic passwords in the list.
-------- CVE Security Recommendations ------------------------------------------ --------------------
[!!] CVE-2016-6662(<= 5.5.52) : "Oracle MySQL through 5.5.52
[--] False positive CVE(s) for MySQL and MariaDB 5.5.x can be found.
[--] Check careful each CVE for those particular versions
[!!] 1 CVE(s) found for your MySQL release.
-------- Performance Metrics -----------------------------------------------------------------------
[--] Up for: 13m 39s (2K q [2.452 qps], 434 conn, TX: 925K, RX: 146K)
[--] Reads / Writes: 70% / 30%
[--] Binary logging is disabled
[--] Physical Memory : 3.8G
[--] Max MySQL memory : 597.8M
[--] Other process memory: 63.7M
[--] Total buffers: 192.0M global + 2.7M per thread (151 max threads)
[--] P_S Max memory usage: 0B
[--] Galera GCache Max memory usage: 0B
[OK] Maximum reached memory usage: 232.3M (6.00% of installed RAM)
[OK] Maximum possible memory usage: 597.8M (15.44% of installed RAM)
[OK] Overall possible memory usage with other process is compatible with memory available
[OK] Slow queries: 0% (0/2K)
[OK] Highest usage of available connections: 9% (15/151)
[OK] Aborted connections: 0.00% (0/434)
[!!] 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.
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 5 sorts)
[OK] No joins without indexes
[OK] Temporary tables created on disk: 25% (69 on disk / 273 total)
[OK] Thread cache hit rate: 96% (15 created / 434 connections)
[OK] Table cache hit rate: 91% (72 open / 79 opened)
[OK] Open file limit used: 6% (68/1K)
[OK] Table locks acquired immediately: 100% (224 immediate / 224 locks)
-------- Performance schema ------------------------------------------------------------------------
[--] Performance schema is disabled.
-------- ThreadPool Metrics ------------------------------------------------------------------------
[--] ThreadPool stat is disabled.
-------- MyISAM Metrics ----------------------------------------------------------------------------
[!!] Key buffer used: 18.2% (3M used / 16M cache)
[OK] Key buffer size / total MyISAM indexes: 16.0M/124.0K
-------- InnoDB Metrics ----------------------------------------------------------------------------
[--] InnoDB is enabled.
[--] InnoDB Thread Cucurrency: 0
[!!] InnoDB File per table is not activated
[!!] InnoDB buffer pool / data size: 128.0M/218.7M
[!!] Ratio InnoDB log file size / InnoDB Buffer pool size (3.90625 %): 5.0M/128.0M should be equal 25%
[OK] InnoDB buffer pool instances: 1
[--] InnoDB Buffer Pool Chunk Size not used or defined in your version
[OK] InnoDB Read buffer efficiency: 99.98% (4252997 hits/ 4253965 total)
[!!] InnoDB Write Log efficiency: 17.98% (16 hits/ 89 total)
[OK] InnoDB log waits: 0.00% (0 waits / 73 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:
1 CVE(s) found for your MySQL release. Consider upgrading your version !
MySQL started within last 24 hours - recommendations may be inaccurate
Enable the slow query log to troubleshoot bad queries
Configure your accounts with ip or subnets only, then update your configuration with skip-name-resolve=1
Variables to adjust:
query_cache_type (=0)
innodb_file_per_table=ON
innodb_buffer_pool_size (>= 218M) if possible.
innodb_log_file_size should be equals to 1/4 of buffer pool size (=32M) if possible.
And here is my.cnf:
#
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
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 = 16M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
wait_timeout = 1800
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover = BACKUP
#max_connections = 100
#table_cache = 64
#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
#
# Error logging goes to syslog due to /etc/mysql/conf.d/mysqld_safe_syslog.cnf.
#
# Here you can see queries with especially long duration
#log_slow_queries = /var/log/mysql/mysql-slow.log
#long_query_time = 2
#log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
# other settings you may need to change.
#server-id = 1
#log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
#binlog_do_db = include_database_name
#binlog_ignore_db = include_database_name
#
# * 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/
I've also checked the slow queries log, but nothing was slow enough to go there. I only use one index on one column in the users-table. That speeds up some queries but just that, MySQL's CPU usage is the same with and without it.
I have 3 tables with almost 1.000.000 rows but I'm only using one index in the users table. Here is the explain of one of my queries:
EXPLAIN SELECT * FROM bets WHERE user = 76561198156588991
(Here is the result: gyazo.com/201c91cc5fd903667e30a26067001d0e and it was executed in 0.02 sec but CPU went from 0 to 15% just with this query).
Best Answer
There are many reasons for the problem but first from what You need to start
Give for MySQL at least half of server memory
Second - high cpu show bad index work and/or a lot of sort operations in queries
it is not possible to make conclusion without server check - monitoring and profile all top queries
The speed - it only one side of medal, query could be fast (because data is very small), but if not use indexes or make group by / order by for big data sets - this is give high cpu usage now and will be bottle neck when loading will increase.
Try to use some of available tools for collect real queries statistics:
Thank analyse top 20% of queries by:
based on result - add indexes, change queries when necessary
in 99.99% cases after this - problem will gone