38 | 何时使用除了Innodb以外的Memory引擎

一、前言

这里的前言就是上篇评论,顺便准备下初始化数据~
create table t1(id int primary key, c int) engine=Memory;
create table t2(id int primary key, c int) engine=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);

二、内容

2.1.Innodb引擎和Memory引擎区别?

  • 在索引存储上:Innodb主键索引存储的是具体的数据,这种索引存储方式成为索引组织表。而 Memory 引擎采用的是把数据单独存放,索引上保存数据位置的数据组织形式,我们称之为堆组织表

  • 数据存放顺序上:Innodb数据存放总是有序的,Memory数据存放顺序由插入顺序决定

  • 空洞处理上:Innodb插入数据时考虑到数据有序性会在固定位置插入,Memory有空位置就插。

  • 查找效率上:Innodb引擎主键索引和普通索引查找数据方式不同,Memory查找数据主键索引和普通索引没区别

  • 数据变更效率上:数据位置发生变化的时候,InnoDB 表只需要修改主键索引,而内存表需要修改所有索引

  • 字段类型上:支持变长数据类型,不同记录的长度可能不同;内存表不支持 Blob 和 Text 字段,并且即使定义了 varchar(N),实际也当作 char(N),也就是固定长度字符串来存储。

2.2.Memory引擎范围查找时如何用上索引?

  • 可以在内存表上创建b-tree索引,方式:alter table table add index column_btree_index using btree (column);

2.3.为什么不建议你在生产环境上使用内存表?

  • 内存表的锁力度不同于MDL锁,是直接锁全表(堵塞所有操作包括查询)

  • 数据持久化问题。在MS架构中,备库的重启或者down机会导致内存表丢失。在主备恢复时主库发来一个表更新语句,备库就会找不到对应的表结构导致主备复制停止。最重要的是,MySQL知道主库重启之后,出现主备不一致,因此在数据库重启之后,往 binlog 里面写入一行 DELETE FROM table。如果在MM架构中,备库 binlog 里的 delete 语句就会传到主库,数据莫名删除。

2.4.基于2.3我们知道了内存表的问题,那么结论是什么?有特殊情况么,为什么?

  • 把普通的内存表都换成Innodb表代替

  • 用户临时表除外,1)临时表不会被其他线程访问,没有并发问题。2)临时表重启后会删除,不存在清空数据问题。3)备库的临时表不会影响主库的用户线程

三、问题

3.1.这是一个问题

内容:假设刚刚接手的一个数据库上,真的发现了一个内存表。备库重启之后肯定是会导致备库的内存表数据被清空,进而导致主备同步停止。这时,最好的做法是将它修改成 InnoDB 引擎表。假设当时的业务场景暂时不允许你修改引擎,你可以加上什么自动化逻辑,来避免主备同步停止呢?

  • 我们假设的是主库暂时不能修改引擎,那么就把备库的内存表引擎先都改成 InnoDB。对于每个内存表,执行(目的:这样就能避免备库重启的时候,数据丢失的问题。)
    set sql_log_bin=off;
    alter table tbl_name engine=innodb;

  • 如果由于主库异常重启,触发了 HA,这时候我们之前修改过引擎的备库变成了主库。而原来的主库变成了新备库,在新备库上把所有的内存表(这时候表里没数据)都改成 InnoDB 表。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值