Re: Proposal: Generic WAL logical messages - Mailing list pgsql-hackers

From Petr Jelinek
Subject Re: Proposal: Generic WAL logical messages
Date
Msg-id 56D36A2C.3070807@2ndquadrant.com
Whole thread Raw
In response to Re: Proposal: Generic WAL logical messages  (Andres Freund <andres@anarazel.de>)
Responses Re: Proposal: Generic WAL logical messages
List pgsql-hackers
Hi,

thanks for looking Andres,


On 27/02/16 01:05, Andres Freund wrote:
> Hi,
>
> I'm not really convinced by RegisterStandbyMsgPrefix() et al. There's
> not much documentation about what it actually is supposed to
> acomplish. Afaics you're basically forced to use
> shared_preload_libraries with it right now?  Also, iterating through a
> linked list everytime something is logged doesn't seem very satisfying?
>

Well, my reasoning there was to stop multiple plugins from using same 
prefix and for that you need some kind of registry. Making this a shared 
catalog seemed like huge overkill given the potentially transient nature 
of output plugins and this was the best I could come up with. And yes it 
requires you to load your plugin before you can log a message for it.

I am not married to this solution so if you have better ideas or if you 
think the clashes are not read issue, we can change it.

>
> On 2016-02-24 18:35:16 +0100, Petr Jelinek wrote:
>> +SET synchronous_commit = on;
>> +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
>> + ?column?
>> +----------
>> + init
>> +(1 row)
>
>> +SELECT 'msg1' FROM pg_logical_send_message(true, 'test', 'msg1');
>> + ?column?
>> +----------
>> + msg1
>> +(1 row)
>
> Hm. Somehow 'sending' a message seems wrong here. Maybe 'emit'?
>
>> +      <row>
>> +       <entry id="pg-logical-send-message-text">
>> +        <indexterm>
>> +         <primary>pg_logical_send_message</primary>
>> +        </indexterm>
>> +        <literal><function>pg_logical_send_message(<parameter>transactional</parameter> <type>bool</type>,
<parameter>prefix</parameter><type>text</type>, <parameter>content</parameter> <type>text</type>)</function></literal>
 
>> +       </entry>
>> +       <entry>
>> +        void
>> +       </entry>
>> +       <entry>
>> +        Write text logical decoding message. This can be used to pass generic
>> +        messages to logical decoding plugins through WAL. The parameter
>> +        <parameter>transactional</parameter> specifies if the message should
>> +        be part of current transaction or if it should be written and decoded
>> +        immediately. The <parameter>prefix</parameter> has to be prefix which
>> +        was registered by a plugin. The <parameter>content</parameter> is
>> +        content of the message.
>> +       </entry>
>> +      </row>
>
> It's not decoded immediately, even if emitted non-transactionally.
>

Okay, immediately is somewhat misleading. How does "should be written 
immediately and decoded as soon as logical decoding reads the WAL 
record" sound ?

>> +    <sect3 id="logicaldecoding-output-plugin-message">
>> +     <title>Generic Message Callback</title>
>> +
>> +     <para>
>> +      The optional <function>message_cb</function> callback is called whenever
>> +      a logical decoding message has been decoded.
>> +<programlisting>
>> +typedef void (*LogicalDecodeMessageCB) (
>> +    struct LogicalDecodingContext *,
>> +    ReorderBufferTXN *txn,
>> +    XLogRecPtr message_lsn,
>> +    bool transactional,
>> +    const char *prefix,
>> +    Size message_size,
>> +    const char *message
>> +);
>
> We should at least document what txn is set to if not transactional.
>

Will do (it's NULL).

>> +void
>> +logicalmsg_desc(StringInfo buf, XLogReaderState *record)
>> +{
>> +    char               *rec = XLogRecGetData(record);
>> +    xl_logical_message *xlrec = (xl_logical_message *) rec;
>> +
>> +    appendStringInfo(buf, "%s message size %zu bytes",
>> +                     xlrec->transactional ? "transactional" : "nontransactional",
>> +                     xlrec->message_size);
>> +}
>
> Shouldn't we check
>            uint8         info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
>            if XLogRecGetInfo(record) == XLOG_LOGICAL_MESSAGE
> here?
>

I thought it's kinda pointless, but we seem to be doing it in other 
places so will add.

>
>> +void
>> +ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn,
>> +                          bool transactional, const char *prefix, Size msg_sz,
>> +                          const char *msg)
>> +{
>> +    ReorderBufferTXN *txn = NULL;
>> +
>> +    if (transactional)
>> +    {
>> +        ReorderBufferChange *change;
>> +
>> +        txn = ReorderBufferTXNByXid(rb, xid, true, NULL, lsn, true);
>> +
>> +        Assert(xid != InvalidTransactionId);
>> +        Assert(txn != NULL);
>> +
>> +        change = ReorderBufferGetChange(rb);
>> +        change->action = REORDER_BUFFER_CHANGE_MESSAGE;
>> +        change->data.msg.transactional = true;
>> +        change->data.msg.prefix = pstrdup(prefix);
>> +        change->data.msg.message_size = msg_sz;
>> +        change->data.msg.message = palloc(msg_sz);
>> +        memcpy(change->data.msg.message, msg, msg_sz);
>> +
>> +        ReorderBufferQueueChange(rb, xid, lsn, change);
>> +    }
>> +    else
>> +    {
>> +        rb->message(rb, txn, lsn, transactional, prefix, msg_sz, msg);
>> +    }
>> +}
>
>
> This approach prohibts catalog access when processing a nontransaction
> message as there's no snapshot set up.
>

Hmm I do see usefulness in having snapshot, although I wonder if that 
does not kill the point of non-transactional messages. Question is then 
though which snapshot should the message see, base_snapshot of 
transaction? That would mean we'd have to call SnapBuildProcessChange 
for non-transactional messages which we currently avoid. Alternatively 
we could probably invent lighter version of that interface that would 
just make sure builder->snapshot is valid and if not then build it but 
I am honestly sure if that's a win or not.

--   Petr Jelinek                  http://www.2ndQuadrant.com/  PostgreSQL Development, 24x7 Support, Training &
Services



pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: WIP: Upper planner pathification
Next
From: Andres Freund
Date:
Subject: Re: Proposal: Generic WAL logical messages