Re: Damage control for planner's get_actual_variable_endpoint() runaway

Andres Freund <andres@anarazel.de>

From: Andres Freund <andres@anarazel.de>
To: Jakub Wartak <jakub.wartak@enterprisedb.com>
Cc: Robert Haas <robertmhaas@gmail.com>, Tom Lane <tgl@sss.pgh.pa.us>, Simon Riggs <simon.riggs@enterprisedb.com>, Alvaro Herrera <alvherre@alvh.no-ip.org>, PostgreSQL Hackers <pgsql-hackers@postgresql.org>
Date: 2022-11-21T17:30:48Z
Lists: pgsql-hackers
Hi,

On 2022-11-21 17:06:16 +0100, Jakub Wartak wrote:
> @@ -6213,14 +6216,26 @@ get_actual_variable_endpoint(Relation heapRel,
>  	/* Fetch first/next tuple in specified direction */
>  	while ((tid = index_getnext_tid(index_scan, indexscandir)) != NULL)
>  	{
> +		BlockNumber block = ItemPointerGetBlockNumber(tid);
>  		if (!VM_ALL_VISIBLE(heapRel,
> -							ItemPointerGetBlockNumber(tid),
> +							block,
>  							&vmbuffer))
>  		{
>  			/* Rats, we have to visit the heap to check visibility */
>  			if (!index_fetch_heap(index_scan, tableslot))
>  				continue;		/* no visible tuple, try next index entry */
>  
> +			{
> +				CHECK_FOR_INTERRUPTS();
> +				if (block != last_block)
> +					visited_pages++;
> +#define VISITED_PAGES_LIMIT 100
> +				if (visited_pages > VISITED_PAGES_LIMIT)
> +					break;
> +				else
> +					continue; /* no visible tuple, try next index entry */
> +			}
> +
>  			/* We don't actually need the heap tuple for anything */
>  			ExecClearTuple(tableslot);
>  
> -- 
> 2.30.2

This can't quite be right - isn't this only applying the limit if we found a
visible tuple?

Greetings,

Andres Freund



Commits

  1. YA attempt at taming worst-case behavior of get_actual_variable_range.

  2. Improve performance of get_actual_variable_range with recently-dead tuples.

  3. Use SnapshotDirty rather than an active snapshot to probe index endpoints.