MySQL面試題-日志(答案版)

在這里插入圖片描述

日志

1、為什么需要 undo log?

(1)實現事務回滾,保障事務的原子性。
事務處理過程中,如果出現了錯誤或者用戶執 行了 ROLLBACK 語句,MySQL 可以利用 undo log 中的歷史數據將數據恢復到事務開始之前的狀態。

undo log 是一種用于撤銷回退的日志。在事務沒提交之前,MySQL 會先記錄更新前的數據到 undo log 日志文件里面,當事務回滾時,可以利用 undo log 來進行回滾。

在插入一條記錄時,要把這條記錄的主鍵值記下來,這樣之后回滾時只需要把這個主鍵值對應的記錄刪掉就好了;
在刪除一條記錄時,要把這條記錄中的內容都記下來,這樣之后回滾時再把由這些內容組成的記錄插入到表中就好了;
在更新一條記錄時,要把被更新的列的舊值記下來,這樣之后回滾時再把這些列更新為舊值就好了。

在這里插入圖片描述
(2)實現 MVCC(多版本并發控制)關鍵因素之一。
MVCC 是通過 ReadView + undo log 實現的。undo log 為每條記錄保存多份歷史數據,MySQL 在執行快照讀(普通 select 語句)的時候,會根據事務的 Read View 里的信息,順著 undo log 的版本鏈找到滿足其可見性的記錄。

2、為什么需要 Buffer Pool?

MySQL 的數據都是存在磁盤中的,那么我們要更新一條記錄的時候,得先要從磁盤讀取該記錄,然后在內存中修改這條記錄。那修改完這條記錄是選擇直接寫回到磁盤,還是選擇緩存起來呢?

當然是緩存起來好,這樣下次有查詢語句命中了這條記錄,直接讀取緩存中的記錄,就不需要從磁盤獲取數據了。

為此,Innodb 存儲引擎設計了一個緩沖池(Buffer Pool),來提高數據庫的讀寫性能。

當讀取數據時,如果數據存在于 Buffer Pool 中,客戶端就會直接讀取 Buffer Pool 中的數據,否則再去磁盤中讀取。
當修改數據時,如果數據存在于 Buffer Pool 中,那直接修改 Buffer Pool 中數據所在的頁,然后將其頁設置為臟頁(該頁的內存數據和磁盤上的數據已經不一致),為了減少磁盤I/O,不會立即將臟頁寫入磁盤,后續由后臺線程選擇一個合適的時機將臟頁寫入到磁盤。

3、Buffer Pool 緩存什么?

(1)數據頁
(2)索引頁
(3)插入緩存頁
(4)undo頁
(5)自適應哈希索引
(6)鎖信息

開啟事務后,InnoDB 層更新記錄前,首先要記錄相應的 undo log,如果是更新操作,需要把被更新的列的舊值記下來,也就是要生成一條 undo log,undo log 會寫入 Buffer Pool 中的 Undo 頁面。

4、為什么需要 redo log ?

(1)實現事務的持久性,讓 MySQL 有 crash-safe 的能力
保證 MySQL 在任何時間段突然崩潰,重啟后之前已提交的記錄都不會丟失;

Buffer Pool 是提高了讀寫效率沒錯,但是問題來了,Buffer Pool 是基于內存的,而內存總是不可靠,萬一斷電重啟,還沒來得及落盤的臟頁數據就會丟失。

為了防止斷電導致數據丟失的問題,當有一條記錄需要更新的時候,InnoDB 引擎就會先更新內存(同時標記為臟頁),然后將本次對這個頁的修改以 redo log 的形式記錄下來,這個時候更新就算完成了。

后續,InnoDB 引擎會在適當的時候,由后臺線程將緩存在 Buffer Pool 的臟頁刷新到磁盤里,這就是 WAL (Write-Ahead Logging)技術

WAL 技術指的是, MySQL 的寫操作并不是立刻寫到磁盤上,而是先寫日志,然后在合適的時間再寫到磁盤上。

在這里插入圖片描述
(2)將寫操作從「隨機寫」變成了「順序寫」,提升 MySQL 寫入磁盤的性能。

我們思考一個問題,redo log 要寫到磁盤,數據也要寫磁盤,為什么要多此一舉?

寫入 redo log 的方式使用了追加操作, 所以磁盤操作是順序寫,而寫入數據需要先找到寫入位置,然后才寫到磁盤,所以磁盤操作是隨機寫。

