{"record":{"id":"0caf4adbb2535a8c","repo":"apache/seatunnel","slug":"cannot-determine-replica-identity-information-for","errorCode":null,"errorMessage":"Cannot determine REPLICA IDENTITY information for table '{}'","messagePattern":"Cannot determine REPLICA IDENTITY information for table '(.+?)'","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-opengauss/src/main/java/io/debezium/connector/postgresql/connection/PostgresConnection.java","lineNumber":235,"sourceCode":"                \"SELECT relreplident FROM pg_catalog.pg_class c \"\n                        + \"LEFT JOIN pg_catalog.pg_namespace n ON c.relnamespace=n.oid \"\n                        + \"WHERE n.nspname=? and c.relname=?\";\n        String schema =\n                tableId.schema() != null && tableId.schema().length() > 0\n                        ? tableId.schema()\n                        : \"public\";\n        StringBuilder replIdentity = new StringBuilder();\n        prepareQuery(\n                statement,\n                stmt -> {\n                    stmt.setString(1, schema);\n                    stmt.setString(2, tableId.table());\n                },\n                rs -> {\n                    if (rs.next()) {\n                        replIdentity.append(rs.getString(1));\n                    } else {\n                        LOGGER.warn(\n                                \"Cannot determine REPLICA IDENTITY information for table '{}'\",\n                                tableId);\n                    }\n                });\n        return ServerInfo.ReplicaIdentity.parseFromDB(replIdentity.toString());\n    }\n\n    /**\n     * Returns the current state of the replication slot\n     *\n     * @param slotName the name of the slot\n     * @param pluginName the name of the plugin used for the desired slot\n     * @return the {@link SlotState} or null, if no slot state is found\n     * @throws SQLException\n     */\n    public SlotState getReplicationSlotState(String slotName, String pluginName)\n            throws SQLException {\n        ServerInfo.ReplicationSlot slot;","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-opengauss/src/main/java/io/debezium/connector/postgresql/connection/PostgresConnection.java#L217-L253","documentation":"The OpenGauss/PostgreSQL connector (vendored Debezium PostgresConnection.readReplicaIdentityInfo) queries pg_class.relreplident for the target table; if the query returns no row, the connector logs this WARN and falls back to ServerInfo.ReplicaIdentity.parseFromDB(\"\") — i.e. it proceeds with a default/parsed-empty replica identity instead of the real one. This can later cause incorrect before-image data on UPDATE/DELETE if the assumed identity is wrong.","triggerScenarios":"replicaIdentity() calls readReplicaIdentityInfo which runs a parameterized query on pg_class with schema name and table name; rs.next() is false — the table row is not visible to the querying user or the tableId (schema.table) does not exist at that moment (renamed/dropped between metadata fetch and this query, or case-sensitivity/quoting mismatch).","commonSituations":"CDC user lacking SELECT privileges on the system catalog row for the schema/table; table created/renamed after the initial metadata snapshot; case-sensitive identifiers (mixed-case table names) mishandled; OpenGauss vs PostgreSQL catalog differences in vendored code.","solutions":["Verify the table exists: SELECT relreplident FROM pg_class c JOIN pg_namespace n ON c.relnamespace=n.oid WHERE n.nspname='<schema>' AND c.relname='<table>';","GRANT SELECT on the table (and schema usage) to the CDC user so catalog lookups succeed.","Check identifier case/quoting in the connector's table list — mixed-case names often need exact case in config.","Set the replica identity explicitly: ALTER TABLE <t> REPLICA IDENTITY FULL, then restart the task so metadata is re-read."],"exampleFix":"// before: table invisible to CDC user\nCREATE USER st WITH PASSWORD '***';\n// after\nCREATE USER st WITH PASSWORD '***';\nGRANT USAGE ON SCHEMA public TO st;\nGRANT SELECT ON public.mytable TO st;\nALTER TABLE public.mytable REPLICA IDENTITY FULL;","handlingStrategy":"validation","validationCode":"SELECT c.relreplident FROM pg_class c JOIN pg_namespace n ON c.relnamespace=n.oid\nWHERE n.nspname='<schema>' AND c.relname='<table>'; -- must return exactly one row","typeGuard":null,"tryCatchPattern":"ResultSet rs = ...; if (!rs.next()) { LOGGER.warn(\"Cannot determine REPLICA IDENTITY information for table '{}'\", tableId); // fall back to default identity, or fail fast if before-images are required }","preventionTips":["Grant the CDC user USAGE on the schema and SELECT on catalog-visible table rows.","Set ALTER TABLE ... REPLICA IDENTITY FULL for tables needing complete before-images.","Match identifier case exactly in connector table configs (quote mixed-case names).","Re-read table metadata after DDL (rename/drop/create) or restart the task.","Verify catalog behavior differences on OpenGauss when using the vendored Postgres connection code."],"tags":["opengauss","postgres","cdc","replica-identity","metadata"],"backgroundTag":"record-not-found","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}