寫在前面
1. MySQL 的重要性就不用再過多的強(qiáng)調(diào)了,相信很多人的開發(fā)學(xué)習(xí)之路都行從:Hello Word --> CRUD。?作為一名后端開發(fā)人員不僅要熟練掌握 SQL 語句想许,還要弄清楚數(shù)據(jù)庫的底層原理,這樣才能在設(shè)計(jì)時(shí),考慮周到流纹。記得我第二段實(shí)習(xí)糜烹,有一個(gè)周五臨近下班的時(shí)間,突然監(jiān)控系統(tǒng)出現(xiàn)大量報(bào)警漱凝,于是組內(nèi)大佬們就趕緊排查問題疮蹦,后來發(fā)現(xiàn)是運(yùn)營活動(dòng)時(shí)間配置錯(cuò)誤(不要糾結(jié)為什么沒有合法性校驗(yàn))。但是由于組內(nèi)一位大佬當(dāng)時(shí)寫這塊代碼時(shí)在 SQL 語句上加了兜底策略茸炒,避免了事故的加劇愕乎,這一行 SQL 可謂是價(jià)值“千金”,當(dāng)時(shí)簡直是膜拜壁公!深刻感受到 SQL 的重要性妆毕!
2. 我學(xué)習(xí)數(shù)據(jù)庫這個(gè)模塊的時(shí)候主要分為兩個(gè)階段:第一個(gè)階段主要是學(xué)習(xí) SQL 語句,主要看的視頻贮尖,分為基礎(chǔ)和高級(jí),資源截圖如下趁怔,需要的可以在我公眾號(hào)“資源分享”里獲得湿硝。
第二個(gè)階段主要是看書,做筆記:先看了《MySQL必知必會(huì)》這本小冊(cè)子润努,這本書還是很通俗易懂的关斜,建議大家可以看看。還有一本《高性能MySQL》铺浇,相信很多人都看過這本書痢畜。這本書對(duì) MySQL 架構(gòu)、索引鳍侣、查詢性能優(yōu)化等進(jìn)行了詳細(xì)的講解丁稀,同樣推薦大家花時(shí)間好好看一看。
3. 看面經(jīng)和做筆記倚聚,這兩點(diǎn)的重要性就不多說了线衫。
4. MySQL 的常問方式,我總結(jié)有以下幾個(gè)大的方面:
(1)場景題惑折,手寫 SQL授账;
(2)MySQL 的相關(guān)底層原理:存儲(chǔ)引擎、索引惨驶、鎖白热、事務(wù)等等;
(3)查詢性能優(yōu)化粗卜。
1屋确、請(qǐng)說下你對(duì) MySQL 架構(gòu)的了解?
先看下 MySQL 的基本架構(gòu)圖:
大體來說,MySQL 可以分為 Server 層和存儲(chǔ)引擎兩部分乍恐。
Server 層包括:連接器评疗、查詢緩存、分析器茵烈、優(yōu)化器百匆、執(zhí)行器等,涵蓋了 MySQL 的大多數(shù)核心服務(wù)功能呜投,以及所有的內(nèi)置函數(shù)(如:日期加匈、時(shí)間、數(shù)學(xué)和加密函數(shù)等)仑荐,所有跨存儲(chǔ)引擎的功能都在這一層實(shí)現(xiàn)雕拼,比如:存儲(chǔ)過程、觸發(fā)器粘招、視圖等等啥寇。
存儲(chǔ)引擎層負(fù)責(zé):數(shù)據(jù)的存儲(chǔ)和提取。其架構(gòu)是插件式的洒扎,支持 InnoDB辑甜、MyISAM 等多個(gè)存儲(chǔ)引擎。從 MySQL5.5.5 版本開始默認(rèn)的是InnoDB袍冷,但是在建表時(shí)可以通過 engine = MyISAM 來指定存儲(chǔ)引擎磷醋。不同存儲(chǔ)引擎的表數(shù)據(jù)存取方式不同,支持的功能也不同胡诗。
從上圖中可以看出邓线,不同的存儲(chǔ)引擎共用一個(gè) Server 層,也就是從連接器到執(zhí)行器的部分煌恢。
2骇陈、一條 SQL 語句在數(shù)據(jù)庫框架中的執(zhí)行流程?
1. 應(yīng)用程序把查詢 SQL 語句發(fā)送給服務(wù)器端執(zhí)行症虑;
2. 查詢緩存缩歪,如果查詢緩存是打開的,服務(wù)器在接收到查詢請(qǐng)求后谍憔,并不會(huì)直接去數(shù)據(jù)庫查詢匪蝙,而是在數(shù)據(jù)庫的查詢緩存中找是否有相對(duì)應(yīng)的查詢數(shù)據(jù),如果存在习贫,則直接返回給客戶端逛球。只有緩存不存在時(shí),才會(huì)進(jìn)行下面的操作苫昌;
3. 查詢優(yōu)化處理颤绕,生成執(zhí)行計(jì)劃。這個(gè)階段主要包括解析 SQL、預(yù)處理奥务、優(yōu)化 SQL 執(zhí)行計(jì)劃物独;
4. MySQL 根據(jù)相應(yīng)的執(zhí)行計(jì)劃完成整個(gè)查詢;
5. 將查詢結(jié)果返回給客戶端氯葬。
詳細(xì)過程可以看我的博客:
https://blog.csdn.net/pcwl1206/article/details/86137408
3挡篓、數(shù)據(jù)庫的三范式是什么?
1. 第一范式:強(qiáng)調(diào)的是列的原子性帚称,即數(shù)據(jù)庫表的每一列都是不可分割的原子數(shù)據(jù)項(xiàng)官研;
2. 第二范式:要求實(shí)體的屬性完全依賴于主關(guān)鍵字。所謂完全依賴是指不能存在僅依賴主關(guān)鍵字一部分的屬性闯睹;
3. 第三范式:任何非主屬性不依賴于其它非主屬性戏羽。
4、MySQL 中的數(shù)據(jù)類型有哪些楼吃?
?MySQL 中的數(shù)據(jù)類型主要有數(shù)值類型始花、時(shí)間/日期類型、字符串類型孩锡,如下圖所示:
5衙荐、char 和 varchar 的區(qū)別?
char(n)?:固定長度類型浮创,比如:訂閱 char(10),當(dāng)你輸入"abc"三個(gè)字符的時(shí)候砌函,它們占的空間還是 10 個(gè)字節(jié)斩披,其他 7 個(gè)是空字節(jié)。char 優(yōu)點(diǎn):效率高讹俊;缺點(diǎn):占用空間垦沉;適用場景:存儲(chǔ)密碼的 md5 值,固定長度的仍劈,使用 char 非常合適厕倍。
varchar(n)?:可變長度,存儲(chǔ)的值是每個(gè)值占用的字節(jié)再加上一個(gè)用來記錄其長度的字節(jié)的長度贩疙。
所以讹弯,從空間上考慮 varcahr 比較合適;從效率上考慮 char 比較合適这溅,二者使用需要權(quán)衡组民。
6、varchar(10) 和 varchar(20)?的區(qū)別悲靴?
varchar(10) 中 10 的涵義最多存放 10 個(gè)字符臭胜,varchar(10) 和 varchar(20) 存儲(chǔ)? hello 所占空間一樣,但后者在排序時(shí)會(huì)消耗更多內(nèi)存,因?yàn)?order by col 采用 fixed_length 計(jì)算 col 長度耸三。
7乱陡、談?wù)勀銓?duì)索引的理解?
索引的出現(xiàn)是為了提高數(shù)據(jù)的查詢效率仪壮,就像書的目錄一樣憨颠。一本500頁的書,如果你想快速找到其中的某一個(gè)知識(shí)點(diǎn)睛驳,在不借助目錄的情況下烙心,那我估計(jì)你可得找一會(huì)兒。同樣乏沸,對(duì)于數(shù)據(jù)庫的表而言淫茵,索引其實(shí)就是它的“目錄”。
同樣索引也會(huì)帶來很多負(fù)面影響:創(chuàng)建索引和維護(hù)索引需要耗費(fèi)時(shí)間蹬跃,這個(gè)時(shí)間隨著數(shù)據(jù)量的增加而增加匙瘪;索引需要占用物理空間,不光是表需要占用數(shù)據(jù)空間蝶缀,每個(gè)索引也需要占用物理空間丹喻;當(dāng)對(duì)表進(jìn)行增、刪翁都、改碍论、的時(shí)候索引也要?jiǎng)討B(tài)維護(hù),這樣就降低了數(shù)據(jù)的維護(hù)速度柄慰。
建立索引的原則:
1. 在最頻繁使用的鳍悠、用以縮小查詢范圍的字段上建立索引;
2. 在頻繁使用的坐搔、需要排序的字段上建立索引藏研。
不適合建立索引的情況:
1. 對(duì)于查詢中很少涉及的列或者重復(fù)值比較多的列,不宜建立索引概行;
2. 對(duì)于一些特殊的數(shù)據(jù)類型蠢挡,不宜建立索引,比如:文本字段(text)等凳忙。
8业踏、索引的底層使用的是什么數(shù)據(jù)結(jié)構(gòu)?
索引的數(shù)據(jù)結(jié)構(gòu)和具體存儲(chǔ)引擎的實(shí)現(xiàn)有關(guān),涧卵,在MySQL中使用較多的索引有 Hash 索引堡称、B+樹索引等。而我們經(jīng)常使用的 InnoDB 存儲(chǔ)引擎的默認(rèn)索引實(shí)現(xiàn)為 B+ 樹索引艺演。
9却紧、談?wù)勀銓?duì) B+ 樹的理解桐臊?
1. B+ 樹是基于 B 樹和葉子節(jié)點(diǎn)順序訪問指針進(jìn)行實(shí)現(xiàn),它具有 B 樹的平衡性晓殊,并且通過順序訪問指針來提高區(qū)間查詢的性能断凶。
2. 在 B+ 樹中,一個(gè)節(jié)點(diǎn)中的 key 從左到右非遞減排列巫俺,如果某個(gè)指針的左右相鄰 key 分別是 key i 和 key i+1认烁,且不為 null,則該指針指向節(jié)點(diǎn)的所有 key 大于等于 key i 且小于等于 key i+1介汹。
3. 進(jìn)行查找操作時(shí)却嗡,首先在根節(jié)點(diǎn)進(jìn)行二分查找,找到一個(gè) key 所在的指針嘹承,然后遞歸地在指針?biāo)赶虻墓?jié)點(diǎn)進(jìn)行查找窗价。直到查找到葉子節(jié)點(diǎn),然后在葉子節(jié)點(diǎn)上進(jìn)行二分查找叹卷,找出 key 所對(duì)應(yīng)的 data撼港。
4. 插入、刪除操作會(huì)破壞平衡樹的平衡性骤竹,因此在插入刪除操作之后帝牡,需要對(duì)樹進(jìn)行一個(gè)分裂、合并蒙揣、旋轉(zhuǎn)等操作來維護(hù)平衡性靶溜。
10、為什么 InnoDB 存儲(chǔ)引擎選用 B+ 樹而不是 B 樹呢懒震?
用 B+ 樹不用 B 樹考慮的是 IO 對(duì)性能的影響墨技,B 樹的每個(gè)節(jié)點(diǎn)都存儲(chǔ)數(shù)據(jù),而 B+ 樹只有葉子節(jié)點(diǎn)才存儲(chǔ)數(shù)據(jù)挎狸,所以查找相同數(shù)據(jù)量的情況下,B 樹的高度更高断楷,IO 更頻繁锨匆。數(shù)據(jù)庫索引是存儲(chǔ)在磁盤上的,當(dāng)數(shù)據(jù)量大時(shí)冬筒,就不能把整個(gè)索引全部加載到內(nèi)存了恐锣,只能逐一加載每一個(gè)磁盤頁(對(duì)應(yīng)索引樹的節(jié)點(diǎn))。
11舞痰、談?wù)勀銓?duì)聚簇索引的理解土榴?
聚簇索引是對(duì)磁盤上實(shí)際數(shù)據(jù)重新組織以按指定的一個(gè)或多個(gè)列的值排序的算法。特點(diǎn)是存儲(chǔ)數(shù)據(jù)的順序和索引順序一致响牛。一般情況下主鍵會(huì)默認(rèn)創(chuàng)建聚簇索引玷禽,且一張表只允許存在一個(gè)聚簇索引赫段。
聚簇索引和非聚簇索引的區(qū)別:
聚簇索引的葉子節(jié)點(diǎn)就是數(shù)據(jù)節(jié)點(diǎn),而非聚簇索引的葉子節(jié)點(diǎn)仍然是索引節(jié)點(diǎn)矢赁,只不過有指向?qū)?yīng)數(shù)據(jù)塊的指針糯笙。
12、談?wù)勀銓?duì)哈希索引的理解撩银?
哈希索引能以 O(1) 時(shí)間進(jìn)行查找给涕,但是失去了有序性。無法用于排序與分組额获、只支持精確查找够庙,無法用于部分查找和范圍查找。
InnoDB 存儲(chǔ)引擎有一個(gè)特殊的功能叫“自適應(yīng)哈希索引”抄邀,當(dāng)某個(gè)索引值被使用的非常頻繁時(shí)耘眨,會(huì)在 B+ 樹索引之上再創(chuàng)建一個(gè)哈希索引,這樣就讓 B+Tree 索引具有哈希索引的一些優(yōu)點(diǎn)撤摸,比如:快速的哈希查找毅桃。
13、談?wù)勀銓?duì)覆蓋索引的認(rèn)識(shí)准夷?
如果一個(gè)索引包含了滿足查詢語句中字段與條件的數(shù)據(jù)就叫做覆蓋索引钥飞。具有以下優(yōu)點(diǎn):
1. 索引通常遠(yuǎn)小于數(shù)據(jù)行的大小,只讀取索引能大大減少數(shù)據(jù)訪問量衫嵌。
2.一些存儲(chǔ)引擎(例如:MyISAM)在內(nèi)存中只緩存索引读宙,而數(shù)據(jù)依賴于操作系統(tǒng)來緩存。因此楔绞,只訪問索引可以不使用系統(tǒng)調(diào)用(通常比較費(fèi)時(shí))结闸。
3. 對(duì)于 InnoDB 引擎,若輔助索引能夠覆蓋查詢酒朵,則無需訪問主索引桦锄。
14、索引的分類蔫耽?
從數(shù)據(jù)結(jié)構(gòu)角度
1. 樹索引 (O(log(n)))
2. Hash 索引
從物理存儲(chǔ)角度
1. 聚集索引(clustered index)
2. 非聚集索引(non-clustered index)
從邏輯角度
1. 普通索引
2. 唯一索引
3. 主鍵索引
4. 聯(lián)合索引
5. 全文索引
14刻蚯、談?wù)勀銓?duì)最左前綴原則的理解幔欧?
MySQL 使用聯(lián)合索引時(shí)撬碟,需要滿足最左前綴原則伯顶。下面舉例對(duì)其進(jìn)行說明:
1.?一個(gè) 2 列的索引?(name, age),對(duì)?(name)鳖眼、(name, age)?上建立了索引黑毅;2.?一個(gè) 3 列的索引?(name, age, sex),對(duì)?(name)钦讳、(name, age)矿瘦、(name, age, sex)?上建立了索引枕面。
1. B+ 樹的數(shù)據(jù)項(xiàng)是復(fù)合的數(shù)據(jù)結(jié)構(gòu),比如:(name, age, sex) 的時(shí)候匪凡,B+ 樹是按照從左到右的順序來建立搜索樹的膊畴,比如:當(dāng)(小明, 22, 男)這樣的數(shù)據(jù)來檢索的時(shí)候,B+ 樹會(huì)優(yōu)先比較 name 來確定下一步的所搜方向病游,如果 name 相同再依次比較 age 和 sex唇跨,最后得到檢索的數(shù)據(jù)。但當(dāng) (22, 男) 這樣沒有 name 的數(shù)據(jù)來的時(shí)候衬衬,B+ 樹就不知道第一步該查哪個(gè)節(jié)點(diǎn)买猖,因?yàn)榻⑺阉鳂涞臅r(shí)候 name 就是第一個(gè)比較因子,必須要先根據(jù) name 來搜索才能知道下一步去哪里查詢滋尉。
2. 當(dāng) (小明, 男) 這樣的數(shù)據(jù)來檢索時(shí)玉控,B+ 樹可以用 name 來指定搜索方向,但下一個(gè)字段 age 的缺失狮惜,所以只能把名字等于小明的數(shù)據(jù)都找到高诺,然后再匹配性別是男的數(shù)據(jù)了, 這個(gè)是非常重要的性質(zhì)碾篡,即索引的最左匹配特性虱而。
關(guān)于最左前綴的補(bǔ)充:
1. 最左前綴匹配原則會(huì)一直向右匹配直到遇到范圍查詢(>、<开泽、between牡拇、like)就停止匹配,比如:a = 1 and b = 2 and c > 3 and d = 4 如果建立 (a, b, c, d) 順序的索引穆律,d 是用不到索引的惠呼。如果建立 (a, b, d, c) 的索引則都可以用到,a峦耘、b剔蹋、d 的順序可以任意調(diào)整。
2. = 和 in 可以亂序辅髓,比如:a = 1 and b = 2 and c = 3 建立 (a, b ,c) 索引可以任意順序泣崩,MySQL 的優(yōu)化器會(huì)優(yōu)化成索引可以識(shí)別的形式。
15利朵、怎么知道創(chuàng)建的索引有沒有被使用到?或者說怎么才可以知道這條語句運(yùn)行很慢的原因?
使用 Explain 命令來查看語句的執(zhí)行計(jì)劃猎莲,MySQL 在執(zhí)行某個(gè)語句之前绍弟,會(huì)將該語句過一遍查詢優(yōu)化器,之后會(huì)拿到對(duì)語句的分析著洼,也就是執(zhí)行計(jì)劃樟遣,其中包含了許多信息而叼。可以通過其中和索引有關(guān)的信息來分析是否命中了索引豹悬,例如:possilbe_key葵陵、key、key_len 等字段瞻佛,分別說明了此語句可能會(huì)使用的索引脱篙、實(shí)際使用的索引以及使用的索引長度。
16伤柄、什么情況下索引會(huì)失效绊困?即查詢不走索引?
下面列舉幾種不走索引的 SQL 語句:
1. 索引列參與表達(dá)式計(jì)算:
SELECT'sname'FROM'stu'WHERE'age'+10=30;
2. 函數(shù)運(yùn)算:
SELECT'sname'FROM'stu'WHERELEFT('date',4)?<1990;
3. %詞語%--模糊查詢:
SELECT*FROM'manong'WHERE`uname`LIKE'碼農(nóng)%'--?走索引?SELECT*FROM'manong'WHERE`uname`LIKE"%碼農(nóng)%"--?不走索引?
4. 字符串與數(shù)字比較不走索引:
CREATETABLE'a'('a'char(10));EXPLAINSELECT*FROM'a'WHERE'a'="1"--?走索引?EXPLAINSELECT*FROM'a'WHERE'a'=1--?不走索引适刀,同樣也是使用了函數(shù)運(yùn)算?
5. 查詢條件中有 or 秤朗,即使其中有條件帶索引也不會(huì)使用。換言之笔喉,就是要求使用的所有字段取视,都必須建立索引:
select*fromdeptwheredname='xxx'orloc='xx'ordeptno =45;
6. 正則表達(dá)式不使用索引。
7. MySQL 內(nèi)部優(yōu)化器會(huì)對(duì) SQL 語句進(jìn)行優(yōu)化常挚,如果優(yōu)化器估計(jì)使用全表掃描要比使用索引快作谭,則不使用索引。
17待侵、查詢性能的優(yōu)化方法丢早?
減少請(qǐng)求的數(shù)據(jù)量
1. 只返回必要的列:最好不要使用 SELECT * 語句。
2. 只返回必要的行:使用 LIMIT 語句來限制返回的數(shù)據(jù)秧倾。
3. 緩存重復(fù)查詢的數(shù)據(jù):使用緩存可以避免在數(shù)據(jù)庫中進(jìn)行查詢怨酝,特別在要查詢的數(shù)據(jù)經(jīng)常被重復(fù)查詢時(shí),緩存帶來的查詢性能提升將會(huì)是非常明顯的那先。
減少服務(wù)器端掃描的行數(shù)
1. 最有效的方式是使用索引來覆蓋查詢农猬。
18、InnoDB 和 MyISAM 的比較售淡?
1. 事務(wù):MyISAM不支持事務(wù)斤葱,InnoDB支持事務(wù);
2. 全文索引:MyISAM 支持全文索引揖闸,InnoDB 5.6 之前不支持全文索引揍堕;
3. 關(guān)于 count(*):MyISAM會(huì)直接存儲(chǔ)總行數(shù),InnoDB 則不會(huì)汤纸,需要按行掃描衩茸。意思就是對(duì)于 select count(*) from table; 如果數(shù)據(jù)量大,MyISAM 會(huì)瞬間返回贮泞,而 InnoDB 則會(huì)一行行掃描楞慈;
4. 外鍵:MyISAM 不支持外鍵幔烛,InnoDB 支持外鍵;
5. 鎖:MyISAM 只支持表鎖囊蓝,InnoDB 可以支持行鎖饿悬。
19、談?wù)勀銓?duì)水平切分和垂直切分的理解聚霜?
水平切分
水平切分是將同一個(gè)表中的記錄拆分到多個(gè)結(jié)構(gòu)相同的表中狡恬。當(dāng)一個(gè)表的數(shù)據(jù)不斷增多時(shí),水平切分是必然的選擇俯萎,它可以將數(shù)據(jù)分布到集群的不同節(jié)點(diǎn)上傲宜,從而緩存單個(gè)數(shù)據(jù)庫的壓力。
垂直切分
垂直切分是將一張表按列切分成多個(gè)表夫啊,通常是按照列的關(guān)系密集程度進(jìn)行切分函卒,也可以利用垂直切分將經(jīng)常被使用的列和不經(jīng)常被使用的列切分到不同的表中。例如:將原來的電商數(shù)據(jù)庫垂直切分成商品數(shù)據(jù)庫撇眯、用戶數(shù)據(jù)庫等报嵌。
20、主從復(fù)制中涉及到哪三個(gè)線程熊榛?
主要涉及三個(gè)線程:binlog 線程锚国、I/O 線程和 SQL 線程。
1. binlog 線程 :負(fù)責(zé)將主服務(wù)器上的數(shù)據(jù)更改寫入二進(jìn)制日志(Binary log)中玄坦。
2. I/O 線程 :負(fù)責(zé)從主服務(wù)器上讀取二進(jìn)制日志血筑,并寫入從服務(wù)器的重放日志(Relay log)中。
3. SQL 線程 :負(fù)責(zé)讀取重放日志并重放其中的 SQL 語句煎楣。
21豺总、主從同步的延遲原因及解決辦法?
主從同步的延遲的原因:
假如一個(gè)服務(wù)器開放 N 個(gè)連接給客戶端择懂,這樣有會(huì)有大并發(fā)的更新操作, 但是從服務(wù)器的里面讀取 binlog 的線程僅有一個(gè)喻喳, 當(dāng)某個(gè) SQL 在從服務(wù)器上執(zhí)行的時(shí)間稍長或者由于某個(gè) SQL 要進(jìn)行鎖表就會(huì)導(dǎo)致主服務(wù)器的 SQL 大量積壓,未被同步到從服務(wù)器里困曙。這就導(dǎo)致了主從不一致表伦, 也就是主從延遲。
主從同步延遲的解決辦法:
實(shí)際上主從同步延遲根本沒有什么一招制敵的辦法慷丽, 因?yàn)樗械?SQL 必須都要在從服務(wù)器里面執(zhí)行一遍蹦哼,但是主服務(wù)器如果不斷的有更新操作源源不斷的寫入,那么一旦有延遲產(chǎn)生要糊,那么延遲加重的可能性就會(huì)原來越大纲熏。當(dāng)然我們可以做一些緩解的措施。
1. 我們知道因?yàn)橹鞣?wù)器要負(fù)責(zé)更新操作, 它對(duì)安全性的要求比從服務(wù)器高赤套,所有有些設(shè)置可以修改,比如sync_binlog=1珊膜,innodb_flush_log_at_trx_commit = 1 之類的設(shè)置容握,而 slave 則不需要這么高的數(shù)據(jù)安全,完全可以將 sync_binlog 設(shè)置為 0 或者關(guān)閉 binlog车柠、innodb_flushlog剔氏、innodb_flush_log_at_trx_commit 也 可以設(shè)置為 0 來提高 SQL 的執(zhí)行效率。
2. 增加從服務(wù)器竹祷,這個(gè)目的還是分散讀的壓力谈跛, 從而降低服務(wù)器負(fù)載。
22塑陵、談?wù)勀銓?duì)數(shù)據(jù)庫讀寫分離的理解感憾?
讀寫分離常用代理方式來實(shí)現(xiàn),代理服務(wù)器接收應(yīng)用層傳來的讀寫請(qǐng)求令花,然后決定轉(zhuǎn)發(fā)到哪個(gè)服務(wù)器阻桅。主服務(wù)器處理寫操作以及實(shí)時(shí)性要求比較高的讀操作,而從服務(wù)器處理讀操作兼都。
讀寫分離能提高性能的原因在于:
1. 主從服務(wù)器負(fù)責(zé)各自的讀和寫嫂沉,極大程度緩解了鎖的爭用;
2. 從服務(wù)器可以使用 MyISAM扮碧,提升查詢性能以及節(jié)約系統(tǒng)開銷趟章;
3. 增加冗余,提高可用性慎王。
23蚓土、請(qǐng)你描述下事務(wù)的特性?
1. 原子性:事務(wù)是最小的執(zhí)行單位柬祠,不允許分割北戏。事務(wù)的原子性確保動(dòng)作要么全部完成,要么完全不起作用漫蛔;
2. 一致性:執(zhí)行事務(wù)前后嗜愈,數(shù)據(jù)庫從一個(gè)一致性狀態(tài)轉(zhuǎn)換到另一個(gè)一致性狀態(tài)。
3. 隔離性:并發(fā)訪問數(shù)據(jù)庫時(shí)莽龟,一個(gè)用戶的事物不被其他事務(wù)所干擾蠕嫁,各并發(fā)事務(wù)之間數(shù)據(jù)庫是獨(dú)立的;
4. 持久性:一個(gè)事務(wù)被提交之后毯盈。它對(duì)數(shù)據(jù)庫中數(shù)據(jù)的改變是持久的剃毒,即使數(shù)據(jù)庫 發(fā)生故障也不應(yīng)該對(duì)其有任何影響。
24、談?wù)勀銓?duì)事務(wù)隔離級(jí)別的理解赘阀?
1. READ_UNCOMMITTED(未提交讀): 最低的隔離級(jí)別益缠,允許讀取尚未提交的數(shù)據(jù)變更,可能會(huì)導(dǎo)致臟讀基公、幻讀或不可重復(fù)讀幅慌;
2. READ_COMMITTED(提交讀): 允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù),可以阻止臟讀轰豆,但是幻讀或不可重復(fù)讀仍有可能發(fā)生胰伍;
3. REPEATABLE_READ(可重復(fù)讀): 對(duì)同一字段的多次讀取結(jié)果都是一致的,除非數(shù)據(jù)是被本身事務(wù)自己所修改酸休,可以阻止臟讀和不可重復(fù)讀骂租,但幻讀仍有可能發(fā)生;
4. SERIALIZABLE(串行化): 最高的隔離級(jí)別斑司,完全服從 ACID 的隔離級(jí)別渗饮。所有的事務(wù)依次逐個(gè)執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾宿刮,也就是說抽米,該級(jí)別可以防止臟讀、不可重復(fù)讀以及幻讀糙置。但是這將嚴(yán)重影響程序的性能云茸。通常情況下也不會(huì)用到該級(jí)別。
25谤饭、解釋下什么叫臟讀标捺、不可重復(fù)讀和幻讀?
臟讀:
表示一個(gè)事務(wù)能夠讀取另一個(gè)事務(wù)中還未提交的數(shù)據(jù)揉抵。比如:某個(gè)事務(wù)嘗試插入記錄 A亡容,此時(shí)該事務(wù)還未提交,然后另一個(gè)事務(wù)嘗試讀取到了記錄 A冤今。
不可重復(fù)讀?:
是指在一個(gè)事務(wù)內(nèi)闺兢,多次讀同一數(shù)據(jù)。
幻讀:
指同一個(gè)事務(wù)內(nèi)多次查詢返回的結(jié)果集不一樣戏罢。比如同一個(gè)事務(wù) A 第一次查詢時(shí)候有 n 條記錄屋谭,但是第二次同等條件下查詢卻有 n+1 條記錄,這就好像產(chǎn)生了幻覺龟糕。發(fā)生幻讀的原因也是另外一個(gè)事務(wù)新增或者刪除或者修改了第一個(gè)事務(wù)結(jié)果集里面的數(shù)據(jù)桐磁,同一個(gè)記錄的數(shù)據(jù)內(nèi)容被修改了,所有數(shù)據(jù)行的記錄就變多或者變少了讲岁。
26我擂、MySQL 默認(rèn)的隔離級(jí)別是什么衬以?
MySQL默認(rèn)采用的 REPEATABLE_READ隔離級(jí)別。
Oracle 默認(rèn)采用的 READ_COMMITTED 隔離級(jí)別校摩。
27看峻、談?wù)勀銓?duì)?MVCC 的了解?
數(shù)據(jù)庫并發(fā)場景:
1. 讀-讀:不存在任何問題衙吩,也不需要并發(fā)控制备籽;
2. 讀-寫:有線程安全問題,可能會(huì)造成事務(wù)隔離性問題分井,可能遇到臟讀,幻讀霉猛,不可重復(fù)讀尺锚;
3. 寫-寫:有線程安全問題,可能會(huì)存在更新丟失問題惜浅。
多版本并發(fā)控制(MVCC)是一種用來解決讀-寫沖突的無鎖并發(fā)控制瘫辩,也就是為事務(wù)分配單向增長的時(shí)間戳,為每個(gè)修改保存一個(gè)版本坛悉,版本與事務(wù)時(shí)間戳關(guān)聯(lián)伐厌,讀操作只讀該事務(wù)開始前的數(shù)據(jù)庫的快照。?
?MVCC 可以為數(shù)據(jù)庫解決以下問題:
1. 在并發(fā)讀寫數(shù)據(jù)庫時(shí)裸影,可以做到在讀操作時(shí)不用阻塞寫操作挣轨,寫操作也不用阻塞讀操作,提高了數(shù)據(jù)庫并發(fā)讀寫的性能轩猩;
2. 同時(shí)還可以解決臟讀卷扮,幻讀,不可重復(fù)讀等事務(wù)隔離問題均践,但不能解決更新丟失問題晤锹。
28、說一下 MySQL 的行鎖和表鎖彤委?
MyISAM 只支持表鎖鞭铆,InnoDB 支持表鎖和行鎖,默認(rèn)為行鎖焦影。
表級(jí)鎖:開銷小车遂,加鎖快,不會(huì)出現(xiàn)死鎖斯辰。鎖定粒度大艰额,發(fā)生鎖沖突的概率最高,并發(fā)量最低椒涯。
行級(jí)鎖:開銷大柄沮,加鎖慢,會(huì)出現(xiàn)死鎖。鎖力度小祖搓,發(fā)生鎖沖突的概率小狱意,并發(fā)度最高。
29拯欧、InnoDB 存儲(chǔ)引擎的鎖的算法有哪些详囤?
1. Record lock:單個(gè)行記錄上的鎖;
2. Gap lock:間隙鎖镐作,鎖定一個(gè)范圍藏姐,不包括記錄本身;
3. Next-key lock:record+gap 鎖定一個(gè)范圍该贾,包含記錄本身羔杨。
30、MySQL 問題排查都有哪些手段杨蛋?
1. 使用 show processlist 命令查看當(dāng)前所有連接信息兜材;
2. 使用 Explain 命令查詢 SQL 語句執(zhí)行計(jì)劃;
3. 開啟慢查詢?nèi)罩境蚜Γ榭绰樵兊?SQL曙寡。
31、MySQL 數(shù)據(jù)庫 CPU 飆升到 500% 的話他怎么處理寇荧?
1. 列出所有進(jìn)程? show processlist举庶,觀察所有進(jìn)程,多秒沒有狀態(tài)變化的(干掉)揩抡;
2. 查看超時(shí)日志或者錯(cuò)誤日志 (一般會(huì)是查詢以及大批量的插入會(huì)導(dǎo)致 CPU與 I/O 上漲灯变,當(dāng)然不排除網(wǎng)絡(luò)狀態(tài)突然斷了,導(dǎo)致一個(gè)請(qǐng)求服務(wù)器只接受到一半捅膘。