Gel Configuration Issues for Logical Replication
Author: chuckyQCreated May 1, 2026Updated May 1, 2026
- Gel Version: 6.11+e4f7b57
- Gel CLI Version: Gel CLI 7.10.2+e00c46c
- OS Version: Ubuntu 24.04.3 LTS
Steps to Reproduce:
- Initialize a Gel instance on RDS (I used the CloudFormation yaml file)
- Use
psqlto log into the cluster - Run the following query to find the tables with missing primary keys:
SELECT table_schema, table_name
FROM information_schema.tables tbl
WHERE table_type = 'BASE TABLE'
AND table_schema NOT IN ('pg_catalog', 'information_schema', 'pglogical')
AND NOT EXISTS (SELECT 1
FROM information_schema.key_column_usage kcu
WHERE kcu.table_name = tbl.table_name
AND kcu.table_schema = tbl.table_schema);To fix, I inserted my own primary keys as an auto-incrementing integer.
- Certain views and functions rely on data types of the form reg* that cause the blue/green deployment to fail. To fix this, I dropped these from databases in the blue cluster and recreated them on the green cluster. On my cluster, the following objects that caused issues were:
- "edgedbsql_v6_2f20b3fed0".pg_type view
- "edgedbsql_v6_2f20b3fed0"._pg_truetypmod function
- "edgedbsql_v6_2f20b3fed0"._pg_truetypid function
- "edgedbsql_v6_2f20b3fed0".pg_type_ materialized view
I used the following query to find the problem columns (this was provided in the RDS logs):
WITH RECURSIVE oids AS (
SELECT oid FROM pg_catalog.pg_type t WHERE t.typnamespace =
(SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = 'pg_catalog') AND
t.typname IN ('regcollation', 'regconfig', 'regdictionary', 'regnamespace', 'regoper', 'regoperator', 'regproc', 'regprocedure')
UNION ALL SELECT * FROM (WITH x AS (SELECT oid FROM oids) SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typbasetype = x.oid AND typtype = 'd' UNION ALL
SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typelem = x.oid AND typtype = 'b' UNION ALL
SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, x WHERE
t.typtype = 'c' AND t.oid = c.reltype AND c.oid = a.attrelid AND NOT a.attisdropped AND a.atttypid = x.oid UNION ALL
SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_range r, x
WHERE t.typtype = 'r' AND
r.rngtypid = t.oid AND
r.rngsubtype = x.oid) foo)
SELECT relnamespace, relname, attname, reltype, nspname, nspowner FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n, pg_catalog.pg_attribute a
WHERE c.oid = a.attrelid AND
NOT a.attisdropped AND
a.atttypid IN (SELECT oid FROM oids) AND
c.relkind IN ('r', 'm', 'i') AND
c.relnamespace = n.oid AND
n.nspname !~ '^pg_temp_' AND
n.nspname !~ '^pg_toast_temp_' AND
n.nspname NOT IN ('pg_catalog', 'information_schema');The output from the command was the following:
nspname | relname | attname
-------------------------+----------+--------------
edgedbsql_v6_2f20b3fed0 | pg_type_ | typsubscript
edgedbsql_v6_2f20b3fed0 | pg_type_ | typinput
edgedbsql_v6_2f20b3fed0 | pg_type_ | typoutput
edgedbsql_v6_2f20b3fed0 | pg_type_ | typreceive
edgedbsql_v6_2f20b3fed0 | pg_type_ | typsend
edgedbsql_v6_2f20b3fed0 | pg_type_ | typmodin
edgedbsql_v6_2f20b3fed0 | pg_type_ | typmodout
edgedbsql_v6_2f20b3fed0 | pg_type_ | typanalyzeAfter backtracking what I needed to delete to make these columns drop, I found the objects that were causing the issue.
- DDL was not disabled and there is no clear way to disable it through Gel. To fix, I added the following function (provided by the AWS documentation) manually to each database in the underlying Postgres cluster:
CREATE OR REPLACE FUNCTION block_ddl_bg() RETURNS event_trigger
SECURITY DEFINER
AS $$
DECLARE
-- Define allowed users and roles here
allowed_users TEXT[] := ARRAY['rdsadmin', 'rdsrepladmin'];
allowed_roles TEXT[] := ARRAY['rdsrepladmin'];
BEGIN
-- Check if either the session user or current role is allowed
IF NOT (session_user = ANY(allowed_users) OR current_role = ANY(allowed_roles)) THEN
RAISE EXCEPTION 'DDL operations are blocked to prevent Blue Green Deployment replica degradation. User: %, Role: %, Status: BLOCKED',
session_user, current_role;
END IF;
END;
$$ LANGUAGE plpgsql;
CREATE EVENT TRIGGER block_ddl_trigger ON ddl_command_start
EXECUTE FUNCTION block_ddl_bg();After performing all of these configuration changes, I was able to upgrade my Postgres cluster from 16 to 17.
I know the current procedure still requires a full dump-and-restore when changing Gel versions, but this is a good start for the Postgres major version upgrade and maybe Gel can support it.
Source: geldata/gel