Re: Logical Decoding Callbacks

From: Andres Freund <andres(at)2ndquadrant(dot)com>
To: Xavier Stevens <xavier(at)simple(dot)com>
Cc: Michael Paquier <michael(dot)paquier(at)gmail(dot)com>, PostgreSQL mailing lists <pgsql-general(at)postgresql(dot)org>
Subject: Re: Logical Decoding Callbacks
Date: 2015-02-10 21:23:10
Message-ID: 20150210212310.GO21017@alap3.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On 2015-02-10 10:33:41 -0800, Xavier Stevens wrote:
> Sorry to raise the issue on startup_cb. I added a whole bunch of logging
> statements and I was only running the section of code I wanted when the
> startup callback had options.

Heh.

Just to make sure: You can pass options via replication protocol too.

> This now gets me to the next issue I encounter. In my output plugin, I'm
> trying to use the SPI interface to query about PostGIS OIDs in the startup
> callback. Just calling SPI_connect() seems to be causing a segfault.

> This is the last thing I see in the logs before the segfault occurs:
>
> https://github.com/xstevens/decoderbufs/blob/master/src/decoderbufs.c#L151

The problem likely is that in the startup callback you're neither
guaranteed to be in a transaction, nor to have a snapshot set up.

It'd generally be easier to analyze such problems if you provide a
backtrace (e.g. by enabling core files). Another generally very
adviseable thing to do when developing code running in the backend is to
enable assertions (you may already do that...).

You can lookup types much easier than that btw. C.f. TypenameGetTypid(typname)

But note that both that and what you do would possibly fail if there's
more than one geometry type around. You could either hardcode postgis'
schema name and use
namespaceId = LookupExplicitNamespace(schemaname, false);
typoid = GetSysCacheOid2(TYPENAMENSP, PointerGetDatum(typname), ObjectIdGetDatum(namespaceId));
if (typoid == InvalidOid)
elog(ERROR, "cache lookup failed for type %u", typoid);

or be a bit more complex and lookup the postgis' extension's schema
pg_extension.extnamespace first.

Anyway, to run full queries in the startup callback you're going to have
to do something like:

if (!IsTransactionState())
{
tx_started = true;
StartTransactionCommand();
}
PushActiveSnapshot(GetTransactionSnapshot());

/* do your stuff */

PopActiveSnapshot();
if (tx_started)
CommitTransactionCommand();

Note that the begin, change, commit callbacks *do* run with a
transaction and snapshot setup. But you can't run general SQL queries -
only catalog tables (or tables marked as such) are accessible.

Greetings,

Andres Freund

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

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Jeremiah Ocasio 2015-02-10 23:26:32 Re: [ADMIN] Change postgresql encoding
Previous Message Merlin Moncure 2015-02-10 21:22:00 Re: Stability of JSON textual representation