I know very little about database administration but I have to deal with some very large tables on my site.
This server has 64GB of RAM and Intel Core i7-3820 (4 x 3600 MHz). Most of everything it does is MySQL. I use half MyISAM and half InnoDB tables.
I have a couple of tables in MyISAM with billions of rows. Every day I have a script which disables keys, add a few million more rows, then enables keys again. The ALTER TABLE... ENABLE KEYS causes the server to basically stop for a couple of hours. No web site which uses MySQL will load at all, even though they are not accessing the tables being altered at all.
Please also advise me on how to setup the my.cnf file to fix this issue and optimize for rebuilding these indexes as fast as possible. Someone told me to increase the key_buffer_size, but I'm unsure about whether this is good as everyone seems to have a different opinion..? Currently it looks like this:
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
skip-external-locking
max_allowed_packet = 512M
table_open_cache = 1024
sort_buffer_size = 128M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 24G
thread_cache_size = 12
query_cache_size = 256M
thread_concurrency = 16
log-bin=mysql-bin
binlog_format=mixed
server-id = 1
innodb_file_per_table = 1
table_cache = 1024
key_buffer = 256M
key_buffer_size = 12G
myisam_repair_threads = 4
big-tables
bind-address = 127.0.0.1
max_connections = 400
tmp_table_size = 4G
max_heap_table_size = 4G
log_bin = /backup/mysql-bin-logs/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
innodb_buffer_pool_size = 12G
local-infile=1
net_read_timeout = 1800
net_write_timeout = 1800
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
local-infile=1
[myisamchk]
key_buffer_size = 256M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M
key_buffer = 256M
[mysqlhotcopy]
interactive-timeout
MySQL Version
innodb_version 5.5.30
protocol_version 10
version 5.5.30-log
version_comment MySQL Community Server (GPL) by Remi
version_compile_machine x86_64
version_compile_os Linux
UPDATE
I've started a bounty. I changed some of the my.conf settings (also updated in this post). Then when I tried to rebuild the indexes on the large table it started out with Repair with 8 threads (even though the number of repair threads is set to 4) and then when I checked it a few hours later the same command was on Repair with keycache, which is now where it's sitting. So somehow it degraded down from the sort to keycache method (I have no idea why!)
Please help me optimize this! It's supposed to run every day but currently takes several days just to ALTER TABLE... ENABLE KEYS.
Here are some other variables I was asked for, which I do not understand but might help you help me:
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| key_cache_block_size | 1024 |
+----------------------+-------+
+-----------------+-------------+
| Variable_name | Value |
+-----------------+-------------+
| key_buffer_size | 12884901888 |
+-----------------+-------------+
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Key_blocks_unused | 0 |
+-------------------+-------+
UPDATEDATE 2 (5/21)
Thinking it would solve me problem, I have changed my script to entirely truncate the table, reinsert all the rows, and add the indexes one at a time. Instead of disabling keys, adding new rows and then enabling keys.
Unfortunately it did not help because the index creation still goes to repair with keycache.
Here is the result of SHOW CREATE TABLE research_storage1:
CREATE TABLE `research_storage1` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`word1` mediumint(8) unsigned NOT NULL,
`word2` mediumint(8) unsigned NOT NULL,
`origyear` smallint(5) unsigned NOT NULL,
`cat` tinyint(3) unsigned NOT NULL,
`pibn` int(10) unsigned NOT NULL,
`page` smallint(5) unsigned NOT NULL,
`pos` smallint(5) unsigned NOT NULL,
`num` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `pibnpage` (`pibn`,`page`,`word2`,`word1`),
KEY `word21pibn` (`word2`,`word1`,`pibn`,`num`),
KEY `word12num` (`word1`,`word2`,`num`),
KEY `cat1` (`cat`,`word1`),
KEY `year1` (`origyear`,`word1`),
KEY `catyear1` (`cat`,`origyear`,`word1`),
KEY `pibn` (`pibn`,`word1`)
) ENGINE=MyISAM DEFAULT CHARSET=ascii COLLATE=ascii_bin DATA DIRECTORY='/storage/researchdb/' INDEX DIRECTORY='/storage/researchdb/';
I also ran this command:
SELECT data_length/power(1024,3) dat,index_length/power(1024,3) ndx FROM information_schema.tables WHERE table_schema='dbname' AND table_name='tablename';
But the problem with this is that I currently have 2 tables for this table, 1 which is truncated, and 1 which has all the data but no indexes (the former will be replaced with the latter once indexes are complete)... the reason being because I am unable to build the damn indexes (hence the problem). Here is the info for the truncated table, and then the table with data but no indexes:
+------+------------------------+
| dat | ndx |
+------+------------------------+
| 0 | 0.00000095367431640625 |
+------+------------------------+
+-------------------+--------------------+
| dat | ndx |
+-------------------+--------------------+
| 51.61232269741595 | 27.559160232543945 |
+-------------------+--------------------+
Please also note that the table will be 10x larger than this before all the data is received.
show variables like '%version%';)? Some rather old versions have major bugs with ENABLE KEYS. There are also some tidbits on index creation here that might help. – Nathan Jolly May 09 '13 at 09:44ALTER TABLE ... ENABLE KEYSrunning please runSHOW PROCESSLIST;and post the output of that Process only. – RolandoMySQLDBA May 09 '13 at 13:39SHOW VARIABLES LIKE 'key_cache_block_size';,SHOW VARIABLES LIKE 'key_buffer_size';,SHOW GLOBAL STATUS LIKE '%Key_blocks_unused%';)? – Cristian Porta May 10 '13 at 06:33100 - ((key_blocks_unused * key_cache_block_size ) * 100 / key_buffer_size )your cache hit ratio is 100% so it seems that yourkey_buffer_sizeis too small. Can you post the size of your table(MYI and MYD) and theindex_length(SELECT INDEX_LENGTH FROM information_schema.tables WHERE TABLE_SCHEMA = <yourschema> AND TABLE_NAME = <yourtable>;)? Than we can try using Multiple Key Cahce... – Cristian Porta May 16 '13 at 06:23INSERT INTO tbl VALUES (...),(...),(...)...(...),(...);? Do you useLOAD DATA INFILE ...;? – RolandoMySQLDBA May 17 '13 at 18:53SELECT data_length/power(1024,3) dat,index_length/power(1024,3) ndx FROM information_schema.tables WHERE table_schema='yourdb' AND table_name='yourtable';and post whatdatandndxare. – RolandoMySQLDBA May 17 '13 at 18:56SELECT data_length/power(1024,3) dat,index_length/power(1024,3) ndx FROM information_schema.tables WHERE table_schema='yourdb' AND table_name='yourtable'; and post whatdatandndxare. – RolandoMySQLDBA May 20 '13 at 03:25