磁盤的「順序寫 」比「隨機寫」 高效的多,因此 redo log 寫入磁盤的開銷更小。

5、什么是 redo log?

redo log 是物理日志,記錄了某個數據頁做了什么修改,比如對 XXX 表空間中的 YYY 數據頁 ZZZ 偏移量的地方做了AAA 更新,每當執行一個事務就會產生這樣的一條或者多條物理日志。

在事務提交時,只要先將 redo log 持久化到磁盤即可,可以不需要等到將緩存在 Buffer Pool 里的臟頁數據持久化到磁盤。

當系統崩潰時,雖然臟頁數據沒有持久化,但是 redo log 已經持久化,接著 MySQL 重啟后,可以根據 redo log 的內容,將所有數據恢復到最新的狀態。

6、產生的 redo log 是直接寫入磁盤的嗎?

實際上, 執行一個事務的過程中,產生的 redo log 也不是直接寫入磁盤的,因為這樣會產生大量的 I/O 操作,而且磁盤的運行速度遠慢于內存。

所以,redo log 也有自己的緩存—— redo log buffer,每當產生一條 redo log 時,會先寫入到 redo log buffer,后續在持久化到磁盤。

redo log buffer 默認大小 16 MB,可以通過 innodb_log_Buffer_size 參數動態的調整大小,增大它的大小可以讓 MySQL 處理「大事務」是不必寫入磁盤,進而提升寫 IO 性能。

在這里插入圖片描述

7、redo log 什么時候刷盤?

(1)MySQL 正常關閉時;
(2)當 redo log buffer 中記錄的寫入量大于 redo log buffer 內存空間的一半時,會觸發落盤;
(3)InnoDB 的后臺線程每隔 1 秒,將 redo log buffer 持久化到磁盤。
(4)每次事務提交時都將緩存在 redo log buffer 里的 redo log 直接持久化到磁盤(這個策略可由 innodb_flush_log_at_trx_commit 參數控制)

innodb_flush_log_at_trx_commit 參數:
01.當設置該參數為 0 時,表示每次事務提交時 ,還是將 redo log 留在 redo log buffer 中 ,該模式下在事務提交時不會主動觸發寫入磁盤的操作。
02.當設置該參數為 1 時,表示每次事務提交時,都將緩存在 redo log buffer 里的 redo log 直接持久化到磁盤,這樣可以保證 MySQL 異常重啟之后數據不會丟失。
03.當設置該參數為 2 時,表示每次事務提交時,都只是緩存在 redo log buffer 里的 redo log 寫到 redo log 文件,注意寫入到「 redo log 文件」并不意味著寫入到了磁盤,因為操作系統的文件系統中有個 Page Cache,Page Cache 是專門用來緩存文件數據的,所以寫入「 redo log文件」意味著寫入到了操作系統的文件緩存。
innodb_flush_log_at_trx_commit 為 02 的時候,InnoDB 的后臺線程每隔 1 秒落盤一次redo log

在這里插入圖片描述

8、redo log 文件寫滿了怎么辦?

默認情況下, InnoDB 存儲引擎有 1 個重做日志文件組( redo log Group),「重做日志文件組」由有 2 個 redo log 文件組成,這兩個 redo 日志的文件名叫 :ib_logfile0 和 ib_logfile1 。

在重做日志組中,每個 redo log File 的大小是固定且一致的,假設每個 redo log File 設置的上限是 1 GB,那么總共就可以記錄 2GB 的操作。

重做日志文件組是以循環寫的方式工作的,從頭開始寫,寫到末尾就又回到開頭,相當于一個環形。

所以 InnoDB 存儲引擎會先寫 ib_logfile0 文件,當 ib_logfile0 文件被寫滿的時候,會切換至 ib_logfile1 文件,當 ib_logfile1 文件也被寫滿時,會切換回 ib_logfile0 文件。

redo log 是循環寫的方式,相當于一個環形,InnoDB 用 write pos 表示 redo log 當前記錄寫到的位置,用 checkpoint 表示當前要擦除的位置:
在這里插入圖片描述
如果 write pos 追上了 checkpoint,就意味著 redo log 文件滿了,這時 MySQL 不能再執行新的更新操作,也就是說 MySQL 會被阻塞(因此所以針對并發量大的系統,適當設置 redo log 的文件大小非常重要),此時會停下來將 Buffer Pool 中的臟頁刷新到磁盤中,然后標記 redo log 哪些記錄可以被擦除,接著對舊的 redo log 記錄進行擦除,等擦除完舊記錄騰出了空間,checkpoint 就會往后移動(圖中順時針),然后 MySQL 恢復正常運行,繼續執行新的更新操作。

