欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

從一個(gè)線上問題分析binlog與內(nèi)部XA事務(wù)提交過程

1. 問題
業(yè)務(wù)上新增一條訂單記錄,用戶接收到BinLake拉取的MySQL從庫數(shù)據(jù)消息后,馬上根據(jù)消息內(nèi)的訂單號去查詢同一個(gè)MySQL從庫,發(fā)現(xiàn)有些時(shí)候無法查到該條數(shù)據(jù),等待大約500ms~1000ms后再去查詢數(shù)據(jù)庫,可以查詢到該條數(shù)據(jù)。
注: BinLake為京東商城數(shù)據(jù)庫技術(shù)部自研的一套訂閱和消費(fèi)MySQL數(shù)據(jù)庫binlog的組件,本例所描述的問題是業(yè)務(wù)方希望根據(jù)訂閱的binlog來獲取實(shí)時(shí)訂單等業(yè)務(wù)消息。
2. Binlog與內(nèi)部XA
2.1. XA的概念
XA(分布式事務(wù))規(guī)范主要定義了(全局)事務(wù)管理器(TM: Transaction Manager)和(局部)資源管理器(RM: Resource Manager)之間的接口。XA為了實(shí)現(xiàn)分布式事務(wù),將事務(wù)的提交分成了兩個(gè)階段:也就是2PC (tow phase commit),XA協(xié)議就是通過將事務(wù)的提交分為兩個(gè)階段來實(shí)現(xiàn)分布式事務(wù)。
兩階段
1)prepare 階段
事務(wù)管理器向所有涉及到的數(shù)據(jù)庫服務(wù)器發(fā)出prepare"準(zhǔn)備提交"請求,數(shù)據(jù)庫收到請求后執(zhí)行數(shù)據(jù)修改和日志記錄等處理,處理完成后只是把事務(wù)的狀態(tài)改成"可以提交",然后把結(jié)果返回給事務(wù)管理器。即:為prepare階段,TM向RM發(fā)出prepare指令,RM進(jìn)行操作,然后返回成功與否的信息給TM。
2)commit 階段
事務(wù)管理器收到回應(yīng)后進(jìn)入第二階段,如果在第一階段內(nèi)有任何一個(gè)數(shù)據(jù)庫的操作發(fā)生了錯(cuò)誤,或者事務(wù)管理器收不到某個(gè)數(shù)據(jù)庫的回應(yīng),則認(rèn)為事務(wù)失敗,回撤所有數(shù)據(jù)庫的事務(wù)。數(shù)據(jù)庫服務(wù)器收不到第二階段的確認(rèn)提交請求,也會(huì)把"可以提交"的事務(wù)回撤。如果第一階段中所有數(shù)據(jù)庫都提交成功,那么事務(wù)管理器向數(shù)據(jù)庫服務(wù)器發(fā)出"確認(rèn)提交"請求,數(shù)據(jù)庫服務(wù)器把事務(wù)的"可以提交"狀態(tài)改為"提交完成"狀態(tài),然后返回應(yīng)答。即:為事務(wù)提交或者回滾階段,如果TM收到所有RM的成功消息,則TM向RM發(fā)出提交指令;不然則發(fā)出回滾指令。
外部與內(nèi)部XA
MySQL中的XA實(shí)現(xiàn)分為:外部XA和內(nèi)部XA。前者是指我們通常意義上的分布式事務(wù)實(shí)現(xiàn);后者是指單臺(tái)MySQL服務(wù)器中,Server層作為TM(事務(wù)協(xié)調(diào)者,通常由binlog模塊擔(dān)當(dāng)),而服務(wù)器中的多個(gè)數(shù)據(jù)庫實(shí)例作為RM,而進(jìn)行的一種分布式事務(wù),也就是MySQL跨庫事務(wù);也就是一個(gè)事務(wù)涉及到同一條MySQL服務(wù)器中的兩個(gè)innodb數(shù)據(jù)庫(目前似乎只有innodb支持XA)。內(nèi)部XA也可以用來保證redo和binlog的一致性問題。
2.2. redo與binlog的一致性問題
我們MySQL為了兼容其它非事務(wù)引擎的復(fù)制,在server層面引入了 binlog, 它可以記錄所有引擎中的修改操作,因而可以對所有的引擎使用復(fù)制功能; 然而這種情況會(huì)導(dǎo)致redo log與binlog的一致性問題;MySQL通過內(nèi)部XA機(jī)制解決這種一致性的問題。
第一階段:InnoDB prepare, write/sync redo log;binlog不作任何操作;
第二階段:包含兩步,1> write/sync Binlog; 2> InnoDB commit (commit in memory);
當(dāng)然在5.6之后引入了組提交的概念,可以在IO性能上進(jìn)行一些提升,但總體的執(zhí)行順序不會(huì)改變。
當(dāng)?shù)诙A段的第1步執(zhí)行完成之后,binlog已經(jīng)寫入,MySQL會(huì)認(rèn)為事務(wù)已經(jīng)提交并持久化了(在這一步binlog就已經(jīng)ready并且可以發(fā)送給訂閱者了)。在這個(gè)時(shí)刻,就算數(shù)據(jù)庫發(fā)生了崩潰,那么重啟MySQL之后依然能正確恢復(fù)該事務(wù)。在這一步之前包含這一步任何操作的失敗都會(huì)引起事務(wù)的rollback。
第二階段的第2大部分都是內(nèi)存操作,比如釋放鎖,釋放mvcc相關(guān)的read view等等。MySQL認(rèn)為這一步不會(huì)發(fā)生任何錯(cuò)誤,一旦發(fā)生了錯(cuò)誤那就是數(shù)據(jù)庫的崩潰,MySQL自身無法處理。這個(gè)階段沒有任何導(dǎo)致事務(wù)rollback的邏輯。在程序運(yùn)行層面,只有這一步完成之后,事務(wù)導(dǎo)致變更才能通過API或者客戶端查詢體現(xiàn)出來。
下面的一張圖,說明了MySQL在何時(shí)會(huì)將binlog發(fā)送給訂閱者。
從一個(gè)線上問題分析binlog與內(nèi)部XA事務(wù)提交過程
理論上來說,也可以在commit階段完成之后再將binlog發(fā)送給訂閱者,但這樣會(huì)增大主從延遲的風(fēng)險(xiǎn)。
3. 相關(guān)代碼

