| 2069 | |
| 2070 | |
| 2071 | void |
| 2072 | seq_redo(XLogReaderState *record) |
| 2073 | { |
| 2074 | XLogRecPtr lsn = record->EndRecPtr; |
| 2075 | uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK; |
| 2076 | Buffer buffer; |
| 2077 | Page page; |
| 2078 | Page localpage; |
| 2079 | char *item; |
| 2080 | Size itemsz; |
| 2081 | xl_seq_rec *xlrec = (xl_seq_rec *) XLogRecGetData(record); |
| 2082 | sequence_magic *sm; |
| 2083 | |
| 2084 | if (info != XLOG_SEQ_LOG) |
| 2085 | elog(PANIC, "seq_redo: unknown op code %u", info); |
| 2086 | |
| 2087 | buffer = XLogInitBufferForRedo(record, 0); |
| 2088 | page = (Page) BufferGetPage(buffer); |
| 2089 | |
| 2090 | /* |
| 2091 | * We always reinit the page. However, since this WAL record type is also |
| 2092 | * used for updating sequences, it's possible that a hot-standby backend |
| 2093 | * is examining the page concurrently; so we mustn't transiently trash the |
| 2094 | * buffer. The solution is to build the correct new page contents in |
| 2095 | * local workspace and then memcpy into the buffer. Then only bytes that |
| 2096 | * are supposed to change will change, even transiently. We must palloc |
| 2097 | * the local page for alignment reasons. |
| 2098 | */ |
| 2099 | localpage = (Page) palloc(BufferGetPageSize(buffer)); |
| 2100 | |
| 2101 | PageInit(localpage, BufferGetPageSize(buffer), sizeof(sequence_magic)); |
| 2102 | sm = (sequence_magic *) PageGetSpecialPointer(localpage); |
| 2103 | sm->magic = SEQ_MAGIC; |
| 2104 | |
| 2105 | item = (char *) xlrec + sizeof(xl_seq_rec); |
| 2106 | itemsz = XLogRecGetDataLen(record) - sizeof(xl_seq_rec); |
| 2107 | |
| 2108 | if (PageAddItem(localpage, (Item) item, itemsz, |
| 2109 | FirstOffsetNumber, false, false) == InvalidOffsetNumber) |
| 2110 | elog(PANIC, "seq_redo: failed to add item to page"); |
| 2111 | |
| 2112 | PageSetLSN(localpage, lsn); |
| 2113 | |
| 2114 | memcpy(page, localpage, BufferGetPageSize(buffer)); |
| 2115 | MarkBufferDirty(buffer); |
| 2116 | UnlockReleaseBuffer(buffer); |
| 2117 | |
| 2118 | pfree(localpage); |
| 2119 | } |
| 2120 | |
| 2121 | /* |
| 2122 | * Flush cached sequence information. |
nothing calls this directly
no test coverage detected