只要賒帳記錄在了粉板上或寫了帳本上,以後即便掌櫃忘記了,
好比停業幾天,回覆生意後依然能夠經過帳本和粉板上的數據明確賒帳帳目mysql
有了redo log,InnoDB就能夠保證即便數據庫發生異常重啓,以前提交的記錄都不會丟失,這個能力成爲crash-safe2、重要的日誌模塊:binlogsql
redo是物理的,binlog是邏輯的;如今因爲redo是屬於InnoDB引擎,因此必需要有binlog,由於你可使用別的引擎數據庫
通常採用row,由於遇到時間,從庫可能會出現不一致的狀況,可是row更新先後都有,會致使日誌變大
最後2個參數,保證事務成功,日誌必須落盤,這樣,數據庫crash後,就不會丟失某個事務的數據了bash
一、互聯網公司,使用MySQL的功能相對少(存儲過程、觸發器、函數) session
選擇默認的語句模式,Statement Level(默認)
二、公司若是用到使用MySQL的特殊功能(存儲過程、觸發器、函數) oracle
則選擇Mixed模式
三、公司若是用到使用MySQL的特殊功能(存儲過程、觸發器、函數)又但願數據最大化一直,此時最好選擇Row level模式app
binlog
日誌記錄效果[root@db01]# mysqlbinlog --base64-output="decode-rows" --verbose mysql-bin.000248 /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 #160628 11:06:52 server id 1 end_log_pos 107 Start: binlog v 4, server v 5.5.49-log created 160628 11:06:52 at startup # Warning: this binlog is either in use or was not closed properly. ROLLBACK/*!*/; # at 107 #160628 11:07:09 server id 1 end_log_pos 177 Query thread_id=1 exec_time=0 error_code=0 SET TIMESTAMP=1467083229/*!*/; SET @@session.pseudo_thread_id=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;/*!\C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; BEGIN /*!*/; # at 177 # at 223 #160628 11:07:09 server id 1 end_log_pos 223 Table_map: `oldboy`.`sc` mapped to number 33 #160628 11:07:09 server id 1 end_log_pos 785 Update_rows: table id 33 flags: STMT_END_F ### UPDATE `oldboy`.`sc` ### WHERE ### @1=1 ### @2=1001
圖中綠色框表示是在內粗執行,紅色框表示是在執行器中執行運維
1.首先客戶端經過tcp/ip發送一條sql語句到server層的SQL interfacetcp
2.SQL interface接到該請求後,先對該條語句進行解析,驗證權限是否匹配函數
3.驗證經過之後,分析器會對該語句分析,是否語法有錯誤等
4.接下來是優化器器生成相應的執行計劃,選擇最優的執行計劃
5.以後會是執行器根據執行計劃執行這條語句。在這一步會去open table,若是該table上有MDL,則等待。若是沒有,則加在該表上加短暫的MDL(S),
(若是opend_table太大,代表open_table_cache過小。須要不停的去打開frm文件)
6.進入到引擎層,首先會去innodb_buffer_pool裏的data dictionary(元數據信息)獲得表信息
7.經過元數據信息,去lock info裏查出是否會有相關的鎖信息,並把這條update語句須要的鎖信息寫入到lock info裏(鎖這裏還有待補充)
8.而後涉及到的老數據經過快照的方式存儲到innodb_buffer_pool裏的undo page裏,而且記錄undo log修改的redo
(若是data page裏有就直接載入到undo page裏,若是沒有,則須要去磁盤裏取出相應page的數據,載入到undo page裏)
9.在innodb_buffer_pool的data page作update操做。並把操做的物理數據頁修改記錄到redo log buffer裏
因爲update這個事務會涉及到多個頁面的修改,因此redo log buffer裏會記錄多條頁面的修改信息。
由於group commit的緣由,此次事務所產生的redo log buffer可能會跟隨其它事務一同flush而且sync到磁盤上
10.同時修改的信息,會按照event的格式,記錄到binlog_cache中。(這裏注意binlog_cache_size是transaction級別的,不是session級別的參數,
一旦commit以後,dump線程會從binlog_cache裏把event主動發送給slave的I/O線程)
11.以後把這條sql,須要在二級索引上作的修改,寫入到change buffer page,等到下次有其餘sql須要讀取該二級索引時,再去與二級索引作merge
(隨機I/O變爲順序I/O,可是因爲如今的磁盤都是SSD,因此對於尋址來講,隨機I/O和順序I/O差距不大)
12.此時update語句已經完成,須要commit或者rollback。這裏討論commit的狀況,而且雙1
13.commit操做,因爲存儲引擎層與server層之間採用的是內部XA(保證兩個事務的一致性,這裏主要保證redo log和binlog的原子性),
因此提交分爲prepare階段與commit階段
14.prepare階段,將事務的xid寫入,將binlog_cache裏的進行flush以及sync操做(大事務的話這步很是耗時)
15.commit階段,因爲以前該事務產生的redo log已經sync到磁盤了。因此這步只是在redo log裏標記commit
16.當binlog和redo log都已經落盤之後,若是觸發了刷新髒頁的操做,先把該髒頁複製到doublewrite buffer裏,把doublewrite buffer裏的刷新到共享表空間,而後纔是經過page cleaner線程把髒頁寫入到磁盤中
其實在實現上5是調用了6的過程了的,因此是一回事。MySQL server 層和InnoDB層都保存了表結構,因此有書上描述時會拆開說。
必需要保證2份日誌一致,使用的2階段式提交;其實感受像事務,不是成功就是失敗,不能讓中間環節出現,也就是一個成功,一個失敗
若是有一天mysql只有InnoDB引擎了,有redo來實現複製,那麼感受oracle的DG就誕生了,物理的速度也將遠超邏輯的,畢竟只記錄了改動向量
老師,今天MYSQL第二講中提到binlog和redo log, 我感受binlog不少餘,按理是否是隻要redo log就夠了?[費解]
一個緣由是,redolog只有InnoDB有,別的引擎沒有。 另外一個緣由是,redolog是循環寫的,不持久保存,binlog的「歸檔」這個功能,redolog是不具有的。
老師您好,我以前是作運維的,經過binlog恢復誤操做的數據,可是實際上,咱們會後知後覺,誤刪除一段時間了,才發現誤刪除,此時,我把以前誤刪除的binlog導入,再把誤刪除以後binlog導入,會出現問題,好比主鍵衝突,並且binlog導數據,不一樣模式下時間也有不一樣,可是通常都是row模式,時間仍是好久,有沒什麼方式,時間短且數據一致性強的方式
其實恢復數據只能恢復到誤刪以前到一刻, 誤刪以後的,不能只靠binlog來作,由於業務邏輯可能由於誤刪操做的行爲,插入了邏輯錯誤的語句, 因此以後的,跟業務一塊兒,從業務快速補數據的。只靠binlog補出來的每每不完整
1 prepare階段
2 寫binlog
3 commit
當在2以前崩潰時
重啓恢復:後發現沒有commit,回滾。備份恢復:沒有binlog 。一致
當在3以前崩潰
重啓恢復:雖沒有commit,但知足prepare和binlog完整,因此重啓後會自動commit。備份:有binlog. 一致
備份時間週期的長短,感受有2個方便
首先,是恢復數據丟失的時間,既然須要恢復,確定是數據丟失了。若是一天一備份的話,只要找到這天的全備,加入這天某段時間的binlog來恢復,若是一週一備份,假設是週一,而你要恢復的數據是週日某個時間點,那就,須要全備+週一到週日某個時間點的所有binlog用來恢復,時間相比前者須要增長不少;看業務能忍受的程度
其次,是數據庫丟失,若是一週一備份的話,須要確保整個一週的binlog都無缺無損,不然將沒法恢復;而一天一備,只要保證這天的binlog都無缺無損;固然這個能夠經過校驗,或者冗餘等技術來實現,相比之下,上面那點更重要
一、帳本記上 賣一瓶可樂(redo log爲 prepare狀態), 二、而後收錢放入錢箱(bin log記錄) 三、而後回過頭在帳本上打個勾(redo log置爲commit)表示一筆交易結束。
一、回過頭來整理這次交易,發現只有記帳沒有收錢,則交易失敗,刪掉帳本上的記錄(回滾); 二、若是收了錢後被終止,而後回過頭髮現帳本有記錄(prepare)並且錢箱有本次收入(bin log),則繼續完善帳本(commit),本次交易有效。