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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL 体系结构详细介绍

發(fā)布時間:2025/3/21 数据库 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL 体系结构详细介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

一、MySQL軟件架構(gòu)

? ? MySQL體系結(jié)構(gòu)圖(邏輯結(jié)構(gòu))

1、Connectors

指的是不同語言中與MySQL的連接交互層;

2、Management Serveices & Utilities

系統(tǒng)管理和控制工具,例如備份恢復(fù)、MySQL復(fù)制、集群等;

3、Connection Pool

連接池,管理緩沖用戶連接、用戶名、密碼、權(quán)限校驗(yàn)、線程處理等需要緩存的信息;
MySQL服務(wù)器對每一個連接產(chǎn)生一個線程,而這個線程獨(dú)自為該連接服務(wù)。因此,MySQL服務(wù)器中的并行是指并行執(zhí)行許多個查詢而非一次查詢內(nèi)的并行。也由此原因致使MySQL對多核支持不夠好,MySQL服務(wù)器是一組線程的集合。

4、SQL Interface

SQL接口,接受用戶的SQL命令,并且返回用戶需要查詢的結(jié)果。比如DML就是調(diào)用SQL Interface;

5、Parser

解析器,SQL命令傳遞到解析器的時候會被解析器驗(yàn)證和解析。解析器是由Lex和YACC實(shí)現(xiàn)的,是一個很長的腳本;
主要功能:?

  • 將SQL語句分解成數(shù)據(jù)結(jié)構(gòu),并將這個結(jié)構(gòu)傳遞到后續(xù)步驟,以后SQL語句的傳遞和處理就是基于這個結(jié)構(gòu)的;
  • 如果在分解構(gòu)成中遇到錯誤,那么就說明這個SQL語句是不合理的 ;
  • Lex:Lexical Analyzer是一種生成掃描器的工具。掃描器是一種識別文本中的詞匯模式的程序;
  • Yacc:Yet Another Compiler Compiler是一種工具,將任何一種編程語言的所有語法翻譯成針對此種語言的 Yacc 語法解析器;

6、Optimizer

查詢優(yōu)化器,SQL語句在查詢之前會使用查詢優(yōu)化器對查詢進(jìn)行優(yōu)化。他使用的是“選取-投影-聯(lián)接”策略進(jìn)行查詢;
優(yōu)化 select uid,name from user where gender = 1; SQL語句執(zhí)行的過程如下:

  • 這個select 查詢先根據(jù)where 語句進(jìn)行記錄選取,而不是先將表全部記錄查詢出來以后再進(jìn)行g(shù)ender過濾;
  • 這個select查詢先根據(jù)uid和name進(jìn)行屬性投影(字段選擇),而不是將屬性全部取出以后再進(jìn)行過濾;
  • 將這兩個查詢條件聯(lián)接起來生成最終查詢結(jié)果;

7、Cache&Buffer

高速緩存區(qū),查詢緩存,如果查詢緩存有命中的查詢結(jié)果,查詢語句就可以直接去查詢緩存中取數(shù)據(jù)。通過LRU算法將數(shù)據(jù)的冷端溢出,未來得及刷新到磁盤的數(shù)據(jù)頁,叫臟頁。這個緩存機(jī)制是由一系列小緩存組成的。比如表緩存,記錄緩存,key緩存,權(quán)限緩存等;?

8、Engine

存儲引擎,存儲引擎是MySQL與文件打交道的子系統(tǒng)。也是MySQL最具有特色的一個地方。MySQL的存儲引擎是插件式的,它根據(jù)MySQL AB公司提供的文件訪問層的一個抽象接口來定制一種文件訪問機(jī)制(這種訪問機(jī)制就叫存儲引擎)現(xiàn)在有很多種存儲引擎,各個存儲引擎的優(yōu)勢各不一樣。MySQL也支持自定義制存儲引擎,甚至一個庫中不同的表使用不同的存儲引擎,這些都是允許的。

二、數(shù)據(jù)庫與數(shù)據(jù)庫實(shí)例

數(shù)據(jù)庫:物理操作系統(tǒng)文件或其他形式文件類型的集合;
數(shù)據(jù)庫實(shí)例:數(shù)據(jù)庫后臺進(jìn)程或線程及一個共享內(nèi)存區(qū)域組成,數(shù)據(jù)庫實(shí)例是用來操作數(shù)據(jù)庫文件的;
MySQL是一個單進(jìn)程多線程架構(gòu)的數(shù)據(jù)庫,與SQL Server類似。Oracle數(shù)據(jù)庫在Linux OS下是多進(jìn)程,在Windows下也是單進(jìn)程多線程。MySQL數(shù)據(jù)庫實(shí)例在系統(tǒng)上的表現(xiàn)就是一個進(jìn)程。

三、MySQL常用存儲引擎

存儲引擎其實(shí)就是如何存儲數(shù)據(jù),如何為存儲的數(shù)據(jù)建立索引以及如何更新、查詢數(shù)據(jù)等技術(shù)實(shí)現(xiàn)的方法。
MySQL中的數(shù)據(jù)用各種不同的技術(shù)存儲在文件(或內(nèi)存)中,這些技術(shù)中的每一種技術(shù)都使用不同的存儲機(jī)制、索引技巧、鎖定水平,并且最終提供廣泛的不同功能和能力。在MySQL中將這些不同的技術(shù)及配套的相關(guān)功能稱為存儲引擎。

1、存儲引擎查詢

查看MySQL服務(wù)器支持的存儲引擎及默認(rèn)的存儲引擎。存儲引擎是針對數(shù)據(jù)表的,不是針對數(shù)據(jù)庫的,通過如下命令查看具體表指定的存儲引擎。

mysql> show engines; +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | MyISAM | YES | MyISAM storage engine | NO | NO | NO | | CSV | YES | CSV storage engine | NO | NO | NO | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | | PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO | | FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ mysql> show variables like '%engine%'; +----------------------------------+--------+ | Variable_name | Value | +----------------------------------+--------+ | default_storage_engine | InnoDB | | default_tmp_storage_engine | InnoDB | | disabled_storage_engines | | | internal_tmp_disk_storage_engine | InnoDB | +----------------------------------+--------+ 4 rows in set (0.01 sec)

2、常用存儲引擎

Innodb是MySQL數(shù)據(jù)庫5.5版本后的默認(rèn)存儲引擎,默認(rèn)所說的MySQL即指Innodb存儲引擎的MySQL,所以關(guān)于Innodb的體系結(jié)構(gòu)專門梳理介紹。

2.1、InnoDB
2.1.1、InnoDB體系結(jié)構(gòu)圖

InnoDB是MySQL5.5以后的默認(rèn)存儲引擎,支持事務(wù)ACID,回滾,系統(tǒng)崩潰恢復(fù)能力及多版本并發(fā)控制的事務(wù)安全,主要用于OLTP數(shù)據(jù)庫業(yè)務(wù)場景;支持自增長列(auto_increment);支持外鍵約束(foreign key);支持MVCC的行級鎖;使用Btree索引;
Innodb存儲引擎主要包括多個內(nèi)存池以及后臺線程。
內(nèi)存池:由Buffer Pool包括(undo page、Change buffer page、Adaptive Hash Index、Lock info、data dictionary),Doublewrite Buffer,Additional Memory pool、Redo Log Buffer 組成,主要維護(hù)進(jìn)程/線程的內(nèi)部數(shù)據(jù)、緩存磁盤數(shù)據(jù),修改文件前先在內(nèi)存中修改;
MySQL5.7官方文檔中關(guān)于Innodb存儲引擎的體系結(jié)構(gòu)講解包括
Buffer Pool
Change Buffer
Adaptive Hash Index
Redo Log Buffer
System Tablespace
InnoDB Data Dictionary
Doublewrite Buffer
Undo Logs
File-Per-Table Tablespaces
General Tablespaces
Undo Tablespace
Temporary Tablespace
Redo Log
InnoDB有表空間的概念,包括共享表空間和獨(dú)立表空間(獨(dú)立表空間的模式中也要有系統(tǒng)表空間ibdataX,來用于存儲內(nèi)部的數(shù)據(jù)字典、Undo日志等,通過innodb_file_per_table參數(shù)設(shè)置啟用獨(dú)立表空間),默認(rèn)獨(dú)立表空間模式下會在數(shù)據(jù)目錄下創(chuàng)建tablename.ibd、tablename.frm文件。
InnoDB支持記錄Redo文件,記錄對所有頁面的修改(頁面物理結(jié)構(gòu)的變更)操作,可以通過相關(guān)的參數(shù)進(jìn)行自定義設(shè)置Redo文件存儲路徑;
InnoDB支持記錄Undo文件,記錄數(shù)據(jù)修改前的備份,存儲在共享表空間中。用戶保證事務(wù)的原子性(恢復(fù))和實(shí)現(xiàn)MVCC多版本并發(fā)控制,輔助完成事務(wù)的持久化(Undo信息會持久化)。可通過相關(guān)參數(shù)進(jìn)行自定義設(shè)置;
更改緩沖(change buffer),基于聚集索引的操作是順序的,不會造成數(shù)據(jù)庫隨機(jī)讀取,但修改非聚集索引時就會產(chǎn)生大量的隨機(jī)讀寫。當(dāng)修改非聚集索引的數(shù)據(jù)時,修改操作并非實(shí)時更新索引的葉子頁,而是把若干對同一頁面的更新緩存起來做合并(merge)將一次性更新操作,轉(zhuǎn)化隨機(jī)IO為順序IO,這樣可以避免隨機(jī)IO帶來性能損耗,提高數(shù)據(jù)庫的寫性能。
寫兩次(double write),(重做日志記錄的是頁的物理操作,如果頁本身損壞,對其重做就沒有意義了,在應(yīng)用重做日志前,需要一個頁的副本。先通過頁的副本還原該頁,再應(yīng)用重做日志進(jìn)行恢復(fù))當(dāng)mysql將臟數(shù)據(jù)flush到data file的時候,先使用memcopy將臟數(shù)據(jù)復(fù)制到內(nèi)存中的double write buffer,之后通過double wirte buffer再分2次,每次寫入1M到共享表空間,然后馬上調(diào)用fsync函數(shù),同步到磁盤上;將數(shù)據(jù)頁(page)加載到內(nèi)存(innodb buffer)->更新數(shù)據(jù)產(chǎn)生臟頁(dirty page)->使用memcopy將臟數(shù)據(jù)復(fù)制到內(nèi)存中的double write buffer(size=2M)->double wirte buffer再分2次,每次寫入1M到共享表空間(ibdata文件)->調(diào)用fsync函數(shù),同步到磁盤;使用memcopy將臟數(shù)據(jù)復(fù)制到內(nèi)存中的double write buffer(size=2M)->double wirte buffer再分2次,每次寫入1M到共享表空間(ibdata文件)就是double的過程。
自適應(yīng)hash索引(adaptive hash index),Innodb會監(jiān)控表上索引的查找情況,如果通過建立Hash索引能帶來性能的提升,則會自動建立hash索引,該過程只能由MySQL Server自行控制,無法人工干預(yù)且只適用于等值索引查詢;

后臺線程:包括(Mater Thread、IO Thread、Lock Monitor Thread、Error Monitor Thread、Purge Thread、Page Cleaner Thread)刷新內(nèi)存池中的過程數(shù)據(jù),管理維護(hù)InnoDB存儲引擎正常工作;
InnoDB主要的后臺線程

Master Thread是一個非常核心的后臺線程,主要負(fù)責(zé)將緩沖池中的數(shù)據(jù)異步刷新到磁盤,保證數(shù)據(jù)的一致性,包括:臟頁(dirty page)的刷新、合并插入緩沖(insert buffer merge)、回滾頁回收(undo purge)等。innodb_max_dirty_pages_pct臟頁刷盤的配置參數(shù),新版默認(rèn)75,google默認(rèn)90。

2.1.2、InnoDB表

InnoDB表邏輯結(jié)構(gòu)

  • 表空間:InnoDB存儲引擎邏輯結(jié)構(gòu)的最高層
  • 段:組成表空間,數(shù)據(jù)段,索引段,回滾段等
  • 區(qū):由64個連續(xù)的頁組成,每個區(qū)大小1MB
  • 頁:每個頁16KB且不能修改,數(shù)據(jù)頁,索引頁,系統(tǒng)頁等
  • 行:每頁最多允許存放7992行數(shù)據(jù)
  • 行記錄格式:常見兩種行記錄格式Compact和Redundant,MySQL5.1版本后,主要是Compact行記錄格式。對于Compact,不管是char型還是varchar型,null型都是不占用存儲空間的;對于Redundant,varchar的null不占用空間,char的null型是占用存儲空間的。
  • Varchar類型的長度是65535,但實(shí)際一般除開其他開銷大概65530左右,同時這個限制是一整行數(shù)據(jù)的長度。
  • create table tbl_varchar(a varchar(22000), b varchar(22000), cvarchar(22000)) charset=latin1 engine=innodb; 因?yàn)橐恍锌傞L大于了65535

