成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL 是什么?架構(gòu)是怎么樣的?

數(shù)據(jù)庫(kù) MySQL
MySQL數(shù)據(jù)庫(kù),是一款存放和管理數(shù)據(jù)的軟件, 它介于應(yīng)用和數(shù)據(jù)之間,通過一些設(shè)計(jì),將大量數(shù)據(jù),變成一張張像 excel 的數(shù)據(jù)表。

你是一個(gè)程序員,你做了一個(gè)網(wǎng)站應(yīng)用,站點(diǎn)里的用戶數(shù)據(jù),需要存到某個(gè)地方,方便隨時(shí)讀寫。

很容易想到可以將數(shù)據(jù)存到文件里。

但如果數(shù)據(jù)量很大,想從大量文件數(shù)據(jù)中查找某部分?jǐn)?shù)據(jù),并更新,是一件很痛苦的事情。

那么問題就來了,有辦法可以解決這個(gè)問題嗎?

好辦,沒有什么是加一層中間層不能解決的,如果有,那就再加一層。

這次我們要加的中間層是 MySQL。

mysql是數(shù)據(jù)和應(yīng)用的中間層

什么是 MySQL

Mysql數(shù)據(jù)庫(kù),是一款存放和管理數(shù)據(jù)的軟件, 它介于應(yīng)用和數(shù)據(jù)之間,通過一些設(shè)計(jì),將大量數(shù)據(jù),變成一張張像 excel 的數(shù)據(jù)表。為應(yīng)用提供創(chuàng)建(Create), 讀取(Read), 更新(Update), 刪除(Delete)等核心操作。

MySQL是什么

我們來看下它是怎么實(shí)現(xiàn)的。

數(shù)據(jù)頁(yè)

MySQL 將數(shù)據(jù)組織成 excel 表的樣子。

excel 文件在磁盤上是個(gè)xls 文件,MySQL 的數(shù)據(jù)表也類似,在磁盤上則是個(gè)ibd 后綴的文件。

ibd文件是什么

數(shù)據(jù)表越大,磁盤上的 ibd 文件也就越大。

直接讀寫一個(gè)大文件里的全部數(shù)據(jù)會(huì)很慢,所以 MySQL 將數(shù)據(jù)拆成一個(gè)個(gè)數(shù)據(jù)頁(yè),每頁(yè)大小 16KB。這樣我們讀寫部分表數(shù)據(jù)的時(shí)候,就只需要讀取磁盤里的幾個(gè)數(shù)據(jù)頁(yè)就好。

MySQL將文件分成多個(gè)數(shù)據(jù)頁(yè)

索引

但數(shù)據(jù)頁(yè)那么多,查某條數(shù)據(jù)時(shí),怎么知道要讀哪些數(shù)據(jù)頁(yè)?

好辦,可以為每個(gè)數(shù)據(jù)頁(yè)加入頁(yè)號(hào),再為每行數(shù)據(jù)加個(gè)序號(hào),這個(gè)序號(hào)其實(shí)就是所謂的主鍵。

按主鍵大小排序,將每個(gè)數(shù)據(jù)頁(yè)里最小的主鍵序號(hào)和所在頁(yè)的頁(yè)號(hào)提出來,放入到一個(gè)新生成的數(shù)據(jù)頁(yè)中,并且給數(shù)據(jù)頁(yè)加入層級(jí)的概念。

這樣我們就可以通過上層的數(shù)據(jù)頁(yè)快速縮小查找范圍,加速查找數(shù)據(jù)頁(yè)的過程。

現(xiàn)在頁(yè)跟頁(yè)之間看起來就像是一棵倒過來的樹,這棵可以加速查找數(shù)據(jù)頁(yè)的樹,就是我們常說的B+樹索引。

B+樹索引

上面提到的是針對(duì)主鍵的索引,也就是主鍵索引。

主鍵索引

按同樣的思路,也可以為其他數(shù)據(jù)表的列去建立索引,比如用戶表的名稱字段,這樣我們就能快速查找到名字為 xx 的用戶有哪些,這就是所謂的輔助索引。

輔助索引

Buffer Pool

但就算有了索引,數(shù)據(jù)也還是在磁盤上。每次都讀磁盤太慢了。有辦法提升下性能嗎?

有!在磁盤數(shù)據(jù)和應(yīng)用之間,加一層進(jìn)程內(nèi)緩存,緩存里裝的就是前面提到的 16KB 數(shù)據(jù)和索引頁(yè), 它就是所謂的 Buffer Pool。

buffer pool是什么

讀數(shù)據(jù)的時(shí)候優(yōu)先讀 Buffer Pool,有數(shù)據(jù)就返回,沒數(shù)據(jù)才去磁盤里讀取,減少了讀磁盤的次數(shù),大大提升了性能。

但問題就來了,我們知道,文件讀取,默認(rèn)會(huì)先將文件數(shù)據(jù)加載到操作系統(tǒng)的文件緩存中,同樣都是緩存,為什么還要整 Buffer Pool 這死出?

這是因?yàn)檫M(jìn)程自己維護(hù)的 Buffer Pool ,可以定制更多緩存策略,還能實(shí)現(xiàn)加鎖等各種數(shù)據(jù)表高級(jí)特性。

也正是因?yàn)橐呀?jīng)有了 Buffer Pool,所以也就沒必要使用操作系統(tǒng)的文件緩存了,所以 Buffer Pool 通過"直接 I/O" 模式, 繞過操作系統(tǒng)的緩存機(jī)制,直接從磁盤讀寫數(shù)據(jù)。

buffer pool直接IO

自適應(yīng) hash 索引

就算有了 buffer pool,要查到某個(gè)數(shù)據(jù)頁(yè),也依然要查找 B+樹,查詢復(fù)雜度 O(lgn)。能更快嗎?

能!可以使用查詢復(fù)雜度為 **O(1)**的 hash 表進(jìn)行優(yōu)化。

記錄每個(gè)數(shù)據(jù)頁(yè)的查詢頻率,對(duì)于熱點(diǎn)數(shù)據(jù)頁(yè),我們以查詢的值為 key,數(shù)據(jù)頁(yè)地址為 value,構(gòu)建 hash 表。

比如name為 'xiaobai' 的數(shù)據(jù)頁(yè),被頻繁查詢,那 key 就是 xiaobai,value 就是包含 xiaobai 記錄的數(shù)據(jù)頁(yè)的地址。

哈希的key和value

這個(gè) hash 表,就是所謂的自適應(yīng)哈希索引,Adaptive Hash Index。

自適應(yīng)哈希

Change Buffer

有了自適應(yīng) hash 索引的加持,讀性能提高了。那寫性能也能優(yōu)化嗎?

能!

大部分?jǐn)?shù)據(jù)表,除了主鍵索引外,我們還會(huì)加一些輔助索引。比如對(duì)用戶名加個(gè)輔助索引。

那對(duì)于這類數(shù)據(jù)表的寫操作,更新完主鍵索引的數(shù)據(jù)頁(yè)之后,還需要更新輔助索引頁(yè)。這樣讀取輔助索引頁(yè)的磁盤 IO 必然少不了。

更新主鍵和輔助索引

怎么辦呢?我們可以先將要寫入的數(shù)據(jù)收集到一塊內(nèi)存里,等哪天磁盤里的索引頁(yè)正好被讀入 Buffer pool 的時(shí)候,再將寫入數(shù)據(jù)應(yīng)用到索引頁(yè)中。

通過這個(gè)方式減少大量的磁盤 IO,提升性能。

而這個(gè)將寫操作收集起來的地方,就是所謂的 Change Buffer,它其實(shí)是 Buffer pool 的一部分。

Change Buffer的更新流程

Undo Log

在數(shù)據(jù)庫(kù)中,有一個(gè)叫事務(wù)的概念。不了解沒關(guān)系,說白了,就是可以讓多行數(shù)據(jù),要么同時(shí)更新成功,要么同時(shí)更新失敗。也就是所謂的原子性。

事務(wù)是什么

為了實(shí)現(xiàn)這一點(diǎn),我們就需要知道寫數(shù)據(jù)時(shí)每行數(shù)據(jù)原來長(zhǎng)啥樣,方便對(duì)更新后的數(shù)據(jù)行,進(jìn)行回滾,因此就有了 Undo Log。

undo log回滾

更新 buffer pool 數(shù)據(jù)頁(yè)的時(shí)候:

  • 會(huì)用舊數(shù)據(jù)生成 undo log 記錄,存儲(chǔ)在 Buffer Pool 中的特殊 undo log 內(nèi)存頁(yè)中。
  • 并隨著 buffer pool 的刷盤機(jī)制,不定時(shí)寫入到磁盤的 undo log 文件中。

undo log的寫入流程

Redo Log

上面提到的都是 buffer pool 相關(guān)的內(nèi)容,它們本質(zhì)上都是內(nèi)存。

如果內(nèi)存數(shù)據(jù)只寫了一半到磁盤中,數(shù)據(jù)庫(kù)進(jìn)程就崩了,那一個(gè)事務(wù)里的多行數(shù)據(jù)就沒能做到"同時(shí)更新成功"。

怎么辦呢?

好辦,我們將事務(wù)中更新數(shù)據(jù)行的操作都寫入到 redo log buffer 內(nèi)存中,然后在事務(wù)提交的時(shí)候進(jìn)行 redo log 刷磁盤,將數(shù)據(jù)固化到 redo log 文件中。

數(shù)據(jù)庫(kù)進(jìn)程崩潰重啟后,就能通過 redo log file 找到歷史操作記錄,重做數(shù)據(jù)。保證了事務(wù)里的多行數(shù)據(jù)變更,要么都成功,要么都失敗。

redo log的寫入流程

這時(shí)候問題就來了,我有這功夫更新 redo log file 文件,直接將 buffer pool 的數(shù)據(jù)寫入到磁盤不香嗎?

為什么不直接寫磁盤數(shù)據(jù)頁(yè)

不太一樣,redo log file 是順序?qū)懭氲?,buffer pool 的內(nèi)存數(shù)據(jù)是隨機(jī)分散在磁盤各處的,順序?qū)懘疟P性能是隨機(jī)寫的幾十倍,所以很多存儲(chǔ)系統(tǒng)在寫數(shù)據(jù)時(shí)都會(huì)搞個(gè)日志來記錄操作,方便服務(wù)重啟后進(jìn)行數(shù)據(jù)對(duì)賬,確保數(shù)據(jù)的一致性和完整性,這類操作就是所謂的 Write-Ahead Logging (WAL) 。

順序?qū)懕入S機(jī)寫快很多

但問題又來了,redo log buffer 也是內(nèi)存,buffer pool 也是內(nèi)存,如果 redo log buffer 里的數(shù)據(jù)還沒來得及寫入到 redo log,數(shù)據(jù)庫(kù)進(jìn)程就崩了,那 redo log buffer 里的數(shù)據(jù)不也丟了嗎?

是的,所以 redo log 的作用并不是保證所有數(shù)據(jù)不丟失,而是確保已提交事務(wù)的變更不會(huì)丟失。但因?yàn)?redo log 刷盤頻率很高,所以丟失數(shù)據(jù)的概率很低。

redo log 本質(zhì)上是寫入性能和數(shù)據(jù)完整性折中的產(chǎn)物,做架構(gòu)就是這樣,做到最后總是需要通過犧牲某些東西去換取另一樣?xùn)|西,果然,程序員才是真正的煉金術(shù)師。

Innodb 是什么

我們將上面提到的內(nèi)容,分為內(nèi)存和磁盤兩部分,一部分是內(nèi)存里的自適應(yīng)哈希,buffer pool,以及 redo log buffer。另一部分是磁盤里存放行數(shù)據(jù)和索引的.ibd 文件, 以及 undo log, redo log 等文件。它們共同構(gòu)成了 innodb 存儲(chǔ)引擎。并對(duì)外提供一系列函數(shù)接口。

比如操作數(shù)據(jù)行的 write_row(), update_row(),以及操作數(shù)據(jù)表的 create(), drop()等等接口。

我們平時(shí)寫的 SQL 語(yǔ)句,最終都會(huì)轉(zhuǎn)換成 InnoDB 提供的這些接口函數(shù)調(diào)用。

innodb提供的函數(shù)接口

比如:

  • INSERT 語(yǔ)句會(huì)調(diào)用 write_row() 接口來插入數(shù)據(jù)行。
  • UPDATE 語(yǔ)句會(huì)調(diào)用 update_row() 接口來更新數(shù)據(jù)行。
  • CREATE TABLE 語(yǔ)句會(huì)調(diào)用 create() 接口來創(chuàng)建新表。
  • DROP TABLE 語(yǔ)句會(huì)調(diào)用 drop() 接口來刪除表。

但問題就來了,我們平時(shí)讀寫 mysql 用的 sql 語(yǔ)句,是怎么轉(zhuǎn)成存儲(chǔ)引擎的函數(shù)接口的呢?

那就需要介紹 Server 層了。

Server 層是什么

Server 層,本質(zhì)上是 sql 語(yǔ)句 和 innodb 存儲(chǔ)引擎之間的中間層。

server層

在 Server 層內(nèi)提供一個(gè)連接管理模塊,用于管理來自應(yīng)用的網(wǎng)絡(luò)連接。

并提供一個(gè)分析器,用于判斷 SQL 語(yǔ)句有沒有語(yǔ)法錯(cuò)誤,比如 select,是不是少打了一個(gè)l。

再提供一個(gè)優(yōu)化器,用于根據(jù)一定的規(guī)則選擇該用什么索引,生成執(zhí)行計(jì)劃。

之后,提供一個(gè)執(zhí)行器,根據(jù)執(zhí)行計(jì)劃去調(diào)用Innodb 存儲(chǔ)引擎的接口函數(shù)。

server層做了哪些事情

server 層和存儲(chǔ)引擎層共同構(gòu)成了一個(gè)完整的數(shù)據(jù)庫(kù),它就是我們常說的 MySQL 數(shù)據(jù)庫(kù)。

MySQL是什么

并且,server 層和存儲(chǔ)引擎層是通過接口函數(shù)進(jìn)行解耦的,換句話說就是,只要實(shí)現(xiàn)了上面這些接口函數(shù),就能作為存儲(chǔ)引擎與 Server 層對(duì)接。

引擎解耦

比如,MySQL 早期用的是 myisam 存儲(chǔ)引擎,后來才支持的 innodb。

常用存儲(chǔ)引擎有哪些

binlog 是什么

你聽說過刪庫(kù)跑路吧,為了防止數(shù)據(jù)庫(kù)表被刪除帶來的影響, server 層會(huì)將歷史上所有變更操作記錄到磁盤上的日志文件中,這個(gè)日志文件就是所謂的 binlog。一旦誤刪表,就可以利用 binlog 來恢復(fù)數(shù)據(jù)。

那么問題就來了,innodb 有一個(gè) redo log 也做類似的事情,為什么還要多此一舉?評(píng)論區(qū)告訴我答案。

這是因?yàn)?redo log 是環(huán)狀寫入的,后面寫的內(nèi)容最終會(huì)覆蓋前面的內(nèi)容,也就是不會(huì)記錄所有歷史寫操作,而 binlog 卻會(huì)記錄所有歷史變更。并且 binlog 位于 server 層,這樣不管底層的存儲(chǔ)引擎是什么,都能復(fù)用這部分能力。

binlog寫入流程

MySQL 主從架構(gòu)

由于 binlog 記錄了一個(gè) MySQL 的所有變更操作,因此我們還可以利用 binlog 數(shù)據(jù),"復(fù)制"一個(gè)新的 MySQL 出來。原來的 master 叫主數(shù)據(jù)庫(kù),復(fù)制出來的則是從數(shù)據(jù)庫(kù),主數(shù)據(jù)庫(kù)負(fù)責(zé)承接寫流量,從數(shù)據(jù)庫(kù)負(fù)責(zé)讀流量,這樣就可以讓 MySQL 承接更高的讀寫流量。它就是經(jīng)典的 MySQL 主從同步架構(gòu)。

數(shù)據(jù)庫(kù)查詢更新流程

接下來我們用實(shí)際例子將上面提到的內(nèi)容串起來。首先不管是查詢還是更新操作,客戶端都會(huì)先跟 mysql 建立網(wǎng)絡(luò)連接,并將 sql 發(fā)送到 server 層,經(jīng)過分析器解析 sql 語(yǔ)法、優(yōu)化器選擇索引生成執(zhí)行計(jì)劃,最終給到執(zhí)行器調(diào)用 InnoDB 的函數(shù)接口。

  • 對(duì)于讀操作。InnoDB存儲(chǔ)引擎會(huì)先檢查 Buffer Pool 中是否存在所需的 B+樹數(shù)據(jù)頁(yè),如果存在則直接返回?cái)?shù)據(jù)。如果 Buffer Pool 中沒有所需的數(shù)據(jù)頁(yè),則會(huì)從磁盤中讀取相應(yīng)的數(shù)據(jù)頁(yè)加載到 Buffer Pool 中,再返回?cái)?shù)據(jù)。同時(shí),如果查詢的數(shù)據(jù)是熱點(diǎn)數(shù)據(jù),還會(huì)將數(shù)據(jù)頁(yè)加入到自適應(yīng)哈希索引豪華套餐中,加速后續(xù)的查詢。
  • 對(duì)于寫操作,則會(huì)先將數(shù)據(jù)寫入 Buffer Pool,并生成相應(yīng)的 Undo Log 記錄,以便在事務(wù)回滾時(shí)能夠恢復(fù)數(shù)據(jù)的原始狀態(tài)。接下來,會(huì)將寫操作記錄到 Redo Log Buffer 中,這些 redo log 會(huì)周期性地寫入到磁盤中的 Redo Log 文件中,就算數(shù)據(jù)庫(kù)崩了,已提交的事務(wù)也不會(huì)丟失。對(duì)于輔助索引的更新操作,InnoDB 會(huì)將這些更新暫時(shí)存儲(chǔ)在 Change Buffer 中,等到相關(guān)的索引頁(yè)被讀取到 Buffer Pool 時(shí)再進(jìn)行實(shí)際的更新操作,從而減少磁盤 I/O,提高寫入性能。同時(shí),所有的變更都會(huì)記錄到 server 層的 binlog 中,以便進(jìn)行數(shù)據(jù)恢復(fù)。

mysql架構(gòu)總覽圖

現(xiàn)在大家通了嗎?

總結(jié)

  • MySQL 分為 server 層和存儲(chǔ)引擎層。存儲(chǔ)引擎層可更換,既可以是 myisam,也可以是 innodb。當(dāng)前用 innodb 更多。
  • innodb 分為內(nèi)存和磁盤兩部分,一部分是內(nèi)存里的自適應(yīng) hash,buffer bool,以及 redo log buffer。另一部分是磁盤里存放行數(shù)據(jù)和索引的.ibd 文件, 以及 undo log, redo log 等文件。
  • mysql server 層會(huì)通過 binlog 記錄數(shù)據(jù)庫(kù)變更操作,binlog 可以用于數(shù)據(jù)恢復(fù),也可以用于主從同步等場(chǎng)景。
責(zé)任編輯:趙寧寧 來源: 小白debug
相關(guān)推薦

2025-01-20 07:00:00

2024-11-25 07:00:00

RedisMySQL數(shù)據(jù)庫(kù)

2025-06-20 08:03:36

Hadoopmysql數(shù)據(jù)庫(kù)

2025-02-03 08:00:00

HDFS架構(gòu)存儲(chǔ)數(shù)據(jù)

2024-06-24 00:07:00

開源es搜索引擎

2024-03-04 08:03:50

k8sClusterNode

2024-05-22 08:02:30

2025-06-11 08:35:00

數(shù)據(jù)倉(cāng)庫(kù)數(shù)倉(cāng)分層架構(gòu)

2022-08-12 17:14:46

元宇宙

2023-05-15 10:17:03

2009-12-24 14:05:06

Fedora core

2014-08-25 10:11:18

極致用戶體驗(yàn)

2017-10-17 15:02:35

RS-485總線布線雙絞線

2019-01-11 10:39:24

軟件架構(gòu)虛擬空間機(jī)器人

2014-02-18 11:24:07

云計(jì)算PaaS

2020-08-13 12:02:13

前端培訓(xùn)學(xué)習(xí)

2011-05-31 17:27:58

網(wǎng)站權(quán)重

2016-03-09 11:25:39

前端開發(fā)工程師簡(jiǎn)歷

2024-01-03 13:06:50

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 成人在线播放网站 | 国产婷婷在线视频 | 黄色精品视频网站 | 久久久国产一区二区三区 | 欧美一级特黄aaa大片在线观看 | 久草热在线| 91视频导航| 一级一级毛片免费看 | 日韩视频一区二区三区 | 欧美性一级 | 欧美一区在线视频 | 久久国产精品一区二区三区 | 国产精品999| 日韩毛片在线免费观看 | h片在线免费看 | 男人天堂免费在线 | 中文字幕一区二区三区精彩视频 | 欧美日韩在线成人 | 国产超碰人人爽人人做人人爱 | 免费a网站| 欧美极品在线播放 | 国产小视频自拍 | 色免费视频 | 国产成人精品一区二区三区在线观看 | 亚洲成人网在线观看 | 99成人 | 久久国产精品亚洲 | 仙人掌旅馆在线观看 | 国产美女在线观看 | 九九久久精品视频 | 国产乱码精品一品二品 | www.99热 | 亚洲性视频 | 欧美综合久久久 | 欧美v在线观看 | 国产视频三级 | 天天看天天操 | 国产精品日韩在线 | 久久久久国产一级毛片高清网站 | 男人的天堂久久 | 日韩精品一区二区三区在线观看 |