Skip to content

Commit 50371df

Browse files
committed
Don't try to print data type names in slot_store_error_callback().
The existing code tried to do syscache lookups in an already-failed transaction, which is problematic to say the least. After some consideration of alternatives, the best fix seems to be to just drop type names from the error message altogether. The table and column names seem like sufficient localization. If the user is unsure what types are involved, she can check the local and remote table definitions. Having done that, we can also discard the LogicalRepTypMap hash table, which had no other use. Arguably, LOGICAL_REP_MSG_TYPE replication messages are now obsolete as well; but we should probably keep them in case some other use emerges. (The complexity of removing something from the replication protocol would likely outweigh any savings anyhow.) Masahiko Sawada and Bharath Rupireddy, per complaint from Andres Freund. Back-patch to v10 where this code originated. Discussion: https://postgr.es/m/[email protected]
1 parent 6bd3ec6 commit 50371df

File tree

3 files changed

+6
-134
lines changed

3 files changed

+6
-134
lines changed

src/backend/replication/logical/relation.c

+1-104
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,19 @@
1717

1818
#include "postgres.h"
1919

20-
#include "access/sysattr.h"
2120
#include "access/table.h"
2221
#include "catalog/namespace.h"
2322
#include "catalog/pg_subscription_rel.h"
2423
#include "executor/executor.h"
2524
#include "nodes/makefuncs.h"
2625
#include "replication/logicalrelation.h"
2726
#include "replication/worker_internal.h"
28-
#include "utils/builtins.h"
2927
#include "utils/inval.h"
30-
#include "utils/lsyscache.h"
31-
#include "utils/memutils.h"
32-
#include "utils/syscache.h"
28+
3329

3430
static MemoryContext LogicalRepRelMapContext = NULL;
3531

3632
static HTAB *LogicalRepRelMap = NULL;
37-
static HTAB *LogicalRepTypMap = NULL;
3833

3934
/*
4035
* Partition map (LogicalRepPartMap)
@@ -118,15 +113,6 @@ logicalrep_relmap_init(void)
118113
LogicalRepRelMap = hash_create("logicalrep relation map cache", 128, &ctl,
119114
HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
120115

121-
/* Initialize the type hash table. */
122-
ctl.keysize = sizeof(Oid);
123-
ctl.entrysize = sizeof(LogicalRepTyp);
124-
ctl.hcxt = LogicalRepRelMapContext;
125-
126-
/* This will usually be small. */
127-
LogicalRepTypMap = hash_create("logicalrep type map cache", 2, &ctl,
128-
HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
129-
130116
/* Watch for invalidation events. */
131117
CacheRegisterRelcacheCallback(logicalrep_relmap_invalidate_cb,
132118
(Datum) 0);
@@ -450,95 +436,6 @@ logicalrep_rel_close(LogicalRepRelMapEntry *rel, LOCKMODE lockmode)
450436
rel->localrel = NULL;
451437
}
452438

453-
/*
454-
* Free the type map cache entry data.
455-
*/
456-
static void
457-
logicalrep_typmap_free_entry(LogicalRepTyp *entry)
458-
{
459-
pfree(entry->nspname);
460-
pfree(entry->typname);
461-
}
462-
463-
/*
464-
* Add new entry or update existing entry in the type map cache.
465-
*/
466-
void
467-
logicalrep_typmap_update(LogicalRepTyp *remotetyp)
468-
{
469-
MemoryContext oldctx;
470-
LogicalRepTyp *entry;
471-
bool found;
472-
473-
if (LogicalRepTypMap == NULL)
474-
logicalrep_relmap_init();
475-
476-
/*
477-
* HASH_ENTER returns the existing entry if present or creates a new one.
478-
*/
479-
entry = hash_search(LogicalRepTypMap, (void *) &remotetyp->remoteid,
480-
HASH_ENTER, &found);
481-
482-
if (found)
483-
logicalrep_typmap_free_entry(entry);
484-
485-
/* Make cached copy of the data */
486-
entry->remoteid = remotetyp->remoteid;
487-
oldctx = MemoryContextSwitchTo(LogicalRepRelMapContext);
488-
entry->nspname = pstrdup(remotetyp->nspname);
489-
entry->typname = pstrdup(remotetyp->typname);
490-
MemoryContextSwitchTo(oldctx);
491-
}
492-
493-
/*
494-
* Fetch type name from the cache by remote type OID.
495-
*
496-
* Return a substitute value if we cannot find the data type; no message is
497-
* sent to the log in that case, because this is used by error callback
498-
* already.
499-
*/
500-
char *
501-
logicalrep_typmap_gettypname(Oid remoteid)
502-
{
503-
LogicalRepTyp *entry;
504-
bool found;
505-
506-
/* Internal types are mapped directly. */
507-
if (remoteid < FirstGenbkiObjectId)
508-
{
509-
if (!get_typisdefined(remoteid))
510-
{
511-
/*
512-
* This can be caused by having a publisher with a higher
513-
* PostgreSQL major version than the subscriber.
514-
*/
515-
return psprintf("unrecognized %u", remoteid);
516-
}
517-
518-
return format_type_be(remoteid);
519-
}
520-
521-
if (LogicalRepTypMap == NULL)
522-
{
523-
/*
524-
* If the typemap is not initialized yet, we cannot possibly attempt
525-
* to search the hash table; but there's no way we know the type
526-
* locally yet, since we haven't received a message about this type,
527-
* so this is the best we can do.
528-
*/
529-
return psprintf("unrecognized %u", remoteid);
530-
}
531-
532-
/* search the mapping */
533-
entry = hash_search(LogicalRepTypMap, (void *) &remoteid,
534-
HASH_FIND, &found);
535-
if (!found)
536-
return psprintf("unrecognized %u", remoteid);
537-
538-
Assert(OidIsValid(entry->remoteid));
539-
return psprintf("%s.%s", entry->nspname, entry->typname);
540-
}
541-
542439
/*
543440
* Partition cache: look up partition LogicalRepRelMapEntry's
544441
*

src/backend/replication/logical/worker.c

+5-27
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ static dlist_head lsn_mapping = DLIST_STATIC_INIT(lsn_mapping);
132132
typedef struct SlotErrCallbackArg
133133
{
134134
LogicalRepRelMapEntry *rel;
135-
int local_attnum;
136135
int remote_attnum;
137136
} SlotErrCallbackArg;
138137

@@ -503,36 +502,23 @@ slot_fill_defaults(LogicalRepRelMapEntry *rel, EState *estate,
503502
}
504503

505504
/*
506-
* Error callback to give more context info about type conversion failure.
505+
* Error callback to give more context info about data conversion failures
506+
* while reading data from the remote server.
507507
*/
508508
static void
509509
slot_store_error_callback(void *arg)
510510
{
511511
SlotErrCallbackArg *errarg = (SlotErrCallbackArg *) arg;
512512
LogicalRepRelMapEntry *rel;
513-
char *remotetypname;
514-
Oid remotetypoid,
515-
localtypoid;
516513

517514
/* Nothing to do if remote attribute number is not set */
518515
if (errarg->remote_attnum < 0)
519516
return;
520517

521518
rel = errarg->rel;
522-
remotetypoid = rel->remoterel.atttyps[errarg->remote_attnum];
523-
524-
/* Fetch remote type name from the LogicalRepTypMap cache */
525-
remotetypname = logicalrep_typmap_gettypname(remotetypoid);
526-
527-
/* Fetch local type OID from the local sys cache */
528-
localtypoid = get_atttype(rel->localreloid, errarg->local_attnum + 1);
529-
530-
errcontext("processing remote data for replication target relation \"%s.%s\" column \"%s\", "
531-
"remote type %s, local type %s",
519+
errcontext("processing remote data for replication target relation \"%s.%s\" column \"%s\"",
532520
rel->remoterel.nspname, rel->remoterel.relname,
533-
rel->remoterel.attnames[errarg->remote_attnum],
534-
remotetypname,
535-
format_type_be(localtypoid));
521+
rel->remoterel.attnames[errarg->remote_attnum]);
536522
}
537523