9、redo log和 binlog的區別

(1)適用對象不同:

binlog 是 MySQL 的 Server 層實現的日志,所有存儲引擎都可以使用;
redo log 是 Innodb 存儲引擎實現的日志;

(2)文件格式不同:

binlog 有 3 種格式類型,分別是 STATEMENT(默認格式)、ROW、 MIXEDSTATEMENT:每一條修改數據的 SQL 都會被記錄到 binlog 中,主從復制中 slave 端再根據 SQL 語句重現。但 STATEMENT 有動態函數的問題,比如你用了 uuid 或者 now 這些函數,你在主庫上執行的結果并不是你在從庫執行的結果,這種隨時在變的函數會導致復制的數據不一致;
ROW:記錄行數據最終被修改成什么樣了(這種格式的日志,就不能稱為邏輯日志了),不會出現 STATEMENT 下動態函數的問題。但 ROW 的缺點是每行數據的變化結果都會被記錄,比如執行批量 update 語句,更新多少行數據就會產生多少條記錄,使 binlog 文件過大,而在 STATEMENT 格式下只會記錄一個 update 語句而已;
MIXED:包含了 STATEMENT 和 ROW 模式,它會根據不同的情況自動使用 ROW 模式和 STATEMENT 模式;
redo log是物理日志,記錄的是在某個數據頁做了什么修改,比如對 XXX 表空間中的 YYY 數據頁 ZZZ 偏移量的地方做了AAA 更新;

(3)寫入方式不同

binlog 是追加寫,寫滿一個文件,就創建一個新的文件繼續寫,不會覆蓋以前的日志,保存的是全量的日志。
redo log 是循環寫,日志空間大小是固定,全部寫滿就從頭開始,保存未被刷入磁盤的臟頁日志。

(4)用途不同:

binlog 用于備份恢復、主從復制;
redo log 用于掉電等故障恢復。

10、如果不小心整個數據庫的數據被刪除了,能使用 redo log 文件恢復數據嗎?

不可以使用 redo log 文件恢復,只能使用 binlog 文件恢復。

因為 redo log 文件是循環寫,是會邊寫邊擦除日志的,只記錄未被刷入磁盤的數據的物理日志,已經刷入磁盤的數據都會從 redo log 文件里擦除。

binlog 文件保存的是全量的日志,也就是保存了所有數據變更的情況,理論上只要記錄在 binlog 上的數據,都可以恢復,所以如果不小心整個數據庫的數據被刪除了,得用 binlog 文件恢復數據。

11、主從復制的流程是怎么樣的?

(1)MySQL 主庫在收到客戶端提交事務的請求之后,會先寫入 binlog,再提交事務,更新存儲引擎中的數據,事務提交完成后,返回給客戶端“操作成功”的響應。
(2)從庫會創建一個專門的 I/O 線程,連接主庫的 log dump 線程,來接收主庫的 binlog 日志,再把 binlog 信息寫入 relay log 的中繼日志里,再返回給主庫“復制成功”的響應。
(3)從庫會創建一個用于回放 binlog 的線程,去讀 relay log 中繼日志,然后回放 binlog 更新存儲引擎中的數據,最終實現主從的數據一致性。

12、從庫是不是越多越好?

不是的。

因為從庫數量增加,從庫連接上來的 I/O 線程也比較多,主庫也要創建同樣多的 log dump 線程來處理復制的請求,對主庫資源消耗比較高,同時還受限于主庫的網絡帶寬。

13、MySQL 主從復制還有哪些模型?

(1)同步復制:MySQL 主庫提交事務的線程要等待所有從庫的復制成功響應,才返回客戶端結果。這種方式在實際項目中,基本上沒法用,原因有兩個:一是性能很差,因為要復制到所有節點才返回響應;二是可用性也很差,主庫和所有從庫任何一個數據庫出問題,都會影響業務。
(2)異步復制(默認模型):MySQL 主庫提交事務的線程并不會等待 binlog 同步到各從庫,就返回客戶端結果。這種模式一旦主庫宕機,數據就會發生丟失。
(3)半同步復制:MySQL 5.7 版本之后增加的一種復制方式,介于兩者之間,事務線程不用等待所有的從庫復制成功響應,只要一部分復制成功響應回來就行,比如一主二從的集群,只要數據成功復制到任意一個從庫上,主庫的事務線程就可以返回給客戶端。這種半同步復制的方式,兼顧了異步復制和同步復制的優點,即使出現主庫宕機,至少還有一個從庫有最新的數據,不存在數據丟失的風險。

