You can subscribe to this list here.
2010 |
Jan
|
Feb
|
Mar
|
Apr
(4) |
May
(28) |
Jun
(12) |
Jul
(11) |
Aug
(12) |
Sep
(5) |
Oct
(19) |
Nov
(14) |
Dec
(12) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2011 |
Jan
(18) |
Feb
(30) |
Mar
(115) |
Apr
(89) |
May
(50) |
Jun
(44) |
Jul
(22) |
Aug
(13) |
Sep
(11) |
Oct
(30) |
Nov
(28) |
Dec
(39) |
2012 |
Jan
(38) |
Feb
(18) |
Mar
(43) |
Apr
(91) |
May
(108) |
Jun
(46) |
Jul
(37) |
Aug
(44) |
Sep
(33) |
Oct
(29) |
Nov
(36) |
Dec
(15) |
2013 |
Jan
(35) |
Feb
(611) |
Mar
(5) |
Apr
(55) |
May
(30) |
Jun
(28) |
Jul
(458) |
Aug
(34) |
Sep
(9) |
Oct
(39) |
Nov
(22) |
Dec
(32) |
2014 |
Jan
(16) |
Feb
(16) |
Mar
(42) |
Apr
(179) |
May
(7) |
Jun
(6) |
Jul
(9) |
Aug
|
Sep
(4) |
Oct
|
Nov
(3) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1
|
2
(1) |
3
(3) |
4
(3) |
5
|
6
|
7
|
8
|
9
(1) |
10
(1) |
11
(3) |
12
(4) |
13
|
14
|
15
|
16
(1) |
17
|
18
|
19
(1) |
20
|
21
|
22
|
23
|
24
(7) |
25
(16) |
26
(2) |
27
|
28
|
29
|
30
(4) |
31
(3) |
|
|
|
|
From: Abbas B. <ga...@us...> - 2011-05-02 14:51:48
|
Project "Postgres-XC". The branch, master has been updated via a877e0769b83719b446d15a243e14b05700f975a (commit) from 7bbb6a36362ac0b9e92191bce988eeaa5dd5b118 (commit) - Log ----------------------------------------------------------------- commit a877e0769b83719b446d15a243e14b05700f975a Author: Abbas <abb...@en...> Date: Mon May 2 19:16:38 2011 +0500 This patch fixes TWO bugs 3273569 & 3243469 The problem was that prepared transactions were not being listed in the system view pg_prepared_xacts. The reason was that in XC transactions are not prepared on the coordinator and hence the function pg_prepared_xact does not return any. The main worker function GetPreparedTransactionList which is supposed to return an array of prepared transactions for the user level function pg_prepared_xact, always finds ZERO in TwoPhaseState->numPrepXacts, since the transaction was never prepared on the coordinator. The solution was to ask data nodes, where the transaction was actually prepared. All data nodes may not be involved in all transactions hence we have to ask all data nodes in any case. In order to implement this solution we created two schemas, __pgxc_datanode_schema__ & __pgxc_coordinator_schema__ one for data nodes and one for coordinators respectively. Next these schemas were added to the default search path in coordinator as well as on data node. Hence the default search path on coordinator is "$user",public, __pgxc_coordinator_schema__ and on the data node is "$user",public, __pgxc_datanode_schema__ Next we created a table named pg_prepared_xact in the schema __pgxc_coordinator_schema__ with the same fields as the old view pg_prepared_xact. and we created the old view pg_prepared_xact in the schema __pgxc_datanode_schema__. Now when a query for the view pg_prepared_xact is launched on the coordinator, it knows it is a table distributed in round robin fashion on all data nodes and hence it generates a query to ask all data nodes. The only difference will be that if we have two data nodes and the transaction was prepared on both we will get two rows for it which is correct. If one row per transaction is required all that is required is to add distinct in the query. A few changes in this patch are due to the following two limitations which are not addressed by this patch. 1. create table in system_view.sql does not enter a corresponding row in pgxc_class. 2. We need to ROLLBACK manually after a PREPARE TRANSCATION fails due to name duplication. The prepared_xacts.sql test case now passes, and hence successive regression runs are now possible. diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index b0cd121..2392e7a 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -51,6 +51,9 @@ #include "utils/rel.h" #include "utils/syscache.h" +#ifdef PGXC +#include "pgxc/pgxc.h" +#endif /* * The namespace search path is a possibly-empty list of namespace OIDs. diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index fca7be9..a039578 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -150,7 +150,12 @@ CREATE VIEW pg_locks AS CREATE VIEW pg_cursors AS SELECT * FROM pg_cursor() AS C; -CREATE VIEW pg_prepared_xacts AS +CREATE SCHEMA __pgxc_coordinator_schema__; +CREATE SCHEMA __pgxc_datanode_schema__; + +create table __pgxc_coordinator_schema__.pg_prepared_xacts ( transaction xid, gid text, prepared timestamptz, owner name, database name ); + +CREATE VIEW __pgxc_datanode_schema__.pg_prepared_xacts AS SELECT P.transaction, P.gid, P.prepared, U.rolname AS owner, D.datname AS database FROM pg_prepared_xact() AS P diff --git a/src/backend/pgxc/locator/locator.c b/src/backend/pgxc/locator/locator.c index 5d6667e..acab6d7 100644 --- a/src/backend/pgxc/locator/locator.c +++ b/src/backend/pgxc/locator/locator.c @@ -750,9 +750,41 @@ RelationLocInfo * GetRelationLocInfo(Oid relid) { RelationLocInfo *ret_loc_info = NULL; + char *namespace; Relation rel = relation_open(relid, AccessShareLock); + /* This check has been added as a temp fix for CREATE TABLE not adding entry in pgxc_class + * when run from system_views.sql + */ + if ( rel != NULL && + rel->rd_rel != NULL && + rel->rd_rel->relkind == RELKIND_RELATION && + rel->rd_rel->relname.data != NULL && + (strcmp(rel->rd_rel->relname.data, PREPARED_XACTS_TABLE) == 0) ) + { + namespace = get_namespace_name(rel->rd_rel->relnamespace); + + if (namespace != NULL && (strcmp(namespace, PGXC_COORDINATOR_SCHEMA) == 0)) + { + RelationLocInfo *dest_info; + + dest_info = (RelationLocInfo *) palloc0(sizeof(RelationLocInfo)); + + dest_info->relid = relid; + dest_info->locatorType = 'N'; + dest_info->nodeCount = NumDataNodes; + dest_info->nodeList = GetAllDataNodes(); + + relation_close(rel, AccessShareLock); + pfree(namespace); + + return dest_info; + } + + if (namespace != NULL) pfree(namespace); + } + if (rel && rel->rd_locator_info) ret_loc_info = CopyRelationLocInfo(rel->rd_locator_info); diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 552b0d8..1058c50 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -538,6 +538,26 @@ PostmasterMain(int argc, char *argv[]) /* Initialize paths to installation files */ getInstallationPaths(argv[0]); +#ifdef PGXC + /* Decide whether coordinator or data node before setting GUC variables */ + while ((opt = getopt(argc, argv, "A:B:Cc:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:W:X-:")) != -1) + { + switch (opt) + { + case 'C': + isPGXCCoordinator = true; + break; + case 'X': + isPGXCDataNode = true; + break; + default: + break; + } + } + /* Reset getopt for parsing again */ + optind = 1; +#endif + /* * Options setup */ diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index c8648ee..d955b23 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -2236,6 +2236,10 @@ static struct config_int ConfigureNamesInt[] = } }; +#ifdef PGXC +/* Variable to store search path */ +static char boot_search_path[255]; +#endif static struct config_real ConfigureNamesReal[] = { @@ -2364,7 +2368,6 @@ static struct config_real ConfigureNamesReal[] = } }; - static struct config_string ConfigureNamesString[] = { { @@ -2561,7 +2564,11 @@ static struct config_string ConfigureNamesString[] = GUC_LIST_INPUT | GUC_LIST_QUOTE }, &namespace_search_path, +#ifdef PGXC + boot_search_path, assign_search_path, NULL +#else "\"$user\",public", assign_search_path, NULL +#endif }, { @@ -3296,6 +3303,14 @@ build_guc_variables(void) struct config_generic **guc_vars; int i; +#ifdef PGXC + strcpy(boot_search_path, "\"$user\",public, "); + if (IS_PGXC_DATANODE) + strcat(boot_search_path, PGXC_DATA_NODE_SCHEMA); + else + strcat(boot_search_path, PGXC_COORDINATOR_SCHEMA); +#endif + for (i = 0; ConfigureNamesBool[i].gen.name; i++) { struct config_bool *conf = &ConfigureNamesBool[i]; diff --git a/src/include/pgxc/locator.h b/src/include/pgxc/locator.h index 3272ab6..9f669d9 100644 --- a/src/include/pgxc/locator.h +++ b/src/include/pgxc/locator.h @@ -28,6 +28,10 @@ #define IsReplicated(x) (x->locatorType == LOCATOR_TYPE_REPLICATED) +#define PGXC_COORDINATOR_SCHEMA "__pgxc_coordinator_schema__" +#define PGXC_DATA_NODE_SCHEMA "__pgxc_datanode_schema__" +#define PREPARED_XACTS_TABLE "pg_prepared_xacts" + #include "nodes/primnodes.h" #include "utils/relcache.h" diff --git a/src/test/regress/expected/prepared_xacts_2.out b/src/test/regress/expected/prepared_xacts_2.out new file mode 100644 index 0000000..e456200 --- /dev/null +++ b/src/test/regress/expected/prepared_xacts_2.out @@ -0,0 +1,230 @@ +-- +-- PREPARED TRANSACTIONS (two-phase commit) +-- +-- We can't readily test persistence of prepared xacts within the +-- regression script framework, unfortunately. Note that a crash +-- isn't really needed ... stopping and starting the postmaster would +-- be enough, but we can't even do that here. +-- create a simple table that we'll use in the tests +CREATE TABLE pxtest1 (foobar VARCHAR(10)); +INSERT INTO pxtest1 VALUES ('aaa'); +-- Test PREPARE TRANSACTION +BEGIN; +UPDATE pxtest1 SET foobar = 'bbb' WHERE foobar = 'aaa'; +SELECT * FROM pxtest1 ORDER BY foobar; + foobar +-------- + bbb +(1 row) + +PREPARE TRANSACTION 'foo1'; +SELECT * FROM pxtest1 ORDER BY foobar; + foobar +-------- + aaa +(1 row) + +-- Test pg_prepared_xacts system view +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; + gid +------ + foo1 +(1 row) + +-- Test ROLLBACK PREPARED +ROLLBACK PREPARED 'foo1'; +SELECT * FROM pxtest1 ORDER BY foobar; + foobar +-------- + aaa +(1 row) + +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; + gid +----- +(0 rows) + +-- Test COMMIT PREPARED +BEGIN; +INSERT INTO pxtest1 VALUES ('ddd'); +SELECT * FROM pxtest1 ORDER BY foobar; + foobar +-------- + aaa + ddd +(2 rows) + +PREPARE TRANSACTION 'foo2'; +SELECT * FROM pxtest1 ORDER BY foobar; + foobar +-------- + aaa +(1 row) + +COMMIT PREPARED 'foo2'; +SELECT * FROM pxtest1 ORDER BY foobar; + foobar +-------- + aaa + ddd +(2 rows) + +-- Test duplicate gids +BEGIN; +UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd'; +SELECT * FROM pxtest1 ORDER BY foobar; + foobar +-------- + aaa + eee +(2 rows) + +PREPARE TRANSACTION 'foo3'; +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; + gid +------ + foo3 +(1 row) + +BEGIN; +INSERT INTO pxtest1 VALUES ('fff'); +SELECT * FROM pxtest1 ORDER BY foobar; + foobar +-------- + aaa + ddd + fff +(3 rows) + +-- This should fail, because the gid foo3 is already in use +PREPARE TRANSACTION 'foo3'; +ERROR: Could not prepare transaction on data nodes +ROLLBACK; +SELECT * FROM pxtest1 ORDER BY foobar; + foobar +-------- + aaa + ddd +(2 rows) + +ROLLBACK PREPARED 'foo3'; +SELECT * FROM pxtest1 ORDER BY foobar; + foobar +-------- + aaa + ddd +(2 rows) + +-- Clean up +DROP TABLE pxtest1; +-- Test subtransactions +BEGIN; + CREATE TABLE pxtest2 (a int); + INSERT INTO pxtest2 VALUES (1); + SAVEPOINT a; +ERROR: SAVEPOINT is not yet supported. + INSERT INTO pxtest2 VALUES (2); +ERROR: current transaction is aborted, commands ignored until end of transaction block + ROLLBACK TO a; +ERROR: no such savepoint + SAVEPOINT b; +ERROR: current transaction is aborted, commands ignored until end of transaction block + INSERT INTO pxtest2 VALUES (3); +ERROR: current transaction is aborted, commands ignored until end of transaction block +PREPARE TRANSACTION 'regress-one'; +BEGIN; + CREATE TABLE pxtest2 (a int); + INSERT INTO pxtest2 VALUES (1); + INSERT INTO pxtest2 VALUES (3); +PREPARE TRANSACTION 'regress-one'; +CREATE TABLE pxtest3(fff int); +-- Test shared invalidation +BEGIN; + DROP TABLE pxtest3; + CREATE TABLE pxtest4 (a int); + INSERT INTO pxtest4 VALUES (1); + INSERT INTO pxtest4 VALUES (2); + DECLARE foo CURSOR FOR SELECT * FROM pxtest4; + -- Fetch 1 tuple, keeping the cursor open + FETCH 1 FROM foo; + a +--- + 1 +(1 row) + +PREPARE TRANSACTION 'regress-two'; +-- No such cursor +FETCH 1 FROM foo; +ERROR: cursor "foo" does not exist +-- Table doesn't exist, the creation hasn't been committed yet +SELECT * FROM pxtest2; +ERROR: relation "pxtest2" does not exist +LINE 1: SELECT * FROM pxtest2; + ^ +-- There should be two prepared transactions +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; + gid +------------- + regress-one + regress-two +(2 rows) + +-- pxtest3 should be locked because of the pending DROP +set statement_timeout to 2000; +SELECT * FROM pxtest3; +ERROR: canceling statement due to statement timeout +reset statement_timeout; +-- Disconnect, we will continue testing in a different backend +\c - +-- There should still be two prepared transactions +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; + gid +------------- + regress-one + regress-two +(2 rows) + +-- pxtest3 should still be locked because of the pending DROP +set statement_timeout to 2000; +SELECT * FROM pxtest3; +ERROR: canceling statement due to statement timeout +reset statement_timeout; +-- Commit table creation +COMMIT PREPARED 'regress-one'; +\d pxtest2 + Table "public.pxtest2" + Column | Type | Modifiers +--------+---------+----------- + a | integer | + +SELECT * FROM pxtest2; + a +--- + 1 + 3 +(2 rows) + +-- There should be one prepared transaction +SELECT DISTINCT gid FROM pg_prepared_xacts; + gid +------------- + regress-two +(1 row) + +-- Commit table drop +COMMIT PREPARED 'regress-two'; +SELECT * FROM pxtest3; +ERROR: relation "pxtest3" does not exist +LINE 1: SELECT * FROM pxtest3; + ^ +-- There should be no prepared transactions +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; + gid +----- +(0 rows) + +-- Clean up +DROP TABLE pxtest2; +DROP TABLE pxtest3; -- will still be there if prepared xacts are disabled +ERROR: table "pxtest3" does not exist +DROP TABLE pxtest4; diff --git a/src/test/regress/sql/prepared_xacts.sql b/src/test/regress/sql/prepared_xacts.sql index b8915bd..fb9bc64 100644 --- a/src/test/regress/sql/prepared_xacts.sql +++ b/src/test/regress/sql/prepared_xacts.sql @@ -22,14 +22,14 @@ PREPARE TRANSACTION 'foo1'; SELECT * FROM pxtest1 ORDER BY foobar; -- Test pg_prepared_xacts system view -SELECT gid FROM pg_prepared_xacts ORDER BY gid; +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; -- Test ROLLBACK PREPARED ROLLBACK PREPARED 'foo1'; SELECT * FROM pxtest1 ORDER BY foobar; -SELECT gid FROM pg_prepared_xacts ORDER BY gid; +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; -- Test COMMIT PREPARED @@ -50,7 +50,7 @@ UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd'; SELECT * FROM pxtest1 ORDER BY foobar; PREPARE TRANSACTION 'foo3'; -SELECT gid FROM pg_prepared_xacts ORDER BY gid; +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; BEGIN; INSERT INTO pxtest1 VALUES ('fff'); @@ -59,8 +59,8 @@ SELECT * FROM pxtest1 ORDER BY foobar; -- This should fail, because the gid foo3 is already in use PREPARE TRANSACTION 'foo3'; +ROLLBACK; SELECT * FROM pxtest1 ORDER BY foobar; - ROLLBACK PREPARED 'foo3'; SELECT * FROM pxtest1 ORDER BY foobar; @@ -79,6 +79,13 @@ BEGIN; INSERT INTO pxtest2 VALUES (3); PREPARE TRANSACTION 'regress-one'; +BEGIN; + CREATE TABLE pxtest2 (a int); + INSERT INTO pxtest2 VALUES (1); + INSERT INTO pxtest2 VALUES (3); +PREPARE TRANSACTION 'regress-one'; + + CREATE TABLE pxtest3(fff int); -- Test shared invalidation @@ -99,7 +106,7 @@ FETCH 1 FROM foo; SELECT * FROM pxtest2; -- There should be two prepared transactions -SELECT gid FROM pg_prepared_xacts ORDER BY gid; +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; -- pxtest3 should be locked because of the pending DROP set statement_timeout to 2000; @@ -110,7 +117,7 @@ reset statement_timeout; \c - -- There should still be two prepared transactions -SELECT gid FROM pg_prepared_xacts ORDER BY gid; +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; -- pxtest3 should still be locked because of the pending DROP set statement_timeout to 2000; @@ -123,16 +130,17 @@ COMMIT PREPARED 'regress-one'; SELECT * FROM pxtest2; -- There should be one prepared transaction -SELECT gid FROM pg_prepared_xacts; +SELECT DISTINCT gid FROM pg_prepared_xacts; -- Commit table drop COMMIT PREPARED 'regress-two'; SELECT * FROM pxtest3; -- There should be no prepared transactions -SELECT gid FROM pg_prepared_xacts ORDER BY gid; +SELECT DISTINCT gid FROM pg_prepared_xacts ORDER BY gid; -- Clean up DROP TABLE pxtest2; DROP TABLE pxtest3; -- will still be there if prepared xacts are disabled DROP TABLE pxtest4; + ----------------------------------------------------------------------- Summary of changes: src/backend/catalog/namespace.c | 3 ++ src/backend/catalog/system_views.sql | 7 ++++- src/backend/pgxc/locator/locator.c | 32 ++++++++++++++++++++ src/backend/postmaster/postmaster.c | 20 ++++++++++++ src/backend/utils/misc/guc.c | 17 ++++++++++- src/include/pgxc/locator.h | 4 ++ .../{prepared_xacts.out => prepared_xacts_2.out} | 27 ++++++++++++----- src/test/regress/sql/prepared_xacts.sql | 24 ++++++++++----- 8 files changed, 116 insertions(+), 18 deletions(-) copy src/test/regress/expected/{prepared_xacts.out => prepared_xacts_2.out} (81%) hooks/post-receive -- Postgres-XC |