你知道學校裏的MySQL與社會中的MySQL有啥區別嗎?(詳解一)

簡介:以上文章講述的是【2020總結與2021展望,挑戰阿里面試】接下來我總結一下【接私活用到的數據庫進階版知識與面試知識】。覺得我還可以的可以加羣一起督促學習探討技術。QQ羣:1076570504 個人學習資料庫http://www.aolanghs.com/ 微信公衆號搜索【歡少的成長之路】

前言

簡介

本文經驗都是我看書學習的總結的一些經驗,面試常問的知識點,所以請關注後再繼續觀看學習!下面已經給出了書的目錄!今後將按目錄的順序繼續更新學習心得!

文章最後我會寫一些面試的技術思路,我知道關於面試一直都是熱門話題,有非常多的人寫甚至抄襲,不過我保證我都是原創,我相信聰明的小夥伴應該都發現了文章有一些詞的表述都用到了江蘇連雲港的方言。今後我將持續努力,鑽研技術的同時將自己的收穫通過寫博客文章分享給你們。

個人介紹

我在實習的公司主要負責是做Net C# 語言的。工作應用場景主要是工業控制。平時的私活主要是用Java開發的Web網站,C#開發的PC桌面應用軟件,微信小程序,Anroid移動端開發,IOS(團隊內有專人負責)!

目標

希望通過這些MySQL的內部原理的知識可以幫助大家培養髮現新問題的洞察力,能學習和實踐的結合設計出維護基於MySQL的系統。

目錄

第一章:數據庫基礎知識(正在更新)
第二章:基準測試
第三章:服務器性能刨析
第四章:Schema與數據庫類型優化
第五章:創建高性能的索引
第六章:查詢性能優化
第七章:MySQL高級特性
第八章:優化服務器設置
第九章:操作系統和硬件優化
第十章:複製底層實現
第十一章:可擴展的MySQL
第十二章:高可用性
第十三章:雲端的MySQL
第十四章:應用層優化
第十五章:備份與恢復
第十六章:MySQL用戶工具














正文

MySQL簡單的運行流程

特性

MySQL最與衆不同的就是他的特性【存儲引擎架構】。這種架構的設計將查詢處理,其他系統任務和數據的存儲/提取相分離。這樣做的好處是可以在使用時根據性能,特性以及其他需求選擇相應的數據存儲方式。

連接的實現分析

每個客戶端連接都會在服務器進程中擁有一個線程,這個連接的查詢只會在這個線程中單獨執行,該線程只能輪流在某個CPU核心或者CPU中執行。服務器會負責緩存緩存線程,因此不需要爲每一個新建的連接創建或者銷燬線程。
當客戶端發送連接之後,服務器會對其進行認證。基於用戶名,主機信息,密碼。如果使用了SSL方式連接還可以使用X.509證書認證。認證成功之後服務器會驗證你的查詢權限等。

SQL語句分析

舉一個Select語句的例子:在解析查詢之前

  1. 服務器會先檢查查詢緩存
  2. 如果能夠在其中找到對應的查詢,服務器就不必再執行查詢解析,優化和執行的整個過程
  3. 而是直接返回查詢緩存中的結果集

控制MySQL併發讀寫

問題:email郵箱!一個郵箱的郵件都是串行在一起的彼此首位相連。這種格式對於讀取和分析郵件信息非常友好,同時投遞也很容易,只要在末端添加郵件就可以了。正題來了假如兩個進程在同一時刻對同一個郵箱進行投遞郵件時會發生什麼?

答案:數據會被破環,兩封郵件內容會交叉的附加在郵箱文件的末尾!

方案:通過lock鎖防止數據損壞。如果客戶端試圖投遞郵件,而郵箱已經被其他客戶鎖住,那就必須等待,直到釋放才能進行投遞。

通過這種方案的確可以做到數據不被破壞,但是如果只能等待的話併發效率太低了!讀寫鎖的展開

讀寫鎖:

  1. 讀鎖是共享的或者說是相互不阻塞的。多個客戶在同一時刻可以同時讀取同一個資源互不干擾。
  2. 寫鎖是排他鎖也就是會阻塞其他的寫鎖和讀鎖。這也是出於安全考慮。只有這樣才能確保在一定的時間內一個用戶能夠執行寫入並防止其他用戶讀取正在寫入的同一資源。