14、binlog 什么時候刷盤?

binlog寫入流程:事務執行過程中,先把日志寫到 binlog cache(Server 層的 cache),事務提交的時候,再把 binlog cache 寫到 binlog 文件中,并清空 binlog cache。最后由配置決定binlog文件什么時候落到磁盤上。

一個事務的 binlog 是不能被拆開的,因此無論這個事務有多大(比如有很多條語句),也要保證一次性寫入。這是因為有一個線程只能同時有一個事務在執行的設定,所以每當執行一個 begin/start transaction 的時候,就會默認提交上一個事務,這樣如果一個事務的 binlog 被拆開的時候,在備庫執行就會被當做多個事務分段自行,這樣破壞了原子性,是有問題的。

MySQL 給每個線程分配了一片內存用于緩沖 binlog ,該內存叫 binlog cache,參數 binlog_cache_size 用于控制單個線程內 binlog cache 所占內存的大小。如果超過了這個參數規定的大小,就要暫存到磁盤。

雖然每個線程有自己 binlog cache,但是最終都寫到同一個 binlog 文件

在這里插入圖片描述
圖中的 write,指的就是指把日志寫入到 binlog 文件,但是并沒有把數據持久化到磁盤,因為數據還緩存在文件系統的 page cache 里,write 的寫入速度還是比較快的,因為不涉及磁盤 I/O。

圖中的 fsync,才是將數據持久化到磁盤的操作,這里就會涉及磁盤 I/O,所以頻繁的 fsync 會導致磁盤的 I/O 升高。

MySQL提供一個 sync_binlog 參數來控制數據庫的 binlog 刷到磁盤上的頻率:

01.sync_binlog = 0 的時候,表示每次提交事務都只 write,不 fsync,后續交由操作系統決定何時將數據持久化到磁盤;
02.sync_binlog = 1 的時候,表示每次提交事務都會 write,然后馬上執行 fsync;
03.sync_binlog =N(N>1) 的時候,表示每次提交事務都 write,但累積 N 個事務后才 fsync。

15、一條Update語句的完整過程

(1)執行器負責具體執行,會調用存儲引擎的接口,通過主鍵索引樹搜索獲取 id = 1 這一行記錄(在 buffer pool 中,就直接返回給執行器更新;不在 buffer pool,將數據頁從磁盤讀入到 buffer pool,返回記錄給執行器)
(2)執行器得到聚簇索引記錄后,會看一下更新前的記錄和更新后的記錄是否一樣(一樣就無需走后續流程,不一樣的話就把更新前的記錄和更新后的記錄都當作參數傳給 InnoDB 層,讓 InnoDB 真正的執行更新記錄的操作;)
(3)開啟事務, InnoDB 層更新記錄前,首先要記錄相應的 undo log,因為這是更新操作,需要把被更新的列的舊值記下來,也就是要生成一條 undo log,undo log 會寫入 Buffer Pool 中的 Undo 頁面,不過在內存修改該 Undo 頁面后,需要記錄對應的 redo log。
(4)InnoDB 層開始更新記錄,會先更新內存(同時標記為臟頁),然后將記錄寫到 redo log 里面,這個時候更新就算完成了。為了減少磁盤I/O,不會立即將臟頁寫入磁盤,后續由后臺線程選擇一個合適的時機將臟頁寫入到磁盤。這就是 WAL 技術,MySQL 的寫操作并不是立刻寫到磁盤上,而是先寫 redo 日志,然后在合適的時間再將修改的行數據寫到磁盤上。
(5)至此,一條記錄更新完了。
(6)在一條更新語句執行完成后,然后開始記錄該語句對應的 binlog,此時記錄的 binlog 會被保存到 binlog cache,并沒有刷新到硬盤上的 binlog 文件,在事務提交時才會統一將該事務運行過程中的所有 binlog 刷新到硬盤。
(7)事務提交,剩下的就是「兩階段提交」的事情了

16、為什么需要兩階段提交?

事務提交后,redo log 和 binlog 都要持久化到磁盤,但是這兩個是獨立的邏輯,可能出現半成功的狀態,這樣就造成兩份日志之間的邏輯不一致。

(1)如果在將 redo log 刷入到磁盤之后, MySQL 突然宕機了,而 binlog 還沒有來得及寫入。在主從架構中,binlog 會被復制到從庫,由于 binlog 丟失了某些更新語句,會導致主從數據不一致。
(2)如果在將 binlog 刷入到磁盤之后, MySQL 突然宕機了,而 redo log 還沒有來得及寫入。由于 redo log 還沒寫,崩潰恢復以后這個事務無效,主庫中可能丟失某些更新語句,binlog 會被復制到從庫,從庫執行了這些更新語句,也會導致主從數據不一致。

MySQL 為了避免出現兩份日志之間的邏輯不一致的問題,使用了「兩階段提交」來解決,兩階段提交其實是分布式事務一致性協議,它可以保證多個邏輯操作要不全部成功,要不全部失敗,不會出現半成功的狀態。

17、什么是兩階段提交?

在 MySQL 的 InnoDB 存儲引擎中,開啟 binlog 的情況下,MySQL 會同時維護 binlog 日志與 InnoDB 的 redo log,為了保證這兩個日志的一致性,MySQL 使用了內部 XA 事務,內部 XA 事務由 binlog 作為協調者,存儲引擎是參與者。

事務的提交過程有兩個階段,就是將 redo log 的寫入拆成了兩個步驟:prepare 和 commit,中間再穿插寫入binlog:

(1)prepare 階段:將 XID(內部 XA 事務的 ID) 寫入到 redo log,同時將 redo log 對應的事務狀態設置為 prepare,然后將 redo log 持久化到磁盤(innodb_flush_log_at_trx_commit = 1 的作用);

(2)commit 階段:把 XID 寫入到 binlog,然后將 binlog 持久化到磁盤(sync_binlog = 1 的作用),接著調用引擎的提交事務接口,將 redo log 狀態設置為 commit,此時該狀態并不需要持久化到磁盤,只需要 write 到文件系統的 page cache 中就夠了,因為只要 binlog 寫磁盤成功,就算 redo log 的狀態還是 prepare 也沒有關系,一樣會被認為事務已經執行成功;

在這里插入圖片描述

18、分析兩階段提交下異常重啟不會導致主從數據不一致。

在 MySQL 重啟后會按順序掃描 redo log 文件,碰到處于 prepare 狀態的 redo log,就拿著 redo log 中的 XID 去 binlog 查看是否存在此 XID:

(1)如果 binlog 中沒有當前內部 XA 事務的 XID,說明 redolog 完成刷盤,但是 binlog 還沒有刷盤,則回滾事務。
(2)如果 binlog 中有當前內部 XA 事務的 XID,說明 redolog 和 binlog 都已經完成了刷盤,則提交事務。

在這里插入圖片描述

對于處于 prepare 階段的 redo log,即可以提交事務,也可以回滾事務,這取決于是否能在 binlog 中查找到與 redo log 相同的 XID,如果有就提交事務,如果沒有就回滾事務。這樣就可以保證 redo log 和 binlog 這兩份日志的一致性了。

所以說,兩階段提交是以 binlog 寫成功為事務提交成功的標識,因為 binlog 寫成功了,就意味著能在 binlog 中查找到與 redo log 相同的 XID。

19、事務沒提交的時候,redo log 會被持久化到磁盤嗎?這樣會不會有問題?

事務執行中間過程的 redo log 也是直接寫在 redo log buffer 中的,這些緩存在 redo log buffer 里的 redo log 也會被「后臺線程」每隔一秒一起持久化到磁盤。也就是說,事務沒提交的時候,redo log 也是可能被持久化到磁盤的。

如果 mysql 崩潰了,還沒提交事務的 redo log 已經被持久化磁盤了,mysql 重啟后,數據不就不一致了?

這種情況 mysql 重啟會進行回滾操作,因為事務沒提交的時候,binlog 是還沒持久化到磁盤的。所以, redo log 可以在事務沒提交之前持久化到磁盤,但是 binlog 必須在事務提交之后,才可以持久化到磁盤。

20、兩階段提交存在什么問題?

兩階段提交雖然保證了兩個日志文件的數據一致性,但是性能很差,主要有兩個方面的影響:
(1)磁盤 I/O 次數高:對于“雙1”配置,每個事務提交都會進行兩次 fsync(刷盤),一次是 redo log 刷盤,另一次是 binlog 刷盤。

binlog 和 redo log 在內存中都對應的緩存空間,binlog 會緩存在 binlog cache,redo log 會緩存在 redo log buffer,它們持久化到磁盤的時機分別由下面這兩個參數控制。一般我們為了避免日志丟失的風險,會將這兩個參數設置為 1:
01.當 sync_binlog = 1 的時候,表示每次提交事務都會將 binlog cache 里的 binlog 直接持久到磁盤;
02.當 innodb_flush_log_at_trx_commit = 1 時,表示每次事務提交時,都將緩存在 redo log buffer 里的 redo log 直接持久化到磁盤;

(2)鎖競爭激烈:兩階段提交雖然能夠保證「單事務」兩個日志的內容一致,但在「多事務」的情況下,卻不能保證兩者的提交順序一致,因此,在兩階段提交的流程基礎上,還需要加一個鎖來保證提交的原子性,從而保證多事務的情況下,兩個日志的提交順序一致。

在早期的 MySQL 版本中,通過使用 prepare_commit_mutex 鎖來保證事務提交的順序,在一個事務獲取到鎖時才能進入 prepare 階段,一直到 commit 階段結束才能釋放鎖,下個事務才可以繼續進行 prepare 操作。
通過加鎖雖然完美地解決了順序一致性的問題,但在并發量較大的時候,就會導致對鎖的爭用,性能不佳。

21、怎么解決兩階段提交的問題?

MySQL 引入了 binlog 組提交(group commit)機制,當有多個事務提交的時候,會將多個 binlog 刷盤操作合并成一個,從而減少磁盤 I/O 的次數,如果說 10 個事務依次排隊刷盤的時間成本是 10,那么將這 10 個事務一次性一起刷盤的時間成本則近似于 1。

22、詳細說說兩階段提交的流程。

(1)flush 階段

第一個事務會成為 flush 階段的 Leader,此時后面到來的事務都是 Follower獲取隊列中的事務組,由事務組的 Leader 對 rodo log 做一次 write + fsync,即一次將同組事務的 redolog 刷盤:完成了 prepare 階段后,將這一組事務執行過程中產生的 binlog 寫入 binlog 文件(調用 write,不會調用 fsync,所以不會刷盤,binlog 緩存在操作系統的文件系統中)。

(2)sync 階段

一組事務的 binlog 寫入到 binlog 文件后,并不會馬上執行刷盤的操作,而是會等待一段時間,這個等待的時長由 Binlog_group_commit_sync_delay 參數控制,目的是為了組合更多事務的 binlog,然后再一起刷盤在等待的過程中,如果事務的數量提前達到了 Binlog_group_commit_sync_no_delay_count 參數設置的值,就不用繼續等待了,就馬上將 binlog 刷盤binlog_group_commit_sync_delay= N,表示在等待 N 微妙后,直接調用 fsync,將處于文件系統中 page cache 中的 binlog 刷盤,也就是將「 binlog 文件」持久化到磁盤。
binlog_group_commit_sync_no_delay_count = N,表示如果隊列中的事務數達到 N 個,就忽視binlog_group_commit_sync_delay 的設置,直接調用 fsync,將處于文件系統中 page cache 中的 binlog 刷盤。

(3)commit 階段

調用引擎的提交事務接口,將 redo log 狀態設置為 commit。

23、組提交發現MySQL的IO還是很高,有什么辦法優化?

現在我們知道事務在提交的時候,需要將 binlog 和 redo log 持久化到磁盤,那么如果出現 MySQL 磁盤 I/O 很高的現象,我們可以通過控制以下參數,來 “延遲” binlog 和 redo log 刷盤的時機,從而降低磁盤 I/O 的頻率:

(1)設置組提交的兩個參數: binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count 參數,延遲 binlog 刷盤的時機,從而減少 binlog 的刷盤次數。

這個方法是基于“額外的故意等待”來實現的,因此可能會增加語句的響應時間,但即使 MySQL 進程中途掛了,也沒有丟失數據的風險,因為 binlog 早被寫入到 page cache 了,只要系統沒有宕機,緩存在 page cache 里的 binlog 就會被持久化到磁盤。

(2)將 sync_binlog 設置為大于 1 的值(比較常見是 100~1000),表示每次提交事務都 write,但累積 N 個事務后才 fsync,相當于延遲了 binlog 刷盤的時機。

這樣做的風險是,主機掉電時會丟 N 個事務的 binlog 日志。

(3)將 innodb_flush_log_at_trx_commit 設置為 2。表示每次事務提交時,都只是緩存在 redo log buffer 里的 redo log 寫到 redo log 文件

