1斩祭、MySQL的復制原理以及流程
(1)弟翘、復制基本原理流程
1. 主:binlog線程——記錄下所有改變了數(shù)據庫數(shù)據的語句身笤,放進master上的binlog中左冬;
2. 從:io線程——在使用start slave 之后,負責從master上拉取 binlog 內容范抓,放進 自己的relay log中骄恶;
3. 從:sql執(zhí)行線程——執(zhí)行relay log中的語句;
(2)匕垫、MySQL復制的線程有幾個及之間的關聯(lián)
MySQL 的復制是基于如下 3 個線程的交互( 多線程復制里面應該是 4 類線程):
1. Master 上面的 binlog dump 線程僧鲁,該線程負責將 master 的 binlog event 傳到slave;
2. Slave 上面的 IO 線程象泵,該線程負責接收 Master 傳過來的 binlog寞秃,并寫入 relay log;
3. Slave 上面的 SQL 線程偶惠,該線程負責讀取 relay log 并執(zhí)行春寿;
4. 如果是多線程復制,無論是 5.6 庫級別的假多線程還是 MariaDB 或者 5.7 的真正的多線程復制忽孽, SQL 線程只做 coordinator绑改,只負責把 relay log 中的 binlog讀出來然后交給 worker 線程, woker 線程負責具體 binlog event 的執(zhí)行兄一;
(3)厘线、MySQL如何保證復制過程中數(shù)據一致性及減少數(shù)據同步延時
一致性主要有以下幾個方面:
1.在 MySQL5.5 以及之前, slave 的 SQL 線程執(zhí)行的 relay log 的位置只能保存在文件( relay-log.info)里面出革,并且該文件默認每執(zhí)行 10000 次事務做一次同步到磁盤造壮, 這意味著 slave 意外 crash 重啟時, SQL 線程執(zhí)行到的位置和數(shù)據庫的數(shù)據是不一致的骂束,將導致復制報錯耳璧,如果不重搭復制,則有可能會
導致數(shù)據不一致展箱。 MySQL 5.6 引入參數(shù) relay_log_info_repository旨枯,將該參數(shù)設置為 TABLE 時, MySQL 將 SQL 線程執(zhí)行到的位置存到mysql.slave_relay_log_info 表析藕,這樣更新該表的位置和 SQL 線程執(zhí)行的用戶事務綁定成一個事務召廷,這樣 slave 意外宕機后, slave 通過 innodb 的崩潰
恢復可以把 SQL 線程執(zhí)行到的位置和用戶事務恢復到一致性的狀態(tài)账胧。
2. MySQL 5.6 引入 GTID 復制竞慢,每個 GTID 對應的事務在每個實例上面最多執(zhí)行一次, 這極大地提高了復制的數(shù)據一致性治泥;
3. MySQL 5.5 引入半同步復制筹煮, 用戶安裝半同步復制插件并且開啟參數(shù)后,設置超時時間居夹,可保證在超時時間內如果 binlog 不傳到 slave 上面败潦,那么用戶提交事務時不會返回,直到超時后切成異步復制准脂,但是如果切成異步之前用戶線程提交時在 master 上面等待的時候劫扒,事務已經提交,該事務對 master
上面的其他 session 是可見的狸膏,如果這時 master 宕機沟饥,那么到 slave 上面該事務又不可見了,該問題直到 5.7 才解決湾戳;
4. MySQL 5.7 引入無損半同步復制贤旷,引入參 rpl_semi_sync_master_wait_point,該參數(shù)默認為 after_sync砾脑,指的是在切成半同步之前幼驶,事務不提交,而是接收到 slave 的 ACK 確認之后才提交該事務韧衣,從此盅藻,復制真正可以做到無損的了。
5.可以再說一下 5.7 的無損復制情況下畅铭, master 意外宕機萧求,重啟后發(fā)現(xiàn)有 binlog沒傳到 slave 上面,這部分 binlog 怎么辦顶瞒?夸政??分 2 種情況討論榴徐, 1 宕機時已經切成異步了守问, 2 是宕機時還沒切成異步?坑资?耗帕? 這個怎么判斷宕機時有沒有切成異步呢?袱贮?仿便? 分別怎么處理??嗽仪?
延時性:
5.5 是單線程復制荒勇, 5.6 是多庫復制(對于單庫或者單表的并發(fā)操作是沒用的), 5.7 是真正意義的多線程復制闻坚,它的原理是基于 group commit沽翔, 只要
master 上面的事務是 group commit 的,那 slave 上面也可以通過多個 worker線程去并發(fā)執(zhí)行窿凤。 和 MairaDB10.0.0.5 引入多線程復制的原理基本一樣仅偎。
(4)、工作遇到的復制 bug 的解決方法
5.6 的多庫復制有時候自己會停止雳殊,我們寫了一個腳本重新 start slave;待補充…
2橘沥、MySQL中myisam與innodb的區(qū)別,至少5點
(1)夯秃、問5點不同
1.InnoDB支持事物威恼,而MyISAM不支持事物
2.InnoDB支持行級鎖,而MyISAM支持表級鎖
3.InnoDB支持MVCC, 而MyISAM不支持
4.InnoDB支持外鍵寝并,而MyISAM不支持
5.InnoDB不支持全文索引箫措,而MyISAM支持。
6.InnoDB不能通過直接拷貝表文件的方法拷貝表到另外一臺機器衬潦, myisam 支持
7.InnoDB表支持多種行格式斤蔓, myisam 不支持
8.InnoDB是索引組織表, myisam 是堆表
(2)镀岛、innodb引擎的4大特性
1.插入緩沖(insert buffer)
2.二次寫(double write)
3.自適應哈希索引(ahi)
4.預讀(read ahead)
(3)弦牡、各種不同 mysql 版本的Innodb的改進
MySQL5.6 下 Innodb 引擎的主要改進:( 1) online DDL( 2) memcached NoSQL 接口( 3) transportable tablespace( alter table discard/import tablespace)( 4) MySQL 正常關閉時,可以 dump 出 buffer pool 的( space漂羊, page_no)驾锰,重啟時 reload,加快預熱速度( 5) 索引和表的統(tǒng)計信息持久化到 mysql.innodb_table_stats 和mysql.innodb_index_stats走越,可提供穩(wěn)定的執(zhí)行計劃( 6) Compressed row format 支持壓縮表MySQL 5.7 innodb 引擎主要改進( 1) 修改 varchar 字段長度有時可以使用 online DDL( 2) Buffer pool 支持在線改變大型衷ァ( 3) Buffer pool 支持導出部分比例( 4) 支持新建 innodb tablespace,并可以在其中創(chuàng)建多張表( 5) 磁盤臨時表采用 innodb 存儲旨指,并且存儲在 innodb temp tablespace 里面赏酥,以前是 myisam 存儲( 6) 透明表空間壓縮功能
(4)、2者select ?count(*)哪個更快谆构,為什么
myisam更快裸扶,因為myisam內部維護了一個計數(shù)器,可以直接調取搬素。
(5)呵晨、2 者的索引的實現(xiàn)方式
都是 B+樹索引魏保, Innodb 是索引組織表, myisam 是堆表摸屠, 索引組織表和堆表的區(qū)別要熟悉
3谓罗、MySQL中varchar與char的區(qū)別以及varchar(50)中的50代表的涵義
(1)、varchar與char的區(qū)別
在單字節(jié)字符集下餐塘, char( N) 在內部存儲的時候總是定長, 而且沒有變長字段長度列表中皂吮。 在多字節(jié)字符集下面戒傻, char(N)如果存儲的字節(jié)數(shù)超過 N,那么 char( N)將和 varchar( N)沒有區(qū)別蜂筹。在多字節(jié)字符集下面需纳,如果存
儲的字節(jié)數(shù)少于 N,那么存儲 N 個字節(jié)艺挪,后面補空格不翩,補到 N 字節(jié)長度。 都存儲變長的數(shù)據和變長字段長度列表麻裳。 varchar(N)無論是什么字節(jié)字符集口蝠,都是變長的,即都存儲變長數(shù)據和變長字段長度列表津坑。
(2)妙蔗、varchar(50)中50的涵義
最多存放50個字符,varchar(50)和(200)存儲hello所占空間一樣疆瑰,但后者在排序時會消耗更多內存眉反,因為order by col采用fixed_length計算col長度(memory引擎也一樣)。在早期 MySQL 版本中穆役, 50 代表字節(jié)數(shù)寸五,現(xiàn)在代表字符數(shù)。
(3)耿币、int(20)中20的涵義
是指顯示字符的長度
不影響內部存儲梳杏,只是影響帶 zerofill 定義的 int 時,前面補多少個 0淹接,易于報表展示
(4)秘狞、mysql為什么這么設計
對大多數(shù)應用沒有意義,只是規(guī)定一些工具用來顯示字符的個數(shù)蹈集;int(1)和int(20)存儲和計算均一樣烁试;
(1)拢肆、有多少種日志
redo和undo
(2)减响、日志的存放形式
redo:在頁修改的時候靖诗,先寫到 redo log buffer 里面, 然后寫到 redo log 的文件系統(tǒng)緩存里面(fwrite)支示,然后再同步到磁盤文件( fsync)刊橘。
Undo:在 MySQL5.5 之前, undo 只能存放在 ibdata*文件里面颂鸿, 5.6 之后促绵,可以通過設置 innodb_undo_tablespaces 參數(shù)把 undo log 存放在 ibdata*之外。
(3)嘴纺、事務是如何通過日志來實現(xiàn)的败晴,說得越深入越好
基本流程如下:
因為事務在修改頁時,要先記 undo栽渴,在記 undo 之前要記 undo 的 redo尖坤, 然后修改數(shù)據頁,再記數(shù)據頁修改的 redo闲擦。 Redo(里面包括 undo 的修改) 一定要比數(shù)據頁先持久化到磁盤慢味。 當事務需要回滾時,因為有 undo墅冷,可以把數(shù)據頁回滾到前鏡像的
狀態(tài)纯路,崩潰恢復時,如果 redo log 中事務沒有對應的 commit 記錄寞忿,那么需要用 undo把該事務的修改回滾到事務開始之前感昼。 如果有 commit 記錄,就用 redo 前滾到該事務完成時并提交掉罐脊。
5定嗓、MySQL binlog的幾種日志錄入格式以及區(qū)別
(1)、 各種日志格式的涵義
1.Statement:每一條會修改數(shù)據的sql都會記錄在binlog中萍桌。優(yōu)點:不需要記錄每一行的變化宵溅,減少了binlog日志量,節(jié)約了IO上炎,提高性能恃逻。(相比row能節(jié)約多少性能 與日志量,這個取決于應用的SQL情況藕施,正常同一條記錄修改或者插入row格式所產生的日志量還小于Statement產生的日志量寇损,但是考慮到如果帶條 件的update操作,以及整表刪除裳食,alter表等操作矛市,ROW格式會產生大量日志,因此在考慮是否使用ROW格式日志時應該跟據應用的實際情況诲祸,其所 產生的日志量會增加多少浊吏,以及帶來的IO性能問題而昨。)缺點:由于記錄的只是執(zhí)行語句,為了這些語句能在slave上正確運行找田,因此還必須記錄每條語句在執(zhí)行的時候的 一些相關信息歌憨,以保證所有語句能在slave得到和在master端執(zhí)行時候相同 的結果。另外mysql 的復制,像一些特定函數(shù)功能墩衙,slave可與master上要保持一致會有很多相關問題(如sleep()函數(shù)务嫡, last_insert_id(),以及user-defined functions(udf)會出現(xiàn)問題).使用以下函數(shù)的語句也無法被復制:* LOAD_FILE()* UUID()* USER()* FOUND_ROWS()* SYSDATE() (除非啟動時啟用了 --sysdate-is-now 選項)同時在INSERT ...SELECT 會產生比 RBR 更多的行級鎖2.Row:不記錄sql語句上下文相關信息漆改,僅保存哪條記錄被修改心铃。優(yōu)點: binlog中可以不記錄執(zhí)行的sql語句的上下文相關的信息,僅需要記錄那一條記錄被修改成什么了籽懦。所以rowlevel的日志內容會非常清楚的記錄下 每一行數(shù)據修改的細節(jié)于个。而且不會出現(xiàn)某些特定情況下的存儲過程氛魁,或function暮顺,以及trigger的調用和觸發(fā)無法被正確復制的問題缺點:所有的執(zhí)行的語句當記錄到日志中的時候,都將以每行記錄的修改來記錄秀存,這樣可能會產生大量的日志內容,比 如一條update語句捶码,修改多條記錄,則binlog中每一條修改都會有記錄或链,這樣造成binlog日志量會很大惫恼,特別是當執(zhí)行alter table之類的語句的時候,由于表結構修改澳盐,每條記錄都發(fā)生改變祈纯,那么該表每一條記錄都會記錄到日志中。3.Mixedlevel: 是以上兩種level的混合使用叼耙,一般的語句修改使用statment格式保存binlog腕窥,如一些函數(shù),statement無法完成主從復制的操作筛婉,則 采用row格式保存binlog,MySQL會根據執(zhí)行的每一條具體的sql語句來區(qū)分對待記錄的日志形式簇爆,也就是在Statement和Row之間選擇 一種.新版本的MySQL中隊row level模式也被做了優(yōu)化,并不是所有的修改都會以row level來記錄爽撒,像遇到表結構變更的時候就會以statement模式來記錄入蛆。至于update或者delete等修改數(shù)據的語句,還是會記錄所有行的變更硕勿。
?(2)哨毁、適用場景
在一條 SQL 操作了多行數(shù)據時, statement 更節(jié)省空間源武, row 更占用空間挑庶。但是 row模式更可靠言秸。
(3)、結合第一個問題迎捺,每一種日志格式在復制中的優(yōu)劣
Statement 可能占用空間會相對小一些举畸,傳送到 slave 的時間可能也短,但是沒有 row模式的可靠凳枝。 Row 模式在操作多行數(shù)據時更占用空間抄沮, 但是可靠。
6岖瑰、下MySQL數(shù)據庫cpu飆升到500%的話他怎么處理叛买?
當 cpu 飆升到 500%時,先用操作系統(tǒng)命令 top 命令觀察是不是 mysqld 占用導致的蹋订,如果不是率挣,找出占用高的進程,并進行相關處理露戒。如果是 mysqld 造成的椒功, show processlist,看看里面跑的 session 情況智什,是不是有消耗資源的 sql 在運行动漾。找出消耗高的 sql,
看看執(zhí)行計劃是否準確荠锭, index 是否缺失旱眯,或者實在是數(shù)據量太大造成。一般來說证九,肯定要 kill 掉這些線程(同時觀察 cpu 使用率是否下降)删豺,等進行相應的調整(比如說加索引、改 sql愧怜、改內存參數(shù))之后呀页,再重新跑這些 SQL。也有可能是每個 sql 消耗資源并不多叫搁,但是突然之間赔桌,
有大量的 session 連進來導致 cpu 飆升,這種情況就需要跟應用一起來分析為何連接數(shù)會激增渴逻,再做出相應的調整疾党,比如說限制連接數(shù)等
(1)惨奕、explain出來的各種item的意義
id:每個被獨立執(zhí)行的操作的標志雪位,表示對象被操作的順序。一般來說梨撞, id 值大雹洗,先被執(zhí)行香罐;如果 id 值相同,則順序從上到下时肿。
select_type:查詢中每個 select 子句的類型庇茫。
table:名字,被操作的對象名稱螃成,通常的表名(或者別名)旦签,但是也有其他格式。
partitions:匹配的分區(qū)信息寸宏。
type:join 類型宁炫。
possible_keys:列出可能會用到的索引。
key:實際用到的索引氮凝。
key_len:用到的索引鍵的平均長度羔巢,單位為字節(jié)。
ref:表示本行被操作的對象的參照對象罩阵,可能是一個常量用 const 表示竿秆,也可能是其他表的
key 指向的對象,比如說驅動表的連接列永脓。
rows:估計每次需要掃描的行數(shù)袍辞。
filtered:rows*filtered/100 表示該步驟最后得到的行數(shù)(估計值)鞋仍。
extra:重要的補充信息常摧。
(2)、profile的意義以及使用場景
Profile 用來分析 sql 性能的消耗分布情況威创。當用 explain 無法解決慢 SQL 的時候落午,需要用profile 來對 sql 進行更細致的分析,找出 sql 所花的時間大部分消耗在哪個部分肚豺,確認 sql的性能瓶頸溃斋。
(3)、explain 中的索引問題
Explain 結果中吸申,一般來說梗劫,要看到盡量用 index(type 為 const、 ref 等截碴, key 列有值)梳侨,避免使用全表掃描(type 顯式為 ALL)。比如說有 where 條件且選擇性不錯的列日丹,需要建立索引走哺。
被驅動表的連接列,也需要建立索引哲虾。被驅動表的連接列也可能會跟 where 條件列一起建立聯(lián)合索引丙躏。當有排序或者 group by 的需求時择示,也可以考慮建立索引來達到直接排序和匯總的需求。
8晒旅、備份計劃栅盲,mysqldump以及xtranbackup的實現(xiàn)原理
(1)、備份計劃
視庫的大小來定废恋,一般來說 100G 內的庫剪菱,可以考慮使用 mysqldump 來做,因為 mysqldump更加輕巧靈活拴签,備份時間選在業(yè)務低峰期孝常,可以每天進行都進行全量備份(mysqldump 備份
出來的文件比較小,壓縮之后更小)蚓哩。100G 以上的庫构灸,可以考慮用 xtranbackup 來做,備份速度明顯要比 mysqldump 要快岸梨。一般是選擇一周一個全備喜颁,其余每天進行增量備份,備份時間為業(yè)務低峰期曹阔。
(2)半开、備份恢復時間
物理備份恢復快,邏輯備份恢復慢
這里跟機器赃份,尤其是硬盤的速率有關系寂拆,以下列舉幾個僅供參考
20G的2分鐘(mysqldump)
80G的30分鐘(mysqldump)
111G的30分鐘(mysqldump)
288G的3小時(xtra)
3T的4小時(xtra)
邏輯導入時間一般是備份時間的5倍以上
(3)、備份恢復失敗如何處理
首先在恢復之前就應該做足準備工作抓韩,避免恢復的時候出錯纠永。比如說備份之后的有效性檢查、權限檢查谒拴、空間檢查等尝江。如果萬一報錯,再根據報錯的提示來進行相應的調整英上。
(4)炭序、mysqldump和xtrabackup實現(xiàn)原理
mysqldump
mysqldump 屬于邏輯備份。加入--single-transaction 選項可以進行一致性備份。后臺進程會先設置 session 的事務隔離級別為 RR(SET SESSION TRANSACTION ISOLATION LEVELREPEATABLE READ),
之后顯式開啟一個事務(START TRANSACTION /*!40100 WITH CONSISTENTSNAPSHOT */)帖鸦,這樣就保證了該事務里讀到的數(shù)據都是事務事務時候的快照。之后再把表的數(shù)據讀取出來彼妻。 如果加上--master-data=1 的話,在剛開始的時候還會加一個數(shù)據庫的讀鎖
(FLUSH TABLES WITH READ LOCK),等開啟事務后,再記錄下數(shù)據庫此時 binlog 的位置(showmaster status)侨歉,馬上解鎖屋摇,再讀取表的數(shù)據。等所有的數(shù)據都已經導完幽邓,就可以結束事務
Xtrabackup:
xtrabackup 屬于物理備份炮温,直接拷貝表空間文件,同時不斷掃描產生的 redo 日志并保存下來牵舵。最后完成 innodb 的備份后柒啤,會做一個 flush engine logs 的操作(老版本在有 bug,在5.6 上不做此操作會丟數(shù)據)畸颅,確保所有的 redo log 都已經落盤(涉及到事務的兩階段提交
概念担巩,因為 xtrabackup 并不拷貝 binlog,所以必須保證所有的 redo log 都落盤没炒,否則可能會丟最后一組提交事務的數(shù)據)涛癌。這個時間點就是 innodb 完成備份的時間點,數(shù)據文件雖然不是一致性的送火,但是有這段時間的 redo 就可以讓數(shù)據文件達到一致性(恢復的時候做的事
情)拳话。然后還需要 flush tables with read lock,把 myisam 等其他引擎的表給備份出來种吸,備份完后解鎖弃衍。 這樣就做到了完美的熱備。
9坚俗、mysqldump中備份出來的sql镜盯,如果我想sql文件中,一行只有一個insert....value()的話坦冠,怎么辦形耗?如果備份需要帶上master的復制點信息怎么辦哥桥?
--skip-extended-insert
[root@helei-zhuanshu ~]# mysqldump -uroot -p helei --skip-extended-insert
Enter password:
? KEY `idx_c1` (`c1`),
? KEY `idx_c2` (`c2`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `helei`
--
LOCK TABLES `helei` WRITE;
/*!40000 ALTER TABLE `helei` DISABLE KEYS */;
INSERT INTO `helei` VALUES (1,32,37,38,'2016-10-18 06:19:24','susususususususususususu');
INSERT INTO `helei` VALUES (2,37,46,21,'2016-10-18 06:19:24','susususususu');
INSERT INTO `helei` VALUES (3,21,5,14,'2016-10-18 06:19:24','susu');
可以使用批量 ssh 工具 pssh 來對需要重啟的機器執(zhí)行重啟命令拟糕。 也可以使用 salt(前提是客戶端有安裝 salt)或者 ansible( ansible 只需要 ssh 免登通了就行)等多線程工具同時操作多臺服務器
(1)、讀取參數(shù)
global buffer 以及 local buffer送滞;
Global buffer:
Innodb_buffer_pool_size
innodb_log_buffer_size
innodb_additional_mem_pool_size
local buffer(下面的都是 server 層的 session 變量侠草,不是 innodb 的):
Read_buffer_size
Join_buffer_size
Sort_buffer_size
Key_buffer_size
Binlog_cache_size
(2)、寫入參數(shù)
innodb_flush_log_at_trx_commit
innodb_buffer_pool_size
insert_buffer_size
innodb_double_write
innodb_write_io_thread
innodb_flush_method
(3)犁嗅、與IO相關的參數(shù)
innodb_write_io_threads = 8
innodb_read_io_threads = 8
innodb_thread_concurrency = 0
Sync_binlog
Innodb_flush_log_at_trx_commit
Innodb_lru_scan_depth
Innodb_io_capacity
Innodb_io_capacity_max
innodb_log_buffer_size
innodb_max_dirty_pages_pct
(4)边涕、緩存參數(shù)以及緩存的適用場景
query cache/query_cache_type
并不是所有表都適合使用query cache。造成query cache失效的原因主要是相應的table發(fā)生了變更
第一個:讀操作多的話看看比例,簡單來說功蜓,如果是用戶清單表园爷,或者說是數(shù)據比例比較固定,比如說商品列表式撼,是可以打開的童社,前提是這些庫比較集中,數(shù)據庫中的實務比較小著隆。
第二個:我們“行騙”的時候扰楼,比如說我們競標的時候壓測,把query cache打開美浦,還是能收到qps激增的效果弦赖,當然前提示前端的連接池什么的都配置一樣。大部分情況下如果寫入的居多浦辨,訪問量并不多腾节,那么就不要打開,例如社交網站的荤牍,10%的人產生內容案腺,其余的90%都在消費,打開還是效果很好的康吵,但是你如果是qq消息劈榨,或者聊天,那就很要命晦嵌。
第三個:小網站或者沒有高并發(fā)的無所謂同辣,高并發(fā)下,會看到 很多 qcache 鎖 等待惭载,所以一般高并發(fā)下旱函,不建議打開query cache
12、你是如何監(jiān)控你們的數(shù)據庫的描滔?你們的慢日志都是怎么查詢的棒妨?
監(jiān)控的工具有很多,例如zabbix含长,lepus券腔,我這里用的是lepus
13、你是否做過主從一致性校驗拘泞,如果有纷纫,怎么做的,如果沒有陪腌,你打算怎么做辱魁?
主從一致性校驗有多種工具 例如checksum烟瞧、mysqldiff、pt-table-checksum等
14染簇、表中有大字段X(例如:text類型)燕刻,且字段X不會經常更新,以讀為為主剖笙,請問您是選擇拆成子表卵洗,還是繼續(xù)放一起?寫出您這樣選擇的理由
答:拆帶來的問題:連接消耗 + 存儲拆分空間;不拆可能帶來的問題:查詢性能弥咪;
如果能容忍拆分帶來的空間問題,拆的話最好和經常要查詢的表的主鍵在物理結構上放置在一起(分區(qū)) 順序IO,減少連接消耗,最后這是一個文本列再加上一個全文索引來盡量抵消連接消耗
如果能容忍不拆分帶來的查詢性能損失的話:上面的方案在某個極致條件下肯定會出現(xiàn)問題,那么不拆就是最好的選擇
15过蹂、MySQL中InnoDB引擎的行鎖是通過加在什么上完成(或稱實現(xiàn))的?為什么是這樣子的聚至?
答:InnoDB是基于索引來完成行鎖
例: select * from tab_with_index where id = 1 for update;
for update 可以根據條件來完成行鎖鎖定,并且 id 是有索引鍵的列,
如果 id 不是索引鍵那么InnoDB將完成表鎖,,并發(fā)將無從談起
16酷勺、如何從mysqldump產生的全庫備份中只恢復某一個庫、某一張表扳躬?
全庫備份
[root@HE1 ~]# mysqldump -uroot -p --single-transaction -A --master-data=2 >dump.sql
只還原erp庫的內容
[root@HE1 ~]# mysql -uroot -pMANAGER erp --one-database <dump.sql
可以看出這里主要用到的參數(shù)是--one-database簡寫-o的參數(shù)脆诉,極大方便了我們的恢復靈活性
那么如何從全庫備份中抽取某張表呢,全庫恢復贷币,再恢復某張表小庫還可以击胜,大庫就很麻煩了,那我們可以利用正則表達式來進行快速抽取役纹,具體實現(xiàn)方法如下:
從全庫備份中抽取出t表的表結構
[root@HE1 ~]# sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `t`/!d;q' dump.sql
DROP TABLE IF EXISTS`t`;
/*!40101 SET@saved_cs_client? ? =@@character_set_client */;
/*!40101 SETcharacter_set_client = utf8 */;
CREATE TABLE `t` (
? `id` int(10) NOT NULL AUTO_INCREMENT,
? `age` tinyint(4) NOT NULL DEFAULT '0',
? `name` varchar(30) NOT NULL DEFAULT '',
? PRIMARY KEY (`id`)
) ENGINE=InnoDBAUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
/*!40101 SETcharacter_set_client = @saved_cs_client */;
從全庫備份中抽取出t表的內容
[root@HE1 ~]# grep'INSERT INTO `t`' dump.sql
INSERT INTO `t`VALUES (0,0,''),(1,0,'aa'),(2,0,'bbb'),(3,25,'helei');
17偶摔、在當前的工作中,你碰到到的最大的mysql db?問題以及如何解決的促脉?
可以選擇一個處理過的比較棘手的案例辰斋,或者選擇一個老師在課程上講過的死鎖的案例;沒有及時 Purge + insert 唯一索引造成的死鎖:具體案例可以參考學委筆記。
18瘸味、請簡潔地描述下MySQL?中InnoDB?支持的四種事務隔離級別名稱宫仗,以及逐級之間的區(qū)別?
(1)旁仿、事物的4種隔離級別
讀未提交(read uncommitted)
讀已提交(read committed)
可重復讀(repeatable read)
串行(serializable)
(2)藕夫、不同級別的現(xiàn)象
Read Uncommitted:可以讀取其他 session 未提交的臟數(shù)據。
Read Committed:允許不可重復讀取丁逝,但不允許臟讀取汁胆。提交后,其他會話可以看到提交的數(shù)據霜幼。
Repeatable Read: 禁止不可重復讀取和臟讀取、以及幻讀(innodb 獨有)誉尖。
Serializable: 事務只能一個接著一個地執(zhí)行罪既,但不能并發(fā)執(zhí)行。事務隔離級別最高。
不同的隔離級別有不同的現(xiàn)象琢感,并有不同的鎖定/并發(fā)機制丢间,隔離級別越高,數(shù)據庫的并發(fā)性就越差驹针。
其中許多有水分,一看到簡歷自我介紹柬甥,說公司項目的時候饮六,會寫上 linux 系統(tǒng)維護,mssql server 項目苛蒲,或者 oracle data gard 項目卤橄,一般如果有這些的話,工作在 3 年到 4年的話臂外,他的 2 年 MySQL DBA 管理經驗窟扑,是有很大的水分的。剛開始我跟領導說漏健,這些
不用去面試了嚎货,肯定 mysql dba 經驗不足,領導說先面面看看蔫浆,于是我就面了厂抖,結果很多人卡在基礎知識這一環(huán)節(jié)之上,比如:
( 1)有的卡在復制原理之上
( 2)有的卡在 binlog 的日志格式的種類和分別
( 3)有的卡在 innodb 事務與日志的實現(xiàn)上克懊。
( 4)有的卡在 innodb 與 myisam 的索引實現(xiàn)方式的理解上面忱辅。
.........
個人覺得如果有過真正的 2 年 mysql 專職 dba 經驗,那么肯定會在 mysql 的基本原理上有所研究谭溉,因為很多問題都不得不讓你去仔細研究各種細節(jié)墙懂,而自 己研究過的細節(jié)肯定會記憶深刻,別人問起一定會說的頭頭是道扮念,起碼一些最基本的關鍵參數(shù)比如
Seconds_Behind_Master 為 60 這個值 60 的準確涵義损搬,面試了 10+的 mysql dba,沒有一個說的準確柜与,有的說不知道忘記了巧勤,有的說是差了 60 秒,有的說是與主上執(zhí)行時間延后了 60 秒弄匕。
我一般先問他現(xiàn)在管理的數(shù)據庫架構是什么,如果他只說出了主從迁匠,而沒有說任何 ha的方案剩瓶,那么我就可以判斷出他沒有實際的 ha 經驗驹溃。不過這時候也不能就是 斷定他不懂mysql 高可用,也許是沒有實際機會去使用延曙,那么我就要問 mmm 以及 mha 以及mm+keepalived 等的原理
實現(xiàn)方式以及它們之間的優(yōu) 勢和不足了豌鹤,一般這種情況下,能說出這個的基本沒有枝缔。mmm 那東西好像不靠譜布疙,據說不穩(wěn)定,但是有人在用的愿卸,我只在虛擬機上面用過灵临,和mysql-router 比較像,都是指定可寫的機器和只讀機器擦酌。 MHA 的話一句話說不完俱诸,可以翻翻學委的筆記
3 、對于簡歷中寫有批量MySQL?數(shù)據庫服務器的管理經驗
這個如果他說有的話赊舶,我會先問他們現(xiàn)在實際線上的 mysql 數(shù)據庫數(shù)量有多少睁搭,分多少個節(jié)點組,最后問這些節(jié)點組上面的 slow log 是如何組合在一起來統(tǒng)計分析的笼平。如果這些他都答對了园骆,那么我還有一問,就是現(xiàn)在手上有 600 臺數(shù)據庫寓调,新來的機器锌唾, Mysql 都
安裝好了,那么你如 何在最快的時間里面把這 600 臺 mysql 數(shù)據庫的 mysqld 服務啟動起來夺英。這個重點在于最快的時間晌涕,而能準確回答出清晰思路的只有 2 個人。slow log 分析:可以通過一個管理服務器定時去各臺 MySQL 服務器上面 mv 并且 cp slowlog痛悯,
然后分析入庫余黎,頁面展示。最快的時間里面啟動 600 臺服務器: 肯定是多線程载萌。 可以用 pssh惧财, ansible 等多線程批量管理服務器的工具
首先問 mysql 中 sql 優(yōu)化的思路扭仁,如果能準備說出來垮衷, ok,那么我就開始問 explain的各種參數(shù)了乖坠,重點是 select_type搀突, type, possible_key, ref,rows,extra 等參數(shù)的各種
值的含義瓤帚,如果他都回答正確了描姚,那么我再問 file sort 的含義以及什么時候會出現(xiàn)這個分析結果涩赢,如果這里他也回答對了戈次,那么我就準備問 profile 分析了轩勘,如果這里他也答對了,那么我就會再問一個問 題怯邪,
那是曾經 tx 問我的讓我郁悶不已的問題绊寻,一個 6 億的表 a,一個 3 億的表 b悬秉,通過外間 tid 關聯(lián)澄步,你如何最快的查詢出滿足條件的第 50000 到第 50200中的這 200 條數(shù)據記錄。
Explain 在上面的題目中有了和泌,這里就不說了村缸。如何最快的查詢出滿足條件的第 50000 到第 50200 中的這 200 條數(shù)據記錄?這個我想不出來武氓!
關于 explain 的各種參數(shù)梯皿,請參考: http://blog.csdn.net/mchdba/article/details/9190771
這個對于數(shù)據庫設計我真的沒有太多的經驗县恕,我也就只能問問最基礎的东羹, mysql 中varchar(60) 60 是啥含義, int(30)中 30 是啥含義忠烛? 如果他都回答對了属提,那么我就問 mysql中為什么要這么設計呢?
如果他還回答對了美尸,我就繼續(xù)問 int(20)存儲的數(shù)字的上限和下限是多少冤议?這個問題難道了全部的 mysql dba 的應聘者,不得不佩服提出這個問題的金總的睿智啊师坎,因為這個問題回答正確了恕酸,
那么他確實認認真真地研究了 mysql 的設計中關于字段類型的細節(jié)。至 于豐富的設計數(shù)據庫的經驗屹耐,不用著急尸疆,這不我上面還有更加厲害的 dba嗎,他會搞明白的惶岭,那就跟我無關了寿弱。
varchar(60)的 60 表示最多可以存儲 60 個字符。int(30)的 30 表示客戶端顯示這個字段的寬度按灶。
為何這么設計症革?說不清楚,請大家補充 鸯旁。 int(20)的上限為 2147483647(signed)或者4294967295(unsigned)噪矛。
6 量蕊、關于mysql?參數(shù)優(yōu)化的經驗
首先問他它們線上 mysql 數(shù)據庫是怎么安裝的,如果說是 rpm 安裝的艇挨,那么我就直接問調優(yōu)參數(shù)了残炮,如果是源碼安裝的,那么我就要問編譯中的一些參數(shù)了缩滨,比如 my.cnf 以及存儲引擎以及字符類型等等势就。然后從以下幾個方面問起:( 1) mysql 有哪些 global 內存參數(shù),有哪些 local 內存參數(shù)脉漏。Global:innodb_buffer_pool_size/innodb_additional_mem_pool_size/innodb_log_buffer_size/key_buffer_size/query_cache_size/table_open_cache/table_definition_cache/thread_cache_sizeLocal:read_buffer_size/read_rnd_buffer_size/sort_buffer_size/join_buffer_size/binlog_cache_size/tmp_table_size/thread_stack/bulk_insert_buffer_size( 2) mysql 的寫入參數(shù)需要調整哪些苞冯?重要的幾個寫參數(shù)的幾個值得含義以及適用場景,比如 innodb_flush_log_at_trx_commit 等侧巨。 (求補充)sync_binlog 設置為 1舅锄,保證 binlog 的安全性。innodb_flush_log_at_trx_commit:0:事務提交時不將 redo log buffer 寫入磁盤(僅每秒進行 master thread 刷新司忱,安全性最差皇忿,性能最好)1:事務提交時將 redo log buffer 寫入磁盤(安全性最好,性能最差烘贴, 推薦生產使用)2:事務提交時僅將 redo log buffer 寫入操作系統(tǒng)緩存(安全性和性能都居中禁添,當 mysql宕機但是操作系統(tǒng)不宕機則不丟數(shù)據,如果操作系統(tǒng)宕機桨踪,最多丟一秒數(shù)據)innodb_io_capacity/innodb_io_capacity_max:看磁盤的性能來定老翘。如果是 HDD 可以設置為 200-幾百不等。如果是 SSD锻离,推薦為 4000 左右铺峭。 innodb_io_capacity_max 更大一些。innodb_flush_method 設置為 O_DIRECT汽纠。( 3) 讀取的話卫键,那幾個全局的 pool 的值的設置,以及幾個 local 的 buffer 的設置虱朵。Global:innodb_buffer_pool_size:設置為可用內存的 50%-60%左右莉炉,如果不夠,再慢慢上調碴犬。innodb_additional_mem_pool_size:采用默認值 8M 即可絮宁。innodb_log_buffer_size:默認值 8M 即可。key_buffer_size:myisam 表需要的 buffer size服协,選擇基本都用 innodb绍昂,所以采用默認的 8M 即可。Local:join_buffer_size: 當 sql 有 BNL 和 BKA 的時候,需要用的 buffer_size(plain indexscans, range index scans 的時候可能也會用到)窘游。默認為 256k唠椭,建議設置為 16M-32M。read_rnd_buffer_size:當使用 mrr 時忍饰,用到的 buffer贪嫂。默認為 256k,建議設置為16-32M喘批。read_buffer_size:當順序掃描一個 myisam 表撩荣,需要用到這個 buffer铣揉∪纳睿或者用來決定memory table 的大小」涔埃或者所有的 engine 類型做如下操作:order by 的時候用 temporaryfile敌厘、 SELECT INTO … OUTFILE 'filename' 、 For caching results of nested queries朽合。默認為 128K俱两,建議為 16M。sort_buffer_size: sql 語句用來進行 sort 操作(order by,group by)的 buffer曹步。如果 buffer 不夠宪彩,則需要建立 temporary file。如果在 show global status 中發(fā)現(xiàn)有大量的 Sort_merge_passes 值讲婚,則需要考慮調大 sort_buffer_size尿孔。默認為 256k,建議設置為 16-32M筹麸。binlog_cache_size: 表示每個 session 中存放 transaction 的 binlog 的 cache size活合。默認 32K。一般使用默認值即可物赶。如果有大事務白指,可以考慮調大。thread_stack: 每個進程都需要有酵紫,默認為 256K告嘲,使用默認值即可。( 4) 還有就是著名的 query cache 了奖地,以及 query cache 的適用場景了橄唬,這里有一個陷阱,就是高并發(fā)的情況下鹉动,比如雙十一的時候轧坎, query cache 開還是不開,開了怎么保證高并發(fā)泽示,不開又有何別的考慮缸血?建議關閉蜜氨,上了性能反而更差。
gap 鎖飒炎, next-key 鎖,以及 innodb 的行鎖是怎么實現(xiàn)的笆豁,以及 myisam 的鎖是怎么實現(xiàn)的等
Innodb 的鎖的策略為 next-key 鎖郎汪,即 record lock+gap lock。是通過在 index 上加 lock 實現(xiàn)的闯狱,如果 index 為 unique index煞赢,則降級為 record lock,如果是普通 index,則為 next-key lock哄孤,如果沒有 index照筑,則直接鎖住全表。 myisam 直接使用全表掃描瘦陈。
我就問了 ndbd 的節(jié)點的啟動先后順序,再問配置參數(shù)中的內存配置幾個重要的參數(shù)晨逝,再問 sql 節(jié)點中執(zhí)行一個 join 表的 select 語句的實現(xiàn)流程是怎么走的蛾默? ok,能回答的也只有一個捉貌。
關于 mysql 集群入門資料支鸡,請參考: http://write.blog.csdn.net/postlist/1583151/all
就問 mysqldump 中備份出來的 sql昏翰,如果我想 sql 文件中苍匆,一行只有一個 insert .... value()的話,怎么辦棚菊?如果備份需要帶上 master 的復制點信息怎么辦浸踩?或者 xtrabackup 中如何
做到實時在線備份的?以及 xtrabackup 是如何做到帶上 master 的復制點的信息的统求? 當前 xtrabackup 做增量備份的時候有何缺陷检碗?能全部回答出來的沒有一個,不過沒有關系码邻,只要回答出 mysqldump 或者xtrabackup 其中一個的也可以折剃。
1). --skip-extended-insert
2). --master-date=1
3). 因為 xtrabackup 是多線程,一個線程不停地在拷貝新產生的 redo 文件像屋,另外的線程去備份數(shù)據庫怕犁,當所有表空間備份完成的時候,它會執(zhí)行 flush table with read lock 操作
鎖住所有表,然后執(zhí)行 show master status; 接著執(zhí)行 flush engine logs; 最后解鎖表奏甫。執(zhí)行 show master status; 時就能獲取到 mster 的復制點信息戈轿,執(zhí)行 flush engine logs 強制把redo 文件刷新到磁盤。
4). xtrabackup 增量備份的缺陷不了解阵子,在線上用 xtrabackup 備份沒有發(fā)現(xiàn)什么缺陷思杯。
就問你現(xiàn)在線上數(shù)據量有多大挠进,如果是 100G色乾,你用 mysqldump 出來要多久,然后 mysql進去又要多久领突,如果互聯(lián)網不允許延時的話暖璧,你又怎么做到 恢復單張表的時候保證 nagios不報警。如果有人說 mysqldump 出來 1 個小時就 ok 了攘须,那么我就要問問他 db 服務器是
啥配置了漆撞,如果他說 mysql 進去 50 分鐘搞定了,那么我也要問問他 db 機器啥配置了于宙,如果是普通的吊絲 pc server,那么真實性悍汛,大家懂得捞魁。然后如果你用 xtrabackup 備份要多久,恢復要多久离咐,大家都知道 copy-back 這一步要很久谱俭,那么你有沒有辦法對這一塊優(yōu)化。