"out of relcache_callback_list slots" after multiple calls to pg_logical_slot_get_binary_changes
Yu Shi (Fujitsu) <shiy.fnst@fujitsu.com>
From: "shiy.fnst@fujitsu.com" <shiy.fnst@fujitsu.com>
To: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2023-02-19T02:40:31Z
Lists: pgsql-hackers
Attachments
- v1-0001-Unregister-syscache-callback-and-relcache-callbac.patch (application/octet-stream) patch v1-0001
Hi hackers,
After multiple calls to the function pg_logical_slot_get_binary_changes() in
single client backend (the output plugin of the slot is pgoutput), I got the
following error:
client backend FATAL: out of relcache_callback_list slots
client backend CONTEXT: slot "testslot", output plugin "pgoutput", in the startup callback
client backend STATEMENT: SELECT data FROM pg_logical_slot_get_binary_changes('testslot', NULL, NULL, 'proto_version', '3', 'streaming', 'off', 'publication_names', 'pub');
I tried to look into it and found that it's because every time the function
(pg_logical_slot_get_binary_changes) is called, relcache callback and syscache
callbacks are registered when initializing pgoutput (see pgoutput_startup() and
init_rel_sync_cache()), but they are not unregistered when it shutdowns. So,
after multiple calls to the function, MAX_RELCACHE_CALLBACKS is exceeded. This
is mentioned in the following comment.
/*
* We can get here if the plugin was used in SQL interface as the
* RelSchemaSyncCache is destroyed when the decoding finishes, but there
* is no way to unregister the relcache invalidation callback.
*/
if (RelationSyncCache == NULL)
return;
Could we fix it by adding two new function to unregister relcache callback and
syscache callback? I tried to do so in the attached patch.
Regards,
Shi Yu
Commits
-
Don't repeatedly register cache callbacks in pgoutput plugin.
- 05172f1f3749 16.0 landed
- cef1c9c0cf6e 15.3 landed
- 95558bc8ff89 12.15 landed
- 861e9e48601b 13.11 landed
- 44dbc960f671 11.20 landed
- 0f78df719a90 14.8 landed