注意寫入到「 redo log 文件」并不意味著寫入到了磁盤,因為操作系統的文件系統中有個 Page Cache,專門用來緩存文件數據的,所以寫入「 redo log文件」意味著寫入到了操作系統的文件緩存,然后交由操作系統控制持久化到磁盤的時機。但是這樣做的風險是,主機掉電的時候會丟數據。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/718593.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/718593.shtml
英文地址,請注明出處:http://en.pswp.cn/news/718593.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ssh無法直接登入Linux超級用戶root(23/3/3更新)

說明:不允許ssh用超級用戶的身份登入是為了安全性,如果只是學習使用對安全性沒啥要求可以按以下操作解除限制 以普通用戶登錄到服務器后,執行以下命令以編輯 SSH 服務器配置文件 /etc/ssh/sshd_config sudo nano /etc/ssh/sshd_config 此時會…

【C++練級之路】【Lv.10】【STL】priority_queue類和反向迭代器的模擬實現

快樂的流暢:個人主頁 個人專欄:《C語言》《數據結構世界》《進擊的C》 遠方有一堆篝火,在為久候之人燃燒! 文章目錄 一、仿函數1.1 仿函數的介紹1.2 仿函數的優勢 二、priority_queue2.1 push2.2 pop2.3 top2.4 size2.5 empty 三、…

【3D Slicer】心臟CT圖像分割操作保姆級教程 Cardiac CT image segmentation

心臟CT圖像分割操作流程指南 1 安裝3D Slicer軟件2 打開文件2.1 從File->Add Data->Choose File2.2 直接拖入 3 進行分割操作4 切片填充 Fill between slices5 第二個例子6 數據保存7 打開保存后的文件 1 安裝3D Slicer軟件 方式二選一 1.官網:3D Slicer 2.百…

JNI方案說明和使用方法介紹

