mysql中的事務(wù)重做日志(redo log)與回滾日志(undo log)
事務(wù)重做日志(redo log)與回滾日志(undo log)
查看事務(wù)日志:
show engine innodb status; show engine innodb status\G;

查看日志文件設(shè)置狀態(tài):
show variables like 'innodb_%';

- innodb_log_files_in_group:DB 中設(shè)置幾組事務(wù)日志,默認(rèn)是2;
- innodb_log_group_home_dir 事務(wù)日志存放目錄,不設(shè)置;
- ib_logfile0… 存放在數(shù)據(jù)文件目錄下 InnoDB 存儲引擎可將所有數(shù)據(jù)存放于 ibdata* 的共享表空間,也可將每張表存放于獨(dú)立的 .ibd 文件的獨(dú)立表空間;
注意:在 MySQL 中對于數(shù)據(jù)來說,最為重要的是日志文件
redo log => ib_logfile0… undo log => ibdata
重做日志
持久化
事務(wù)被提交,數(shù)據(jù)一定會被寫入到數(shù)據(jù)庫中并持久存儲起來,通常來說當(dāng)事務(wù)已經(jīng)被提交之后,就無法再次回滾了。
重做日志實(shí)現(xiàn)持久化
與原子性一樣,事務(wù)的持久性也是通過日志來實(shí)現(xiàn)的,MySQL 使用重做日志( redo log )實(shí)現(xiàn)事務(wù)的持久性,重做日志由兩部分組成,一是內(nèi)存中的重做日志緩沖區(qū),因?yàn)橹刈鋈罩揪彌_區(qū)在內(nèi)存中,所以它是易失的;另一個就是在磁盤上的重做日志文件,它是持久的。

當(dāng)我們在一個事務(wù)中嘗試對數(shù)據(jù)進(jìn)行寫時,它會先將數(shù)據(jù)從磁盤讀入內(nèi)存,并更新內(nèi)存中緩存的數(shù)據(jù),然后生成一條重做日志并寫入重做日志緩存,當(dāng)事務(wù)真正提交時,MySQL 會將重做日志緩存中的內(nèi)容刷新到重做日志文件,再將內(nèi)存中的數(shù)據(jù)更新到磁盤上,圖中的第4、5步就是在事務(wù)提交時執(zhí)行的。
重做日志執(zhí)行
在MySQL中事務(wù)執(zhí)行 commit 提交了之后,但是服務(wù)器宕機(jī)了,數(shù)據(jù)還沒有寫入磁盤,在MySQL重啟服務(wù)之后會重新執(zhí)行這個重做日志寫入數(shù)據(jù)。
回滾日志
原子性
通俗的解釋就是:一條繩子上的螞蚱。
專業(yè)性的解釋是:事務(wù)一系列的操作,要么全部執(zhí)行,要么都不執(zhí)行。
回滾日志實(shí)現(xiàn)原子性
想要保證事務(wù)的原子性,就需要在異常發(fā)生時,對已經(jīng)執(zhí)行的操作進(jìn)行回滾,而在 MySQL 中,恢復(fù)機(jī)制是通過回滾日志( undo log )實(shí)現(xiàn)的,所有事務(wù)進(jìn)行的修改都會先記錄到這個回滾日志中,然后再對數(shù)據(jù)庫中的對應(yīng)行進(jìn)行寫入。
注意:系統(tǒng)發(fā)生崩潰、數(shù)據(jù)庫進(jìn)程直接被殺死后,當(dāng)用戶再次啟動數(shù)據(jù)庫進(jìn)程時,還能夠立刻通過查詢回滾日志將之前未完成的事務(wù)進(jìn)行回滾,這也就需要回滾日志必須先于數(shù)據(jù)持久化到磁盤上,是我們需要先寫日志后寫數(shù)據(jù)庫的主要原因。
在日志文件中:在事務(wù)中使用的每一條 insert into 都對應(yīng)了一條 delete ,每一條 update 也對應(yīng)一條相反的 update 語句。

回滾日志執(zhí)行
- 1.手動執(zhí)行回滾命令時會執(zhí)行。
- 2.如果程序在事務(wù)執(zhí)行之后,提交命令執(zhí)行之前出現(xiàn)了異常,在下次 MySQL 服務(wù)重啟的時候會執(zhí)行。
測試:在事務(wù)提交前停止mysql服務(wù)

然后我們停止MySQL服務(wù):

停止成功;然后再開啟 MySQL 服務(wù):

啟動成功,然后查詢一下數(shù)據(jù):

沒有查詢到新增的數(shù)據(jù);數(shù)據(jù)已經(jīng)丟失了,需要執(zhí)行了commit之后數(shù)據(jù)才不會丟失。
重做日志與回滾日志總結(jié)
到現(xiàn)在為止我們了解了 MySQL 中的兩種日志,回滾日志( undo log )和重做日志( redo log );在數(shù)據(jù)庫系統(tǒng)中,事務(wù)的原子性和持久性是由事務(wù)日志( transaction log )保證的,在實(shí)現(xiàn)時也就是上面提到的兩種日志;欠著用于對事務(wù)的影響進(jìn)行撤銷,后者在錯誤處理時對已經(jīng)提交的事務(wù)進(jìn)行重做,它們能保證兩點(diǎn):
發(fā)生錯誤或者需要回滾的事務(wù)能夠成功回滾(原子性)。在事務(wù)提交后,數(shù)據(jù)沒來得及寫入磁盤就宕機(jī)時,在下次重新啟動后能夠成功恢復(fù)數(shù)據(jù)(持久性)。
在數(shù)據(jù)庫中,這兩種日志經(jīng)常都是一起工作的,我們可以將他們整體看作一條事務(wù)日志,其中包含了事務(wù)的ID、修改的行元素以及修改前后的值。

總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySql使用mysqldump 導(dǎo)入與導(dǎo)出方法總結(jié)
這篇文章主要介紹了MySql使用mysqldump 導(dǎo)入與導(dǎo)出方法總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
MySQL命令行界面中出現(xiàn)字符錯誤提示的原因及解決方法
這篇文章主要介紹了MySQL命令行界面中出現(xiàn)字符錯誤提示的原因及解決方法,同時文中還附帶了MySQL導(dǎo)入亂碼問題的解決辦法提示,需要的朋友可以參考下2016-03-03
MySQL多實(shí)例的配置應(yīng)用實(shí)例場景
在一臺服務(wù)器上,運(yùn)行多個數(shù)據(jù)庫服務(wù),這些服務(wù)進(jìn)程通過不同的socket監(jiān)聽不同的服務(wù)端口來提供各自的服務(wù),這篇文章主要介紹了MySQL多實(shí)例的配置場景分析,需要的朋友可以參考下2021-12-12
Mysql基礎(chǔ)學(xué)習(xí)之LAG與LEAD開窗函數(shù)
lead和lag是在SQL中用于創(chuàng)建窗口函數(shù)的兩個常用函數(shù),這篇文章主要給大家介紹了關(guān)于Mysql基礎(chǔ)學(xué)習(xí)之LAG與LEAD開窗函數(shù)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11

