Showing posts with label Innodb_buffer_pool_size. Show all posts
Showing posts with label Innodb_buffer_pool_size. Show all posts

Friday, July 20, 2012

How to scale inserts in MySQL with Innodb Engine

Usually we thinks/expect that inserts with large number of threads would to be faster but this is not always true(Due to MySQL limitations). The bottleneck might be the CPU, IO controller and OS. MySQL cannot fully use available cores/cpus  in server e.g. MySQL 5.0 (Innodb) is limited to 4 cores etc. We are working on scaling inserts, we have two data processing clusters each of which use 50 threads - so total 100 threads to  insert data into MySQL database (version 5.0.51). The issue, inserts are delayed by minute(s) and the backlog continues to grow... After examining innodb monitor status we found long list of transactions waiting for AUTO-INC lock: For example:


------- TRX HAS BEEN WAITING 9 SEC FOR THIS LOCK TO BE GRANTED: TABLE LOCK table `alertxxxx/alertdata` trx id 0 685590474 lock mode AUTO-INC waiting ------------------ ---TRANSACTION 0 685590465, ACTIVE 10 sec, process no 8457, OS thread id 1169045824 setting auto-inc lock

Why AUTO-INC lock?

 When accessing the auto-increment counter, InnoDB engine uses a special table-level AUTO-INC lock that it keeps to the end of the current SQL statement, not to the end of the transaction. This basically causes all inserts into the same table to serialize. With single row inserts it is normally not too bad but could prevent scalability with multiple threads inserting Bug #16979. However, we can get better through put (inserts per second) with less  number of threads. So after dropping number of threads on both clusters by 50% initially - taking it to 20-20 sessions. The problem almost disappeared and when we further reduced number of threads to 10-10 sessions, the problem disappeared!

Beginning with MySQL 5.1.22 - new locking model introduced for handling Innodb auto-increment in InnoDB. There is a good article which talks about this MySQL Site and Blog

Similarly, if you want to achieve fast insert performance, it can be interesting to load files instead of the loading the inserts one by one : it is 3 to 4 times faster.
If the goal is a huge amount of data already known at that time, it is probably the best option.

Optimization: We can’t use load files for all projects. We need to insert data row by row. For same we can optimize variables/Configuration.

1. Optimize database structure - Design your tables to minimize their space on the disk. This can result in huge improvements by reducing the amount of data written to and read from disk. Smaller tables normally require less main memory while their contents are being actively processed during query execution. Any space reduction for table data also results in smaller indexes that can be processed faster. Ensure columns have the right data types and require least amount of storage; you should try to use the most precise type in all cases. For example, if an integer column is used for values in the range from 1 to 99999, MEDIUMINT UNSIGNED is the best type. For more information about optimizing database structure click MySQL Site. If you store large strings (TEXT) or BLOB, compression may help there.
Use procedure analyse () function to check optimal data type based on table . But before changing data type, check your future plans, So it will not create a  problem in near future.



2. Innodb flush method - e.g. O_DIRECT, if used can help to avoid double buffering between the InnoDB buffer pool and the operating system's filesystem cache. MySQL reference manual explain this MySQL Site.

[ Warning]
           O_DIRECT, serializes the writes in ext3. Howerver, impact can be lowered by using innodb_file_per_table)

3. Innodb thread concurrency - Keep the value low for this option variable (default 8 ok), however the correct value for this variable is dependent on environment and workload. This option variable is explained MySQL Site

4. Innodb buffer pool - Innodb maintains a buffer pool for caching data and indexes in memory. Making the pool larger can improve performance by reducing the amount of disk I/O needed, here is the detail about it.

5. Innodb log file size- The larger the value, the less checkpoint flush activity is needed in the buffer pool, saving disk I/O. But larger log files also mean that recovery is slower in case of a crash. As of MySQL 5.5, recovery times have been greatly improved and the whole log file flushing algorithm has been improved. In 5.5 you generally want larger log files as recovery is improved.

6. Filesystem selection and disk issues - 'xfs' is known to perform very well with MySQL. Also writing the redo logs, binary logs, data files in different physical disks is a good practice with a bigger gain than server configuration. RAID 10 is recommended for best performance, more detail about disk issue can be found at MySQL Site .

Wednesday, May 30, 2012

Basic Performance Tuning Concepts for MySQL

Here is the some common performance tuning concepts/process that I follow to tune the MySQL Server. This is only a basic introduction to performance tuning. For more in-depth tuning, it strongly depends on your systems, data and usage.

Below is the steps I follow to tune MySQL Server.

1.    Query optimization

2.    Data type Optimization

3.    MySQL Server variables optimization

4.    Hardware optimization





1.    Query optimization/Tuning

First, though probably the most important, we look at tuning queries. We check whether they are executing smoothly or not. In particular, we make sure that they’re using indexes, joining on appropriate columns and they’re running quickly. To get the list of those queries which are not using index, executing smoothly or taking more the expected time in execution, we turn on the Slow Query Log for some time, with proper setting of long query time and variables.  At the end we will got the log file with queries which have taken more than expected time in execution.  Run the resulting log through mysqldumpslow, which will produce a summary of the log. This summary will have the detail of query, query execution time, occurrence of query.   This will help you prioritize which queries to tackle first. Then, you can use EXPLAIN to find out what they’re doing, and adjust your indexes accordingly.



Note: - Adding a new index is overhead on I/O. Think before you are adding any index/indexes on the table.



2.    Data type Optimization

In this step we will check weather data type for all columns has been declared correctly or not. We will check it with procedure analyze function. Remember it will calculate/Suggest based on current database size/data.  Before changing it also think about future prospects.



3.    MySQL Server variables optimization

For tuning Innodb performance, the  primary variable is innodb_buffer_pool_size. This is the chunk of memory that InnoDB uses for caching data, indexes and various pieces of information about your database. The bigger, the better. If you can cache all of your data in memory, you’ll see significant performance improvements.

For MyISAM, there is a similar buffer defined by key_buffer_size, though this is only used for indexes, not data. Again, the bigger, the better.

Other variables that are worth investigating for performance tuning are:

query_cache_size - This can be very useful if you have a small number of read queries that are repeated frequently, with no write queries in between. There have been problems with too large a query cache locking up the server, so you will need to experiment to find a value that’s right for you.

innodb_log_file_size - Don’t fall into the trap of setting this to be too large. A large InnoDB log file group is necessary if you have lots of large, concurrent transactions, but comes at the expense of slowing down InnoDB recover, in event of a crash.

sort_buffer_size - Another one that shouldn’t be set too large.

innodb_flush_log_at_trx_commit—How innoDB will commit


4.    Hardware optimization

There are a few recommendations for improving the performance of MySQL by upgrading your hardware:

·         Use a 64-bit processor, operating system and MySQL binary. This will allow you to address lots of RAM.

·         Speaking of RAM, buy lots of it. Enough to fit all of your data and indexes, if you can.

·         If you can’t fit all of your data into RAM, you’ll need fast disks, RAID if you can. Have multiple disks, so you can separate your data files, OS files and log files onto different physical disks.

Friday, May 18, 2012

Calculate the size of innodb_buffer_pool_size and key_buffer_size


As a DBA sometime you will be working on Performance Optimization/Tuning/Configuration Optimization. You must be working to tune RAM of existing/New server. Keep in mind below points.


To working with transactional database you need to configure innodb_buffer_pool_size.  It will cache Indexes as well as data. Use below query to check the size.


SELECT CONCAT(ROUND(KBS/POWER(1024,
IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.49999),
SUBSTR(' KMG',IF(PowerOf1024<0,0,
IF(PowerOf1024>3,0,PowerOf1024))+1,1)) recommended_innodb_buffer_pool_size
FROM (SELECT SUM(data_length+index_length) KBS FROM information_schema.tables
WHERE engine='InnoDB') A,
(SELECT 2 PowerOf1024) B;



If you are working with MyISAM engine, you can calculate size of key_buffer_size using the below query. It will provide you approximate size of key_buffer_size. It cache only MyISAM Indexes.


SELECT CONCAT(ROUND(KBS/POWER(1024,
IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.4999),
SUBSTR(' KMG',IF(PowerOf1024<0,0,
IF(PowerOf1024>3,0,PowerOf1024))+1,1))
recommended_key_buffer_size FROM
(SELECT LEAST(POWER(2,32),KBS1) KBS
FROM (SELECT SUM(index_length) KBS1
FROM information_schema.tables
WHERE engine='MyISAM' AND
table_schema NOT IN ('information_schema','mysql')) AA ) A,
(SELECT 2 PowerOf1024) B;