依然使用InnoDB引擎
一、Server層
1. 連接器:連接建立后的權限變更不會對原有連接起作用,重新建立連接后才生效;show processlist命令可以查看系統中的連接,Command列為Sleep的連接為空閑連接;長時間沒有動靜(默認8小時,參數wait_timeout控制),連接會自動斷開;數據庫連接使用長連接有個問題就是,數據庫操作使用的臨時內存是存在連接對象中,只有連接斷開后才釋放,目前數據庫連接池(如druid)已經通過設置無效連接判斷等配置方法解決此問題。
2. 查詢緩存:不建議開啟,因為查詢緩存弊大於利,而且MySQL8.0開始已經廢棄這個功能
3. 分析器:詞法分析和語法分析
4. 優化器:如對使用哪個索引進行選擇,如表關聯時決定各個表的連接順序
5. 執行器:先判斷是否有權限,然后再執行操作
二、InnoDB存儲引擎層:磁盤文件結構包括表空間文件和redo log,內存結構包括緩沖池和日志緩沖區redo log
1. 表空間文件包含系統表空間(數據字典、雙寫緩沖區、修改緩沖區、回滾段undo logs、索引段)和用戶表空間(每個表對應一個用戶表空間,存放當前表數據和索引)
2. redo log:是一組大小固定且能循環使用的一組文件
3. 緩沖池:數據頁:磁盤上的數據在內存中的備份;索引頁:磁盤上的索引在內存中的備份;數據字典:表、索引、外鍵等對象的定義;undo log緩沖區:記錄回滾日志
4. InnoDB邏輯存儲結構解讀
用戶表空間:存有數據和索引,這些數據以段的形式存儲在文件中,有葉節點段(數據段)、非葉節點段(索引段)、回滾段
段:每一個段又分成多個區
區:每個區由64個頁組成,一個頁默認大小為16K,區大小為1M;為了保證區中頁的連續性,區擴展時,InnoDB會一次性從磁盤中申請4~5個區
頁:每個頁又有多條記錄組成,InnoDB中每個頁的默認大小為16KB,是InnoDB讀寫數據的基本單位
記錄:存有具體數據,如有列字段、回滾指針和事務ID
5. InnoDB內存結構:數據新增或修改操作,先寫入到redo log buffer,再寫入到buffer pool中,然后再寫入到redo log文件,提交事務。臟頁落盤是根據checkpoint執行的。
Buffer Pool:數據頁(data page)和索引頁(index page)在內存中使用的數據淘汰策略都是LRU算法;insert buffer page后面改名為change buffer page,修改緩沖區,對要插入或修改的數據暫存在修改緩沖區中,等積累到一定數量再刷新到磁盤,這樣就減少了IO操作,也利於提高維護輔助索引性能;鎖信息(lock info)為了支持對共享資源進行並發訪問,提供數據的完整性和一致性;數據字典(data dictionary)存放的是表定義和索引信息,避免每次使用時都重新在磁盤讀取;自適應哈希索引(adaptive hash index),對某些滿足創建自適應哈希索引條件的查詢語句,MySQL會自動創建自適應哈希索引指向相應的數據頁,提高查詢效率。
double write:執行checkpoint之后,臟頁需要落盤,會先將數據先寫入雙寫緩沖區,然后再寫入系統表空間一份作為備份,再寫入用戶表空間,這樣是防止寫入用戶表空間時系統出問題時,可以使用系統表空間的備份數據再進行數據頁中臟數據落盤。
注意:double write和redo log沒關系,double write是保證臟頁可以正常寫入用戶表空間,如果整個double write出錯,臟頁數據丟失,只能依賴redo log來恢復數據了
redo log buffer:主要是提高寫入redo log文件性能,先寫入redo log buffer再寫入redo log文件,減少IO操作;只有寫入redo log文件的數據才算成功;當插入或修改數據時,先寫入redo log buffer,然后再寫入change buffer,然后寫入redo log文件,數據落盤,提交事務;redo log buffer寫入redo log文件的配置由innodb_flush_log_at_trx_commit控制,默認為1,0表示事務提交時,等待主線程每秒按時寫入redo log;1表示事務提交時,直接寫入redo log文件系統緩存,同時調用fsync,將文件系統緩存中數據寫入磁盤,可以保證數據不會丟失;2表示事務提交時,同時寫入redo log文件系統緩存,不會調用fsync,而是等待文件系統自己將數據寫入磁盤
Additional Memory Pool:已廢除。
6. 內存數據(buffer pool中數據)落盤:當對數據進行插入或修改后,雖然寫入了redo log,同時也修改了buffer pool中的相關緩存數據,造成內存中數據和磁盤中數據不一致,稱內存中數據為臟頁。臟頁落盤,依賴於checkpoint自動執行,其執行時機如下:
sharp checkpoint:關閉數據庫時,執行強制落盤。
fuzzy checkopoint:數據庫運行中進行落盤,其落盤時機如下
1)、根據一定時間頻率,默認10秒,對部分臟頁數據進行落盤
2)、當buffer pool中數據需要進行LRU算法清理數據時,會優先對要清理的臟頁數據進行落盤
3)、臟頁過多,達到innodb_max_dirty_pages_pct配置的閾值時,默認90,即buffer pool的90%,就會執行臟頁落盤
4)、當redo log寫滿時,也會對臟頁進行落盤,以便重用redo log空間
臟頁落盤后就需要對redo log中的數據進行相應處理,分為異步落盤和同步落盤,具體操作根據同步(sync_water_mark=90%*innodb_log_file_size)或異步(async_water_mark=75%*innodb_log_file_size)操作標准值和checkpooint_age進行比較來確定。checkpoint_age=redolog_lsn - checkpoint_lsn,lsn(Log Sequence Number)表示日志版本號,redo log和buffer pool是可以通過lsn進行關聯的,這樣臟頁落盤后,可以根據lsn來判斷redo log中的哪些數據可以被覆蓋。不管是同步還是異步flush checkpoint,都不會阻塞用戶查詢進程
1)、當checkpoint_age < async_water_mark時,即redo log剩余空間超過25%時無需執行flush checkpoint;
2)、當async_water_mark < checkpoint_age < async_water_mark時,執行異步 flush checkpoint,直到滿足checkpoint_age < async_water_mark
3)、當checkpoint_age > async_water_mark時,執行同步flush checkpoint,直到滿足checkpoint_age < async_water_mark