讀書筆記之-《高性能MySQL》

數據庫相關的知識,看了《高性能MySQL》和《數據庫系統實現》兩本。兩本書綜合看效果更好。 《高性能MySQL》從使用的角度入手,《數據庫系統實現》從原理的角度入手。以前學習數據庫相關的知識時有個執念,一定要弄明白它是怎麼實現的,就直接買了一個《MySQL內核:Innodb存儲引擎》,結果看不懂,束之高閣。

數據庫的知識,個人覺得如下的順序比較合理。

硬盤

《數據庫系統實現》在第二章就單獨用一章的篇幅講解磁盤的存儲原理。這是因爲計算機內置組件中具備持久存儲能力的只有硬盤,軟件屈從於硬件。因此理解磁盤的存儲特點才能理解軟件設計背後的邏輯。磁盤存儲有如下的特點:

  1. 特性A:相比CPU的延遲,磁盤延遲非常非常大。 在《性能之巔》中有做過對比,對於3.3GHz的CPU, 一個指令週期爲0.3ns;機械硬盤一次I/O的延遲爲1~10ms。這個差距有多大,如果一個CPU指令週期爲1s, 那麼機械硬盤一次I/O的延遲爲1~12個月。真是等到花兒都謝了。

  2. 特性B:磁盤是塊設備,每次寫入都是按塊來的。通常一個塊爲512byte。即使用硬盤,得注意不能用輪船隻運輸一個土豆到美國

  3. 特性C:順序IO的性能遠遠高於隨機IO的性能。因爲順序IO避免了尋道時間和旋轉延遲。

上述的特性不僅影響了數據庫的設計,更是深刻影響了操作系統的設計,例如page cache

讀寫

數據庫的操作基本上就是更高階的讀寫: select 和 delete/update 是我們使用數據庫頻率最高的操作了。 所以,數據庫解決的核心問題就是如何組織數據實現高性能的讀寫。

###事務
高性能沒法忽略掉併發,在併發讀寫場景下,就會出現數據一致性的問題。所以事務就用來解決數據一致性的問題了。

默認每條SQL語句都是一個事務, 可以手動設置提交點改變這一規則

在MySQL中,事務的隔離級別有4種。這4種其實不用死記硬背,可以從應用場景推導出來。

未提交讀

事物A修改了記錄a, 沒有提交;事務B讀取表,讀取到了該事務。 這就是未提交讀。 如果我們自己設計數據庫,在原數據上修改字段,如果沒有其他手段的控制,併發情況下就會出現這種情況。由於讀取到了髒數據,也稱爲髒讀。這裏我們也可以將事務換一個熟悉的概念:線程來理解

提交讀

針對上面未提交讀的問題,如果將改動保存在事務的作用域內部,那麼未提交的數據就不會影響其他事務。 這種隔離級別就是提交讀。也叫不可重複讀。因爲失誤內部兩次執行可能得到不一樣的結果。

可重複讀

提交讀面臨的不可重複讀的問題,在可重複讀隔離級別下可以避免。它能保證一個事務多次讀取同一條記錄不會改變。當然,如果事務內部改變了該記錄,另說。這個級別帶來的另一個問題就是[幻讀]。 這個很好理解: 2個事務。事務A 讀取記錄不存在就寫入;事務B寫入記錄。 事務A有可能出現寫入失敗的情況。

可序列化

將事務順序執行。性能最低的做法。

索引

通常查詢數據有兩種典型的場景: 等值查詢區間查詢。 即select * from table where field=a 或者 select * from table where field between a and b。 如果沒有索引,唯一的做法就是全表掃描。這是一種大海撈針的做法。 程序員一般關注兩個點: 問題在哪和怎麼優化。 對於等值查詢,最好的優化方式就是hash了。對於區間查詢,不是hash算法的用武之地,因爲它有個隱藏的邏輯: 排序。 通常,具備排序功能的數據結構有: 排序後的數組,鏈表。 跳躍表。AVL樹,紅黑樹,B樹,B+樹。

爲什麼選擇B+樹?

  1. 硬盤是塊設備。使用B+樹,可以通過在同一個塊中容納N個元素,從而控制B樹的層級不超過3層。減小IO的次數。
  2. B+樹葉子節點是鏈表。方便磁盤順序IO的操作。

性能

性能就是響應時間。 性能問題的排查思路是top-down的方式:

  1. CPU,內存,網絡,IO, 硬盤是否OK?
  2. 不OK只有3種情況: 餘量不足 或者 配置不合理 或者 出故障了。
  3. 索引優化, 表結構優化,查詢優化 其頭並進。

性能問題需要更多是操作系統相關的知識。

複製

這個是MySQL的殺手鐗。如果沒有複製功能,MySQL不可能這麼流行。 複製引申出來的特性: 讀寫分離,負載均衡,高可用,故障切換, 備份, 測試升級。都是濫大街的概念。

複製的實現方式:基於行的複製和基於日誌的複製。

可擴展性

可擴展性就是通過增加資源來提升系統容量的能力。比如MySQL通過讀寫分離,每新增一個Slave節點,數據庫層面的讀併發能力有所提升。當然由於系統分層,每個層級都支持可擴展性,整個系統才具備可擴展性。

數據庫層級的擴展常用策略就是分庫分表這些策略了。

另外,可擴展性跟系統性能是兩回事。 比如Hive性能較低,但是不影響其可擴展性。

高可用

高可用本質上就是更少的宕機時間。 如果從計算機的視角來看待人,人的可用性一般只有50%,按每天8小時工作制,人的可用性只有33%。

利用top-down的思路, 實現高可用,只有兩種辦法: 提升平均失效時間間隔, 簡而言之,就是讓系統兩次宕機中間的時間間隔越長越好;降低平均恢復時間, 簡而言之,就是出了故障修復時間越短越好。 所以,高可用更多的是架構層面的東西, 比如MySQL的互爲主備,負載均衡。

備份

備份是個容易被忽略的話題。屬於那種平時不待見,關鍵時刻需要扛雷。 備份的作用基本有三個: 災難恢復,審計,測試。

《高性能MySQL》是一本兼顧深度和廣度的書,沒有那麼多的原理性細節,適合開發閱讀。如果想更深入學習,估計《數據庫系統實現》是一本比較適合的書。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章