diff options
Diffstat (limited to 'doc/src/sgml/html/logicaldecoding-output-plugin.html')
-rw-r--r-- | doc/src/sgml/html/logicaldecoding-output-plugin.html | 471 |
1 files changed, 471 insertions, 0 deletions
diff --git a/doc/src/sgml/html/logicaldecoding-output-plugin.html b/doc/src/sgml/html/logicaldecoding-output-plugin.html new file mode 100644 index 0000000..992b338 --- /dev/null +++ b/doc/src/sgml/html/logicaldecoding-output-plugin.html @@ -0,0 +1,471 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.6. Logical Decoding Output Plugins</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding" /><link rel="next" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.6. Logical Decoding Output Plugins</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-OUTPUT-PLUGIN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.6. Logical Decoding Output Plugins</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-INIT">49.6.1. Initialization Function</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-CAPABILITIES">49.6.2. Capabilities</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-MODE">49.6.3. Output Modes</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-CALLBACKS">49.6.4. Output Plugin Callbacks</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-OUTPUT">49.6.5. Functions for Producing Output</a></span></dt></dl></div><p> + An example output plugin can be found in the + <a class="link" href="test-decoding.html" title="F.45. test_decoding"> + <code class="filename">contrib/test_decoding</code> + </a> + subdirectory of the PostgreSQL source tree. + </p><div class="sect2" id="LOGICALDECODING-OUTPUT-INIT"><div class="titlepage"><div><div><h3 class="title">49.6.1. Initialization Function</h3></div></div></div><a id="id-1.8.14.12.3.2" class="indexterm"></a><p> + An output plugin is loaded by dynamically loading a shared library with + the output plugin's name as the library base name. The normal library + search path is used to locate the library. To provide the required output + plugin callbacks and to indicate that the library is actually an output + plugin it needs to provide a function named + <code class="function">_PG_output_plugin_init</code>. This function is passed a + struct that needs to be filled with the callback function pointers for + individual actions. +</p><pre class="programlisting"> +typedef struct OutputPluginCallbacks +{ + LogicalDecodeStartupCB startup_cb; + LogicalDecodeBeginCB begin_cb; + LogicalDecodeChangeCB change_cb; + LogicalDecodeTruncateCB truncate_cb; + LogicalDecodeCommitCB commit_cb; + LogicalDecodeMessageCB message_cb; + LogicalDecodeFilterByOriginCB filter_by_origin_cb; + LogicalDecodeShutdownCB shutdown_cb; + LogicalDecodeFilterPrepareCB filter_prepare_cb; + LogicalDecodeBeginPrepareCB begin_prepare_cb; + LogicalDecodePrepareCB prepare_cb; + LogicalDecodeCommitPreparedCB commit_prepared_cb; + LogicalDecodeRollbackPreparedCB rollback_prepared_cb; + LogicalDecodeStreamStartCB stream_start_cb; + LogicalDecodeStreamStopCB stream_stop_cb; + LogicalDecodeStreamAbortCB stream_abort_cb; + LogicalDecodeStreamPrepareCB stream_prepare_cb; + LogicalDecodeStreamCommitCB stream_commit_cb; + LogicalDecodeStreamChangeCB stream_change_cb; + LogicalDecodeStreamMessageCB stream_message_cb; + LogicalDecodeStreamTruncateCB stream_truncate_cb; +} OutputPluginCallbacks; + +typedef void (*LogicalOutputPluginInit) (struct OutputPluginCallbacks *cb); +</pre><p> + The <code class="function">begin_cb</code>, <code class="function">change_cb</code> + and <code class="function">commit_cb</code> callbacks are required, + while <code class="function">startup_cb</code>, + <code class="function">filter_by_origin_cb</code>, <code class="function">truncate_cb</code>, + and <code class="function">shutdown_cb</code> are optional. + If <code class="function">truncate_cb</code> is not set but a + <code class="command">TRUNCATE</code> is to be decoded, the action will be ignored. + </p><p> + An output plugin may also define functions to support streaming of large, + in-progress transactions. The <code class="function">stream_start_cb</code>, + <code class="function">stream_stop_cb</code>, <code class="function">stream_abort_cb</code>, + <code class="function">stream_commit_cb</code>, <code class="function">stream_change_cb</code>, + and <code class="function">stream_prepare_cb</code> + are required, while <code class="function">stream_message_cb</code> and + <code class="function">stream_truncate_cb</code> are optional. + </p><p> + An output plugin may also define functions to support two-phase commits, + which allows actions to be decoded on the <code class="command">PREPARE TRANSACTION</code>. + The <code class="function">begin_prepare_cb</code>, <code class="function">prepare_cb</code>, + <code class="function">stream_prepare_cb</code>, + <code class="function">commit_prepared_cb</code> and <code class="function">rollback_prepared_cb</code> + callbacks are required, while <code class="function">filter_prepare_cb</code> is optional. + </p></div><div class="sect2" id="LOGICALDECODING-CAPABILITIES"><div class="titlepage"><div><div><h3 class="title">49.6.2. Capabilities</h3></div></div></div><p> + To decode, format and output changes, output plugins can use most of the + backend's normal infrastructure, including calling output functions. Read + only access to relations is permitted as long as only relations are + accessed that either have been created by <code class="command">initdb</code> in + the <code class="literal">pg_catalog</code> schema, or have been marked as user + provided catalog tables using +</p><pre class="programlisting"> +ALTER TABLE user_catalog_table SET (user_catalog_table = true); +CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true); +</pre><p> + Note that access to user catalog tables or regular system catalog tables + in the output plugins has to be done via the <code class="literal">systable_*</code> + scan APIs only. Access via the <code class="literal">heap_*</code> scan APIs will + error out. Additionally, any actions leading to transaction ID assignment + are prohibited. That, among others, includes writing to tables, performing + DDL changes, and calling <code class="literal">pg_current_xact_id()</code>. + </p></div><div class="sect2" id="LOGICALDECODING-OUTPUT-MODE"><div class="titlepage"><div><div><h3 class="title">49.6.3. Output Modes</h3></div></div></div><p> + Output plugin callbacks can pass data to the consumer in nearly arbitrary + formats. For some use cases, like viewing the changes via SQL, returning + data in a data type that can contain arbitrary data (e.g., <code class="type">bytea</code>) is + cumbersome. If the output plugin only outputs textual data in the + server's encoding, it can declare that by + setting <code class="literal">OutputPluginOptions.output_type</code> + to <code class="literal">OUTPUT_PLUGIN_TEXTUAL_OUTPUT</code> instead + of <code class="literal">OUTPUT_PLUGIN_BINARY_OUTPUT</code> in + the <a class="link" href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-STARTUP" title="49.6.4.1. Startup Callback">startup + callback</a>. In that case, all the data has to be in the server's encoding + so that a <code class="type">text</code> datum can contain it. This is checked in assertion-enabled + builds. + </p></div><div class="sect2" id="LOGICALDECODING-OUTPUT-PLUGIN-CALLBACKS"><div class="titlepage"><div><div><h3 class="title">49.6.4. Output Plugin Callbacks</h3></div></div></div><p> + An output plugin gets notified about changes that are happening via + various callbacks it needs to provide. + </p><p> + Concurrent transactions are decoded in commit order, and only changes + belonging to a specific transaction are decoded between + the <code class="literal">begin</code> and <code class="literal">commit</code> + callbacks. Transactions that were rolled back explicitly or implicitly + never get + decoded. Successful savepoints are + folded into the transaction containing them in the order they were + executed within that transaction. A transaction that is prepared for + a two-phase commit using <code class="command">PREPARE TRANSACTION</code> will + also be decoded if the output plugin callbacks needed for decoding + them are provided. It is possible that the current prepared transaction + which is being decoded is aborted concurrently via a + <code class="command">ROLLBACK PREPARED</code> command. In that case, the logical + decoding of this transaction will be aborted too. All the changes of such + a transaction are skipped once the abort is detected and the + <code class="function">prepare_cb</code> callback is invoked. Thus even in case of + a concurrent abort, enough information is provided to the output plugin + for it to properly deal with <code class="command">ROLLBACK PREPARED</code> once + that is decoded. + </p><div class="note"><h3 class="title">Note</h3><p> + Only transactions that have already safely been flushed to disk will be + decoded. That can lead to a <code class="command">COMMIT</code> not immediately being decoded in a + directly following <code class="literal">pg_logical_slot_get_changes()</code> + when <code class="varname">synchronous_commit</code> is set + to <code class="literal">off</code>. + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STARTUP"><div class="titlepage"><div><div><h4 class="title">49.6.4.1. Startup Callback</h4></div></div></div><p> + The optional <code class="function">startup_cb</code> callback is called whenever + a replication slot is created or asked to stream changes, independent + of the number of changes that are ready to be put out. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeStartupCB) (struct LogicalDecodingContext *ctx, + OutputPluginOptions *options, + bool is_init); +</pre><p> + The <code class="literal">is_init</code> parameter will be true when the + replication slot is being created and false + otherwise. <em class="parameter"><code>options</code></em> points to a struct of options + that output plugins can set: +</p><pre class="programlisting"> +typedef struct OutputPluginOptions +{ + OutputPluginOutputType output_type; + bool receive_rewrites; +} OutputPluginOptions; +</pre><p> + <code class="literal">output_type</code> has to either be set to + <code class="literal">OUTPUT_PLUGIN_TEXTUAL_OUTPUT</code> + or <code class="literal">OUTPUT_PLUGIN_BINARY_OUTPUT</code>. See also + <a class="xref" href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-MODE" title="49.6.3. Output Modes">Section 49.6.3</a>. + If <code class="literal">receive_rewrites</code> is true, the output plugin will + also be called for changes made by heap rewrites during certain DDL + operations. These are of interest to plugins that handle DDL + replication, but they require special handling. + </p><p> + The startup callback should validate the options present in + <code class="literal">ctx->output_plugin_options</code>. If the output plugin + needs to have a state, it can + use <code class="literal">ctx->output_plugin_private</code> to store it. + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-SHUTDOWN"><div class="titlepage"><div><div><h4 class="title">49.6.4.2. Shutdown Callback</h4></div></div></div><p> + The optional <code class="function">shutdown_cb</code> callback is called + whenever a formerly active replication slot is not used anymore and can + be used to deallocate resources private to the output plugin. The slot + isn't necessarily being dropped, streaming is just being stopped. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeShutdownCB) (struct LogicalDecodingContext *ctx); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-BEGIN"><div class="titlepage"><div><div><h4 class="title">49.6.4.3. Transaction Begin Callback</h4></div></div></div><p> + The required <code class="function">begin_cb</code> callback is called whenever a + start of a committed transaction has been decoded. Aborted transactions + and their contents never get decoded. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeBeginCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); +</pre><p> + The <em class="parameter"><code>txn</code></em> parameter contains meta information about + the transaction, like the time stamp at which it has been committed and + its XID. + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-COMMIT"><div class="titlepage"><div><div><h4 class="title">49.6.4.4. Transaction End Callback</h4></div></div></div><p> + The required <code class="function">commit_cb</code> callback is called whenever + a transaction commit has been + decoded. The <code class="function">change_cb</code> callbacks for all modified + rows will have been called before this, if there have been any modified + rows. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeCommitCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-CHANGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.5. Change Callback</h4></div></div></div><p> + The required <code class="function">change_cb</code> callback is called for every + individual row modification inside a transaction, may it be + an <code class="command">INSERT</code>, <code class="command">UPDATE</code>, + or <code class="command">DELETE</code>. Even if the original command modified + several rows at once the callback will be called individually for each + row. The <code class="function">change_cb</code> callback may access system or + user catalog tables to aid in the process of outputting the row + modification details. In case of decoding a prepared (but yet + uncommitted) transaction or decoding of an uncommitted transaction, this + change callback might also error out due to simultaneous rollback of + this very same transaction. In that case, the logical decoding of this + aborted transaction is stopped gracefully. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeChangeCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + Relation relation, + ReorderBufferChange *change); +</pre><p> + The <em class="parameter"><code>ctx</code></em> and <em class="parameter"><code>txn</code></em> parameters + have the same contents as for the <code class="function">begin_cb</code> + and <code class="function">commit_cb</code> callbacks, but additionally the + relation descriptor <em class="parameter"><code>relation</code></em> points to the + relation the row belongs to and a struct + <em class="parameter"><code>change</code></em> describing the row modification are passed + in. + </p><div class="note"><h3 class="title">Note</h3><p> + Only changes in user defined tables that are not unlogged + (see <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-UNLOGGED"><code class="literal">UNLOGGED</code></a>) and not temporary + (see <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-TEMPORARY"><code class="literal">TEMPORARY</code> or <code class="literal">TEMP</code></a>) can be extracted using + logical decoding. + </p></div></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-TRUNCATE"><div class="titlepage"><div><div><h4 class="title">49.6.4.6. Truncate Callback</h4></div></div></div><p> + The <code class="function">truncate_cb</code> callback is called for a + <code class="command">TRUNCATE</code> command. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeTruncateCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + int nrelations, + Relation relations[], + ReorderBufferChange *change); +</pre><p> + The parameters are analogous to the <code class="function">change_cb</code> + callback. However, because <code class="command">TRUNCATE</code> actions on + tables connected by foreign keys need to be executed together, this + callback receives an array of relations instead of just a single one. + See the description of the <a class="xref" href="sql-truncate.html" title="TRUNCATE"><span class="refentrytitle">TRUNCATE</span></a> statement for + details. + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-FILTER-ORIGIN"><div class="titlepage"><div><div><h4 class="title">49.6.4.7. Origin Filter Callback</h4></div></div></div><p> + The optional <code class="function">filter_by_origin_cb</code> callback + is called to determine whether data that has been replayed + from <em class="parameter"><code>origin_id</code></em> is of interest to the + output plugin. +</p><pre class="programlisting"> +typedef bool (*LogicalDecodeFilterByOriginCB) (struct LogicalDecodingContext *ctx, + RepOriginId origin_id); +</pre><p> + The <em class="parameter"><code>ctx</code></em> parameter has the same contents + as for the other callbacks. No information but the origin is + available. To signal that changes originating on the passed in + node are irrelevant, return true, causing them to be filtered + away; false otherwise. The other callbacks will not be called + for transactions and changes that have been filtered away. + </p><p> + This is useful when implementing cascading or multidirectional + replication solutions. Filtering by the origin allows to + prevent replicating the same changes back and forth in such + setups. While transactions and changes also carry information + about the origin, filtering via this callback is noticeably + more efficient. + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-MESSAGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.8. Generic Message Callback</h4></div></div></div><p> + The optional <code class="function">message_cb</code> callback is called whenever + a logical decoding message has been decoded. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeMessageCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr message_lsn, + bool transactional, + const char *prefix, + Size message_size, + const char *message); +</pre><p> + The <em class="parameter"><code>txn</code></em> parameter contains meta information about + the transaction, like the time stamp at which it has been committed and + its XID. Note however that it can be NULL when the message is + non-transactional and the XID was not assigned yet in the transaction + which logged the message. The <em class="parameter"><code>lsn</code></em> has WAL + location of the message. The <em class="parameter"><code>transactional</code></em> says + if the message was sent as transactional or not. Similar to the change + callback, in case of decoding a prepared (but yet uncommitted) + transaction or decoding of an uncommitted transaction, this message + callback might also error out due to simultaneous rollback of + this very same transaction. In that case, the logical decoding of this + aborted transaction is stopped gracefully. + + The <em class="parameter"><code>prefix</code></em> is arbitrary null-terminated prefix + which can be used for identifying interesting messages for the current + plugin. And finally the <em class="parameter"><code>message</code></em> parameter holds + the actual message of <em class="parameter"><code>message_size</code></em> size. + </p><p> + Extra care should be taken to ensure that the prefix the output plugin + considers interesting is unique. Using name of the extension or the + output plugin itself is often a good choice. + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-FILTER-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.9. Prepare Filter Callback</h4></div></div></div><p> + The optional <code class="function">filter_prepare_cb</code> callback + is called to determine whether data that is part of the current + two-phase commit transaction should be considered for decoding + at this prepare stage or later as a regular one-phase transaction at + <code class="command">COMMIT PREPARED</code> time. To signal that + decoding should be skipped, return <code class="literal">true</code>; + <code class="literal">false</code> otherwise. When the callback is not + defined, <code class="literal">false</code> is assumed (i.e. no filtering, all + transactions using two-phase commit are decoded in two phases as well). +</p><pre class="programlisting"> +typedef bool (*LogicalDecodeFilterPrepareCB) (struct LogicalDecodingContext *ctx, + TransactionId xid, + const char *gid); +</pre><p> + The <em class="parameter"><code>ctx</code></em> parameter has the same contents as for + the other callbacks. The parameters <em class="parameter"><code>xid</code></em> + and <em class="parameter"><code>gid</code></em> provide two different ways to identify + the transaction. The later <code class="command">COMMIT PREPARED</code> or + <code class="command">ROLLBACK PREPARED</code> carries both identifiers, + providing an output plugin the choice of what to use. + </p><p> + The callback may be invoked multiple times per transaction to decode + and must provide the same static answer for a given pair of + <em class="parameter"><code>xid</code></em> and <em class="parameter"><code>gid</code></em> every time + it is called. + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-BEGIN-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.10. Transaction Begin Prepare Callback</h4></div></div></div><p> + The required <code class="function">begin_prepare_cb</code> callback is called + whenever the start of a prepared transaction has been decoded. The + <em class="parameter"><code>gid</code></em> field, which is part of the + <em class="parameter"><code>txn</code></em> parameter, can be used in this callback to + check if the plugin has already received this <code class="command">PREPARE</code> + in which case it can either error out or skip the remaining changes of + the transaction. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeBeginPrepareCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.11. Transaction Prepare Callback</h4></div></div></div><p> + The required <code class="function">prepare_cb</code> callback is called whenever + a transaction which is prepared for two-phase commit has been + decoded. The <code class="function">change_cb</code> callback for all modified + rows will have been called before this, if there have been any modified + rows. The <em class="parameter"><code>gid</code></em> field, which is part of the + <em class="parameter"><code>txn</code></em> parameter, can be used in this callback. +</p><pre class="programlisting"> +typedef void (*LogicalDecodePrepareCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-COMMIT-PREPARED"><div class="titlepage"><div><div><h4 class="title">49.6.4.12. Transaction Commit Prepared Callback</h4></div></div></div><p> + The required <code class="function">commit_prepared_cb</code> callback is called + whenever a transaction <code class="command">COMMIT PREPARED</code> has been decoded. + The <em class="parameter"><code>gid</code></em> field, which is part of the + <em class="parameter"><code>txn</code></em> parameter, can be used in this callback. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeCommitPreparedCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-ROLLBACK-PREPARED"><div class="titlepage"><div><div><h4 class="title">49.6.4.13. Transaction Rollback Prepared Callback</h4></div></div></div><p> + The required <code class="function">rollback_prepared_cb</code> callback is called + whenever a transaction <code class="command">ROLLBACK PREPARED</code> has been + decoded. The <em class="parameter"><code>gid</code></em> field, which is part of the + <em class="parameter"><code>txn</code></em> parameter, can be used in this callback. The + parameters <em class="parameter"><code>prepare_end_lsn</code></em> and + <em class="parameter"><code>prepare_time</code></em> can be used to check if the plugin + has received this <code class="command">PREPARE TRANSACTION</code> in which case + it can apply the rollback, otherwise, it can skip the rollback operation. The + <em class="parameter"><code>gid</code></em> alone is not sufficient because the downstream + node can have a prepared transaction with same identifier. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeRollbackPreparedCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_end_lsn, + TimestampTz prepare_time); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-START"><div class="titlepage"><div><div><h4 class="title">49.6.4.14. Stream Start Callback</h4></div></div></div><p> + The <code class="function">stream_start_cb</code> callback is called when opening + a block of streamed changes from an in-progress transaction. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeStreamStartCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-STOP"><div class="titlepage"><div><div><h4 class="title">49.6.4.15. Stream Stop Callback</h4></div></div></div><p> + The <code class="function">stream_stop_cb</code> callback is called when closing + a block of streamed changes from an in-progress transaction. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeStreamStopCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-ABORT"><div class="titlepage"><div><div><h4 class="title">49.6.4.16. Stream Abort Callback</h4></div></div></div><p> + The <code class="function">stream_abort_cb</code> callback is called to abort + a previously streamed transaction. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeStreamAbortCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr abort_lsn); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.17. Stream Prepare Callback</h4></div></div></div><p> + The <code class="function">stream_prepare_cb</code> callback is called to prepare + a previously streamed transaction as part of a two-phase commit. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeStreamPrepareCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-COMMIT"><div class="titlepage"><div><div><h4 class="title">49.6.4.18. Stream Commit Callback</h4></div></div></div><p> + The <code class="function">stream_commit_cb</code> callback is called to commit + a previously streamed transaction. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeStreamCommitCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-CHANGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.19. Stream Change Callback</h4></div></div></div><p> + The <code class="function">stream_change_cb</code> callback is called when sending + a change in a block of streamed changes (demarcated by + <code class="function">stream_start_cb</code> and <code class="function">stream_stop_cb</code> calls). + The actual changes are not displayed as the transaction can abort at a later + point in time and we don't decode changes for aborted transactions. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeStreamChangeCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + Relation relation, + ReorderBufferChange *change); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-MESSAGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.20. Stream Message Callback</h4></div></div></div><p> + The <code class="function">stream_message_cb</code> callback is called when sending + a generic message in a block of streamed changes (demarcated by + <code class="function">stream_start_cb</code> and <code class="function">stream_stop_cb</code> calls). + The message contents for transactional messages are not displayed as the transaction + can abort at a later point in time and we don't decode changes for aborted + transactions. +</p><pre class="programlisting"> +typedef void (*LogicalDecodeStreamMessageCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr message_lsn, + bool transactional, + const char *prefix, + Size message_size, + const char *message); +</pre><p> + </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-TRUNCATE"><div class="titlepage"><div><div><h4 class="title">49.6.4.21. Stream Truncate Callback</h4></div></div></div><p> + The <code class="function">stream_truncate_cb</code> callback is called for a + <code class="command">TRUNCATE</code> command in a block of streamed changes + (demarcated by <code class="function">stream_start_cb</code> and + <code class="function">stream_stop_cb</code> calls). +</p><pre class="programlisting"> +typedef void (*LogicalDecodeStreamTruncateCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + int nrelations, + Relation relations[], + ReorderBufferChange *change); +</pre><p> + The parameters are analogous to the <code class="function">stream_change_cb</code> + callback. However, because <code class="command">TRUNCATE</code> actions on + tables connected by foreign keys need to be executed together, this + callback receives an array of relations instead of just a single one. + See the description of the <a class="xref" href="sql-truncate.html" title="TRUNCATE"><span class="refentrytitle">TRUNCATE</span></a> statement for + details. + </p></div></div><div class="sect2" id="LOGICALDECODING-OUTPUT-PLUGIN-OUTPUT"><div class="titlepage"><div><div><h3 class="title">49.6.5. Functions for Producing Output</h3></div></div></div><p> + To actually produce output, output plugins can write data to + the <code class="literal">StringInfo</code> output buffer + in <code class="literal">ctx->out</code> when inside + the <code class="function">begin_cb</code>, <code class="function">commit_cb</code>, + or <code class="function">change_cb</code> callbacks. Before writing to the output + buffer, <code class="function">OutputPluginPrepareWrite(ctx, last_write)</code> has + to be called, and after finishing writing to the + buffer, <code class="function">OutputPluginWrite(ctx, last_write)</code> has to be + called to perform the write. The <em class="parameter"><code>last_write</code></em> + indicates whether a particular write was the callback's last write. + </p><p> + The following example shows how to output data to the consumer of an + output plugin: +</p><pre class="programlisting"> +OutputPluginPrepareWrite(ctx, true); +appendStringInfo(ctx->out, "BEGIN %u", txn->xid); +OutputPluginWrite(ctx, true); +</pre><p> + </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.5. System Catalogs Related to Logical Decoding </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.7. Logical Decoding Output Writers</td></tr></table></div></body></html>
\ No newline at end of file |