欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品

主頁 > 知識(shí)庫 > MySQL中的redo log和undo log日志詳解

MySQL中的redo log和undo log日志詳解

熱門標(biāo)簽:智能外呼系統(tǒng)復(fù)位 拉卡拉外呼系統(tǒng) 高清地圖標(biāo)注道路 臨清電話機(jī)器人 話務(wù)外呼系統(tǒng)怎么樣 400電話可以辦理嗎 外東北地圖標(biāo)注 云南電商智能外呼系統(tǒng)價(jià)格 大眾點(diǎn)評(píng)星級(jí)酒店地圖標(biāo)注

MySQL日志系統(tǒng)中最重要的日志為重做日志redo log和歸檔日志bin log,后者為MySQL Server層的日志,前者為InnoDB存儲(chǔ)引擎層的日志。

1 重做日志redo log

1.1 什么是redo log

redo log用于保證事務(wù)的持久性,即ACID中的D。

持久性:指一個(gè)事務(wù)一旦被提交,它對(duì)數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的,接下來即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對(duì)其有任何影響。

redo log有兩種類型,分別為物理重做日志和邏輯重做日志。在InnoDB中redo log大多數(shù)情況下是一個(gè)物理日志,記錄數(shù)據(jù)頁面的物理變化(實(shí)際的數(shù)據(jù)值)。

1.2 redo log的功能

redo log的主要功能是用于數(shù)據(jù)庫崩潰時(shí)的數(shù)據(jù)恢復(fù)。

1.3 redo log的組成

redo log可以分為以下兩部分

存儲(chǔ)在內(nèi)存中的重做日志緩沖區(qū)存儲(chǔ)在磁盤上的重做日志文件

1.4 記錄redo log的時(shí)機(jī)

在完成數(shù)據(jù)的修改之后,臟頁刷入磁盤之前寫入重做日志緩沖區(qū)。即先修改,再寫入。

臟頁:內(nèi)存中與磁盤上不一致的數(shù)據(jù)(并不是壞的?。?/p>

在以下情況下,redo log由重做日志緩沖區(qū)寫入磁盤上的重做日志文件。

  • redo log buffer的日志占據(jù)redo log buffer總?cè)萘康囊话霑r(shí),將redo log寫入磁盤。
  • 一個(gè)事務(wù)提交時(shí),他的redo log都刷入磁盤,這樣可以保證數(shù)據(jù)絕不丟失(最常見的情況)。注意這時(shí)內(nèi)存中的臟頁可能尚未全部寫入磁盤。
  • 后臺(tái)線程定時(shí)刷新,有一個(gè)后臺(tái)線程每過一秒就將redo log寫入磁盤。
  • MySQL關(guān)閉時(shí),redo log都被寫入磁盤。

第一種情況和第四種情況一定會(huì)執(zhí)行redo log的寫入,第二種情況和第三種情況的執(zhí)行要根據(jù)參數(shù)innodb_flush_log_at_trx_commit的設(shè)定值,在下文會(huì)有詳細(xì)描述。

索引的創(chuàng)建也需要記錄redo log。

1.5 一個(gè)重做全過程的示例

以更新事務(wù)為例。

  • 將原始數(shù)據(jù)讀入內(nèi)存,修改數(shù)據(jù)的內(nèi)存副本。
  • 生成redo log并寫入重做日志緩沖區(qū),redo log中存儲(chǔ)的是修改后的新值。
  • 事務(wù)提交時(shí),將重做日志緩沖區(qū)中的內(nèi)容刷新到重做日志文件。
  • 隨后正常將內(nèi)存中的臟頁刷回磁盤。

1.6 持久性的保證

1.6.1 Force Log at Commit機(jī)制

Force Log at Commit機(jī)制實(shí)現(xiàn)了事務(wù)的持久性。在內(nèi)存中操作時(shí),日志被寫入重做日志緩沖區(qū)。但在事務(wù)提交之前,必須首先將所有日志寫入磁盤上的重做日志文件。

為了確保每個(gè)日志都寫入重做日志文件,必須使用一個(gè)fsync系統(tǒng)調(diào)用,確保OS buffer中的日志被完整地寫入磁盤上的log file。

fsync系統(tǒng)調(diào)用:需要你在入?yún)⒌奈恢蒙蟼鬟f給他一個(gè)fd,然后系統(tǒng)調(diào)用就會(huì)對(duì)這個(gè)fd指向的文件起作用。fsync會(huì)確保一直到寫磁盤操作結(jié)束才會(huì)返回,所以當(dāng)你的程序使用這個(gè)函數(shù)并且它成功返回時(shí),就說明數(shù)據(jù)肯定已經(jīng)安全的落盤了。所以fsync適合數(shù)據(jù)庫這種程序。

1.6.2 innodb_flush_log_at_trx_commit參數(shù)

InnoDB提供了一個(gè)參數(shù)innodb_flush_log_at_trx_commit控制日志刷新到磁盤的策略。

  • 當(dāng)innodb_flush_log_at_trx_commit值為1時(shí)(默認(rèn))。事務(wù)每次提交都必須將log buffer中的日志寫入os buffer并調(diào)用fsync()寫入磁盤中。

這種方式即使系統(tǒng)崩潰也不會(huì)丟失任何數(shù)據(jù),但是因?yàn)槊看翁峤欢紝懭氪疟P,IO性能較差。

  • 當(dāng)innodb_flush_log_at_trx_commit值為0時(shí)。事務(wù)提交時(shí)不將log buffer寫入到os buffer,而是每秒寫入os buffer并調(diào)用fsync()寫入到log file on disk中。

這實(shí)際上相當(dāng)于在內(nèi)存中維護(hù)了一個(gè)用戶設(shè)計(jì)的緩沖區(qū),它減少了和os buffer之間的數(shù)據(jù)傳輸,有更好的性能。

每秒寫入磁盤,系統(tǒng)崩潰會(huì)丟失1s的數(shù)據(jù)。

  • 當(dāng)innodb_flush_log_at_trx_commit值為2時(shí)。每次提交都僅寫入os buffer,然后每秒調(diào)用fsync()將os buffer中的日志寫入到log file on disk中。

雖然說我們是每秒調(diào)用fsync()將os buffer中的日志寫入到log file on disk中,但是平時(shí)即使不調(diào)用fsync,數(shù)據(jù)也會(huì)2自主地逐漸進(jìn)入磁盤。所以當(dāng)發(fā)生系統(tǒng)崩潰,相比第二種情況,會(huì)丟失較少的數(shù)據(jù)。

但同時(shí),由于每次提交都寫入os buffer,所以相比第二種情況,性能會(huì)差一些,但還是比第一種好的。

無論是哪種情況

1.6.3 一個(gè)小的性能測(cè)試

幾個(gè)選項(xiàng)之間的性能差距是極大的,下面做一個(gè)簡單的測(cè)試。

#創(chuàng)建測(cè)試表
drop table if exists test_flush_log;
create table test_flush_log(id int,name char(50))engine=innodb;

#創(chuàng)建插入指定行數(shù)的記錄到測(cè)試表中的存儲(chǔ)過程
drop procedure if exists proc;
delimiter $$
create procedure proc(i int)
begin
    declare s int default 1;
    declare c char(50) default repeat('a',50);
    while s=i do
        start transaction;
        insert into test_flush_log values(null,c);
        commit;
        set s=s+1;
    end while;
end$$
delimiter ;

下面均插入十萬條記錄。

Ⅰ 當(dāng)innodb_flush_log_at_trx_commit值為1時(shí)

test> call proc(100000)
[2021-07-25 13:22:02] completed in 27 s 350 ms

需要長達(dá)27.35s。

Ⅱ 當(dāng)innodb_flush_log_at_trx_commit值為2時(shí)

test> set @@global.innodb_flush_log_at_trx_commit=2;    
test> truncate test_flush_log;

test> call proc(100000)
[2021-07-25 13:27:33] completed in 5 s 774 ms

只需5.774s,性能大大提升。

Ⅲ 當(dāng)innodb_flush_log_at_trx_commit值為0時(shí)

test> set @@global.innodb_flush_log_at_trx_commit=0;
test> truncate test_flush_log;

test> call proc(100000)
[2021-07-25 13:30:34] completed in 3 s 537 ms

只需3.537s,性能更高。

顯然,innodb_flush_log_at_trx_commit值為1時(shí)性能差得非常明顯,改為0和2后性能都有大幅提升,其中0更快但相比2提升不大。

雖然改為0和2可以大幅提升性能,但會(huì)嚴(yán)重影響安全性。我們可以通過修改存儲(chǔ)過程,將事務(wù)的創(chuàng)建和提交放到循環(huán)外,統(tǒng)一提交,減少了IO頻率。

drop procedure if exists proc;
delimiter $$
create procedure proc(i int)
begin
    declare s int default 1;
    declare c char(50) default repeat('a',50);
    start transaction;
    while s=i DO
        insert into test_flush_log values(null,c);
        set s=s+1;
    end while;
    commit;
end$$
delimiter ;

1.6.4 迷你事務(wù)mini-transaction

mini-trasaction是InnoDB處理小型事務(wù)時(shí)使用的一種機(jī)制,它可以確保并發(fā)事務(wù)操作和數(shù)據(jù)庫異常發(fā)生時(shí),數(shù)據(jù)頁中的數(shù)據(jù)一致性。

