skip to Main Content

We’re doing a Postgres native logical replication between two databases.

Now, we’re getting an error trying to update from the publisher one of thousand tables that we have.

When we try to update the table it returns this error:

ERROR: Column list used by the publication does not cover the replica identity.cannot update table "etiquetas_j".

ERROR: cannot update table "etiquetas_j"
Estado SQL: 42P10
Detalle: Column list used by the publication does not cover the replica identity.

The table definition, datatypes, indexes, and pkeys are the same at publisher and subscriptor

See here:

Publisher:

    CREATE TABLE IF NOT EXISTS public.etiquetas_j (
    etiqueta_id integer NOT NULL,
    fecha timestamp without time zone,
    j_id integer NOT NULL,
    usuario_del_id integer,
    usuario_mod_id integer,
    organigrama_mod character varying(2) COLLATE pg_catalog."default",
    id integer NOT NULL DEFAULT nextval('etiquetas_j_id_seq1'::regclass),
    CONSTRAINT etiquetas_j_pkey PRIMARY KEY (id))
TABLESPACE pg_default; ALTER TABLE IF EXISTS public.etiquetas_j
    OWNER to postgres;


CREATE INDEX IF NOT EXISTS etiquetas_j_etiqueta_id_idx
    ON public.etiquetas_j USING btree
    (etiqueta_id ASC NULLS LAST)
    TABLESPACE pg_default;

CREATE INDEX IF NOT EXISTS etiquetas_j_id_idx
    ON public.etiquetas_j USING btree
    (j_id ASC NULLS LAST)
    TABLESPACE pg_default;

Subscriptor:

CREATE TABLE IF NOT EXISTS public.etiquetas_j
(
    etiqueta_id integer NOT NULL,
    fecha timestamp without time zone,
    j_id integer NOT NULL,
    usuario_del_id integer,
    usuario_mod_id integer,
    organigrama_mod character varying(2) COLLATE pg_catalog."default",
    id integer NOT NULL DEFAULT nextval('etiquetas_j_id_seq1'::regclass),
    CONSTRAINT etiquetas_j_pkey PRIMARY KEY (id)
)

TABLESPACE pg_default;

ALTER TABLE IF EXISTS public.etiquetas_j
    OWNER to postgres;

CREATE INDEX IF NOT EXISTS etiquetas_j_etiqueta_id_idx
    ON public.etiquetas_j USING btree
    (etiqueta_id ASC NULLS LAST)
    TABLESPACE pg_default;

CREATE INDEX IF NOT EXISTS etiquetas_j_id_idx
    ON public.etiquetas_j USING btree
    (j_id ASC NULLS LAST)
    TABLESPACE pg_default;

The publication is defined as follows:

CREATE PUBLICATION publication_visor FOR TABLE etiquetas_j(
    etiqueta_id,
    fecha,
    j_id,
    usuario_del_id,
    usuario_mod_id ,
    organigrama_mod,
    id)

The error occurs when we execute in the provider:
update etiquetas_j set organigrama_mod = '02' where id = 3;

Thanks, and sorry for the bad english!

We have already checked:

  1. See what the indexes are.
  2. See what differs in both schemas.
  3. See what publisher was sending at publication create.
  4. Applied ALTER TABLE etiquetas_j REPLICA IDENTITY FULL;

2

Answers


  1. Chosen as BEST ANSWER

    I solved it.

    For some reason, we used ALTER TABLE in the publisher side and the subscription side to make id as primary key and the schemas, indexes, and everything was identical. Enable the subscription again and refresh the PUBLICATION on the CLIENT SIDE but never worked.

    I did the next steps to solve it:

    1. Pause the SUBSCRIPTION: ALTER SUBSCRIPTION subscription_name DISABLE
    2. Drop the PUBLICATION of the table in the PUBLISHER SIDE. DROP PUBLICATION publication_name
    3. Backup only the data of the table that was throwing error in the PUBLISHER SIDE.
    4. Deleted the table in the PUBLISHER SIDE.
    5. Created the table again in the PUBLISHER SIDE but now, with id as primary key from zero (not with alter).
    6. Create a NEW SLOT in the Publisher Side. select pg_create_logical_replication_slot('YOUR_NEW_NAME_SLOT', 'pgoutput');
    7. Create the PUBLICATION that includes that table.
    8. In the client side, resume the subscription. ALTER SUBSCRIPTION subscription_name ENABLE
    9. Set the new slot to the subscriptor ALTER SUBSCRIPTION subscription_name SET (slot_name='YOUR_NEW_NAME_SLOT')
    10. ALTER SUBSCRIPTION subscription_name REFRESH PUBLICATION;
    11. See if SLOT has active: true. SELECT slot_name, plugin, slot_type, database, active FROM pg_replication_slots WHERE plugin = 'pgoutput';
    12. If slot it's working ok. Restore the data in the PUBLISHER SIDE and CLIENT SIDE will start to replicate.
    13. After the replication ends, update one row, or anything and will work.

    We specify the slots in the subscriptor because we have two databases at the same server instance.


  2. When the replica identity of the table is not entirely covered by the columns provided in the publication, you will receive the error "Column list used by the publication does not cover the replica identity." In your situation, you have a publication defined on the table etiquetas_j with a list of specified columns. Although it is not one of the columns stated in the publication (etiqueta_id, fecha, id, j_id, usuario_del_id, usuario_mod_id, organigrama_mod), the organigrama_mod column gets updated when you attempt to edit the table.

    You must check that the columns involved in the replica identity (primary key or unique constraint columns) are listed in the publication column list in order to fix this. The id column in your case appears to be the main key, and you’ve included it in the publication. The organigrama_mod column appears to be updated rather than being a part of the replica identity, though.

    The organigrama_mod column needs to be added to the list of publication columns in order to resolve the problem, or you should avoid directly editing it if it isn’t part of the replica identity. To cover all columns and prevent future problems, you might also think about altering the replica identity of the table to FULL.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search