通過這種方式解決了數據破壞問題,效率也有所提高,真正大型項目還是不夠!鎖粒度與鎖策略的展開

解決目標:提高資源的併發的方法可以只鎖定需要修改的部分數據,而不是所有資源。更理性的方式是隻對會修改的數據片進行精確鎖定,任何時候在給定的資源中,鎖定的數據量越少則系統開發程度越高,只要不衝突就可以了。

鎖策略與鎖粒度:在鎖的開銷與安全性尋求一個平衡,這種平衡也會影響性能。大多數數據庫會直接用行級鎖。MySQL提供了多種選擇,每一個存儲引擎都可以實現自己的鎖粒度和鎖策略。比如將鎖粒度固定在某個級別,可以爲某些場景提供更好的性能。如果性能需求提高直接提高鎖粒度就可以了。下面展開兩個重要的鎖策略表鎖和行級鎖。

表鎖與行級鎖:

區別:

  1. 表鎖是最基本的鎖策略,也是開銷最小的策略,表鎖是直接鎖定整張表,一個用戶對錶進行寫入操作時需要獲得寫鎖纔可以。獲取寫鎖之後會阻塞其他用戶對他的讀寫操作。只有沒有寫鎖的時候其他讀取的用戶才能獲得讀鎖進行讀取。讀鎖之間是不阻塞的
  2. 行級鎖可以心最大程度上支持併發處理,同樣的道理,也是開銷最大的策略。行級鎖只有在存儲引擎層實現,MySQL服務器層不參與實現。

事務:

什麼是事務呢?事務就是銀行的需求一樣,如果在執行過程中斷電或者不符合條件的情況被停止執行,則已經執行的sql語句全部回滾。也就是說 事務操作過程要不全部成功,要不全部失敗!事務ACID的特性可以確保銀行不會弄丟你的錢

事務的ACID

  1. 原子性:要不全部成功,要不全部失敗,不可能只執行其中一部分操作,這就是事務的原子性
  2. 一致性:一致性主要體現在數據一致性,事務最終沒有提交,事務所修改的數據不會保存在數據庫中
  3. 隔離性:當前事務執行的修改在最終提交之前,對其他事務是不可見的。
  4. 持久性:一旦事務提交,將修改的數據持久化到數據庫中就算數據庫斷電崩潰也不會丟失。

應用開發中的選型

實現的ACID數據庫跟沒有實現ACID數據庫,通常會需要更長的CPU處理能力以及更大的內存和磁盤空間。所以一定要根據當前特定的需求業務選擇相應的數據庫存儲引擎。如果不需要事務,選擇非事務存儲引擎可以獲得更高的性能。

事務的四種隔離級別

  1. read uncommitted(未提交讀):事務中的修改即使沒有提交對其他事務都是可見的,也可以稱爲髒讀,這個級別會導致很多問題,從性能上來說不會比其他隔離級別好太多,但缺乏其他隔離級別的很多好處。除非真的有特定的需求,一般很少用
  2. reda committed(提交讀):大多數數據庫默認的都是read committed,但是MySQL默認的不是這個!一個事務從執行到提交前,其他事務都是不可見的,有時候也可以叫不可重複讀,因爲兩次執行同樣的查詢可能會得到不一樣的查詢結果。
  3. repeatable read(可重複讀):repeatable read解決了read committed髒讀的問題,這個隔離級別也是MySQL默認的隔離級別。該級別保證了同一個事務多次執行可以讀取同樣的數據,但是有個缺陷就是存在幻讀!幻讀就是當事務在某個範圍內讀取數據時,這時另一個事務在這個範圍插入了數據,當讀取的事務再次讀取該範圍時會產生幻行。通過多版本併發控制(MVCC)解決了幻讀的問題。
  4. serializable(可串行化):這是最高的隔離級別,它通過強制事務在從串行上執行,避免了前面說的幻讀問題,簡單來說就在在讀取數據時加一個鎖,這就暴露了另一個問題,大量的加鎖會導致出現爭鎖超時的問題。只有特定的需求情況下或者可以接收沒有併發的情況下才考慮這種隔離級別。

MySQL中的事務