十年的黑河網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都營銷網(wǎng)站建設(shè)的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整黑河建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“黑河網(wǎng)站設(shè)計(jì)”,“黑河網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

  1. int MYSQL_BIN_LOG::ordered_commit(THD *thd, bool all, bool skip_commit) {
  2. .....
  3. //進(jìn)入flush stage,
  4. change_stage(thd, Stage_manager::FLUSH_STAGE, thd, NULL, &LOCK_log);
  5. ....
  6. //通知底層存儲(chǔ)引擎日志刷盤
  7. process_flush_stage_queue(&total_bytes, &do_rotate, &wait_queue);
  8. .....
  9. //將各個(gè)線程的binlog從cache寫到文件中
  10. flush_cache_to_file(&flush_end_pos);
  11. ....
  12. //進(jìn)入到Sync stage
  13. change_stage(thd, Stage_manager::SYNC_STAGE, wait_queue, &LOCK_log,
  14. &LOCK_sync));
  15. //binlog fsync落盤
  16. sync_binlog_file(false)
  17. //通知binlog發(fā)送線程,有新的binlog落盤可以發(fā)送到訂閱者了
  18. update_binlog_end_pos(tmp_thd->get_trans_pos());
  19. //進(jìn)入commit state
  20. change_stage(thd, Stage_manager::COMMIT_STAGE, final_queue,
  21. leave_mutex_before_commit_stage, &LOCK_commit);
  22. ....
  23. //事務(wù)狀態(tài)提交
  24. process_commit_stage_queue(thd, commit_queue);
  25. ....
    }

其中,在update_binlog_end_pos之后,binlog發(fā)送線程就已經(jīng)可以讀取最新的binlog發(fā)送給訂閱者了。當(dāng)訂閱者收到這些binlog之后如果process_commit_stage_queue因?yàn)橄到y(tǒng)調(diào)度等原因還未執(zhí)行完成,那么訂閱者碰巧在此時(shí)發(fā)起問題中所描述的查詢,就會(huì)發(fā)生查詢不到的情況。
下面我們看一下process_commit_stage_queue都做了什么。
在process_commit_stage_queue會(huì)分別調(diào)用到binlog的commit方法binlog_commit和innodb的commit函數(shù)trx_commit_in_memory。

  1. static int binlog_commit(handlerton , THD , bool) {
  2. DBUG_ENTER("binlog_commit");
  3. /*
  4. Nothing to do (any more) on commit.
  5. */
  6. DBUG_RETURN(0);
  7. }
    在binlog_commit中什么也不做,因?yàn)楦鷅inlog有關(guān)的操作前面都已經(jīng)做完了。
    最后看一下存儲(chǔ)引擎innodb的trx_commit_in_memory都干了什么。
  8. static void trx_commit_in_memory(
  9. trx_t trx, /!< in/out: transaction */
  10. const mtr_t mtr, /!< in: mini-transaction of
  11. trx_write_serialisation_history(), or NULL if
  12. the transaction did not modify anything */
  13. bool serialised)
  14. /*!< in: true if serialisation log was
  15. written */
  16. {
  17. ....
  18. //釋放鎖
  19. lock_trx_release_locks(trx);
  20. ut_ad(trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY));
  21. .....
  22. //釋放mvcc相關(guān)的read view
  23. if (trx->read_only || trx->rsegs.m_redo.rseg == NULL) {
  24. MONITOR_INC(MONITOR_TRX_RO_COMMIT);
  25. if (trx->read_view != NULL) {
  26. trx_sys->mvcc->view_close(trx->read_view, false);
  27. }
  28. } else {
  29. ut_ad(trx->id > 0);
  30. MONITOR_INC(MONITOR_TRX_RW_COMMIT);
  31. }
  32. }
  33. ....
  34. //清理insert操作相關(guān)的undo log(注意,此時(shí)只有insert的undo需要清理)
  35. if (mtr != NULL) {
  36. if (trx->rsegs.m_redo.insert_undo != NULL) {
  37. trx_undo_insert_cleanup(&trx->rsegs.m_redo, false);
  38. }
  39. if (trx->rsegs.m_noredo.insert_undo != NULL) {
  40. trx_undo_insert_cleanup(&trx->rsegs.m_noredo, true);
  41. }
  42. }