538524
/*
@@ -553,7 +539,6 @@ slot_store_data(TupleTableSlot *slot, LogicalRepRelMapEntry *rel,
553539

554540
/* Push callback + info on the error context stack */
555541
errarg.rel = rel;
556-
errarg.local_attnum = -1;
557542
errarg.remote_attnum = -1;
558543
errcallback.callback = slot_store_error_callback;
559544
errcallback.arg = (void *) &errarg;
@@ -573,7 +558,6 @@ slot_store_data(TupleTableSlot *slot, LogicalRepRelMapEntry *rel,
573558

574559
Assert(remoteattnum < tupleData->ncols);
575560

576-
errarg.local_attnum = i;
577561
errarg.remote_attnum = remoteattnum;
578562

579563
if (tupleData->colstatus[remoteattnum] == LOGICALREP_COLUMN_TEXT)
@@ -622,7 +606,6 @@ slot_store_data(TupleTableSlot *slot, LogicalRepRelMapEntry *rel,
622606
slot->tts_isnull[i] = true;
623607
}
624608

625-
errarg.local_attnum = -1;
626609
errarg.remote_attnum = -1;
627610
}
628611
else
@@ -679,7 +662,6 @@ slot_modify_data(TupleTableSlot *slot, TupleTableSlot *srcslot,
679662

680663
/* For error reporting, push callback + info on the error context stack */
681664
errarg.rel = rel;
682-
errarg.local_attnum = -1;
683665
errarg.remote_attnum = -1;
684666
errcallback.callback = slot_store_error_callback;
685667
errcallback.arg = (void *) &errarg;
@@ -702,7 +684,6 @@ slot_modify_data(TupleTableSlot *slot, TupleTableSlot *srcslot,
702684
{
703685
StringInfo colvalue = &tupleData->colvalues[remoteattnum];
704686

705-
errarg.local_attnum = i;
706687
errarg.remote_attnum = remoteattnum;
707688

708689
if (tupleData->colstatus[remoteattnum] == LOGICALREP_COLUMN_TEXT)
@@ -747,7 +728,6 @@ slot_modify_data(TupleTableSlot *slot, TupleTableSlot *srcslot,
747728
slot->tts_isnull[i] = true;
748729
}
749730

750-
errarg.local_attnum = -1;
751731
errarg.remote_attnum = -1;
752732
}
753733
}
@@ -1217,8 +1197,7 @@ apply_handle_relation(StringInfo s)
12171197
/*
12181198
* Handle TYPE message.
12191199
*
1220-
* Note we don't do local mapping here, that's done when the type is
1221-
* actually used.
1200+
* This is now vestigial; we read the info and discard it.
12221201
*/
12231202
static void
12241203
apply_handle_type(StringInfo s)
@@ -1229,7 +1208,6 @@ apply_handle_type(StringInfo s)
12291208
return;
12301209

12311210
logicalrep_read_typ(s, &typ);
1232-
logicalrep_typmap_update(&typ);
12331211
}
12341212

12351213
/*

src/include/replication/logicalrelation.h

-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,4 @@ extern LogicalRepRelMapEntry *logicalrep_partition_open(LogicalRepRelMapEntry *r
4646
extern void logicalrep_rel_close(LogicalRepRelMapEntry *rel,
4747
LOCKMODE lockmode);
4848

49-
extern void logicalrep_typmap_update(LogicalRepTyp *remotetyp);
50-
extern char *logicalrep_typmap_gettypname(Oid remoteid);
51-
5249
#endif /* LOGICALRELATION_H */

0 commit comments

Comments
 (0)