1. 程式人生 > >樂視mysql面試題【轉】

樂視mysql面試題【轉】

需要 好的 硬件 select 業務 以及 局限性 測試環境 獨立

最近,朋友去樂視面試了mysql DBA,以下是我據整理的樂視mysql面試題答案,供大家參考

1. MYISAM和INNODB的不同?
答:主要有以下幾點區別:
a)構造上的區別
MyISAM在磁盤上存儲成三個文件,其中.frm文件存儲表定義;.MYD (MYData)為數據文件;.MYI (MYIndex)為索引文件。
而innodb是由.frm文件、表空間(分為獨立表空間或者共享表空間)和日誌文件(redo log)組成。
b)事務上的區別
myisam不支持事務;而innodb支持事務。
c)鎖上的區別
myisam使用的是表鎖;而innodb使用的行鎖(當然innodb也支持表鎖)。

表級鎖:直接鎖定整張表,在鎖定期間,其他進程無法對該表進行寫操作,如果設置的是寫鎖,那麽其他進程讀也不允許,因此myisam支持的並發量低,但myisam不會出現死鎖;
行級鎖:只對指定的行進行鎖定,其他進程還是可以對表中的其他行進行操作的。因此行鎖能大大的減少數據庫操作的沖突,但有時會導致死鎖。
d)是否支持外鍵的區別
myisam不支持外鍵,innodb支持外鍵
e) select count(*)的區別
對於沒有where的count(*)使用MyISAM要比InnoDB快得多。因為MyISAM內置了一個計數器,count(*)時它直接從計數器中讀,而InnoDB必須掃描全表。
f)myisam只把索引都load到內存中,而innodb存儲引擎是把數據和索引都load到內存中


2. 公司現有的數據庫架構,總共有幾組mysql庫?
答:我們公司現在有兩組MySQL。其中一套是生產庫,一套是測試庫。
生產庫和測試庫都是用的mha +半同步復制做的高可用。
我們所有的項目web前端量(大概有10個項目)指向的都是一個機器上的mysql實例。因為我們是傳統行業,並發訪問量並不是很大,所以目前我們的生產mysql數據庫未出現性能問題。

3. 如何提高insert的性能?
答:有如下方法:
a)合並多條 insert 為一條,即: insert into t values(a,b,c), (d,e,f) ,,,

原因分析:主要原因是多條insert合並後日誌量(MySQL的binlog和innodb的事務讓日誌) 減少了,降低日誌刷盤的數據量和頻率,從而提高效率。通過合並SQL語句,同時也能減少SQL語句解析的次數,減少網絡傳輸的IO。
b)修改參數 bulk_insert_buffer_size, 調大批量插入的緩存;
c)設置 innodb_flush_log_at_trx_commit = 0 ,相對於 innodb_flush_log_at_trx_commit = 1 可以十分明顯的提升導入速度;
(備註:innodb_flush_log_at_trx_commit 參數對 InnoDB Log 的寫入性能有非常關鍵的影響。該參數可以設置為0,1,2,解釋如下:
   0:log buffer中的數據將以每秒一次的頻率寫入到log file中,且同時會進行文件系統到磁盤的同步操作,但是每個事務的commit並不會觸發任何log buffer 到log file 的刷新或者文件系統到磁盤的刷新操作;
   1:在每次事務提交的時候將log buffer 中的數據都會寫入到log file,同時也會觸發文件系統到磁盤的同步;
   2:事務提交會觸發log buffer 到log file的刷新,但並不會觸發磁盤文件系統到磁盤的同步。此外,每秒會有一次文件系統到磁盤同步操作。

d)手動使用事務
因為mysql默認是autocommit的,這樣每插入一條數據,都會進行一次commit;所以,為了減少創建事務的消耗,我們可用手工使用事務,即START TRANSACTION;insert 。。,insert。。 commit;即執行多個insert後再一起提交;一般1000條insert 提交一次。

4. 和上一個問題相關,如果insert等dml語句的性能有問題的話,或者其他問題的存在,可能造成同步延遲,所以如何有效避免同步延遲的出現?

答:MySQL主從同步延遲的最主要原因就是主庫是多線程寫,而從庫只有一個線程(即slave_sql_running)來同步,所以在主庫中如果有一個ddl或dml操作執行10分鐘,那麽這個操作在從庫上同樣需要執行10分鐘。有人可能會問:“主庫上那個相同的DDL、DML也需要執行10分,為什麽slave會延時?”,答案是master可以並發,Slave_SQL_Running線程卻不可以。
所以,為了減少從庫的延時,我們需要平時做好以下維護:
a)盡量讓主庫的dml或者ddl快速執行,如提高insert的效率(方法見上);
b) 為了安全,有人可能會將主庫的sync_binlog設置為1,innodb_flush_log_at_trx_commit也設置為1之類的,而slave則不需要這麽高的數據安全,完全可以講sync_binlog設置為0或者關閉binlog,innodb_flushlog也可以設置為0,來提高從庫sql的執行效率。
(備註:sync_binlog是控制binlog_cache刷新到磁盤binlog頻率的,而innodb_flush_log_at_trx_commit是控制redo log buffer刷新到磁盤redolog頻率的。sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系統自己控制它的緩存的刷新。如果sync_binlog>0,表示每sync_binlog次事務提交,MySQL調用文件系統的刷新操作將緩存刷下去。最安全的就是sync_binlog=1了,表示每次事務提交,MySQL都會把binlog刷下去。這樣的話,在數據庫所在的主機操作系統損壞或者突然掉電的情況下,系統才有可能丟失1個事務的數據。所以sync_binlog=1保證了數據安全,但是性能最差。)
c)使用比主庫更好的硬件設備作為slave
d) 使用mysql 5.6新參數 slave_parallel_workers ,使從庫多線程,不過,slave_parallel_workers只能支持一個實例下多個 database 間的並發復制,並不能真正做到多表並發復制。因此在較大並發負載時,slave還是沒有辦法及時追上master,需要想辦法進行優化。
e)升級Mysql到5.7,因為mysql 5.7支持真正意義的從庫多線程了,即主庫多少線程,從庫也多少線程。mysql 5.7號稱主從復制永不丟數據(一直沒時間試用過)。