迷你事務(wù)必須遵循下面三個(gè)協(xié)議:

  • FIX規(guī)則。寫時(shí)必須使用獨(dú)占鎖,讀時(shí)必須使用共享鎖。反正就是要鎖住。
  • 預(yù)寫日志。預(yù)寫日志即WAL,Write-Ahead Log。持久化數(shù)據(jù)之前,必須先持久化內(nèi)存中的日志。每個(gè)頁面都有一個(gè)LSN(日志序列號(hào))。在將數(shù)據(jù)寫入磁盤前,要先將內(nèi)存中序列號(hào)小于LSN的日志寫入磁盤。WAL提供三種持久化模式

最嚴(yán)格的是full-sync,fsync保證在返回之前將記錄刷新到磁盤,最大化了數(shù)據(jù)的安全性。

第二個(gè)級(jí)別是write-only,保證記錄寫入操作系統(tǒng)。這允許數(shù)據(jù)在進(jìn)程級(jí)別的崩潰后幸存。

最不嚴(yán)格的是no-sync,將記錄保存在內(nèi)存緩沖區(qū)中,不保證立即寫入文件系統(tǒng)。

強(qiáng)制日志再提交。即Force-log-at-commit,它要求提交事務(wù)時(shí)必須把所有迷你事務(wù)日志刷新到磁盤。

1.7 寫redo log的過程

如上圖,展示了redo log是如何被寫入log buffer的。每個(gè)mini-trasaction對(duì)應(yīng)于每個(gè)DML操作,例如更新語句等。

  • 每個(gè)數(shù)據(jù)修改后被寫入迷你事務(wù)私有緩沖區(qū)。
  • 當(dāng)更新語句完成,redo log從迷你事務(wù)私有緩沖區(qū)被寫入內(nèi)存中的公共日志緩沖區(qū)。
  • 提交外部事務(wù)時(shí),會(huì)將重做日志緩沖區(qū)刷入重做日志文件。

1.8 日志塊 log block

redo log以塊為單位進(jìn)行存儲(chǔ),每個(gè)塊大小為512字節(jié)。無論是在內(nèi)存重做日志緩沖區(qū)、操作系統(tǒng)緩沖區(qū)還是重做日志文件中,都是以這樣的512字節(jié)大小的塊進(jìn)行存儲(chǔ)的。

每個(gè)日志塊頭由以下四個(gè)部分組成

  • log_block_hdr_no:(4字節(jié))該日志塊在redo log buffer中的位置ID。
  • log_block_hdr_data_len:(2字節(jié))該log block中已記錄的log大小。寫滿該log block時(shí)為0x200,表示512字節(jié)。
  • log_block_first_rec_group:(2字節(jié))該log block中第一個(gè)log的開始偏移位置。
  • lock_block_checkpoint_no:(4字節(jié))寫入檢查點(diǎn)信息的位置。

1.9 log group

log group代表redo log的分組,由多個(gè)大小相同的redo log file組成。由一個(gè)參數(shù)innodb_log_files_group決定,默認(rèn)為2。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜img-qAyaSeL3543740G:61311akw89MySQL[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-h01w68EG-1627284031849)(G:\markdown\MySQL\image-20210726131134489.png)].png)]

這個(gè)group是邏輯上的概念,但可以通過變量 innodb_log_group_home_dir 來定義組的目錄,redo log file都放在這個(gè)目錄下,默認(rèn)是在datadir下。

2 撤銷日志undo log

2.1 關(guān)于undo log

undo log存在的意義是確保數(shù)據(jù)庫事務(wù)的原子性。

原子性是指事務(wù)是一個(gè)不可分割的工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。

  • edo log記錄了事務(wù)的行為,可以很好地保證一致性,對(duì)數(shù)據(jù)進(jìn)行“重做”操作。但事務(wù)有時(shí)還需要進(jìn)行“回滾”操作,這時(shí)就需要undo log。當(dāng)我們對(duì)記錄做了變更操作的時(shí)候就需要產(chǎn)生undo log,其中記錄的是老版本的數(shù)據(jù),當(dāng)舊事務(wù)需要讀取數(shù)據(jù)時(shí),可以順著undo鏈找到滿足其可見性地記錄。
  • undo log通常以邏輯日志的形式存在。我們可以認(rèn)為當(dāng)delete一條記錄時(shí),undo log會(huì)產(chǎn)生一條對(duì)應(yīng)的insert記錄,反之亦然。當(dāng)update一條記錄時(shí),會(huì)產(chǎn)生一條相反的update記錄。
  • undo log采用段segment的方式來記錄,每個(gè)undo操作在記錄的時(shí)候占用一個(gè)undo log segment。
  • undo log也會(huì)產(chǎn)生redo log,因?yàn)閡ndo log也要實(shí)現(xiàn)持久性保護(hù)。

