Although all built-in WAL-logged modules have their own types of WAL records, there is also a generic WAL record type, which describes changes to pages in a generic way. 組み込みのWALにログを書き込むすべてのモジュールは、それぞれに独自の型のWALレコードがありますが、ページへの変更を汎用的な方法で記述する汎用WALレコード型もあります。
Generic WAL records are ignored during <link linkend="logicaldecoding">Logical Decoding</link>. If logical decoding is required for your extension, consider a Custom WAL Resource Manager. 汎用WALレコードはロジカルデコーディング時に無視されます。 拡張にロジカルデコーディングが必要な場合は、カスタムWALリソースマネージャを検討してください。
The API for constructing generic WAL records is defined in
<filename>access/generic_xlog.h</filename> and implemented
in <filename>access/transam/generic_xlog.c</filename>.
汎用WALレコードを構築するためのAPIはaccess/generic_xlog.h
に定義されており、access/transam/generic_xlog.c
で実装されています。
To perform a WAL-logged data update using the generic WAL record facility, follow these steps: 汎用WALレコードの機能を使ってWAL書き込みを伴うデータ更新を行うには、以下の手順に従ってください。
<function>state = GenericXLogStart(relation)</function> — start
construction of a generic WAL record for the given relation.
state = GenericXLogStart(relation)
により、指定のリレーションについての汎用WALレコードの構築を開始します。
<function>page = GenericXLogRegisterBuffer(state, buffer, flags)</function>
— 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
<literal>GENERIC_XLOG_FULL_IMAGE</literal>, 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.
<function>GenericXLogRegisterBuffer</function> can be repeated if the
WAL-logged action needs to modify multiple pages.
page = GenericXLogRegisterBuffer(state, buffer, flags)
により、現在の汎用WALレコード内で更新されるバッファを登録します。
この関数はバッファページの一時コピーへのポインタを返すので、更新はそれに対して行ってください。
(バッファの内容は直接更新しないでください。)
3番目の引数は、操作についてのフラグのビットマスクです。
現在のところ、使用できるフラグはGENERIC_XLOG_FULL_IMAGE
のみで、これはWALレコードには変更の差分ではなく、ページ全体のイメージが含まれることを示します。
典型的には、このフラグはページが新しいか、あるいは完全に書き換えられるときにセットされます。
WAL書き込み対象の動作が複数のページを更新する必要がある場合は、GenericXLogRegisterBuffer
を繰り返すことができます。
Apply modifications to the page images obtained in the previous step. 前の手順で取得したページのイメージに更新を適用する。
<function>GenericXLogFinish(state)</function> — apply the changes to
the buffers and emit the generic WAL record.
GenericXLogFinish(state)
により、バッファの変更を適用し、汎用WALレコードを送出する。
WAL record construction can be canceled between any of the above steps by
calling <function>GenericXLogAbort(state)</function>. This will discard all
changes to the page image copies.
WALレコードの構築は、上記の手順内の間のどこででも、GenericXLogAbort(state)
を呼び出すことで中止できます。
これによりページイメージのコピーに対する変更はすべて廃棄されます。
Please note the following points when using the generic WAL record facility: 汎用WALレコードの機能を使うときは、以下の点に注意してください。
No direct modifications of buffers are allowed! All modifications must
be done in copies acquired from <function>GenericXLogRegisterBuffer()</function>.
In other words, code that makes generic WAL records should never call
<function>BufferGetPage()</function> 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 <function>GenericXLogRegisterBuffer()</function> until after
<function>GenericXLogFinish()</function>.
バッファの直接更新は許されません!
すべての更新はGenericXLogRegisterBuffer()
で取得したコピーに対して行わなければなりません。
言い換えれば、汎用WALレコードを使うコードではBufferGetPage()
を呼び出してはいけません。
しかし、適切なときにバッファにピンを立てる、外す、そしてロックする、解除するのが呼び出し側の責任であることに変わりはありません。
各ターゲットバッファの排他的ロックをGenericXLogRegisterBuffer()
の前からGenericXLogFinish()
の後まで保持していなければなりません。
Registrations of buffers (step 2) and modifications of page images (step 3) can be mixed freely, i.e., both steps may be repeated in any sequence. Keep in mind that buffers should be registered in the same order in which locks are to be obtained on them during replay. 手順2のバッファの登録と、手順3のページイメージの更新は自由に混在させることができます。 つまり、両方の手順を任意の順序で繰り返すことができます。 バッファの登録は、再生時にロックを取得する順序と同じにすべきであることを覚えていてください。
The maximum number of buffers that can be registered for a generic WAL
record is <literal>MAX_GENERIC_XLOG_PAGES</literal>. An error will be thrown
if this limit is exceeded.
汎用WALレコードに登録できるバッファの最大数はMAX_GENERIC_XLOG_PAGES
です。
この制限を超えるとエラーが発生します。
Generic WAL assumes that the pages to be modified have standard
layout, and in particular that there is no useful data between
<structfield>pd_lower</structfield> and <structfield>pd_upper</structfield>.
汎用WALでは、更新対象のページが標準的なレイアウトになっている、特にpd_lower
とpd_upper
の間には意味のあるデータがないということを想定しています。
Since you are modifying copies of buffer
pages, <function>GenericXLogStart()</function> does not start a critical
section. Thus, you can safely do memory allocation, error throwing,
etc. between <function>GenericXLogStart()</function> and
<function>GenericXLogFinish()</function>. The only actual critical section is
present inside <function>GenericXLogFinish()</function>. There is no need to
worry about calling <function>GenericXLogAbort()</function> during an error
exit, either.
ここではバッファページのコピーを更新するため、GenericXLogStart()
はクリティカルセクションを開始しません。
従って、GenericXLogStart()
とGenericXLogFinish()
の間では、メモリの割り当て、エラーの発生などを安全に実行できます。
唯一の本当のクリティカルセクションはGenericXLogFinish()
の内部にあります。
エラー終了の中でGenericXLogAbort()
を呼び出すことについても心配する必要はありません。
<function>GenericXLogFinish()</function> takes care of marking buffers dirty
and setting their LSNs. You do not need to do this explicitly.
GenericXLogFinish()
はバッファをダーティにして、LSNの設定をすることの処理をします。
これについて明示的な処理をする必要はありません。
For unlogged relations, everything works the same except that no actual WAL record is emitted. Thus, you typically do not need to do any explicit checks for unlogged relations. ログを取らないリレーションは、実際のWALレコードが送出されないことを除けば、すべてが同じように動作します。 従って、通常は、ログを取らないリレーションについて明示的な検査をする必要はありません。
The generic WAL redo function will acquire exclusive locks to buffers in the same order as they were registered. After redoing all changes, the locks will be released in the same order. 汎用WALを再生する機能は、バッファの排他的ロックを、バッファが登録されたのと同じ順序で取得します。 すべての変更を再生した後で、ロックは同じ順序で解放されます。
If <literal>GENERIC_XLOG_FULL_IMAGE</literal> 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.
登録バッファにGENERIC_XLOG_FULL_IMAGE
が指定されない場合、汎用WALレコードは古いページイメージと新しいページイメージの間の差分を含むものとされます。
この差分はバイト毎の比較に基づくものです。
これはデータをページ内で移動する場合、あまり小さくなりませんが、将来は改善されるかもしれません。