日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

高性能mysql第一章——架构

發布時間:2023/12/10 数据库 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高性能mysql第一章——架构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第一章 架構

1.1 mysql邏輯架構


mysql服務器邏輯架構圖如上圖所示。

第一層為連接/線程處理層。每個客戶端連接mysql服務器,都會擁有一個線程。服務器會緩存線程,因此無需為每一個連接新建或釋放線程。mysql5.5以上的版本還提供了線程池,可以用少量線程服務大量連接。當客戶端連接到服務器時,服務器需要對其認證,根據用戶名主機名密碼等信息,確定客戶端是否有查詢/更新某個數據庫內某張表的權限。

第二層為mysql的核心服務功能層。包括查詢解析、分析、優化、緩存以及所有內置函數(日期、時間等),所有跨存儲引擎的功能 都在這一層實現(視圖、存儲過程、觸發器等)。

第三層包含了存儲引擎。存儲引擎負責數據的存儲和提取,每個存儲引擎都有它的優勢與劣勢,服務器通過API與存儲引擎通信。存儲引擎API包含幾十個底層函數,用于執行“開始一個事務”等操作,但是不會解析sql。

1.2 并發控制

討論mysql兩個層面的并發控制:存儲引擎層服務器層

1.2.1 讀寫鎖

在處理并發寫或并發讀寫時,可以通過由兩種類型的鎖組成的鎖系統來解決問題,這兩種鎖就是 共享鎖(讀鎖)排它鎖(寫鎖)。讀鎖是共享的,互相不阻塞,寫鎖是排它的,只有一個線程能進行寫操作,其他讀鎖和寫鎖都是阻塞的。

并且,寫鎖擁有更高的優先級。在一個鎖隊列中,寫鎖可以插到讀鎖的前面。

1.2.2 鎖粒度

一種理想的鎖方式是,盡量只鎖定需要修改的資源,而不是所有資源。鎖定的數據量越小,并發程度越高。

但是鎖也是需要時空開銷的,判斷是否有鎖、加鎖、釋放鎖的操作都需要額外的開銷,如果鎖粒度太小,雖然并發程度高,但系統花大量資源去管理鎖,而不是存取數據,也是得不償失。

鎖策略 就是在 鎖的開銷數據安全性 之間尋求平衡。大多數據庫都是行級鎖 ,而mysql提供了更多鎖的可能性。每種存儲引擎都可以實現自己的鎖策略和鎖粒度。將鎖粒度固定在某一級別,可以為特定的應用場景提供更好的性能,但同時也會失去對一些應用場景的支持。但好在mysql支持多個存儲引擎

表鎖

表鎖是mysql中最基本、開銷最小的鎖策略。盡管存儲引擎可以設計管理自己的鎖,但mysql服務器還是利用表鎖來實現不同的目的。例如:會為alter table之類的語句使用表鎖,而忽略存儲引擎的鎖機制。

行級鎖

行級鎖是mysql中支持并發量最大、開銷最大的鎖策略。行級鎖只在存儲引擎層實現,服務器層沒有實現。并且服務器層完全不了解存儲引擎層的鎖實現。

1.3 事務

事務是一組原子性的操作,是一個獨立執行單元。事務內的語句,要么全部執行成功,要么全部執行失敗。

start transaction sql1 sql2 sql3 commit

用start transaction開始一個事務,三條sql語句,要么全部執行成功commit上去將結果永遠保留,要么roll back撤銷所有修改。

事務的ACID

一個良好的事務處理系統,必須滿足ACID,否則任何事情都有可能發生。比如運行到一半程序崩掉、運行時其他事務也在運行并和當前事務操作同一條數據……

原子性(atomicity): 要么全部執行成功,要么全部執行失敗。

一致性(consistency): 數據庫總是從一個一致性狀態,轉移到另一個一致性狀態中去。

隔離性(isolation): 通常,一個事務在commit之前,所做的修改對其他事務而言是不可見的。

持久性(durability): 一旦事務提交,則會永久保留到數據庫內。

一個數據庫系統想要實現ACID,需要做許多復雜的工作,像鎖粒度升級會增加系統開銷一樣,事務處理過程中的安全性的保證,需要更強的cpu處理能力、更大的內存和磁盤。但我們可自行選擇,如果不需要事務,可以使用非事務型的存儲引擎

1.3.1 隔離級別

在sql標準中定義了四種隔離級別。每一種都規定了,在事務中的修改,哪些在事務內和事務間是可見的,哪些是不可見的。較低級別的隔離,意味著更好的并發性和較小的開銷。

未提交讀: 事務還未提交,其他事務就可見到更改。這種情況非常危險,不推薦使用。

提交讀: 一個事務從開始到提交結束,其中的修改僅事務本身可見。大多數據庫系統的默認隔離級別都是提交讀(mysql不是)。提交讀又稱作不可重復讀,即同一事務中兩次讀的結果可能是不一樣的。

可重復讀: 此級別保證了同一事務中多次讀的結果是相同的。可重復讀是mysql的默認隔離級別。但可重復讀依然存在問題,即在這個事務執行時,其他事務在該范圍內插入了新數據。

可串行化: 這是最高級別的隔離,會在讀寫的每一行數據上都加鎖,可能會導致大量超時和鎖爭用的問題。

1.3.2 死鎖

當兩個或多個事物占用著自己的資源,而都在等待對方占用的資源時,會形成死鎖。

start transaction update a update b commitstart transaction update b update a commit

如果湊巧,兩個事務都執行了第一條語句,在等待第二條語句的執行,那么就會形成死鎖。為了解決這種問題,數據庫系統引入了大量的死鎖檢測和死鎖超時機制。
一種是在事務開始前檢測死鎖的循環依賴,若有可能導致死鎖,則報錯。
一種是發生死鎖時,設置最長等待時間,大于這個時間則放棄資源(不推薦,性能變差)。
一種是發生死鎖時,將擁有最少行級寫鎖的事務回滾。

1.3.3 mysql中的事務

mysql提供了兩種事務型存儲引擎:InnoDB、NDB Cluster。

mysql5.5.5之后,InnDB為mysql的默認存儲引擎。

1. 自動提交 autocommit

mysql默認采用自動提交模式。如果不是顯示的開啟一個事務,任何查詢都會被當作一個事務。在當前連接中,可以通過設置autocommit變量開啟/禁用自動模式。

當autocommit為off時,所有的查詢語句都是在一個事務中,直到遇到commit或rollback命令,該事務結束,同時開啟下一個事務。

有一些mysql命令,在執行之前會強行commit當前的活動事務。例如alter table、lock tables等,具體要看mysql版本。

2. 混合使用存儲引擎

mysql服務器層是不管事務,事務是由下層的存儲引擎層實現的。所以在同一事務中,使用多種存儲引擎是不可靠的。如果在事務中,混合使用了事務型的表與非事務型的表(InnoDB表和MyISAM表),正常情況不會有什么問題,但當需要roll back時,非事務型的表是不可回滾的。

1.4 多版本并發控制

mysql多數事務型存儲引擎實現的都不是簡單的行級鎖,而是引入了多版本并發控制(MVCC) 用于 提高并發量,但每種存儲引擎的實現方式不同。

MVCC是行級鎖的變種,但它在很多情況下避免了加鎖的操作,因此開銷更低。雖然實現機制各不相同,但大都實現了非阻塞的讀操作,寫操作也只鎖定必要的行。

以InnoDB的MVCC為例,InnoDB以 在每行記錄后面保存兩個隱藏的列 來實現MVCC。這兩個列,一列保存 這一行的創建時間,一列保存 這一行的過期時間。但存儲的并不是真正的時間,而是 系統版本號。每開始一個事務,系統版本號就會自增。事務通過自身的系統版本號與這兩個隱藏的列對比,來操作數據。

在可重復度的隔離級別下,InnoDB的MVCC的具體操作如下:

select

InnoDB查找 創建系統版本號 <= 事務系統版本號的行,即在事務開始前就存在的行,或者由事務自身插入或修改的行。

同時該行的過期系統版本號要么未定義,要么 > 事務系統版本號。

insert

新插入的每一行 創建時間都是當前事務的系統版本號。

delete

刪除的每一行 過期時間都是當前事務的系統版本號。

update

插入一條新數據,創建時間是當前事務的系統版本號,將原來行的過期時間置為當前事務的系統版本號。

這兩個額外的系統版本號,使得大多數讀操作都不用加鎖。不足之處是需要額外的存儲空間,要進行更多的判斷以及額外的維護工作。

MVCC只在 提交讀 和 可重復度 兩個隔離級別下工作,因為未提交讀總是能讀取到最新的行,而不是符合當前事務版本的行,而串行化會對所有行加鎖。

1.5 mysql存儲引擎

文件系統中,mysql將每個數據庫(schema)保存為數據目錄下的一個子目錄。創建表時,mysql會在數據庫子目錄下創建一個和表同名的 frm后綴文件保存表的定義。因為mysql使用文件系統的目錄和文件來保存數據庫和表的結構定義,大小寫敏感和操作系統密切相關。

可以看到,該文件存儲著表名、存儲引擎、表行數、創建時間、更新時間、所用字符集等等一些基礎信息。

總結

以上是生活随笔為你收集整理的高性能mysql第一章——架构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。