Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5329942

Browse files
committed
Revert patch for taking fewer snapshots.
This reverts commit d573e23, "Take fewer snapshots". While that seemed like a good idea at the time, it caused execution to use a snapshot that had been acquired before locking any of the tables mentioned in the query. This created user-visible anomalies that were not present in any prior release of Postgres, as reported by Tomas Vondra. While this whole area could do with a redesign (since there are related cases that have anomalies anyway), it doesn't seem likely that any future patch would be reasonably back-patchable; and we don't want 9.2 to exhibit a behavior that's subtly unlike either past or future releases. Hence, revert to prior code while we rethink the problem.
1 parent d3237e0 commit 5329942

File tree

7 files changed

+32
-46
lines changed

7 files changed

+32
-46
lines changed

doc/src/sgml/release-9.2.sgml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -809,13 +809,6 @@
809809
</para>
810810
</listitem>
811811

812-
<listitem>
813-
<para>
814-
Take fewer <acronym>MVCC</acronym> snapshots
815-
(Robert Haas)
816-
</para>
817-
</listitem>
818-
819812
<listitem>
820813
<para>
821814
Make the number of CLOG buffers scale based on <link

src/backend/commands/portalcmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ PerformCursorOpen(PlannedStmt *stmt, ParamListInfo params,
121121
/*
122122
* Start execution, inserting parameters if any.
123123
*/
124-
PortalStart(portal, params, 0, true);
124+
PortalStart(portal, params, 0, GetActiveSnapshot());
125125

126126
Assert(portal->strategy == PORTAL_ONE_SELECT);
127127

src/backend/commands/prepare.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause,
289289
/*
290290
* Run the portal as appropriate.
291291
*/
292-
PortalStart(portal, paramLI, eflags, true);
292+
PortalStart(portal, paramLI, eflags, GetActiveSnapshot());
293293

294294
(void) PortalRun(portal, count, false, dest, dest, completionTag);
295295

src/backend/executor/spi.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,7 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
11271127
CachedPlan *cplan;
11281128
List *stmt_list;
11291129
char *query_string;
1130+
Snapshot snapshot;
11301131
MemoryContext oldcontext;
11311132
Portal portal;
11321133

@@ -1269,6 +1270,15 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
12691270
}
12701271
}
12711272

1273+
/* Set up the snapshot to use. */
1274+
if (read_only)
1275+
snapshot = GetActiveSnapshot();
1276+
else
1277+
{
1278+
CommandCounterIncrement();
1279+
snapshot = GetTransactionSnapshot();
1280+
}
1281+
12721282
/*
12731283
* If the plan has parameters, copy them into the portal. Note that this
12741284
* must be done after revalidating the plan, because in dynamic parameter
@@ -1284,13 +1294,7 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
12841294
/*
12851295
* Start portal execution.
12861296
*/
1287-
if (read_only)
1288-
PortalStart(portal, paramLI, 0, true);
1289-
else
1290-
{
1291-
CommandCounterIncrement();
1292-
PortalStart(portal, paramLI, 0, false);
1293-
}
1297+
PortalStart(portal, paramLI, 0, snapshot);
12941298

12951299
Assert(portal->strategy != PORTAL_MULTI_QUERY);
12961300

src/backend/tcop/postgres.c

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,10 @@ exec_simple_query(const char *query_string)
976976

977977
plantree_list = pg_plan_queries(querytree_list, 0, NULL);
978978

979+
/* Done with the snapshot used for parsing/planning */
980+
if (snapshot_set)
981+
PopActiveSnapshot();
982+
979983
/* If we got a cancel signal in analysis or planning, quit */
980984
CHECK_FOR_INTERRUPTS();
981985

@@ -1000,19 +1004,9 @@ exec_simple_query(const char *query_string)
10001004
NULL);
10011005

