国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

MySQL8.0 redo log優(yōu)化概述和線(xiàn)程模型介紹

發(fā)布時(shí)間:2021-09-14 18:07 來(lái)源:億速云 閱讀:0 作者:chen 欄目: Mysql 歡迎投稿:712375056

本篇內容介紹了“8.0 redo log優(yōu)化概述和線(xiàn)程模型介紹”的有關(guān)知識,在實(shí)際案例的操作過(guò)程中,不少人都會(huì )遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學(xué)有所成!

1 MySQL redo_log簡(jiǎn)要回顧


在MySQL 5.7中寫(xiě)性能將受限于redo_log的同步操作,特別是在多cpu,存儲設備很快的情況下,MySQL 5.7 redo_log的設計無(wú)法有效利用存儲設備性能,因此需要重新設計。MySQL 5.7瓶頸在于mtr將在把log寫(xiě)到log buffer時(shí)加log_sys_t::mutex鎖,之后該mtr把dirty page加入flush list中時(shí),為了保證全局有序,會(huì )加 log_sys_t::flush_order_mutex鎖。如果其他用戶(hù)線(xiàn)程的mtr要把log寫(xiě)到log buffer,需要等待log_sys_t::mutex,同時(shí)為了保證全局lsn有序,其他用戶(hù)線(xiàn)程的mtr即使要往其他flush list中加數據也需要等待log_sys_t::flush_order_mutex鎖,這兩把鎖是MySQL 5.7中redo_log的主要性能瓶頸。

2 redo log優(yōu)化概述


目前,redo log是無(wú)鎖全異步設計,其流程架構圖如下所示:

如上圖所示,redo log的異步工作線(xiàn)程為4個(gè),另2個(gè)異步輔助線(xiàn)程:分別是:log_writer, log_flusher, log_flush_notifier, log_write_notifier, log_checkpointer,log_close,log_flush_notifier /log_write_notifier為圖中log notifier線(xiàn)程組,輔助線(xiàn)程為log_checkpointer, log_closer。

log_writer:負責將日志從log buffer寫(xiě)入磁盤(pán),并推進(jìn)write_lsn(原子數據)
log_flusher:負責fsync,并推進(jìn)flushed_to_disk_lsn(原子數據)
log_write_notifier:監聽(tīng)write_lsn,喚醒等待log落盤(pán)的用戶(hù)線(xiàn)程(根據flush_log_at_trx_commit設置,用戶(hù)commit操作會(huì )等待write_lsn推進(jìn))
log_flush_notifier:監聽(tīng)flushed_to_disk_lsn,喚醒等待log fsync的用戶(hù)線(xiàn)程。

log_closer:1、在正常退出時(shí)清理所有redo_log相關(guān)lsn\log buffer相關(guān)數據結構;2、定期清理recent_closer的過(guò)老數據(recent_closer所用之后詳述)

log_checkpointer:定期做checkpoint檢查,根據flush list刷dirty page情況推進(jìn)check point,釋放log buffer等


1 線(xiàn)程同步數據結構

異步線(xiàn)程之間通過(guò)2種數據結構進(jìn)行數據同步:原子讀寫(xiě)(atomic )和Link_buf。原子讀寫(xiě)是c++11針對多核cpu的一個(gè)新特性,在不加鎖的情況下,對一個(gè)64位數據的原子讀寫(xiě)。

Link_buf是MySQL新實(shí)現的數據結構,邏輯上是循環(huán)數組,數組下標表示start lsn,數據內容是lsn長(cháng)度,數據類(lèi)型為原子類(lèi)型,如果數據內容(lsn 長(cháng)度)為0表示這個(gè)slot為空 。每個(gè)通過(guò)合理的std::atomic_thread_fence(std::memory_order_release) / std::atomic_thread_fence(std::memory_order_acquire)操作,保證對里面不同slot的lsn讀寫(xiě)的無(wú)鎖并發(fā)。

3 mtr流程


3.1 流程

為了解決多個(gè)用戶(hù)線(xiàn)程的mtr對redo log的爭搶?zhuān)琈ySQL引入了Link_buf的兩個(gè)實(shí)例:recent_write / recent_close. 這兩個(gè)實(shí)例的數據類(lèi)型是上文介紹的Link_buf,不同mtr線(xiàn)程和log_writer線(xiàn)程可以無(wú)鎖對recent_write / recent_close不同slot進(jìn)行讀寫(xiě),recent_write / recent_close鏈表長(cháng)度固定,由innodb_log_recent_closed_size 和innodb_log_recent_written_size制定。mtr的流程如下所示:

  • mtr通過(guò)sn和log_len獲得寫(xiě)入的

    start_lsn/end_lsn,
    log_buffer_reserve(*log_sys, len);

  • 將mtr的每個(gè)block都memcpy到log_buffer

  • 推進(jìn)recent_write的lsn位置到end_lsn
    m_impl->m_log.for_each_block(write_log);

  • 查看recent_close是否有空間,如果recent_close由于最早lsn對應的slot為空(表示該slot等待數據填充),而沒(méi)有空間存儲目前mtr對應的lsn,那么,當前mtr需要等待,直到recent_close最早的slot推進(jìn)
    log_wait_for_space_in_log_recent_closed(*log_sys, handle.start_lsn);

  • 將dirty block添加到flush list
    add_dirty_blocks_to_flush_list(handle.start_lsn, handle.end_lsn);

  • 將當前l(fā)sn寫(xiě)入到recent_close
    log_buffer_close(*log_sys, handle);