undo log通常以邏輯日志的形式存在。我們可以認(rèn)為當(dāng)delete一條記錄時(shí),undo log會(huì)產(chǎn)生一條對(duì)應(yīng)的insert記錄,反之亦然。當(dāng)update一條記錄時(shí),會(huì)產(chǎn)生一條相反的update記錄。

undo log采用段segment的方式來記錄,每個(gè)undo操作在記錄的時(shí)候占用一個(gè)undo log segment。

undo log也會(huì)產(chǎn)生redo log,因?yàn)閡ndo log也要實(shí)現(xiàn)持久性保護(hù)。

2.2 undo log segment

為了保證事務(wù)并發(fā)操作時(shí),寫各自的undo log時(shí)不發(fā)生沖突,nnodb用段的方式管理undo log。rollback segment稱為回滾段,每個(gè)回滾段中有1024個(gè)undo log segment。MySQL5.5以后的版本支持128個(gè)rollback segment,就可以存儲(chǔ)128*1024個(gè)操作,還可以通過innodb_undo_logs參數(shù)定義盯梢個(gè)rollback segment。

2.3 purge

在聚集索引列的操作中,MySQL是這樣設(shè)計(jì)的。對(duì)一條delete語句

delete from t where a = 1

假如a有聚集索引(主鍵),那么不會(huì)進(jìn)行真正的刪除,而是在主鍵列等于1的記錄處設(shè)置delete flag為1,即把記錄保存在B+樹中。同理,對(duì)于update操作,不是直接更新記錄,而是把舊紀(jì)錄標(biāo)識(shí)為刪除,再創(chuàng)建一條新記錄。

那么,舊版本記錄什么時(shí)候真正的刪除呢?

InnoDB使用undo日志進(jìn)行舊版本的刪除操作,這個(gè)操作稱為purge操作。InnoDB開辟了purge線程進(jìn)行purge操作,并且可以控制purge線程的數(shù)量,每個(gè)purge線程每10s 進(jìn)行一次purge操作。

InnoDB的undo log設(shè)計(jì)

一個(gè)頁上允許多個(gè)事務(wù)的undo log存在,undo log的存儲(chǔ)順序是隨時(shí)的。InnoDB維護(hù)了一個(gè)history鏈表,按照事務(wù)提交的順序?qū)ndo log進(jìn)行連接。

在執(zhí)行purge過程中,InnoDB存儲(chǔ)引擎首先從history list中找到第一個(gè)需要被清理的記錄,這里為trx1,清理之后InnoDB存儲(chǔ)引擎會(huì)在trx1所在的Undo page中繼續(xù)尋找是否存在可以被清理的記錄,這里會(huì)找到事務(wù)trx3,接著找到trx5,但是發(fā)現(xiàn)trx5被其他事務(wù)所引用而不能清理,故再去history list中取查找,發(fā)現(xiàn)最尾端的記錄時(shí)trx2,接著找到trx2所在的Undo page,依次把trx6、trx4清理,由于Undo page2中所有的記錄都被清理了,因此該Undo page可以進(jìn)行重用。

InnoDB存儲(chǔ)引擎這種先從history list中找undo log,然后再從Undo page中找undo log的設(shè)計(jì)模式是為了避免大量隨機(jī)讀操作,從而提高purge的效率。

3 InnoDB的恢復(fù)操作

3.1 數(shù)據(jù)頁刷盤的規(guī)則和checkpoint

內(nèi)存中(buffer pool)未刷到磁盤的數(shù)據(jù)稱為臟數(shù)據(jù)(dirty data)。由于數(shù)據(jù)和日志都以頁的形式存在,所以臟頁表示臟數(shù)據(jù)和臟日志。

在InnoDB中,checkpoint是數(shù)據(jù)刷盤的唯一規(guī)則。checkpoint觸發(fā)后,會(huì)將內(nèi)存中的臟數(shù)據(jù)刷到磁盤。

innodb存儲(chǔ)引擎中checkpoint分為兩種:

  • sharp checkpoint:在重用redo log文件(例如切換日志文件)的時(shí)候,將所有已記錄到redo log中對(duì)應(yīng)的臟數(shù)據(jù)刷到磁盤。
  • fuzzy checkpoint:一次只刷一小部分的日志到磁盤,而非將所有臟日志刷盤。有以下幾種情況會(huì)觸發(fā)該檢查點(diǎn):

