『淺入淺出』MySQL 和 InnoDB

『淺入淺出』MySQL 和 InnoDB
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

作為一名開發人員,在日常的工作中會難以避免地接觸到資料庫,無論是基於檔案的 sqlite 還是工程上使用非常廣泛的 MySQL、PostgreSQL,但是一直以來也沒有對資料庫有一個非常清晰並且成體系的認知,所以最近兩個月的時間看了幾本資料庫相關的書籍並且閱讀了 MySQL 的官方文件,希望對各位瞭解資料庫的、不瞭解資料庫的有所幫助。

mysql

本文中對於資料庫的介紹以及研究都是在 MySQL 上進行的,如果涉及到了其他資料庫的內容或者實現會在文中單獨指出。

資料庫的定義

很多開發者在最開始時其實都對資料庫有一個比較模糊的認識,覺得資料庫就是一堆資料的集合,但是實際卻比這複雜的多,資料庫領域中有兩個詞非常容易混淆,也就是資料庫例項

資料庫:物理操作檔案系統或其他形式檔案型別的集合;
例項:MySQL 資料庫由後臺執行緒以及一個共享記憶體區組成;

對於資料庫和例項的定義都來自於 MySQL 技術內幕:InnoDB 儲存引擎 一書,想要了解 InnoDB 儲存引擎的讀者可以閱讀這本書籍。

資料庫和例項

在 MySQL 中,例項和資料庫往往都是一一對應的,而我們也無法直接運算元據庫,而是要通過資料庫例項來運算元據庫檔案,可以理解為資料庫例項是資料庫為上層提供的一個專門用於操作的介面。

Database - Instance

在 Unix 上,啟動一個 MySQL 例項往往會產生兩個程序,mysqld

當我們使用上面的程式碼建立表時,會在磁碟上的 datadir

如果使用上面的 SQL 在資料庫中建立一張表,B 樹就會使用 id

如果我們使用 id

如果使用 Next-Key 鎖,那麼 Next-Key 鎖就可以在需要的時候鎖定以下的範圍:

(-∞, 21]
(21, 30]
(30, 40]
(40, 50]
(50, 80]
(80, ∞)

既然叫 Next-Key 鎖,鎖定的應該是當前值和後面的範圍,但是實際上卻不是,Next-Key 鎖鎖定的是當前值和前面的範圍。

當我們更新一條記錄,比如 SELECT * FROM users WHERE age = 30 FOR UPDATE;

髒讀

當事務的隔離級別為 READ UNCOMMITED 時,我們在 SESSION 2 中插入的未提交資料在 SESSION 1 中是可以訪問的。

Read-Uncommited-Dirty-Read

不可重複讀

當事務的隔離級別為 READ COMMITED 時,雖然解決了髒讀的問題,但是如果在 SESSION 1 先查詢了一個範圍的資料,在這之後 SESSION 2 中插入一條資料並且提交了修改,在這時,如果 SESSION 1 中再次使用相同的查詢語句,就會發現兩次查詢的結果不一樣。

Read-Commited-Non-Repeatable-Read

不可重複讀的原因就是,在 READ COMMITED 的隔離級別下,儲存引擎不會在查詢記錄時新增間隙鎖,鎖定 id < 5 這個範圍。

幻讀

重新開啟了兩個會話 SESSION 1 和 SESSION 2,在 SESSION 1 中我們查詢全表的資訊,沒有得到任何記錄;在 SESSION 2 中向表中插入一條資料並提交;由於 REPEATABLE READ 的原因,再次查詢全表的資料時,我們獲得到的仍然是空集,但是在向表中插入同樣的資料卻出現了錯誤。

Repeatable-Read-Phantom-Read

這種現象在資料庫中就被稱作幻讀,雖然我們使用查詢語句得到了一個空的集合,但是插入資料時卻得到了錯誤,好像之前的查詢是幻覺一樣。

在標準的事務隔離級別中,幻讀是由更高的隔離級別 SERIALIZABLE 解決的,但是它也可以通過 MySQL 提供的 Next-Key 鎖解決:

Repeatable-with-Next-Key-Lock

REPERATABLE READ 和 READ UNCOMMITED 其實是矛盾的,如果保證了前者就看不到已經提交的事務,如果保證了後者,就會導致兩次查詢的結果不同,MySQL 為我們提供了一種折中的方式,能夠在 REPERATABLE READ 模式下加鎖訪問已經提交的資料,其本身並不能解決幻讀的問題,而是通過文章前面提到的 Next-Key 鎖來解決。

總結

文章中的內容大都來自於 高效能 MySQLMySQL 技術內幕:InnoDB 儲存引擎資料庫索引設計與優化 以及 MySQL 的 官方文件

由於篇幅所限僅能對資料庫中一些重要內容進行簡單的介紹和總結,文中內容難免有所疏漏,如果對文章內容的有疑問,可以在部落格下面評論留言(評論系統使用 Disqus,需要翻牆)。

Reference

mysqld_safe version different than mysqld?
File Space Management
Externally Stored Fields in InnoDB
InnoDB Record Structure
InnoDB Page Structure
Difference between clustered and nonclustered index
InnoDB Locking
樂觀鎖與悲觀鎖的區別
Optimistic concurrency control
MySQL 四種事務隔離級的說明

Refer:

[1] 『淺入淺出』MySQL 和 InnoDB

http://draveness.me/mysql-innodb.html 

[2] 10分鐘讓你明白MySQL是如何利用索引的

http://bit.ly/2vhq6ng

[3] MySQL 索引設計概要

https://segmentfault.com/p/1210000011131061/read


(adsbygoogle = window.adsbygoogle || []).push({});

function googleAdJSAtOnload() {
var element = document.createElement(“script”);
element.src = “//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js”;
element.async = true;
document.body.appendChild(element);
}
if (window.addEventListener) {
window.addEventListener(“load”, googleAdJSAtOnload, false);
} else if (window.attachEvent) {
window.attachEvent(“onload”, googleAdJSAtOnload);
} else {
window.onload = googleAdJSAtOnload;
}

資料庫 最新文章