MySQL執行流程 select語句執行流程 增刪改語句執行流程 update語句的整體執行流程和select語句是一樣的。只是少了緩存的那一步驟。 mysql想完成數據的修改,會先從存儲引擎層讀取數據,把數據讀取到服務層進行數據的修改,再通過存儲引擎層把數據更新到資料庫中。 mysql每次讀取數據 ...
MySQL執行流程
select語句執行流程
增刪改語句執行流程
update語句的整體執行流程和select語句是一樣的。只是少了緩存的那一步驟。
mysql想完成數據的修改,會先從存儲引擎層讀取數據,把數據讀取到服務層進行數據的修改,再通過存儲引擎層把數據更新到資料庫中。
mysql每次讀取數據都會讀取16384B的數據,預設是16KB的數據。一頁的數據。
在innodb引擎中設計了 buffer pool 緩衝區。Mysql從磁碟中通過IO讀取數據到buffer pool中,引擎從bffer pool中獲取數據,然後修改,再把數據寫入到buffer pool中。從而完成讀寫的操作,因為是基於記憶體的操作,所以速度是非常快的。
臟數據:buffer pool中的數據,還沒有同步到磁碟中的數據稱為臟數據。
innodb的臟頁刷新機制說明:
1、當innodb中的臟頁比例超過innodb_max_dirty_pages_pct_lwm的值時,這個時候innodb就會開始刷新臟頁到磁碟。
2、當innodb中的臟頁比例超過innodb_max_dirty_pages_pct_lwm的值,而且還超過innodb_max_dirty_pages_pct時innodb就會進入勤快刷新模式(agressively flush)這個模式下innodb會把臟頁更快的刷新到磁碟。
3、還有一種情況叫做sharp checkpoint ,當innodb要重用它之前的redo文件時,就會把innodb_buffer_pool中所有與這個文件有關的頁面都要刷新到磁碟;這樣做就有可能引起磁碟的IO風暴了,輕者影響性能,重者影響可用性。
對於控制刷新機制的各個參數的說明:
1、innodb_max_dirty_pages_pct預設值為75,也就是說當臟頁比例超過75%時才會進入勤快刷新模式。
2、innodb_max_dirty_pages_pct_lwm預設值是0,0對於innodb_max_dirty_pages_pct_lwm來說是一個特殊值,它表示不啟用這個功能;由於沒有啟用這個功能,也就是說innodb_buffer_pool中的臟頁比例會操持在75%左右。
Mysql會在後臺使用若幹線程,負責把buffer pool中的數據刷新到磁碟中去。
後臺常用的線程:
master thread 主線程
IO thread IO操作的線程
Purge thread 清理數據和日誌的線程
Page C1eaner thred 刷髒的線程
查看buffer pool的大小,預設是128M
# 查詢innodb buffer pool相關配置
show VARIABLES like '%innodb_buffer_pool%';
數據存儲到buffer pool中,預設是128M,如果buffer pool存滿了,那麼innodb引擎會使用改良的LRU演算法清理數據。
註意:LRU演算法是最近最久未使用法,mysql會對LRU的演算法進行改良。
官網文檔地址:https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool.html
冷熱分離的方式:
新的數據剛進來的時候進入冷區域,如果下一秒被調用就進去熱區域頂部,熱區域的數據都會向下移動。
redo log 日誌
redo log日誌是innodb存儲引擎自帶的。
避免伺服器宕機或者其他突發事件,導致需要保存到資料庫的數據還沒來得及存儲,所以才有了redo log。在mysql事務的層面上來說,redo log保證了數據的持久性。
問題:數據沒有直接存入到磁碟上,而是先存入到buffer pool中,然後再刷入磁碟,目的是為了性能考慮,但是現在有需要存入到redo log 日誌的磁碟文件中,這樣性能不就下降了?
答案:性能肯定是會有一些影響,但是需要保證數據可恢復的能力。寫入redo log磁碟文件中的速度會更快一些。
隨機磁碟IO和順序磁碟IO的區別。
隨機磁碟IO的情況是數據是會分散到不同的扇區去存儲,因為底層是通過索引的順序來存儲,索引會存儲到不同的扇區。那麼更新數據的時候會增加尋道的時間,寫入數據會變慢。
順序磁碟IO是按著順序追加寫入的。 速度會快一些。
# 通過命令查看innodb_log相關的信息。
show VARIABLES like '%innodb_log%';
預設是分成2組innodb_log_files_in_group
,所以產生2個日誌文件。
每個文件的大小預設是48Minnodb_log_file_size
固定的(可以修改),數據滿了會產生覆蓋的效果。
站在mysql事務的角度,redo log日誌是事務持久性的保證。
log buffer 刷盤機制(什麼時候將記錄的數據存儲到磁碟中),官網說明
log buffer刷盤時間間隔
每隔一秒刷盤一次,但是具體的刷盤策略由innodb_flush_log_at_trx_commit參數來決定。
log buffer 刷盤機制:
innodb_flush_log_at_trx_commit:用來控制redo log刷新到磁碟的策略。
當設置為1的時候,事務每次提交都會將log buffer中的日誌寫入os buffer並調用fsync()刷到log file on disk中。這種方式即使系統崩潰也不會丟失任何數據,但是因為每次提交都寫入磁碟,IO的性能較差。
當設置為0的時候,事務提交時不會將log buffer中日誌寫入到os buffer,而是每秒寫入os buffer並調用fsync()寫入到log file on disk中。也就是說設置為0時是(大約)每秒刷新寫入到磁碟中的,當系統崩潰,會丟失1秒鐘的數據。
當設置為2的時候,每次提交都僅寫入到os buffer,然後是每秒調用fsync()將os buffer中的日誌寫入到log file on disk。
undo log日誌
undo log日誌是innodb存儲引擎自帶的。
undo log可以稱為撤銷日誌或者回滾日誌,站在事務的角度,undo log可以保證事務的原子性。
日誌中記錄的反向操作,例如:把username=”張三” 修改成了username=”趙四”,那麼undo log中記錄的是原來的值,即 username=”張三” 這樣資料庫再發生回滾操作的時候,可以把數據恢復回來。
本地存儲位置:
show VARIABLES like '%undo%';
bin log 日誌
bin log是mysql服務端的日誌。
binary log 二進位日誌,屬於mysql服務層的日誌。bin log是預設關閉的。
binlog是記錄所有資料庫表結構變更(例如CREATE、ALTER TABLE…)以及表數據修改(INSERT、UPDATE、DELETE…)的二進位日誌。
binlog不會記錄SELECT和SHOW這類操作,因為這類操作對數據本身並沒有修改,但你可以通過查詢通用日誌來查看MySQL執行過的所有語句。
主要作用是主從複製和數據恢復的作用。
特點:
記錄DDL和DML的語句,屬於邏輯日誌
沒有固定大小限制,內容可以追加
Server層實現,可以被所有存儲引擎使用
用於數據恢復和主從複製。
show GLOBAL VARIABLES like '%log_bin%';
bin log主從複製的原理流程圖: