MySQL Memory存储引擎表

MEMORY存储引擎特性

Storage limits RAM Transactions No Locking granularity Table
MVCC No Geospatial data type support No Geospatial indexing support No
B-tree indexes Yes T-tree indexes No Hash indexes Yes
Full-text search indexes No Clustered indexes No Data caches N/A
Index caches N/A Compressed data No Encrypted data Yes
Cluster database support No Replication support Yes Foreign key support No
Backup / point-in-time recovery Yes Query cache support Yes Update statistics for data dictionary Yes

MEMORY存储引擎 VS MySQL Cluster

MEMORY存储引擎的使用场景及特点:

  • 涉及会话管理、缓存操作等非关键性数据
  • 发挥内存存储引擎的特性:快速访问、低延迟
  • 只读或已读为主的访问模式(非频繁写)

MySQL Cluster(集群)支持与MEMORY引擎同样的功能并提供更高的性能,并提供MEMORY不支持的更多其他特性:

  • 行级锁支持多线程多用户并发
  • 支持读写混合语句的扩展
  • 可选择磁盘介质永久保存数据
  • Shared-nothing及分布式架构防止单点故障,实现高可用性
  • 数据自动分布在各个节点上,不需考分区或分片解决方案
  • 支持MEMORY中不支持的变长数据类型(包含BLOB 和 TEXT)

MEMORY表性能特点

内存性能被单一线程执行及表级锁开销所制约,当负载增加特别是包含大量写操作时,这将成为性能的瓶颈。尽管是完全使用内存访问,但是在业务繁忙的系统,他们并不见得比InnoDB表更快。在一般查询系统,或读/写工作负载,表级锁粒度将大大降低并发访问。

MEMORY表的特性

  • 每一个内存表都将在磁盘上生成一个文件用于存储表定义(不包含数据),扩展名为tbl_ame.frm
    给MEMORY表的空间都以小块来分配。表使用时100%动态哈希来插入,不需要溢出区或额外的键空间。自由列表无额外的空间需求。删除的记录会被放入链表内并会在有新记录插入时重新使用,MEMORY表也没有通常哈希表中删除插入相关的问题。
  • MEMORY表使用固定长度的行存储格式,可变长度类型如Varchar使用固定长度
  • MEMORY表不能包含BLOB 或 TEXT列
  • MEMORY表支持AUTO_INCREMENT列
  • 像其他非临时表一样,非临时内存表也可多Session共享

MEMORY表DDL操作

创建表时使用ENGINE=MEMORY,MEMORY表大小由max_heap_table_size控制,该值默认为16MB

mysql> CREATE TABLE t (i INT) ENGINE=MEMORY;

mysql> CREATE TABLE test_memory ENGINE= MEMORY as select * from test;

mysql> DROP TABLE test_memory;

MEMORY表支持HASH与BTREE索引,MEMORY表最大支持64个索引,每个索引16列,最大键长度为3072字节
MEMORY表中如果Hash索引包含大量重复的键(多个索引项包含相同值),更新或删除表中键值会非常缓慢,减慢程度与重复度成正比,可使用BTREE索引避免此问题;
MEMORY表支持非唯一键(一般哈希索引不能实现的特性;
索引列可包含NULL值

mysql> CREATE TABLE lookup
        (id INT, INDEX USING HASH (id))
       ENGINE = MEMORY;

mysql> CREATE TABLE lookup
        (id INT, INDEX USING BTREE (id))
       ENGINE = MEMORY;

MEMORY表 与 TEMPORARY表

两者均可将数据放入内存,当临时表数据超过tmp_table_size时,自动转化为磁盘表,性能急剧下降
MEMORY表数据满之后,会提示错误,不会进行转化。

MEMORY表与复制

当主库关闭或重启时,主库上的MEMORY表数据清空,会造成主从数据不一致。
为同步主备数据MEMORY表,当主库启动后第一次使用内存表时,会在主库的binlog中写入一条DELETE语句,来删除从库中的数据。当主库重启及第一次使用内存表间,从库的数据依旧不是最新的数据,为避免该情况,主库启动时使用--init-file重置内存表。
可以将INSERT INTO ... SELECT 或 LOAD DATA INFILE等初始化语句放入该文件中作为MEMORY表
持久的数据源。
MEMORY也支持INSERT DELAYED来导入数据供会话并发访问。

MEMORY表内存管理方式

服务器需要足够的内存来运行所有正在使用的内存表
当删除部分记录时,内存不会立即被回收;只有全部记录都被删除时,内存才会被回收。之前用于存储删除记录的内存空间会被该表的新增记录使用。
收回内存表使用空间的方式执行DELETE、TRUNCATE或DROP TABLE可完全释放该表占用的内存
使用ALTER TABLE ENGINE=MEMORY重建表可释放已删除记录占用的空间

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*))

ALIGN()代表round-up因子,确保行长度是char指针大小的整数倍,sizeof(char×)在32位机器是4,在64位机器上是8.
要控制单个表的最大尺寸,设置max_heap_table_size变量的会话值,(不要改变全局max_heap_table_size的值,除非你希望所有session创建的内存表都使用这个值)

mysql> SET max_heap_table_size = 1024*1024;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.01 sec)

mysql> SET max_heap_table_size = 1024*1024*2;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.00 sec)

当服务重启后,两个表都将使用全局max_heap_table_size
在创建MEMORY表时,也可指定MAX_ROW来限制存储的最大记录,该选项仍然作为限制表最大尺寸的约束,
但不会让表增长超过max_heap_table_size的值,需要将MAX_ROW与max_heap_table_size均合理设置。

参见
http://dev.mysql.com/doc/refman/5.6/en/memory-storage-engine.html
http://www.nowamagic.net/librarys/veda/detail/1405

整理自网络

svoid
2014-09-16


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值