共計(jì) 5058 個(gè)字符,預(yù)計(jì)需要花費(fèi) 13 分鐘才能閱讀完成。
本篇內(nèi)容介紹了“mysql 相關(guān)的面試題有哪些”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓丸趣 TV 小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
1. MYISAM 和 INNODB 的不同?
答:主要有以下幾點(diǎn)區(qū)別:
a)構(gòu)造上的區(qū)別
MyISAM 在磁盤(pán)上存儲(chǔ)成三個(gè)文件,其中.frm 文件存儲(chǔ)表定義;.MYD (MYData) 為數(shù)據(jù)文件;.MYI (MYIndex)為索引文件。
而 innodb 是由.frm 文件、表空間(分為獨(dú)立表空間或者共享表空間)和日志文件(redo log)組成。
b)事務(wù)上的區(qū)別
myisam 不支持事務(wù);而 innodb 支持事務(wù)。
c) 鎖上的區(qū)別
myisam 使用的是表鎖;而 innodb 使用的行鎖(當(dāng)然 innodb 也支持表鎖)。
表級(jí)鎖:直接鎖定整張表,在鎖定期間,其他進(jìn)程無(wú)法對(duì)該表進(jìn)行寫(xiě)操作,如果設(shè)置的是寫(xiě)鎖,那么其他進(jìn)程讀也不允許,因此 myisam 支持的并發(fā)量低,但 myisam 不會(huì)出現(xiàn)死鎖;
行級(jí)鎖:只對(duì)指定的行進(jìn)行鎖定,其他進(jìn)程還是可以對(duì)表中的其他行進(jìn)行操作的。因此行鎖能大大的減少數(shù)據(jù)庫(kù)操作的沖突,但有時(shí)會(huì)導(dǎo)致死鎖。
d) 是否支持外鍵的區(qū)別
myisam 不支持外鍵,innodb 支持外鍵
e) select count(*) 的區(qū)別
對(duì)于沒(méi)有 where 的 count(*) 使用 MyISAM 要比 InnoDB 快得多。因?yàn)?MyISAM 內(nèi)置了一個(gè)計(jì)數(shù)器,count(*)時(shí)它直接從計(jì)數(shù)器中讀,而 InnoDB 必須掃描全表。
f)myisam 只把索引都 load 到內(nèi)存中,而 innodb 存儲(chǔ)引擎是把數(shù)據(jù)和索引都 load 到內(nèi)存中
2. 公司現(xiàn)有的數(shù)據(jù)庫(kù)架構(gòu),總共有幾組 mysql 庫(kù)?
答:我們公司現(xiàn)在有兩組 MySQL。其中一套是生產(chǎn)庫(kù),一套是測(cè)試庫(kù)。
生產(chǎn)庫(kù)和測(cè)試庫(kù)都是用的 mha + 半同步復(fù)制做的高可用。
我們所有的項(xiàng)目 web 前端量(大概有 10 個(gè)項(xiàng)目)指向的都是一個(gè)機(jī)器上的 mysql 實(shí)例。因?yàn)槲覀兪莻鹘y(tǒng)行業(yè),并發(fā)訪問(wèn)量并不是很大,所以目前我們的生產(chǎn) mysql 數(shù)據(jù)庫(kù)未出現(xiàn)性能問(wèn)題。
3. 如何提高 insert 的性能?
答:有如下方法:
a)合并多條 insert 為一條,即:insert into t values(a,b,c), (d,e,f) ,,,
原因分析:主要原因是多條 insert 合并后日志量(MySQL 的 binlog 和 innodb 的事務(wù)讓日志)減少了,降低日志刷盤(pán)的數(shù)據(jù)量和頻率,從而提高效率。通過(guò)合并 SQL 語(yǔ)句,同時(shí)也能減少 SQL 語(yǔ)句解析的次數(shù),減少網(wǎng)絡(luò)傳輸?shù)?IO。
b)修改參數(shù) bulk_insert_buffer_size,調(diào)大批量插入的緩存;
c)設(shè)置 innodb_flush_log_at_trx_commit = 0,相對(duì)于 innodb_flush_log_at_trx_commit = 1 可以十分明顯的提升導(dǎo)入速度;
(備注:innodb_flush_log_at_trx_commit 參數(shù)對(duì) InnoDB Log 的寫(xiě)入性能有非常關(guān)鍵的影響。該參數(shù)可以設(shè)置為 0,1,2,解釋如下:
0:log buffer 中的數(shù)據(jù)將以每秒一次的頻率寫(xiě)入到 log file 中,且同時(shí)會(huì)進(jìn)行文件系統(tǒng)到磁盤(pán)的同步操作,但是每個(gè)事務(wù)的 commit 并不會(huì)觸發(fā)任何 log buffer 到 log file 的刷新或者文件系統(tǒng)到磁盤(pán)的刷新操作;
1:在每次事務(wù)提交的時(shí)候?qū)?log buffer 中的數(shù)據(jù)都會(huì)寫(xiě)入到 log file,同時(shí)也會(huì)觸發(fā)文件系統(tǒng)到磁盤(pán)的同步;
2:事務(wù)提交會(huì)觸發(fā) log buffer 到 log file 的刷新,但并不會(huì)觸發(fā)磁盤(pán)文件系統(tǒng)到磁盤(pán)的同步。此外,每秒會(huì)有一次文件系統(tǒng)到磁盤(pán)同步操作。
)
d)手動(dòng)使用事務(wù)
因?yàn)?mysql 默認(rèn)是 autocommit 的,這樣每插入一條數(shù)據(jù),都會(huì)進(jìn)行一次 commit;所以,為了減少創(chuàng)建事務(wù)的消耗,我們可用手工使用事務(wù),即 START TRANSACTION;insert。。,insert。。commit;即執(zhí)行多個(gè) insert 后再一起提交;一般 1000 條 insert 提交一次。
4. 和上一個(gè)問(wèn)題相關(guān),如果 insert 等 dml 語(yǔ)句的性能有問(wèn)題的話,或者其他問(wèn)題的存在,可能造成同步延遲,所以如何有效避免同步延遲的出現(xiàn)?
答:MySQL 主從同步延遲的最主要原因就是主庫(kù)是多線程寫(xiě),而從庫(kù)只有一個(gè)線程(即 slave_sql_running)來(lái)同步,所以在主庫(kù)中如果有一個(gè) ddl 或 dml 操作執(zhí)行 10 分鐘,那么這個(gè)操作在從庫(kù)上同樣需要執(zhí)行 10 分鐘。有人可能會(huì)問(wèn):“主庫(kù)上那個(gè)相同的 DDL、DML 也需要執(zhí)行 10 分,為什么 slave 會(huì)延時(shí)?”,答案是 master 可以并發(fā),Slave_SQL_Running 線程卻不可以。
所以,為了減少?gòu)膸?kù)的延時(shí),我們需要平時(shí)做好以下維護(hù):
a)盡量讓主庫(kù)的 dml 或者 ddl 快速執(zhí)行,如提高 insert 的效率(方法見(jiàn)上);
b)為了安全,有人可能會(huì)將主庫(kù)的 sync_binlog 設(shè)置為 1,innodb_flush_log_at_trx_commit 也設(shè)置為 1 之類的,而 slave 則不需要這么高的數(shù)據(jù)安全,完全可以講 sync_binlog 設(shè)置為 0 或者關(guān)閉 binlog,innodb_flushlog 也可以設(shè)置為 0,來(lái)提高從庫(kù) sql 的執(zhí)行效率。
(備注:sync_binlog 是控制 binlog_cache 刷新到磁盤(pán) binlog 頻率的,而 innodb_flush_log_at_trx_commit 是控制 redo log buffer 刷新到磁盤(pán) redolog 頻率的。sync_binlog=0,表示 MySQL 不控制 binlog 的刷新,由文件系統(tǒng)自己控制它的緩存的刷新。如果 sync_binlog 0,表示每 sync_binlog 次事務(wù)提交,MySQL 調(diào)用文件系統(tǒng)的刷新操作將緩存刷下去。最安全的就是 sync_binlog= 1 了,表示每次事務(wù)提交,MySQL 都會(huì)把 binlog 刷下去。這樣的話,在數(shù)據(jù)庫(kù)所在的主機(jī)操作系統(tǒng)損壞或者突然掉電的情況下,系統(tǒng)才有可能丟失 1 個(gè)事務(wù)的數(shù)據(jù)。所以 sync_binlog= 1 保證了數(shù)據(jù)安全,但是性能最差。)
c)使用比主庫(kù)更好的硬件設(shè)備作為 slave
d) 使用 mysql 5.6 新參數(shù) slave_parallel_workers,使從庫(kù)多線程,不過(guò),slave_parallel_workers 只能支持一個(gè)實(shí)例下多個(gè) database 間的并發(fā)復(fù)制,并不能真正做到多表并發(fā)復(fù)制。因此在較大并發(fā)負(fù)載時(shí),slave 還是沒(méi)有辦法及時(shí)追上 master,需要想辦法進(jìn)行優(yōu)化。
e)升級(jí) Mysql 到 5.7,因?yàn)?mysql 5.7 支持真正意義的從庫(kù)多線程了,即主庫(kù)多少線程,從庫(kù)也多少線程。mysql 5.7 號(hào)稱主從復(fù)制永不丟數(shù)據(jù)(一直沒(méi)時(shí)間試用過(guò))。
5. 有沒(méi)有用 GTID, 對(duì) GTID 了解嗎?
答:用過(guò) GTID。曾經(jīng)民航局的一個(gè)項(xiàng)目就用的是 GTID。
GTID 是 mysql 5.6 的新東西,用事務(wù)提交號(hào)替換 binlog 的位置號(hào)。不過(guò) GTID 這個(gè)東西在 5.6 還是有很多局限性的,個(gè)人不建議用。
GTID 的全稱為 global transaction identifier ,可以翻譯為全局事務(wù)標(biāo)示符。
GTID 由兩部分組成:GTID = source_id:transaction_id
source_id 用于標(biāo)示源服務(wù)器,用 server_uuid 來(lái)表示,這個(gè)值在第一次啟動(dòng)時(shí)生成,并寫(xiě)入到配置文件 data/auto.cnf 中
transaction_id 則是根據(jù)在源服務(wù)器上第幾個(gè)提交的事務(wù)來(lái)確定。
6. Innodb 是行鎖,那什么時(shí)候會(huì)產(chǎn)生行鎖,什么情況下會(huì)變成表鎖?
答:一般情況下,innodb 只對(duì)指定的行進(jìn)行鎖定,其他進(jìn)程還是可以對(duì)表中的其他行進(jìn)行操作的,因此,這時(shí)候 innodb 加的就是行鎖;
但是,如果在執(zhí)行一個(gè) SQL 語(yǔ)句時(shí) MySQL 不能確定要掃描的范圍,InnoDB 表同樣會(huì)鎖全表,例如 update table set num=1 where name like“%aaa%”。
7. 使用過(guò)其他分支版本的數(shù)據(jù)庫(kù)嗎?percona,mariadb 等。對(duì) percona 的 pxc 集群了解嗎?
答:除了 oracle 旗下的 MySQL 外,我還使用過(guò) percona server。percona 是在源生 mysql 的基礎(chǔ)上,進(jìn)行了優(yōu)化和改進(jìn),所以 percona 的性能比 mysql 更好。目前,我知道 percona 提供免費(fèi)的線程池功能,而社區(qū)版的 mysql 沒(méi)有線程池的功能(當(dāng)然,企業(yè)版的 mysql 是有線程池的,但是需要收費(fèi));另外 percona 還支持 NUMA 等功能。
我熟悉 pxc,我曾經(jīng)在測(cè)試環(huán)境搭建過(guò) pxc,但是沒(méi)有在生產(chǎn)上使用,因?yàn)槟壳笆褂?pxc 的企業(yè)不是很多,目前我知道搜狐在用 pxc。
pxc 是摒棄 mysql 主從的概念,即對(duì)于 pxc 來(lái)說(shuō),每個(gè)節(jié)點(diǎn)都可以讀寫(xiě),并且寫(xiě)一份數(shù)據(jù),其他節(jié)點(diǎn)會(huì)同時(shí)擁有,這是一種同步的復(fù)制方案(區(qū)別于 Mysql 主從的異步復(fù)制)
8. 除了 mysql,還了解過(guò)其他數(shù)據(jù)庫(kù)嗎?oracle,redis,mongodb 等。
答:除了 mysql,我還熟悉 oracle,對(duì) oracle 有兩年的使用經(jīng)驗(yàn)。
不過(guò),我對(duì) redis 和 mongodb 沒(méi)有接觸過(guò),如果工作需要,我會(huì)學(xué)習(xí)他們。
9. 工作中遇到的最大的問(wèn)題以及做的最好的工作?
答:自由發(fā)揮
10. 分庫(kù)分表有沒(méi)有用到,怎么實(shí)現(xiàn)的?
答:目前,根據(jù)我們的業(yè)務(wù)量,還沒(méi)有使用分庫(kù)分表。但是我有在關(guān)注 MySQL 的分布式方案,以前 mysql 分布式比較常用的方法是用阿里巴巴的 cobar,將一張表水平拆分成多份分別放入不同的庫(kù)來(lái)實(shí)現(xiàn)表的水平拆分,或?qū)⒉煌谋矸湃氩煌膸?kù),但是后來(lái)發(fā)現(xiàn) cobar 有一個(gè)問(wèn)題一直不能很好的解決。目前,我關(guān)注到有很多人用 mycat 替換了 cobar。
11. 新創(chuàng)建的數(shù)據(jù)庫(kù),需要調(diào)整哪些參數(shù)?
答:調(diào)整兩方面的參數(shù),即調(diào)整操作系統(tǒng)的和數(shù)據(jù)庫(kù) my.cnf 的:
a)操作系統(tǒng)的參數(shù)
linux 參數(shù)系統(tǒng)的默認(rèn)參數(shù)很多都是很保守的,所以需要根據(jù)服務(wù)器性能將一些參數(shù)進(jìn)行加大,如我會(huì)調(diào)整 nofile(最大文件句柄數(shù))和 nproc(最大線程數(shù)),將其放到最大;我會(huì)將 vm.swappiness 設(shè)置為 0,表示最大限度使用物理內(nèi)存,然后才是 swap 空間;我會(huì)將 net.ipv4.tcp_tw_reuse 設(shè)置為 1,表示將 netstat 中出現(xiàn)的 TIME-WAIT 狀態(tài)的 sockets 重用到新的 TCP 連接上 … 等等
b)數(shù)據(jù)庫(kù)的參數(shù)
對(duì)于 mysql 來(lái)說(shuō),my.cnf 的參數(shù)調(diào)整非常重要,如果采用默認(rèn)值,那么是很難發(fā)揮 mysql 性能的。一般我會(huì)特別關(guān)注 innodb_buffer_pool 這個(gè)值,該值一般設(shè)置為物理內(nèi)存的 70%, 這樣就可以把 mysql 的表和索引最大限度的 load 到內(nèi)存中,從而使 mysql 數(shù)據(jù)庫(kù)性能得到大的提升;另外,我還特別關(guān)注 sync_binlog 和 innodb_flush_log_at_trx_commit 這兩個(gè)值的設(shè)置,具體含義見(jiàn)上;還有 max_user_connections,我一般將該值設(shè)置為 2000;還有 innodb_lock_wait_timeout,看程序是長(zhǎng)連接還是短連接,一般我會(huì)設(shè)置為 60 秒;還有 innodb_log_file_size,這個(gè)值也設(shè)置的大一點(diǎn),我一般設(shè)置的為 500M 或 1G。
12. mysql 的權(quán)限怎么管理?
答:只給 insert,update,select 和 delete 四個(gè)權(quán)限即可。有時(shí)候 delete 都不給。
13. 有開(kāi)發(fā)基礎(chǔ)嗎?
答:沒(méi)有
14. 如果發(fā)現(xiàn) CPU,或者 IO 壓力很大,怎么定位問(wèn)題?
答:
1、首先我會(huì)用 top 命令和 iostat 命令,定位是什么進(jìn)程在占用 cpu 和磁盤(pán) io;
2、如果是 mysql 的問(wèn)題,我會(huì)登錄到數(shù)據(jù)庫(kù),通過(guò) show full processlist 命令,看現(xiàn)在數(shù)據(jù)庫(kù)在執(zhí)行什么 sql 語(yǔ)句,是否有語(yǔ)句長(zhǎng)時(shí)間執(zhí)行使數(shù)據(jù)庫(kù)卡住;
3、執(zhí)行 show innodb engine status 命令,查看數(shù)據(jù)庫(kù)是否有鎖資源爭(zhēng)用;
4、查看 mysql 慢查詢?nèi)罩荆词欠裼新?sql;
5、找到引起數(shù)據(jù)庫(kù)占用資源高的語(yǔ)句,進(jìn)行優(yōu)化,該建索引的建索引,索引不合適的刪索引,或者根據(jù)情況 kill 掉耗費(fèi)資源的 sql 語(yǔ)句等
“mysql 相關(guān)的面試題有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注丸趣 TV 網(wǎng)站,丸趣 TV 小編將為大家輸出更多高質(zhì)量的實(shí)用文章!