自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MySQL MyISAM引擎是什么?有什么致命缺陷?為何現(xiàn)在都不使用了?

數(shù)據(jù)庫 其他數(shù)據(jù)庫
"當(dāng)我啟動 InnoDB 引擎時,服務(wù)器內(nèi)存突然耗盡..." —— 林淵如何用 Buffer Pool 優(yōu)化化解內(nèi)存危機?

上一篇《MySQL:MyISAM 鎖表致千萬損失!穿越工程師如何逆天改命》,我發(fā)現(xiàn)自己穿越到了 過去,這個年代的 MySQL 居然還在用 MyISAM……次日上午,技術(shù)部緊急會議

"林工,你說要換引擎就換?"

首席 DBA 老張拍案而起,"這系統(tǒng)跑了三年都沒事,你才來三天就搞事情?"

林淵默然調(diào)出昨晚的監(jiān)控數(shù)據(jù):

# 昨夜事故報告
Lock_time_avg: 12.7s  # 表鎖平均等待時間
Table_locks_immediate=2345
Table_locks_waited=8765  # 鎖等待率高達(dá)78%


"各位請看,"林淵點擊投影,"這不是故障,而是架構(gòu)級癌癥。"

連接池危機

詭異現(xiàn)象

SHOW PROCESSLIST;
+-----+------+-----------+------+---------+------+-------+------------------+
| Id  | User | Host      | db   | Command | Time | State | Info             |
+-----+------+-----------+------+---------+------+-------+------------------+
| 101 | app  | 10.0.0.5  | prod | Sleep   | 632  |       | NULL             |
| 102 | app  | 10.0.0.5  | prod | Sleep   | 587  |       | NULL             |
| 103 | app  | 10.0.0.5  | prod | Sleep   | 524  |       | NULL             |

(超過 300 個僵尸連接,消耗 1GB 內(nèi)存)

技術(shù)解析

圖片圖片

  • 線程泄漏原理: MySQL 4.0 采用"每連接每線程"模型,線程執(zhí)行完不會銷毀而是進(jìn)入thread_cache
  • 但當(dāng)wait_timeout設(shè)置過大時(默認(rèn) 8 小時),大量空閑線程堆積。

林淵的解法

// 修改mysqld.cc的線程管理邏輯
void handle_one_connection(THD *thd) {
    while (!abort_loop) {
        if (thd->net.vio->read_packet() == 0) {  // 無數(shù)據(jù)時主動釋放
            thread_scheduler.end_thread(thd, true);
            break;
        }
        do_command(thd);
    }
}

操作結(jié)果: 內(nèi)存占用從 3.2GB 降至 1.8GB,QPS 提升 40%。

SQL 執(zhí)行過程

驚魂時刻:當(dāng)林淵試圖優(yōu)化慢查詢時,系統(tǒng)突然報錯:

ERROR 1064 (42000): You have an error in your SQL syntax...

——用戶輸入的SELECT * FORM orders竟然未被攔截!

解剖流程

圖片圖片

關(guān)鍵發(fā)現(xiàn)

  • 查詢緩存陷阱query_cache_type=ON導(dǎo)致頻繁緩存失效(命中率僅 12%)
  • 解析器漏洞:未啟用嚴(yán)格模式(sql_mode未設(shè)置)允許錯誤語法通過
  • 優(yōu)化器缺陷:缺乏直方圖統(tǒng)計,錯誤選擇全表掃描

林淵的急救包

SET GLOBAL query_cache_size=0;  -- 關(guān)閉毒藥級查詢緩存
SET GLOBAL sql_mode='STRICT_TRANS_TABLES';  -- 啟用嚴(yán)格模式
ANALYZE TABLE orders;  -- 手動更新統(tǒng)計信息

變更存儲引擎

驚險時刻:當(dāng)林淵嘗試在線更換存儲引擎時

ALTER TABLE orders ENGINE=InnoDB;

系統(tǒng)突然僵死!SHOW PROCESSLIST顯示:

| 145 | system user | NULL | NULL | alter table | 89  | copy to tmp table |

引擎切換原理

圖片圖片

林淵的破局操作

  1. 使用pt-online-schema-change工具在線變更(提前 20 年發(fā)明)
  2. 分階段遷移數(shù)據(jù):
# 步驟1:創(chuàng)建影子表
CREATE TABLE _orders_new LIKE orders ENGINE=InnoDB;

# 步驟2:分批拷貝(每次10萬條)
INSERT INTO _orders_new SELECT * FROM orders WHERE id BETWEEN ? AND ?;

# 步驟3:原子切換(0.01秒鎖定)
RENAME TABLE orders TO _orders_old, _orders_new TO orders;

引擎插件的秘密

林淵在ha_myisam.cc中發(fā)現(xiàn)關(guān)鍵結(jié)構(gòu):

struct st_mysql_storage_engine myisam_storage_engine = {
    "MyISAM",
    "MySQL AB",
    "Default engine with fast read speed",
    { /* 函數(shù)指針表 */
        myisam_create_handler,
        myisam_hton_commit,
        NULL  // 事務(wù)相關(guān)為空
    }
};

"原來 MyISAM 的事務(wù)支持是先天殘疾..."他若有所思。

下節(jié)預(yù)告

"當(dāng)我啟動 InnoDB 引擎時,服務(wù)器內(nèi)存突然耗盡..." —— 林淵如何用 Buffer Pool 優(yōu)化化解內(nèi)存危機?

且看下一章節(jié)《InnoDB 架構(gòu)設(shè)計:行級鎖原理、預(yù)寫日志(WAL)、Change Buffer》!

責(zé)任編輯:武曉燕 來源: 碼哥跳動
相關(guān)推薦

2012-03-20 11:16:24

MySQLMyISAM

2019-06-11 16:11:16

MySQLMyISAMInnoDB

2021-08-23 06:22:00

PaaSDevOps平臺即服務(wù)

2022-09-08 08:02:26

MySQL隔離

2021-01-21 17:27:05

區(qū)塊鏈加密貨幣穩(wěn)定幣

2010-05-11 15:06:24

MySQL MyISA

2010-05-21 16:23:52

MySQL MyISA

2010-11-23 11:27:53

MySQL MyISA

2013-04-19 01:42:02

2022-05-16 23:10:54

穩(wěn)定幣區(qū)塊鏈加密貨幣

2019-09-12 14:44:53

云計算云架構(gòu)數(shù)據(jù)

2022-02-27 15:19:26

云彈性安全技術(shù)

2010-05-21 16:10:28

2015-10-30 15:55:43

MySQL

2018-01-08 11:09:00

超頻DIY主板

2009-05-05 10:19:37

存儲引擎InnoDBMyISAM

2018-06-14 10:44:59

MySQLMyISAMInnoDB

2021-08-27 15:46:29

數(shù)字人民幣數(shù)字貨幣區(qū)塊鏈

2022-04-16 14:20:29

MySQL數(shù)據(jù)庫

2023-03-28 07:03:15

gRPCMetadata
點贊
收藏

51CTO技術(shù)棧公眾號