access/generic_xlog.h
and implemented in access/transam/generic_xlog.c
.state = GenericXLogStart(relation)
— start construction of a generic WAL record for the given relation.page = GenericXLogRegisterBuffer(state, buffer, flags)
— register a buffer to be modified within the current generic WAL record. This function returns a pointer to a temporary copy of the buffer's page, where modifications should be made. (Do not modify the buffer's contents directly.) The third argument is a bit mask of flags applicable to the operation. Currently the only such flag is GENERIC_XLOG_FULL_IMAGE
, which indicates that a full-page image rather than a delta update should be included in the WAL record. Typically this flag would be set if the page is new or has been rewritten completely. GenericXLogRegisterBuffer
can be repeated if the WAL-logged action needs to modify multiple pages.GenericXLogFinish(state)
— apply the changes to the buffers and emit the generic WAL record.GenericXLogAbort(state)
. This will discard all changes to the page image copies.GenericXLogRegisterBuffer()
. In other words, code that makes generic WAL records should never call BufferGetPage()
for itself. However, it remains the caller's responsibility to pin/unpin and lock/unlock the buffers at appropriate times. Exclusive lock must be held on each target buffer from before GenericXLogRegisterBuffer()
until after GenericXLogFinish()
.MAX_GENERIC_XLOG_PAGES
. An error will be thrown if this limit is exceeded.pd_lower
and pd_upper
.GenericXLogStart()
does not start a critical section. Thus, you can safely do memory allocation, error throwing, etc. between GenericXLogStart()
and GenericXLogFinish()
. The only actual critical section is present inside GenericXLogFinish()
. There is no need to worry about calling GenericXLogAbort()
during an error exit, either.GenericXLogFinish()
takes care of marking buffers dirty and setting their LSNs. You do not need to do this explicitly.GENERIC_XLOG_FULL_IMAGE
is not specified for a registered buffer, the generic WAL record contains a delta between the old and the new page images. This delta is based on byte-by-byte comparison. This is not very compact for the case of moving data within a page, and might be improved in the future.