Let's make a logger. CREATE TABLE ddl_history ( id BIGSERIAL PRIMARY KEY, event_time TIMESTAMPTZ DEFAULT now(), command TEXT, object_type TEXT, object_name TEXT ); Create the function: CREATE OR REPLACE FUNCTION capture_ddl() RETURNS event_trigger LANGUAGE plpgsql AS $$ BEGIN INSERT INTO ddl_history ( command, object_type, object_name ) SELECT TG_TAG, object_type, object_identity FROM pg_event_trigger_ddl_commands(); END; $$; DROP TABLE CREATE OR REPLACE FUNCTION capture_drop() RETURNS event_trigger LANGUAGE plpgsql AS $$ BEGIN INSERT INTO ddl_log ( event_time, command, object_type, object_name ) SELECT now(), TG_TAG, object_type, object_identity FROM pg_event_trigger_dropped_objects(); END; $$; Create the trigger: CREATE EVENT TRIGGER capture_ddl_trigger ON ddl_command_end EXECUTE FUNCTION capture_ddl(); Now test: CREATE TABLE products ( id INT PRIMARY KEY, name TEXT ); Check: SELECT * FROM ddl_history; docker-compose.yml for LOGICAL REPLICATION MODE services: postgres: image: postgres:15 container_name: cluster1Node1 restart: unless-stopped environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres ports: - "5444:5432" volumes: - ./postgres_data:/var/lib/postgresql/data command: - postgres - -c - wal_level=logical - -c - max_replication_slots=10 - -c - max_wal_senders=10 sudo docker compose down sudo docker compose up -d SHOW wal_level; psql -h 172.16.10.123 -p 5444 -U postgres SHOW max_replication_slots; SHOW max_wal_senders; CREATE TABLE users ( id INT PRIMARY KEY, name TEXT ); SELECT * FROM pg_create_logical_replication_slot( 'myslot', 'test_decoding' ); INSERT INTO users VALUES (1, 'Alice'); SELECT * FROM pg_logical_slot_peek_changes( 'myslot', NULL, NULL ); |===================================================| | psql -h 127.0.0.1 -p 5444 -U postgres -d postgres | |===================================================| command: - postgres - -c - wal_level=logical - -c - shared_preload_libraries=spock - -c - max_replication_slots=10 - -c - max_wal_senders=10 - -c - track_commit_timestamp=on psql -h 127.0.0.1 -p 5444 -U postgres -d postgres sudo nano postgres_data/pg_hba.conf host all all 172.19.0.0/16 scram-sha-256 host all all 172.16.10.0/24 scram-sha-256 sudo docker exec -it cluster1Node1 psql -U postgres -d postgres ALTER USER postgres WITH PASSWORD 'postgres'; sudo docker exec -it cluster1Node3 bash psql -U postgres -c "SHOW hba_file;" psql -U postgres -c "SELECT pg_reload_conf();" |==========| |LINK Nodes| |==========| SELECT spock.sub_create( subscription_name := 'node2_from_node1', provider_dsn := 'host=172.16.10.123 port=5444 dbname=postgres user=postgres password=postgres' ); |=============| |Register Node| |=============| psql -h localhost -p 5444 -U postgres -d postgres CREATE EXTENSION IF NOT EXISTS spock; SELECT extname, extversion FROM pg_extension WHERE extname = 'spock'; SELECT spock.node_create( node_name := 'node1', dsn := 'host=172.16.10.123 port=5444 dbname=postgres user=postgres password=postgres' ); SELECT * FROM spock.node; |================| | CREATE A table | |================| CREATE TABLE test_replication ( id bigint PRIMARY KEY, source_node text, message text ); SELECT spock.repset_add_table( 'default', 'test_replication' ); |===========| |Turn On DDL| |===========| CREATE TABLE customers ( id bigint PRIMARY KEY, name text ); ALTER SYSTEM SET spock.enable_ddl_replication = on; ALTER SYSTEM SET spock.include_ddl_repset = on; SELECT pg_reload_conf(); SHOW spock.enable_ddl_replication; SHOW spock.include_ddl_repset; |======================================================| | HOW TO INSERT OR PUT AUTO GEN OF ID IN EXISTING TABLE| |======================================================| ALTER TABLE test_replication ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY; HOW TO UPADE A NODE CONFIG UPDATE spock.local_node SET node_local_interface = ( SELECT if_id FROM spock.node_interface WHERE if_name = 'node2_local' AND if_nodeid = 13534 ); |========================| |WAY TO ENTER PSQL SHELL | |========================| psql "postgresql://postgres_exporter:postgres@172.16.10.178:5444/postgres" |=============================| |ENDPONT TO DETECT A DEAD LOCK| |=============================| http://172.16.10.178:9188/metrics | grep -i deadlock |========================| |FEATURES COMPLETED TODAY| |========================| | Requirement | `postgres_exporter` | What you need | | ----------------------- | ------------------: | --------------------------------- | | Connections | ✅ | postgres_exporter | | Transactions | ✅ | postgres_exporter | | Locks | ✅/⚠️ | PostgreSQL metrics/custom query | | Blocking sessions | ⚠️ | Custom PostgreSQL query | | Deadlocks | ✅ | postgres_exporter | | Long-running queries | ⚠️ | `pg_stat_activity` / custom query | | WAL | ✅ | postgres_exporter | | Database health | ✅ | postgres_exporter + Prometheus | | PostgreSQL CPU usage | ❌ | cAdvisor / process monitoring | | PostgreSQL memory usage | ❌ | cAdvisor / process monitoring | | Storage/disk usage | ❌ | node_exporter / cAdvisor | | Network usage | ❌ | node_exporter / cAdvisor | |==================| | Whats This for? | |==================| postgres=# SELECT * FROM spock.replication_set_table; set_id | set_reloid | set_att_list | set_row_filter -----------+------------------+--------------+---------------- 590430464 | ddl_test | | 590430464 | test_replication | | 590430464 | lock_test | | (3 rows) postgres=# !!!!!!!!!WHEN TESTING NEW NODES OR REFRESHING THE NODES!!!!!!!!! SET spock.enable_ddl_replication = off; |=============================| |ADD UUID IN AN EXISTING TABLE| |=============================| CREATE EXTENSION IF NOT EXISTS pgcrypto; ALTER TABLE public.test_replication ADD COLUMN uuid_id uuid DEFAULT gen_random_uuid(); Populate any existing rows that somehow got NULL: UPDATE public.test_replication SET uuid_id = gen_random_uuid() WHERE uuid_id IS NULL; Make it not null: ALTER TABLE public.test_replication ALTER COLUMN uuid_id SET NOT NULL; Now remove the old primary key: ALTER TABLE public.test_replication DROP CONSTRAINT test_replication_pkey; Make the UUID the new primary key: ALTER TABLE public.test_replication ADD PRIMARY KEY (uuid_id); |===========================| |!!!CAUTION AFTER LINKING!!!| |===========================| CHECK THIS SELECT * FROM spock.replication_set_table; SELECT slot_name, active, active_pid, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots; postgres=# SELECT * FROM spock.replication_set; |===============================| |CREATE A TABLE NOT USING SPROKE| |===============================| SELECT spock.replicate_ddl( $$ CREATE TABLE public.vm2_ddl_test ( uuid_id UUID PRIMARY KEY DEFAULT gen_random_uuid(), source_node TEXT NOT NULL, message TEXT, created_at TIMESTAMPTZ DEFAULT now() ); $$ ); WTF IS THIS!!! To check if provider is sending data postgres=# SELECT slot_name, active, active_pid, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots;