MySQL的memory存儲(chǔ)引擎詳解
Memory 存儲(chǔ)引擎是 MySQL 中一種高性能但非持久化的存儲(chǔ)方案,適合臨時(shí)數(shù)據(jù)存儲(chǔ)和緩存場(chǎng)景。其核心優(yōu)勢(shì)在于極快的讀寫速度,需注意數(shù)據(jù)丟失風(fēng)險(xiǎn)和內(nèi)存占用限制。
在使用時(shí)需結(jié)合業(yè)務(wù)需求,合理配置參數(shù)(如max_heap_table_size),并避免將其用于需要持久化或事務(wù)支持的場(chǎng)景。
1、Memory引擎介紹
MySQL Memory引擎用于創(chuàng)建內(nèi)存中的表,數(shù)據(jù)存儲(chǔ)在內(nèi)存,訪問快速但重啟后數(shù)據(jù)丟失。通過--init-file啟動(dòng)mysqld可持久化數(shù)據(jù)。
內(nèi)存表默認(rèn)使用hash索引,適用于臨時(shí)表,但有限制如不支持BLOB/TEXT,且所有用戶可見。可以利用其速度優(yōu)勢(shì)創(chuàng)建內(nèi)存臨時(shí)表替代MyISAM臨時(shí)表。
數(shù)據(jù)完全存儲(chǔ)在內(nèi)存中:
- 數(shù)據(jù)和索引均存在于內(nèi)存中,無(wú)磁盤 I/O 開銷。
- 重啟 MySQL 或異常關(guān)閉后,數(shù)據(jù)會(huì)丟失。
存儲(chǔ)限制:
- 受max_heap_table_size和tmp_table_size參數(shù)限制。
- 不支持大字段(如TEXT、BLOB)。
存儲(chǔ)結(jié)構(gòu):
- 僅支持哈希索引,適合等值查詢(
=),不支持范圍查詢(>、<、BETWEEN)。 - 不支持事務(wù)
2、Memory內(nèi)存結(jié)構(gòu)
僅支持哈希索引,數(shù)據(jù)存放將索引和數(shù)據(jù)分開存儲(chǔ)。
索引采用Hash的形式,存放主鍵id和指向數(shù)據(jù)的指針,而數(shù)據(jù)則按插入順序存放。稱這種數(shù)據(jù)組織方式為堆組織方式。
如下圖所示:

特點(diǎn):且數(shù)據(jù)的hash的key也不支持有序,value也沒指定的順序。
3、內(nèi)存表的鎖
內(nèi)存表不支持行鎖,只支持表鎖。如果一張表有更新,就會(huì)堵住其它所有在這個(gè)表上的讀寫操作。導(dǎo)致了Memory存儲(chǔ)引擎在進(jìn)行并發(fā)操作時(shí)會(huì)造成大量的阻塞,效率不高。
示例:

在這個(gè)執(zhí)行序列里, session A的update語(yǔ)句要執(zhí)行50秒, 在這個(gè)語(yǔ)句執(zhí)行期間session B的查詢會(huì)進(jìn)入鎖等待狀態(tài)。 session C的show processlist 結(jié)果輸出如下:

跟行鎖比起來(lái), 表鎖對(duì)并發(fā)訪問的支持不夠好。
4、持久化
如果數(shù)據(jù)庫(kù)重啟,所有的內(nèi)存表都會(huì)被清空。
在主備場(chǎng)景:

看一下下面這個(gè)時(shí)序:
- 業(yè)務(wù)正常訪問主庫(kù)。
- 備庫(kù)硬件升級(jí), 備庫(kù)重啟, 內(nèi)存表t1內(nèi)容被清空。
- 備庫(kù)重啟后, 客戶端發(fā)送一條update語(yǔ)句, 修改表t1的數(shù)據(jù)行, 這時(shí)備庫(kù)應(yīng)用線程就會(huì)報(bào)錯(cuò)“找不到要更新的行”。
??注意:內(nèi)存表可能導(dǎo)致主備不一致。
解決方案:
所以, 擔(dān)心主庫(kù)重啟之后, 出現(xiàn)主備不一致, MySQL在實(shí)現(xiàn)上做了這樣一件事兒: 在數(shù)據(jù)庫(kù)重啟之后, 往binlog里面寫入一行DELETE FROM t1。

在備庫(kù)重啟的時(shí)候, 備庫(kù)binlog里的delete語(yǔ)句就會(huì)傳到主庫(kù), 然后把主庫(kù)內(nèi)存表的內(nèi)容刪除。這樣使用的時(shí)候就會(huì)發(fā)現(xiàn), 主庫(kù)的內(nèi)存表數(shù)據(jù)突然被清空了。
無(wú)論是M-S架構(gòu),還是雙M架構(gòu),內(nèi)存表都不適合在生產(chǎn)環(huán)境上作為普通數(shù)據(jù)表使用。
5、優(yōu)缺點(diǎn)