MySQL默認採用自動提交的模式。也就是說如果不是專門寫一個事務執行,則每個查詢都可以看成是一個事務。
第一圖可以查看當前的事務提交模式,第二張圖可以修改事務提交模式 1或者NO表示啓動,0或者OFF表示禁用

  1. 當autocommit=0時,所有的查詢都是在一個事務,直到專門直接commit或者rollback回滾,該事務結束同時又開始了新的事務,修改autocommit對非事務型的表不會有任何影響。對於這類表來說沒有commit或者rollback的概念,也可以說相當於一直處於啓用的狀態
  2. MySQL可以通過執行以下代碼設置隔離級別。
set transaction isolationlevel  //設置隔離級別,設置隔離級別會在下一個事務開始的時候生效

在這裏插入圖片描述
在這裏插入圖片描述

死鎖:

很多時候會看到博客文章標題出現死鎖數據,那麼死鎖到底是什麼?什麼導致了死鎖?

死鎖是指兩個或多個事務對同一資源的相互佔用。當前執行寫操作時,另一方需要獲得一個寫鎖,而另一個事務也是需要獲得一個寫鎖。兩個事務都等待着對方釋放鎖,同時又持有對方的鎖。從而導致惡性循環的現象。除非有外部因素介入纔可能接觸死鎖。死活會影響查詢數據的效率。以下兩個情況會死鎖

  1. 當多個事務試圖以不同的順序鎖定資源時,就可能發生了死鎖
  2. 多個事務同時訪問同一個資源時,也會產生死鎖
事務1start transaction
update StockPrice set close=45 where stockid=4 and date=2021-01-31update StockPrice set close=40 where stockid=3 and date=2021-01-31
事務2start transaction
update StockPrice set close=35 where stockid=3 and date=2021-01-31update StockPrice set close=30 where stockid=4 and date=2021-01-31

以上代碼舉個例子幫助不懂的更好的理解。如果兩個事務都執行的update的第一條語句,根據鎖的過程會鎖定當前的那一條數據(鎖定id等於3和4的數據)也就是給他上鎖,當兩個事務執行第二條sql語句執行的時候(操作id等於3和4)就存在了死鎖的情況因爲兩個都上鎖也都等待着對方釋放鎖。

爲了解決這一問題,數據庫系統實現了死鎖超時機制和各種死鎖檢測。InnoDB存儲引擎檢測到死鎖的循環依賴,會立即返回一個錯誤,這種方式很有效。還有一種方式是當查詢的時間達到鎖等待超時的設定後放棄鎖請求。這種不太友好。

目前InnoDB的處理方式是將持有最少行級鎖的事務進行回滾(這是相對比較簡單的死鎖回滾算法)

死鎖產生有雙重原因

  1. 數據存在衝突
  2. 存儲引擎的實現方式

如何處理死鎖呢?

  1. 死鎖發生後,只有部分或者完全回滾其中一個事務,才能打破死鎖這是無法避免的。
  2. 大多數情況下只需要重新執行因死鎖導致的事務即可。

先給貓洗個澡等會回來繼續寫
在這裏插入圖片描述

事務日誌

存在優勢:事務日誌可以提高事務的效率。

實現方式:存儲引擎在修改表數據的時候只需要修改其內存拷貝,再把修改的數據持久化到事務日誌中,而不用每一次都把數據持久化到磁盤。事務日誌採用追加的方式。所以寫日誌的操作是磁盤上一小塊區域的順序IO,而不像隨機ID需要在磁盤的多個地方移動磁頭,所以採用事務日誌的方式會快很多。事務日誌持久之後,內存中被修改的數據就可以在後臺慢慢的刷回磁盤中,從而不會影響用戶體驗也提升了性能。修改數據需要寫兩次磁盤

多版本併發控制(MVCC)

概念:MySQL大多數事務型存儲引擎實現的都不是簡單的行級鎖,基於提高行級鎖的性能,一般同時都實現了多版本併發控制(mvcc)。不僅MySQL,包括oracle,postgresql等其他數據庫系統都實現了mvcc,因爲mvcc沒有統一的實現標準,所以各自的實現機制也都不一樣。