數(shù)據(jù)頁結(jié)構(gòu)

  • File Header(文件頭):記錄頁的頭信息,固定長度38字節(jié);
  • Page Header(頁頭):記錄頁的狀態(tài)信息,固定長度65字節(jié);
  • Infimum+Supremum Records:兩個虛擬的行記錄,用于限定記錄的邊界;
  • User Records:用戶記錄,實(shí)際記錄的內(nèi)容,InnoDB采用B+樹索引組織存儲表;
  • Free Space:空閑空間,鏈表數(shù)據(jù)結(jié)構(gòu),記錄刪除后會被加入空閑空間;
  • Page Director:頁目錄,存放記錄的相對位置,B+索引不能找到具體的一條記錄,只能找到該記錄所在的頁,數(shù)據(jù)庫把頁載入內(nèi)存,再通過Page Director查找具體記錄行;
  • File Trailer:文件結(jié)尾信息,固定長度8字節(jié);

2.2、MyISAM

MyISAM是MySQL5.5之前的默認(rèn)存儲引擎,不支持事務(wù),不支持行級鎖,只支持并發(fā)插入的表鎖,主要用于高負(fù)載的查詢。
MySQL的系統(tǒng)表大部分都是MyISAM存儲引擎的,支持對只讀表進(jìn)行壓縮,單壓縮后不能對該表進(jìn)行修改只能查詢;
MyISAM按照插入的順序在磁盤上存儲數(shù)據(jù),并為每行生成自然順序行號(row number),從0開始。因?yàn)樵M的大小固定,所以MyISAM可以很容易的從表的開始位置找到某一字節(jié)的位置。
MyISAM不支持聚簇索引,使用Btree索引,但實(shí)現(xiàn)細(xì)節(jié)與InnoDB不同,索引中每一個葉子節(jié)點(diǎn)僅僅包含索引字段關(guān)鍵字和行號(row number),且葉子節(jié)點(diǎn)按照索引字段關(guān)鍵字的順序存儲,實(shí)際上,在MyISAM中,primary key和其它索引沒有什么區(qū)別。Primary key僅僅只是一個叫做PRIMARY的唯一,非空的索引而已。
創(chuàng)建MyISAM表,MySQL5.7的MyISAM表已經(jīng)支持text,blob類型了。
mysql> create table tbl_myisam(id int,name varchar(20),describle text,image blob) engine=myisam;
mysql> create table table_myisam_compressed engine=myisam as select * from information_schema.columns;
Query OK, 3132 rows affected (0.23 sec)
Records: 3132 ?Duplicates: 0 ?Warnings: 0
MyISAM表默認(rèn)在數(shù)據(jù)目錄下創(chuàng)建tablename.MYD、tablename.MYI、tablename.frm文件

[root@mysqlnode02 test1212]# ll -h tbl_myisam.* -rw-r----- 1 mysql mysql 8.5K Dec 12 09:28 tbl_myisam.frm -rw-r----- 1 mysql mysql 0 Dec 12 09:28 tbl_myisam.MYD -rw-r----- 1 mysql mysql 1.0K Dec 12 09:28 tbl_myisam.MYI

查看數(shù)據(jù)表的狀態(tài)信息,MyISAM表存儲格式,三種存儲格式(Row_format):靜態(tài)(Fixed,char)、動態(tài)(Dynamic,varchar\blob\text)、壓縮(先創(chuàng)建表再通過myisampack工具壓縮處理)
mysql> show table status like 'tbl_myisam'\G
MyISAM表容易損壞,可以通過工具進(jìn)行檢查和修復(fù),如果有問題Msg_type里會有warning或error。沒有問題的話出現(xiàn)的結(jié)果Status是OK。可以使用repair命令修復(fù)損壞的MyISAM表,MySQL5.7修復(fù)后不生成*.old文件

mysql> check table tbl_myisam; +---------------------+-------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------------------+-------+----------+----------+ | test1212.tbl_myisam | check | status | OK | +---------------------+-------+----------+----------+ 1 row in set (0.00 sec)mysql> repair table tbl_myisam; +---------------------+--------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------------------+--------+----------+----------+ | test1212.tbl_myisam | repair | status | OK | +---------------------+--------+----------+----------+ 1 row in set (0.00 sec) -- 利用myisampack工具,通過.MYI文件壓縮數(shù)據(jù)文件.MYD [root@mysqlnode02 test1212]# myisampack ./myisam.MYI

2.3、Memory

Memory存儲引擎的表都是內(nèi)存表。實(shí)際的數(shù)據(jù)存儲在內(nèi)存中,磁盤中只有表結(jié)構(gòu)定義文件tablename.frm,有利于快速處理,提高整個表的處理能力,重啟或關(guān)機(jī)數(shù)據(jù)會丟失,可提供極快的訪問。Mysql服務(wù)單獨(dú)給memory存儲引擎的表分配內(nèi)存空間,而且表一直持有這些內(nèi)存空間(即使刪除數(shù)據(jù)也不釋放內(nèi)存),直到有drop、alter、create等重建對象才能釋放內(nèi)存。內(nèi)存的占用空間由max_heap_table_size參數(shù)控制,默認(rèn)16M,Mysql服務(wù)重啟后,所有表會自動繼承全局的max_heap_table_size參數(shù)的值;
創(chuàng)建memory存儲引擎表,不支持BLOB/TEXT類型

mysql> create table tbl_memory(id int,name varchar(20),describle text,image blob) engine=memory; ERROR 1163 (42000): The used table type doesn't support BLOB/TEXT columns mysql> create table tbl_memory(id int,name varchar(20)) engine=memory; Query OK, 0 rows affected (0.01 sec) mysql> show variables like 'max_heap_table_size'; +---------------------+----------+ | Variable_name | Value | +---------------------+----------+ | max_heap_table_size | 16777216 | +---------------------+----------+ 1 row in set (0.01 sec)

默認(rèn)使用hash索引,對應(yīng)等值查詢效率很高,對應(yīng)范圍查詢性能不高;支持Btree索引,如要使用Btree索引需要明確指定創(chuàng)建索引類型;

mysql> create index idx_id on tbl_memory(id); mysql> create index idx_name using btree on tbl_memory(name); mysql> show index from tbl_memory\G

Memory存儲引擎的表只有一個tablename.frm文件

[root@mysqlnode02 test1212]# ll -h tbl_memory.* -rw-r----- 1 mysql mysql 8.4K Dec 12 09:46 tbl_memory.frm

2.4、CSV

