mirror of https://github.com/citusdata/citus.git
99 lines
4.5 KiB
PL/PgSQL
99 lines
4.5 KiB
PL/PgSQL
/* citus--7.0-4--7.0-5.sql */
|
|
|
|
SET search_path = 'pg_catalog';
|
|
|
|
CREATE TYPE pg_catalog.noderole AS ENUM (
|
|
'primary', -- node is available and accepting writes
|
|
'secondary', -- node is available but only accepts reads
|
|
'unavailable' -- node is in recovery or otherwise not usable
|
|
-- adding new values to a type inside of a transaction (such as during an ALTER EXTENSION
|
|
-- citus UPDATE) isn't allowed in PG 9.6, and only allowed in PG10 if you don't use the
|
|
-- new values inside of the same transaction. You might need to replace this type with a
|
|
-- new one and then change the column type in pg_dist_node. There's a list of
|
|
-- alternatives here:
|
|
-- https://stackoverflow.com/questions/1771543/postgresql-updating-an-enum-type/41696273
|
|
);
|
|
|
|
ALTER TABLE pg_dist_node ADD COLUMN noderole noderole NOT NULL DEFAULT 'primary';
|
|
|
|
-- we're now allowed to have more than one node per group
|
|
ALTER TABLE pg_catalog.pg_dist_node DROP CONSTRAINT pg_dist_node_groupid_unique;
|
|
|
|
-- so make sure pg_dist_shard_placement only returns writable placements
|
|
CREATE OR REPLACE VIEW pg_catalog.pg_dist_shard_placement AS
|
|
SELECT shardid, shardstate, shardlength, nodename, nodeport, placementid
|
|
FROM pg_dist_placement placement INNER JOIN pg_dist_node node ON (
|
|
placement.groupid = node.groupid AND node.noderole = 'primary'
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION citus.pg_dist_node_trigger_func()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
/* AddNodeMetadata also takes out a ShareRowExclusiveLock */
|
|
LOCK TABLE pg_dist_node IN SHARE ROW EXCLUSIVE MODE;
|
|
IF (TG_OP = 'INSERT') THEN
|
|
IF NEW.noderole = 'primary'
|
|
AND EXISTS (SELECT 1 FROM pg_dist_node WHERE groupid = NEW.groupid AND
|
|
noderole = 'primary' AND
|
|
nodeid <> NEW.nodeid) THEN
|
|
RAISE EXCEPTION 'there cannot be two primary nodes in a group';
|
|
END IF;
|
|
RETURN NEW;
|
|
ELSIF (TG_OP = 'UPDATE') THEN
|
|
IF NEW.noderole = 'primary'
|
|
AND EXISTS (SELECT 1 FROM pg_dist_node WHERE groupid = NEW.groupid AND
|
|
noderole = 'primary' AND
|
|
nodeid <> NEW.nodeid) THEN
|
|
RAISE EXCEPTION 'there cannot be two primary nodes in a group';
|
|
END IF;
|
|
RETURN NEW;
|
|
END IF;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER pg_dist_node_trigger
|
|
BEFORE INSERT OR UPDATE ON pg_dist_node
|
|
FOR EACH ROW EXECUTE PROCEDURE citus.pg_dist_node_trigger_func();
|
|
|
|
DROP FUNCTION master_add_node(text, integer);
|
|
CREATE FUNCTION master_add_node(nodename text,
|
|
nodeport integer,
|
|
groupid integer default 0,
|
|
noderole noderole default 'primary',
|
|
OUT nodeid integer,
|
|
OUT groupid integer,
|
|
OUT nodename text,
|
|
OUT nodeport integer,
|
|
OUT noderack text,
|
|
OUT hasmetadata boolean,
|
|
OUT isactive bool,
|
|
OUT noderole noderole)
|
|
RETURNS record
|
|
LANGUAGE C STRICT
|
|
AS 'MODULE_PATHNAME', $$master_add_node$$;
|
|
COMMENT ON FUNCTION master_add_node(nodename text, nodeport integer,
|
|
groupid integer, noderole noderole)
|
|
IS 'add node to the cluster';
|
|
|
|
DROP FUNCTION master_add_inactive_node(text, integer);
|
|
CREATE FUNCTION master_add_inactive_node(nodename text,
|
|
nodeport integer,
|
|
groupid integer default 0,
|
|
noderole noderole default 'primary',
|
|
OUT nodeid integer,
|
|
OUT groupid integer,
|
|
OUT nodename text,
|
|
OUT nodeport integer,
|
|
OUT noderack text,
|
|
OUT hasmetadata boolean,
|
|
OUT isactive bool,
|
|
OUT noderole noderole)
|
|
RETURNS record
|
|
LANGUAGE C STRICT
|
|
AS 'MODULE_PATHNAME',$$master_add_inactive_node$$;
|
|
COMMENT ON FUNCTION master_add_inactive_node(nodename text,nodeport integer,
|
|
groupid integer, noderole noderole)
|
|
IS 'prepare node by adding it to pg_dist_node';
|
|
|
|
RESET search_path;
|