您好,登錄后才能下訂單哦!
這篇文章主要介紹了MySQL的基礎架構和日志系統實例分析的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇MySQL的基礎架構和日志系統實例分析文章都會有所收獲,下面我們一起來看看吧。
MySQL可以分為Server層和存儲引擎層兩部分
Server層包括連接器、查詢緩存、分析器、優化器、執行器等,涵蓋MySQL的大多數核心服務功能,以及所有的內置函數(如日期、時間、數學和加密函數等),所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器、視圖等
存儲引擎負責數據的存儲和提取。其架構模式是插件式的,支持InnoDB、MyISAM、Memory等多個存儲引擎。現在最常用的存儲引擎是InnoDB,它從MySQL 5.5.5版本開始成為了默認存儲引擎。可以通過在SQL語句中使用engin=memory來指定使用內存引擎執行
不同的存儲引擎共用一個Server層
連接器負責跟客戶端建立連接、獲取權限、維持和管理連接。連接命令一般是:
mysql -h$ip -P$port -u$user -p
連接命令中的mysql是客戶端工具,用來跟服務端建立連接。在完成TCP握手后,連接器就要開始認證身份
如果用戶名或密碼不對,就會收到一個"Access denied for user"的錯誤,然后客戶端程序結束執行
如果用戶名密碼認證通過,連接器回到權限表里面查出你擁有的權限。之后,這個連接里面的權限判斷邏輯,都將依賴于此時讀到的權限
這就意味著,一個用戶成功建立連接后,即使用管理員帳號對這個用戶的權限做了修改,也不會影響已經存在連接的權限。修改完成后,只有再新建的連接才會使用新的權限設置
連接完成后,如果你沒有后續的動作,這個連接就處于空閑狀態,可以在show processlist命令中看到它
Command為Sleep表示此連接是一個空閑連接
客戶端如果太長時間沒動靜,連接器就會自動將它斷開。這個時間是由參數wait_timeout控制的。默認值是8小時
如果在連接被斷開之后,客戶端再次發送請求的話,就會收到一個錯誤提示:Lost connection to MySQL server during query。這時候就需要重新連接,然后在執行請求了
數據庫里面,長連接是指連接成功后,如果客戶端持續有請求,則一直使用同一個連接。短連接則是指每次執行完很少的幾次查詢就斷開連接,下次查詢再重新建立一個
建立連接的過程通常是比較復雜的,所以建議盡量使用長連接
但是全部使用長連接后,有些時候MySQL占用內存漲得特別快,這是因為MySQL在執行過程中臨時使用的內存是管理在連接對象里面的。這些資源會在連接斷開的時候才釋放。所以如果長連接累計下來,可能導致內存占用太大,被系統強行殺掉(OOM),從現象看就是MySQL異常重啟了
可以通過以下兩種方案解決這個問題:
1.定期斷開長連接。使用一段時間,或者程序里面判斷執行過一個占用內存的大查詢后,斷開連接,之后要查詢再重連
2.如果使用的是MySQL5.7或更新版本,可以在每次執行一個比較大的操作后,通過執行mysql_reset_connection來重新初始化連接資源。這個過程不需要重連和重新做權限驗證,但是會將連接恢復到剛剛創建完時的狀態
建立連接完成后,可以執行select語句了。MySQL拿到一個查詢請求后,會先到查詢緩存看看,之前是不是執行過這條語句。之前執行過的語句及其結果可能會以key-value對的形式,被直接緩存在內存中。key是查詢的語句,value是查詢的結果。如果查詢能夠直接在這個緩存中找到key,那么這個value就會被直接返回給客戶端
如果語句不在查詢緩存中,就會繼續后面的執行階段。執行完成后,執行結果會被存入查詢緩存中。如果查詢命中緩存,MySQL不需要執行后面的復雜操作,就可以直接返回結果,這個效率很高
但是大多數情況下不建議使用查詢緩存,因為查詢緩存的失效非常頻繁,只要對一個表的更新,這個表上所有的查詢緩存都會被清空。對于更新壓力大的數據庫來說,查詢緩存的命中率會非常低
可以將參數query_cache_type設置成DEMAND,這樣對于默認的SQL語句都不使用查詢緩存。而對于確定要是查詢緩存的語句,可以用SQL_CACHE顯示指定,如下面這條語句一樣:
select SQL_CACHE * from T where ID=10;
MySQL8.0版本直接將查詢緩存的整塊功能刪掉了
如果沒有命中查詢緩存,就要開始真正執行語句了。MySQL首先要對SQL語句做解析
分析器會先做詞法分析。輸入的是由多個字符串和空格組成的一條SQL語句,MySQL需要識別出里面的字符串分別是什么,代表什么
select * from T where ID=10;
MySQL從輸入的select這個關鍵字識別出來,這是一個查詢語句。它也要把字符串T識別成表名T,把字符串ID識別成列ID
做完了這些識別以后,就要做語法分析。根據詞法分析的結果,語法分析器會根據語法規則,判斷這個SQL語句是否滿足MySQL語法。如果語法不對,就會收到"You have an error in your SQL syntax"的錯誤提示
經過了分析器,在開始執行之前,還要先經過優化器的處理
優化器是在表里面有多個索引的時候,決定使用哪個索引;或者在一個語句有多表關聯的時候,決定各個表的連接順序
優化器階段完成后,這個語句的執行方案就確定下來了,然后進入執行器階段,開始執行語句
開始執行的時候,要先判斷一下你對這個表T有沒有執行查詢的權限,如果沒有,就會返回沒有權限的錯誤,如下所示
mysql> select * from T where ID=10; ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'
如果有權限,就打開表繼續執行。打開表的時候,執行器就會根據表的引擎定義,去使用這個引擎提供的接口
比如在表T中,ID字段沒有索引,那么執行器的執行流程是這樣的:
1.調用InnoDB引擎接口取這個表的第一行,判斷ID值是不是10,如果不是則跳過,如果是則將這個行存在結果集中
2.調用引擎接口取下一行,重復相同的判斷邏輯,直到取到這個表的最后一行
3.執行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結果集返回給客戶端
在數據庫的慢查詢日志中看到一個rows_examined的字段,表示這個語句執行過程掃描了多少行。這個值就是在執行器每次調用引擎獲取數據行的時候累加的
在有些場景下,執行器調用一次,在引起內部則掃描了多行,因此引擎掃描行數跟rows_examined并不是完全相同的
表T的創建語句如下,這個表有一個主鍵ID和一個整型字段c:
create table T(ID int primary key, c int);
如果要將ID=2這一行的值加1,SQL語句如下:
update T set c=c+1 where ID=2;
在MySQL中,如果每次的更新操作都需要寫進磁盤,然后磁盤也要找到對應的那條記錄,然后再更新,整個過程IO成本、查找成本都很高。MySQL里常說的WAL技術,全稱是Write-Ahead Logging,它的關鍵點就是先寫日志,再寫磁盤
當有一條記錄需要更新的時候,InnoDB引擎就會把記錄寫到redo log里面,并更新buffer pool的page,這個時候更新就算完成了
buffer pool是物理頁的緩存,對InnoDB的任何修改操作都會首先在buffer pool的page上進行,然后這樣的頁面將被標記為臟頁并被放到專門的flush list上,后續將由專門的刷臟線程階段性的將這些頁面寫入磁盤
InnoDB的redo log是固定大小的,比如可以配置為一組4個文件,每個文件的大小是1GB,從頭開始寫,寫到末尾就又回到開頭循環寫
write pos是當前記錄的位置,一邊寫一邊后移,寫到第3號文件末尾后就回到0號文件開頭。check point是當前要擦除的位置,也是往后推移并且循環的,擦除記錄前要把記錄更新到數據文件
write pos和check point之間空著的部分,可以用來記錄新的操作。如果write pos追上check point,這時候不能再執行新的更新,需要停下來擦掉一些記錄,把check point推進一下
有了redo log,InnoDB就可以保證即使數據庫發生異常重啟,之前提交的記錄都不會丟失,這個能力稱為crash-safe
MySQL整體來看就有兩塊:一塊是Server層,主要做的是MySQL功能層面的事情;還有一塊是引擎層,負責存儲相關的具體事宜。redo log是InnoDB引擎特有的日志,而Server層也有自己的日志,稱為binlog
為什么會有兩份日志?
因為最開始MySQL里并沒有InnoDB引擎。MySQL自帶的引擎是MyISAM,但是MyISAM沒有crash-safe的能力,binlog日志只能用于歸檔。而InnoDB是以插件形式引入MySQL的,既然只依靠binlog是沒有crash-safe能力的,所以InnoDB使用redo log來實現crash-safe能力
binlog的日志格式:
binlog的格式有三種:STATEMENT,ROW,MIXED
1)、STATEMENT模式
binlog里面記錄的就是SQL語句的原文。優點是并不需要記錄每一行的數據變化,減少了binlog日志量,節約IO,提高性能。缺點是在某些情況下會導致master-slave中的數據不一致(如sleep()函數, last_insert_id(),以及user-defined functions(udf)等會出現問題)
2)、ROW模式
不記錄每條SQL語句的上下文信息,僅需記錄哪條數據被修改了,修改成什么樣了。而且不會出現某些特定情況下的存儲過程或function或trigger的調用和觸發無法被正確復制的問題。缺點是會產生大量的日志,尤其是alter table的時候會讓日志暴漲
3)、MIXED模式
以上兩種模式的混合使用,一般的復制使用STATEMENT模式保存binlog,對于STATEMENT模式無法復制的操作使用ROW模式保存binlog,MySQL會根據執行的SQL語句選擇日志保存方式
1.redo log是InnoDB引擎特有的;binlog是MySQL的Server層實現的,所有引擎都可以使用
2.redo log是物理日志,記錄的是在某個數據也上做了什么修改;binlog是邏輯日志,記錄的是這個語句的原始邏輯,比如給ID=2這一行的c字段加1
3.redo log是循環寫的,空間固定會用完;binlog是可以追加寫入的,binlog文件寫到一定大小后會切換到下一個,并不會覆蓋以前的日志
執行器和InnoDB引擎在執行這個update語句時的內部流程:
1.執行器先找到引擎取ID=2這一行。ID是主鍵,引擎直接用樹搜索找到這一行。如果ID=2這一行所在的數據也本來就在內存中,就直接返回給執行器;否則,需要先從磁盤讀入內存,然后再返回
2.執行器拿到引擎給的行數據,把這個值加上1,得到新的一行數據,再調用引擎接口寫入這行新數據
3.引擎將這行新數據更新到內存中,同時將這個更新操作記錄到redo log里面,此時redo log處于prepare狀態。然后告知執行器執行完成了,隨時可以提交事務
4.執行器生成這個操作的binlog,并把binlog寫入磁盤
5.執行器調用引擎的提交事務接口,引擎把剛剛寫入的redo log改成提交狀態,更新完成
update語句的執行流程圖如下,圖中淺色框表示在InnoDB內部執行的,深色框表示是在執行器中執行的
將redo log的寫入拆成了兩個步驟:prepare和commit,這就是兩階段提交
由于redo log和binlog是兩個獨立的邏輯,如果不用兩階段提交,要么就是先寫完redo log再寫binlog,或者先寫完binlog再寫redo log
1.先寫完redo log再寫binlog。如果在redo log寫完,binlog還沒有寫完的時候,MySQL進程異常重啟。由于redo log寫完之后,系統即使崩潰,仍然能夠把數據恢復回來,所以恢復后這一行c的值是1。但是由于binlog還沒寫完就crash了,這時候binlog里面就沒有記錄這個語句,binlog中記錄的這一行c的值為0
2.先寫binlog后寫redo log。如果在binlog寫完之后crash,由于redo log還沒寫,崩潰恢復以后這個事務無效,所以這一行的c的值是0。但是binlog里面已經記錄了把c從0改成1這個日志。所以,在之后binlog來恢復的時候就多了一個事務出來,恢復出來的這一行c的值就是1
如果不使用兩階段提交,那么數據庫的狀態就有可能和用它的日志恢復出來的庫的狀態不一致。redo log和binlog都可以用于表示事務的提交狀態,而兩階段提交就是讓這兩個狀態保持邏輯上的一致
redo log用于保證crash-safe能力。innodb_flush_log_at_trx_commit這個參數設置成1的時候,表示每次事務的redo log都直接持久化到磁盤,這樣可以保證MySQL異常重啟之后數據不丟失
sync_binlog這個參數設置成1的時候,表示每次事務的binlog都持久化到磁盤,這樣可以保證MySQL異常重啟之后binlog不丟失
當內存數據頁跟磁盤數據頁不一致的時候,我們稱這個內存頁為臟頁。內存數據寫入到磁盤后,內存和磁盤行的數據頁的內容就一致了,稱為干凈頁
第一種場景是,InnoDB的redo log寫滿了,這時候系統會停止所有更新操作,把checkpoint往前推進,redo log留出空間可以繼續寫
checkpoint位置從CP推進到CP’,就需要將兩個點之間的日志對應的所有臟頁都flush到磁盤上。之后,上圖中從write pos到CP’之間就是可以再寫入的redo log的區域
第二種場景是,系統內存不足。當需要新的內存頁,而內存不夠用的時候,就要淘汰一些數據頁,空出內存給別的數據頁使用。如果淘汰的是臟頁,就要先將臟頁寫到磁盤
這時候不能直接把內存淘汰掉,下次需要請求的時候,從磁盤讀入數據頁,然后拿redo log出來應用不就行了?
這里是從性能考慮的。如果刷臟頁一定會寫盤,就保證了每個數據頁有兩種狀態:一種是內存里存在,內存里就肯定是正確的結果,直接返回;另一種是內存里沒有數據,就可以肯定數據文件上是正確的結果,讀入內存后返回。這樣的效率最高
第三種場景是,MySQL認為系統空閑的時候刷臟頁,當然在系統忙的時候也要找時間刷一點臟頁
第四種場景是,MySQL正常關閉的時候會把內存的臟頁都flush到磁盤上,這樣下次MySQL啟動的時候,就可以直接從磁盤上讀數據,啟動速度會很快
redo log寫滿了,要flush臟頁,出現這種情況的時候,整個系統就不能再接受更新了,所有的更新都必須堵住
內存不夠用了,要先將臟頁寫到磁盤,這種情況是常態。InnoDB用緩沖池管理內存,緩沖池中的內存頁有三種狀態:
第一種是還沒有使用的
第二種是使用了并且是干凈頁
第三種是使用了并且是臟頁
InnoDB的策略是盡量使用內存,因此對于一個長時間運行的庫來說,未被使用的頁面很少
當要讀入的數據頁沒有在內存的時候,就必須到緩沖池中申請一個數據頁。這時候只能把最久不使用的數據頁從內存中淘汰掉:如果要淘汰的是一個干凈頁,就直接釋放出來復用;但如果是臟頁,即必須將臟頁先刷到磁盤,變成干凈頁后才能復用
刷頁雖然是常態,但是出現以下兩種情況,都是會明顯影響性能的:
一個查詢要淘汰的臟頁個數太多,會導致查詢的響應時間明顯變長
日志寫滿,更新全部堵住,寫性能跌為0,這種情況對敏感業務來說,是不能接受的
首先,要正確地告訴InnoDB所在主機的IO能力,這樣InnoDB才能知道需要全力刷臟頁的時候,可以刷多快。參數為innodb_io_capacity,建議設置成磁盤的IOPS
InnoDB的刷盤速度就是考慮臟頁比例和redo log寫盤速度。參數innodb_max_dirty_pages_pct是臟頁比例上限,默認值是75%。臟頁比例是通過Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total得到的,SQL語句如下:
mysql> select VARIABLE_VALUE into @a from performance_schema.global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty'; select VARIABLE_VALUE into @b from performance_schema.global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_total'; select @a/@b;
問題一:在兩階段提交的不同時刻,MySQL異常重啟會出現什么現象
如果在圖中時刻A的地方,也就是寫入redo log處于prepare階段之后、寫binlog之前,發生了崩潰,由于此時binlog還沒寫,redo log也還沒提交,所以崩潰恢復的時候,這個事務會回滾。這時候,binlog還沒寫,所以也不會傳到備庫
如果在圖中時刻B的地方,也就是binlog寫完,redo log還沒commit前發生崩潰,那崩潰恢復的時候MySQL怎么處理?
崩潰恢復時的判斷規則:
1)如果redo log里面的事務是完整的,也就是已經有了commit標識,則直接提交
2)如果redo log里面的事務只有完整的prepare,則判斷對應的事務binlog是否存在并完整
a.如果完整,則提交事務
b.否則,回滾事務
時刻B發生崩潰對應的就是2(a)的情況,崩潰恢復過程中事務會被提交
問題二:MySQL怎么知道binlog是完整的?
一個事務的binlog是有完整格式的:
statement格式的binlog,最后會有COMMIT
row格式的binlog,最后會有一個XID event
問題三:redo log和binlog是怎么關聯起來的?
它們有一個共同的數據字段,叫XID。崩潰恢復的時候,會按順序掃描redo log:
如果碰到既有prepare、又有commit的redo log,就直接提交
如果碰到只有prepare、而沒有commit的redo log,就拿著XID去binlog找對應的事務
問題四:redo log一般設置多大?
如果是現在常見的幾個TB的磁盤的話,redo log設置為4個文件、每個文件1GB
問題五:正常運行中的實例,數據寫入后的最終落盤,是從redo log更新過來的還是從buffer pool更新過來的呢?
redo log并沒有記錄數據頁的完整數據,所以它并沒有能力自己去更新磁盤數據頁,也就不存在數據最終落盤是由redo log更新過去的情況
1.如果是正常運行的實例的話,數據頁被修改以后,跟磁盤的數據頁不一致,稱為臟頁。最終數據落盤,就是把內存中的數據頁寫盤。這個過程,甚至與redo log毫無關系
2.在崩潰恢復場景中,InnoDB如果判斷到一個數據頁可能在崩潰恢復的時候丟失了更新,就會將它對到內存,然后讓redo log更新內存內容。更新完成后,內存頁變成臟頁,就回到了第一種情況的狀態
問題六:redo log buffer是什么?是先修改內存,還是先寫redo log文件?
在一個事務的更新過程中,日志是要寫多次的。比如下面這個事務:
begin;insert into t1 ...insert into t2 ...commit;
這個事務要往兩個表中插入記錄,插入數據的過程中,生成的日志都得先保存起來,但又不能在還沒commit的時候就直接寫到redo log文件里
所以,redo log buffer就是一塊內存,用來先存redo日志的。也就是說,在執行第一個insert的時候,數據的內存被修改了,redo log buffer也寫入了日志。但是,真正把日志寫到redo log文件,是在執行commit語句的時候做的
只要redo log和binlog保證持久化到磁盤,就能確保MySQL異常重啟后,數據可以恢復
事務執行過程中,先把日志寫到binlog cache,事務提交的時候,再把binlog cache寫到binlog文件中。一個事務的binlog是不能被拆開的,因此不論這個事務多大,也要確保一次性寫入
系統給binlog cache分配了一片內存,每個線程一個,參數binlog_cache_size用于控制單個線程內binlog cache所占內存的大小。如果超過了這個參數規定的大小,就要暫存到磁盤
事務提交的時候,執行器把binlog cache里的完整事務寫入到binlog中,并清空binlog cache
每個線程有自己binlog cache,但是共用一份binlog文件
圖中的write,指的就是把日志寫入到文件系統的page cache,并沒有把數據持久化到磁盤,所以速度比較快
圖中的fsync,才是將數據持久化到磁盤的操作。一般情況下認為fsync才占磁盤的IOPS
write和fsync的時機,是由參數sync_binlog控制的:
sync_binlog=0的時候,表示每次提交事務都只write,不fsync
sync_binlog=1的時候,表示每次提交事務都會執行fsync
sync_binlog=N(N>1)的時候,表示每次提交事務都write,但累積N個事務后才fsync
因此,在出現IO瓶頸的場景中,將sync_binlog設置成一個比較大的值,可以提升性能,對應的風險是:如果主機發生異常重啟,會丟失最近N個事務的binlog日志
事務在執行過程中,生成的redo log是要先寫到redo log buffer的。redo log buffer里面的內容不是每次生成后都要直接持久化到磁盤,也有可能在事務還沒提交的時候,redo log buffer中的部分日志被持久化到磁盤
redo log可能存在三種狀態,對應下圖的三個顏色塊
這三張狀態分別是:
存在redo log buffer中,物理上是在MySQL進程內存中,就是圖中紅色的部分
寫到磁盤,但是沒有持久化,物理上是在文件系統的page cache里面,也就是圖中黃色的部分
持久化到磁盤,對應的是hard disk,也就是圖中的綠色部分
日志寫到redo log buffer和write到page cache都是很快的,但是持久化到磁盤的速度就慢多了
為了控制redo log的寫入策略,InnoDB提供了innodb_flush_log_at_trx_commit參數,它有三種可能取值:
設置為0的時候,表示每次事務提交時都只是把redo log留在redo log buffer中
設置為1的時候,表示每次事務提交時都將redo log直接持久化到磁盤
設置為2的時候,表示每次事務提交時都只是把redo log寫到page cache
InnoDB有一個后臺線程,每隔1秒,就會把redo log buffer中的日志,調用write寫到文件系統的page cache,然后調用fsync持久化到磁盤。事務執行中間過程的redo log也是直接寫在redo log buffer中的,這些redo log也會被后臺線程一起持久化到磁盤。也就是說,一個沒有提交的事務的redo log也是可能已經持久化到磁盤的
還有兩種場景會讓一個沒有提交的事務的redo log寫入到磁盤中
1.redo log buffer占用的空間即將達到innodb_log_buffer_size一半的時候,后臺線程會主動寫盤。由于事務并沒有提交,所以這個寫盤動作只是write,而沒有調用fsync,也就是只留在文件系統的page cache
2.并行的事務提交的時候,順帶將這個事務的redo log buffer持久化到磁盤。假設一個事務A執行到一半,已經寫了一些redo log到buffer中,這時候有另外一個線程的事務B提交,如果innodb_flush_log_at_trx_commit設置的是1,事務B要把redo log buffer里的日志全部持久化到磁盤。這時候,就會帶上事務A在redo log buffer里的日志一起持久化到磁盤
兩階段提交,時序上redo log先prepare,再寫binlog,最后再把redo log commit。如果把innodb_flush_log_at_trx_commit設置成1,那么redo log在prepare階段就要持久化一次
MySQL的雙1配置,指的就是sync_binlog和innodb_flush_log_at_trx_commit都設置成1。也就是說,一個事務完整提交前,需要等待兩次刷盤,一次是redo log(prepare階段),一次是binlog
日志邏輯序列號LSN是單調遞增的,用來對應redo log的一個個寫入點,每次寫入長度為length的redo log,LSN的值就會加上length。LSN也會寫到InnoDB的數據頁中,來確保數據頁不會被多次執行重復的redo log
上圖是三個并發事務在prepare階段,都寫完redo log buffer,持久化到磁盤的過程,對應的LSN分別是50、120和160
1.trx1是第一個到達的,會被選為這組的leader
2.等trx1要開始寫盤的時候,這個組里面已經有了三個事務,這時候LSN也變成了160
3.trx1去寫盤的時候,帶的就是LSN=160,因此等trx1返回時,所有LSN小于等于160的redo log,都已經被持久化到磁盤
4.這時候trx2和trx3就可以直接返回了
一個組提交里面,組員越多,節約磁盤IOPS的效果要好
為了讓一次fsync帶的組員更多,MySQL做了拖時間的優化
binlog也可以組提交了,在執行上圖第4步把binlog fsync到磁盤時,如果有多個事務的binlog已經寫完了,也是一起持久化的,這樣也可以減少IOPS的消耗
如果想提升binlog組提交的效果,可以通過設置binlog_group_commit_sync_delay和binlog_group_commit_sync_no_delay_count兩個參數來實現
1.binlog_group_commit_sync_delay參數表示延遲多少微妙后才調用fsync
2.binlog_group_commit_sync_no_delay_count參數表示積累多少次以后才調用fsync
這兩個條件只要有一個滿足就會調用fsync
WAL機制主要得益于兩方面:
redo log和binlog都是順序寫的,磁盤的順序寫比隨機寫速度要快
組提交機制,可以大幅降低磁盤訂單IOPS消耗
1.設置binlog_group_commit_sync_delay(延遲多少微妙后才調用fsync)和binlog_group_commit_sync_no_delay_count(積累多少次以后才調用fsync)參數,減少binlog的寫盤次數。這個方法是基于額外的故意等待來實現的,因此可能會增加語句的響應時間,但沒有丟失數據的風險
2.將sync_binlog設置為大于1的值(每次提交事務都write,但累積N個事務后才fsync)。這樣做的風險是,主機掉電的時候會丟binlog日志
3.將innodb_flush_log_at_trx_commit設置為2(每次事務提交時都只是把redo log寫到page cache)。這樣做的風險是,主機掉電的時候會丟數據
關于“MySQL的基礎架構和日志系統實例分析”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“MySQL的基礎架構和日志系統實例分析”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。