【環球新視野】PostgreSQL的clog屬于日志還是數據,需要遵守write-WAL-before-data嗎?

            2023-03-05 20:25:35 來源:騰訊云


            (資料圖片)

            總結

            從原理上來看,MVCC需要給定事務ID后,能查詢到事務的狀態。

            在PG中事務狀態可以從幾個路徑獲取:

            在快照中查詢(活躍事務)在元組頭的狀態為查詢(不活躍事務)在CLOG中查詢(不活躍事務)

            如果不看實現只看概念,不活躍事務提交狀態也可以在XLOG中查詢,CLOG可以視作一種XLOG commit/rollback日志的緩存、映射,一種事務提交狀態的快速查詢方式。

            所以在write-WAL-before-data中,CLOG也會按照data來處理,只有XLOG屬于WAL。

            Postgresql中clog寫盤實現SlruPhysicalWritePage

            postgresql中clog使用SLRU機制讀寫,在Slru寫盤前,會有保證xlog先寫的機制:

            group_lsn表示32個事務一組中最大的日志序列號(LSN)。group_lsn主要用于事務提交非同步落盤的場景。
            static boolSlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruWriteAll fdata){...if (shared->group_lsn != NULL){/* * We must determine the largest async-commit LSN for the page. This * is a bit tedious, but since this entire function is a slow path * anyway, it seems better to do this here than to maintain a per-page * LSN variable (which"d need an extra comparison in the * transaction-commit path). */XLogRecPtrmax_lsn;intlsnindex,lsnoff;lsnindex = slotno * shared->lsn_groups_per_page;max_lsn = shared->group_lsn[lsnindex++];for (lsnoff = 1; lsnoff < shared->lsn_groups_per_page; lsnoff++){XLogRecPtrthis_lsn = shared->group_lsn[lsnindex++];if (max_lsn < this_lsn)max_lsn = this_lsn;    <<<<<<<<<<<<<<<<<<<<<<<<< 找到最大的LSN}if (!XLogRecPtrIsInvalid(max_lsn)){/* * As noted above, elog(ERROR) is not acceptable here, so if * XLogFlush were to fail, we must PANIC.  This isn"t much of a * restriction because XLogFlush is just about all critical * section anyway, but let"s make sure. */START_CRIT_SECTION();XLogFlush(max_lsn);      <<<<<<<<<<<<<<<<<<<<<<<<< 先保證XLOG寫到這個位點!END_CRIT_SECTION();}}  ...  if (pg_pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)  {    ...  }}

            Postgresql中用戶數據寫盤實現FlushBuffer

            數據頁面同理,也是先找到頁面lsn,刷xlog,在寫數據。

            static voidFlushBuffer(BufferDesc *buf, SMgrRelation reln){...buf_state = LockBufHdr(buf);/* * Run PageGetLSN while holding header lock, since we don"t have the * buffer locked exclusively in all cases. */recptr = BufferGetLSN(buf);   <<<<<<<<<<<<<<<<<<<<<<<<< 找到頁面的LSN/* To check if block content changes while flushing. - vadim 01/17/97 */buf_state &= ~BM_JUST_DIRTIED;UnlockBufHdr(buf, buf_state);/* * Force XLOG flush up to buffer"s LSN.  This implements the basic WAL * rule that log updates must hit disk before any of the data-file changes * they describe do. * * However, this rule does not apply to unlogged relations, which will be * lost after a crash anyway.  Most unlogged relation pages do not bear * LSNs since we never emit WAL records for them, and therefore flushing * up through the buffer LSN would be useless, but harmless.  However, * GiST indexes use LSNs internally to track page-splits, and therefore * unlogged GiST pages bear "fake" LSNs generated by * GetFakeLSNForUnloggedRel.  It is unlikely but possible that the fake * LSN counter could advance past the WAL insertion point; and if it did * happen, attempting to flush WAL through that location would fail, with * disastrous system-wide consequences.  To make sure that can"t happen, * skip the flush if the buffer isn"t permanent. */if (buf_state & BM_PERMANENT)XLogFlush(recptr);         <<<<<<<<<<<<<<<<<<<<<<<<< 先保證XLOG寫到這個位點!    ...smgrwrite(reln,  BufTagGetForkNum(&buf->tag),  buf->tag.blockNum,  bufToWrite,  false);  ...}

            標簽: PostgreSQL

          亚洲国产精品无码专区| 亚洲精品国产成人99久久| 亚洲精品无码永久在线观看你懂的 | 老司机亚洲精品影院在线观看 | 亚洲国产精品白丝在线观看| 久久久亚洲精品无码| 亚洲AV永久精品爱情岛论坛| 亚洲精品你懂的在线观看| 亚洲日韩精品无码一区二区三区 | 亚洲午夜国产片在线观看| 亚洲AV无码一区二区三区国产| 亚洲av无码日韩av无码网站冲| 亚洲综合色丁香婷婷六月图片| 国产日本亚洲一区二区三区 | 亚洲人成色77777在线观看大| 亚洲av手机在线观看| 亚洲国产午夜福利在线播放| 亚洲AV无码乱码在线观看牲色| 亚洲精品第一国产综合精品99| 亚洲精品高清在线| 亚洲熟女乱综合一区二区| 亚洲一区二区三区在线视频| 中文字幕第13亚洲另类| 亚洲日产无码中文字幕| 九月丁香婷婷亚洲综合色| 亚洲AV永久无码精品成人| 久久精品国产亚洲AV无码娇色| 亚洲gv白嫩小受在线观看| 亚洲AV人无码综合在线观看| 久久精品国产亚洲av影院| 亚洲永久中文字幕在线| 亚洲精品福利你懂| 亚洲精品无码专区久久| 国产精品亚洲а∨无码播放不卡| 亚洲电影日韩精品 | 亚洲卡一卡二卡乱码新区| 亚洲国产成人久久综合| www亚洲一级视频com| 自拍偷自拍亚洲精品第1页| 亚洲av最新在线网址| 亚洲理论片在线中文字幕|