這一步完成之后,在運(yùn)行時(shí)刻事務(wù)的變更才能被查詢到。但需要記住,MySQL在binlog落盤成功后就認(rèn)為事務(wù)的持久化已經(jīng)完成。
30. 總結(jié)
在binlog落盤之后,MySQL就會(huì)認(rèn)為事務(wù)的持久化已經(jīng)完成(在這個(gè)時(shí)刻之后,就算數(shù)據(jù)庫發(fā)生了崩潰都可以在重啟后正確的恢復(fù)該事務(wù))。但是該事務(wù)產(chǎn)生的數(shù)據(jù)變更被別的客戶端查詢出來還需要在commit全部完成之后。MySQL會(huì)在binlog落盤之后會(huì)立即將新增的binlog發(fā)送給訂閱者以盡可能的降低主從延遲。但由于多線程時(shí)序等原因,當(dāng)訂閱者在收到該binlog之后立即發(fā)起一個(gè)查詢操作,可能不會(huì)查詢到任何該事務(wù)產(chǎn)生的數(shù)據(jù)變更(因?yàn)榇藭r(shí)該事務(wù)所處線程可能尚未完成最后的commit步驟)。
如果應(yīng)用需要根據(jù)binlog作為一些業(yè)務(wù)邏輯的觸發(fā)點(diǎn),還是需要考慮引入一些延時(shí)重試機(jī)制或者重新考慮合適的實(shí)現(xiàn)架構(gòu)。

本文由京東商城數(shù)據(jù)庫技術(shù)部王治提供。

網(wǎng)站欄目:從一個(gè)線上問題分析binlog與內(nèi)部XA事務(wù)提交過程
分享地址:http://aaarwkj.com/article22/gjcccc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、關(guān)鍵詞優(yōu)化、外貿(mào)網(wǎng)站建設(shè)、電子商務(wù)、網(wǎng)站收錄、營銷型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
人妻免费精品久久一区| 亚洲乱码一区二区三区人妇| 少妇被啪出水在线视频| 五月婷婷少妇中文字幕| 欧美生活一区二区三区| 男人av天堂手机在线| 麻豆视传媒短视频网站| 日韩中文字幕在线二区| 日本加勒比系列在线视频| 国产激情久久久久久久久久久| 国产成人亚洲精品午夜国产馆| 黑人爆操中国女孩在线观看| 日本精品亚洲一区二区三区| 黄色片黄色片美女黄色片亚洲黄色片| 亚洲精品一区二区三区毛片| 国产精品大全中文字幕| 免费观看亚洲成人av| 中文字幕人妻系列东京热| 久久久久亚洲av成人网人| 日韩亚洲欧洲一区二区三区| 少妇高潮毛片免费看高潮| 青青草原综合视频在线| 国产91在线视频播放| 97免费公开在线观看| 国产黄色一区二区三区| 精品亚洲国产成人av| 成人黄网站色大片免费观看| 日韩精品有码在线视频免费观看| 在线免费观看日本91| 国产精品福利午夜在线| 日本午夜视频在线观看| 视频二区国产欧美日韩| 欧美另类不卡在线观看| 美国真人性做爰视频免费| 成人作爱视频免费播放| 欧美香蕉一区二区视频| 91精品午夜在线观看| 国产高清内射一级一片高清视频| 爱爱网爱综合日日干夜夜操| 夫妻晚上同房太猛视频| av天堂资源地址在线观看|