-
技術(shù)性
1.加鎖lock
2.多行并發(fā)cuontdownlatch
3.最基本的代碼快,以及運(yùn)行的結(jié)果與驗(yàn)證邏輯和目的查看全部 -
1.搶紅包的設(shè)計目的是?
2.搶紅包的代碼并發(fā)與分類塊的群體如何區(qū)分?大數(shù)據(jù)分析的出用戶手機(jī)的人群角色?
3.搶紅包為了營造氣氛和收割用戶互聯(lián)網(wǎng)社交與用戶未來角色與精準(zhǔn)營銷而設(shè)計金額大小?
4.老年用戶與年輕用戶之間的互動,家庭成員之間關(guān)于網(wǎng)絡(luò)使用的正確打開方式的模塊會帶來更好的春晚的團(tuán)聚和良好的國風(fēng)家風(fēng)?
5.免費(fèi)始終是免費(fèi),可付費(fèi)也不見得這么多年春晚有搶紅包環(huán)節(jié)是市場營銷、頭部冠名贊助商、互聯(lián)網(wǎng)大咖品牌贊助商、實(shí)體品牌贊助商有將廣告文案、營銷與紅包讓利及真正的老舍下的身心健康真正運(yùn)用到實(shí)際,哪怕是無窮接近到實(shí)際也好,但從無。這也是這個免費(fèi)課程無法帶來更深層次的教育營銷和真正應(yīng)用到各行各業(yè)的營銷課程。下沉的教育營銷和公益營銷都夠不著………查看全部 -
學(xué)習(xí)數(shù)據(jù)
查看全部 -
Mysql
1.一條SQL查詢語句是如何執(zhí)行的?mysql的服務(wù)架構(gòu)
整體結(jié)構(gòu):MySQL Server架構(gòu)自頂向下大致可以分網(wǎng)絡(luò)連接層、服務(wù)層、存儲引擎層和系統(tǒng)文件層。
網(wǎng)絡(luò)連接層:也就是各種數(shù)據(jù)庫連接客戶端,如 常見的 Java、C、Python、.NET等,它們通過各自API技術(shù)與MySQL建立連接。
服務(wù)層:是MySQL Server的核心,主要包含 連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等。
存儲引擎層:各種存儲引擎,其架構(gòu)模式是插件式的,存儲引擎層負(fù)責(zé)數(shù)據(jù)的存儲和提取,MySQL 5.5.5 版本InnoDB開始成為了默認(rèn)存儲引擎。
系統(tǒng)文件層:各種系統(tǒng)文件,比如日志文件,比如 binlog? undo.log redo.log?
上面我們提到mysql的服務(wù)層劃分:
第一步:連接器:負(fù)責(zé)管理鏈接,用戶賬戶權(quán)限驗(yàn)證? ?
第二步:查詢緩存:查詢緩存,命中直接返回?
連接建立完成后,你就可以執(zhí)行sql查詢語句了,執(zhí)行邏輯就會來到第二步:查詢緩存。
MySQL 拿到一個查詢請求后,會先到查詢緩存看看,之前是不是執(zhí)行過這條語句。?
如果查詢命中緩存,MySQL 不需要執(zhí)行后面的復(fù)雜操作,就可以直接返回結(jié)果,這個效率會很高。
但是:不建議使用查詢緩存,原因如下:
因?yàn)椴樵兙彺嫱状笥诶?。查詢緩存的失效非常頻繁,只要有對一個表的更新,這個表上所有的查詢緩存都會被清空。
對于你確定要使用查詢緩存的語句,可以用 SQL_CACHE 顯式指定,像下面這個語句一樣:
mysql> select SQL_CACHE * from T where ID=10;
同時:需要注意的是,MySQL 8.0 版本直接將查詢緩存的整塊功能刪掉了,也就是說 8.0 開始徹底沒有這個功能了。
查詢緩存如何設(shè)置:
have_query_cache 表示當(dāng)前mysql版本是否支持查詢緩存。
query_cache_type 0 時表示關(guān)閉,1時表示打開,2表示只要select 中明確指定SQL_CACHE才緩存。?
query_cache_limit 表示單個結(jié)果集所被允許緩存的最大值。?
query_cache_min_res_unit 每個被緩存的結(jié)果集要占用的最小內(nèi)存。?
query_cache_size 用于查詢緩存的內(nèi)存大小。
qcache_free_memory 查詢緩存目前剩余空間大小。
qcache_hits 查詢緩存的命中次數(shù)。?
qcache_inserts 查詢緩存插入的次數(shù)。
第三步:分析器:詞法分析 語法分析
如果沒有命中查詢緩存,就要開始真正執(zhí)行語句了。首先,MySQL 需要知道你要做什么,因此需要對 SQL 語句做解析,生成"解析樹"。
預(yù)處理器根據(jù)一些MySQL規(guī)則進(jìn)一步檢查“解析樹”是否合法;
分析器先會做“詞法分析”。你輸入的是由多個字符串和空格組成的一條 SQL 語句,MySQL 需要識別出里面的字符串分別是什么,代表什么。
做完了這些識別以后,就要做“語法分析”。根據(jù)詞法分析的結(jié)果,語法分析器會根據(jù)語法規(guī)則,判斷你輸入的這個sql語句是否滿足 MySQL 語法。
?
第四步:執(zhí)行優(yōu)化器
經(jīng)過了分析器,MySQL 就知道你要做什么了。在開始執(zhí)行之前,還要先經(jīng)過優(yōu)化器的處理。
優(yōu)化器是 決定使用哪個索引; 決定各個表的連接順序。?
原則是:盡可能掃描少的數(shù)據(jù)庫行紀(jì)錄
第五步:執(zhí)行器: 操作存儲引擎,獲取結(jié)果并返回
MySQL 通過分析器知道了你要做什么,通過優(yōu)化器知道了該怎么做,于是就進(jìn)入了執(zhí)行器階段,開始執(zhí)行語句。
開始執(zhí)行的時候,先檢驗(yàn)權(quán)限
如果操作表的權(quán)限,就打開表繼續(xù)執(zhí)行。打開表的時候,執(zhí)行器就會根據(jù)表的存儲引擎,去使用這個引擎提供的接口。
?
2.日志系統(tǒng):一條SQL更新語句是如何執(zhí)行的??
關(guān)鍵詞: WAL write ahead logging 先寫日志、 undolog redolog 、 binlog、 兩階段提交? innodb存儲引擎
如果要將 ID=2 這一行的值加 1,SQL 語句就會這么寫:
mysql> update T set c=c+1 where ID=2;
該過程是如何執(zhí)行的呢?
首先,可以確定的說,查詢語句的那一套流程,更新語句也是同樣會走一遍。
1.你執(zhí)行語句前要先連接數(shù)據(jù)庫,這是連接器的工作。
2.前面我們說過,在一個表上有更新的時候,跟這個表有關(guān)的查詢緩存會失效,所以這條語句就會把表 T 上所有緩存結(jié)果都清空。這也就是我們一般不建議使用查詢緩存的原因。
3.接下來,分析器會通過詞法解析和語法解析知道這是一條更新語句。
4.優(yōu)化器決定要使用 ID 這個索引。
5.然后,執(zhí)行器負(fù)責(zé)具體執(zhí)行,找到這一行,然后更新。
更新流程還涉及兩個重要的日志模塊:redo log(重做日志)和 binlog(歸檔日志)
客戶端執(zhí)行DDL語句(create)/ DML語句(insert,update,delete)/DCL語句(grant,revoke),數(shù)據(jù)庫服務(wù)端執(zhí)行的時候會涉及到 undolog(撤銷日志) redolog(重做日志) 和 binlog (歸檔日志)
show engines:查看當(dāng)前數(shù)據(jù)庫支持的引擎信息,在5.5版本之前默認(rèn)采用MyISAM存儲引擎,從5.5開始采用InnoDB存儲引
常見存儲引擎有:
InnoDB:支持事務(wù),具有提交,回滾和崩潰恢復(fù)能力,事務(wù)安全
MyISAM:不支持事務(wù)和外鍵,訪問速度快
Memory:利用內(nèi)存創(chuàng)建表,訪問速度非???,因?yàn)閿?shù)據(jù)在內(nèi)存,而且默認(rèn)使用Hash索引,但是一旦關(guān)閉,數(shù)據(jù)就會丟失
了解 redolog(重做日志) 和 binlog (歸檔日志) 之前我們先詳細(xì)學(xué)習(xí)下Innodb存儲引擎的架構(gòu)模型
? 分析下 Innodb 存儲引擎:
Innodb存儲引擎: 它支持外鍵,擅長處理事務(wù),具有自動崩潰恢復(fù)的特性;
InnoDB引擎架構(gòu)圖:主要分為內(nèi)存結(jié)構(gòu)和磁盤結(jié)構(gòu)兩大部分
內(nèi)存結(jié)構(gòu):
內(nèi)存結(jié)構(gòu)主要包括Buffer Pool、Change Buffer、Adaptive Hash Index和Log Buffer四大組件
Buffer Pool:緩沖池,以緩存頁page作為基本單位,大小默認(rèn)為16k, 緩存頁之間通過鏈表進(jìn)行鏈接
作用:在InnoDB訪問表記錄和索引時會在Page頁中緩存,以后使用可以減少磁盤IO操作,提升效率
page頁的類型分為三種:
free page :空閑page,未被使用
clean page:被使用page,數(shù)據(jù)沒有被修改過
dirty page:臟頁,被使用page,數(shù)據(jù)被修改過,頁中數(shù)據(jù)和磁盤的數(shù)據(jù)產(chǎn)生了不一致
page頁通過三種鏈表來進(jìn)行維護(hù)
free list :表示空閑緩沖區(qū),管理free page
flush list:表示需要刷新到磁盤的緩沖區(qū),管理dirty page,內(nèi)部page按修改時間排序。臟頁即存在于flush鏈表,也在LRU鏈表中,但是兩種互不影響,LRU鏈表負(fù)責(zé)管理page的可用性和釋放,而flush鏈表負(fù)責(zé)管理臟頁的刷盤操作。
lru list? :表示正在使用的緩沖區(qū),管理clean page和dirty page,緩沖區(qū)以midpoint為基點(diǎn),前面鏈表稱為new列表區(qū),存放經(jīng)常訪問的數(shù)據(jù),占63%;后面的鏈表稱為old列表區(qū),存放使用較少數(shù)據(jù),占37%。
Change Buffer:
寫緩存區(qū):在進(jìn)行DML操作時,如果緩存池中沒有其相應(yīng)的Page數(shù)據(jù),并不會立刻將磁盤頁加載到緩沖池,而是在寫緩沖區(qū)記錄緩沖變更,等未來數(shù)據(jù)被讀取時,再將數(shù)據(jù)合并恢復(fù)到BP中。
當(dāng)更新一條記錄時,該記錄在BufferPool存在,直接在BufferPool修改,一次內(nèi)存操作。
如果該記錄在BufferPool不存在(沒有命中),會直接在ChangeBuffer進(jìn)行一次內(nèi)存操作,不用再去磁盤查詢數(shù)據(jù),避免一次磁盤IO。
當(dāng)下次查詢記錄時,會先進(jìn)性磁盤讀取,然后再從ChangeBuffer中讀取信息合并,最終載入BufferPool中。
?
Adaptive Hash Index:自適應(yīng)哈希索引,用于優(yōu)化對BP數(shù)據(jù)的查詢
InnoDB存儲引擎會自動根據(jù)訪問的頻率和模式來為某些頁建立哈希索引。
Log Buffer: 日志緩沖區(qū),用來保存要寫入磁盤上log文件(Redo/Undo)的數(shù)據(jù)
? ? ?LogBuffer主要是用于記錄InnoDB引擎日志,在DML操作時會產(chǎn)生Redo和Undo日志
磁盤結(jié)構(gòu):
表空間:存放表結(jié)構(gòu)和數(shù)據(jù)(InnoDB使用聚集索引(聚簇索引),索引和記錄在一起存儲,既緩存索引,也緩存記錄。)
數(shù)組字典:InnoDB數(shù)據(jù)字典由內(nèi)部系統(tǒng)表組成,這些表包含用于查找表、索引和表字段等對象的元數(shù)據(jù)
redo日志:用于在崩潰恢復(fù)期間更正不完整事務(wù)寫入的數(shù)據(jù)。MySQL以循環(huán)方式寫入重做日志文件,記錄InnoDB中所有對Buffer Pool修改的日志。
undo日志:撤消日志是在事務(wù)開始之前保存的被修改數(shù)據(jù)的備份,用于例外情況時回滾事務(wù)
3.詳細(xì)解析日志文件 undo.log redo.log binlog作用和功能?
undo.log撤銷日志:
Undo Log:數(shù)據(jù)庫事務(wù)開始之前,會將要修改的記錄存放到 Undo 日志里,當(dāng)事務(wù)回滾時或者數(shù)據(jù)庫崩潰時,可以利用 Undo 日志,撤銷未提交事務(wù)對數(shù)據(jù)庫產(chǎn)生的影響
Undo Log產(chǎn)生和銷毀:
Undo Log在事務(wù)開始前產(chǎn)生;
事務(wù)在提交時,并不會立刻刪除undolog,innodb會將該事務(wù)對應(yīng)的undo log放入到刪除列表中,后面會通過后臺線程purge thread進(jìn)行回收處理。
Undo Log屬于邏輯日志,記錄一個變化過程。例如執(zhí)行一個delete,undolog會記錄一個insert;執(zhí)行一個update,undolog會記錄一個相反的update。
Undo Log存儲:undo log采用段的方式管理和記錄。在innodb數(shù)據(jù)文件中包含一種rollback segment回滾段,內(nèi)部包含1024個undo log segment。
Undo Log作用:
實(shí)現(xiàn)事務(wù)原子性:事務(wù)處理過程中,如果出現(xiàn)了錯誤或者用戶執(zhí)行了 ROLLBACK 語句,MySQL 可以利用 Undo Log 中的備份將數(shù)據(jù)恢復(fù)到事務(wù)開始之前的狀態(tài)
實(shí)現(xiàn)MVCC多版本控制:事務(wù)未提交之前,Undo Log保存了未提交之前的版本數(shù)據(jù),Undo Log 中的數(shù)據(jù)可作為數(shù)據(jù)舊版本快照供其他并發(fā)事務(wù)進(jìn)行快照讀
redo.log重做日志:
redo.log:以恢復(fù)操作為目的,在數(shù)據(jù)庫發(fā)生意外時重現(xiàn)操作。防止在發(fā)生故障的時間點(diǎn),尚有臟頁未寫入表的 IBD 文件中,在重啟 MySQL服務(wù)的時候,根據(jù)Redolog進(jìn)行重做,從而達(dá)到事務(wù)的未入磁盤數(shù)據(jù)進(jìn)行持久化這一特性。
? ? ?redo.Log 的生成和釋放:?
隨著事務(wù)操作的執(zhí)行,就會生成Redo Log,在事務(wù)提交時會將產(chǎn)生Redo Log寫入Log Buffer,并不是隨著事務(wù)的提交就立刻寫入磁盤文件。(兩階段提交)
等事務(wù)操作的臟頁寫入到磁盤之后,Redo Log 的使命也就完成了,Redo Log占用的空間就可以重用(被覆蓋寫入)。
redo.log的寫入機(jī)制:循環(huán)順序?qū)?/p>
屬于innodb,4個文件共4GB大小,環(huán)形,磁盤地址有序,負(fù)責(zé)事務(wù)。crash-safe能力。?
Mysql數(shù)據(jù)庫的寫前日志(Write Ahead Log, WAL)機(jī)制,也就是說,在實(shí)際將數(shù)據(jù)記錄表中之前,先把修改的數(shù)據(jù)記到日志文件中,以便故障時進(jìn)行恢復(fù)。
binlog歸檔日志:
屬于mysql server層,無大小限制,會無限創(chuàng)建binlog文件,負(fù)責(zé)歸檔恢復(fù)。
binlog是記錄所有數(shù)據(jù)庫表結(jié)構(gòu)變更以及表數(shù)據(jù)修改的二進(jìn)制日志,不會記錄SELECT和SHOW這類操作。
binlog日志是以事件形式(Log Event)記錄,還包含語句所執(zhí)行的消耗時間。
應(yīng)用場景:
主從復(fù)制:在主庫中開啟Binlog功能,這樣主庫就可以把Binlog傳遞給從庫,從庫拿到Binlog后實(shí)現(xiàn)數(shù)據(jù)恢復(fù)達(dá)到主從數(shù)據(jù)一致性。
數(shù)據(jù)恢復(fù):通過mysqlbinlog工具來恢復(fù)數(shù)據(jù)。
redo 和undo 兩種日志的相同和差異:
1redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 層實(shí)現(xiàn)的,所有引擎都可以使用。
2redo log 是物理日志,記錄的是“在某個數(shù)據(jù)頁上做了什么修改”;binlog 是邏輯日志,記錄的是這個語句的原始邏輯,比如“給 ID=2 這一行的 c 字段加 1 ”。
3redo log 是循環(huán)寫的,空間固定會用完;binlog 是可以追加寫入的。“追加寫”是指 binlog 文件寫到一定大小后會切換到下一個,并不會覆蓋以前的日志。
4.數(shù)據(jù)庫的兩階段提交:為了保證binlog和redolog兩個日志之間的一致性
兩階段提交過程:
1.server拿到數(shù)據(jù)對數(shù)據(jù)修改,把修改結(jié)果發(fā)給引擎。?
2.引擎記錄redo log狀態(tài)為 prepare,之后告訴server可以提交事務(wù)。?
3.server接到通知后記錄binlog,之后調(diào)引擎接口提交事務(wù)。?
4.引擎接到提交事務(wù)的通知,將redo log改為commit狀態(tài)。
引擎修改兩次redo log的狀態(tài)的操作叫兩階段提交。?
為什么日志需要“兩階段提交”。這里不妨用反證法來進(jìn)行解釋。? 崩潰恢復(fù)? 和? 數(shù)據(jù)主從同步
由于 redo log 和 binlog 是兩個獨(dú)立的邏輯,如果不用兩階段提交,要么就是先寫完 redo log 再寫 binlog,或者采用反過來的順序。我們看看這兩種方式會有什么問題
仍然用前面的 update 語句來做例子。假設(shè)當(dāng)前 ID=2 的行,字段 c 的值是 0,再假設(shè)執(zhí)行 update 語句過程中c=1 ,在寫完第一個日志后,第二個日志還沒有寫完期間發(fā)生了 crash,會出現(xiàn)什么情況呢?
第一種情況:先寫 redo log 后寫 binlog。假設(shè)在 redo log 寫完,binlog 還沒有寫完的時候,MySQL 進(jìn)程異常重啟。
? ?由于我們前面說過的,redo log 寫完之后,系統(tǒng)即使崩潰,仍然能夠把數(shù)據(jù)恢復(fù)回來,所以恢復(fù)后這一行 c 的值是 1。
? ? ? ? ? ?但是由于 binlog 沒寫完就 crash 了,這時候 binlog 里面就沒有記錄這個語句。因此,之后備份日志的時候,存起來的 binlog 里面就沒有這條語句。
? ? ? ? ? ?然后你會發(fā)現(xiàn),如果需要用這個 binlog 來恢復(fù)臨時庫的話,由于這個語句的 binlog 丟失,這個臨時庫就會少了這一次更新,恢復(fù)出來的這一行 c 的值就是 0,與原庫的值不同。
第二種情況:先寫 binlog 后寫 redo log。如果在 binlog 寫完之后 crash,由于 redo log 還沒寫,崩潰恢復(fù)以后這個事務(wù)無效,所以這一行 c 的值是 0。
? ?但是 binlog 里面已經(jīng)記錄了"把 c 從 0 改成 1"這個日志。所以,在之后用 binlog 來恢復(fù)的時候就多了一個事務(wù)出來,恢復(fù)出來的這一行 c 的值就是 1,與原庫的值不同。
可以看到,如果不使用“兩階段提交”,那么數(shù)據(jù)庫的狀態(tài)就有可能和用它的日志恢復(fù)出來的庫的狀態(tài)不一致。
5.詳解事務(wù)的ACID特性以及實(shí)現(xiàn)原理? 和 事務(wù)隔離級別 以及 多版本控制MVCC
事務(wù):簡單來說,事務(wù)就是要保證一組數(shù)據(jù)庫操作,要么全部成功,要么全部失敗。在 MySQL 中,事務(wù)支持是在引擎層實(shí)現(xiàn)的;
提到事務(wù),你肯定會想到 ACID,那它們是如何實(shí)現(xiàn)的呢?(只有Innodb存儲引擎支持事務(wù))
原子性(Atomicity): 事務(wù)是一個原子操作單元,其對數(shù)據(jù)的修改,要么全都執(zhí)行,要么全都不執(zhí)行。
事務(wù)的原子性是通過WAL(先寫日志再刷磁盤)實(shí)現(xiàn)。最終落地到 undo日志實(shí)現(xiàn)
隔離性(Isolation):指的是一個事務(wù)的執(zhí)行不能被其他事務(wù)干擾,即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對其他的并發(fā)事務(wù)是隔離的。
InnoDB 支持的隔離性有 4 種,隔離性從低到高分別為:讀未提交、讀已提交、可重復(fù)讀、串行化。?
底層是通過對 鎖 和 多版本控制(MVCC)技術(shù)的封裝,從而實(shí)現(xiàn)不通的隔離級別
持久性:指的是一個事務(wù)一旦提交,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就應(yīng)該是永久性的,后續(xù)的操作或故障不應(yīng)該對其有任何影響,不會丟失。
redo log在系統(tǒng)宕機(jī)重啟之類的情況時,可以修復(fù)數(shù)據(jù),從而保障事務(wù)的持久性。
MySQL的持久性也與WAL技術(shù)相關(guān),redo log在系統(tǒng)Crash重啟之類的情況時,可以修復(fù)數(shù)據(jù),從而保障事務(wù)的持久性。
通過原子性可以保證邏輯上的持久性,通過存儲引擎的數(shù)據(jù)刷盤可以保證物理上的持久性。
一致性(Consistency): 指的是事務(wù)開始之前和事務(wù)結(jié)束之后,數(shù)據(jù)庫的完整性限制未被破壞。一致性包括兩方面的內(nèi)容,分別是約束一致性和數(shù)據(jù)一致性。
一致性也可以理解為數(shù)據(jù)的完整性。數(shù)據(jù)的完整性是通過原子性、隔離性、持久性來保證的,而這3個特性又是通過 Redo/Undo 來保證的
?
6.如果沒有事務(wù)隔離會產(chǎn)生什么問題?
當(dāng)數(shù)據(jù)庫上有多個事務(wù)同時操作同一條記錄的時候,就可能出現(xiàn)臟讀(dirty read)、不可重復(fù)讀(non-repeatable read)、幻讀(phantom read)的問題
更新丟失
當(dāng)兩個或多個事務(wù)選擇同一行,然后基于最初選定的值更新該行時,由于每個事務(wù)都不知道其他事務(wù)的存在,就會發(fā)生丟失更新問題:最后的更新覆蓋了由其他事務(wù)所做的更新。
當(dāng)兩個或多個事務(wù)更新同一行記錄,會產(chǎn)生更新丟失現(xiàn)象??梢苑譃榛貪L覆蓋和提交覆蓋。
回滾覆蓋:一個事務(wù)回滾操作,把其他事務(wù)已提交的數(shù)據(jù)給覆蓋了。
提交覆蓋:一個事務(wù)提交操作,把其他事務(wù)已提交的數(shù)據(jù)給覆蓋了。
臟讀: 讀到其他事務(wù)未提交的數(shù)據(jù); ? (一個事務(wù)讀取了其它事務(wù)update后未提交的數(shù)據(jù),注意是針對其它事務(wù)的修改未提交的操作 )
不可重復(fù)讀: 前后讀取的同一條記錄內(nèi)容不一致; (一個事務(wù)讀取了其它事務(wù)update或delete后已提交的數(shù)據(jù),注意是針對其它事務(wù)修改或刪除已提交的操作 )
幻讀: 前后讀取的記錄數(shù)量不一致。 ? (一個事務(wù)讀取了其它事務(wù)新insert已經(jīng)提交的數(shù)據(jù)。注意是針對其它事務(wù)新增已提交的數(shù)據(jù))
7.mysql的隔離級別有哪些? 隔離級別是如何實(shí)現(xiàn)的?隔離級別如何設(shè)置?
在談隔離級別之前,你首先要知道,隔離得越嚴(yán)實(shí),數(shù)據(jù)庫執(zhí)行效率就會越低。因此很多時候,我們都要在二者之間尋找一個平衡點(diǎn)。
SQL標(biāo)準(zhǔn)的事務(wù)隔離級別包括:
讀未提交 : 一個事務(wù)還沒提交時,它做的變更就能被別的事務(wù)看到。(別人改數(shù)據(jù)的事務(wù)尚未提交,我在我的事務(wù)中也能讀到)
讀已提交 : 一個事務(wù)提交之后,它做的變更才會被其他事務(wù)看到。? (別人改數(shù)據(jù)的事務(wù)已經(jīng)提交,我在我的事務(wù)中才能讀到)
可重復(fù)讀**: 一個事務(wù)執(zhí)行過程中看到的數(shù)據(jù),總是跟這個事務(wù)在啟動時看到的數(shù)據(jù)是一致的。(別人改數(shù)據(jù)的事務(wù)已經(jīng)提交了,但該事務(wù)比我的事務(wù)開始的晚,我在我的事務(wù)中也不去讀)
串行化: 顧名思義是對于同一行記錄,當(dāng)出現(xiàn)讀寫鎖沖突的時候,后訪問的事務(wù)必須等前一個事務(wù)執(zhí)行完成,才能繼續(xù)執(zhí)行;(我的事務(wù)尚未提交,別人就別想改數(shù)據(jù))
數(shù)據(jù)庫對四種隔離級別的實(shí)現(xiàn),是依靠視圖來實(shí)現(xiàn)的:
1、讀未提交:沒有視圖的概念,直接返回記錄的最新值;?
2、讀已提交:每次執(zhí)行sql語句之前創(chuàng)建視圖;?
3、可重復(fù)讀:每次創(chuàng)建事務(wù)的時候創(chuàng)建視圖;?
4、串行化:通過加鎖來避免并行訪問
事務(wù)設(shè)置隔離級別的相關(guān)命令:
mysql>? show variables like 'transaction_isolation';查看事務(wù)隔離級別
set tx_isolation='各個隔離級別';// 設(shè)置事務(wù)隔離級別
8.什么是索引?以及索引的作用?常用的索引有哪些類型?
索引一種數(shù)據(jù)結(jié)構(gòu),通常采用B+樹實(shí)現(xiàn);為了提升查詢速率;類似于新華字典中的字典目錄,索引是存儲在文件中的,因此需要占據(jù)物理空間。因此并不是索引越多越好
索引可以分為以下幾種:
從應(yīng)用層次劃分:普通索引:沒有任何限制、? 唯一索引:唯一可為空、 主鍵索引:唯一且非空、 復(fù)合索引:遵循最左前綴原則
從數(shù)據(jù)存儲和索引鍵值邏輯關(guān)系劃分:非聚集索引(非聚簇索引,數(shù)據(jù)和索引分開存放 ,比如mysame)、聚集索引(聚簇索引 比如 innodb引擎將數(shù)據(jù)和索引存儲在一個表中)
從索引鍵值類型劃分:主鍵索引、輔助索引(二級索引)
從索引存儲數(shù)據(jù)結(jié)構(gòu)劃分:B+樹索引、Hash索引、FULLTEXT全文索引等
9.索引采用了哪些數(shù)據(jù)結(jié)構(gòu)?常用的有三種:哈希表? 有序數(shù)組? ?B+樹?
哈希表:
哈希表是一種鍵值存儲數(shù)據(jù)的結(jié)構(gòu),我們只要輸入待查找的鍵即 key,就可以找到其對應(yīng)的值即 Value。
如果產(chǎn)生哈希沖突,使用拉鏈法接入,在節(jié)點(diǎn)下面掛一個數(shù)組或鏈表
查找一個元素的過程:
處理步驟就是:首先,將 key值 通過哈希函數(shù)算出 N;如果存在鏈表,按順序遍歷,找到目標(biāo)記錄。
哈希表只適用于等值查詢,其區(qū)間查詢效率很低;
該種數(shù)據(jù)結(jié)構(gòu)主要應(yīng)用在 Memory 存儲引擎 和 innodb存儲引擎的自適應(yīng)hash索引中
有序數(shù)組:
基于排序的數(shù)組實(shí)現(xiàn);
有序數(shù)組能夠解決hash函數(shù)不能滿足支持快速范圍查詢。查找速度為log(n),但缺陷也很明顯,針對插入和刪除場景,需要挪動后面的整個記錄,代價太高。
可以結(jié)合二分法就可以快速得到某個等值查詢,這個時間復(fù)雜度是 O(log(N))。
有序數(shù)組適用于靜態(tài)搜索引擎。
B+樹(為什么非要采用B+樹)
為什么數(shù)據(jù)庫存儲使用b+樹 而不是二叉樹,因?yàn)槎鏄錁涓哌^高,每次查詢都需要訪問過多節(jié)點(diǎn),即訪問數(shù)據(jù)塊過多,而從磁盤隨機(jī)讀取數(shù)據(jù)塊過于耗時。
MySQL的存儲結(jié)構(gòu)
表存儲結(jié)構(gòu)
單位:表>段>區(qū)>頁>行
在數(shù)據(jù)庫中, 不論讀一行,還是讀多行,都是將這些行所在的頁進(jìn)行加載。也就是說存儲空間的基本單位是頁。
一個頁就是一棵樹B+樹的節(jié)點(diǎn),數(shù)據(jù)庫I/O操作的最小單位是頁,與數(shù)據(jù)庫相關(guān)的內(nèi)容都會存儲在頁的結(jié)構(gòu)里
10.數(shù)據(jù)庫三大范式
第一范式:每一列都是不可以再才拆分的
第二范式:基于第一范式,非主鍵字段完全依賴主鍵字段,而不是依賴于主鍵字段的一部分
第三范式:在第二范式的基礎(chǔ)上,非主鍵列只依賴于主鍵,不依賴于其他非主鍵。
在設(shè)計數(shù)據(jù)庫結(jié)構(gòu)的時候,要盡量遵守三范式,如果不遵守,必須有足夠的理由。比如性能。事實(shí)上我們經(jīng)常會為了性能而妥協(xié)數(shù)據(jù)庫的設(shè)計
11.binlog的應(yīng)用場景? Binlog 日志文件的錄入方式,錄入方式優(yōu)缺點(diǎn)對比?
Binlog是記錄所有數(shù)據(jù)庫表結(jié)構(gòu)變更以及表數(shù)據(jù)修改的二進(jìn)制日志,不會記錄SELECT和SHOW這類操作。
Binlog日志是以事件形式(Log Event)記錄,還包含語句所執(zhí)行的消耗時間。開啟Binlog日志有以下兩個最重要的使用場景。
主從復(fù)制:在主庫中開啟Binlog功能,這樣主庫就可以把Binlog傳遞給從庫,從庫拿到Binlog后實(shí)現(xiàn)數(shù)據(jù)恢復(fù)達(dá)到主從數(shù)據(jù)一致性。
數(shù)據(jù)恢復(fù):通過mysqlbinlog工具來恢復(fù)數(shù)據(jù)。
binlog的日志文件錄入方式有三種: row statment? mixed?
ROW(row-based replication, RBR):日志中會記錄每一行數(shù)據(jù)被修改的情況,? 修改記錄復(fù)制
優(yōu)點(diǎn):能清楚記錄每一個行數(shù)據(jù)的修改細(xì)節(jié),能完全實(shí)現(xiàn)主從數(shù)據(jù)同步和數(shù)據(jù)的恢復(fù)。
缺點(diǎn):批量操作,會產(chǎn)生大量的日志,或者修改表結(jié)構(gòu),尤其是alter table會讓日志暴漲。
STATMENT(statement-based replication, SBR):記錄每一條修改數(shù)據(jù)的SQL語句到master的Binlog中,簡稱SQL語句復(fù)制。
優(yōu)點(diǎn):日志量小,減少磁盤IO,提升存儲和恢復(fù)速度
缺點(diǎn):在某些情況下會導(dǎo)致主從數(shù)據(jù)不一致,比如last_insert_id()、now()等函數(shù)。 無法記錄數(shù)據(jù)庫函數(shù)
MIXED(mixed-based replication, MBR):以上兩種模式的混合使用,一般會使用STATEMENT模式保存binlog,對于STATEMENT模式無法復(fù)制的操作使用ROW模式保存binlog,MySQL會根據(jù)執(zhí)行的SQL語句選擇寫入模式。
12.分析下mysql的存儲引擎有哪些?優(yōu)缺點(diǎn)?以及Innodb和mysiam的區(qū)別?存儲引擎選擇?
通過 show engines 可以查看當(dāng)前數(shù)據(jù)庫所支持的引擎信息;主要應(yīng)用的是 innodb myisam , 在mysql版本5.5默認(rèn)采用myisam存儲引擎,5.6.版本之后采用innodb存儲引擎
innodb 和 myisam 的區(qū)別
鎖機(jī)制
InnoDB默認(rèn)支持行級鎖,鎖定指定記錄?;谒饕齺砑渔i實(shí)現(xiàn)。
MyISAM默認(rèn)支持表級鎖,鎖定整張表。
索引結(jié)構(gòu)
InnoDB使用聚集索引(聚簇索引),索引和記錄在一起存儲,既緩存索引,也緩存記錄。
MyISAM使用非聚集索引(非聚簇索引),索引和記錄分開。
并發(fā)處理能力
MyISAM使用表鎖,會導(dǎo)致寫操作并發(fā)率低,讀之間并不阻塞,讀寫阻塞。
InnoDB讀寫阻塞可以與隔離級別有關(guān),可以采用多版本并發(fā)控制(MVCC)來支持高并發(fā)
存儲文件
InnoDB表對應(yīng)兩個文件,一個.frm表結(jié)構(gòu)文件,一個.ibd數(shù)據(jù)文件。InnoDB表最大支持64TB;
MyISAM表對應(yīng)三個文件,一個.frm表結(jié)構(gòu)文件,一個MYD表數(shù)據(jù)文件,一個.MYI索引文件。從MySQL5.0開始默認(rèn)限制是256TB。
如何選擇存儲引擎:
如果沒有特別的需求,使用默認(rèn)的Innodb即可。
MyISAM:以讀寫插入為主的應(yīng)用程序,比如博客系統(tǒng)、新聞門戶網(wǎng)站。
Innodb:更新(刪除)操作頻率也高,或者要保證數(shù)據(jù)的完整性;并發(fā)量高,支持事務(wù)和外鍵。比如OA自動化辦公系統(tǒng)。
13.詳解索引為什么是B+tree數(shù)據(jù)結(jié)構(gòu),而不采用B tree
B+樹索引:首先B+樹具備以下特性:
1.非葉子節(jié)點(diǎn)不存儲data數(shù)據(jù),只存儲索引值,這樣便于存儲更多的索引值
2.葉子節(jié)點(diǎn)包含了所有的索引值和data數(shù)據(jù),也就是說 一顆樹就是帶有索引的完整表記錄
3.葉子節(jié)點(diǎn)用指針連接,提高區(qū)間的訪問性能
相比B樹,B+樹進(jìn)行范圍查找時,只需要查找定位兩個節(jié)點(diǎn)的索引值,然后利用葉子節(jié)點(diǎn)的指針進(jìn)行遍歷即可。而B樹需要遍歷范圍內(nèi)所有的節(jié)點(diǎn)和數(shù)據(jù),顯然B+Tree效率高。
14.什么情況下會導(dǎo)致索引失效? 查詢范圍不明確導(dǎo)致索引失效
1. 使用like 左邊包含 %
2. 不滿足最左前綴原則
3. 在索引列上進(jìn)行計算或者使用函數(shù)
4. 使用了select * ,會導(dǎo)致全表查詢
5. 查詢時字段類型不同,如? 某個表中的code 字段 varchar類型 添加了索引? 查詢時 code='101'可以命中索引,但是code=101就會導(dǎo)致全表掃描status
6. 錯誤的使用 or關(guān)鍵字,注意:如果使用了or關(guān)鍵字,那么它前面和后面的字段都要加索引,不然所有的索引都會失效,例如:where id=1 or service_code ='test02' or? status =1; 前兩個字段有索引,但是status沒有索引
7. 使用 order by 關(guān)鍵字容易導(dǎo)致索引失效
如果order by語句中沒有加where或limit關(guān)鍵字,該sql語句將不會走索引。
對不同的索引做order by
聯(lián)合索引不滿足最左匹配原則
如果order by后面有一個聯(lián)合索引的多個字段,它們具有不同的排序規(guī)則也會導(dǎo)致索引失效
8. 使用表中的列進(jìn)行對比
9. 錯誤的使用 not in 或者 not exists
15.索引分析和優(yōu)化?如何對數(shù)據(jù)庫sql語句進(jìn)行索引分析與優(yōu)化?explain 命令是如何執(zhí)行的?
我們可以通過explian命令來查詢sql語句的執(zhí)行情況,例如 explian select 語句
explian命令有一些關(guān)鍵信息 如 select_type? type? possiable_key key? rows? extra?
詳細(xì)解析
select_type 表示sql語句查詢類型: 例如,SIMPLE : 表示查詢語句不包含子查詢或union;SUBQUERY:SELECT子查詢語句
type: 表示存儲引擎查詢數(shù)據(jù)時采用的方式,通過它可以判斷出查詢是全表掃描還是基于索引的部分掃描。
all: 全表查詢
index:表示基于索引的全表掃描,先掃描索引再掃描全表數(shù)據(jù)。
range:表示使用索引范圍查詢。使用>、>=、<、<=、in等等。
ref:表示使用非唯一索引進(jìn)行單值查詢。
eq_ref:一般情況下出現(xiàn)在多表join查詢,表示前面表的每一個記錄,都只能匹配后面表的一行結(jié)果。
const:表示使用主鍵或唯一索引做等值查詢,常量查詢。
NULL:表示不用訪問表,速度最快。
possible_key:可能會使用到的索引
key:命中的索引,使用的索引
rows:估算SQL要查詢到結(jié)果需要掃描多少行記錄。這個值越小越好
extra:查詢時的擴(kuò)展信息
Using where :表示查詢需要通過索引回表查詢數(shù)據(jù)。
Using index:表示查詢需要通過索引,索引就可以滿足所需數(shù)據(jù)。
Using filesort:表示查詢出來的結(jié)果需要額外排序,數(shù)據(jù)量小在內(nèi)存,大的話在磁盤,因此有Using filesort建議優(yōu)化。
Using temprorary:查詢使用到了臨時表,一般出現(xiàn)于去重、分組等操作。
16.什么是回表查詢(重點(diǎn))?
回表查詢:InnoDB索引有聚簇索引和輔助索引。聚簇索引的葉子節(jié)點(diǎn)存儲行記錄,InnoDB必須要有,且只有一個。
輔助索引的葉子節(jié)點(diǎn)存儲的是主鍵值和索引字段值,通過輔助索引無法直接定位行記錄,通常情況下,需要掃碼兩遍索引樹。
先通過輔助索引定位主鍵值,然后再通過聚簇索引定位行記錄,這就叫做回表查詢,它的性能比掃一遍索引樹低。
總結(jié):通過索引查詢主鍵值,然后再去聚簇索引查詢記錄信息
17.Mysql慢查詢實(shí)戰(zhàn)+SQL優(yōu)化,慢查詢?nèi)罩痉治??如何查看慢查詢?nèi)罩??如何?yōu)化慢查詢?nèi)罩?/p>
注意點(diǎn):切記在生產(chǎn)環(huán)境上開啟慢查詢,會影響數(shù)據(jù)庫性能 variables slow_query_log
1.首先查看慢查詢是否開啟: SHOW VARIABLES LIKE 'slow_query_log%'
2.開啟慢查詢并設(shè)置慢查詢: 如果為OFF,則通過命令 SET global slow_query_log = ON 開啟 并設(shè)置 long_query_time = 10 指定慢查詢的閾值
3.查看慢查詢sql文件:MySQL 提供了一個慢查詢?nèi)罩痉治龉ぞ適ysqldumpslow,可以通過該工具分析慢查詢?nèi)罩緝?nèi)容,主要看執(zhí)行時長,鎖表時間和sql語句等關(guān)鍵字段
4.通過explian命令分析慢查詢sql
5.進(jìn)行sql語句優(yōu)化,并監(jiān)控性能
?
18.事務(wù)并發(fā)控制的實(shí)現(xiàn)方案有哪些? 說下 MVCC 以及 mysql的鎖機(jī)制? ? ****
事務(wù)并發(fā)會導(dǎo)致更新丟失,臟讀,不可重復(fù)讀,幻讀問題,為了避免上述問題,我們可以通過以下方案解決:
1.通過排隊(duì)的方法:就是完全順序執(zhí)行所有事務(wù)的數(shù)據(jù)庫操作,不需要加鎖,簡單的說就是全局排隊(duì);
2.排他鎖:如果事務(wù)之間涉及到相同的數(shù)據(jù)項(xiàng)時,會使用排他鎖,先進(jìn)入的事務(wù)獨(dú)占數(shù)據(jù)項(xiàng)以后,其他事務(wù)被阻塞,等待前面的事務(wù)釋放鎖。
3.讀寫鎖:讀寫鎖區(qū)分讀操作和寫操作,讓讀和讀之間不加鎖,但是讀寫或?qū)懽x或?qū)憣懶枰渔i
4.通過MVCC機(jī)制實(shí)現(xiàn)讀讀,讀寫,寫讀不加鎖,通過讀取副本(實(shí)現(xiàn)讀寫不加鎖操作),但是寫寫仍然需要加鎖;
所謂的MVCC是什么呢?多版本控制,基于 Copy on Write機(jī)制實(shí)現(xiàn)(先寫日志再刷入磁盤)
在事務(wù)A開始寫操作的時候會copy一個記錄的副本(記錄在undo.log日志中),其他事務(wù)B讀操作會讀取這個記錄副本,因此不會影響其他事務(wù)對此記錄的讀取,實(shí)現(xiàn)寫和讀并行。
MVCC實(shí)現(xiàn)原理:
MVCC的實(shí)現(xiàn)原理主要依賴于記錄中的三個隱藏字段,undolog, read view來實(shí)現(xiàn)的。
在 MVCC 并發(fā)控制中,讀操作可以分為兩類: 快照讀(Snapshot Read)與當(dāng)前讀 (Current Read)。
快照讀:讀取的是記錄的快照版本(有可能是歷史版本),不用加鎖。(select)
當(dāng)前讀:讀取的是記錄的最新版本,并且當(dāng)前讀返回的記錄,都會加鎖,保證其他事務(wù)不會再并發(fā)修改這條記錄。(select... for update 或lock in share mode,insert/delete/update)
每個事務(wù)都會包含三個隱藏字段:隱含ID、事務(wù)號Tid和回滾指針Roll_PT,每次寫更新都會在事務(wù)ID上增加1
19.鎖可以有哪些分類?鎖機(jī)制是如何實(shí)現(xiàn)得?樂觀鎖,悲觀鎖是如何實(shí)現(xiàn)的?
在 MySQL中鎖有很多不同的分類。根據(jù)不通的劃分規(guī)則:
根據(jù)鎖的粒度可分為表級鎖、行級鎖和頁級鎖。
表級鎖:每次操作鎖住整張表。鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。應(yīng)用在MyISAM、InnoDB、BDB 等存儲引擎中。
行級鎖:每次操作鎖住一行數(shù)據(jù)。鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度最高。應(yīng)用在InnoDB 存儲引擎中。
頁級鎖:每次鎖定相鄰的一組記錄,鎖定粒度界于表鎖和行鎖之間,開銷和加鎖時間界于表鎖和行鎖之間,并發(fā)度一般。應(yīng)用在BDB 存儲引擎中。
根據(jù)鎖的操作行為分為讀鎖和寫鎖,從操作的類型可分為讀鎖和寫鎖。
讀鎖(S鎖):共享鎖,針對同一份數(shù)據(jù),多個讀操作可以同時進(jìn)行而不會互相影響。
寫鎖(X鎖):排他鎖,當(dāng)前寫操作沒有完成前,它會阻斷其他寫鎖和讀鎖。
根據(jù)鎖的的實(shí)現(xiàn)方式分為悲觀鎖和樂觀鎖從操作的性能可分為樂觀鎖和悲觀鎖。
樂觀鎖:一般的實(shí)現(xiàn)方式是對記錄數(shù)據(jù)版本進(jìn)行比對,在數(shù)據(jù)更新提交的時候才會進(jìn)行沖突檢測,如果發(fā)現(xiàn)沖突了,則提示錯誤信息。
悲觀鎖:在對一條數(shù)據(jù)修改的時候,為了避免同時被其他人修改,在修改數(shù)據(jù)之前先鎖定,再修改的控制方式。共享鎖和排他鎖是悲觀鎖的不同實(shí)現(xiàn),但都屬于悲觀范疇。
從廣義上來講,前面提到的行鎖、表鎖、讀鎖、寫鎖、共享鎖、排他鎖等,這些都屬于悲觀鎖范疇。
?
20.什么情況下會產(chǎn)生死鎖?如何避免死鎖? 如何解決死鎖?? https://blog.csdn.net/qq_34107571/article/details/78001309
死鎖的標(biāo)準(zhǔn)定義:是指兩個或兩個以上的進(jìn)程在執(zhí)行過程中,因爭奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進(jìn)下去。
死鎖產(chǎn)生必須要具備以下四個條件:
互斥條件:某資源在一段時間內(nèi)只由一個進(jìn)程占用
相互等待條件:指在發(fā)生死鎖時,必然存在一個進(jìn)程和資源的環(huán)形鏈,比如 A進(jìn)程正在等待一個B進(jìn)程占用的資源;B進(jìn)程又正在等待A進(jìn)程占用的資源
不可剝奪條件:指進(jìn)程已經(jīng)獲取的資源,在未使用完之前,只能由自身釋放
請求和保持:指進(jìn)程已經(jīng)保持至少一個資源,但又提出了新的資源請求,而該資源已被其它進(jìn)程占有,此時請求進(jìn)程阻塞,但又對自己已獲得的其它資源保持不放
以下幾種情況下會出現(xiàn)死鎖:
情況一:
如果在事務(wù)中執(zhí)行了一條沒有索引條件的查詢,引發(fā)全表掃描,把行級鎖上升為全表記錄鎖定(等價于表級鎖),多個這樣的事務(wù)執(zhí)行后,就很容易產(chǎn)生死鎖和阻塞
解決方案:
SQL語句中不要使用太復(fù)雜的關(guān)聯(lián)多表的查詢;
使用explain“執(zhí)行計劃"對SQL語句進(jìn)行分析,對于有全表掃描和全表鎖定的SQL語句,建立相應(yīng)的索引進(jìn)行優(yōu)化。
情況二:
兩個事務(wù)分別想拿到對方持有的鎖,互相等待,于是產(chǎn)生死鎖。
解決方案:
在同一個事務(wù)中,盡可能做到一次鎖定所需要的所有資源
按照id對資源排序,然后按順序進(jìn)行處理
四、 如何預(yù)防死鎖
如何避免死鎖?為此我們在開發(fā)的過程中需要遵循如下原則:
1.編寫應(yīng)用程序避免長事務(wù),讓進(jìn)程持有鎖的時間盡可能短
2.避免并發(fā)的執(zhí)行 修改數(shù)據(jù)的語句。
3.要求每一個事務(wù)一次就將所有要使用到的數(shù)據(jù)全部加鎖,否則就不允許執(zhí)行。
4.預(yù)先規(guī)定一個加鎖順序,所有的事務(wù)都必須按照這個順序?qū)?shù)據(jù)執(zhí)行封鎖。如不同的過程在事務(wù)內(nèi)部對對象的更新執(zhí)行順序應(yīng)盡量保證一致。
5.使用盡可能低的隔離級別。
6.數(shù)據(jù)存儲空間離散法。該方法是指采用各種手段,將邏輯上在一個表中的數(shù)據(jù)分散的若干離散的空間上去,以便改善對表的訪問性能。主要通過將大表按行或者列分解為若干小表,或者按照不同的用戶群兩種方法實(shí)現(xiàn)。
??
怎么查詢死鎖: https://www.cnblogs.com/jpfss/p/11491526.html
1、查詢進(jìn)程id,然后kill id? show processlist? ?kill id?
2、查詢是否鎖表 : show OPEN TABLES where In_use > 0;
3、在5.5中,information_schema 庫中增加了三個關(guān)于鎖的表(innoDB引擎):
innodb_trx? ? ? ? ?## 當(dāng)前運(yùn)行的所有事務(wù)
innodb_locks? ? ? ?## 當(dāng)前出現(xiàn)的鎖
innodb_lock_waits? ## 鎖等待的對應(yīng)關(guān)系
4、通過show engine innodb status\G命令查看近期死鎖日志信息。查看死鎖日志
21.Mysql 主從之間是怎么同步數(shù)據(jù)的? 主從復(fù)制的用途?如何解決主從復(fù)制延遲問題?
主從復(fù)制主要應(yīng)用于:
故障切換:用于故障切換(高可用)
數(shù)據(jù)備份:避免由于數(shù)據(jù)宕機(jī)影響業(yè)務(wù)(高可用)
讀寫分離:提供查詢服務(wù)(讀擴(kuò)展)
主從復(fù)制通過以下三個步驟完成數(shù)據(jù)同步:
1.主庫將數(shù)據(jù)庫的變更操作記錄到Binlog日志文件中
2.從庫讀取主庫中的Binlog日志文件信息寫入到從庫的Relay Log中繼日志中
3.從庫讀取中繼日志信息在從庫中進(jìn)行Replay,更新從庫數(shù)據(jù)信息
在上述三個過程中,涉及了Master的BinlogDump Thread和? ?Slave的I/O Thread、SQL Thread,它們的作用如下:
Master服務(wù)器對數(shù)據(jù)庫更改操作記錄在Binlog中,BinlogDump Thread接到寫入請求后,讀取Binlog信息推送給Slave的I/O Thread。
Slave的I/O Thread將讀取到的Binlog信息寫入到本地Relay Log中。
Slave的SQL Thread檢測到Relay Log的變更請求,解析relay log中內(nèi)容在從庫上執(zhí)行
22.mysql主從復(fù)制存在的問題,如何解決主從復(fù)制延遲問題?
mysql主從復(fù)制存在的問題:
主庫宕機(jī)后,數(shù)據(jù)可能丟失
從庫只有一個SQL Thread,主庫寫壓力大,復(fù)制很可能延時
解決方法:
半同步復(fù)制---解決數(shù)據(jù)丟失的問題
半同步復(fù)制: 為了提升數(shù)據(jù)安全,MySQL讓Master在某一個時間點(diǎn)等待Slave節(jié)點(diǎn)的 ACK(Acknowledgecharacter)消息,接收到ACK消息后才進(jìn)行事務(wù)提交。
并行復(fù)制----解決從庫復(fù)制延遲的問題
并行復(fù)制在從庫中有兩個線程IO Thread和SQL Thread,都是單線程模式工作,因此有了延遲問題,我們可以采用多線程機(jī)制來加強(qiáng),減少從庫復(fù)制延遲。(IO Thread多線程意義不大,主要指的是SQL Thread多線程)
在MySQL的5.6、5.7、8.0版本上,都是基于上述SQL Thread多線程思想,不斷優(yōu)化,減少復(fù)制延遲。
23.數(shù)據(jù)庫如何實(shí)現(xiàn)分庫分表?什么是分庫分表?分庫分表的策略是什么?
存在的問題:
業(yè)務(wù)越來越大,單表數(shù)據(jù)超出了數(shù)據(jù)庫支持的容量
Tps過大,十幾萬并發(fā)量,傳統(tǒng)的架構(gòu)(一主多從),主庫容量肯定無法滿足這么高的Tps
拆分的模式:水平拆分 垂直拆分 都屬于物理空間的拆分。
垂直拆分:由于表數(shù)量多導(dǎo)致的單個庫大。將表拆分到多個庫中。
水平拆分:由于表記錄多導(dǎo)致的單個庫大。將表記錄拆分到多個表中。
??
面試八股文: https://blog.csdn.net/o9109003234/article/details/121026489
?
Mysql的集群架構(gòu)
Mysql的集群方案有以下三種:? 主從架構(gòu)? 雙主架構(gòu)? 分庫分表
主從架構(gòu)(如何實(shí)現(xiàn),如何保證數(shù)據(jù)一致性)
主從模式:是指數(shù)據(jù)可以從一個主數(shù)據(jù)庫復(fù)制到一個或多個從節(jié)數(shù)據(jù)庫。MySQL 默認(rèn)采用異步復(fù)制方式
主從架構(gòu)的作用:
讀寫分離,提供查詢服務(wù)(讀擴(kuò)展)
數(shù)據(jù)備份,避免影響業(yè)務(wù)(高可用)
實(shí)時災(zāi)備,用于故障切換(高可用)
主從復(fù)制整體分為以下三個步驟:
1.主庫將數(shù)據(jù)庫的變更操作記錄到Binlog日志文件中
2.從庫讀取主庫中的Binlog日志文件信息寫入到從庫的 Relay Log中繼日志中
3.從庫讀取中繼日志信息在從庫中進(jìn)行Replay(數(shù)據(jù)恢復(fù)),更新從庫數(shù)據(jù)信息
在上述三個過程中,涉及了三個線程, Master的BinlogDump Thread和Slave的I/O Thread、SQL Thread,它們的作用如下:
BinlogDump Thread(binlog日志推送線程) : 當(dāng)Master服務(wù)器對數(shù)據(jù)庫更改操作記錄在Binlog中,該線程接到寫入請求后,讀取Binlog信息推送給Slave的I/O Thread。
I/O Thread(從庫IO線程): 該線程讀取到的Binlog信息寫入到本地Relay Log中。
SQL Thread(從庫sql線程): Slave的SQL Thread檢測到Relay Log的變更請求,解析relay log中內(nèi)容在從庫上執(zhí)行。
上述過程都是異步操作,俗稱異步復(fù)制,存在數(shù)據(jù)延遲現(xiàn)象。
主從復(fù)制存在的問題(也就是異步操作導(dǎo)致的問題):
主庫宕機(jī),可能導(dǎo)致數(shù)據(jù)丟失問題:
數(shù)據(jù)延遲問題:從庫只有一個SQL Thread,主庫寫壓力大,復(fù)制很可能延時
如何主從復(fù)制存在的上述問題:
半同步復(fù)制---解決數(shù)據(jù)丟失的問題
為了提升數(shù)據(jù)安全,MySQL可以讓Master在某一個時間點(diǎn)等待Slave節(jié)點(diǎn)的 ACK消息,接收到ACK消息后才進(jìn)行事務(wù)提交,這也是半同步復(fù)制的基礎(chǔ),
MySQL從5.5版本開始引入了半同步復(fù)制機(jī)制來降低數(shù)據(jù)丟失的概率。
介紹半同步復(fù)制之前先快速過一下 MySQL 事務(wù)寫入碰到主從復(fù)制時的完整過程,主庫事務(wù)寫入分為 4個步驟:
InnoDB Redo File Write (Prepare Write)? 兩階段提交中的prepare階段
Binlog File Flush & Sync to Binlog File 兩階段提交中的寫入binlog階段
InnoDB Redo File Commit(Commit Write) 兩階段提交中的寫入commit階段
Send Binlog to Slave: 主庫通過binlogDump thread 推送binlog日志到從庫
當(dāng)Master不需要關(guān)注Slave是否接受到Binlog Event時,即為傳統(tǒng)的主從復(fù)制。
當(dāng)Master需要在第三步等待Slave返回ACK時,即為 after-commit,半同步復(fù)制(MySQL 5.5引入)。
當(dāng)Master需要在第二步等待 Slave 返回 ACK 時,即為 after-sync,增強(qiáng)半同步(MySQL 5.7引入)
半同步復(fù)制:主庫等待從庫寫入 relay log 并返回 ACK 后才進(jìn)行Engine Commit。
并行復(fù)制----解決從庫復(fù)制延遲的問題,通過增加 SQL Thread線程數(shù)實(shí)現(xiàn)?
復(fù)制延遲的根本原因:
在從庫中有兩個線程IO Thread和SQL Thread,都是單線程模式工作,因此有了延遲問題;
我們可以采用多線程機(jī)制來加強(qiáng),減少從庫復(fù)制延遲。(IO Thread多線程意義不大,主要指的是SQL Thread多線程:解析redaylog中的內(nèi)容,并在從庫上執(zhí)行)
在MySQL的5.6、5.7、8.0版本上,都是基于上述SQL Thread多線程思想,不斷優(yōu)化,減少復(fù)制延遲。
上面說主從復(fù)制的根本目的是為了實(shí)現(xiàn) 讀寫分離:
在讀寫分離的應(yīng)用場景下, 可以在從庫追加多個索引來優(yōu)化查詢,主庫這些索引可以不加,用于提升寫效率。
為了避免主從同步出現(xiàn)的延遲性問題出現(xiàn),我們也可以使用以下方案:
寫后立刻讀
在寫入數(shù)據(jù)庫后,某個時間段內(nèi)讀操作就去主庫,之后讀操作訪問從庫。
二次查詢
先去從庫讀取數(shù)據(jù),找不到時就去主庫進(jìn)行數(shù)據(jù)讀取。該操作容易將讀壓力返還給主庫,
根據(jù)業(yè)務(wù)特殊處理
根據(jù)業(yè)務(wù)特點(diǎn)和重要程度進(jìn)行調(diào)整,比如重要的,實(shí)時性要求高的業(yè)務(wù)數(shù)據(jù)讀寫可以放在主庫。對于次要的業(yè)務(wù),實(shí)時性要求不高可以進(jìn)行讀寫分離,查詢時去從庫查詢。
?
查看全部 -
call
查看全部 -
j
查看全部 -
1
查看全部 -
ccc
查看全部 -
并發(fā)
查看全部 -
現(xiàn)場是CPU調(diào)度的基本單位也是執(zhí)行的基本單位查看全部
-
一個進(jìn)程可以有很多個線程查看全部
舉報