mysql memory engine

前言

  刚刚遇到了mysql无法插入数据,报错:the table xxx is full

  查询原因,是xx表使用了memory engine,其中mysql的memory engine中有max_heap_table_size = 256M限制,数据稍多就满了。

  解决,修改mysql的配置文件my.ini

#根据自己需求修改大小
tmp_table_size = 256M
max_heap_table_size = 256M

关于memory engine

  1.memory表默认创建index是hash索引,虽然memory也支持btree索引,但需要指定.这里就有个值得注意的地方了,要是在程序中大量使用等值查询一类sql语句,但是如果出现大量的范围查找还是指定btree比较好.

  2.innodb表也支持把数据和索引完全加载到内存中,相比之下,memory占用的内存要小于innodb,且memory全表扫描效率略高于innodb,这应该是和innodb独特的类btree数据结构有关.当然并不能说innodb不如memory,只是读方面和全表扫描上,毕竟行级锁和事务的innodb在大规模的写操作和数据安全性上是memory不能比的.

  3,当数据量比较多的时候一定要修改max_heap_table_size系统变量,否则会限制插入.即使突破了改变的限制,memory表的大小还是会受到OS内存寻址空间,和物理内存的限制,物理内存好理解,在32位的OS上最大支持4G的内存寻址空间也很好理解.

  4.memory不支持text.blob字段类型.使用memory引擎最好不要存太大的数据,实在费内存.memory中char和varchar类型并没有什么区别.

  5.挡在MySQL Replication中使用memory的时候,如果master重启而slave没有的话,那么master自启动开始就没有数据,而slave中则依然存在数据.直到该内存在master上第一次被调用的时候,master会在binlog中写入一条deleted from语句来删除数据,所以这个时候,slave中有在master启动到执行第一条sql之间的间隔时间的过期数据.这个可以通过master上配置--init-file选项来解决

附:
A.memory占用内存的官方计算公式

     SUM_OVER_ALL_BTREE_KEYS(max_length_of_key + sizeof(char*) * 4)

     + SUM_OVER_ALL_HASH_KEYS(sizeof(char*) * 2)

     + ALIGN(length_of_row+1, sizeof(char*))


B.建表的sql和生成测试数据的sp

root@localhost in zhwq 06:59:15>create table mem(
    ->  id int auto_increment not null primary key,
    ->  num int default 100,
    ->  datetime datetime,
    ->  index mem_num_b (num) using btree,
    ->  index mem_num (num),
    ->  index mem_dt_b (datetime) using btree,
    ->  index mem_dt (datetime))engine=memory character  set utf8;
Query OK, 0 rows affected (0.04 sec)
root@localhost in zhwq 06:59:43>delimiter #
root@localhost in zhwq 07:03:20>create procedure insert_mem(p int)
    -> begin
    ->  set @i = 0;
    ->  repeat
    ->    insert into mem (num,datetime) values(floor(rand()*1000),now());
    ->    set @i = @i+1;
    ->  until @i > p end repeat;
    -> end
    -> #
Query OK, 0 rows affected (0.03 sec)

root@localhost in zhwq 07:20:02>delimiter ;

root@localhost in zhwq 07:20:07>call insert_mem(1000);
Query OK, 0 rows affected (0.05 sec)

有网友测试过memory和memcache之间的性能比对,个人认为两者的场景一般不会相同,可比性不太大,有空再研究下

参考

[1] kevon_sun.解决mysql出现"the table is full"的问题 .http://blog.csdn.net/kevon_sun/article/details/7967728

[2] xiao7ng.MySQL Memory Engine Test.http://blog.csdn.net/xiao7ng/article/details/5423877

原文地址:https://www.cnblogs.com/ccdc/p/4119465.html