CSV存儲引擎是基于CSV格式文件存儲數(shù)據(jù)的。該存儲引擎的表將數(shù)據(jù)以CSV文本方式存儲,可以手動直接編輯數(shù)據(jù)文件,也可通過DML語句操作CSV表,適用于進(jìn)行小數(shù)據(jù)量的中間數(shù)據(jù)交換場景。

-- 創(chuàng)建CSV存儲引擎表,要求創(chuàng)建時指定各列非空約束。 mysql> create table tbl_csv(id int,name varchar(30)) engine=csv; ERROR 1178 (42000): The storage engine for the table doesn't support nullable columns mysql> create table tbl_csv(id int not null,name varchar(30) not null) engine=csv; Query OK, 0 rows affected (0.00 sec) -- CSV存儲引擎的表包括.frm是表結(jié)構(gòu)定義文件;.CSV是存放數(shù)據(jù)文件;.CSM是表狀態(tài)及表的數(shù)據(jù)量文件 [root@mysqlnode02 test1212]# ll -h tbl_csv.* -rw-r----- 1 mysql mysql 35 Dec 12 09:54 tbl_csv.CSM -rw-r----- 1 mysql mysql 0 Dec 12 09:54 tbl_csv.CSV -rw-r----- 1 mysql mysql 8.4K Dec 12 09:54 tbl_csv.frm -- 手動編輯.CSV數(shù)據(jù)文件,刷新數(shù)據(jù)表,DML操作數(shù)據(jù)表 [root@mysqlnode02 test1212]# vi tbl_csv.CSV [root@mysqlnode02 test1212]# cat tbl_csv.CSV 1,'AAAAA' 2,BBBBB mysql> flush table tbl_csv; Query OK, 0 rows affected (0.00 sec) mysql> select * from tbl_csv; +----+---------+ | id | name | +----+---------+ | 1 | 'AAAAA' | | 2 | BBBBB | +----+---------+ 2 rows in set (0.00 sec) mysql> delete from tbl_csv where id=2; mysql> insert into tbl_csv values (id,'BBBBB');

2.5、BLACKHOLE

支持事務(wù),而且支持mvcc的行級鎖,主要用于日志記錄或同步歸檔,這個存儲引擎除非有特別目的,否則不適合使用。

2.6、FEDERATED

能夠?qū)⒍鄠€分離的MySQL服務(wù)器鏈接起來,從多個物理服務(wù)器創(chuàng)建一個邏輯數(shù)據(jù)庫。十分適合于分布式環(huán)境或數(shù)據(jù)集市環(huán)境。

2.7、ARCHIVE

歸檔(適用于存放大量數(shù)據(jù)的存儲引擎);支持select、insert等操作;不支持delete 、update、索引等操作;使用zlib無損數(shù)據(jù)壓縮算法,節(jié)省空間;適用于大量歷史數(shù)據(jù)(可查詢但不能刪除)的保存。
使用ARCHIVE存儲的空間大小是MyISAM存儲大小的1/7,大大減少了空間的占用。

mysql> create table tbl_archive engine=archive as select * from information_schema.columns; Query OK, 3153 rows affected (0.19 sec) Records: 3153 Duplicates: 0 Warnings: 0 -- .ARZ是數(shù)據(jù)壓縮文件;.frm是表結(jié)構(gòu)定義文件 [root@mysqlnode02 test1212]# ll -h tbl_archive.* -rw-r----- 1 mysql mysql 30K Dec 12 10:20 tbl_archive.ARZ -rw-r----- 1 mysql mysql 14K Dec 12 10:20 tbl_archive.frm

四、物理結(jié)構(gòu)(物理文件)

1、參數(shù)文件

告訴MySQL實(shí)例啟動時在哪找到數(shù)據(jù)庫文件,指定某些初始化參數(shù),這些參數(shù)定義了某種內(nèi)存結(jié)構(gòu)的大小等設(shè)置。用文件存儲,可編輯,加載不到則不能成功啟動。參數(shù)有動態(tài)和靜態(tài)之分,靜態(tài)只讀,動態(tài)可以通過set命令設(shè)置。修改時有作用域的區(qū)分,通過session或global設(shè)置相應(yīng)的有效域。

# 查看MySQL的參數(shù)文件讀取順序 [root@mysqlnode02 data]# mysql --help | grep 'my.cnf'order of preference, my.cnf, $MYSQL_TCP_PORT, /etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf

2、錯誤日志文件

記錄MySQL的啟動、運(yùn)行、關(guān)閉過程進(jìn)行了記錄,MySQL使用過程中的錯誤信息,還記錄了一些警告信息以及正確信息,可通過show variables like ‘log_error’查看具體的文件路徑。

mysql> show variables like 'log_error'; +---------------+-----------------------------+ | Variable_name | Value | +---------------+-----------------------------+ | log_error | /mysqldb/errorlog/error.log | +---------------+-----------------------------+ 1 row in set (0.01 sec)

3、慢查詢?nèi)罩疚募?/h2>

記錄SQL語句執(zhí)行較慢的語句,可通過slow_query_log參數(shù)控制是否開啟,slow_query_log_file參數(shù)控制對應(yīng)的日志文件路徑,可通過mysqldumpslow工具查看慢日志。long_query_time參數(shù)設(shè)置慢查詢閥值,等于0記錄全部SQL,log_output 參數(shù)設(shè)置日志記錄文件或表中(file/Table)log_queries_not_using_indexes參數(shù)設(shè)置未使用索引的查詢也算慢查詢。

4、全查日志文件

記錄MySQL的所有請求信息(操作命令),通過general_log,general_log_file兩個參數(shù)控制開啟與路徑設(shè)置。

5、二進(jìn)制日志文件

不記錄查詢,只記錄對數(shù)據(jù)庫所有的修改操作,用于恢復(fù)和復(fù)制。log_bin參數(shù)設(shè)置是否開啟(開啟時需要設(shè)置server_id),max_binlog_size 設(shè)置二進(jìn)制日志的大小,64MB比較合適,log_bin_basename參數(shù)設(shè)置二進(jìn)制日志文件的路徑和名稱前綴,binlog_format參數(shù)設(shè)置日志格式(statement,row,mixed)三種格式,可通過mysqlbinlog工具查看二進(jìn)制日志文件內(nèi)容。

6、Socket文件

當(dāng)用UNIX套接字方式進(jìn)行連接時需要指定的文件。修改了socket文件的目錄時,通過MySQL客戶端工具連接MySQL時需要-S指定socket文件。socket參數(shù)設(shè)置文件的存儲目錄和文件名,可以在my.cnf的[client]下增加socket配置后不用每次都指定。
[client]
socket = /MySQLdb/sockandpid/MySQL.sock