master thread checkpoint。由master線程控制,每秒或每10秒刷入一定比例的臟頁到磁盤。
flush_lru_list checkpoint。從MySQL5.6開始可通過 innodb_page_cleaners 變量指定專門負(fù)責(zé)臟頁刷盤的page cleaner線程的個(gè)數(shù),該線程的目的是為了保證lru列表有可用的空閑頁。
async/sync flush checkpoint。同步刷盤還是異步刷盤。例如還有非常多的臟頁沒刷到磁盤(非常多是多少,有比例控制),這時(shí)候會(huì)選擇同步刷到磁盤,但這很少出現(xiàn);如果臟頁不是很多,可以選擇異步刷到磁盤,如果臟頁很少,可以暫時(shí)不刷臟頁到磁盤
dirty page too much checkpoint。臟頁太多時(shí)強(qiáng)制觸發(fā)檢查點(diǎn),目的是為了保證緩存有足夠的空閑空間。too much的比例由變量 innodb_max_dirty_pages_pct 控制,MySQL 5.6默認(rèn)的值為75,即當(dāng)臟頁占緩沖池的百分之75后,就強(qiáng)制刷一部分臟頁到磁盤。

由于刷臟頁需要一定的時(shí)間來完成,所以記錄檢查點(diǎn)的位置是在每次刷盤結(jié)束之后才在redo log中標(biāo)記的。

3.2 LSN

3.2.1 LSN概念

LSN稱為日志的邏輯序列號(hào),在InnoDB中占用8個(gè)字節(jié)

我們可以通過LSN了解到下面這些信息:

  • 數(shù)據(jù)頁的版本信息。
  • 寫入的日志總量。
  • 檢查點(diǎn)的位置。

在下面兩個(gè)位置存在LSN:

  • redo log的記錄中。
  • 每個(gè)數(shù)據(jù)頁的頭部有一個(gè)變量fil_page_lsn記錄了本頁最終的LSN值是多少。

顯然,如果頁中的LSN值小于redo log中的LSN值,說明數(shù)據(jù)出現(xiàn)了丟失。

通過show engine innodb status可以查看當(dāng)前InnoDB的運(yùn)行信息,其中有一欄log中有關(guān)于lsn的記錄。

  • log sequence number記錄了當(dāng)前的redo log(in buffer)中的LSN。
  • log flushed up to是刷到磁盤重做日志文件中的LSN。
  • pages flushed up to是已經(jīng)刷到磁盤數(shù)據(jù)頁上的LSN。
  • last checkpoint at是上一次檢查點(diǎn)所在位置的LSN。

3.2.2 LSN處理流程

(1).首先修改內(nèi)存中的數(shù)據(jù)頁,并在數(shù)據(jù)頁中記錄LSN,暫且稱之為data_in_buffer_lsn;

(2).并且在修改數(shù)據(jù)頁的同時(shí)(幾乎是同時(shí))向redo log in buffer中寫入redo log,并記錄下對(duì)應(yīng)的LSN,暫且稱之為redo_log_in_buffer_lsn;

(3).寫完buffer中的日志后,當(dāng)觸發(fā)了日志刷盤的幾種規(guī)則時(shí),會(huì)向redo log file on disk刷入重做日志,并在該文件中記下對(duì)應(yīng)的LSN,暫且稱之為redo_log_on_disk_lsn;

(4).數(shù)據(jù)頁不可能永遠(yuǎn)只停留在內(nèi)存中,在某些情況下,會(huì)觸發(fā)checkpoint來將內(nèi)存中的臟頁(數(shù)據(jù)臟頁和日志臟頁)刷到磁盤,所以會(huì)在本次checkpoint臟頁刷盤結(jié)束時(shí),在redo log中記錄checkpoint的LSN位置,暫且稱之為checkpoint_lsn。

(5).要記錄checkpoint所在位置很快,只需簡單的設(shè)置一個(gè)標(biāo)志即可,但是刷數(shù)據(jù)頁并不一定很快,例如這一次checkpoint要刷入的數(shù)據(jù)頁非常多。也就是說要刷入所有的數(shù)據(jù)頁需要一定的時(shí)間來完成,中途刷入的每個(gè)數(shù)據(jù)頁都會(huì)記下當(dāng)前頁所在的LSN,暫且稱之為data_page_on_disk_lsn。

上圖中,從上到下的橫線分別代表:時(shí)間軸、buffer中數(shù)據(jù)頁中記錄的LSN(data_in_buffer_lsn)、磁盤中數(shù)據(jù)頁中記錄的LSN(data_page_on_disk_lsn)、buffer中重做日志記錄的LSN(redo_log_in_buffer_lsn)、磁盤中重做日志文件中記錄的LSN(redo_log_on_disk_lsn)以及檢查點(diǎn)記錄的LSN(checkpoint_lsn)。

假設(shè)在最初時(shí)(12:0:00)所有的日志頁和數(shù)據(jù)頁都完成了刷盤,也記錄好了檢查點(diǎn)的LSN,這時(shí)它們的LSN都是完全一致的。

假設(shè)此時(shí)開啟了一個(gè)事務(wù),并立刻執(zhí)行了一個(gè)update操作,執(zhí)行完成后,buffer中的數(shù)據(jù)頁和redo log都記錄好了更新后的LSN值,假設(shè)為110。這時(shí)候如果執(zhí)行 show engine innodb status 查看各LSN的值,即圖中①處的位置狀態(tài),結(jié)果會(huì)是:

log sequence number(110) > log flushed up to(100) = pages flushed up to = last checkpoint at

之后又執(zhí)行了一個(gè)delete語句,LSN增長到150。等到12:00:01時(shí),觸發(fā)redo log刷盤的規(guī)則(其中有一個(gè)規(guī)則是 innodb_flush_log_at_timeout 控制的默認(rèn)日志刷盤頻率為1秒),這時(shí)redo log file on disk中的LSN會(huì)更新到和redo log in buffer的LSN一樣,所以都等于150,這時(shí) show engine innodb status ,即圖中②的位置,結(jié)果將會(huì)是:

log sequence number(150) = log flushed up to > pages flushed up to(100) = last checkpoint at

再之后,執(zhí)行了一個(gè)update語句,緩存中的LSN將增長到300,即圖中③的位置。

假設(shè)隨后檢查點(diǎn)出現(xiàn),即圖中④的位置,正如前面所說,檢查點(diǎn)會(huì)觸發(fā)數(shù)據(jù)頁和日志頁刷盤,但需要一定的時(shí)間來完成,所以在數(shù)據(jù)頁刷盤還未完成時(shí),檢查點(diǎn)的LSN還是上一次檢查點(diǎn)的LSN,但此時(shí)磁盤上數(shù)據(jù)頁和日志頁的LSN已經(jīng)增長了,即:

log sequence number > log flushed up to 和 pages flushed up to > last checkpoint at

但是log flushed up to和pages flushed up to的大小無法確定,因?yàn)槿罩舅⒈P可能快于數(shù)據(jù)刷盤,也可能等于,還可能是慢于。但是checkpoint機(jī)制有保護(hù)數(shù)據(jù)刷盤速度是慢于日志刷盤的:當(dāng)數(shù)據(jù)刷盤速度超過日志刷盤時(shí),將會(huì)暫時(shí)停止數(shù)據(jù)刷盤,等待日志刷盤進(jìn)度超過數(shù)據(jù)刷盤。

等到數(shù)據(jù)頁和日志頁刷盤完畢,即到了位置⑤的時(shí)候,所有的LSN都等于300。

隨著時(shí)間的推移到了12:00:02,即圖中位置⑥,又觸發(fā)了日志刷盤的規(guī)則,但此時(shí)buffer中的日志LSN和磁盤中的日志LSN是一致的,所以不執(zhí)行日志刷盤,即此時(shí) show engine innodb status 時(shí)各種lsn都相等。

隨后執(zhí)行了一個(gè)insert語句,假設(shè)buffer中的LSN增長到了800,即圖中位置⑦。此時(shí)各種LSN的大小和位置①時(shí)一樣。

隨后執(zhí)行了提交動(dòng)作,即位置⑧。默認(rèn)情況下,提交動(dòng)作會(huì)觸發(fā)日志刷盤,但不會(huì)觸發(fā)數(shù)據(jù)刷盤,所以 show engine innodb status 的結(jié)果是:

log sequence number = log flushed up to > pages flushed up to = last checkpoint at

最后隨著時(shí)間的推移,檢查點(diǎn)再次出現(xiàn),即圖中位置⑨。但是這次檢查點(diǎn)不會(huì)觸發(fā)日志刷盤,因?yàn)槿罩镜腖SN在檢查點(diǎn)出現(xiàn)之前已經(jīng)同步了。假設(shè)這次數(shù)據(jù)刷盤速度極快,快到一瞬間內(nèi)完成而無法捕捉到狀態(tài)的變化,這時(shí) show engine innodb status 的結(jié)果將是各種LSN相等。

3.3 InnoDB的恢復(fù)行為

啟動(dòng)InnoDB時(shí),一定會(huì)進(jìn)行恢復(fù)操作,無論上次是因?yàn)槭裁丛蛲顺觥?/p>

checkpoint表示已經(jīng)完整刷到磁盤上data page上的LSN,因此恢復(fù)時(shí)僅需要恢復(fù)從checkpoint開始的日志部分。例如,當(dāng)數(shù)據(jù)庫在上一次checkpoint的LSN為10000時(shí)宕機(jī),且事務(wù)是已經(jīng)提交過的狀態(tài)。啟動(dòng)數(shù)據(jù)庫時(shí)會(huì)檢查磁盤中數(shù)據(jù)頁的LSN,如果數(shù)據(jù)頁的LSN小于日志中的LSN,則會(huì)從檢查點(diǎn)開始恢復(fù)。