10021006
/*
1003-
* Start the portal.
1004-
*
1005-
* If we took a snapshot for parsing/planning, the portal may be able
1006-
* to reuse it for the execution phase. Currently, this will only
1007-
* happen in PORTAL_ONE_SELECT mode. But even if PortalStart doesn't
1008-
* end up being able to do this, keeping the parse/plan snapshot
1009-
* around until after we start the portal doesn't cost much.
1007+
* Start the portal. No parameters here.
10101008
*/
1011-
PortalStart(portal, NULL, 0, snapshot_set);
1012-
1013-
/* Done with the snapshot used for parsing/planning */
1014-
if (snapshot_set)
1015-
PopActiveSnapshot();
1009+
PortalStart(portal, NULL, 0, InvalidSnapshot);
10161010

10171011
/*
10181012
* Select the appropriate output format: text unless we are doing a
@@ -1735,19 +1729,15 @@ exec_bind_message(StringInfo input_message)
17351729
cplan->stmt_list,
17361730
cplan);
17371731

1738-
/*
1739-
* And we're ready to start portal execution.
1740-
*
1741-
* If we took a snapshot for parsing/planning, we'll try to reuse it for
1742-
* query execution (currently, reuse will only occur if PORTAL_ONE_SELECT
1743-
* mode is chosen).
1744-
*/
1745-
PortalStart(portal, params, 0, snapshot_set);
1746-
17471732
/* Done with the snapshot used for parameter I/O and parsing/planning */
17481733
if (snapshot_set)
17491734
PopActiveSnapshot();
17501735

1736+
/*
1737+
* And we're ready to start portal execution.
1738+
*/
1739+
PortalStart(portal, params, 0, InvalidSnapshot);
1740+
17511741
/*
17521742
* Apply the result format requests to the portal.
17531743
*/

src/backend/tcop/pquery.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -447,18 +447,17 @@ FetchStatementTargetList(Node *stmt)
447447
* currently only honored for PORTAL_ONE_SELECT portals). Most callers
448448
* should simply pass zero.
449449
*
450-
* The use_active_snapshot parameter is currently used only for
451-
* PORTAL_ONE_SELECT portals. If it is true, the active snapshot will
452-
* be used when starting up the executor; if false, a new snapshot will
453-
* be taken. This is used both for cursors and to avoid taking an entirely
454-
* new snapshot when it isn't necessary.
450+
* The caller can optionally pass a snapshot to be used; pass InvalidSnapshot
451+
* for the normal behavior of setting a new snapshot. This parameter is
452+
* presently ignored for non-PORTAL_ONE_SELECT portals (it's only intended
453+
* to be used for cursors).
455454
*
456455
* On return, portal is ready to accept PortalRun() calls, and the result
457456
* tupdesc (if any) is known.
458457
*/
459458
void
460459
PortalStart(Portal portal, ParamListInfo params,
461-
int eflags, bool use_active_snapshot)
460+
int eflags, Snapshot snapshot)
462461
{
463462
Portal saveActivePortal;
464463
ResourceOwner saveResourceOwner;
@@ -500,8 +499,8 @@ PortalStart(Portal portal, ParamListInfo params,
500499
case PORTAL_ONE_SELECT:
501500

502501
/* Must set snapshot before starting executor. */
503-
if (use_active_snapshot)
504-
PushActiveSnapshot(GetActiveSnapshot());
502+
if (snapshot)
503+
PushActiveSnapshot(snapshot);
505504
else
506505
PushActiveSnapshot(GetTransactionSnapshot());
507506

src/include/tcop/pquery.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ extern List *FetchPortalTargetList(Portal portal);
2828
extern List *FetchStatementTargetList(Node *stmt);
2929

3030
extern void PortalStart(Portal portal, ParamListInfo params,
31-
int eflags, bool use_active_snapshot);
31+
int eflags, Snapshot snapshot);
3232

3333
extern void PortalSetResultFormat(Portal portal, int nFormats,
3434
int16 *formats);

0 commit comments

Comments
 (0)