7、pid文件

MySQL實(shí)例的進(jìn)程文件,MySQL實(shí)例啟動的時候,會將自己的進(jìn)程id寫入一個文件中,pid_file參數(shù)設(shè)置pid文件的路徑和名稱,rpm默認(rèn)安裝后會放在默認(rèn)目錄中,重新初始化時需要在my.cnf文件中具體配置(自定義設(shè)置的路徑不起作用/var/run/mysqld/mysqld.pid)。
[root@mysqlnode02 data]# cat /var/run/mysqld/mysqld.pid
1403

8、表結(jié)構(gòu)文件

存放MySQL表結(jié)構(gòu)定義的文件,每個表都有一個.frm后綴的文件,存放在datadir對應(yīng)的數(shù)據(jù)庫目錄里。

9、數(shù)據(jù)文件

存儲數(shù)據(jù)的文件,每個存儲引擎的數(shù)據(jù)文件后綴有一定的差異,MyISAM的數(shù)據(jù)文件是.MYD,InnoDB的數(shù)據(jù)文件是.ibd或.ibdata*。

10、索引文件

存儲索引的文件,每個存儲引擎的索引文件后綴會有一定的差異,MyISAM的索引文件是.MYI,InnoDB的索引文件存儲在.ibd文件中。

11、Innodb特有的文件

11.1、表空間文件

默認(rèn)的表空間文件是%datadir%/ibdata1為統(tǒng)一表空間文件,可以通過innodb_file_per_table參數(shù)設(shè)單獨(dú)表空間文件,存儲各表對應(yīng)的數(shù)據(jù)、索引、插入緩存等信息,其余信息還是存放在默認(rèn)的表空間.ibdata1中;

11.2、Redo日志文件

記錄innodb存儲引擎對應(yīng)數(shù)據(jù)所在的頁的更改物理情況,用于保證實(shí)例或介質(zhì)失敗后的數(shù)據(jù)完整性恢復(fù),先與數(shù)據(jù)持久化,innodb_log_file_size參數(shù)設(shè)置redo文件的大小,innodb_log_files_in_group參數(shù)設(shè)置redo文件組的文件數(shù)量,innodb_log_group_home_dir參數(shù)設(shè)置redo文件的路徑,ib_logfile*。
二進(jìn)制日志與重做日志區(qū)別

11.3、Undo日志文件

存在于共享表空間ibdata1里面,有一個回滾段地址,里面存放了頭信息,配置頭信息,段的頭信息,里面存儲了與redo相反的數(shù)據(jù)更新操作,如果rollback的話,就把undo段里面數(shù)據(jù)回寫到數(shù)據(jù)文件里面。undo log用來完成事務(wù)的回滾以及MVCC的功能

五、MySQL內(nèi)存結(jié)構(gòu)

MySQL內(nèi)存分配規(guī)則是,用多少給多少,最高到配置的值,不是立即分配;MySQL中內(nèi)存大致分為全局內(nèi)存(Global buffer)、線程內(nèi)存(Thread buffer)兩大部分。

1、Global Buffer

innodb_buffer_pool_size(IBP)
InnoDB高速緩存data page和index page,是對InnoDB引擎影響最大的參數(shù),建議設(shè)置為內(nèi)存的50%-80%;合并插入緩存也是其中的一部分;
通過show global status like 'innodb_buffer_pool_%'\G;查看IBP的狀態(tài),單位是page(16kb),如果Innodb_buffer_pool_wait_free較大需要增加IBP;
通過show status like 'innodb_data_read%';查詢的值計算IBP的各種效率,Innodb_data_read總共讀入的字節(jié)數(shù),Innodb_data_reads發(fā)起請求的次數(shù),每次讀取可能需要讀取多個頁;
IBP利用率:(1-Innodb_buffer_pool_reads/Innodb_buffer_pool_read_requests)*100%,Innodb_buffer_pool_reads(從物理磁盤讀取的頁數(shù))Innodb_buffer_pool_read_requests(從緩沖池中讀取的頁數(shù));
IBP命中率:Innodb_buffer_pool_read_requests/(Innodb_buffer_pool_read_
requests+Innodb_buffer_pool_reads+Innodb_buffer_pool_read_ahead);
平均每次讀取的字節(jié)數(shù):Innodb_data_read/Innodb_data_reads
innodb_log_buffer_size
InnoDB redo日志緩沖區(qū),提高redo寫入效率,如果show global status like '%Innodb%'\G;查出Innodb_log_waits大于0則需要增加該區(qū)域大小;
query_cache_size
查詢高速緩沖,緩存結(jié)果,減少硬解析,建議關(guān)閉,通過專業(yè)的緩存redis等處理;

2、Thread Buffer

每個連接到MySQL服務(wù)器的線程都需要自己的緩沖,連接時大概會立即分配256k,甚至在現(xiàn)場空閑時他們使用默認(rèn)的線程堆棧網(wǎng)絡(luò)緩存等。當(dāng)需要進(jìn)行復(fù)雜操作時會給分配相應(yīng)的內(nèi)存空間,操作完成后即釋放。
read_buffer_size:對表進(jìn)行順序掃描的請求分配的讀入緩沖區(qū);
read_rnd_buffer_size:對表進(jìn)行任意行讀取時分配隨機(jī)讀緩存區(qū);
sort_buffer_size:對查詢數(shù)據(jù)進(jìn)行排序使用的緩存大小;
join_buffer_size:減少參與join的“被驅(qū)動表”的讀取次數(shù)以提高性能,當(dāng)空間不足時會分批在join_buffer中進(jìn)行;
binlog_cache_size:二進(jìn)制日志緩存大小,提高二進(jìn)制日志寫入效率,可以通過如下狀態(tài)信息查看Binlog_cache_disk_use,Binlog_cache_use;
thread_cache_size:默認(rèn)是9需要根據(jù)業(yè)務(wù)進(jìn)行比較的修改,如1024;

六、MySQL查詢執(zhí)行過程

查詢緩存,判斷sql語句是否完全匹配,再判斷是否有權(quán)限,兩個判斷為假則到解析器解析語句,為真則提取數(shù)據(jù)結(jié)果返回給用戶;
解析器解析。解析器先詞法分析,語法分析,檢查錯誤比如引號有沒閉合等,然后生成解析樹;
預(yù)處理。預(yù)處理解決解析器無法決解的語義,如檢查表和列是否存在,別名是否有錯,生成新的解析樹;
優(yōu)化器做大量的優(yōu)化操作;
生成執(zhí)行計劃;
查詢執(zhí)行引擎,負(fù)責(zé)調(diào)度存儲引擎獲取相應(yīng)數(shù)據(jù);
返回結(jié)果

七、MVCC機(jī)制

MVCC是一種多版本并發(fā)控制機(jī)制,行級鎖對系統(tǒng)的開銷較大,通過保存數(shù)據(jù)在某個時間點(diǎn)的快照來實(shí)現(xiàn)MVCC可以替代行鎖,降低系統(tǒng)并發(fā)控制的開銷。
一致性的非鎖定讀:InnoDB存儲引擎通過行多版本控制的方式來讀取當(dāng)前執(zhí)行時間數(shù)據(jù)庫中行的數(shù)據(jù)。如果讀取的行正在執(zhí)行Delete、update操作,這時讀取操作不會因此而會等待行上鎖的釋放,相反,InnoDB存儲引擎會去讀取行的一個快照數(shù)據(jù)。快照數(shù)據(jù)是指該行之前版本的數(shù)據(jù),該實(shí)現(xiàn)是通過Undo段來實(shí)現(xiàn)。而Undo用來事務(wù)中回滾數(shù)據(jù),因此快照本身是沒有額外開銷的。此外,快照數(shù)據(jù)是不需要上鎖的,因?yàn)闆]有必要對歷史的數(shù)據(jù)進(jìn)行修改。一個行可能有不止一個快照數(shù)據(jù),所以稱這種技術(shù)為行多版本技術(shù)。由此帶來并發(fā)控制,稱之為多版本并發(fā)控制(Multi VersionConcurrency Control, MVCC)。

1、InnoDB的MVCC

MVCC (Multiversion Concurrency Control),即多版本并發(fā)控制技術(shù),它使得大部分支持行鎖的事務(wù)引擎,不再單純的使用行鎖來進(jìn)行數(shù)據(jù)庫的并發(fā)控制,取而代之的是把數(shù)據(jù)庫的行鎖與行的多個版本結(jié)合起來,只需要很小的開銷,就可以實(shí)現(xiàn)非鎖定讀,從而大大提高數(shù)據(jù)庫系統(tǒng)的并發(fā)性能,MVCC是通過保存數(shù)據(jù)在某個時間點(diǎn)的快照來實(shí)現(xiàn)的。
讀鎖,S鎖,若當(dāng)前事務(wù)T對數(shù)據(jù)對象A加S鎖,則T可以讀取A,其他事務(wù)可以對A加S鎖,但T和其他事務(wù)都不能修改A;
寫鎖,X鎖,若當(dāng)前事務(wù)T對數(shù)據(jù)對象A加X鎖,則T可以讀也可以修改A,其他事務(wù)不能對A加任何鎖(即不能讀取或修改A);
表鎖,操作對象是數(shù)據(jù)表,若當(dāng)前事務(wù)T對表A加讀鎖,其他事務(wù)可讀不可寫;若加寫鎖,其他事務(wù)增刪改都不行;
行級鎖,操作對象是數(shù)據(jù)表中的一行數(shù)據(jù),行級鎖是MySQL存儲引擎實(shí)現(xiàn)的,不是MySQL服務(wù)器實(shí)現(xiàn)的,行級鎖開銷大,但并發(fā)性好。
InnoDB的MVCC主要是為Repeatable-Read事務(wù)隔離級別做的,簡單的理解InnoDB是通過在每行記錄后面保存兩個隱藏的列來實(shí)現(xiàn)MVCC,這兩個列分別保存了這個行的創(chuàng)建時間和刪除時間(系統(tǒng)版本號,也可以理解為事務(wù)的ID),每開始一個事務(wù),系統(tǒng)版本號會自動增加。通過這兩時間(系統(tǒng)版本號),在不同的事務(wù)隔離級別下操作相應(yīng)的數(shù)據(jù)行。
Select:只會檢索創(chuàng)建時間版本早于當(dāng)前系統(tǒng)版本號的數(shù)據(jù)行(系統(tǒng)版本號小于或等于當(dāng)前事務(wù)對應(yīng)的系統(tǒng)版本號)且行的刪除版本要么未定義,要么大于當(dāng)前版本號;
Insert:InnoDB會為每個新增的行(創(chuàng)建時間)記錄當(dāng)前系統(tǒng)版本號;
Delete:InnoDB會為每個刪除的行(刪除時間)記錄當(dāng)前系統(tǒng)版本號;
Update:InnoDB會為新增的一行數(shù)據(jù)的(創(chuàng)建時間)記錄當(dāng)前系統(tǒng)版本號,同時也會把被修改的數(shù)據(jù)行的(刪除時間)記錄當(dāng)前系統(tǒng)版本號;
MVCC應(yīng)有的特點(diǎn),每行數(shù)據(jù)都存在一個版本,每次數(shù)據(jù)更新時都更新的該版本;修改是copy當(dāng)前版本隨意修改,各事務(wù)之間無干擾;保存時比較版本號,如果成功(commit),則覆蓋原記錄,失敗則放棄copy(rollback)。
InnoDB的實(shí)現(xiàn)方式,事務(wù)以排他鎖的方式修改原數(shù)據(jù);把修改前的數(shù)據(jù)放入Undo log通過回滾指針與主數(shù)據(jù)關(guān)聯(lián);修改成功則(commit),失敗則利用undo log(rollback)。具體執(zhí)行過程:begin->用排他鎖鎖定該行->記錄redo log->記錄undo log->修改當(dāng)前行的值,寫事務(wù)編號,回滾指針指向undo log中的修改前的行->end。
mvcc中update步驟:
記錄事務(wù)中修改行數(shù)據(jù)的相應(yīng)字段和值(包括舊版本事務(wù)id)在undo-log中記錄;
修改相應(yīng)數(shù)據(jù);
在redo-log中保存要修改的相應(yīng)(新版本事務(wù)id)數(shù)據(jù)寫入;
假如update不能正常運(yùn)行則根據(jù)undo-log redo-log 來恢復(fù);
當(dāng)然如果當(dāng)前版本事務(wù)沒有commit的話則通過undo-log信息恢復(fù)原始數(shù)據(jù)狀態(tài)。
所以InnoDB的實(shí)現(xiàn)真算不上MVCC,因?yàn)椴]有實(shí)現(xiàn)核心的多版本并存,undo log中的內(nèi)容只是串行化的結(jié)果,記錄了多個事務(wù)的過程,不屬于多版本共存。MVCC是通過版本號比對進(jìn)行事務(wù)的提交或回滾,類似于通過樂觀鎖替代兩階段提交,兩階段提交是保證多行數(shù)據(jù)修改一致性的唯一手段,其本職是鎖定;樂觀鎖本質(zhì)是消除鎖定,二者矛盾,所以理想的MVCC難以實(shí)現(xiàn)實(shí)際應(yīng)用,InnoDB只是在Repeatable-Read事務(wù)隔離級別下實(shí)現(xiàn)的一種非阻塞讀而已。
InnoDB的MVCC是行鎖的一個補(bǔ)充,主要實(shí)現(xiàn)了“Repeatable-Read”模式下的非鎖定讀(讀非阻塞)。
在Read Committed和Repeatable Read下,InnoDB存儲引擎使用非鎖定一致性讀。然而,對于快照的定義卻不同。在Read Committed事務(wù)隔離級別下,對于快照數(shù)據(jù),非鎖定一致性讀總是讀取被鎖定行的最新一份快照數(shù)據(jù)。在Repeatable事務(wù)隔離級別下,對于快照數(shù)據(jù),非鎖定一致性讀總是讀取事務(wù)開始時的行數(shù)據(jù)版本。

