【MySQL】事物日志
查看事物日志
show engine innodb status
查看日志文件設置狀態
show?varibales like 'innodb_%';
innnodb_log_file_in_group中設置幾組事物日志,默認是2;
innodb_log_group_home_dir事物日志存放目錄,不設置會存在數據庫的默認文件目錄下
innodb存儲引擎可將所有數據存放于ibdata*的共享表空間,也可以將每張表存放于獨立的ibd文件的獨立表空間
注意:在Mysql中對于數據來說,最為重要的是日志文件
重做日志:redo log = ib_logfile
回滾日志:undo log = ibdata
回滾日志
事物的屬性與一個原子性,通俗的解釋就是一條繩上的螞蚱。專業點就是一系列的操作,要么全部執行,要么都不執行
想要保證事物的原子性,就需要在異常發生時,對已經執行的操作進行回滾,而在Mysql中,恢復機制是通過回滾日志實現的,也就是undo log,所有的事物進行的修改都會先記錄到這個回滾日志中,然后在對數據庫中的對應進行寫入
注意:系統發生崩潰,數據庫進程直接被殺死后,當用戶再次啟動數據庫進程時,還能夠立刻通過查詢回滾日志將之前未完成的事物進程回滾,這也就需要回滾日志必須先于數據持久化到磁盤上,是我們需要先寫日志后寫數據庫的主要原因
在日志文件中,在事物中使用的每一條insert都對應了一條delete,沒一條uodate也都對應一條相反的update語句
重做日志
與原子性一樣,事務的持久性也是通過日志來實現的,MySQL 使用重做日志(redo log)實現事務的持久性,重做日志由兩部分組成,一是內存中的重做日志緩沖區,因為重做日志緩沖區在內存中,所以它是易失的,另一個就是在磁盤上的重做日志文件,它是持久的。
在事務寫入過程
當我們在一個事務中嘗試對數據進行寫時,它會先將數據從磁盤讀入內存,并更新內存中緩存的數據,然后生成一條重做日志并寫入重做日志緩存,當事務真正提交時,MySQL 會將重做日志緩存中的內容刷新到重做日志文件,再將內存中的數據更新到磁盤上,圖中的第 4、5 步就是在事務提交時執行的。
回滾日志和重做日志
到現在為止我們了解了 MySQL 中的兩種日志,回滾日志(undo log)和重做日志(redo log);在數據庫系統中,事務的原子性和持久性是由事務日志(transaction log)保證的,在實現時也就是上面提到的兩種日志,前者用于對事務的影響進行撤銷,后者在錯誤處理時對已經提交的事務進行重做,它們能保證兩點:
發生錯誤或者需要回滾的事務能夠成功回滾(原子性);
在事務提交后,數據沒來得及寫會磁盤就宕機時,在下次重新啟動后能夠成功恢復數據(持久性);
在數據庫中,這兩種日志經常都是一起工作的,我們可以將它們整體看做一條事務日志,其中包含了事務的 ID、修改的行元素以及修改前后的值。
事務日志流程
checkpoint,即檢查點。在undolog中寫入檢查點,表示在checkpoint前的事務都已經完成commit或者rollback了,也就是檢查點前面的事務已經不存在數據一致性的問題了(此處暫時不會深入解釋)
Innodb的事務日志是指Redo log,簡稱Log,保存在日志文件ib_logfile里面(去mysql數據目錄下看下)。Innodb還有另外一個日志Undo log,但Undo log是存放在共享表空間里面的(ibdata*文件,存儲的是check point日志序列號)。
Innodb的一條事務日志共經歷4個階段:
1)創建階段:事務創建一條日志;
2)日志刷盤:日志寫入到磁盤上的日志文件;(ib_logfile里面)
3)數據刷盤:日志對應的臟頁數據寫入到磁盤上的數據文件;
4)寫CKP:日志被當作Checkpoint寫入日志文件;(ib_data里面)
innodb_flush_log_at_trx_commit 參數解析
0:log buffer將每秒一次地寫入log file中,并且log file的flush(刷到磁盤)操作同時進行。該模式下在事務提交的時候,不會主動觸發寫入磁盤的操作。
1:每次事務提交時MySQL都會把log buffer的數據寫入log file,并且flush(刷到磁盤)中去,該模式為系統默認。
2:每次事務提交時MySQL都會把log buffer的數據寫入log file,但是flush(刷到磁盤)操作并不會同時進行。該模式下,MySQL會每秒執行一次 flush(刷到磁盤)操作。
關于性能:0>2>1
關于安全:1>2>0
注意事項
innodb_flush_log_at_trx_commit=0,表示每隔一秒把log buffer刷到文件系統中(os buffer)去,并且調用文件系統的“flush”操作將緩存刷新到磁盤上去。也就是說一秒之前的日志都保存在日志緩沖區,也就是內存上,如果機器宕掉,可能丟失1秒的事務數據。
innodb_flush_log_at_trx_commit=1,表示在每次事務提交的時候,都把log buffer刷到文件系統中(os buffer)去,并且調用文件系統的“flush”操作將緩存刷新到磁盤上去。這樣的話,數據庫對IO的要求就非常高了,如果底層的硬件提供的IOPS比較差,那么MySQL數據庫的并發很快就會由于硬件IO的問題而無法提升。
innodb_flush_log_at_trx_commit=2,表示在每次事務提交的時候會把log buffer刷到文件系統中去,但并不會立即刷寫到磁盤。如果只是MySQL數據庫掛掉了,由于文件系統沒有問題,那么對應的事務數據并沒有丟失。只有在數據庫所在的主機操作系統損壞或者突然掉電的情況下,數據庫的事務數據可能丟失1秒之類的事務數據。這樣的好處,減少了事務數據丟失的概率,而對底層硬件的IO要求也沒有那么高(log buffer寫到文件系統中,一般只是從log buffer的內存轉移的文件系統的內存緩存中,對底層IO沒有壓力)。
MySQL 數據庫
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。