Skip to content

Commit eb7ec13

Browse files
committed
Merge branch 'PGPROEE9_6_MULTIMASTER' into PGPROEE9_6
2 parents d2db994 + 6f61722 commit eb7ec13

File tree

150 files changed

+20694
-249
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+20694
-249
lines changed

.dockerignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
*/*/.git
2+
.git
3+
.vscode
4+
*.yml
5+
*/*/*.yml
6+
Dockerfile
7+

Dockerfile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
FROM alpine:3.4
2+
3+
RUN apk add --update gcc libc-dev bison flex readline-dev zlib-dev perl make diffutils gdb iproute2 musl-dbg
4+
5+
# there is already accidental postgres user in alpine
6+
# RUN addgroup pg && adduser -h /pg -D -G pg pg
7+
RUN mkdir /pg && chown postgres:postgres pg
8+
9+
ENV LANG en_US.utf8
10+
ENV CFLAGS -O0
11+
ENV PATH /pg/install/bin:$PATH
12+
13+
COPY ./ /pg/src
14+
RUN chown -R postgres:postgres /pg
15+
16+
RUN cd /pg/src && \
17+
./configure --enable-cassert --enable-debug --prefix=/pg/install && \
18+
make -j 4 install
19+

contrib/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ SUBDIRS = \
2727
isn \
2828
lo \
2929
ltree \
30+
mmts \
3031
oid2name \
3132
pageinspect \
3233
passwordcheck \

contrib/mmts/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
tests/node*
2+
tmp_check

contrib/mmts/Cluster.pm

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
package Cluster;
2+
3+
use strict;
4+
use warnings;
5+
6+
use PostgresNode;
7+
use TestLib;
8+
use Test::More;
9+
use Cwd;
10+
11+
use Socket;
12+
13+
sub check_port
14+
{
15+
my ($host, $port) = @_;
16+
my $iaddr = inet_aton($host);
17+
my $paddr = sockaddr_in($port, $iaddr);
18+
my $proto = getprotobyname("tcp");
19+
my $available = 0;
20+
21+
socket(SOCK, PF_INET, SOCK_STREAM, $proto)
22+
or die "socket failed: $!";
23+
24+
if (bind(SOCK, $paddr) && listen(SOCK, SOMAXCONN))
25+
{
26+
$available = 1;
27+
}
28+
29+
close(SOCK);
30+
diag("checking for port $port = $available\n");
31+
return $available;
32+
}
33+
34+
my %allocated_ports = ();
35+
sub allocate_ports
36+
{
37+
my @allocated_now = ();
38+
my ($host, $ports_to_alloc) = @_;
39+
40+
while ($ports_to_alloc > 0)
41+
{
42+
my $port = int(rand() * 16384) + 49152;
43+
next if $allocated_ports{$port};
44+
if (check_port($host, $port))
45+
{
46+
$allocated_ports{$port} = 1;
47+
push(@allocated_now, $port);
48+
$ports_to_alloc--;
49+
}
50+
}
51+
52+
return @allocated_now;
53+
}
54+
55+
sub new
56+
{
57+
my ($class, $nodenum) = @_;
58+
59+
my $nodes = [];
60+
61+
foreach my $i (1..$nodenum)
62+
{
63+
my $host = "127.0.0.1";
64+
my ($pgport, $arbiter_port) = allocate_ports($host, 2);
65+
my $node = new PostgresNode("node$i", $host, $pgport);
66+
$node->{id} = $i;
67+
$node->{arbiter_port} = $arbiter_port;
68+
push(@$nodes, $node);
69+
}
70+
71+
my $self = {
72+
nodenum => $nodenum,
73+
nodes => $nodes,
74+
};
75+
76+
bless $self, $class;
77+
return $self;
78+
}
79+
80+
sub init
81+
{
82+
my ($self) = @_;
83+
my $nodes = $self->{nodes};
84+
85+
foreach my $node (@$nodes)
86+
{
87+
$node->init(hba_permit_replication => 0);
88+
}
89+
}
90+
91+
sub configure
92+
{
93+
my ($self) = @_;
94+
my $nodes = $self->{nodes};
95+
my $nnodes = scalar @{ $nodes };
96+
97+
my $connstr = join(', ', map { "${ \$_->connstr('postgres') } arbiter_port=${ \$_->{arbiter_port} }" } @$nodes);
98+
99+
foreach my $node (@$nodes)
100+
{
101+
my $id = $node->{id};
102+
my $host = $node->host;
103+
my $pgport = $node->port;
104+
my $arbiter_port = $node->{arbiter_port};
105+
106+
$node->append_conf("postgresql.conf", qq(
107+
log_statement = none
108+
listen_addresses = '$host'
109+
unix_socket_directories = ''
110+
port = $pgport
111+
max_prepared_transactions = 10
112+
max_connections = 10
113+
max_worker_processes = 100
114+
wal_level = logical
115+
max_wal_senders = 5
116+
wal_sender_timeout = 0
117+
default_transaction_isolation = 'repeatable read'
118+
max_replication_slots = 5
119+
shared_preload_libraries = 'multimaster'
120+
shared_buffers = 16MB
121+
122+
multimaster.arbiter_port = $arbiter_port
123+
multimaster.workers = 1
124+
multimaster.node_id = $id
125+
multimaster.conn_strings = '$connstr'
126+
multimaster.heartbeat_recv_timeout = 2050
127+
multimaster.heartbeat_send_timeout = 250
128+
multimaster.max_nodes = $nnodes
129+
multimaster.ignore_tables_without_pk = true
130+
multimaster.queue_size = 4194304
131+
multimaster.min_2pc_timeout = 150000
132+
log_line_prefix = '%t: '
133+
));
134+
135+
$node->append_conf("pg_hba.conf", qq(
136+
local replication all trust
137+
host replication all 127.0.0.1/32 trust
138+
host replication all ::1/128 trust
139+
));
140+
}
141+
}
142+
143+
sub start
144+
{
145+
my ($self) = @_;
146+
my $nodes = $self->{nodes};
147+
148+
foreach my $node (@$nodes)
149+
{
150+
$node->start();
151+
}
152+
}
153+
154+
sub stopnode
155+
{
156+
my ($node, $mode) = @_;
157+
return 1 unless defined $node->{_pid};
158+
$mode = 'fast' unless defined $mode;
159+
my $name = $node->name;
160+
diag("stopping $name ${mode}ly");
161+
162+
if ($mode eq 'kill') {
163+
killtree($node->{_pid});
164+
return 1;
165+
}
166+
167+
my $pgdata = $node->data_dir;
168+
my $ret = TestLib::system_log('pg_ctl', '-D', $pgdata, '-m', 'fast', 'stop');
169+
my $pidfile = $node->data_dir . "/postmaster.pid";
170+
diag("unlink $pidfile");
171+
unlink $pidfile;
172+
$node->{_pid} = undef;
173+
$node->_update_pid;
174+
175+
if ($ret != 0) {
176+
diag("$name failed to stop ${mode}ly");
177+
return 0;
178+
}
179+
180+
return 1;
181+
}
182+
183+
sub stopid
184+
{
185+
my ($self, $idx, $mode) = @_;
186+
return stopnode($self->{nodes}->[$idx]);
187+
}
188+
189+
sub dumplogs
190+
{
191+
my ($self) = @_;
192+
my $nodes = $self->{nodes};
193+
194+
diag("Dumping logs:");
195+
foreach my $node (@$nodes) {
196+
diag("##################################################################");
197+
diag($node->{_logfile});
198+
diag("##################################################################");
199+
my $filename = $node->{_logfile};
200+
open my $fh, '<', $filename or die "error opening $filename: $!";
201+
my $data = do { local $/; <$fh> };
202+
diag($data);
203+
diag("##################################################################\n\n");
204+
}
205+
}
206+
207+
sub stop
208+
{
209+
my ($self, $mode) = @_;
210+
my $nodes = $self->{nodes};
211+
$mode = 'fast' unless defined $mode;
212+
213+
my $ok = 1;
214+
diag("stopping cluster ${mode}ly");
215+
216+
foreach my $node (@$nodes) {
217+
if (!stopnode($node, $mode)) {
218+
$ok = 0;
219+
# if (!stopnode($node, 'kill')) {
220+
# my $name = $node->name;
221+
# BAIL_OUT("failed to kill $name");
222+
# }
223+
}
224+
}
225+
sleep(2);
226+
227+
$self->dumplogs();
228+
229+
return $ok;
230+
}
231+
232+
sub bail_out_with_logs
233+
{
234+
my ($self, $msg) = @_;
235+
$self->dumplogs();
236+
BAIL_OUT($msg);
237+
}
238+
239+
sub teardown
240+
{
241+
my ($self) = @_;
242+
my $nodes = $self->{nodes};
243+
244+
foreach my $node (@$nodes)
245+
{
246+
$node->teardown();
247+
}
248+
}
249+
250+
sub psql
251+
{
252+
my ($self, $index, @args) = @_;
253+
my $node = $self->{nodes}->[$index];
254+
return $node->psql(@args);
255+
}
256+
257+
sub poll
258+
{
259+
my ($self, $poller, $dbname, $pollee, $tries, $delay) = @_;
260+
my $node = $self->{nodes}->[$poller];
261+
for (my $i = 0; $i < $tries; $i++) {
262+
my $psql_out;
263+
my $pollee_plus_1 = $pollee + 1;
264+
$self->psql($poller, $dbname, "select mtm.poll_node($pollee_plus_1, true);", stdout => \$psql_out);
265+
if ($psql_out eq "t") {
266+
return 1;
267+
}
268+
my $tries_left = $tries - $i - 1;
269+
diag("$poller poll for $pollee failed [$tries_left tries left]");
270+
sleep($delay);
271+
}
272+
return 0;
273+
}
274+
275+
1;

contrib/mmts/Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM pgproent
2+
3+
RUN mkdir /pg/mmts
4+
COPY ./ /pg/mmts/
5+
6+
RUN export USE_PGXS=1 && \
7+
cd /pg/mmts && make clean && make install
8+
9+
# pg_regress client assumes such dir exists on server
10+
RUN cp /pg/src/src/test/regress/*.so /pg/install/lib/postgresql/
11+
USER postgres
12+
RUN mkdir /pg/src/src/test/regress/results
13+
ENV PGDATA /pg/data
14+
ENTRYPOINT ["/pg/mmts/tests2/docker-entrypoint.sh"]
15+
16+
EXPOSE 5432
17+
CMD ["postgres"]

contrib/mmts/Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
MODULE_big = multimaster
2+
OBJS = multimaster.o arbiter.o bytebuf.o bgwpool.o pglogical_output.o pglogical_proto.o pglogical_receiver.o pglogical_apply.o pglogical_hooks.o pglogical_config.o pglogical_relid_map.o ddd.o bkb.o spill.o
3+
4+
EXTENSION = multimaster
5+
DATA = multimaster--1.0.sql
6+
7+
.PHONY: all
8+
9+
EXTRA_INSTALL=contrib/mmts
10+
11+
all: multimaster.so
12+
13+
PG_CPPFLAGS = -I$(libpq_srcdir)
14+
SHLIB_LINK = $(libpq)
15+
16+
ifdef USE_PGXS
17+
PG_CONFIG = pg_config
18+
PGXS := $(shell $(PG_CONFIG) --pgxs)
19+
include $(PGXS)
20+
else
21+
subdir = contrib/multimaster
22+
top_builddir = ../..
23+
include $(top_builddir)/src/Makefile.global
24+
include $(top_srcdir)/contrib/contrib-global.mk
25+
endif
26+
27+
check: temp-install
28+
$(prove_check)
29+

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy