# Copyright (c) 2021-2025, PostgreSQL Global Development Group
# Binary mode logical replication test
use strict;
use warnings FATAL => 'all';
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More;
# Create and initialize a publisher node
my $node_publisher = PostgreSQL::Test::Cluster->new('publisher');
$node_publisher->init(allows_streaming => 'logical');
$node_publisher->start;
# Create and initialize subscriber node
my $node_subscriber = PostgreSQL::Test::Cluster->new('subscriber');
$node_subscriber->init;
$node_subscriber->start;
# Create tables on both sides of the replication
my $ddl = qq(
CREATE TABLE public.test_numerical (
a INTEGER PRIMARY KEY,
b NUMERIC,
c FLOAT,
d BIGINT
);
CREATE TABLE public.test_arrays (
a INTEGER[] PRIMARY KEY,
b NUMERIC[],
c TEXT[]
););
# Configure logical replication
$node_publisher->safe_psql('postgres', "CREATE PUBLICATION tpub FOR ALL TABLES");
# ------------------------------------------------------ # Ensure binary mode also executes COPY in binary format # ------------------------------------------------------
# Insert some content before creating a subscription
$node_publisher->safe_psql( 'postgres', qq(
INSERT INTO public.test_numerical (a, b, c, d) VALUES
(1, 1.2, 1.3, 10),
(2, 2.2, 2.3, 20);
INSERT INTO public.test_arrays (a, b, c) VALUES
('{1,2,3}', '{1.1, 1.2, 1.3}', '{"one", "two", "three"}'),
('{3,1,2}', '{1.3, 1.1, 1.2}', '{"three", "one", "two"}');
));
# Ensure the COPY command is executed in binary format on the publisher
$node_publisher->wait_for_log(
qr/LOG: ( [A-Z0-9]+:)? statement: COPY (.+)? TO STDOUT WITH \(FORMAT binary\)/
);
# Ensure nodes are in sync with each other
$node_subscriber->wait_for_subscription_sync($node_publisher, 'tsub');
my $sync_check = qq(
SELECT a, b, c, d FROM test_numerical ORDER BY a;
SELECT a, b, c FROM test_arrays ORDER BY a;
);
# Check the synced data on the subscriber
my $result = $node_subscriber->safe_psql('postgres', $sync_check);
is( $result, '1|1.2|1.3|10 2|2.2|2.3|20
{1,2,3}|{1.1,1.2,1.3}|{one,two,three}
{3,1,2}|{1.3,1.1,1.2}|{three,one,two}', 'check synced data on subscriber');
# ---------------------------------- # Ensure apply works in binary mode # ----------------------------------
# Insert some content and make sure it's replicated across
$node_publisher->safe_psql( 'postgres', qq(
INSERT INTO public.test_arrays (a, b, c) VALUES
('{2,1,3}', '{1.2, 1.1, 1.3}', '{"two", "one", "three"}'),
('{1,3,2}', '{1.1, 1.3, 1.2}', '{"one", "three", "two"}');
$result = $node_subscriber->safe_psql('postgres', "SELECT a, b, c, d FROM test_numerical ORDER BY a");
is( $result, '1|1.2|1.3|10 2|2.2|2.3|20 3|3.2|3.3|30 4|4.2|4.3|40', 'check replicated data on subscriber');
# Test updates as well
$node_publisher->safe_psql( 'postgres', qq(
UPDATE public.test_arrays SET b[1] = 42, c = NULL;
UPDATE public.test_numerical SET b = 42, c = NULL;
));
$node_publisher->wait_for_catchup('tsub');
$result = $node_subscriber->safe_psql('postgres', "SELECT a, b, c FROM test_arrays ORDER BY a");
is( $result, '{1,2,3}|{42,1.2,1.3}|
{1,3,2}|{42,1.3,1.2}|
{2,1,3}|{42,1.1,1.3}|
{3,1,2}|{42,1.1,1.2}|', 'check updated replicated data on subscriber');
$result = $node_subscriber->safe_psql('postgres', "SELECT a, b, c, d FROM test_numerical ORDER BY a");
is( $result, '1|42||10 2|42||20 3|42||30 4|42||40', 'check updated replicated data on subscriber');
# ------------------------------------------------------------------------------ # Use ALTER SUBSCRIPTION to change to text format and then back to binary format # ------------------------------------------------------------------------------
# Test to reset back to text formatting, and then to binary again
$node_subscriber->safe_psql('postgres', "ALTER SUBSCRIPTION tsub SET (binary = false);");
$result = $node_subscriber->safe_psql('postgres', "SELECT a, b, c, d FROM test_numerical ORDER BY a");
is( $result, '1|42||10 2|42||20 3|42||30 4|42||40 5|5.2|5.3|50', 'check replicated data on subscriber');
$node_subscriber->safe_psql('postgres', "ALTER SUBSCRIPTION tsub SET (binary = true);");
$node_publisher->safe_psql( 'postgres', qq(
INSERT INTO public.test_arrays (a, b, c) VALUES
('{2,3,1}', '{1.2, 1.3, 1.1}', '{"two", "three", "one"}');
));
$node_publisher->wait_for_catchup('tsub');
$result = $node_subscriber->safe_psql('postgres', "SELECT a, b, c FROM test_arrays ORDER BY a");
is( $result, '{1,2,3}|{42,1.2,1.3}|
{1,3,2}|{42,1.3,1.2}|
{2,1,3}|{42,1.1,1.3}|
{2,3,1}|{1.2,1.3,1.1}|{two,three,one}
{3,1,2}|{42,1.1,1.2}|', 'check replicated data on subscriber');
# --------------------------------------------------------------- # Test binary replication without and with send/receive functions # ---------------------------------------------------------------
# Create a custom type without send/rcv functions
$ddl = qq(
CREATE TYPE myvarchar;
CREATE FUNCTION myvarcharin(cstring, oid, integer) RETURNS myvarchar
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharin';
CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharout';
CREATE TYPE myvarchar (
input = myvarcharin,
output = myvarcharout);
CREATE TABLE public.test_myvarchar (
a myvarchar
););
# Insert some initial data
$node_publisher->safe_psql( 'postgres', qq(
INSERT INTO public.test_myvarchar (a) VALUES
('a');
));
# Check the subscriber log from now on.
my $offset = -s $node_subscriber->logfile;
# Refresh the publication to trigger the tablesync
$node_subscriber->safe_psql('postgres', "ALTER SUBSCRIPTION tsub REFRESH PUBLICATION");
# It should fail
$node_subscriber->wait_for_log(
qr/ERROR: ( [A-Z0-9]+:)? no binary input function available for type/,
$offset);
# Create and set send/rcv functions for the custom type
$ddl = qq(
CREATE FUNCTION myvarcharsend(myvarchar) RETURNS bytea
LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharsend';
CREATE FUNCTION myvarcharrecv(internal, oid, integer) RETURNS myvarchar
LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharrecv';
ALTER TYPE myvarchar SET (
send = myvarcharsend,
receive = myvarcharrecv
););
# Test syncing tables with mismatching column types
$node_publisher->safe_psql( 'postgres', qq(
CREATE TABLE public.test_mismatching_types (
a bigint PRIMARY KEY
);
INSERT INTO public.test_mismatching_types (a)
VALUES (1), (2);
));
# Check the subscriber log from now on.
$offset = -s $node_subscriber->logfile;
$node_subscriber->safe_psql( 'postgres', qq(
CREATE TABLE public.test_mismatching_types (
a int PRIMARY KEY
);
ALTER SUBSCRIPTION tsub REFRESH PUBLICATION;
));
# Cannot sync due to type mismatch
$node_subscriber->wait_for_log(
qr/ERROR: ( [A-Z0-9]+:)? incorrect binary data format/, $offset);
# Check the publisher log from now on.
$offset = -s $node_publisher->logfile;
# Setting binary to false should allow syncing
$node_subscriber->safe_psql( 'postgres', qq(
ALTER SUBSCRIPTION tsub SET (binary = false);));
# Ensure the COPY command is executed in text format on the publisher
$node_publisher->wait_for_log(
qr/LOG: ( [A-Z0-9]+:)? statement: COPY (.+)? TO STDOUT\n/, $offset);
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.15Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.