您好,登錄后才能下訂單哦!
執行insert語句之后插入的數據會不會立馬保存在磁盤中,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
這么一個問題:當你執行一條insert語句之后,插入的數據就立馬保存在磁盤中了么?
答案是不一定!
下面我們來看一下insert語句在寫入磁盤的過程中是如何的!
我們都知道數據在提交到數據庫中會有事務這一步,所以我們可以分兩步來看
1、首先進入server層對sql會進行一些必要的檢查,不會涉及到磁盤的寫入。
2、進入引擎層開始正式提交執行數據。
這里我們首先來了解一下MySQL在InnoDB存儲引擎中,數據是怎么存儲的!
同大多數數據庫一樣,InnoDB有頁(Page)的概念(也可以稱為塊),頁是InnoDB磁盤管理的最小單位。在InnoDB存儲引擎中,默認每個頁的大小為16 KB。而從InnoDB 1.2.x版本開始,可以通過參數InnoDB_page_size將頁的大小設置為4 K、8 K、16 K。若設置完成,則所有表中頁的大小都為InnoDBpagesize,不可以對其再次進行修改。除非通過mysqldump導入和導出操作來產生新的庫。
InnoDB的數據是按數據頁為單位來讀寫的。也就是說,當需要讀一條記錄的時候,并不是將這個記錄本身從磁盤讀出來,而是以頁為單位,將其整體讀入內存。
而將數據從磁盤讀入內存涉及隨機IO的訪問,是數據庫里面成本最高的操作之一,所以為了減少磁盤IO,InnoDB設計了change buffer這個機制。
①在MySQL 5.5之前的版本中,由于只支持緩存insert操作,所以最初叫做insert buffer,只是后來的版本中支持了更多的操作類型緩存,才改叫change Buffer,這也是為什么代碼中有大量的ibuf前綴開頭的函數或變量。
然而使用寫緩沖需要同時滿足兩個條件:
(1) 索引是輔助索引
插入聚簇索引一般是順序的,一般不需要磁盤的隨機讀取,所以不需要使用change Buffer
(2) 索引不是唯一的
輔助索引不能是唯一的,因為在插入緩沖時,數據庫并不去查找索引頁來判斷插入的記錄的唯一性。如果去查找肯定又會有離散讀取的情況發生,從而導致change buffer失去了意義。
②change Buffer的底層實現
change Buffer底層結構是一顆全局的B+樹,負責對所有的表空間進行change Buffer。
所以insert語句并不需要立刻將數據寫入磁盤文件中,只需要修改內存緩沖池當中對應的數據頁就可以了。
4、都知道內存不能保證數據的持久化,如果數據庫在這個過程中宕機了,怎么保證保存在緩存中的數據不丟失。redo log 因此而生,默認情況下每次事務提交都會觸發一次 redo log 刷盤。
5、如果開啟了 binlog 日志,事務邏輯數據將會被寫入 binlog 文件,且為了保證復制安全,建議設置為每次事務提交時,都要將 binlog 日志的變更刷入磁盤。
綜上insert語句成功提交時,數據不是發生立馬磁盤數據寫入的,而是通過 redo log 和 binlog 文件最后把數據寫入到磁盤。然而數據庫緩存區不可能無限大,redo log 也很難容下所有的數據,那緩存區的數據怎么寫到磁盤中呢?
1、當緩沖池中的數據頁達到一定量或數據庫的IO壓力較小時,都會進行數據頁刷盤操作。
2、當開啟共享表空間時,刷新數據時首先會復制一份刷入共享表空間中,由于共享表空間的頁是連續的,對磁盤的寫入也是順序操作,所以這個過程對性能消耗不大。
3、不管是否經過共享表空間,更新的數據頁最終還是需要刷入表空間的數據文件。刷入完成后才能釋放數據庫緩存當中的空間。
4、change Buffer也是數據庫緩存中的一部分,當數據庫緩存空間不足需要交換出部分數據更新頁時,有可能將寫緩沖的數據頁換出,刷入共享表空間中的 change Buffer數據文件中。
5、當 innodb_stats_persistent=ON 時,插入語句所涉及到的數據就會被刷盤到 innodb_table_stats 和 innodbi_ndex_stats 這兩張系統表中。
綜上,一條 insert 語句的所有涉及到的數據在磁盤上會依次寫入 redo log,binlog,共享表空間,最后在自己的用戶表空間落定為安。
從上文可知Change Buffer是一棵B+樹。當需要實現插入記錄的輔助索引頁不在緩沖池中,輔助索引記錄首先會插入到這棵B+樹中。
merge操作可能發生在以下幾種情況下:
①輔助索引頁被讀到緩存中
②Change buffer bitmap頁追蹤到的輔助頁已無可用空間
③master thread工作
第一種情況為當輔助索引頁被讀取到緩沖池中時,例如這在執行正常的SELECT查詢操作,這時需要檢查Insert Buffer Bitmap頁,然后確認該輔助索引頁是否有記錄存放于Insert Buffer B+樹中。若有,則將Insert Buffer B+樹中該頁的記錄插入到該輔助索引頁中。對該頁多次的記錄操作通過幾次操作合并到了原有的輔助索引頁中,因此性能會有大幅提高。
第二種情況Insert Buffer Bitmap 頁用來追蹤每個輔助索引頁的可用空間,并至少有1/32頁的空間。若插入輔助索引記錄時檢測到插入記錄后可用空間會小于1/32頁,則會強制進行一個合并操作,即強制讀取輔助索引頁,將Insert Buffer B+樹中該頁的記錄及待插入的記錄插入到輔助索引頁中。這就是上述所說的第二種情況。
第三種情況就是在Master Thread線程中每秒或每10秒會進行一次Merge Change Buffer的操作,不同之處在于根據線程的工作狀態每次進行merge操作的頁的數量不同。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。