2、mvcc優(yōu)缺點(diǎn)

優(yōu)點(diǎn):在讀取數(shù)據(jù)時,innodb幾乎不用獲取任何鎖,在每個查詢通過版本檢查,只獲取需要的數(shù)據(jù)版本,提高系統(tǒng)并發(fā)度;
缺點(diǎn):為了實(shí)現(xiàn)多版本,innodb必須對每行增加相應(yīng)字段來存儲版本信息,同時需要維護(hù)每一行的版本信息,而且在檢索行的時候,需要進(jìn)行版本的比較,因而減低了查詢效率;innodb還需要定期清理不再需要的行版本,及時回收空間,這也增加開銷;

八、MySQL的事務(wù)

1、事務(wù)隔離級別

MySQL的事務(wù)是存儲引擎層實(shí)現(xiàn)的,本部分主要討論事務(wù)存儲引擎InnoDB相關(guān)事務(wù)原理。SQL標(biāo)準(zhǔn)定義了4類隔離級別,包括了一些具體規(guī)則,用來限定事務(wù)內(nèi)外的哪些改變是可見的,哪些是不可見的。低級別的隔離級一般支持更高的并發(fā)處理,并擁有更低的系統(tǒng)開銷。
Read Uncommitted(讀取未提交內(nèi)容)
在該隔離級別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。本隔離級別很少用于實(shí)際應(yīng)用,因?yàn)樗男阅芤膊槐绕渌墑e好多少。讀取未提交的數(shù)據(jù),也被稱之為臟讀(Dirty Read)。
Read Committed(讀取提交內(nèi)容)
這是大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認(rèn)隔離級別(但不是MySQL默認(rèn)的)。它滿足了隔離的簡單定義:一個事務(wù)只能看見已經(jīng)提交事務(wù)所做的改變。這種隔離級別 也支持所謂的不可重復(fù)讀(Nonrepeatable Read),因?yàn)橥皇聞?wù)的其他實(shí)例在該實(shí)例處理其間可能會有新的commit,所以同一select可能返回不同結(jié)果。
Repeatable Read(可重讀)
這是mysql的默認(rèn)事務(wù)隔離級別,它確保同一事務(wù)的多個實(shí)例在并發(fā)讀取數(shù)據(jù)時,會看到同樣的數(shù)據(jù)行。不過理論上,這會導(dǎo)致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時,另一個事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時,會發(fā)現(xiàn)有新的“幻影” 行。InnoDB和Falcon存儲引擎通過多版本并發(fā)控制(MVCC,Multiversion Concurrency Control)機(jī)制解決了該問題。
Serializable(可串行化)?
這是最高的隔離級別,它通過強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數(shù)據(jù)行上加上共享鎖。在這個級別,可能導(dǎo)致大量的超時現(xiàn)象和鎖競爭。serializable完全鎖定字段,若一個事務(wù)來查詢同一份數(shù)據(jù)就必須等待,直到前一個事務(wù)完成并解除鎖定為止 。是完整的隔離級別,會鎖定對應(yīng)的數(shù)據(jù)表格,因而會有效率的問題。
這四種隔離級別采取不同的鎖類型來實(shí)現(xiàn),若讀取的是同一個數(shù)據(jù)的話,就容易發(fā)生問題。例如:
臟讀(Drity Read):某個事務(wù)已更新一份數(shù)據(jù),另一個事務(wù)在此時讀取了同一份數(shù)據(jù),由于某些原因,前一個RollBack了操作,則后一個事務(wù)所讀取的數(shù)據(jù)就會是不正確的。
不可重復(fù)讀(Non-repeatable read):在一個事務(wù)的兩次查詢之中數(shù)據(jù)不一致,這可能是兩次查詢過程中間插入了一個事務(wù)更新了原有的數(shù)據(jù)。
幻讀(Phantom Read):在一個事務(wù)的兩次查詢中數(shù)據(jù)筆數(shù)不一致,例如有一個事務(wù)查詢了幾列(Row)數(shù)據(jù),而另一個事務(wù)卻在此時插入了新的幾列數(shù)據(jù),先前的事務(wù)在接下來的查詢中,就會發(fā)現(xiàn)有幾列數(shù)據(jù)是它先前所沒有的。
在MySQL中,實(shí)現(xiàn)了這四種隔離級別,分別有可能產(chǎn)生問題如下所示:

2、InnoDB事務(wù)

通過在log buffer中快速記錄SQL語句對數(shù)據(jù)頁的修改,并持久化至redo log文件,需要恢復(fù)時利用Redo log恢復(fù)相應(yīng)數(shù)據(jù);
通過拷貝修改前的數(shù)據(jù)至undo buffer,并持久化至undo log。rollback時利用undo log還原數(shù)據(jù);
通過行級鎖,和MVCC機(jī)制提高數(shù)據(jù)庫并發(fā)能力的同時降低了系統(tǒng)資源開銷;
事務(wù)的四個特性:原子性、一致性、隔離性、持久性?
隔離性通過鎖實(shí)現(xiàn),原子性、一致性、持久性通過數(shù)據(jù)庫的redo和undo來完成。?
重做日志記錄了事務(wù)的行為,通過redo實(shí)現(xiàn),保證了事務(wù)的完整性,但事務(wù)有時還需要撤銷,這時就需要產(chǎn)生undo。undo和redo正好相反,對于數(shù)據(jù)庫進(jìn)行修改時,數(shù)據(jù)庫不但會產(chǎn)生redo,而且還會產(chǎn)生一定的undo,即使執(zhí)行的事務(wù)或語句由于某種原因失敗了,或者如果用一條rollback語句請求回滾,就可以用這些undo信息將數(shù)據(jù)回滾到修改之前的樣子。

