高性能MySQL學習總結一

2021-01-07 紙鶴視界

一、MySQL邏輯架構

第一層的服務不是MySQL獨有的,大多數是基於網絡的客戶端/服務端的工具,如連接處理、授權認證、安全等等。

第二層就是MySQL的核心功能,包括查詢解析、分析、優化、緩存以及所有的內置函數,所有的跨存儲引擎的功能都在這一層實現:存儲過程、觸發器、視圖等。

第三層包含了存儲引擎,主要負責MySQL中數據的存儲和提取。

1.連接管理與安全

每個客戶端連接都會伺服器進程中擁有一個線程,這個連接的查詢只會在這個單獨的線程中執行,該線程只能輪流在某個CPU核心或者CPU中運行,伺服器會緩存線程,所以不需要對每個連接新建或者銷毀一個線程(可以復用緩存中的線程)。

當客戶端連接到MySQL時伺服器需要對其進行認證,如果認證成功,伺服器會繼續驗證該客戶是否有執行某個待定查詢的權限。

2.優化與執行

MySQL會解析查詢,並且創建內部數據結構(解析樹),然後對其進行各種優化,包括重寫查詢SQL、決定表的讀取順序,以及選擇合適的索引等。

對於一個SELECT查詢語句來說:在解析查詢之前,伺服器會先檢查查詢緩存,如果能夠在其中找到對應的查詢,伺服器會直接返回結果,不需要再執行查詢解析、優化和執行整個過程。

二、並發控制

1.讀寫鎖

比如有一張表,多個線程對這張表進行操作,加入剛好有一個線程在對一條數據更改,另一個線程也對其進行讀取操作,那麼進行讀操作的這個線程可能讀到的數據是不正確的,怎麼解決這個問題呢?這時就用到了並發控制,主要是通過兩種鎖來控制的:讀鎖(共享鎖)、寫鎖(排他鎖)

讀鎖是共享的,或者說是相互不阻塞的,即對個線程讀取同一個資源,互不幹擾;寫鎖是排他的,也就是說只要有一個線程對其進行寫操作,那麼其他的讀和寫線程將都會被阻塞。只有這樣才能保證才能保證在給定的時間內只有一個線程在寫操作,並防止其他線程讀取正在寫入的數據。

2.鎖粒度

最理想的情況是:需要寫入哪個對象就鎖定哪個對象。儘量只鎖定需要修改的部分數據,而不是所有的數據。在任何時候,在給定的資源上,鎖定的數據越少,系統的並發程度越高。

但是還有一個問題,加鎖也會消耗資源,鎖的各種操作:獲得鎖、檢查鎖是否已經解除、釋放鎖等,都會增加系統的開銷,如果花費大量的時間來管理鎖,而不是存取數據,那麼系統的性能將會受到影響。

所謂的鎖策略,就是在鎖的開銷和數據的完全性之間尋求平衡。

表鎖是MySQL中最基本的鎖策略,並且是開銷最小的策略(意味著並發程度低),但是表鎖的缺點是在執行插入、刪除、更改的操作時會使其他的用戶線程阻塞。(注意:讀鎖之間是互不影響的)。另外寫鎖比讀鎖的優先級更高。寫鎖可以插到讀鎖中,但是讀鎖卻不能插到寫鎖中。

行級鎖:可以最大程度的支持並發處理(但是同時也帶來了更大的鎖開銷)最典型的就是InnoDB存儲引擎,行級鎖只在存儲引擎層實現。

三、事務

最重要的事務終於到啦,事務即ACID(原子性、一致性、隔離性、持久性),在開始講這四個特性之前我們先舉一個最經典的例子:某帳戶存了1000元,現在用戶A要往裡面存200元、用戶B要往出來取200元。

原子性:一個事務必須被視為不可分割的最小工作單元,整個事務的所有操作要麼全部提交完成,要麼全部失敗回滾,對於一個事務來說不可能執行其中的一部分。那上面例子來說:A要從帳戶取200需要執行以下四步操作:

1 START TRANSACTION;2SELECT'金額'FROM'帳戶表'WHEREuser_id=1221221;3UPDATE'帳戶表'SET'金額'='金額'-200WHEREuser_id=1221221;4COMMIT;

解釋:1.開啟事務 ,2.查詢帳戶有沒有200元 ,3.扣除金額 , 4.提交事務。

原子性就是指這四步完整執行不可再分。

一致性:資料庫從一個一致性的狀態轉換為另一個一致性的狀態。就上面那個例子:如果在第三步執行完系統崩潰,帳戶中的金額還是1000元,因為一個事務沒有執行完,在最終提交前是不會保存到資料庫中的。

隔離性:通常來講一個事務在最終提交前,對其他事務是不可見的。就之前例子來說,第三步執行完,在沒提交之前B帳戶來看到的金額仍然是1000元。是不可見的。

持久性:事務一旦提交其所做的修改就會永遠的被保存到資料庫中,即使系統崩潰也不會丟失。

一個實現了事務的資料庫相比於沒有實現事務的資料庫它需要更強的CPU處理能力、更大的內存、更多的磁碟空間。對於有些不需要事務的查詢類應用選擇一個非事務型的存儲引擎可以獲得更高的性能。

1.隔離級別

一共有四種隔離級別先簡單做個介紹:

A.READ UNCOMMIT(讀未提交)

在這個隔離級別中,事務的修改,即使沒有提交,對其他的事務也是可見的。事務可以讀到未提交的數據,這些數據也被稱為髒讀。

B.READ COMMIT(讀已提交)(不可重複讀)

大多數資料庫系統的默認隔離級別都是讀已提交,但是MySQL不是,MySQL的默認隔離級別是可重複讀。簡單說就是一個事務開始時只能 「看見」 已經提交的事務所做的修改,換句話說,一個事務從開始到提交這個過程中所做的所有修改對其他事務是不可見的。這個級別對於兩次執行相同情況的查詢,可能會得到不同的結果。

C.REPEATABLE READ(可重複讀)

該級別保證了在同一個事務中多次讀取同樣的記錄結果是一致的,但是它無法解決幻讀的問題。

D.SERIALIZABLE(可串行化)

是最高的隔離級別。它通過強制事務串行化執行,避免了所有問題,他會在讀取的每一行記錄上面都加鎖,所以可能導致大量的超時與鎖等待的問題,並發低。

講幾個概念:

1.髒讀:A用戶把錢取出沒有提交,B用戶讀取到修改了的金額為800,過一會A因為異常事務回滾,B再次讀取發現值變為1000,兩次不一樣,第一次讀到的是髒數據。

2.不可以重複讀:B讀到數據為1000後,A修改數據為800並且提交,B再次讀取為800,兩次數據不一致。

3.幻讀:與不可重複讀類似:B讀到一個表裡有10條記錄,A插了一條並提交,B再次讀為11條,感覺發生幻覺一樣。

不同隔離級別引發的問題:

2.死鎖

多個事務在同一資源上相互佔有,並且請求鎖定對方佔用的資源,從而導致惡性循環的現象。

資料庫系統實現了各種死鎖檢測和死鎖超時機制。InnoDB目前處理死鎖的方法是:將持有最少行排它鎖的事務進行回滾。

3.事務日誌

事務日誌可以提高事務的效率,使用事務日誌時:存儲引擎在修改表數據時只需要修改其內存拷貝,再把該修改行為記錄到持久在硬碟上的事務日誌中,不用每次將修改的數據本身持久到硬碟。事務日誌採用追加的方式,寫日誌的操作是磁碟上的一小塊區域內的順序I/O.事務日誌持久後,內存中被修改的數據將在後臺慢慢刷回到磁碟。所以一共需要兩次磁碟I/O:一次寫日誌磁碟I/O,一次刷回磁碟I/O.