5. 有沒有用GTID,對GTID了解嗎?
答:用過GTID。曾經民航局的一個項目就用的是GTID。
GTID是mysql 5.6的新東西,用事務提交號替換binlog的位置號。不過GTID這個東西在5.6還是有很多局限性的,個人不建議用。
GTID的全稱為 global transaction identifier , 可以翻譯為全局事務標示符。
GTID由兩部分組成:GTID = source_id:transaction_id
source_id用於標示源服務器,用server_uuid來表示,這個值在第一次啟動時生成,並寫入到配置文件data/auto.cnf中
transaction_id則是根據在源服務器上第幾個提交的事務來確定。

6. Innodb是行鎖,那什麽時候會產生行鎖,什麽情況下會變成表鎖?
答:一般情況下,innodb只對指定的行進行鎖定,其他進程還是可以對表中的其他行進行操作的,因此,這時候innodb加的就是行鎖;
但是,如果在執行一個SQL語句時MySQL不能確定要掃描的範圍,InnoDB表同樣會鎖全表,例如update table set num=1 where name like “%aaa%”。

7. 使用過其他分支版本的數據庫嗎?percona,mariadb等。對percona的pxc集群了解嗎?

答:除了oracle旗下的MySQL外,我還使用過percona server。percona是在源生mysql的基礎上,進行了優化和改進,所以percona的性能比mysql更好。目前,我知道percona提供免費的線程池功能,而社區版的mysql沒有線程池的功能(當然,企業版的mysql是有線程池的,但是需要收費);另外percona還支持NUMA等功能。
我熟悉pxc,我曾經在測試環境搭建過pxc,但是沒有在生產上使用,因為目前使用pxc的企業不是很多,目前我知道搜狐在用pxc。
pxc是摒棄mysql主從的概念,即對於pxc來說,每個節點都可以讀寫,並且寫一份數據,其他節點會同時擁有,這是一種同步的復制方案(區別於Mysql主從的異步復制)


8. 除了mysql,還了解過其他數據庫嗎?oracle,redis,mongodb等。

答:除了mysql,我還熟悉oracle,對oracle有兩年的使用經驗。
不過,我對redis和mongodb沒有接觸過,如果工作需要,我會學習他們。


9. 工作中遇到的最大的問題以及做的最好的工作?
答:自由發揮

10. 分庫分表有沒有用到,怎麽實現的?

答:目前,根據我們的業務量,還沒有使用分庫分表。但是我有在關註MySQL的分布式方案,以前mysql分布式比較常用的方法是用阿裏巴巴的cobar,將一張表水平拆分成多份分別放入不同的庫來實現表的水平拆分,或將不同的表放入不同的庫,但是後來發現cobar有一個問題一直不能很好的解決。目前,我關註到有很多人用mycat替換了cobar。


11. 新創建的數據庫,需要調整哪些參數?
答:調整兩方面的參數,即調整操作系統的和數據庫my.cnf的:
a)操作系統的參數
linux參數系統的默認參數很多都是很保守的,所以需要根據服務器性能將一些參數進行加大,如我會調整nofile(最大文件句柄數)和nproc(最大線程數),將其放到最大;我會將vm.swappiness設置為0,表示最大限度使用物理內存,然後才是 swap空間;我會將net.ipv4.tcp_tw_reuse 設置為1,表示將netstat中出現的TIME-WAIT狀態的sockets重用到新的TCP連接上...等等
b)數據庫的參數
對於mysql來說,my.cnf的參數調整非常重要,如果采用默認值,那麽是很難發揮mysql性能的。一般我會特別關註innodb_buffer_pool這個值,該值一般設置為物理內存的70%,這樣就可以把mysql的表和索引最大限度的load到內存中,從而使mysql數據庫性能得到大的提升;另外,我還特別關註sync_binlog和innodb_flush_log_at_trx_commit這兩個值的設置,具體含義見上;還有max_user_connections ,我一般將該值設置為2000;還有innodb_lock_wait_timeout,看程序是長連接還是短連接,一般我會設置為60秒;還有innodb_log_file_size ,這個值也設置的大一點,我一般設置的為500M或1G。

12. mysql的權限怎麽管理?
答:只給insert,update,select和delete四個權限即可。有時候delete都不給。


13. 有開發基礎嗎?
答:沒有


14. 如果發現CPU,或者IO壓力很大,怎麽定位問題?

答:
1、首先我會用top命令和iostat命令,定位是什麽進程在占用cpu和磁盤io;
2、如果是mysql的問題,我會登錄到數據庫,通過show full processlist命令,看現在數據庫在執行什麽sql語句,是否有語句長時間執行使數據庫卡住;
3、執行show innodb engine status命令,查看數據庫是否有鎖資源爭用;
4、查看mysql慢查詢日誌,看是否有慢sql;
5、找到引起數據庫占用資源高的語句,進行優化,該建索引的建索引,索引不合適的刪索引,或者根據情況kill掉耗費資源的sql語句等

轉自

樂視mysql面試題-czxin788-ITPUB博客
http://blog.itpub.net/28916011/viewspace-2093197/

樂視mysql面試題【轉】