3、InnoDB鎖信息查詢

在INFORMATION_SCHEMA架構(gòu)下添加了INNODB_TRX、INNODB_LOCKS、InnoDB_LOCK_WAITS。通過這三張表,可以更簡單地監(jiān)控當(dāng)前的事務(wù)并分析可能存在的鎖的問題。
INNODB_TRX由8個字段組成:?
trx_id:InnoDB存儲引擎內(nèi)部唯一的事務(wù)ID?
trx_state:當(dāng)前事務(wù)的狀態(tài)。?
trx_started:事務(wù)的開始時間。?
trx_requested_lock_id:等待事務(wù)的鎖ID。如trx_state的狀態(tài)為LOCK WAIT,那么該值代表當(dāng)前的等待之前事務(wù)占用鎖資源的ID.若trx_state不是LOCK WAIT,則該值為NULL。?
trx_wait_started:事務(wù)等待開始的時間。?
trx_weight:事務(wù)的權(quán)重,反映了一個事務(wù)修改和鎖住的行數(shù)。在InnoDB存儲引擎中,當(dāng)發(fā)生死鎖需要回滾時,InnoDB存儲會選擇該值最小的進(jìn)行回滾。?
trx_mysql_thread_id:Mysql中的線程ID,SHOW PROCESSLIST顯示的結(jié)果。?
trx_query:事務(wù)運(yùn)行的sql語句。?
通過select * from infomation_schema.INNODB_TRX;可查看?
INNODB_LOCKS表,該表由如下字段組成:?
lock_id:鎖的ID。?
lock_trx_id:事務(wù)ID。?
lock_mode:鎖的模式。?
lock_type:鎖的類型,表鎖還是行鎖。?
lock_table:要加鎖的表。?
lock_index:鎖的索引。?
lock_space:InnoDB存儲引擎表空間的ID號。?
lock_page:被鎖住的頁的數(shù)量。若是表鎖,則該值為NULL。?
lock_rec:被鎖住的行的數(shù)量。若是表鎖,則該值為NULL。?
lock_data:被鎖住的行的主鍵值。當(dāng)是表鎖時,該值為NULL。?
通過select * from information_schema.INNODB_LOCK;可查看?
INNODB_LOCK_WAIT由4個字段組成:?
requesting_trx_id:申請鎖資源的事務(wù)ID。?
requesting_lock_id:申請的鎖的ID。?
blocking_trx_id:阻塞的鎖的ID。?
通過select * from information_schema.INNODB_LOCK_WAITS;可查看。?

4、鎖的算法

Record Lock:單行記錄上的鎖?
Gap Lock:間隙鎖,鎖定一個范圍,但不包含記錄本身?
Next-Key Lock:Gap Lock + Record Lock,鎖定一個范圍,并且鎖定記錄本身。

5、鎖的問題

丟失更新:經(jīng)典的數(shù)據(jù)庫問題,當(dāng)兩個或多個事務(wù)選擇同一行,然后基于最初選定的值更新該行時,會發(fā)生丟失更新問題。每個事務(wù)都不知道其它事務(wù)的存在。最后的更新將重寫由其它事務(wù)所做的更新,這將導(dǎo)致數(shù)據(jù)丟失。   
例:?
? ? 事務(wù)A和事務(wù)B同時修改某行的值,?
? ? ?1.事務(wù)A將數(shù)值改為1并提交?
? ? ?2.事務(wù)B將數(shù)值改為2并提交。?
? ? ?這時數(shù)據(jù)的值為2,事務(wù)A所做的更新將會丟失。?
? ? ?解決辦法:事務(wù)并行變串行操作,對更新操作加排他鎖。?
臟讀:一個事務(wù)讀到另一個事務(wù)未提交的更新數(shù)據(jù),即讀到臟數(shù)據(jù)。?
例:?
? ? 1.Mary的原工資為1000, 財務(wù)人員將Mary的工資改為了8000(但未提交事務(wù)) ? ? ? ?
? ? 2.Mary讀取自己的工資 ,發(fā)現(xiàn)自己的工資變?yōu)榱?000,歡天喜地!?
? ? 3.而財務(wù)發(fā)現(xiàn)操作有誤,回滾了事務(wù),Mary的工資又變?yōu)榱?000, 像這樣,Mary記取的工資數(shù)8000是一個臟數(shù)據(jù)。?
? ? 解決辦法:臟讀只有在事務(wù)隔離級別是Read Uncommitted的情況下才會出現(xiàn),innoDB默認(rèn)隔離級別是Repeatable Read,所以生產(chǎn)環(huán)境下不會出現(xiàn)臟讀。

不可重復(fù)讀:在同一個事務(wù)中,多次讀取同一數(shù)據(jù),返回的結(jié)果有所不同。換句話說就是,后續(xù)讀取可以讀到另一個事務(wù)已提交的更新數(shù)據(jù)。相反"可重復(fù)讀"在同一事務(wù)多次讀取數(shù)據(jù)時,能夠保證所讀數(shù)據(jù)一樣,也就是后續(xù)讀取不能讀到另一事務(wù)已提交的更新數(shù)據(jù)。臟讀和不可重復(fù)讀的主要區(qū)別在于,臟讀是讀到未提交的數(shù)據(jù),不可重復(fù)讀是讀到已提交的數(shù)據(jù)。
例:?
? ? ? 1.在事務(wù)1中,Mary 讀取了自己的工資為1000,操作并沒有完成?
? ? ? 2.在事務(wù)2中,這時財務(wù)人員修改了Mary的工資為2000,并提交了事務(wù).?
? ? ? 3.在事務(wù)1中,Mary 再次讀取自己的工資時,工資變?yōu)榱?000?
? ? ? 解決辦法:讀到已提交的數(shù)據(jù),一般數(shù)據(jù)庫是可接受的,因此事務(wù)隔離級別一般設(shè)為Read Committed。Mysql InnoDB通過Next-Key Lock算法避免不可重復(fù)讀,默認(rèn)隔離級別為Repeatable Read。
幻讀,事務(wù)中兩次讀取同一個范圍的數(shù)據(jù),讀到的記錄條數(shù)不一致。

?

轉(zhuǎn)載于:https://my.oschina.net/peakfang/blog/2240253

總結(jié)

以上是生活随笔為你收集整理的MySQL 体系结构详细介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。