6、應(yīng)用
設(shè)置:
set sql_log_bin=off; alter table tbl_name engine=innodb;
假設(shè)有以下兩張表t1、t2,其中表t1是Memory引擎,表t2是InnoDB引擎。
-- 創(chuàng)建表t1,t2,分別使用Memory引擎和InnoDB引擎; create table t1(id int primary key,c int) engine=Memory; create table t2(id int primary key,c int) engine=innodb; insert into t1values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0); insert into t2values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0); -- 執(zhí)行查詢語(yǔ)句,得到結(jié)果如下圖: select * from t1; select * from t2;
結(jié)果如下:

根據(jù)圖示可知:
內(nèi)存表t1的返回結(jié)果里面0在最后一行, 而InnoDB表t2的返回結(jié)果里0在第一行。
表t1是Memory表,而Memory表的數(shù)據(jù)和索引是分開的。
數(shù)據(jù)組織方式如下:

由上可知,內(nèi)存表的數(shù)據(jù)部分以數(shù)組的方式單獨(dú)存放,而主鍵id索引里,存的是每個(gè)數(shù)據(jù)的位置。主鍵id是hash索引,可以看到索引上的key并不是有序的。
在對(duì)表t1執(zhí)行select *的時(shí)候, 走的是全表掃描, 也就是順序掃描這個(gè)數(shù)組。 因此, 0就是最后一個(gè)被讀到, 并放入結(jié)果集的數(shù)據(jù)。
表t2是InnoDB表,其數(shù)據(jù)就放在主鍵索引樹上,主鍵索引是B+樹。
數(shù)據(jù)組織方式如下:

主鍵索引上的值是有序存儲(chǔ)的,在執(zhí)行select *的時(shí)候, 就會(huì)按照葉子節(jié)點(diǎn)從左到右掃描, 所以得到的結(jié)果里, 0就出現(xiàn)在第一行。
關(guān)于三種不同引擎的總結(jié)

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL的查詢緩存機(jī)制基本學(xué)習(xí)教程
這篇文章主要介紹了MySQL的查詢緩存機(jī)制基本學(xué)習(xí)教程,默認(rèn)針對(duì)InnoDB存儲(chǔ)引擎下來(lái)將,需要的朋友可以參考下2015-11-11
MySQL中可為空的字段設(shè)置為NULL還是NOT NULL
今天小編就為大家分享一篇關(guān)于MySQL中可為空的字段設(shè)置為NULL還是NOT NULL,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
Mysql中基本語(yǔ)句優(yōu)化的十個(gè)原則小結(jié)
這篇文章主要給大家總結(jié)介紹了Mysql中基本語(yǔ)句優(yōu)化的十個(gè)原則,通過學(xué)習(xí)與記住它們,在構(gòu)造sql時(shí)可以養(yǎng)成良好的習(xí)慣,文中介紹的相對(duì)比較詳細(xì)與簡(jiǎn)單明了,需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2017-06-06
用C語(yǔ)言操作MySQL數(shù)據(jù)庫(kù)的通用方法
在為MySQL提供接口方面,C語(yǔ)言具有更好的安全性和性能,本篇文章介紹了C語(yǔ)言操作MySQL數(shù)據(jù)庫(kù)的通用方法,需要了解的朋友可以參考下2015-07-07
MySQL日期格式化yyyy-mm-dd詳解(DATE_FORMAT()函數(shù))
MySQL提供了很多功能強(qiáng)大、方便易用的函數(shù),在進(jìn)行數(shù)據(jù)庫(kù)管理以及數(shù)據(jù)的查詢和操作時(shí),幫助我們提高對(duì)數(shù)據(jù)庫(kù)的管理效率,下面這篇文章主要給大家介紹了關(guān)于MySQL日期格式化yyyy-mm-dd(DATE_FORMAT()函數(shù))的相關(guān)資料,需要的朋友可以參考下2023-01-01
mysql數(shù)據(jù)庫(kù)視圖和執(zhí)行計(jì)劃實(shí)戰(zhàn)案例
這篇文章主要給大家介紹了關(guān)于mysql數(shù)據(jù)庫(kù)視圖和執(zhí)行計(jì)劃的相關(guān)資料,在使用MySQL過程中視圖和執(zhí)行計(jì)劃是一個(gè)很好的工具,文中通過圖文以及代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02
Mysql的Binlog數(shù)據(jù)恢復(fù):不小心刪除數(shù)據(jù)庫(kù)詳解
這篇文章主要介紹了Mysql的Binlog數(shù)據(jù)恢復(fù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04

