Commit 9c32e4c3 authored by Amit Kapila's avatar Amit Kapila

Clear the local map when not used.

After commit b0eaa4c5, we use a local map of pages to find the required
space for small relations.  We do clear this map when we have found a block
with enough free space, when we extend the relation, or on transaction
abort so that it can be used next time.  However, we miss to clear it when
we didn't find any pages to try from the map which leads to an assertion
failure when we later tried to use it after relation extension.

In the passing, I have improved some comments in this area.

Reported-by: Tom Lane based on buildfarm results
Author: Amit Kapila
Reviewed-by: John Naylor
Tested-by: Kuntal Ghosh
Discussion: https://postgr.es/m/32368.1551114120@sss.pgh.pa.us
parent 0f3cdf87
...@@ -675,10 +675,7 @@ loop: ...@@ -675,10 +675,7 @@ loop:
*/ */
RelationSetTargetBlock(relation, BufferGetBlockNumber(buffer)); RelationSetTargetBlock(relation, BufferGetBlockNumber(buffer));
/* /* This should already be cleared by now, but make sure it is. */
* In case we used an in-memory map of available blocks, reset it for next
* use.
*/
FSMClearLocalMap(); FSMClearLocalMap();
return buffer; return buffer;
......
...@@ -97,7 +97,16 @@ typedef struct ...@@ -97,7 +97,16 @@ typedef struct
/* Address of the root page. */ /* Address of the root page. */
static const FSMAddress FSM_ROOT_ADDRESS = {FSM_ROOT_LEVEL, 0}; static const FSMAddress FSM_ROOT_ADDRESS = {FSM_ROOT_LEVEL, 0};
/* Local map of block numbers for small heaps with no FSM. */ /*
* For small relations, we don't create FSM to save space, instead we use
* local in-memory map of pages to try. To locate free space, we simply try
* pages directly without knowing ahead of time how much free space they have.
*
* Note that this map is used to the find the block with required free space
* for any given relation. We clear this map when we have found a block with
* enough free space, when we extend the relation, or on transaction abort.
* See src/backend/storage/freespace/README for further details.
*/
typedef struct typedef struct
{ {
BlockNumber nblocks; BlockNumber nblocks;
...@@ -1175,5 +1184,13 @@ fsm_local_search(void) ...@@ -1175,5 +1184,13 @@ fsm_local_search(void)
return target_block; return target_block;
} while (target_block > 0); } while (target_block > 0);
/*
* If we didn't find any available block to try in the local map, then
* clear it. This prevents us from using the map again without setting it
* first, which would otherwise lead to the same conclusion again and
* again.
*/
FSMClearLocalMap();
return InvalidBlockNumber; return InvalidBlockNumber;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment