MySQL
死鎖
兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過程中,因爭奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進(jìn)下去。
產(chǎn)生死鎖的四個(gè)必要條件:
- 互斥條件:一個(gè)資源每次只能被一個(gè)進(jìn)程使用。
- 請求與保持條件:一個(gè)進(jìn)程因請求資源而阻塞時(shí),對已獲得的資源保持不放。
- 不剝奪條件:進(jìn)程已獲得的資源,在末使用完之前,不能強(qiáng)行剝奪。
- 循環(huán)等待條件:若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
死鎖產(chǎn)生影響
當(dāng)產(chǎn)生某表死鎖的一開始,所有涉及這張表的操作都將受到阻塞。假設(shè)這張表在業(yè)務(wù)邏輯上是讀寫頻繁的,那就會(huì)使很多操作在那里排隊(duì)等待,而排隊(duì)等待會(huì)占用數(shù)據(jù)庫連接,當(dāng)該達(dá)到該數(shù)據(jù)庫連接數(shù)的最大承載數(shù)之后,就會(huì)使所有數(shù)據(jù)庫操作均無法再繼續(xù)下去,致使數(shù)據(jù)庫各項(xiàng)指標(biāo)異常,導(dǎo)致整個(gè)環(huán)境崩潰。
如何發(fā)現(xiàn)死鎖
SHOW FULL PROCESSLIST;
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
如何處理死鎖:通過以上方法一可以查詢對應(yīng)死鎖的數(shù)據(jù)庫進(jìn)程,可以直接殺掉kill 進(jìn)程ID。
避免死鎖:
- 按同一順序訪問對象。
- 避免事務(wù)中的用戶交互。
- 保持事務(wù)簡短并在一個(gè)批處理中。
- 使用低隔離級別。
- 使用綁定連接。
隔離級別
- 讀未提交:一個(gè)事務(wù)還沒提交時(shí),它做的變更就能被別的事務(wù)看到。臟讀。
- 讀提交:一個(gè)事物提交之后,它做的變更才會(huì)被其他事務(wù)看到。不可重復(fù)讀,同樣一條記錄,兩次查詢可能會(huì)有不同結(jié)果。
- 可重復(fù)讀:一個(gè)事物執(zhí)行過程中看到的數(shù)據(jù),總是跟這個(gè)事務(wù)在啟動(dòng)時(shí)看到的數(shù)據(jù)是一致的。當(dāng)然在可重復(fù)讀隔離級別下,未提交變更對其它事務(wù)也是不可見的。幻讀,當(dāng)某個(gè)事務(wù)在讀取某個(gè)范圍內(nèi)的記錄時(shí),另一個(gè)事務(wù)在該范圍內(nèi)插入新的記錄,再次讀取產(chǎn)生幻行。多版本并發(fā)控制MVCC來解決。
- 串行化:同一行記錄,寫加寫鎖,讀加讀鎖。當(dāng)讀寫鎖沖突時(shí),后訪問的事務(wù)必須等到前一事務(wù)執(zhí)行完成,才能繼續(xù)執(zhí)行。解決幻讀。
B+樹和B樹
MySQL 中的 B-Tree 索引的物理文件大多都是以 Balance Tree 的結(jié)構(gòu)來存儲(chǔ)的,也就是所有實(shí)際需要的數(shù)據(jù)都存放于 Tree 的葉子節(jié)點(diǎn) ,而且到任何一個(gè)葉子節(jié)點(diǎn) 的最短路徑的長度都是完全相同的,可能各種數(shù)據(jù)庫(或 MySQL 的各種存儲(chǔ)引擎)在存放自己的 B-Tree 索引的時(shí)候會(huì)對存儲(chǔ)結(jié)構(gòu)稍作改造。如 Innodb B+Tree ,在每一葉子節(jié)點(diǎn) 上面出了存放索引鍵的相關(guān)信息之外,還存儲(chǔ)了指向與該葉子節(jié)點(diǎn) 相鄰的后一個(gè)葉子節(jié)點(diǎn)的指針信息,這主要是為了加快檢索多個(gè)相鄰葉子節(jié)點(diǎn)的效率考慮。
在 Innodb 存儲(chǔ)引擎中,存在兩種不同形式的索引,主鍵索引的葉子節(jié)點(diǎn)存的是整行數(shù)據(jù),在innodb里,主鍵索引也被稱為聚簇索引。非主鍵索引的葉子節(jié)點(diǎn)內(nèi)容是主鍵的值,在innodb里,非主鍵索引也被稱為二級索引。
悲觀鎖、樂觀鎖
樂觀鎖顧名思義就是在操作時(shí)很樂觀,認(rèn)為操作不會(huì)產(chǎn)生并發(fā)問題(不會(huì)有其他線程對數(shù)據(jù)進(jìn)行修改),因此不會(huì)上鎖。但是在更新時(shí)會(huì)判斷其他線程在這之前有沒有對數(shù)據(jù)進(jìn)行修改,一般會(huì)使用版本號機(jī)制或CAS(compare and swap)算法實(shí)現(xiàn)。
總是假設(shè)最壞的情況,每次取數(shù)據(jù)時(shí)都認(rèn)為其他線程會(huì)修改,所以都會(huì)加(悲觀)鎖。一旦加鎖,不同線程同時(shí)執(zhí)行時(shí),只能有一個(gè)線程執(zhí)行,其他的線程在入口處等待,直到鎖被釋放。悲觀鎖在MySQL、Java有廣泛的使用:MySQL的讀鎖、寫鎖、行鎖等。
MySQL 索引是不是越多越好?為什么?
數(shù)據(jù)的變更(增刪改)都需要維護(hù)索引,因此更多的索引意味著更多的維護(hù)成本;更多的索引意味著也需要更多的空間;過小的表,建索引可能會(huì)更慢。
主從
一個(gè)節(jié)點(diǎn)存了多少數(shù)據(jù),怎么規(guī)定大小,與磁盤頁對應(yīng)
InnoDB存儲(chǔ)引擎默認(rèn)一個(gè)數(shù)據(jù)頁大小為16kb,非葉子節(jié)點(diǎn)存放(key,pointer),pointer為6個(gè)字節(jié),key為4個(gè)字節(jié),即非葉子節(jié)點(diǎn)能存放16kb/14左右的key,pointer,而葉子節(jié)點(diǎn)如果一條數(shù)據(jù)大小為100字節(jié),那一個(gè)葉子節(jié)點(diǎn)大約可存放160條數(shù)據(jù)。
如果高度為3,則可存放數(shù)據(jù)為:16kb/14 * 16kb/14 * 160大約1億多數(shù)據(jù)。
因此InnoDB存儲(chǔ)引擎b+樹的高度基本為2-3。
- 數(shù)據(jù)庫InnoDB下如何加鎖?
- 分析 delect from table where user_id=“1”;這句話怎么加鎖的?
- 如果user_id使用單列索引,聯(lián)合索引,又是怎么加鎖的?
- mysql實(shí)現(xiàn)事務(wù)的原理(MVCC)
- SQL 語句的具體執(zhí)行過程,比如會(huì)怎么利用索引,怎么優(yōu)化之類的 explain show processlist
- 為什么控制高度?(連續(xù)讀磁盤 效率高)
- 詳細(xì)描述b+?(以innodb索引為例給他畫了下)
- innodb 數(shù)據(jù)隔離級別 (四個(gè)隔離級別說了下 順帶把臟讀 幻讀 不可重復(fù)度說了下)
不影響使用的擴(kuò)容
CAP,mysql集群滿足了什么,什么滿足了CP - 數(shù)據(jù)庫索引結(jié)構(gòu)采用的是什么數(shù)據(jù)結(jié)構(gòu)?為什么要采用這個(gè)結(jié)構(gòu)?假如將數(shù)據(jù)全部加載到內(nèi)存,b+樹還有優(yōu)勢嗎?理由。
- 聚集索引是什么?
主從分離延時(shí)什么造成的
切換備份機(jī)業(yè)務(wù)方需要做什么
redis實(shí)現(xiàn)分布式事務(wù)鎖,有什么缺點(diǎn)
redis:
redis的模型,redis為什么快?redis為什么是單線程的?多核心機(jī)器如何部署redis(單進(jìn)程占用單核)?
epoll,poll和select;
redis,mysql***作的時(shí)間數(shù)量級;
redis各種集群的方式,哨兵模式;
redis持久化的方式,aof文件太大了怎么辦,主從同步的方式;
redis的五種常用數(shù)據(jù)結(jié)構(gòu),以及對應(yīng)的底層數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)(zpilist,skiplist,quicklist,sds等等要有些了解);
講講對Redis的了解,有哪些基本類型和各自底層實(shí)現(xiàn)方法
- redis有哪幾種數(shù)據(jù)類型嗎?你比較熟悉哪幾種?為什么?
- redis里面的哈希表
- Redis 底層用到了哪些數(shù)據(jù)結(jié)構(gòu)?使用 Redis 的 set 來做過什么?
- Redis 使用過程中遇到什么問題?搭建過 Redis 集群嗎?
- 微博刷新選取所有關(guān)注人的最新n條記錄如何取
- redis分片,客戶端的請求怎么處理
- 6 Redis了解么,如果Redis有1億個(gè)key,使用keys命令是否會(huì)影響線上服務(wù),我說會(huì),因?yàn)槭菃尉€程模型,可以部署多個(gè)節(jié)點(diǎn)。
7 問我知不知道有一條命令可以實(shí)現(xiàn)上面這個(gè)功能。不知道
8 Redis的持久化方式,aod和rdb,具體怎么實(shí)現(xiàn),追加日志和備份文件,底層實(shí)現(xiàn)原理的話知道么,不清楚。
9 Redis的list是怎么實(shí)現(xiàn)的,我說用ziplist+quicklist實(shí)現(xiàn)的,ziplist壓縮空間,quicklist實(shí)現(xiàn)鏈表。
10 sortedset怎么實(shí)現(xiàn)的,使用dict+skiplist實(shí)現(xiàn)的,問我skiplist的數(shù)據(jù)結(jié)構(gòu),大概說了下是個(gè)實(shí)現(xiàn)簡單的快速查詢結(jié)構(gòu)。
Redis 底層用到了哪些數(shù)據(jù)結(jié)構(gòu)?使用 Redis 的 set 來做過什么?
Redis 使用過程中遇到什么問題?搭建過 Redis 集群嗎?
消息隊(duì)列:
常用的消息隊(duì)列設(shè)計(jì)和適用的各種場景;
kafka的原理,kafka作為消息隊(duì)列和redis的區(qū)別;
一個(gè)topic中的partition是不是一定散布在同一個(gè)broker中?
如果要保證消息全局有序,怎么做?
leader選舉是怎么選的?
kafka中consumer怎么保持狀態(tài)的?
kafka是哪個(gè)公司出的?(還真老有人問)
有沒有用過一些消息中間件
了解什么消息隊(duì)列,rmq和kafka,沒細(xì)問
操作系統(tǒng):
經(jīng)常問的就是linux指令,死鎖的各種問題,虛擬內(nèi)存什么的,這塊掌握的不是很好。
linux命令:打印中間一列
ab1 ab ab2
cd1 cd cd2
ef1 ef ef2
linux常考指令
操作系統(tǒng)
- 操作系統(tǒng)的競態(tài)?自旋鎖說一下
- 如何實(shí)現(xiàn)線程的同步?線程的上下文有哪些東西?
- 查看文件打開的句柄