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

Commit d3b1b1f

Browse files
committed
Fix CREATE INDEX CONCURRENTLY so that it won't use synchronized scan for
its second pass over the table. It has to start at block zero, else the "merge join" logic for detecting which TIDs are already in the index doesn't work. Hence, extend heapam.c's API so that callers can enable or disable syncscan. (I put in an option to disable buffer access strategy, too, just in case somebody needs it.) Per report from Hannes Dorbath.
1 parent 689d02a commit d3b1b1f

File tree

4 files changed

+69
-22
lines changed

4 files changed

+69
-22
lines changed

src/backend/access/heap/heapam.c

+51-13
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.247 2008/01/01 19:45:46 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.248 2008/01/14 01:39:09 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -62,6 +62,7 @@
6262
static HeapScanDesc heap_beginscan_internal(Relation relation,
6363
Snapshot snapshot,
6464
int nkeys, ScanKey key,
65+
bool allow_strat, bool allow_sync,
6566
bool is_bitmapscan);
6667
static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
6768
ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move);
@@ -81,6 +82,9 @@ static bool HeapSatisfiesHOTUpdate(Relation relation, Bitmapset *hot_attrs,
8182
static void
8283
initscan(HeapScanDesc scan, ScanKey key)
8384
{
85+
bool allow_strat;
86+
bool allow_sync;
87+
8488
/*
8589
* Determine the number of blocks we have to scan.
8690
*
@@ -99,25 +103,39 @@ initscan(HeapScanDesc scan, ScanKey key)
99103
* strategy and enable synchronized scanning (see syncscan.c). Although
100104
* the thresholds for these features could be different, we make them the
101105
* same so that there are only two behaviors to tune rather than four.
106+
* (However, some callers need to be able to disable one or both of
107+
* these behaviors, independently of the size of the table.)
102108
*
103109
* During a rescan, don't make a new strategy object if we don't have to.
104110
*/
105-
if (!scan->rs_bitmapscan &&
106-
!scan->rs_rd->rd_istemp &&
111+
if (!scan->rs_rd->rd_istemp &&
107112
scan->rs_nblocks > NBuffers / 4)
113+
{
114+
allow_strat = scan->rs_allow_strat;
115+
allow_sync = scan->rs_allow_sync;
116+
}
117+
else
118+
allow_strat = allow_sync = false;
119+
120+
if (allow_strat)
108121
{
109122
if (scan->rs_strategy == NULL)
110123
scan->rs_strategy = GetAccessStrategy(BAS_BULKREAD);
111-
112-
scan->rs_syncscan = true;
113-
scan->rs_startblock = ss_get_location(scan->rs_rd, scan->rs_nblocks);
114124
}
115125
else
116126
{
117127
if (scan->rs_strategy != NULL)
118128
FreeAccessStrategy(scan->rs_strategy);
119129
scan->rs_strategy = NULL;
130+
}
120131

132+
if (allow_sync)
133+
{
134+
scan->rs_syncscan = true;
135+
scan->rs_startblock = ss_get_location(scan->rs_rd, scan->rs_nblocks);
136+
}
137+
else
138+
{
121139
scan->rs_syncscan = false;
122140
scan->rs_startblock = 0;
123141
}
@@ -1058,29 +1076,47 @@ heap_openrv(const RangeVar *relation, LOCKMODE lockmode)
10581076
/* ----------------
10591077
* heap_beginscan - begin relation scan
10601078
*
1061-
* heap_beginscan_bm is an alternative entry point for setting up a HeapScanDesc
1062-
* for a bitmap heap scan. Although that scan technology is really quite
1063-
* unlike a standard seqscan, there is just enough commonality to make it
1064-
* worth using the same data structure.
1079+
* heap_beginscan_strat offers an extended API that lets the caller control
1080+
* whether a nondefault buffer access strategy can be used, and whether
1081+
* syncscan can be chosen (possibly resulting in the scan not starting from
1082+
* block zero). Both of these default to TRUE with plain heap_beginscan.
1083+
*
1084+
* heap_beginscan_bm is an alternative entry point for setting up a
1085+
* HeapScanDesc for a bitmap heap scan. Although that scan technology is
1086+
* really quite unlike a standard seqscan, there is just enough commonality
1087+
* to make it worth using the same data structure.
10651088
* ----------------
10661089
*/
10671090
HeapScanDesc
10681091
heap_beginscan(Relation relation, Snapshot snapshot,
10691092
int nkeys, ScanKey key)
10701093
{
1071-
return heap_beginscan_internal(relation, snapshot, nkeys, key, false);
1094+
return heap_beginscan_internal(relation, snapshot, nkeys, key,
1095+
true, true, false);
1096+
}
1097+
1098+
HeapScanDesc
1099+
heap_beginscan_strat(Relation relation, Snapshot snapshot,
1100+
int nkeys, ScanKey key,
1101+
bool allow_strat, bool allow_sync)
1102+
{
1103+
return heap_beginscan_internal(relation, snapshot, nkeys, key,
1104+
allow_strat, allow_sync, false);
10721105
}
10731106

10741107
HeapScanDesc
10751108
heap_beginscan_bm(Relation relation, Snapshot snapshot,
10761109
int nkeys, ScanKey key)
10771110
{
1078-
return heap_beginscan_internal(relation, snapshot, nkeys, key, true);
1111+
return heap_beginscan_internal(relation, snapshot, nkeys, key,
1112+
false, false, true);
10791113
}
10801114

10811115
static HeapScanDesc
10821116
heap_beginscan_internal(Relation relation, Snapshot snapshot,
1083-
int nkeys, ScanKey key, bool is_bitmapscan)
1117+
int nkeys, ScanKey key,
1118+
bool allow_strat, bool allow_sync,
1119+
bool is_bitmapscan)
10841120
{
10851121
HeapScanDesc scan;
10861122

@@ -1103,6 +1139,8 @@ heap_beginscan_internal(Relation relation, Snapshot snapshot,
11031139
scan->rs_nkeys = nkeys;
11041140
scan->rs_bitmapscan = is_bitmapscan;
11051141
scan->rs_strategy = NULL; /* set in initscan */
1142+
scan->rs_allow_strat = allow_strat;
1143+
scan->rs_allow_sync = allow_sync;
11061144

11071145
/*
11081146
* we can use page-at-a-time mode if it's an MVCC-safe snapshot

src/backend/catalog/index.c

+11-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.290 2008/01/03 21:23:15 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.291 2008/01/14 01:39:09 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -2004,12 +2004,16 @@ validate_index_heapscan(Relation heapRelation,
20042004

20052005
/*
20062006
* Prepare for scan of the base relation. We need just those tuples
2007-
* satisfying the passed-in reference snapshot.
2008-
*/
2009-
scan = heap_beginscan(heapRelation, /* relation */
2010-
snapshot, /* seeself */
2011-
0, /* number of keys */
2012-
NULL); /* scan key */
2007+
* satisfying the passed-in reference snapshot. We must disable syncscan
2008+
* here, because it's critical that we read from block zero forward to
2009+
* match the sorted TIDs.
2010+
*/
2011+
scan = heap_beginscan_strat(heapRelation, /* relation */
2012+
snapshot, /* snapshot */
2013+
0, /* number of keys */
2014+
NULL, /* scan key */
2015+
true, /* buffer access strategy OK */
2016+
false); /* syncscan not OK */
20132017

20142018
/*
20152019
* Scan all tuples matching the snapshot.

src/include/access/heapam.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.129 2008/01/01 19:45:56 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.130 2008/01/14 01:39:09 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -141,6 +141,9 @@ extern Relation heap_openrv(const RangeVar *relation, LOCKMODE lockmode);
141141

142142
extern HeapScanDesc heap_beginscan(Relation relation, Snapshot snapshot,
143143
int nkeys, ScanKey key);
144+
extern HeapScanDesc heap_beginscan_strat(Relation relation, Snapshot snapshot,
145+
int nkeys, ScanKey key,
146+
bool allow_strat, bool allow_sync);
144147
extern HeapScanDesc heap_beginscan_bm(Relation relation, Snapshot snapshot,
145148
int nkeys, ScanKey key);
146149
extern void heap_rescan(HeapScanDesc scan, ScanKey key);

src/include/access/relscan.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.59 2008/01/01 19:45:56 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.60 2008/01/14 01:39:09 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -28,6 +28,8 @@ typedef struct HeapScanDescData
2828
ScanKey rs_key; /* array of scan key descriptors */
2929
bool rs_bitmapscan; /* true if this is really a bitmap scan */
3030
bool rs_pageatatime; /* verify visibility page-at-a-time? */
31+
bool rs_allow_strat; /* allow or disallow use of access strategy */
32+
bool rs_allow_sync; /* allow or disallow use of syncscan */
3133

3234
/* state set up at initscan time */
3335
BlockNumber rs_nblocks; /* number of blocks to scan */

0 commit comments

Comments
 (0)