3.2 分析

各用戶(hù)線(xiàn)程的mtr之間對log buffer、flush list的爭搶沖突,通過(guò)recent_write / recent_close的讀寫(xiě)而化解。

1、多個(gè)mtr根據步驟1中分配的lsn,可以并發(fā)的寫(xiě)入log_buffer而不產(chǎn)生沖突。但由于并發(fā)寫(xiě)入,獲得較小lsn的mtr(較早申請lsn的mtr)不一定可以較早的進(jìn)行memcpy,因此在某些時(shí)間點(diǎn)log_buffer會(huì )出現空洞(hole)。對于空洞的解決后面詳述。
2、各mtr作為生產(chǎn)者將數據寫(xiě)入log_buffer, log_writer作為消費者將數據將數據取出,log_writer對數據log_buffer讀取位置的獲取通過(guò)recent_write獲得,由于recent_write的無(wú)鎖設計,mtr與log_writer之間也不會(huì )有上鎖等待過(guò)程。
log_writer必須保證連續日志寫(xiě)入,但在1中分析,并發(fā)mtr或導致log_buffer空洞。因此recent_write提供方法advance_tail_until,該方法使得推進(jìn)數組到第一個(gè)slot存儲值為0的地方,該slot的下標對應lsn就是第一個(gè)空洞出現的位置。log_writer將write_lsn(上次寫(xiě)盤(pán)位置)到該slot對應的lsn之間的日志都從log_buffer寫(xiě)入磁盤(pán)。這套機制保證log_writer連續日志寫(xiě)入,取代MySQL 5.7中log_sys_t::mutex鎖。
3、由于多個(gè)mtr并發(fā)寫(xiě)入,加入各flush list中的數據不在全局有序僅僅每個(gè)flush局部有序,因此需要確定一個(gè)lsn可以保證該lsn之前的所有dirty page都flush結束。針對這個(gè)限制,各mtr線(xiàn)程之間通過(guò)recent_close同步。由于recent_close長(cháng)度固定,如果recent_close中最小的lsn與當前申請的lsn間距大于len(recent_close),則需要等待,recent_close最小lsn的推進(jìn)有log_closer進(jìn)行(后面詳述)。因此,可以保證最大可能亂序長(cháng)度為len(recent_close),一旦block進(jìn)入flush list其對應的lsn減去len(recent_close)位置的lsn一定已經(jīng)刷盤(pán),可以在該點(diǎn)進(jìn)行checkpoint。這套機制保證可以找到一個(gè)較新lsn(較大lsn),同時(shí)保證checkpoint點(diǎn)的新鮮程度,此機制用來(lái)取代MySQL 5.7中log_sys_t::flush_order_mutex鎖。

4 redo log線(xiàn)程模型


redo log線(xiàn)程模型如下圖所示:

4.1 log_writer

log_writer負責將數據從log_buffer刷入disk,流程如下:

  • 推進(jìn)recent_write的tail至最大的連續lsn,并獲取lsn的值(ready_lsn)
    /* Advance lsn up to which data is ready in log buffer. */
    (void)log_advance_ready_for_write_lsn(log);
    ready_lsn = log_buffer_ready_for_write_lsn(log);

  • 數據落盤(pán),將write_lsn至ready_lsn之間的日志從log_buffer刷入FS cache中
    write_blocks(log, write_buf, write_size, real_offset);

  • 推進(jìn)write_lsn,將write_lsn推進(jìn)到ready_lsn
    const lsn_t new_write_lsn = start_lsn + lsn_advance;
    ut_a(new_write_lsn > log.write_lsn.load());
    log.write_lsn.store(new_write_lsn);