還有一種情況,在宕機(jī)前正處于checkpoint的刷盤過程,且數(shù)據(jù)頁的刷盤進(jìn)度超過了日志頁的刷盤進(jìn)度。這時(shí)候一宕機(jī),數(shù)據(jù)頁中記錄的LSN就會(huì)大于日志頁中的LSN,在重啟的恢復(fù)過程中會(huì)檢查到這一情況,這時(shí)超出日志進(jìn)度的部分將不會(huì)重做,因?yàn)檫@本身就表示已經(jīng)做過的事情,無需再重做。

另外,事務(wù)日志具有冪等性,所以多次操作得到同一結(jié)果的行為在日志中只記錄一次。而二進(jìn)制日志不具有冪等性,多次操作會(huì)全部記錄下來,在恢復(fù)的時(shí)候會(huì)多次執(zhí)行二進(jìn)制日志中的記錄,速度就慢得多。例如,某記錄中id初始值為2,通過update將值設(shè)置為了3,后來又設(shè)置成了2,在事務(wù)日志中記錄的將是無變化的頁,根本無需恢復(fù);而二進(jìn)制會(huì)記錄下兩次update操作,恢復(fù)時(shí)也將執(zhí)行這兩次update操作,速度比事務(wù)日志恢復(fù)更慢。

到此這篇關(guān)于MySQL中的redo log和undo log的文章就介紹到這了,更多相關(guān)MySQL中的redo log和undo log內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • MySQL系列之redo log、undo log和binlog詳解
  • 詳解MySQL 重做日志(redo log)與回滾日志(undo logo)
  • MySQL 撤銷日志與重做日志(Undo Log與Redo Log)相關(guān)總結(jié)
  • 基于Redo Log和Undo Log的MySQL崩潰恢復(fù)解析
  • Mysql中undo、redo與binlog的區(qū)別淺析

