Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 88ae538

Browse files
committed
add_node works.
1 parent f85fa95 commit 88ae538

File tree

6 files changed

+251
-98
lines changed

6 files changed

+251
-98
lines changed

bin/common.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ master_port=5432
1313
# declare -a worker_ports=()
1414
declare -a worker_datadirs=("${HOME}/postgres/data2")
1515
declare -a worker_ports=("5433")
16+
# declare -a worker_datadirs=("${HOME}/postgres/data2" "${HOME}/postgres/data3")
17+
# declare -a worker_ports=("5433" "5434")
1618

1719
#------------------------------------------------------------
1820
PATH="$PATH:${pgpath}bin/"
@@ -37,6 +39,7 @@ function stop_nodes()
3739

3840
function restart_nodes()
3941
{
42+
echo "Restarting nodes"
4043
for ((i=0; i<${#worker_datadirs[@]}; ++i)); do
4144
datadir="${worker_datadirs[i]}"
4245
port="${worker_ports[i]}"

bin/shardman_init.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ for datadir in $master_datadir "${worker_datadirs[@]}"; do
1515
done
1616

1717
cat postgresql.conf.master.template >> ${master_datadir}/postgresql.conf
18-
for worker_datadir in $worker_datadirs; do
18+
for worker_datadir in "${worker_datadirs[@]}"; do
1919
cat postgresql.conf.worker.template >> ${worker_datadir}/postgresql.conf
2020
done
2121

pg_shardman--0.0.1.sql

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,33 @@
11
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
22
\echo Use "CREATE EXTENSION pg_shardman" to load this file. \quit
33

4+
-- Functions here use some gucs defined in .so, so we have to ensure that the
5+
-- library is actually loaded.
6+
DO $$
7+
BEGIN
8+
-- Yes, malicious user might have another extension containing 'pg_shardman'...
9+
-- Probably better just call no-op func from the library
10+
IF strpos(current_setting('shared_preload_libraries'), 'pg_shardman') = 0 THEN
11+
RAISE EXCEPTION 'pg_shardman must be loaded via shared_preload_libraries. Refusing to proceed.';
12+
END IF;
13+
END
14+
$$;
15+
16+
-- list of nodes present in the cluster
17+
CREATE TABLE nodes (
18+
id serial PRIMARY KEY,
19+
connstring text,
20+
active bool NOT NULL -- if false, we haven't yet finished adding it
21+
);
22+
23+
-- Currently it is used just to store node id, in general we can keep any local
24+
-- node metadata here. If is ever used extensively, probably hstore suits better.
25+
CREATE TABLE local_meta (
26+
k text NOT NULL, -- key
27+
v text -- value
28+
);
29+
INSERT INTO @extschema@.local_meta VALUES ('node_id', NULL);
30+
431
-- available commands
532
CREATE TYPE cmd AS ENUM ('add_node', 'remove_node');
633
-- command status
@@ -9,7 +36,10 @@ CREATE TYPE cmd_status AS ENUM ('waiting', 'canceled', 'failed', 'in progress',
936
CREATE TABLE cmd_log (
1037
id bigserial PRIMARY KEY,
1138
cmd_type cmd NOT NULL,
12-
status cmd_status DEFAULT 'waiting' NOT NULL
39+
status cmd_status DEFAULT 'waiting' NOT NULL,
40+
-- only for add_node cmd -- generated id for newly added node. Cleaner
41+
-- to keep that is separate table...
42+
node_id int REFERENCES nodes(id)
1343
);
1444

1545
-- Notify shardman master bgw about new commands
@@ -34,19 +64,6 @@ CREATE TABLE cmd_opts (
3464
opt text NOT NULL
3565
);
3666

37-
-- list of nodes present in the cluster
38-
CREATE TABLE nodes (
39-
id serial PRIMARY KEY,
40-
connstring text
41-
);
42-
43-
-- Currently it is used just to store node id, in general we can keep any local
44-
-- node metadata here. If is ever used extensively, probably hstore suits better.
45-
CREATE TABLE local_meta (
46-
k text NOT NULL, -- key
47-
v text -- value
48-
);
49-
INSERT INTO @extschema@.local_meta VALUES ('node_id', NULL);
5067

5168
-- Internal functions
5269

@@ -63,13 +80,47 @@ $$ LANGUAGE plpgsql;
6380
-- These tables will be replicated to worker nodes, notifying them about changes.
6481
-- Called on worker nodes.
6582
CREATE FUNCTION create_meta_sub() RETURNS void AS $$
83+
DECLARE
84+
master_connstring text;
6685
BEGIN
67-
IF NOT EXISTS (SELECT * FROM pg_publication WHERE pubname = 'shardman_meta_pub') THEN
68-
CREATE PUBLICATION shardman_meta_pub FOR TABLE shardman.nodes;
69-
END IF;
86+
SELECT pg_settings.setting into master_connstring from pg_settings
87+
WHERE NAME = 'shardman.master_connstring';
88+
-- Note that 'CONNECTION $1...' USING master_connstring won't work here
89+
EXECUTE format('CREATE SUBSCRIPTION shardman_meta_sub CONNECTION %L PUBLICATION shardman_meta_pub', master_connstring);
7090
END;
7191
$$ LANGUAGE plpgsql;
7292

93+
-- If for cmd cmd_id we haven't yet inserted new node, do that; mark it as passive
94+
-- for now, we still need to setup lr and set its id on the node itself
95+
-- Return generated or existing node id
96+
CREATE FUNCTION insert_node(connstring text, cmd_id bigint) RETURNS int AS $$
97+
DECLARE
98+
n_id int;
99+
BEGIN
100+
SELECT node_id FROM @extschema@.cmd_log INTO n_id WHERE id = cmd_id;
101+
IF n_id IS NULL THEN
102+
INSERT INTO @extschema@.nodes VALUES (DEFAULT, quote_literal(connstring), false)
103+
RETURNING id INTO n_id;
104+
UPDATE @extschema@.cmd_log SET node_id = n_id WHERE id = cmd_id;
105+
END IF;
106+
RETURN n_id;
107+
END
108+
$$ LANGUAGE plpgsql;
109+
110+
-- Create logical pgoutput replication slot, if not exists
111+
CREATE FUNCTION create_repslot(slot_name text) RETURNS void AS $$
112+
DECLARE
113+
slot_exists bool;
114+
BEGIN
115+
EXECUTE format('SELECT EXISTS (SELECT * FROM pg_replication_slots
116+
WHERE slot_name=%L)', slot_name) INTO slot_exists;
117+
IF NOT slot_exists THEN
118+
EXECUTE format('SELECT * FROM pg_create_logical_replication_slot(%L, %L)',
119+
slot_name, 'pgoutput');
120+
END IF;
121+
END
122+
$$ LANGUAGE plpgsql;
123+
73124
-- Remove all our logical replication stuff in case of drop extension.
74125
-- Dropping extension cleanup is not that easy:
75126
-- - pg offers event triggers sql_drop, dd_command_end and ddl_command_start
@@ -84,10 +135,17 @@ $$ LANGUAGE plpgsql;
84135
-- it is our extension is deleting, it calls plpgsql cleanup func
85136
CREATE OR REPLACE FUNCTION pg_shardman_cleanup() RETURNS void AS $$
86137
DECLARE
87-
pub RECORD;
138+
pub record;
139+
sub record;
88140
BEGIN
89141
FOR pub IN SELECT pubname FROM pg_publication WHERE pubname LIKE 'shardman_%' LOOP
90-
EXECUTE 'DROP PUBLICATION ' || quote_ident(pub.pubname);
142+
EXECUTE format('DROP PUBLICATION %I', pub.pubname);
143+
END LOOP;
144+
FOR sub IN SELECT subname FROM pg_subscription WHERE subname LIKE 'shardman_%' LOOP
145+
-- we are managing rep slots manually, so we need to detach it beforehand
146+
EXECUTE format('ALTER SUBSCRIPTION %I DISABLE', sub.subname);
147+
EXECUTE format('ALTER SUBSCRIPTION %I SET (slot_name = NONE)', sub.subname);
148+
EXECUTE format('DROP SUBSCRIPTION %I', sub.subname);
91149
END LOOP;
92150
END;
93151
$$ LANGUAGE plpgsql;
@@ -112,6 +170,7 @@ CREATE FUNCTION set_node_id(node_id int) RETURNS void AS $$
112170
UPDATE @extschema@.local_meta SET v = node_id WHERE k = 'node_id';
113171
$$ LANGUAGE sql;
114172

173+
115174
-- Interface functions
116175

117176
-- TODO: during the initial connection, ensure that nodes id (if any) is not

postgresql.conf.worker.template

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
shared_preload_libraries='pg_pathman, pg_shardman'
1+
shared_preload_libraries = 'pg_pathman, pg_shardman'
22

33
log_min_messages = INFO
44
client_min_messages = LOG
55

66
wal_level = logical
7+
8+
# worker-specific part
9+
shardman.master_connsting = 'port=5432'

src/include/pg_shardman.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33

44
#define shmn_elog(level,fmt,...) elog(level, "[SHARDMAN] " fmt, ## __VA_ARGS__)
55

6+
#define SPI_PROLOG do { \
7+
StartTransactionCommand(); \
8+
SPI_connect(); \
9+
PushActiveSnapshot(GetTransactionSnapshot()); \
10+
} while (0);
11+
12+
#define SPI_EPILOG do { \
13+
PopActiveSnapshot(); \
14+
SPI_finish(); \
15+
CommitTransactionCommand(); \
16+
} while (0);
17+
618
extern void _PG_init(void);
719
extern void shardmaster_main(Datum main_arg);
820

0 commit comments

Comments
 (0)