Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
html
Level: Intermediate
Sean A. Walberg (sean@ertw.com), Senior Network Engineer
07 Jun 2007
Applications using the LAMP (Linux®, Apache, MySQL, PHP/Perl) architecture are constantly being
developed and deployed. But often the server administrator has little control over the application itself
because it's written by someone else. This series of three articles discusses many of the server
configuration items that can make or break an application's performance. This third article, the last in the
series, focuses on tuning the database layer for maximum efficiency.
1 of 7 10/05/2007 11:17 AM
Tuning LAMP systems, Part 3: Tuning your MySQL server http://www.ibm.com/developerworks/linux/library/l-tune-lamp-3.html
You can configure mysqld to log slow queries in the aptly named slow query log. Administrators then look at this log
to help them determine which parts of the application need further investigation. Listing 1 shows the configuration
required in my.cnf to enable the slow query log.
[mysqld]
; enable the slow query log, default 10 seconds
log-slow-queries
; log queries taking longer than 5 seconds
long_query_time = 5
; log queries that don't use indexes even if they take less than long_query_time
; MySQL 4.1 and newer only
log-queries-not-using-indexes
These three settings, used together, log any queries that take longer than 5 seconds and any queries that don't use
indexes. Note the caveat about log-queries-not-using-indexes: You must have MySQL 4.1 or newer. The
slow query log is in your MySQL data directory and is called hostname-slow.log. If you'd rather use a different name
or path, you can do so with log-slow-queries = /new/path/to/file in my.cnf.
Reading through the slow query log is best done with the mysqldumpslow command. Specify the path to the logfile,
and you're given a sorted list of the slow queries, along with how many times they're found in the log. One helpful
feature is that mysqldumpslow removes any user-specified data before collating the results, so different invocations
of the same query are counted as one; this helps point out queries in need of the most work.
Cache queries
Many LAMP applications rely heavily on the database but make the same queries over and over. Each time the query
is made, the database must do the same work -- parse the query, determine how to execute it, load information from
disk, and return it to the client. MySQL has a feature called the query cache that stores the result of a query in memory,
should it be needed again. In many instances, this increases performance drastically. The catch, though, is that the
query cache is disabled by default.
Adding query_cache_size = 32M to /etc/my.conf enables a 32MB query cache.
Monitor the query cache
After you enable the query cache, it's important to understand whether it's being used effectively. MySQL has several
variables you can watch to see how things are going in the cache. Listing 2 shows the status of the cache.
2 of 7 10/05/2007 11:17 AM
Tuning LAMP systems, Part 3: Tuning your MySQL server http://www.ibm.com/developerworks/linux/library/l-tune-lamp-3.html
Enforce limits
You should enforce a few limits in mysqld to ensure that the system load doesn't cause resource starvations. Listing 3
shows some important resource-related settings from my.cnf.
set-variable=max_connections=500
set-variable=wait_timeout=10
max_connect_errors = 100
The maximum connections are governed in the first line. Like MaxClients from Apache, the idea is to make sure
only the number of connections you can serve are allowed. To determine the maximum number of connections your
server has seen so far, execute SHOW STATUS LIKE 'max_used_connections'.
The second line tells mysqld to terminate any connections that have been idle for more than 10 seconds. In LAMP
applications, the connection to the database is usually only as long as the Web server takes to process the request.
Sometimes, under load, connections hang around and take up connection table space. If you have many interactive
users or use persistent connections to the database, then setting this low isn't a good idea!
The final line is a safety measure. If a host has problems connecting to the server and ends up aborting the request too
many times, the host is locked until FLUSH HOSTS can be run. By default, 10 failures are enough to cause blocking.
Changing this value to 100 gives the server enough time to recover from whatever problems it has. Using a higher
value doesn't help you much because if the server can't connect once in 100 tries, chances are it's not going to connect
at all.
3 of 7 10/05/2007 11:17 AM
Tuning LAMP systems, Part 3: Tuning your MySQL server http://www.ibm.com/developerworks/linux/library/l-tune-lamp-3.html
MySQL supports well over 100 tunable settings; but luckily, mastering a small handful will take care of most needs.
Finding the right value for these settings involves looking at status variables via the SHOW STATUS command and,
from that, determining whether mysqld is behaving as you wish. You can't allocate more memory to buffers and
caches than exists in the system, so tuning often involves making compromises.
MySQL tunables apply to either the whole mysqld process or each individual client session.
Server-wide settings
Each table is represented as a file on disk and must be opened before it can be read. To speed up the process of reading
from the file, mysqld caches these open files up to the limit specified by table_cache in /etc/mysqld.conf. Listing
4 shows how to display the activity associated with opening tables.
Listing 4 shows that 5,000 tables are currently open and that 195 tables had to be opened because there was no
available file descriptor in the cache (the statistics were cleared earlier, so it's feasible to have 5,000 open tables with a
history of only 195 opens). If Opened_tables increases quickly as you rerun the SHOW STATUS command, you
aren't getting enough hits out of your cache. If Open_tables is much lower than your table_cache setting, you
have too many (some room to grow is never a bad thing, though). Adjust your table cache with table_cache =
5000, for example.
Like the table cache, there is also a cache for threads. mysqld spawns threads as needed when receiving connections.
On a busy server where connections are torn up and down quickly, caching threads for use later speeds up the initial
connection.
Listing 5 shows how to determine if you have enough threads cached.
The important value here is Threads_created, which is incremented each time mysqld has to create a new
thread. If this number increases quickly between successive SHOW STATUS commands, you should look at increasing
your thread cache. You do this with thread_cache = 40, for example, in my.cnf.
The key buffer stores index blocks for MyISAM tables. Ideally, requests for these blocks should come from memory
instead of disk. Listing 6 shows how to determine how many blocks were read from disk versus those from memory.
4 of 7 10/05/2007 11:17 AM
Tuning LAMP systems, Part 3: Tuning your MySQL server http://www.ibm.com/developerworks/linux/library/l-tune-lamp-3.html
Key_reads represents the number of requests that hit disk, and Key_read_requests is the total number.
Dividing the reads by the read requests gives the miss rate -- in this case, 0.6 misses per 1,000 requests. If you're
missing more than 1 per 1,000 requests, you should consider increasing your key buffer. key_buffer = 384M, for
example, sets the buffer to 384MB.
Temporary tables are used in more advanced queries where data must be stored temporarily before further processing
happens, such as in GROUP BY clauses. Ideally, such tables are created in memory; but if a temporary table gets too
large, it's written to disk. Listing 7 shows the statistics associated with temporary-table creation.
Each use of a temporary table increases Created_tmp_tables; disk-based tables also increment
Created_tmp_disk_tables. There is no hard-and-fast rule for the ratio because it depends on the queries
involved. Watching Created_tmp_disk_tables over time shows the rate of created disk tables, and you can
determine the effectiveness of the settings. Both tmp_table_size and max_heap_table_size control the
maximum size of temporary tables, so make sure you set them both in my.cnf.
Per-session settings
The following settings are per session. Take care when you set these numbers, because when multiplied by the number
of potential connections, these options represent a lot of memory! You can change these numbers in the session
through code or for all sessions in my.cnf.
When MySQL must perform a sort, it allocates a sort buffer to store the rows as they're read from disk. If the size of
the data to sort is too large, the data must go to temporary files on disk and be sorted again. If the
sort_merge_passes status variable is high, this is an indication of this disk activity. Listing 8 shows some of the
sort-related status counters.
If sort_merge_passes is high, this is an indication that sort_buffer_size needs attention. For example,
sort_buffer_size = 4M sets the sort buffer to 4MB.
MySQL also allocates memory to read tables. Ideally, the indexes provide enough information to read in only the
needed rows, but sometimes queries (through poor design or the nature of the data) require large chunks of the table to
be read. To understand this behavior, you need to know how many SELECT statements were run and the number of
times you had to read the next row in the table (rather than a direct access through an index). The commands to do so
are shown in Listing 9.
5 of 7 10/05/2007 11:17 AM
Tuning LAMP systems, Part 3: Tuning your MySQL server http://www.ibm.com/developerworks/linux/library/l-tune-lamp-3.html
+---------------+--------+
| Com_select | 318243 |
+---------------+--------+
1 row in set (0.00 sec)
The Handler_read_rnd_next / Com_select gives your table-scan ratio -- in this case, 521:1. Anything over
4000, and you should look at your read_buffer_size, such as read_buffer_size = 4M. If you're growing
this number beyond 8M, it's time to talk to your developers about tuning those queries!
Summary
This article covered the basics of MySQL tuning and concludes this three-part series on Share this...
tuning LAMP components. Tuning is largely about understanding how things work,
determining if they're working properly, making adjustments, and re-evaluating. Each Digg this
component -- Linux, Apache, PHP, or MySQL -- has various needs. Understanding them story
individually helps eliminate the bottlenecks that can slow your application.
del.icio.usPost to
del.icio.us
Slashdot it!
Resources
Learn
"Migrate from MySQL or PostgreSQL to DB2 Express-C" (developerWorks, June 2006) offers an easy way to
migrate from MySQL to DB2 Express-C.
IBM also provides help for MySQL administrators who are moving to DB2 Express-C by means of "Leveraging
MySQL skills to learn DB2 Express" (developerWorks, Feb 2006) and other articles in the series.
"Using MySQL in a federated database environment" (developerWorks, Dec 2004) is a tutorial on accessing
data stored in a MySQL database from WebSphere. IBM makes sure that WebSphere® software works well
with MySQL.
6 of 7 10/05/2007 11:17 AM
Tuning LAMP systems, Part 3: Tuning your MySQL server http://www.ibm.com/developerworks/linux/library/l-tune-lamp-3.html
SHOW VARIABLES and SHOW STATUS are defined well in the MySQL documentation.
If you like blogs, MySQL Performance Blog, Xaprb, and MySQL DBA are worth reading.
In the Architecture area on developerWorks, get the resources you need to advance your skills in the
architecture arena. Developing the proper architecture is the key to scaling LAMP applications.
In the developerWorks Linux zone, find more resources for Linux developers, including Linux tutorials, as well
as our readers' favorite Linux articles and tutorials over the last month.
mytop tells you exactly what's going on with your MySQL server at that instant and provides some key
statistics. This is the first program I turn to when I hear of database problems.
mysqlard graphs key performance indicators in MySQL servers and provides tuning advice.
A MySQL article isn't complete without a link to phpMyAdmin. Even though some interpretation of the status
variables is provided, this product's strength is how easy it makes administration.
Order the SEK for Linux, a two-DVD set containing the latest IBM trial software for Linux from DB2®,
Lotus®, Rational®, Tivoli®, and WebSphere®.
With IBM trial software, available for download directly from developerWorks, build your next development
project on Linux.
Discuss
Get involved in the developerWorks community through our developer blogs, forums, podcasts, and community
topics in our new developerWorks spaces.
Sean Walberg has been working with Linux and UNIX since 1994 in academic, corporate, and Internet
service provider environments. He has written extensively about systems administration over the past
several years.
DB2, Lotus, Rational, Tivoli, and WebSphere are trademarks of IBM Corporation in the United States, other countries, or
both. Linux is a trademark of Linus Torvalds in the United States, other countries, or both. Other company, product, or
service names may be trademarks or service marks of others.
7 of 7 10/05/2007 11:17 AM