Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
MySQL Performance Tuning 101
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
MySQL Performance Tuning 101Ligaya Turmelle
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Little About Me
• Currently MySQL DBA for Kaplan Professional
• Formally of MySQL Support
• ~8 years
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Little About MySQL
• World’s most popular open source database
• Part of LAMP• Main site: http://www.mysql.com• Downloads/Manuals:
– http://dev.mysql.com– http://www.mysql.org
Tuesday, October 23, 2012
- Mysql.org redirects to dev.mysql.com
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
LAYING THE FOUNDATION
Tuesday, October 23, 2012
This is for the traditional MySQL server - not Cluster.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Before starting
• Server– OS– Network– Filesystem
Tuesday, October 23, 2012
OS, storage, swappiness
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Before starting
• MySQL– Optimize queries– Single greatest
performance increase
Tuesday, October 23, 2012
- Slow query log- EXPLAIN- Indexing strategies- DB Design
Image from NASA and is in public domain - http://mediaarchive.ksc.nasa.gov/detail.cfm?mediaid=21807
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Before starting
• General– No easy answers– Benchmark and Test– Under rather than Over
Tuesday, October 23, 2012
- This is a soft skill with no definite answers.- Under allocate is better than over allocate – swapping- There is such a thing as over-tuning.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
MySQL and Memory
Global• Server Start• Large values• once
Per Connection• As needed• Small values• 0 – N times
Global Memory + (max connections * session buffers)
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Where are we right now?
+-----------------------------------------+-----------------| Variable_name | Value+-----------------------------------------+-----------------| auto_increment_increment | 1| auto_increment_offset | 1| autocommit | ON| automatic_sp_privileges | ON| back_log | 50| basedir | /usr| big_tables | OFF| binlog_cache_size | 32768| binlog_direct_non_transactional_updates | OFF| binlog_format | ROW| bulk_insert_buffer_size | 8388608| character_set_client | latin1| character_set_connection | latin1| character_set_database | latin1| character_set_filesystem | binary| character_set_results | latin1| character_set_server | latin1| character_set_system | utf8| character_sets_dir | /usr/share/mysql| collation_connection | latin1_swedish_c| collation_database | latin1_swedish_c
mysql> SHOW GLOBAL VARIABLES;
Tuesday, October 23, 2012
Before we can go someplace, we first have to know where we are.- Majority of settings
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Where are we right now?
[client]socket = /var/run/mysqld/mysql.sock
[mysqld]# These settings are for this specific box.server-id = 1log-bin = /var/lib/mysql/binlogs/XXXXXXXX-BINpid-file = /var/run/mysqld/mysql.pidsocket = /var/run/mysqld/mysql.sock
performance_schemamax_connections = 200
# The ft_min_word_len is set to 3 instead of the default# 3 letter acronyms in the tables with full textft_min_word_len = 3
# We had to modify the default stopwords for full text# are too common in the searches.ft_stopword_file = /var/lib/mysql/stopwords
# Our current production setting for query_cache_size is# setting to see what the best setting for this is.#query_cache_size = 512M
my.cnf/my.ini
Tuesday, October 23, 2012
- All the rest
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Anything else to consider?
• How much RAM?• Dedicated?• 32 or 64 OS?• 32 or 64 MySQL?• Workload?• Storage engines?
Tuesday, October 23, 2012
- Workload – write heavy? Read heavy? What kind of queries?- Engines: mostly InnoDB? MyISAM? Memory? Etc.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
What are we actually doing?
mysql> show global status;+--------------------------------------+---------------+| Variable_name | Value |+--------------------------------------+---------------+| Aborted_clients | 9363 || Aborted_connects | 15925 || Binlog_cache_disk_use | 15684 || Binlog_cache_use | 272758675 || Bytes_received | 1219816389366 || Bytes_sent | 5227022143540 || Com_admin_commands | 12803263 || 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 | 37 || Com_alter_tablespace | 0 || Com_analyze | 0 || Com_begin | 33025640 || Com_binlog | 0 || Com_call_procedure | 18883995 ||
mysql> SHOW GLOBAL STATUS;
Tuesday, October 23, 2012
- Various counters- What is actually being done – not what we think it is doing- Issue it twice with time between so we can find the difference – Delta * ok during normal operations, but best during peak times
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
DANGER – Math ahead!
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Finding the Delta
• Uptime - Given in secondsEx: 8249391 sec = ~2291.5 hrs = ~95.5 days• Used to find your rate of change for a given
time period:
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Example
Tuesday, October 23, 2012
~1.84 MB/sec
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
LETS GET STARTED
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Generalities
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
COM_*
| Com_select | 1530076294 || Com_set_option | 18004985 || Com_signal | 0 || Com_show_authors | 0 || Com_show_binlog_events | 0 || Com_show_binlogs | 27498 || Com_show_charsets | 1 || Com_show_collations | 39 || Com_show_contributors | 0 || Com_show_create_db | 3 || Com_show_create_event | 0 || Com_show_create_func | 1120 || Com_show_create_proc | 14499 || Com_show_create_table | 183538 || Com_show_create_trigger | 0 || Com_show_databases | 435 || Com_show_engine_logs | 0 || Com_show_engine_mutex | 0 || Com_show_engine_status | 1180106 || Com_show_events | 0 || Com_show_errors | 0 || Com_show_fields | 2915144 || Com_show_function_status | 29 || Com_show_grants | 41 || Com_show_keys | 115 |
• Counters• One for each command• Used with Uptime to get a Delta if desired
Tuesday, October 23, 2012
- This is what you are actually doing. Does it follow what you thought you were doing?
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Miscellanious
• Connections• Queries• Questions• Slow_queries• Sort_merge_passes
Tuesday, October 23, 2012
Misc general information that may be of interest- Connections - # of attempts to connect – successful or not- Queries - # of statements executed – including stored procedures- Questions - # of statements sent to the server by clients and executed- Slow_queries - # of queries that took longer then long_query_time seconds to run- Sort_merge_passes - # of merge passes that sort algorithm had to do * if large – consider increasing sort_buffer_size
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
MyISAM
Tuesday, October 23, 2012
This is slowly dying out but still used in the mysql database. Default engine until 5.5
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
How is MyISAM doing?
• Space– Key_blocks_unused
– Key_blocks_used
• High water mark
Formula:key_buffer_size - (Key_blocks_unused *
key_cache_block_size) = amount actually in use
Tuesday, October 23, 2012
- Block size can be found in key_cache_block_size- Key_blocks_used indicates the max number of blocks that have ever been in use at one time.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
How is MyISAM doing?
• Efficiency– Key_read_requests– Key_reads
– Key_write_requests– Key writes
Formula:Key_reads/Key_read_requests = key cache miss rate
Tuesday, October 23, 2012
- Key_read_requests – cache hit – number of reads from the cache- Key_reads – cache miss – number of physical reads from disk. Large value may mean your key_buffer_size is too small * Key cache miss rate – the lower the value, the better- Key_write_requests – write to cache- Key_writes - physical write to disk
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
How is MyISAM doing?
• Locking– Table_locks_immediate– Table_locks_waited
Tuesday, October 23, 2012
- MyISAM uses table level locking. That means that every time you have to change it, the whole table will be locked for the duration. (Yes - concurrent inserts but that only works under specific circumstances (If a MyISAM table has no holes in the data file (deleted rows in the middle), an INSERT statement can be executed to add rows to the end of the table at the
same time that SELECT statements are reading rows from the table.))
- Want to watch Table_locks_waited since this iterates every time you had to wait to get a table lock. If you have high values for this, and you do not use the MyISAM specific features, you may want to consider changing to another storage engine for better concurrency.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
key_buffer_size
• AKA key cache• Global• Index blocks only• 25% - maybe
Tuesday, October 23, 2012
- The index blocks are buffered and shared by all threads.- MyISAM uses the OS file caching system to hold the data files. This means that we have to leave space for the OS file system otherwise we can start swapping. And swapping is bad with MySQL. - For this reason, on a dedicated machine heavy on MyISAM, 25% of RAM is a place to start.
Notes:- The maximum size is 4G for each key cache.- You can have more then one key cache – see the manual for more information on that.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
InnoDB
Tuesday, October 23, 2012
This has changed a lot with 5.5 and 5.6. In 5.5 it is now the default storage engine.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
How is InnoDB doing?
• Space– Innodb_buffer_pool_pages_data– Innodb_buffer_pool_pages_total– Innodb_buffer_pool_pages_free
Tuesday, October 23, 2012
- Pages data – number of pages containing data (clean and dirty)- Pages total – total size in pages (innodb_page_size – compiled in, default is 16KB)- Pages_free – some are fine – but if you see a lot for a while, you over allocated
- Dirty page = a page that has changes in the buffer that has been saved to the log files but has not yet been saved to the data files on disk.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
How is InnoDB doing?
• Efficiency– Innodb_buffer_pool_read_requests– Innodb_buffer_pool_reads
Formula:1 – (Innodb_buffer_pool_read /
Innodb_buffer_pool_read_requests) = buffer pool hit ratio
Tuesday, October 23, 2012
- Read_requests – logical reads from the buffer – high number is good- Reads – logical reads that had to go to disk – high number is bad
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
How is InnoDB doing?
• Waiting– Innodb_buffer_pool_wait_free– Innodb_log_waits
Tuesday, October 23, 2012
- Wait_free – number of times we have had to wait for pages to be flushed so we can use them (purge/garbage collection to free up space) – * large number bad (writes happen in background normally, this makes them wait). Maybe look at innodb_max_dirty_pages_pct- Log_waits – number of times we had to wait for the log buffer to flush so we can continue - large number bad, consider adjusting the log buffer size
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
innodb_buffer_pool_size
• Global• Caches data and indexes• Larger value reduces IO• Self-contained• 80% max
Tuesday, October 23, 2012
- Size in bytes- InnoDB uses clustered indexes – remember- Larger the value – the more it acts like an in-memory database.- Handles and buffers everything for itself – O_DIRECT- Setting it to high can lead to swap === bad
* Note: in 5.5 you can create multiple buffer pools in order to reduce contention during concurrent memory read and write operations. (innodb_buffer_pool_size is divided equally by the value in innodb_buffer_pool_instances… but make sure each instance has at least 1GB) – see manual for more information
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
innodb_log_file_size
• Size of file on disk• Larger the file, the less checkpoint activity
in buffer pool• Size for each log file• Combined log files size < 4GB• Larger log file ➯ longer crash recovery
Tuesday, October 23, 2012
- Less checkpoint activity means less IO- Typically there are 2 log files in a log group (innodb_log_files_in_group)- 5.5 crash recovery code was optimized. So the recovery time will be significantly lower then in 5.1. Test using the full 4G and reduce if needed.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
innodb_log_buffer_size
• Buffer used to write to the log files on disk• Large transactions (?)
– If so – increasing may help reduce IO• Default is 8MB
Tuesday, October 23, 2012
- If you have large transactions, make sure this can fit them. It reduces the need to write the log to disk before the transactions commit.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Others to notice
• innodb_file_per_table• innodb_buffer_pool_instances• innodb_flush_method• FYI - 5.6 Innodb has full-text indexing
33
Tuesday, October 23, 2012
- file_per_table: tells any new innodb tables to create their own tablespace (.ibd file) (system tablespace is still needed). Turned on in current versions of 5.5 and 5.6 by default. Default of off before that.- buffer_pool_instances: number of instances buffer pool broken into. innodb_buffer_pool_size is divided equally by the value in innodb_buffer_pool_instances. Breaking up the buffer pool can lead to better concurrency. Recommended that each instance be at least 1G - flush_method - usually people should use O_DIRECT
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Query Cache
Tuesday, October 23, 2012
Ask if people understand how the query cache works. If they do not, quickly explain it.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Qcache Data
• Qcache_total_blocks• Qcache_free_blocks
– Not what you think it is• Qcache_lowmem_prunes
Tuesday, October 23, 2012
- Free_blocks – think this would be a good thing, but isn’t. The higher the value , the greater the fragmentation in the query cache. * As Qcache_free_blocks approaches Qcache_total_blocks/2 – the more severe the fragmentation * To defragment the query cache use the FLUSH QUERY CACHE statement- lowmem prunes – number of queries deleted from the QC because of low memory
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Qcache Data (con’t)
• Qcache_hits• Qcache_inserts• Qcache_not_cached• Qcache_queries_in_cache
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Qcache Data into Info
• Hit Rate– Higher the value – the better
• Invalidating queries– Bigger the difference – the better
Formula:Qcache_hits / (Qcache_hits + Com_select) =
Query Cache Hit Rate
Comparison:Qcache_inserts << Com_select
Tuesday, October 23, 2012
- Please keep in mind if you have to warm up the cache. This can skew the data.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
query_cache_size
• Global• Allocated all at once• Default is 0 - disabled
Tuesday, October 23, 2012
- The default of 0 disables the query cache. Generally speaking it is recommended that you start with the query cache off, and only if you think it can help you, do you turn it on. Be sure to check the performance of the system when you turn it on to verify that it does increase. There is potential for substantial performance improvement, but do not assume that it will happen. With some query cache configurations or server workloads, it is possible to see a performance decrease.
- Minor side note - http://bugs.mysql.com/bug.php?id=38551 – Query cache mutex still acquired even with query cache size set to 0
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
query_cache_type
• Global – but can be session• 3 options
– 0 Off– 1 On – Default– 2 On Demand
Tuesday, October 23, 2012
0 – do not cache results in the QC or pull the results out of it1 – Cache everything you can – unless it has SELECT SQL_NO_CACHE2 – cache only those queries that I tell you to with SQL_CACHE
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
GOTCHA!
Tuesday, October 23, 2012
The query cache size will still be allocated when the server starts up – even if you have the type set to 0.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Threads and Table cache
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Threads
• Thread == Connection• Thread cache
– Threads_cached– Threads_connected– Threads_created
Formula:Threads_created / Connections = Thread cache miss rate
Tuesday, October 23, 2012
- In regards to this discussion – that is.- Thread cache * threads can be expensive to create and destroy for every connection.- explain how the thread cache works. (starts out empty and as new connections are made it checks the cache to see if one is there. If so – it uses it. If not it makes a new thread. When done it puts the threads back into the thread cache until it has its max value. Watch Threads_created – if large consider increasing the thread_cache
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
thread_cache_size
• Global – but grows as needed• Number to be cached until needed• May increase performance with lots of new
connections– Or may not. Depends on your thread
implementationFormula:
100 – ((Threads-created/Connections) * 100) = Thread cache efficiency
Tuesday, October 23, 2012
Because of modern thread implementations be sure to test to see if you get any improvement.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
The table cache
• table_cache <= v. 5.1.3 > table_open_cache
• Expands as needed• # of open tables for all threads• Watch Opened_tables
Tuesday, October 23, 2012
- Similar to OS level file descriptors. Increasing this value may mean you have to increase the number of file descriptors MySQL requires.- If Opened_tables is constantly increasing and you are *not* using FLUSH TABLES often – consider increasing this.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Session Level
Tuesday, October 23, 2012
- These values should in the global scope be set to a small value since they are used for each session. Only if you have a session that is doing something out of the ordinary should you consider dynamically changing these values. Keep in mind that each query can potentially have 1 – N instances of a session level buffer as well (think multiple temp tables), so if you increase these values for a specific session you have to be sure the space is available.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Temporary Tables
max_heap_table_size
• Dynamic• Sets the maximum size of
all MEMORY tables
tmp_table_size
• Dynamic• Maximum size of internal
in-memory temp tables• Becomes on-disk MyISAM
table
Tuesday, October 23, 2012
- Other reasons temp tables can automatically go to disk: * BLOB * column in a GROUP BY or DISTINCT clause larger than 512 bytes * any column larger than 512 bytes in the SELECT list, if UNION or UNION ALL is used
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
read_buffer_size
• Dynamic• Sequential scan – allocates this size for
each table scanned• Max: 2GB
– Not normally higher then 8M though
Tuesday, October 23, 2012
- For each thread that does a sequential scan…
- Sequential scan includes full table scans
- Do lots of sequential scans – consider increasing this for the session
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
read_rnd_buffer_size
• Dynamic• Used when reading rows in an arbitrary
sequence• Large value potentially can improve
ORDER BY• Max 2GB
– Not normally higher then 8M
Tuesday, October 23, 2012
- to avoid disk seeks- Example of usage – reading rows in a sorted order after the key – sorting
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
sort_buffer_size
• Dynamic• Doing a sort – allocates a buffer of this size• Helps with ORDER BY and/or GROUP BY• Watch Sort_merge_passes
Tuesday, October 23, 2012
- Whole buffer is allocated even if it is not used
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
bulk_insert_buffer_size
• Dynamic• Cache to make bulk inserts faster• Set to 0 to disable
Tuesday, October 23, 2012
- Bulk inserts == INSERT … SELECT, INSERT … VALUES (…), (…), (…)…, LOAD DATA INFILE when adding data to non-empty tables.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
join_buffer_size
• Use with care• Used for:
– Plain index scans– Range index scans– Joins that do not use indexes – full table scan
• One buffer for each full join between tables
Tuesday, October 23, 2012
- I am always hesitant to show this slide. I do not want people to think this can be used to help poorly optimized queries. Should be used as a band – aid or if adding the appropriate indexes is not possible.
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
Questions?
Tuesday, October 23, 2012
PRIVILEGED AND CONFIDENTIAL: FOR INTERNAL KAPLAN USE ONLY
MySQL Performance Tuning 101Ligaya Turmelle
[email protected]: @lig
Tuesday, October 23, 2012