通过创建触发器和函数实现PostgreSQL增量DDL同步 操作步骤 说明 若源库为本云RDS for PostgreSQL,可以使用root用户创建相关对象,如果执行时报“Must be superuser to create an event trigger”错误,可以通过工单申请处理。本云RDS for PostgreSQL的root用户权限请参见RDS用户指南。 步骤 1 使用拥有创建事件触发器权限的用户连接要同步的数据库。 步骤 2 执行如下语句,创建存储DDL信息的表。 DROP TABLE IF EXISTS public.hwdrsddlinfo; DROP SEQUENCE IF EXISTS public.hwdrsddlinfoidseq; CREATE TABLE public.hwdrsddlinfo( id bigserial primary key, ddl text, username varchar(64) default currentuser, txid varchar(16) default txidcurrent()::varchar(16), tag varchar(64), database varchar(64) default currentdatabase(), schema varchar(64) default currentschema, clientaddress varchar(64) default inetclientaddr(), clientport integer default inetclientport(), eventtime timestamp default currenttimestamp ); 步骤 3 执行如下语句,创建函数。 CREATE OR REPLACE FUNCTION public.hwdrsddlfunction() RETURNS eventtrigger LANGUAGE plpgsql SECURITY INVOKER AS BODYBODY declare ddl text; declare realnum int; declare maxnum int : 50000; begin if (tgtag in ('CREATE TABLE','ALTER TABLE','DROP TABLE','CREATE SCHEMA','CREATE SEQUENCE','ALTER SEQUENCE','DROP SEQUENCE','CREATE VIEW','ALTER VIEW','DROP VIEW','CREATE INDEX','ALTER INDEX','DROP INDEX')) then select currentquery() into ddl; insert into public.hwdrsddlinfo(ddl, username, txid, tag, database, schema, clientaddress, clientport, eventtime) values (ddl, currentuser, cast(txidcurrent() as varchar(16)), tgtag, currentdatabase(), currentschema, inetclientaddr(), inetclientport(), currenttimestamp); select count(id) into realnum from public.hwdrsddlinfo; if realnum > maxnum then if currentsetting('serverversionnum')::int pgbackendpid() and locktype'relation' and relationtoregclass('public.hwdrsddlinfopkey')::oid and mode'RowExclusiveLock'); else delete from public.hwdrsddlinfo where id 'in progress'); end if; end if; end if; end; BODYBODY; 步骤 4 执行以下语句,为步骤2和步骤3中创建的对象赋予必要权限。 GRANT USAGE ON SCHEMA public TO public; GRANT SELECT,INSERT,DELETE ON TABLE public.hwdrsddlinfo TO public; GRANT SELECT,USAGE ON SEQUENCE public.hwdrsddlinfoidseq TO public; GRANT EXECUTE ON FUNCTION public.hwdrsddlfunction() TO public; 步骤 5 执行以下语句,创建DDL事件触发器。 CREATE EVENT TRIGGER hwdrsddlevent ON ddlcommandend EXECUTE PROCEDURE public.hwdrsddlfunction(); 步骤 6 执行以下语句,将创建的事件触发器设置为enable。 ALTER EVENT TRIGGER hwdrsddlevent ENABLE ALWAYS; 步骤 7 返回数据复制服务控制台,创建PostgreSQL>RDS for PostgreSQL的同步任务。 步骤 8 待同步任务结束后,请执行下语句删除创建的表、函数、触发器。 DROP EVENT trigger hwdrsddlevent; DROP FUNCTION public.hwdrsddlfunction(); DROP TABLE public.hwdrsddlinfo;