JNI簡介 JNI(Java Native Interface)是Java編程語言中用于實現Java代碼與本地(Native)代碼(通常是C或C++代碼)交互的機制。它允許Java應用程序調用本地代碼中的功能,也可以讓本地代碼調用Java類和方法。JNI在Java平臺上實現了Java與其他編程語言的互操作性。(即可互相…

無字母數字rce總結(自增、取反、異或、或、臨時文件上傳)

目錄 自增 取反 異或 或 臨時文件上傳 自增 自 PHP 8.3.0 起,此功能已軟棄用 在 PHP 中,可以遞增非數字字符串。該字符串必須是字母數字 ASCII 字符串。當到達字母 Z 且遞增到下個字母時,將進位到左側值。例如,$a Z; $a;將…

C++知識點總結(23):高級模擬算法

高級模擬算法例題 一、P5661 公交換乘1. 審題2. 思路3. 參考答案 二、P1003 鋪地毯1. 審題2. 參考答案 三、P1071 潛伏者1. 審題2. 思路3. 參考答案 一、P5661 公交換乘 1. 審題 2. 思路 總花費中,地鐵是必須花費的,公交車可能不花錢(坐地…

使用VisualDL進行模型訓練和數據可視化

文章目錄 使用VisualDL進行模型訓練和數據可視化1. 環境準備1.1 安裝VisualDL1.2 設置VisualDL 2. 寫入數據并可視化2.1 檢查訓練數據2.2 跟蹤模型訓練2.3 評估模型訓練效果 3. 啟動VisualDL服務4. 總結 使用VisualDL進行模型訓練和數據可視化 VisualDL是飛槳提供的一個可視化…

Java中的Object類詳解

Java中的Object類詳解 1. equals(Object obj)2. hashCode()3. toString()4.getClass()5.notify() 和 notifyAll()6. wait() 和 wait(long timeout)7. clone()8.finalize() Java中的 Object 類是所有類的父類,可以被所有Java類繼承并使用。下面先看下源碼&#xff1a…

google最新大語言模型gemma本地化部署

Gemma是google推出的新一代大語言模型,構建目標是本地化、開源、高性能。 與同類大語言模型對比,它不僅對硬件的依賴更小,性能卻更高。關鍵是完全開源,使得對模型在具有行業特性的場景中,有了高度定制的能力。 Gemma模…

革新商務數據體驗:引領市場的API商品數據接口

在當今商業環境中,革新商務數據體驗對于維持競爭優勢至關重要。API商品數據接口在這一轉型過程中扮演了核心角色,它不僅為企業提供了實時且全面的數據訪問能力,而且還極大地增強了數據的可操作性和決策支持功能。以下是API商品數據接口如何細…

面試數據庫篇(mysql)- 12分庫分表

拆分策略 垂直分庫 垂直分庫:以表為依據,根據業務將不同表拆分到不同庫中。 特點: 按業務對數據分級管理、維護、監控、擴展在高并發下,提高磁盤IO和數據量連接數垂直分表:以字段為依據,根據字段屬性將不同字段拆分到不同表中。 特點: 1,冷熱數據分離 2,減少IO過渡爭…

C語言入門到精通之練習42:畫圖,學用圓畫圓形。

題目&#xff1a;畫圖&#xff0c;學用圓畫圓形。 程序分析&#xff1a;無。 實例 #include <graphics.h> //VC6.0中是不能運行的&#xff0c;要在Turbo2.0/3.0中 int main() { int driver,mode,i; float j1,k1; driverVGA; modeVGAHI; initgraph(&d…

【Micropython基礎】TCP客戶端與服務器

文章目錄 前言一、連接Wifi1.1 創建STA接口1.2 激活wifi接口1.3 連接WIFI1.4 判斷WIFI是否連接1.5 連接WIFI總體代碼 二、創建TCP 客戶端2.1 創建套接字2.2 設置TCP服務器的ip地址和端口2.3 連接TCP服務器2.3 發送數據2.4 接收數據2.5 斷開連接2.6 示例代碼 三、TCP服務器的創建…

批量二維碼的教程和優勢:拓寬應用領域,提升效率與創新

隨著二維碼技術的不斷發展&#xff0c;批量二維碼在多個領域展現出了顯著的優勢&#xff0c;為商業和行業帶來了更多便捷和創新。以下是批量二維碼的一些顯著優勢&#xff1a; 1. 高效快速生成&#xff1a; 批量二維碼一次性生成多個二維碼&#xff0c;相較于逐個生成的方式&…

Linux之進程信號

目錄 一、概念引入 1、生活中的信號 2、Linux中的信號 二、信號處理常見方式 三、信號的產生 1、鍵盤產生信號 2、系統調用接口產生信號 3、軟件條件產生信號 4、硬件異常產生信號 四、信號的保存 相關概念 信號保存——三個數據結構 信號集——sigset_t 信號集操…

超簡單的chatgpt-next-web部署教程!

隨著AI的應用變廣&#xff0c;各類AI程序已逐漸普及&#xff0c;尤其是在一些日常辦公、學習等與撰寫/翻譯文稿密切相關的場景&#xff0c;大家都希望找到一個適合自己的穩定可靠的ChatGPT軟件來使用。 ChatGPT-Next-Web就是一個很好的選擇。它是一個Github上超人氣的免費開源…

Docker基礎教程 - 1 Docker簡介

更好的閱讀體驗&#xff1a;點這里 &#xff08; www.doubibiji.com &#xff09; 1 Docker簡介 Docker是一個強大的容器化平臺&#xff0c;讓你能夠更輕松地構建、部署和運行應用程序。 下面我們來學習 Docker。 1.1 Docker是什么 1 現在遇到的問題 每次部署一臺服務器&…

CSS 入門指南(一)CSS 概述

CSS 概述 CSS 介紹 CSS&#xff08;Cascading Style Sheets&#xff09;通常稱為 CSS 樣式或層疊樣式表&#xff0c;是一種用來為結構化文檔&#xff08;如 HTML 文檔或 XML 應用&#xff09;添加樣式&#xff08;字體、間距和顏色等&#xff09;以及版面的布局等外觀顯示樣式…

《MySQL數據庫》day1

文章目錄 1.名詞解釋2.如何啟動mysql數據庫3.mysql常用命令4.數據庫當中最基本的單元是表&#xff1a;table5.關于SQL語句的分類6.簡單查詢7.條件查詢8.排序9.數據處理函數單行處理函數常見的有哪些&#xff1f; 10.分組函數&#xff08;多行處理函數&#xff09; 1.名詞解釋 …

VUE2與VUE3之間的主要區別

當談到 Vue.js 的版本時&#xff0c;Vue 2 和 Vue 3 是最常被提及的兩個版本。下面是 Vue 2 和 Vue 3 之間的一些主要區別&#xff1a; 1. 性能提升&#xff1a; Vue 3 在底層核心重寫了響應式系統&#xff0c;采用了 Proxy 對象&#xff0c;大幅提高了性能。Vue 3 還引入了靜…