標(biāo)簽:阿里 福州 溫州 揚(yáng)州 山西 定西 三明 無錫

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MySQL中的redo log和undo log日志詳解》,本文關(guān)鍵詞  MySQL,中的,redo,log,和,undo,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《MySQL中的redo log和undo log日志詳解》相關(guān)的同類信息!
  • 本頁收集關(guān)于MySQL中的redo log和undo log日志詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品
  • <rt id="w000q"><acronym id="w000q"></acronym></rt>
  • <abbr id="w000q"></abbr>
    <rt id="w000q"></rt>
    在线看的片片片免费| 一区二区三区在线观看动漫| 免费观看久久久4p| 在线免费播放av| 欧美日韩高清在线播放| 亚洲制服丝袜在线| 日本wwwxx| 欧美日韩精品一区二区在线播放 | 韩国理伦片一区二区三区在线播放 | 久久只精品国产| 理论片日本一区| 国产毛片久久久久久久| 欧美不卡视频一区| 看国产成人h片视频| 韩国三级hd中文字幕| 久久综合色之久久综合| 韩国欧美一区二区| 制服丨自拍丨欧美丨动漫丨| 亚洲国产精品99久久久久久久久| 国产成人免费在线视频| 波多野结衣在线网址| 亚洲色图在线视频| 4438x全国最大成人| 欧美久久久久久久久| 日本成人在线不卡视频| jizz中文字幕| 国产精品久久久一区麻豆最新章节| 粉嫩av一区二区三区在线播放| caoporn91| 亚洲一线二线三线久久久| 久久久久无码国产精品一区李宗瑞 | 99久久久无码国产精品衣服| 国产亚洲欧美在线| 成人精品视频一区二区三区| 欧美中文字幕久久 | 一本久久a久久精品亚洲| 亚洲免费av网站| 好男人香蕉影院| 久久影院视频免费| www.亚洲免费av| 欧美乱妇15p| 精品一区二区免费| 色妞www精品视频| 五月综合激情婷婷六月色窝| 成人无码av片在线观看| 亚洲欧美怡红院| 日批在线观看视频| 国产午夜三级一区二区三| 91在线无精精品入口| 91精品啪在线观看国产60岁| 激情综合五月婷婷| 欧洲激情一区二区| 麻豆91精品91久久久的内涵| 粉嫩av性色av蜜臀av网站| 亚洲成人免费av| 国产午夜精品久久久久久久久| 亚洲色图第一区| 最新中文字幕视频| 自拍偷拍亚洲综合| 黄色在线观看av| 亚洲视频在线一区| 公侵犯人妻一区二区三区| 亚洲欧洲日本在线| 亚洲专区区免费| 亚洲欧美经典视频| 91精品人妻一区二区三区| 亚洲日本中文字幕区| 公侵犯人妻一区二区三区| 综合激情网...| 欧美黄色激情视频| 亚洲午夜激情av| 日韩一卡二卡在线观看| 五月开心婷婷久久| 波多野结衣不卡视频| 蜜臀av一区二区在线免费观看| 色综合天天综合色综合av| 免费成人在线观看| 欧美三级三级三级| 成人丝袜高跟foot| 精品1区2区在线观看| 日本精品一二三区| 国产精品成人在线观看| 亚洲精品色午夜无码专区日韩| 一区二区国产盗摄色噜噜| 长河落日免费高清观看| 视频一区二区欧美| 欧美午夜不卡视频| 成人免费毛片aaaaa**| 精品久久久久久最新网址| 精品国产aⅴ一区二区三区东京热| 久久久久久免费网| 影音先锋人妻啪啪av资源网站| 亚洲欧美福利一区二区| 五月综合色婷婷| 精品在线一区二区三区| 日韩亚洲欧美一区| 国产高潮失禁喷水爽到抽搐 | 在线免费看黄视频| 亚洲va国产天堂va久久en| 91成人免费电影| 成人高清免费观看| 国产亚洲成aⅴ人片在线观看| 久久人人爽人人爽人人片| 亚洲国产一区视频| 欧洲激情一区二区| 99精品在线免费| 国产精品短视频| 欧美色视频一区二区三区在线观看| 蜜桃视频一区二区三区在线观看 | 97精品视频在线观看自产线路二| 国产丝袜欧美中文另类| 国产免费一区二区三区网站免费| 亚洲aⅴ怡春院| 欧美日韩在线精品一区二区三区激情 | 国产三级欧美三级| 尤物视频最新网址| 男人的j进女人的j一区| 91麻豆精品国产91久久久资源速度 | 欧美老女人在线| 少妇欧美激情一区二区三区| 亚洲精品欧美激情| 日本电影亚洲天堂一区| 91亚洲精华国产精华精华液| 国产精品大尺度| 色狠狠桃花综合| 美女被艹视频网站| 亚洲综合一区二区三区| 欧美日韩精品电影| 五月天激情小说| 人人狠狠综合久久亚洲| 日韩欧美在线不卡| 国产精成人品免费观看| 国模大尺度一区二区三区| 国产女人aaa级久久久级 | 国产精品久久久久久久久免费丝袜 | 少妇高潮在线观看| 粉嫩久久99精品久久久久久夜| 国产精品嫩草影院av蜜臀| 亚洲不卡在线播放| 99精品国产99久久久久久白柏| 亚洲女人小视频在线观看| 欧洲av在线精品| 亚洲图片欧美另类| 日韩av高清在线观看| 欧美成人一区二区三区在线观看| 在线观看福利片| 国产激情一区二区三区桃花岛亚洲| 中文字幕第一区综合| 色天天综合色天天久久| 欧美成人精品一区二区综合免费| 三级一区在线视频先锋| 精品久久免费看| 精品国产国产综合精品| 91免费视频大全| 亚洲gay无套男同| 精品国一区二区三区| 欧美风情第一页| 丰满人妻一区二区三区大胸| 日韩有码一区二区三区| 久久夜色精品一区| 老妇女50岁三级| 久久精品无码专区| 黄页视频在线91| 亚洲视频网在线直播| 91精品啪在线观看国产60岁| 在线看片中文字幕| 97久久久精品综合88久久| 图片区日韩欧美亚洲| 久久久五月婷婷| 欧洲一区在线观看| 麻豆国产精品一区| 国产成人aaaa| 亚洲不卡一区二区三区| 久久久久97国产精华液好用吗| 色综合久久久久综合体| 韩国无码一区二区三区精品| 国产乱码字幕精品高清av| 一区二区在线观看不卡| 精品久久久久香蕉网| 色婷婷亚洲精品| 性少妇bbw张开| 94-欧美-setu| 韩国午夜理伦三级不卡影院| 一区二区三区在线视频观看| 久久综合久久鬼色中文字| 欧美性感一类影片在线播放| 亚洲av无码一区二区三区人| 99久久er热在这里只有精品15| 麻豆精品精品国产自在97香蕉| 亚洲日本韩国一区| 精品理论电影在线| 欧美视频精品在线观看| 潮喷失禁大喷水aⅴ无码| 污网站免费观看| 粉嫩蜜臀av国产精品网站| 免费观看一级特黄欧美大片| 亚洲精品福利视频网站| 久久九九国产精品| 7777精品伊人久久久大香线蕉经典版下载 | 欧美亚洲综合另类|