Add GUC for TAM arrow cache size

The arrow cache is used to cache decompressed arrow segments and is
mostly useful for index scans that access values across segments in
non-segment order.

The fixed cache size was set too small for index scans on bigger data
sets. Therefore, increase the default size and make it configurable via
a GUC.
This commit is contained in:
Erik Nordström 2025-02-12 17:18:52 +01:00 committed by Erik Nordström
parent 63ccf6aaa0
commit 4128feb262
6 changed files with 24 additions and 32 deletions

View File

@ -165,6 +165,7 @@ TSDLLEXPORT char *ts_guc_hypercore_indexam_whitelist;
TSDLLEXPORT HypercoreCopyToBehavior ts_guc_hypercore_copy_to_behavior =
HYPERCORE_COPY_NO_COMPRESSED_DATA;
TSDLLEXPORT bool ts_guc_enable_hypercore_scankey_pushdown = true;
TSDLLEXPORT int ts_guc_hypercore_arrow_cache_max_entries;
/* default value of ts_guc_max_open_chunks_per_insert and
* ts_guc_max_cached_chunks_per_hypertable will be set as their respective boot-value when the
@ -1084,6 +1085,23 @@ _guc_init(void)
/* assign_hook= */ NULL,
/* show_hook= */ NULL);
DefineCustomIntVariable(/* name= */ MAKE_EXTOPTION("hypercore_arrow_cache_max_entries"),
/* short_desc= */ "max number of entries in arrow data cache",
/* long_desc= */
"The max number of decompressed arrow segments that can be "
"cached before entries are evicted. This mainly affects the "
"performance of index scans on the Hypercore TAM "
"when segments are accessed in non-sequential order.",
/* valueAddr= */ &ts_guc_hypercore_arrow_cache_max_entries,
/* bootValue= */ 25000,
/* minValue= */ 1,
/* maxValue= */ INT_MAX,
/* context= */ PGC_USERSET,
/* flags= */ 0,
/* check_hook= */ NULL,
/* assign_hook= */ NULL,
/* show_hook= */ NULL);
DefineCustomIntVariable(/* name= */ MAKE_EXTOPTION("debug_bgw_scheduler_exit_status"),
/* short_desc= */ "exit status to use when shutting down the scheduler",
/* long_desc= */ "this is for debugging purposes",

View File

@ -149,6 +149,7 @@ typedef enum HypercoreCopyToBehavior
extern TSDLLEXPORT HypercoreCopyToBehavior ts_guc_hypercore_copy_to_behavior;
extern TSDLLEXPORT bool ts_guc_enable_hypercore_scankey_pushdown;
extern TSDLLEXPORT int ts_guc_hypercore_arrow_cache_max_entries;
void _guc_init(void);

View File

@ -4,9 +4,9 @@
* LICENSE-TIMESCALE for a copy of the license.
*/
#include <postgres.h>
#include "guc.h"
#include <access/attnum.h>
#include <access/tupdesc.h>
#include <c.h>
#include <catalog/pg_attribute.h>
#include <nodes/bitmapset.h>
#include <stdint.h>
@ -70,33 +70,6 @@ dlist_move_tail(dlist_head *head, dlist_node *node)
}
#endif
static uint16
get_cache_maxsize(void)
{
#ifdef TS_DEBUG
const char *maxsize = GetConfigOption("timescaledb.arrow_cache_maxsize", true, false);
char *endptr = NULL;
if (maxsize == NULL)
return ARROW_DECOMPRESSION_CACHE_LRU_ENTRIES;
if (maxsize[0] == '\0')
elog(ERROR, "invalid arrow_cache_maxsize value");
long maxsizel = strtol(maxsize, &endptr, 10);
errno = 0;
if (errno == ERANGE || endptr == NULL || endptr[0] != '\0' || maxsizel <= 0 ||
maxsizel > UINT16_MAX)
elog(ERROR, "invalid arrow_cache_maxsize value");
return maxsizel & 0xFFFF;
#else
return ARROW_DECOMPRESSION_CACHE_LRU_ENTRIES;
#endif
}
void
arrow_column_cache_init(ArrowColumnCache *acache, MemoryContext mcxt)
{
@ -115,7 +88,7 @@ arrow_column_cache_init(ArrowColumnCache *acache, MemoryContext mcxt)
/* minContextSize = */ 0,
/* initBlockSize = */ 64 * 1024,
/* maxBlockSize = */ 64 * 1024);
acache->maxsize = get_cache_maxsize();
acache->maxsize = ts_guc_hypercore_arrow_cache_max_entries;
ctl.keysize = sizeof(ArrowColumnKey);
ctl.entrysize = sizeof(ArrowColumnCacheEntry);

View File

@ -53,7 +53,7 @@ typedef struct ArrowColumnCache
size_t arrow_column_cache_lru_count; /* Arrow column cache LRU list count */
dlist_head arrow_column_cache_lru; /* Arrow column cache LRU list */
HTAB *htab; /* Arrow column cache */
uint16 maxsize;
size_t maxsize;
} ArrowColumnCache;
typedef struct ArrowTupleTableSlot ArrowTupleTableSlot;

View File

@ -12,7 +12,7 @@ show timescaledb.hypercore_indexam_whitelist;
-- user.
grant all on schema _timescaledb_internal to :ROLE_DEFAULT_PERM_USER;
set role :ROLE_DEFAULT_PERM_USER;
SET timescaledb.arrow_cache_maxsize = 4;
SET timescaledb.hypercore_arrow_cache_max_entries = 4;
CREATE TABLE readings(
time timestamptz UNIQUE,
location int,

View File

@ -9,7 +9,7 @@ show timescaledb.hypercore_indexam_whitelist;
grant all on schema _timescaledb_internal to :ROLE_DEFAULT_PERM_USER;
set role :ROLE_DEFAULT_PERM_USER;
SET timescaledb.arrow_cache_maxsize = 4;
SET timescaledb.hypercore_arrow_cache_max_entries = 4;
CREATE TABLE readings(
time timestamptz UNIQUE,