log_writer整個(gè)流程僅通過(guò)recent_write同步log_buffer的連續日志位置,采取spin lock + pthread_cond_timedwait方式輪詢(xún)r(jià)ecent_write。之前MySQL(5.7)的設計寫(xiě)盤(pán)操作是mtr中同步進(jìn)行的,寫(xiě)策略比較單一,mtr寫(xiě)入長(cháng)度(對于文件系統過(guò)大或者過(guò)?。┎缓线m也必須進(jìn)行寫(xiě)入,如果連續寫(xiě)入小數據,會(huì )造成嚴重的IO浪費。修改后的寫(xiě)入策略可以進(jìn)一步優(yōu)化,寫(xiě)入塊大小、需不需要做batch都可以在log_writer中優(yōu)化。

4.2 log_flusher

log_flusher負責將數據fsync到磁盤(pán),推進(jìn)flush_up_to_lsn。log_flusher與log_writer之間僅通過(guò)write_lsn同步刷盤(pán)位置,兩個(gè)線(xiàn)程按照各自速度進(jìn)行刷盤(pán)與fsnyc,他們之間的刷盤(pán)數據同步在OS/FS層進(jìn)行,沒(méi)有用戶(hù)態(tài)的鎖。

4.3 log_notifier

log_notifier包括log_write_notifier和log_flush_notifier,這兩個(gè)線(xiàn)程定期輪詢(xún)(為了加速也會(huì )被喚醒)各自關(guān)心的lsn位置:log_write_notifier關(guān)心write_lsn,log_flush_notifier關(guān)心flush_up_to_lsn。并將根據最新的lsn值喚醒等待的用戶(hù)線(xiàn)程。用戶(hù)線(xiàn)程commit等操作時(shí)會(huì )等在log_write_up_to函數上,當flush_up_to_lsn/write_lsn推進(jìn)到等待位置時(shí),log_write_up_to返回。

4.4 log_closer

log_closer作用有兩個(gè):
定期推進(jìn)recent_close,清除recent_close中已經(jīng)放入flush list的連續lsn片段,保證mtr不會(huì )因為第4步recent_close沒(méi)空間而持續等待;
數據庫正常退出時(shí),做收尾工作,將redo_log中的日志放到flush list中。

4.5 新增參數

與innodb_log_writer_spin_delay/innodb_log_writer_timeout作用相同,closer線(xiàn)程對應inno_log_closer_spin_delay/innodb_log_closer_timeout兩個(gè)參數調節輪詢(xún)速度。

4.6 log_checkpointer

log_checkpointer監控所有flush list,選擇所有flush lists中刷盤(pán)的最?。ㄗ罾希┑膌sn,將此lsn與flushed_to_disk_lsn等進(jìn)行比較之后,設置新的last_checkpoint_lsn。這樣做節省在主進(jìn)程中進(jìn)行checkpoint,將原來(lái)在主進(jìn)程7秒做一次checkpoint改變成在log_checkpointer1秒做一次,一定程度節省數據庫崩潰恢復的時(shí)間。

4.7 參數

1. innodb_log_xxx_spin_delay && innodb_log_xxx_timeout

對于除log_checkpointer以外的log線(xiàn)程,每個(gè)線(xiàn)程都設置了自己的輪詢(xún)參數:innodb_log_xxx_spin_delay和innodb_log_xxx_timeout

控制log線(xiàn)程輪詢(xún)頻率的函數為:

template <typename Condition>
inline static Wait_stats os_event_wait_for(os_event_t &event,
                                           uint64_t spins_limit,
                                           uint64_t timeout,
                                           Condition condition = {})

log線(xiàn)程先等待innodb_log_xxx_spin_delay(spins_limit參數)個(gè)cpu pause指令,如果事件沒(méi)有到來(lái)(condition函數返回false),開(kāi)始等待特定信號量event,睡眠k個(gè)innodb_log_xxx_timeout(timeout參數)us,k隨著(zhù)連續等待次數的增加按照2的指數上升,總體睡眠時(shí)間以100ms為上限。

參數名稱(chēng)列表如下

2. innodb_log_spin_cpu_abs_lwm && innodb_log_spin_cpu_pct_hwm
用innodb_log_spin_cpu_abs_lwm和innodb_log_spin_cpu_pct_hwm進(jìn)行兩個(gè)參數控制os_event_wait_for中自旋鎖的使用。innodb_log_spin_cpu_abs_lwm表示使用自旋鎖的下門(mén)限,cpu低于這個(gè)門(mén)限,表示系統空閑,不需要使用自旋鎖,cpu高于innodb_log_spin_cpu_pct_hwm表示系統特別繁忙,也不許使用自旋鎖。innodb_log_spin_cpu_abs_lwm表示一個(gè)cpu的使用率,比如40core cpu,innodb_log_spin_cpu_abs_lwm為80,在MySQLd上cpu總使用率小于80%,不進(jìn)行自旋。innodb_log_spin_cpu_pct_hwm表示所有cpu的總使用率,比如40core cpu,innodb_log_spin_cpu_pct_hwm為50,在cpu使用率大于2000%時(shí),不進(jìn)行自旋。

5 結語(yǔ)


redo_log的優(yōu)化將之前鎖沖突化解,用戶(hù)線(xiàn)程的“等鎖-寫(xiě)”機制轉化為“寫(xiě)緩沖-查看寫(xiě)盤(pán)”機制。用戶(hù)線(xiàn)程不進(jìn)行刷盤(pán)操作,由后臺線(xiàn)程統一刷盤(pán),用戶(hù)線(xiàn)程在寫(xiě)緩沖后就可以做其他操作,達到日志寫(xiě)盤(pán)和mtr做其他事情的并行,提升效率。

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

亚洲国产高清在线观看视频| 欧美XXXXX高潮喷水| 欧美老人巨大XXXX做受视频| 蜜桃AV少妇久久久久久高潮不断| 成人无码特黄特黄AV片在线| 国产精品香蕉在线观看|