實現方式:通過保存數據在某一個時間點的快照來實現的。也就是說不管需要執行多長時間。每次事務執行的數據都是一致的。相反! 根據事務開始時間的不同選擇的快照也是不同的,所以每個事務對同一張表,同一個時刻看到的數據有可能是不一樣的。(如果沒有這一方面的概念聽起來可能有點迷惑)

多版本併發控制實現的不同,典型的實現有樂觀鎖併發控制悲觀鎖併發控制

如何工作的?

MVCC通過每行記錄後面保存兩個隱藏的列來實現的,一個是保存行的創建時間,一個是保存行的過期時間。存儲的不是時間值,而是系統的版本號。每開始一個新的事務,系統版本號會自動增加。事務開始時刻的系統版本號也就是事務的版本號,用來查詢到每行記錄的版本號進行對比。

  1. select:innodb會根據以下兩個條件檢查每行記錄。只有符合以下條件才能返回作爲查詢的結果
    a=> InnoDB只查找版本早於當前事務版本的數據行(也就是行的系統版本號小於或等於事務的系統版本號),這樣可以確保事務讀取的行,要麼是在事務開始前已經存在的,要麼就是事務自身插入或者修改過的。
    b=> 行的刪除版本要麼未定義,要麼大於當前事務版本號。這可以確保事務讀取到的行,在事務開始之前未被刪除。

  2. insert:innodb爲新插入的每一行保存當前系統版本號作爲行版本號
  3. delete:innodb爲刪除的每一行保存當前的系統版本號作爲行刪除標識
  4. update:innodb爲插入每一行新記錄,保存當前系統版本號作爲行版本號,同時保存當前系統系統版本號到原來的行作爲行刪除標識。

優點:保存這兩個額外的系統版本號的好處就是 操作數據的時候不需要單獨上鎖,這樣設計使得數據操作很簡單,性能也很好。並且也能保證只會讀取到符合標準的行。
缺點:每行記錄都需要額外的存儲空間,需要做更多的檢查行的操作,以及額外的維護工作

MVCC只在repertable read(可重複讀)和read committed(提交讀)兩種隔離級別下工作。其他兩種隔離級別都和mvcc不兼容!
Tip:read uncommitted總是讀取最新的數據行,而不符合當前事務版本的數據行。serializable則會對所有讀取的行都加鎖

面試技巧流程

自我介紹什麼的我就不說了,只說一下技術,拿Socket舉例

常見的小白場景就是

面試官:簡單的介紹一下Socket
應聘人:你好面試官,不好意思我沒用過,好像是通信用的。

常見的初級場景就是。

面試官:簡單的介紹一下Socket
應聘人:你好面試官,Socket是一個安全套接字,用於通信。一個發送點一個接收點,有多種通信協議比如UDP/TCP,TCP是三次握手,UDP是不用握手的。UDP比TCP更高效。如果需要交互判斷的選擇TCP,如果不需要交互判斷的選擇UDP。

以上沒有加分項,或許你可以這樣,中級場景

面試官:簡單的介紹一下Socket
應聘人:你好面試官,Socket我瞭解的是:
A=>安全套接字,要想聊Socket就要深入計算機底層我們可以從OSI7層模型說起,描述每一層的作用。
B=>TCP是什麼,告訴面試官爲什麼是面向連接的可靠的傳輸協議。TCP三次握手都做了哪些事情比如Syn包,Ack包,Syn+Ack包。
C=> 通過交互流程可以展開ddos簡單介紹一下表明你懂的比較多。你是個有乾貨的人,你是個對技術敏感的人。樂於學習的人



告訴面試官Socket在每一層都做了什麼以及Socket通信的時候是如何和外界聯繫的【加分項】

更多面試思路乾貨,請前往微信搜【歡少的成長之路】 或者下面掃碼關注 回覆【面試思路】獲取 感謝各位支持
在這裏插入圖片描述
在這裏插入圖片描述

結尾

目前更新出來的是我學習到的經驗知識與心得,剩下的部分將過幾天持續更新!

知道的越多,不知道的就越多。找準方向,堅持自己的定位!加油向前不斷前行,終會有柳暗花明的一天!
創作不易,你們的支持就是對我最大認可!
文章將持續更新,我們下期見!下期將持續更新【詳解二】 QQ羣:1076570504 微信公衆號搜索【歡少的成長之路】請多多支持!

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