MySQL運維內參_ MySQL、Galera、Inception核心原理與最佳實踐
點評:看這本書就是想知道MySQL用於互聯網行業大併發場景下現在是怎麼處理的。講解MySQL核心存儲源碼實現原理的部分不細緻,MVCC則未涉及。曾經在O'Reilly的高可用MySQL裏講到的MMM、MHA則已經被5.7官方的GTID/Group Replication和Galera Cluster方案代替了?
- InnoDB不是Monty(MySQL作者)開發的?
MySQL源代碼入門
- 代碼目錄:libmysqld、sql、storage
- 5.7: 自動爲root生成臨時密碼?--initialize-insecure
MySQL啓動過程
基於簡化後的代碼講解。不過代碼本身其實說明不了什麼問題,略。
連接的生命與使命
繼續前面的代碼講解風格。
- 每個會話對應一個線程。max_connections
- 這樣看來,InnoDB要支持ACID事務特性,其併發寫(TPS)不可能很高。雖然併發查詢(QPS)可以很高。
- sql_yacc.yy
- INSERT INTO的INTO關鍵字可省略
MySQL表對象緩存
- 精簡的代碼片段:... open_table_from_share
- p41 2部分:
- SHARE的緩存 ??
- SHARE結構被實例化之後的TABLE實例對象的緩存
InnoDB初探
- 源碼目錄:
- fsp=fs physical?
- ibuf=insert buffer,新的名字叫做change buffer,這裏很容易想到OcceanBase...
- mtr=mini transaction(MySQL的MVCC事務實現還是沒有Oracle的強大,譬如,不宜大事務長時間加鎖)
- que:InnoDB內部實現的一個狀態機執行器
- trx:事務實現,MVCC、回滾段、purge、回滾記錄及回滾提交
- mysql系統表是MyISAM存儲引擎的表?
- information_schema:
show create table <tbl-name>
- 5.5+ performance_schema
- information_schema:
- p54 閂(latch):物理頁面的讀寫鎖?我怎麼記得latch相對於Linux內核裏的spinlock
- p57 RR(可重複讀)隔離級別下,如果一個讀事務長期不提交,那麼這個事務後面的所有寫事務的回滾段都不能釋放空間出來
- 導致ibdata文件撐大
- 那麼Oracle裏面是怎麼解決這個問題的???
- 回滾段分離出來單獨文件存儲:innodb_undo_tablespace
- p58 啓動時的恢復:先Redo,再Undo(具體不如直接參考Oracle Core那本書~)
- p60 innobase_fast_shutdown:0,1,2
- 0: 全量的回滾段PURGE、Change Buffer的merge操作、所有日誌刷盤、所有Buffer Pool髒數據刷入數據文件
- p63 checkpoint指的就是對LSN環形buffer刷盤的處理
InnoDB數據字典
- 4個基本的系統表:SYS_TABLES、SYS_COLUMNS、SYS_INDEXES、SYS_FIELDS
- InnoDB用0號表空間0號文件等7號頁面來管理字典信息...
- HASH表緩存及LRU鏈表管理:略
- p74 系統列:Rowid、TRXID、ROLLPTR(應該不支持對於同一行的併發事務吧?)
- InnoDB的庫名稱是直接存入tablename的 => 想重命名數據庫,比較麻煩
- Rowid管理
- 每分配一個在內存中+1,每256寫入一次;重啓時會向上256對齊
InnoDB數據存儲結構
- B+樹:段、簇(extent)、頁面
InnoDB索引實現原理
- B+樹與B樹的區別(作者這裏講解似乎有點問題?)那B*樹又是什麼呢?
- 聚簇索引(primary key)和二級索引
- p95 唯一索引(unique)導致每次修改都會去檢查唯一性,在RR隔離級別下,經常導致死鎖
- InnoDB索引的插入過程(略)
- 頁面結構管理
- p117 槽(slot)?一個頁面內如何管理多個記錄
- 頁面尾部:保存了最新修改的LSN,也是文件頭信息中的FIL_PAGE_LSN
- 頁面重組:類似於GC的概念,略
感覺本章作者講解B+樹的物理存儲管理機制時,很囉嗦。
InnoDB記錄格式
略
揭祕獨特的Double Write(重點)
記錄的邏輯寫轉換爲物理寫,(爲保證磁盤IO的事務性,需要寫2次?我還是有點疑惑的地方...)
InnoDB日誌管理機制
- Buffer Pool
- Redo Log
- LSN:MTR寫入多少log字節,LSN就增長多少(這個有點意思)
- p155 說白了,日誌的作用,就是把隨機寫變成順序寫,用一個速度更快的寫入保證速度較慢的寫入的完整性(!)
- p156 檢查點(lsn_checkpoint_up_to)
- p160 InnoDB的日誌是具有邏輯意義的物理日誌
- Type、(table)spaceid、(page)offset、data ——奇怪,這裏沒有data的長度?
- Type:MLOG_UNDO_INSERT?
- 日誌刷盤時機*
- REDO日誌恢復(略)
- 數據庫回滾
- 《Oracle Core》裏談到Undo日誌其實也是用跟Redo一樣的格式實現的,不過這裏MySQL是怎麼實現的就不知道了
MySQL 5.7中的sys Schema
方便的GTID
- GTID = source_id(server_uuid) : sequence_id
- p205
CHANGE MASTER TO ...
- p214 不支持CREATE TABLE ... SELECT語句,原因是binlog是基於行模式的複製...
半同步複製
- 先同步,timeout的情況下fallback回異步
- 主庫(master)只需要等待至少一個從庫收到並flush binlog到relay log即可。
5.7多線程複製原理
- p231 所有已經處於prepare階段的事務,都是可以並行提交到。
大量表導致服務變慢的問題
- 最終結論:HASH算法的問題???
快速刪除大表
- ibd,‘硬鏈接’,... ?
2條不同的插入語句導致的死鎖(重點)
- p261 隱式鎖:事務1發現自己需要更新的記錄被其他事務(2)佔有了,但還沒有上鎖的時候,此時1會幫忙給2上鎖...
- GAP鎖:爲了實現RR隔離級別的,保證數據在插入時不會導致幻讀;實現依賴於一個heapno的邏輯編號...
- 關於heapno
併發刪除同一行時導致的死鎖
NOT_GAP鎖???將隔離級別從默認的RR改爲Read-Commited
參數SQL_SALVE_SKIP_COUNTER
binlog中的時間戳
- p286 對於慢查詢,鎖等待時間不計算在內?
InnoDB中Rowid對binlog的影響
Percona XtraBackup
- p302 基於InnoDB自身的崩潰恢復機制???
MySQL分庫分表
- 官方:MySQL Connections + MySQL Router + MySQL Fabric?
MySQL數據安全
- p334 Group Replication基於Paxos實現?——但還是需要人工管理維護的吧?
性能拾遺
- p339 5.7.9+,行存儲格式由默認COMPACT改爲了DYNAMIC
- p348 MySQL CLuster的存儲引擎基於NDB?
- p350 傳統磁盤每秒可以完成200次IO,而SSD每秒鐘可完成高達60萬次;SSD已有單盤12TB的容量了...
- p352 MySQL內核的深度定製:AliSQL、TxSQL
- AWS Aurora:數據庫實例與存儲分離???騰訊雲CDB也有類似的版本
Group Replication(重點)
Document Store(JSON)
略
Galera Cluster的設計與實現
- p441 DDL(行數多的時候,大事務)的執行非常危險 => 使用pt-online-schema-change
Galera參數解析
- wsrep(寫集)
Galera驗證方法
Galera消息傳送
GCache
- 每個節點把最新的寫集緩存起來,在需要的時候,如果被選爲Donor節點,可以將緩存的最新增量提供給Joiner
大話SST/IST(狀態傳輸)
Donor/Desynced詳解
Galera併發控制(重點)
Galera流量控制
Galera Cluster影響單節點執行效率的因素
grastate.dat文件
Galera Cluster從庫的轉移
Galera Cluster節點與其從庫的隨意轉換
業務更新慢,不是Galera引起的
- “爲什麼之前的MMM沒有問題?” => PXC使用老版本的客戶端,其auto_commit默認爲False,與新版本默認True不一致
在線改表引發的Galera Cluster集羣死鎖
Inception誕生記(一個SQL審覈軟件,但似乎沒講清楚具體的實現原理?)
按照我的理解,就是Type Check,和虛擬執行,以檢查有無潛在問題?