暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL Memory引擎

346

Hi~朋友,关注置顶防止错过消息

create table t1(id int primary key, c intengine=Memory;create table t2(id int primary key, c intengine=innodb;insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);insert into t2 values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);

数据的组织方式

Memory引擎的表和InnoDB引擎的表我们在执行全表查询的时候,Mmeory引擎的表返回结果0在最后一行,而InnoDB引擎的表0在第一行。这种区别主要是因为数据组织方式的不同

InnoDB引擎索引的组织方式是B+树,是有序存储,在执行select *的时候会从主键索引的叶子节点从左到右扫描,所以0出现在第一行。

Memory引擎的数据和索引是分开的,表的数据部分以数组的方式单独存放,而主键索引中存的是每个数据的位置,且主键id是hash索引,因此在主键索引上的key并不是有序的,当select *会走全表扫描,顺序扫描存放数据的数组,因此0出现在了最后一行。

InnoDB和Memory引擎的数据组织方式

  • InnoDB引擎把数据存储在主键索引上,其他索引上保存的是主键id,该方式称之为索引组织表
  • Memory引擎把数据单独存放,索引上保存的是数据的位置,该方式称之为堆组织表

InnodDB引擎和Memory引擎的不同

  • InnoDB数据总是有序存放,Memory引擎表的数据是按照写入顺序存放
  • 数据文件有空洞时,InnoDB表在插入新数据时为保证有序性,只能在固定的位置写入新值,但是Memory表找到空位就可以插入新值
  • 数据位置发生变更时,InnoDB表只需要修改主键索引,Memory表需要修改所有索引
  • InnoDB表普通索引需要走两次索引查找,Memory表普通索引只走一次和主键索引没有什么区别
  • InnoDB支持变长数据类型,Memory表不支持Blob和Text字段,并且即使定义了VARCHAR(N),也会被当做CHAR(N)

Memory表也支持Hash索引和B-Tree索引,语句如下:

alter table t1 add index a_btree_index using btree (id);alter table t1 add index a_btree_index using hash (id);

Memory表的锁

Memory表不支持行锁,支持表锁。

Session ASession BSession C
update t1 set id = sleep(50) where id = 1;
select * from t1 where id = 2;
show processlist;

可以看出Memory表的锁粒度过大,在处理并发事务时性能较低。

Memory的数据持久性问题

Memory表的数据存放在内存中,如果数据库重启,表中的数据将会被清除,单点下并没有什么问题,但如果在高可用的架构下将会出现问题。

M-S架构下的Memory表的问题

  1. 业务正常访问Master库
  2. 备库硬件升级需要重启,重启以后,内存表的数据会被清空
  3. 备库重启后,主库上有一条update语句需要修改t1的数据行,修改表t1的数据行在传到备库时无法知道要更新的行
  4. 假设恰巧此时发生主备切换,客户端会发现Memory表的数据丢失了。

由于MySQL知道重启后内存表数据会丢失,所以在担心主库重启后,出现主备不一致,MySQL会在数据库重启以后往binlog中写一条TRUNCATE TABLE 库名.memeory表名。

如果你是双M架构,在备库重启的时候,上面的SQL语句会被传递主库执行,然后把主库Memory表的内容也清空了。

本期MySQL Memory引擎就到这,扫码关注,更多内容我们下期再见!

文章转载自程序员修炼笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论