本文目錄一覽:
Mysql主從資料庫
配置好主從以後,主庫插入數據,寫到二進位日誌中,發送給從庫,從庫接收二進位日誌寫到relay日誌中,從庫從relay日誌中讀取、插入數據。
MySql里有多個資料庫
Class.forName(“com.mysql.jdbc.Driver”);
String username = “root”;
String password = “root”;
String url = “jdbc:mysql://localhost:3306/jdbctest”;
conn = DriverManager.getConnection(url, username, password);
假如你用的JDBC方式連接的資料庫,那String url中的jdbctest就是你要連接的資料庫啊,在url中就指定了.上面的代碼就是連接的資料庫的代碼
你的String serverInfo=”jdbc:mysql://127.0.0.1:3306/jsp_db?對應著我寫的url,所以jsp_db就是你要連接的資料庫名,要連哪個資料庫是必須指定的.
MYSQL默認資料庫有幾個?
默認的有mysql,test這幾個資料庫。
從MySQL 5開始, 可以看到多了一個系統資料庫information_schema . information_schema 存貯了其他所有資料庫的信息。
information_schema是一個虛擬資料庫,並不物理存在,在select的時候,從其他資料庫獲取相應的信息。
MySQL 主從,5 分鐘帶你掌握
MySQL 主從一直是面試常客,裡面的知識點雖然基礎,但是能回答全的同學不多。
比如樓哥之前面試小米,就被問到過主從複製的原理,以及主從延遲的解決方案,因為回答的非常不錯,給面試官留下非常好的印象。你之前面試,有遇到過哪些 MySQL 主從的問題呢?
所謂 MySQL 主從,就是建立兩個完全一樣的資料庫,一個是主庫,一個是從庫, 主庫對外提供讀寫的操作,從庫對外提供讀的操作 ,下面是一主一從模式:
對於資料庫單機部署,在 4 核 8G 的機器上運行 MySQL 5.7 時,大概可以支撐 500 的 TPS 和 10000 的 QPS, 當遇到一些活動時,查詢流量驟然,就需要進行主從分離。
大部分系統的訪問模型是讀多寫少,讀寫請求量的差距可能達到幾個數量級,所以我們可以通過一主多從的方式, 主庫只負責寫入和部分核心邏輯的查詢,多個從庫只負責查詢,提升查詢性能,降低主庫壓力。
MySQL 主從還能做到服務高可用,當主庫宕機時,從庫可以切成主庫,保證服務的高可用,然後主庫也可以做數據的容災備份。
整體場景總結如下:
MySQL 的主從複製是依賴於 binlog 的,也就是記錄 MySQL 上的所有變化並以二進位形式保存在磁碟上二進位日誌文件。
主從複製就是將 binlog 中的數據從主庫傳輸到從庫上,一般這個過程是非同步的,即主庫上的操作不會等待 binlog 同步的完成。
詳細流程如下:
當主庫和從庫數據同步時,突然中斷怎麼辦?因為主庫與從庫之間維持了一個長鏈接,主庫內部有一個線程,專門服務於從庫的這個長鏈接的。
對於下面的情況,假如主庫執行如下 SQL,其中 a 和 create_time 都是索引:
我們知道,數據選擇了 a 索引和選擇 create_time 索引,最後 limit 1 出來的數據一般是不一樣的。
所以就會存在這種情況:在 binlog = statement 格式時,主庫在執行這條 SQL 時,使用的是索引 a,而從庫在執行這條 SQL 時,使用了索引 create_time,最後主從數據不一致了。
那麼我們改如何解決呢?
可以把 binlog 格式修改為 row,row 格式的 binlog 日誌記錄的不是 SQL 原文,而是兩個 event:Table_map 和 Delete_rows。
Table_map event 說明要操作的表,Delete_rows event用於定義要刪除的行為,記錄刪除的具體行數。 row 格式的 binlog 記錄的就是要刪除的主鍵 ID 信息,因此不會出現主從不一致的問題。
但是如果 SQL 刪除 10 萬行數據,使用 row 格式就會很占空間的,10 萬條數據都在 binlog 裡面,寫 binlog 的時候也很耗 IO。但是 statement 格式的 binlog 可能會導致數據不一致。
設計 MySQL 的大叔想了一個折中的方案,mixed 格式的 binlog,其實就是 row 和 statement 格式混合使用, 當 MySQL 判斷可能數據不一致時,就用 row 格式,否則使用就用 statement 格式。
有時候我們遇到從資料庫中獲取不到信息的詭異問題時,會糾結於代碼中是否有一些邏輯會把之前寫入的內容刪除,但是你又會發現,過了一段時間再去查詢時又可以讀到數據了,這基本上就是主從延遲在作怪。
主從延遲,其實就是「從庫回放」 完成的時間,與 「主庫寫 binlog」 完成時間的差值, 會導致從庫查詢的數據,和主庫的不一致 。
談到 MySQL 資料庫主從同步延遲原理,得從 MySQL 的主從複製原理說起:
總結一下主從延遲的主要原因 :主從延遲主要是出現在 「relay log 回放」 這一步,當主庫的 TPS 並發較高,產生的 DDL 數量超過從庫一個 SQL 線程所能承受的範圍,那麼延時就產生了,當然還有就是可能與從庫的大型 query 語句產生了鎖等待。
我們一般會把從庫落後的時間作為一個重點的資料庫指標做監控和報警,正常的時間是在毫秒級別,一旦落後的時間達到了秒級別就需要告警了。
解決該問題的方法,除了縮短主從延遲的時間,還有一些其它的方法,基本原理都是盡量不查詢從庫。
具體解決方案如下:
在實際應用場景中,對於一些非常核心的場景,比如庫存,支付訂單等,需要直接查詢從庫,其它非核心場景,就不要去查主庫了。
兩台機器 A 和 B,A 為主庫,負責讀寫,B 為從庫,負責讀數據。
如果 A 庫發生故障,B 庫成為主庫負責讀寫,修復故障後,A 成為從庫,主庫 B 同步數據到從庫 A。
一台主庫多台從庫,A 為主庫,負責讀寫,B、C、D為從庫,負責讀數據。
如果 A 庫發生故障,B 庫成為主庫負責讀寫,C、D負責讀,修復故障後,A 也成為從庫,主庫 B 同步數據到從庫 A。
mysql 核心內容-上
1、SQL語句執行流程
MySQL大體上可分為Server層和存儲引擎層兩部分。
Server層:
連接器:TCP握手後伺服器來驗證登陸用戶身份,A用戶創建連接後,管理員對A用戶許可權修改了也不會影響到已經創建的鏈接許可權,必須重新登陸。
查詢緩存:查詢後的結果存儲位置,MySQL8.0版本以後已經取消,因為查詢緩存失效太頻繁,得不償失。
分析器:根據語法規則,判斷你輸入的這個SQL語句是否滿足MySQL語法。
優化器:多種執行策略可實現目標,系統自動選擇最優進行執行。
執行器:判斷是否有許可權,將最終任務提交到存儲引擎。
存儲引擎層
負責數據的存儲和提取。其架構模式是插件式的,支持InnoDB、MyISAM、Memory等多個存儲引擎。現在最常用的存儲引擎是InnoDB,它從MySQL 5.5.5版本開始成為了默認存儲引擎(經常用的也是這個)。
SQL執行順序
2、BinLog、RedoLog、UndoLog
BinLog
BinLog是記錄所有資料庫表結構變更(例如create、alter table)以及表數據修改(insert、update、delete)的二進位日誌,主從資料庫同步用到的都是BinLog文件。BinLog日誌文件有三種模式。
STATEMENT 模式
內容:binlog 記錄可能引起數據變更的 sql 語句
優勢:該模式下,因為沒有記錄實際的數據,所以日誌量很少 IO 都消耗很低,性能是最優的
劣勢:但有些操作並不是確定的,比如 uuid() 函數會隨機產生唯一標識,當依賴 binlog 回放時,該操作生成的數據與原數據必然是不同的,此時可能造成無法預料的後果。
ROW 模式
內容:在該模式下,binlog 會記錄每次操作的源數據與修改後的目標數據,StreamSets就要求該模式。
優勢:可以絕對精準的還原,從而保證了數據的安全與可靠,並且複製和數據恢復過程可以是並發進行的
劣勢:缺點在於 binlog 體積會非常大,同時,對於修改記錄多、欄位長度大的操作來說,記錄時性能消耗會很嚴重。閱讀的時候也需要特殊指令來進行讀取數據。
MIXED 模式
內容:是對上述STATEMENT 跟 ROW 兩種模式的混合使用。
細節:對於絕大部分操作,都是使用 STATEMENT 來進行 binlog 沒有記錄,只有以下操作使用 ROW 來實現:表的存儲引擎為 NDB,使用了uuid() 等不確定函數,使用了 insert delay 語句,使用了臨時表
主從同步流程:
1、主節點必須啟用二進位日誌,記錄任何修改了資料庫數據的事件。
2、從節點開啟一個線程(I/O Thread)把自己扮演成 mysql 的客戶端,通過 mysql 協議,請求主節點的二進位日誌文件中的事件 。
3、主節點啟動一個線程(dump Thread),檢查自己二進位日誌中的事件,跟對方請求的位置對比,如果不帶請求位置參數,則主節點就會從第一個日誌文件中的第一個事件一個一個發送給從節點。
4、從節點接收到主節點發送過來的數據把它放置到中繼日誌(Relay log)文件中。並記錄該次請求到主節點的具體哪一個二進位日誌文件內部的哪一個位置(主節點中的二進位文件會有多個)。
5、從節點啟動另外一個線程(sql Thread ),把 Relay log 中的事件讀取出來,並在本地再執行一次。
mysql默認的複製方式是非同步的,並且複製的時候是有並行複製能力的。主庫把日誌發送給從庫後不管了,這樣會產生一個問題就是假設主庫掛了,從庫處理失敗了,這時候從庫升為主庫後,日誌就丟失了。由此產生兩個概念。
全同步複製
主庫寫入binlog後強制同步日誌到從庫,所有的從庫都執行完成後才返回給客戶端,但是很顯然這個方式的話性能會受到嚴重影響。
半同步複製
半同步複製的邏輯是這樣,從庫寫入日誌成功後返回ACK確認給主庫,主庫收到至少一個從庫的確認就認為寫操作完成。
還可以延伸到由於主從配置不一樣、主庫大事務、從庫壓力過大、網路震蕩等造成主備延遲,如何避免這個問題?主備切換的時候用可靠性優先原則還是可用性優先原則?如何判斷主庫Crash了?互為主備的情況下如何避免主備循環複製?被刪庫跑路了如何正確恢復?( o )… 感覺越來越扯到DBA的活兒上去了。
RedoLog
可以先通過下面demo理解:
飯點記賬可以把賬單寫在賬本上也可以寫在粉板上。有人賒賬或者還賬的話,一般有兩種做法:
1、直接把賬本翻出來,把這次賒的賬加上去或者扣除掉。
2、先在粉板上記下這次的賬,等打烊以後再把賬本翻出來核算。
生意忙時選後者,因為前者太麻煩了。得在密密麻麻的記錄中找到這個人的賒賬總額信息,找到之後再拿出算盤計算,最後再將結果寫回到賬本上。
同樣在MySQL中如果每一次的更新操作都需要寫進磁碟,然後磁碟也要找到對應的那條記錄,然後再更新,整個過程IO成本、查找成本都很高。而粉板和賬本配合的整個過程就是MySQL用到的是Write-Ahead Logging 技術,它的關鍵點就是先寫日誌,再寫磁碟。此時賬本 = BinLog,粉板 = RedoLog。
1、 記錄更新時,InnoDB引擎就會先把記錄寫到RedoLog(粉板)裡面,並更新內存。同時,InnoDB引擎會在空閑時將這個操作記錄更新到磁碟裡面。
2、 如果更新太多RedoLog處理不了的時候,需先將RedoLog部分數據寫到磁碟,然後擦除RedoLog部分數據。RedoLog類似轉盤。
RedoLog有write pos 跟checkpoint
write pos :是當前記錄的位置,一邊寫一邊後移,寫到第3號文件末尾後就回到0號文件開頭。
check point:是當前要擦除的位置,也是往後推移並且循環的,擦除記錄前要把記錄更新到數據文件。
write pos和check point之間的是粉板上還空著的部分,可以用來記錄新的操作。如果write pos追上checkpoint,表示粉板滿了,這時候不能再執行新的更新,得停下來先擦掉一些記錄,把checkpoint推進一下。
有了redo log,InnoDB就可以保證即使資料庫發生異常重啟,之前提交的記錄都不會丟失,這個能力稱為crash-safe。 redolog兩階段提交:為了讓binlog跟redolog兩份日誌之間的邏輯一致。提交流程大致如下:
1 prepare階段 — 2 寫binlog — 3 commit
當在2之前崩潰時,重啟恢復後發現沒有commit,回滾。備份恢復:沒有binlog 。一致
當在3之前崩潰時,重啟恢複發現雖沒有commit,但滿足prepare和binlog完整,所以重啟後會自動commit。備份:有binlog. 一致
binlog跟redolog區別:
redo log是InnoDB引擎特有的;binlog是MySQL的Server層實現的,所有引擎都可以使用。
redo log是物理日誌,記錄的是在某個數據頁上做了什麼修改;binlog是邏輯日誌,記錄的是這個語句的原始邏輯,比如給ID=2這一行的c欄位加1。
redo log是循環寫的,空間固定會用完;binlog是可以追加寫入的。追加寫是指binlog文件寫到一定大小後會切換到下一個,並不會覆蓋以前的日誌。
UndoLog
UndoLog 一般是邏輯日誌,主要分為兩種:
insert undo log
代表事務在insert新記錄時產生的undo log, 只在事務回滾時需要,並且在事務提交後可以被立即丟棄
update undo log
事務在進行update或delete時產生的undo log; 不僅在事務回滾時需要,在快照讀時也需要;所以不能隨便刪除,只有在快速讀或事務回滾不涉及該日誌時,對應的日誌才會被purge線程統一清除
3、MySQL中的索引
索引的常見模型有哈希表、有序數組和搜索樹。
哈希表:一種以KV存儲數據的結構,只適合等值查詢,不適合範圍查詢。
有序數組:只適用於靜態存儲引擎,涉及到插入的時候比較麻煩。可以參考Java中的ArrayList。
搜索樹:按照數據結構中的二叉樹來存儲數據,不過此時是N叉樹(B+樹)。廣泛應用在存儲引擎層中。
B+樹比B樹優勢在於:
B+ 樹非葉子節點存儲的只是索引,可以存儲的更多。B+樹比B樹更加矮胖,IO次數更少。
B+ 樹葉子節點前後管理,更加方便範圍查詢。同時結果都在葉子節點,查詢效率穩定。
B+樹中更有利於對數據掃描,可以避免B樹的回溯掃描。
索引的優點:
1、唯一索引可以保證每一行數據的唯一性
2、提高查詢速度
3、加速表與表的連接
4、顯著的減少查詢中分組和排序的時間
5、通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。
索引的缺點:
1、創建跟維護都需要耗時
2、創建索引時,需要對錶加鎖,在鎖表的同時,可能會影響到其他的數據操作
3、 索引需要磁碟的空間進行存儲,磁碟佔用也很快。
4、當對表中的數據進行CRUD的時,也會觸發索引的維護,而維護索引需要時間,可能會降低數據操作性能
索引設計的原則不應該:
1、索引不是越多越好。索引太多,維護索引需要時間跟空間。
2、 頻繁更新的數據,不宜建索引。
3、數據量小的表沒必要建立索引。
應該:
1、重複率小的列建議生成索引。因為重複數據少,索引樹查詢更有效率,等價基數越大越好。
2、數據具有唯一性,建議生成唯一性索引。在資料庫的層面,保證數據正確性
3、頻繁group by、order by的列建議生成索引。可以大幅提高分組和排序效率
4、經常用於查詢條件的欄位建議生成索引。通過索引查詢,速度更快
索引失效的場景
1、模糊搜索:左模糊或全模糊都會導致索引失效,比如’%a’和’%a%’。但是右模糊是可以利用索引的,比如’a%’ 。
2、隱式類型轉換:比如select * from t where name = xxx , name是字元串類型,但是沒有加引號,所以是由MySQL隱式轉換的,所以會讓索引失效 3、當語句中帶有or的時候:比如select * from t where name=『sw』 or age=14
4、不符合聯合索引的最左前綴匹配:(A,B,C)的聯合索引,你只where了C或B或只有B,C
關於索引的知識點:
主鍵索引:主鍵索引的葉子節點存的是整行數據信息。在InnoDB里,主鍵索引也被稱為聚簇索引(clustered index)。主鍵自增是無法保證完全自增的哦,遇到唯一鍵衝突、事務回滾等都可能導致不連續。
唯一索引:以唯一列生成的索引,該列不允許有重複值,但允許有空值(NULL)
普通索引跟唯一索引查詢性能:InnoDB的數據是按數據頁為單位來讀寫的,默認每頁16KB,因此這兩種索引查詢數據性能差別微乎其微。
change buffer:普通索引用在更新過程的加速,更新的欄位如果在緩存中,如果是普通索引則直接更新即可。如果是唯一索引需要將所有數據讀入內存來確保不違背唯一性,所以盡量用普通索引。
非主鍵索引:非主鍵索引的葉子節點內容是主鍵的值。在InnoDB里,非主鍵索引也被稱為二級索引(secondary index)
回表:先通過資料庫索引掃描出數據所在的行,再通過行主鍵id取出索引中未提供的數據,即基於非主鍵索引的查詢需要多掃描一棵索引樹。
覆蓋索引:如果一個索引包含(或者說覆蓋)所有需要查詢的欄位的值,我們就稱之為覆蓋索引。
聯合索引:相對單列索引,組合索引是用多個列組合構建的索引,一次性最多聯合16個。
最左前綴原則:對多個欄位同時建立的組合索引(有順序,ABC,ACB是完全不同的兩種聯合索引) 以聯合索引(a,b,c)為例,建立這樣的索引相當於建立了索引a、ab、abc三個索引。另外組合索引實際還是一個索引,並非真的創建了多個索引,只是產生的效果等價於產生多個索引。
索引下推:MySQL 5.6引入了索引下推優化,可以在索引遍歷過程中,對索引中包含的欄位先做判斷,過濾掉不符合條件的記錄,減少回表字數。
索引維護:B+樹為了維護索引有序性涉及到頁分裂跟頁合併。增刪數據時需考慮頁空間利用率。
自增主鍵:一般會建立與業務無關的自增主鍵,不會觸發葉子節點分裂。
延遲關聯:通過使用覆蓋索引查詢返回需要的主鍵,再根據主鍵關聯原表獲得需要的數據。
InnoDB存儲: * .frm文件是一份定義文件,也就是定義資料庫表是一張怎麼樣的表。*.ibd文件則是該表的索引,數據存儲文件,既該表的所有索引樹,所有行記錄數據都存儲在該文件中。
MyISAM存儲:* .frm文件是一份定義文件,也就是定義資料庫表是一張怎麼樣的表。* .MYD文件是MyISAM存儲引擎表的所有行數據的文件。* .MYI文件存放的是MyISAM存儲引擎表的索引相關數據的文件。MyISAM引擎下,表數據和表索引數據是分開存儲的。
MyISAM查詢:在MyISAM下,主鍵索引和輔助鍵索引都屬於非聚簇索引。查詢不管是走主鍵索引,還是非主鍵索引,在葉子結點得到的都是目的數據的地址,還需要通過該地址,才能在數據文件中找到目的數據。
PS:InnoDB支持聚簇索引,MyISAM不支持聚簇索引
4、SQL事務隔離級別
ACID的四個特性
原子性(Atomicity):把多個操作放到一個事務中,保證這些操作要麼都成功,要麼都不成功
一致性(Consistency):理解成一串對數據進行操作的程序執行下來,不會對數據產生不好的影響,比如憑空產生,或消失
隔離性(Isolation,又稱獨立性):隔離性的意思就是多個事務之間互相不干擾,即使是並發事務的情況下,他們只是兩個並發執行沒有交集,互不影響的東西;當然實現中,也不一定需要這麼完整隔離性,即不一定需要這麼的互不干擾,有時候還是允許有部分干擾的。所以MySQL可以支持4種事務隔離性
持久性(Durability):當某個操作操作完畢了,那麼結果就是這樣了,並且這個操作會持久化到日誌記錄中
PS:ACID中C與CAP定理中C的區別
ACID的C著重強調單資料庫事務操作時,要保證數據的完整和正確性,數據不會憑空消失跟增加。CAP 理論中的C指的是對一個數據多個備份的讀寫一致性
事務操作可能會出現的數據問題
1、臟讀(dirty read):B事務更改數據還未提交,A事務已經看到並且用了。B事務如果回滾,則A事務做錯了
2、 不可重複讀(non-repeatable read):不可重複讀的重點是修改: 同樣的條件, 你讀取過的數據, 再次讀取出來發現值不一樣了,只需要鎖住滿足條件的記錄
3、 幻讀(phantom read):事務A先修改了某個表的所有紀錄的狀態欄位為已處理,未提交;事務B也在此時新增了一條未處理的記錄,並提交了;事務A隨後查詢記錄,卻發現有一條記錄是未處理的造成幻讀現象,幻讀僅專指新插入的行。幻讀會造成語義上的問題跟數據一致性問題。
4、 在可重複讀RR隔離級別下,普通查詢是快照讀,是不會看到別的事務插入的數據的。因此,幻讀在當前讀下才會出現。要用間隙鎖解決此問題。
在說隔離級別之前,你首先要知道,你隔離得越嚴實,效率就會越低。因此很多時候,我們都要在二者之間尋找一個平衡點。SQL標準的事務隔離級別由低到高如下: 上圖從上到下的模式會導致系統的並行性能依次降低,安全性依次提高。
讀未提交:別人改數據的事務尚未提交,我在我的事務中也能讀到。
讀已提交(Oracle默認):別人改數據的事務已經提交,我在我的事務中才能讀到。
可重複讀(MySQL默認):別人改數據的事務已經提交,我在我的事務中也不去讀,以此保證重複讀一致性。
串列:我的事務尚未提交,別人就別想改數據。
標準跟實現:上面都是關於事務的標準,但是每一種資料庫都有不同的實現,比如MySQL InnDB 默認為RR級別,但是不會出現幻讀。因為當事務A更新了所有記錄的某個欄位,此時事務A會獲得對這個表的表鎖,因為事務A還沒有提交,所以事務A獲得的鎖沒有釋放,此時事務B在該表插入新記錄,會因為無法獲得該表的鎖,則導致插入操作被阻塞。只有事務A提交了事務後,釋放了鎖,事務B才能進行接下去的操作。所以可以說 MySQL的RR級別的隔離是已經實現解決了臟讀,不可重複讀和幻讀的。
5、MySQL中的鎖
無論是Java的並發編程還是資料庫的並發操作都會涉及到鎖,研發人員引入了悲觀鎖跟樂觀鎖這樣一種鎖的設計思想。
悲觀鎖:
優點:適合在寫多讀少的並發環境中使用,雖然無法維持非常高的性能,但是在樂觀鎖無法提更好的性能前提下,可以做到數據的安全性
缺點:加鎖會增加系統開銷,雖然能保證數據的安全,但數據處理吞吐量低,不適合在讀書寫少的場合下使用
樂觀鎖:
優點:在讀多寫少的並發場景下,可以避免資料庫加鎖的開銷,提高DAO層的響應性能,很多情況下ORM工具都有帶有樂觀鎖的實現,所以這些方法不一定需要我們人為的去實現。
缺點:在寫多讀少的並發場景下,即在寫操作競爭激烈的情況下,會導致CAS多次重試,衝突頻率過高,導致開銷比悲觀鎖更高。
實現:資料庫層面的樂觀鎖其實跟CAS思想類似, 通數據版本號或者時間戳也可以實現。
資料庫並發場景主要有三種:
讀-讀:不存在任何問題,也不需要並發控制
讀-寫:有隔離性問題,可能遇到臟讀,幻讀,不可重複讀
寫-寫:可能存更新丟失問題,比如第一類更新丟失,第二類更新丟失
兩類更新丟失問題:
第一類更新丟失:事務A的事務回滾覆蓋了事務B已提交的結果 第二類更新丟失:事務A的提交覆蓋了事務B已提交的結果
為了合理貫徹落實鎖的思想,MySQL中引入了雜七雜八的各種鎖:
鎖分類
MySQL支持三種層級的鎖定,分別為
表級鎖定
MySQL中鎖定粒度最大的一種鎖,最常使用的MYISAM與INNODB都支持表級鎖定。
頁級鎖定
是MySQL中鎖定粒度介於行級鎖和表級鎖中間的一種鎖,表級鎖速度快,但衝突多,行級衝突少,但速度慢。所以取了折衷的頁級,一次鎖定相鄰的一組記錄。
行級鎖定
Mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少資料庫操作的衝突。其加鎖粒度最小,但加鎖的開銷也最大行級鎖不一定比表級鎖要好:鎖的粒度越細,代價越高,相比表級鎖在表的頭部直接加鎖,行級鎖還要掃描找到對應的行對其上鎖,這樣的代價其實是比較高的,所以表鎖和行鎖各有所長。
MyISAM中的鎖
雖然MySQL支持表,頁,行三級鎖定,但MyISAM存儲引擎只支持表鎖。所以MyISAM的加鎖相對比較開銷低,但數據操作的並發性能相對就不高。但如果寫操作都是尾插入,那還是可以支持一定程度的讀寫並發
從MyISAM所支持的鎖中也可以看出,MyISAM是一個支持讀讀並發,但不支持通用讀寫並發,寫寫並發的資料庫引擎,所以它更適合用於讀多寫少的應用場合,一般工程中也用的較少。
InnoDB中的鎖
該模式下支持的鎖實在是太多了,具體如下:
共享鎖和排他鎖 (Shared and Exclusive Locks)
意向鎖(Intention Locks)
記錄鎖(Record Locks)
間隙鎖(Gap Locks)
臨鍵鎖 (Next-Key Locks)
插入意向鎖(Insert Intention Locks)
主鍵自增鎖 (AUTO-INC Locks)
空間索引斷言鎖(Predicate Locks for Spatial Indexes)
舉個栗子,比如行鎖里的共享鎖跟排它鎖:lock in share modle 共享讀鎖:
為了確保自己查到的數據沒有被其他的事務正在修改,也就是說確保查到的數據是最新的數據,並且不允許其他人來修改數據。但是自己不一定能夠修改數據,因為有可能其他的事務也對這些數據使用了 in share mode 的方式上了S 鎖。如果不及時的commit 或者rollback 也可能會造成大量的事務等待。
for update排它寫鎖:
為了讓自己查到的數據確保是最新數據,並且查到後的數據只允許自己來修改的時候,需要用到for update。相當於一個 update 語句。在業務繁忙的情況下,如果事務沒有及時的commit或者rollback 可能會造成其他事務長時間的等待,從而影響資料庫的並發使用效率。
Gap Lock間隙鎖:
1、行鎖只能鎖住行,如果在記錄之間的間隙插入數據就無法解決了,因此MySQL引入了間隙鎖(Gap Lock)。間隙鎖是左右開區間。間隙鎖之間不會衝突。
2、間隙鎖和行鎖合稱NextKeyLock,每個NextKeyLock是前開後閉區間。
間隙鎖加鎖原則(學完忘那種):
1、加鎖的基本單位是 NextKeyLock,是前開後閉區間。
2、查找過程中訪問到的對象才會加鎖。
3、索引上的等值查詢,給唯一索引加鎖的時候,NextKeyLock退化為行鎖。
4、索引上的等值查詢,向右遍歷時且最後一個值不滿足等值條件的時候,NextKeyLock退化為間隙鎖。
5、唯一索引上的範圍查詢會訪問到不滿足條件的第一個值為止。
mysql資料庫怎麼查看所有庫
1、先鏈接進主庫
2、點擊查詢》輸入:show databases;》執行
如果是linux下面的:
先鏈接進主庫,進入XX庫》use XX》輸入 show tables; 回車
原創文章,作者:EAZH,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/137445.html