4.MySQL中的事務

1.自動提交:MySQL默認採用自動提交的方式。比如每個查詢就是一個事務執行完自動提交。

2.非事務型存儲引擎如:MyISAM無回滾功能。

四、多版本並發控制MVCC

可以認為MVCC是行級鎖的一個變種,它在很多情況下避免了加鎖,MVCC的實現是通過保存數據在某個時間的快照來實現的。

InnoDB的MVCC,是通過在每行記錄後面保存兩個隱藏的列來實現的,這兩個列一個保存了行的創建時間,一個保存了行的刪除時間,存儲的不是真正時間而是系統的版本號。每個新事物開始系統版本號自動遞增。事物開始時刻的版本號作為事物的版本號,用來和查詢到的每行記錄版本號進行比較。

MVCC只在可重複讀和讀已提交兩個隔離級別下工作,其他兩個級別都和MVCC不兼容。因為讀未提交總是讀取最新的數據行,不符合當前事物版本的數據行。可串行化會對所有行加鎖。

我的理解其實MVCC就跟CAS是一個原理,就是一個比較並交換的過程。

相關焦點

  • 基於MySQL的高性能資料庫應用開發
    首頁 > 語言 > 關鍵詞 > 資料庫最新資訊 > 正文 基於MySQL的高性能資料庫應用開發
  • mysql之安裝和遠程登入操作學習總結
    在寫今天關於資料庫的文章之前,還是說一下這近一年來做筆記的感受,我通過這種學習方式:一邊學習一邊總結筆記,日後方便查看和理解;這一點在我從零基礎學習c語言和Linux應用上體現的淋漓盡致,從平時和大家的溝通交流,我能夠去通過以前寫的筆記,做到溫故而知新,同時再給網友講解裡面的原理的時候,又進一步加深了對該知識的理解。
  • 史上最全的MySQL高性能優化實戰總結!
    安全 ---> 數據可持續性性能 ---> 數據的高性能訪問1.3.2 優化的範圍有哪些存儲、主機和作業系統方面:主機架構穩定性I/O規劃及配置Swap交換分區OS內核參數和網絡問題應用程式方面:應用程式穩定性SQL語句性能
  • 高性能Mysql主從架構的複製原理及配置詳解
    複製概述Mysql內建的複製功能是構建大型,高性能應用程式的基礎。將Mysql的數據分布到多個系統上去,這種分布的機制,是通過將Mysql的某一臺主機的數據複製到其它主機(slaves)上,並重新執行一遍來實現的。複製過程中一個伺服器充當主伺服器,而一個或多個其它伺服器充當從伺服器。主伺服器將更新寫入二進位日誌文件,並維護文件的一個索引以跟蹤日誌循環。
  • laravel高性能地從mysql資料庫中隨機獲取n條數據
    laravel如何高性能地從mysql資料庫中隨機獲取n條數據,有時候我們常常會需要從資料庫隨機獲取數據,比如:給工作人員隨機分配10個訂單,隨機從資料庫中隨機抽查100個用戶;這樣我們就需要隨機從資料庫獲取數據。
  • ubuntu18.04 django 連接 mysql 資料庫方法和常見錯誤總結
    ,總結下來分享給大家。我在運行過程中遇到了許多錯誤,並且找到了比較好的解決方法,分享給大家錯誤1 :django.db.utils.OperationalError: (1698, "Access denied for user 'root'@'localhost'")解決方法:mysql> USE mysql;mysql
  • MySQL 常用語法總結
    一、SQL速成  結構查詢語言(SQL)是用於查詢關係資料庫的標準語言,它包括若干關鍵字和一致的語法,
  • python對mysql資料庫的操作(一)
    是的,有,必須得驗證url,這是一個完整的測試用例,再來說註冊,註冊成功後,驗證點再我看來,一是到資料庫查看,用戶註冊的信息是否insert到對應了表了,滿足一的基礎上,再驗證註冊的用戶可不可以登錄。所以說,在自動化測試中,對資料庫的操作,具體看得場景,業務,具體問題得具體分析。
  • 學習筆記:node後臺開發總結
    知識總結:曹迎成。
  • MySQL-ProxySQL中間件(一)
    ProxySQLProxySQL作為一款強大的中間件為MySQL的架構提供了有力的支持。目前可以很好的支持 Master Slave\ MGR \ PXC等,並提供連接池、讀寫分離、日誌記錄等功能,當然還有很多其他實用功能,這裡不一一列舉了。
  • MySQL - mysqldump常用命令 - linux運維菜
    導出數據1、備份全部資料庫的數據和表結構mysqldump -uroot -ppassword -A >all.sql2、只備份表結構,不備份數據mysqldump -uroot -ppassword -A -d > database.sql3、只備份資料庫,不備份表結構mysqldump -uroot -ppassword -A -t > data.sql
  • mysql常用sql語句總結
    like 模糊匹配% 通配任意字符_ 通配單一字符In:in (4,11); between: between 100 and 500;NULL查詢select * from tmp where name is not null;select * from tmp where name is null;
  • 去 BAT 面試,總結了這 55 道 MySQL 面試題!
    以下是mysql_fetch_array和mysql_fetch_object的區別:mysql_fetch_array() - 將結果行作為關聯數組或來自資料庫的常規數組返回。mysql_fetch_object - 從資料庫返回結果行作為對象。
  • 一文詳解MySQL權限
    localhost』; ##都是』Y’mysql> select * from db where user=『root』 and host=『localhost』; ##無記錄mysql> select * from tables_priv where host=『localhost』 and user=『root』; ##無記錄mysql> select
  • MySQL Group Replication 學習筆記
    官方,在5.7版本階段開發的,innodb的分布式資料庫架構,從發布開始就有很多關注,下文是我對目前為止的材料以及實驗的一些總結。主要資料來源是官方blog:http://mysqlhighavailability.com/group replication(後文簡稱GR)實現的分布式資料庫架構,底層的分布式基礎是Paxos(出於行文限制,此處不單獨交代Paxos)。通過Paxos來保證分布式資料庫系統中,事務的提交順序。
  • MYSQL面試常考知識點總結
    具體一頁有多大數據跟作業系統有關,一般為4k或8k,也就是我們讀取一頁內的數據時候,實際上才發生了一次IO,這個理論對於索引的數據結構設計非常有幫助。索引的兩大類型Hash索引和B樹索引     Hash類型的索引:查詢單條快,範圍查詢慢。
  • 學習MySQL的select語句
    ,- 1";多表查詢$sql="select user_name from user  u,membe r  mwhere u.id=m.id and m.reg_date> ;=2006-12-28order by u.id desc"注意:如果user和 member兩個標同時有user_name欄位,會出現mysql
  • MySQL如何完成一次查詢?
    那麼從發出一條sql指令到返回結果mysql都做了什麼事情呢?mysql完成一次查詢過程是比較複雜的,在說明查詢過程前先介紹一下它的基礎概念和結構原理來幫助理解。下面從四個方面介紹,分別是mysql語句,mysql結構原理,mysql查詢過程,最後設置幾個有趣問題。
  • 重新學習Mysql資料庫1:無廢話MySQL入門
    本文轉自網際網路本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡查看https://github.com/h2pl/Java-Tutorial喜歡的話麻煩點下Star哈文章也將同步到我的個人博客:www.how2playlife.com本文是微信公眾號【Java技術江湖】的《重新學習
  • MySQL mysqldump 數據導出詳解
    mysqldump  -uroot -p --all-databases --apply-slave-statements--character-sets-dir字符集文件的目錄mysqldump  -uroot -p --all-databases  --character-sets-dir=/usr/local/mysql/share/mysql