mirror of https://github.com/citusdata/citus.git
Merge pull request #941 from citusdata/bugfix/repair_deadlock
Avoid master_copy_shard_placement after modification deadlockpull/950/head
commit
cf49638287
|
@ -179,6 +179,13 @@ SendCommandListToWorkerInSingleTransaction(char *nodeName, int32 nodePort, char
|
||||||
PGresult *queryResult = NULL;
|
PGresult *queryResult = NULL;
|
||||||
ListCell *commandCell = NULL;
|
ListCell *commandCell = NULL;
|
||||||
|
|
||||||
|
if (XactModificationLevel > XACT_MODIFICATION_NONE)
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
|
||||||
|
errmsg("cannot open new connections after the first modification "
|
||||||
|
"command within a transaction")));
|
||||||
|
}
|
||||||
|
|
||||||
workerConnection = ConnectToNode(nodeName, nodePort, nodeUser);
|
workerConnection = ConnectToNode(nodeName, nodePort, nodeUser);
|
||||||
if (workerConnection == NULL)
|
if (workerConnection == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,38 @@ SELECT shardid as newshardid FROM pg_dist_shard WHERE logicalrelid = 'customer_e
|
||||||
\gset
|
\gset
|
||||||
-- now, update the second placement as unhealthy
|
-- now, update the second placement as unhealthy
|
||||||
UPDATE pg_dist_shard_placement SET shardstate = 3 WHERE shardid = :newshardid AND nodeport = :worker_2_port;
|
UPDATE pg_dist_shard_placement SET shardstate = 3 WHERE shardid = :newshardid AND nodeport = :worker_2_port;
|
||||||
|
-- cannot repair a shard after a modification (transaction still open during repair)
|
||||||
|
BEGIN;
|
||||||
|
ALTER TABLE customer_engagements ADD COLUMN value float;
|
||||||
|
NOTICE: using one-phase commit for distributed DDL commands
|
||||||
|
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||||
|
SELECT master_copy_shard_placement(:newshardid, 'localhost', :worker_1_port, 'localhost', :worker_2_port);
|
||||||
|
ERROR: cannot open new connections after the first modification command within a transaction
|
||||||
|
ROLLBACK;
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO customer_engagements VALUES (4, '04-01-2015', 'fourth event');
|
||||||
|
SELECT master_copy_shard_placement(:newshardid, 'localhost', :worker_1_port, 'localhost', :worker_2_port);
|
||||||
|
ERROR: cannot open new connections after the first modification command within a transaction
|
||||||
|
ROLLBACK;
|
||||||
|
-- modifications after reparing a shard are fine (will use new metadata)
|
||||||
|
BEGIN;
|
||||||
|
SELECT master_copy_shard_placement(:newshardid, 'localhost', :worker_1_port, 'localhost', :worker_2_port);
|
||||||
|
master_copy_shard_placement
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ALTER TABLE customer_engagements ADD COLUMN value float;
|
||||||
|
ROLLBACK;
|
||||||
|
BEGIN;
|
||||||
|
SELECT master_copy_shard_placement(:newshardid, 'localhost', :worker_1_port, 'localhost', :worker_2_port);
|
||||||
|
master_copy_shard_placement
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO customer_engagements VALUES (4, '04-01-2015', 'fourth event');
|
||||||
|
ROLLBACK;
|
||||||
-- add a fake healthy placement for the tests
|
-- add a fake healthy placement for the tests
|
||||||
INSERT INTO pg_dist_shard_placement (nodename, nodeport, shardid, shardstate, shardlength)
|
INSERT INTO pg_dist_shard_placement (nodename, nodeport, shardid, shardstate, shardlength)
|
||||||
VALUES ('dummyhost', :worker_2_port, :newshardid, 1, 0);
|
VALUES ('dummyhost', :worker_2_port, :newshardid, 1, 0);
|
||||||
|
|
|
@ -40,6 +40,28 @@ SELECT shardid as newshardid FROM pg_dist_shard WHERE logicalrelid = 'customer_e
|
||||||
-- now, update the second placement as unhealthy
|
-- now, update the second placement as unhealthy
|
||||||
UPDATE pg_dist_shard_placement SET shardstate = 3 WHERE shardid = :newshardid AND nodeport = :worker_2_port;
|
UPDATE pg_dist_shard_placement SET shardstate = 3 WHERE shardid = :newshardid AND nodeport = :worker_2_port;
|
||||||
|
|
||||||
|
-- cannot repair a shard after a modification (transaction still open during repair)
|
||||||
|
BEGIN;
|
||||||
|
ALTER TABLE customer_engagements ADD COLUMN value float;
|
||||||
|
SELECT master_copy_shard_placement(:newshardid, 'localhost', :worker_1_port, 'localhost', :worker_2_port);
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO customer_engagements VALUES (4, '04-01-2015', 'fourth event');
|
||||||
|
SELECT master_copy_shard_placement(:newshardid, 'localhost', :worker_1_port, 'localhost', :worker_2_port);
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
-- modifications after reparing a shard are fine (will use new metadata)
|
||||||
|
BEGIN;
|
||||||
|
SELECT master_copy_shard_placement(:newshardid, 'localhost', :worker_1_port, 'localhost', :worker_2_port);
|
||||||
|
ALTER TABLE customer_engagements ADD COLUMN value float;
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
SELECT master_copy_shard_placement(:newshardid, 'localhost', :worker_1_port, 'localhost', :worker_2_port);
|
||||||
|
INSERT INTO customer_engagements VALUES (4, '04-01-2015', 'fourth event');
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
-- add a fake healthy placement for the tests
|
-- add a fake healthy placement for the tests
|
||||||
INSERT INTO pg_dist_shard_placement (nodename, nodeport, shardid, shardstate, shardlength)
|
INSERT INTO pg_dist_shard_placement (nodename, nodeport, shardid, shardstate, shardlength)
|
||||||
VALUES ('dummyhost', :worker_2_port, :newshardid, 1, 0);
|
VALUES ('dummyhost', :worker_2_port, :newshardid, 1, 0);
|
||||||
|
|
Loading…
Reference in New Issue