Optimizing MySQL database for Magento on Amazon EC2 server
For KOOLSKOOL we use Amazon EC2 server. Magento is a very powerful ecommerce platform but like any real world application, it needs real server bandwidth.One of the simple ways to optimize the speed is to optimize the MySQL server. The configuration I have used on my EC2 large server is as follows. (This is not a dedicated MySQL server and I am also running apache on this)
wait_timeout=120
tmp_table_size = 64M
max_heap_table_size = 64M
innodb_log_file_size = 100M
innodb_log_buffer_size = 4M
innodb_buffer_pool_size = 2048M
innodb_additional_mem_pool_size = 20M
innodb_flush_log_at_trx_commit = 1
innodb_flush_method=O_DIRECT
innodb_thread_concurrency=8
[mysqld_safe]
#log-error=/var/log/mysqld.log
log-error=/mnt/mysql/err-log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
#log_slow_queries=/var/log/mysqld.slowquery.log
However by doing this I got an error "General error: 1033 Incorrect information in file: './xxx_db/table.frm"
This got fixed immediately by reverting the innodb configuration back. The problem was in the innodb_log_file_size. As I had changed this from 10M to 100M, when the MySQL restarted it would start failing as the existing log were much smaller than what it expects. To fix this you would need
1. Stop MySQL (#/etc/init.d/mysqld stop)
2. Goto the MySQL directory and backup ib_logfile0 and ib_logfile1.
3. Change the my.cnf with the new innodb_log_file_size
4. Start MySQL (#/etc/init.d/mysqld start)
If you check the logs you will find the following
110103 11:24:34 [Warning] Changed limits: max_open_files: 65535 max_connections: 500 table_cache:32512
110103 11:24:34 InnoDB: Log file ./ib_logfile0 did not exist: new to be created InnoDB: Setting log file ./ib_logfile0 size to 100 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Progress in MB: 100
110103 11:24:42 InnoDB: Log file ./ib_logfile1 did not exist: new to be created InnoDB: Setting log file ./ib_logfile1 size to 100 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Progress in MB: 100
110103 11:24:49 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...
110103 11:24:49 InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 3 622597644.
InnoDB: Doing recovery: scanned up to log sequence number 3 622597644
110103 11:24:50 InnoDB: Started; log sequence number 3 622597644
As you have already set your server innodb_buffer_pool_size = 2048M, you will want to make sure that your Linux OS is not caching and swapping you pages. the default swappiness of Linux is set to be 60 (# cat /proc/sys/vm/swappiness) which is good for desktops but not optimized for servers. You would want to set this to 10.
To set this in the running instanyce, ou would #echo 10 > /proc/sys/vm/swappiness
To set this for reboot, you would have to add this line in /etc/sysctl.conf, vm.swappiness=10
By doing this, I have been able to reduce the load time for my homepage by 30%
Useful links
http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/
http://forums.mysql.com/read.php?22,32004,32014
old_passwords=1
key_buffer = 384M
max_allowed_packet = 1M
table_cache = 32M
sort_buffer_size = 10M
read_buffer_size = 10M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
thread_cache_size = 16
query_cache_type = 1
query_cache_size = 48M
max_connections=500key_buffer = 384M
max_allowed_packet = 1M
table_cache = 32M
sort_buffer_size = 10M
read_buffer_size = 10M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
thread_cache_size = 16
query_cache_type = 1
query_cache_size = 48M
wait_timeout=120
tmp_table_size = 64M
max_heap_table_size = 64M
innodb_log_file_size = 100M
innodb_log_buffer_size = 4M
innodb_buffer_pool_size = 2048M
innodb_additional_mem_pool_size = 20M
innodb_flush_log_at_trx_commit = 1
innodb_flush_method=O_DIRECT
innodb_thread_concurrency=8
[mysqld_safe]
#log-error=/var/log/mysqld.log
log-error=/mnt/mysql/err-log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
#log_slow_queries=/var/log/mysqld.slowquery.log
However by doing this I got an error "General error: 1033 Incorrect information in file: './xxx_db/table.frm"
This got fixed immediately by reverting the innodb configuration back. The problem was in the innodb_log_file_size. As I had changed this from 10M to 100M, when the MySQL restarted it would start failing as the existing log were much smaller than what it expects. To fix this you would need
1. Stop MySQL (#/etc/init.d/mysqld stop)
2. Goto the MySQL directory and backup ib_logfile0 and ib_logfile1.
3. Change the my.cnf with the new innodb_log_file_size
4. Start MySQL (#/etc/init.d/mysqld start)
If you check the logs you will find the following
110103 11:24:34 [Warning] Changed limits: max_open_files: 65535 max_connections: 500 table_cache:32512
110103 11:24:34 InnoDB: Log file ./ib_logfile0 did not exist: new to be created InnoDB: Setting log file ./ib_logfile0 size to 100 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Progress in MB: 100
110103 11:24:42 InnoDB: Log file ./ib_logfile1 did not exist: new to be created InnoDB: Setting log file ./ib_logfile1 size to 100 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Progress in MB: 100
110103 11:24:49 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...
110103 11:24:49 InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 3 622597644.
InnoDB: Doing recovery: scanned up to log sequence number 3 622597644
110103 11:24:50 InnoDB: Started; log sequence number 3 622597644
As you have already set your server innodb_buffer_pool_size = 2048M, you will want to make sure that your Linux OS is not caching and swapping you pages. the default swappiness of Linux is set to be 60 (# cat /proc/sys/vm/swappiness) which is good for desktops but not optimized for servers. You would want to set this to 10.
To set this in the running instanyce, ou would #echo 10 > /proc/sys/vm/swappiness
To set this for reboot, you would have to add this line in /etc/sysctl.conf, vm.swappiness=10
By doing this, I have been able to reduce the load time for my homepage by 30%
Useful links
http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/
http://forums.mysql.com/read.php?22,32004,32014
Comments