前言
MySQL是開源世界里面一顆璀璨的明珠,是最流行的關系型開源數據庫。關于MySQL的著作浩如煙海、充棟盈車。如何才能寫出一本有特色內容的書呢?本書獨辟蹊徑,從運維和實踐相結合的角度,分專題和知識點逐一講解。用源碼去解釋MySQL的知識點,分析碰到的問題,這就是本書的特色。
本書內容所涉及的知識點的選擇,建立在我們多年工作經驗的基礎之上。在平時維護MySQL的過程中,覺得需要引起注意或需要弄清楚的,就把它分享出來,希望能管中窺豹,幫助到讀者朋友。
本書總體分三個部分。
第一部分是MySQL。
在這一部分中,我們介紹了MySQL大部分常見知識點的概念和原理,以及運維經驗。所謂源碼面前,了無秘密。我們從MySQL源碼入門開始,介紹源碼結構、啟動過程、創建連接、表對象緩存等,希望讀者在研究MySQL的時候,能充分借助MySQL源碼開源的優勢,從源碼出發,深入理解MySQL的精髓。當然,限于篇幅,我們只能拋磚引玉,適可而止。期望聰明的讀者能打好基礎,登堂入室。
本部分會重點介紹InnoDB的相關概念,從源碼目錄結構,到InnoDB體系架構及其數據字典、數據存儲結構、索引的實現原理、兩次寫(DoubleWrite)、日志管理機制、InnoDB記錄格式等,都進行了深度的剖析,這塊內容比較復雜,也凝聚了我們巨大的心血,期望能幫助讀者理解其中的相關概念。
隨著MySQL 5.7的成熟及MySQL 8.0的發布,一大波MySQL新技術迎面撲來,我們也不會放過這次學習的機會。值得稱道的是,本書中包含了來自兩位MySQL官方團隊的專家特地給我們供稿的內容,分別詳細講述了MySQL對JSON的支持:MySQL Group Replication和MySQL Document Store。另外,我們也關注了MySQL的GTID、SYS Schema、Semi-Sync Replication等,通過對它們詳細的描述,相信本書能為廣大讀者在快速熟悉和掌握MySQL新版本中出現的功能的學習助上一臂之力。
在講述各個知識點的同時,也會結合工作過程中的一些經驗,跟大家分享自己的心得,例如我們詳細介紹了Percona XtraBackup,也分享了在使用它的過程中碰到的問題。類似地,還有快速刪除大表的案例、死鎖的案例、處理很多文件時碰到的問題等。
最后,值得一提的是,我們還結合各個知識點,對MySQL如何保障數據庫安全做了比較詳細的總結,希望這會改變人們對開源數據庫是否可靠這樣問題的一些有爭議的看法。
第二部分是Galera。
Galera是去哪兒網架構MySQL高可用的技術基礎,我們選擇了以Galera Cluster為基礎的Percona XtraDB Cluster為技術原型,自主研發了針對去哪兒網這種以交易為主需求的電子商務網站的MySQL高可用架構方案,目前已經在線使用了三年,可能也是國內最大的Galera集群,我們也很榮幸能成為MySQL集群化的早期踐行者。
本部分首先介紹了Galera Cluster的設計與實現,讓讀者能從宏觀層面理解它。當然,雖然說是宏觀,但是根據本書寫作的主導思想,也不免會從源碼的角度去剖析其架構、理解其精華。Galera提供了非常豐富的參數讓使用者去靈活地設置,我們也做了重點介紹和解析。
在準備工作完成之后,開始講述Galera的重要知識點:驗證方法、消息傳送、GCache實現原理、SST/IST細節、Donor/Desynced詳解、并發控制、FlowControl及grastate.dat文件揭秘等。仔細研讀了這些內容之后,相信讀者對Galera的理解會更上一層樓。
實踐是本書的另一個特色。所以在Galera部分也加入了不少的實踐案例,例如業務更新變慢的根由溯源、手動構建集群死鎖、從庫的轉移等,通過這些內容分享工作中的一些心得,希望讀者能夠從中受益。
第三部分是Inception。
這是我們從零做出來的一個開源項目。Inception已經開源,其手冊也已經在網絡上廣泛傳播,而本書所要講述的,更是對Inception的一種理解,以及它的意義和設計理念。
關于它的誕生、安裝與使用,以及支持的選項、結果集和命令集等,我們都會介紹。同時,值得注意的是,我們特地安排了一節Inception的彩蛋,里面講述了幾個Inception的特殊功能,它們已經成為了日常工作中不可或缺的重要工具。
如何閱讀本書
基于本書的目的,不是為了幫助你了解整個數據庫的所有內容,如果想要了解整個MySQL數據庫的所有內容,在線手冊無疑是最好的幫手。而本書只關注了在工作中總結出來的對工作有用的重點內容。所謂的重點內容很多,它們之間可以不相關,也可以相關,所以行文組織是比較自由的,相應的閱讀模式也可以比較自由。
書中的MySQL部分,其講到的案例都是非常獨立的,與其他章節沒有什么關系,所以可以采取跳躍式閱讀。對于一些講述原理的內容,如果不同章節中有相關聯的部分,在內容中都會有類型參照關于“某某某”的內容來引導閱讀,所以也不需要刻意遵守章節順序。
書中的Galera部分,大部分是在講述它的實現原理,對于這些內容,最好是按照書中的順序閱讀,這樣才可以最好、最快速地理解它們。而后面會講述一些操作方法及案例等內容,都是基于前面的原理的,案例之間沒有相關性,可以采取跳躍式的閱讀方法,找到自己感興趣的內容。
書中的Inception部分,講述了如何誕生、如何使用、如何設計及所支持的功能等內容,這基本也是有順序的,建議按照書中順序來閱讀。
讀者對象
如果你是一名技術管理者,期望本書能幫你建立對MySQL數據庫的信心,助你完成數據庫方向的技術體系建設,同時也能幫助你了解MySQL的原理和架構。其中的知識要點,如果在面試中使用的話,應該能幫你找到你所渴求的那
1% 的頂尖人才。
如果你是一名架構師,期望本書能幫你在MySQL架構上大顯身手,本書中介紹的MySQL
Replication、Semi-Sync Replication、Group Replication、Galera
Cluster,幾乎囊括了所有MySQL架構的基礎,一定有一款適合你。
如果你是一名開發者,期望本書能幫助你在開發過程中,充分理解MySQL的原理,設計出合理的數據庫表和索引,更好地利用MySQL的優勢,避開MySQL的劣勢,合理使用這個優秀的開源數據庫。
如果你是一名DBA,那么真心恭喜你,本書的知識能助你成為那1\%的頂尖人才。
勘誤和支持
由于我們對MySQL及相關技術的認知水平有限,以及在書寫過程中可能存在一些疏忽,書中可能還存在一些不盡如人意的地方,或是不夠完美還需要改進的地方,抑或是存在一些錯誤等問題。我們希望廣大讀者朋友們能指出其中的問題并留下您的寶貴建議或意見,我們會不斷改進,不斷完善,在此先感謝大家。
如果有朋友有任何關于本書的問題,或者建議意見等,想要與我們聯系,可以發郵件到mysql@dbace.club,我們會盡己所能及時回應大家。
我們會在我們的公眾號上隨時發布本書勘誤細節和最新技術進展,同時也會把相關重要意見不定期地結集發布,為了保持隨時溝通并獲取最新的改進資料,可以掃描右側二維碼關注我們的公眾號:formysql。
在我們學習和使用MySQL的過程中,個人知識和經驗的積累及解決問題的思路大部分都來自朋友們的指點和教誨,我們要感謝幫助過我們的朋友們,特別是一起參與ACMUG社區活動的朋友們,限于篇幅,我們不能點名逐一致謝,就以ACMUG代替吧,感謝ACMUG。
特別地,感謝為本書作推薦的作者:甘泉先生、王瀚漓先生、韓朱忠先生、蓋國強先生、劉啟榮先生、田發明先生、彭立勛先生、金官丁先生、葉金榮先生、祝百萬先生、姜承堯先生、陽學仕先生,諸位師長和朋友的傾情推薦給了我們巨大的信心和勇氣,我們表示衷心的感謝。
由于我們幾人出身工科,文字功底粗陋,同時在技術上也不可避免地破綻百出。這里要特別感謝參與本書校對的李坤、田麗芳、高巖,是他們不厭其煩的耐心核對和明察秋毫的細心校正,才使得本書不至于佶屈聱牙、不堪卒讀。
最后,感謝本書的讀者,你們的支持是我們最大的動力,謝謝你們!
第一部分 MySQL篇
1 MySQL源代碼入門
MySQL源代碼的組織結構
Linux下的編譯
安裝MySQL庫
MySQL 5.7權限處理
2 MySQL啟動過程
3 連接的生命與使命
用戶連接線程創建
MySQL處理請求
總結
4 MySQL表對象緩存
表結構的實現原理
涉及的參數變量
優缺點總結
存在的問題
5 InnoDB初探
InnoDB的源代碼目錄結構
InnoDB存儲引擎文件組織
InnoDB體系結構
InnoDB存儲引擎啟動與關閉
- - InnoDB 存儲引擎的啟動
- - InnoDB存儲引擎的關閉
6 InnoDB數據字典
背景
系統表結構
字典表加載
Rowid管理
總結
7 InnoDB數據存儲結構
表空間文件組成結構
- - 段
- - 簇
- - 頁面
段、簇、頁面組織結構
8 InnoDB索引實現原理
背景
B+樹及B樹的區別
索引的設計
聚簇索引和二級索引
二級索引指針
神奇的B+樹網絡
InnoDB索引的插入過程
一個頁面至少要存儲幾條記錄
頁面結構管理
- - 文件管理頭信息
- - 頁面頭信息
- - 最小記錄和最大記錄
- - 頁面數據空間管理
- - 經典的槽管理
- - 頁面尾部
- - 頁面重組
索引頁面的回收
9 InnoDB記錄格式
背景
從源碼入手了解行格式
總結
10 揭秘獨特的兩次寫
單一頁面刷盤
批量頁面刷盤
- - 兩次寫組織結構
- - 批量刷盤兩次寫實現原理
兩次寫的作用
發散思維
總結
11 InnoDB日志管理機制
InnoDB Buffer Pool
REDO LOG日志文件管理的用途
MTR InnoDB物理事務
日志的意義
日志記錄格式
日志刷盤時機
REDO日志恢復
數據庫回滾
- - 數據庫UNDO段管理
- - 數據庫UNDO日志記錄格式
- - 回滾時刻
總結
12 MySQL 5.7中嶄新的MySQL sys Schema
Performance Schema的改進
sys Schema介紹
- - sys Schema視圖摘要
- - sys Schema重點視圖與應用場景
- - 使用風險
總結
13 方便的MySQL GTID
GTID 相關概念
- - 什么是GTID
- - GTID集合
- - GTID生命周期
GTID的維護
- - gtid_executed表
- - gtid_executed表壓縮
GTID搭建主從
- - 搭建主從時,需要注意的MySQL參數
- - 開啟GTID
- - 搭建主從
使用GTID案例總結
- - 如何跳過一個GTID
- - 利用GTID模式快速改變主從復制關系
- - 在線將傳統模式復制改為GTID模式復制
- - 在線將GTID模式復制改為傳統模式復制
GTID的限制
14 MySQL半同步復制
半同步特性
半同步主庫端
半同步從庫端
半同步實現
插件安裝
半同步自動開關
15 MySQL 5.7多線程復制原理
背景
行之有效的延遲優化方法
MySQL 5.6的多線程復制
MySQL 5.7的多線程復制
- - ordered commit
- - 多線程復制分發原理
- - 異常故障恢復
16 大量MySQL表導致服務變慢的問題
背景
問題分析
案例解決
總結
17 MySQL快速刪除大表
背景
問題分析
案例解決
發散思維
總結
18 兩條不同的插入語句導致的死鎖
背景
問題分析
發散思維
總結
19 MySQL在并發刪除同一行數據時導致死鎖的分析
背景
問題分析
發散思維
總結
20 參數SQL_SLAVE_SKIP_COUNTER的奧秘
21 Binlog中的時間戳
背景
問題分析
發散思維
事務中的事件順序
問題延伸
show processlist中的Time
總結
22 InnoDB中Rowid對Binlog的影響
背景
問題分析
總結
23 MySQL備份:Percona XtraBackup的原理與實踐
備份背景及類型
認識Percona XtraBackup
XtraBackup的工作流程
XtraBackup的備份原理
XtraBackup 需要的權限
innobackupex常用的備份選項說明
XtraBackup備份實踐
- - 全量備份
- - 增量備份
- - 并行備份
- - 其他備份
案例實踐與心得
建議與提醒
24 MySQL分庫分表
分庫分表的種類
分庫分表的原則
分庫分表實現
- - 數據庫層的實現
- - 業務層的實現
25 MySQL數據安全
單機安全
集群安全
備份安全
MySQL實例安全保證
- - Double Write
- - REDO LOG
MySQL集群安全保證
- - 傳統的主從模式如何保證數據庫安全
- - Semi_Sync Replication方式的復制
- - MySQL集群化如何保證數據庫安全
總結
26 MySQL 性能拾遺
適當的數據文件大小
- - 碎片空洞問題
- - 設計問題
合理設計表結構
- - 冗余存儲
- - 拆分存儲
- - 重復存儲
- - 特別提醒
正確使用索引
MySQL系統參數
內存和CPU
磁盤的革命
云中漫步
總結
27 MySQL Group Replication
Group Replication概述
- - 組的概念
- - 多主復制
- - 單獨的通信機制
Group Replication服務模式
- - 單主模式
- - 多主模式
- - 服務模式的配置
Binlog Event的多線程執行
- - group_replication_applier通道
- - 基于主鍵的并行執行
搭建Group Replication復制環境
- - MySQL的參數設置
- - Group Replication插件的使用
- - Group Replication插件的基本參數設置
- - Group Replication的數據庫用戶
- - Group Replication組初始化
- - 新成員加入組
Group Replication的高可用性
- - 組內成員數量的變化
- - 強制移除故障成員
Group Replication的監控
Group Replication的基本原理
- - 狀態機復制
- - 分布式的狀態機復制
- - 分布式的高可用數據庫
深入理解Group Replication中事務的執行過程
- - 本地事務控制模塊
- - 成員間的通信模塊
- - 全局事務認證模塊
- - 異地事務執行模塊
- - 事務流程的總結
深入理解成員加入組的過程
- - 組視圖
- - 加入組時視圖的切換
- - View_change_log_event
- - 恢復
28 MySQL Document Store面面觀
新的JSON數據類型和JSON函數
- - JSON數據類型
- - JSON函數詳解
- - JSON函數的運用
MySQL X Plugin 和 X Protocol
- - 支持NoSQL所做的努力
- - 安裝MySQL X Plugin
MySQL Shell
- - 安裝MySQL Shell
- - 運行MySQL Shell
- - 在MySQL Shell中操作JSON文檔
- - 用腳本執行MySQL Shell
X DevAPI
總結
參考資料
第二部分 Galera篇
29 Galera Cluster的設計與實現
Galera Cluster的優點
Galera的引入
Galera接口
總結
30 Galera 參數解析
狀態參數
變量參數
31 Galera的驗證方法
Binlog與Galera的關系
驗證方法
32 Galera的消息傳送
33 GCache實現原理
配置參數
實現原理
發散思維
34 大話SST/IST細節
初始化節點環境
連接到集群并且做SST/IST
如何提供增量數據
總結
35 Donor/Desynced詳解
實現方式
意義何在
問答環節
36 Galera的并發控制機制
數據復制
寫集驗證
寫集APPLY
事務Commit
37 Galera的流量控制
流量控制的定義
流量控制的實現原理及影響
兩個問題
38 Galera Cluster影響單節點執行效率的因素
單點驗證
并發控制
等待GTID
總結
39 grastate.dat文件揭秘
引子
分析研究
總結
40 Galera Cluster從庫的轉移
沒有開啟Server級GTID的情況
開啟了GTID(server級)的情況
總結
41 Galera Cluster節點與其從庫的隨意轉換
背景
從節點向PXC節點的轉換
PXC節點向異步從節點的轉換
42 業務更新慢,不是由Galera引起的
43 在線改表引發的Galera Cluster集群死鎖
背景
用Binlog來代替觸發器
表名交換
Galera Cluster中的問題
一個有趣的實驗
解決方案
總結
第三部分 Inception篇
44 Inception誕生記
關于SQL審核
- - 半自動化方法
人肉法
不滿現狀的追求
何謂Inception
45 Inception安裝與使用
下載和編譯
啟動配置
線上配置需求
需要額外注意的點
使用方法
舉例說明
環境變量的設置
46 支持選項
選項說明
DDL與DML語句分離
小技巧
47 Inception的備份回滾
備份存儲架構
備份所需條件
48 審核規范
支持的語句類型
公共檢查項
插入語句檢查項
更新、刪除語句檢查項
表屬性檢查項
列屬性檢查項
索引屬性檢查項
修改表語句檢查項
總結
49 參數變量
語法和變量
注意事項
50 友好的結果集
結果集結構
總結
51 命令集語句
遠程信息獲取
顯示本地全部變量
顯示本地某個變量
設置本地變量
顯示OSC執行進度
查看當前processlist
52 Inception的彩蛋
對OSC的支持
- - 可選的OSC參數
- - 查看OSC的執行進度
- - 中止OSC的執行
- - 查看所有OSC執行信息
Inception對SQL執行情況的統計
打印語法樹
53 Inception設計
Inception之源
Inception執行流程