From 3a415b2e95b4d5bff99d71ba14a3700c770d56bd Mon Sep 17 00:00:00 2001 From: Mark Hannum Date: Sat, 23 Nov 2024 18:22:40 -0500 Subject: [PATCH] Verify client dbstore only on master Signed-off-by: Mark Hannum --- bdb/llmeta.c | 5 +++-- db/db_tunables.c | 2 ++ db/db_tunables.h | 9 ++++---- db/sqlglue.c | 7 +++++++ db/sqlinterfaces.c | 4 +++- tests/sc_dbstore_func.test/lrl.options | 4 ++++ tests/sc_dbstore_func.test/runit | 21 ++++++++++++++++++- tests/sc_dbstore_func.test/t1_hang.csc2 | 7 +++++++ tests/tunables.test/t00_all_tunables.expected | 2 ++ 9 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 tests/sc_dbstore_func.test/lrl.options create mode 100644 tests/sc_dbstore_func.test/t1_hang.csc2 diff --git a/bdb/llmeta.c b/bdb/llmeta.c index 5bad35d118..8a006f76f8 100644 --- a/bdb/llmeta.c +++ b/bdb/llmeta.c @@ -1329,6 +1329,7 @@ static const uint8_t *llmeta_tablename_alias_data_get( return p_buf; } +int gbl_llmeta_pagesize = 0; /* opens the low level meta table, if this is not called, any calls to * bdb_get_file_version* will return successfully but with a 0 version_number * any calls to bdb_new_file_version will fail */ @@ -1343,8 +1344,8 @@ int bdb_llmeta_open(char name[], char dir[], bdb_state_type *parent_bdb_handle, return 0; } - llmeta_bdb_state = bdb_open_more_lite( - name, dir, 0, LLMETA_IXLEN, 0, parent_bdb_handle, NULL, 0, bdberr); + llmeta_bdb_state = + bdb_open_more_lite(name, dir, 0, LLMETA_IXLEN, gbl_llmeta_pagesize, parent_bdb_handle, NULL, 0, bdberr); BDB_RELLOCK(); diff --git a/db/db_tunables.c b/db/db_tunables.c index dfadf5a43d..18b05161c7 100644 --- a/db/db_tunables.c +++ b/db/db_tunables.c @@ -106,6 +106,7 @@ extern int gbl_fdb_remsql_cdb2api; extern int gbl_goslow; extern int gbl_heartbeat_send; extern int gbl_keycompr; +extern int gbl_llmeta_pagesize; extern int gbl_largepages; extern int gbl_loghist; extern int gbl_loghist_verbose; @@ -171,6 +172,7 @@ extern int diffstat_thresh; extern int reqltruncate; extern int analyze_max_comp_threads; extern int analyze_max_table_threads; +extern int gbl_always_reload_analyze; extern int gbl_block_set_commit_genid_trace; extern int gbl_random_prepare_commit; extern int gbl_all_prepare_commit; diff --git a/db/db_tunables.h b/db/db_tunables.h index feab51d251..05d3e187c3 100644 --- a/db/db_tunables.h +++ b/db/db_tunables.h @@ -71,6 +71,8 @@ REGISTER_TUNABLE("analyze_tbl_threads", "generating index statistics. (Default: 5)", TUNABLE_INTEGER, &analyze_max_table_threads, READONLY, NULL, NULL, analyze_set_max_table_threads, NULL); +REGISTER_TUNABLE("always_reload_analyze", "Reload analyze data on every query. (Default: off)", TUNABLE_BOOLEAN, + &gbl_always_reload_analyze, 0, NULL, NULL, NULL, NULL); REGISTER_TUNABLE("archive_on_init", "Archive files with database extensions in the database directory " "at the time of init. (Default: ON)", @@ -943,11 +945,8 @@ REGISTER_TUNABLE("page_latches", TUNABLE_BOOLEAN, &gbl_page_latches, READONLY | NOARG, NULL, NULL, NULL, NULL); REGISTER_TUNABLE("pageordertablescan", "Perform table scans in page order and not row order. (Default: off)", TUNABLE_BOOLEAN, &gbl_page_order_table_scan, NOARG, NULL, NULL, page_order_table_scan_update, NULL); -/* -REGISTER_TUNABLE("pagesize", NULL, TUNABLE_INTEGER, - &placeholder, DEPRECATED_TUNABLE|READONLY, NULL, NULL, NULL, - NULL); -*/ +REGISTER_TUNABLE("llmeta_pagesize", "Init-option for llmeta and metadb pagesizes. (Default: 4096)", TUNABLE_INTEGER, + &gbl_llmeta_pagesize, READONLY | READEARLY, NULL, NULL, NULL, NULL); REGISTER_TUNABLE("parallel_recovery", NULL, TUNABLE_INTEGER, &gbl_parallel_recovery_threads, READONLY, NULL, NULL, NULL, NULL); diff --git a/db/sqlglue.c b/db/sqlglue.c index b0851021ae..89d15b91eb 100644 --- a/db/sqlglue.c +++ b/db/sqlglue.c @@ -13093,6 +13093,13 @@ int verify_dbstore_client_function(const char *dbstore) int rc = 0; strbuf *sql; + /* This deadlocks in replication. On the master, this is called + * from do_schema_change_tran_thd (prior to finalize). This thread + * calls do_alter_table with tran set to NULL, so no self-deadlock. */ + if (!bdb_iam_master(thedb->bdb_env) || gbl_is_physical_replicant) { + return 0; + } + sql = strbuf_new(); strbuf_appendf(sql, "TESTDEFAULT (%s)", dbstore); diff --git a/db/sqlinterfaces.c b/db/sqlinterfaces.c index f8dec761fa..146b05b9c5 100644 --- a/db/sqlinterfaces.c +++ b/db/sqlinterfaces.c @@ -2658,6 +2658,8 @@ static int reload_analyze(struct sqlthdstate *thd, struct sqlclntstate *clnt, thd->dbopen_gen, bdb_get_dbopen_gen(), thd->analyze_gen, \ cached_analyze_gen, thd->views_gen, gbl_views_gen); +int gbl_always_reload_analyze = 0; + // Call with schema_lk held and in_sqlite_init == 1 static int check_thd_gen(struct sqlthdstate *thd, struct sqlclntstate *clnt, int flags) { @@ -2675,7 +2677,7 @@ static int check_thd_gen(struct sqlthdstate *thd, struct sqlclntstate *clnt, int TRK; return SQLITE_SCHEMA; } - if (thd->analyze_gen != cached_analyze_gen) { + if ((thd->analyze_gen != cached_analyze_gen) || gbl_always_reload_analyze) { int ret; TRK; stmt_cache_reset(thd->stmt_cache); diff --git a/tests/sc_dbstore_func.test/lrl.options b/tests/sc_dbstore_func.test/lrl.options new file mode 100644 index 0000000000..834cfcec42 --- /dev/null +++ b/tests/sc_dbstore_func.test/lrl.options @@ -0,0 +1,4 @@ +# Force large pages in llmeta +llmeta_pagesize 65536 +always_reload_analyze 1 + diff --git a/tests/sc_dbstore_func.test/runit b/tests/sc_dbstore_func.test/runit index a9b9eb4150..dccebe065f 100755 --- a/tests/sc_dbstore_func.test/runit +++ b/tests/sc_dbstore_func.test/runit @@ -3,7 +3,7 @@ bash -n "$0" | exit 1 dbnm=$1 -cat << EOF | cdb2sql ${CDB2_OPTIONS} -tabs -s $dbnm default - >output.actual 2>&1 +cat << EOF | timeout -s 9 60s cdb2sql ${CDB2_OPTIONS} -tabs -s $dbnm default - >output.actual 2>&1 SELECT "- Testing dbstore now() -" CREATE TABLE t1 { tag ondisk { int i } }\$\$ INSERT INTO t1 VALUES (1) @@ -40,6 +40,25 @@ EOF diff output.actual output.expected +function verify_all_replicants() +{ + if [[ -z "$CLUSTER" ]]; then + return 0 + fi + + for node in $CLUSTER ; do + x=$(timeout -s 9 10s cdb2sql ${CDB2_OPTIONS} -tabs -s ${DBNAME} --host $node "select 1") + if [[ $? -ne 0 || "$x" != "1" ]]; then + echo "Failed to connect to $node" + exit 1 + fi + done +} + +# Alter again, and verify that we do not hang on replicants +timeout -s 9 20s cdb2sql ${CDB2_OPTIONS} -tabs $dbnm default "ALTER TABLE t1 { `cat t1_hang.csc2` }" +verify_all_replicants + # Make sure we can create a new db which specifies a client-function dbstore, # but that we fail to create a new db which has an invalid dbstore function. function create_database_with_table() diff --git a/tests/sc_dbstore_func.test/t1_hang.csc2 b/tests/sc_dbstore_func.test/t1_hang.csc2 new file mode 100644 index 0000000000..1e4a1fbd1d --- /dev/null +++ b/tests/sc_dbstore_func.test/t1_hang.csc2 @@ -0,0 +1,7 @@ +schema { + cstring s[33] dbstore={hex(GUID())} + datetime t dbstore={now()} null=yes + datetime t3 dbstore={now()} null=yes + datetime t4 dbstore={now()} null=yes + cstring s2[33] dbstore={hex(GUID())} null=yes +} diff --git a/tests/tunables.test/t00_all_tunables.expected b/tests/tunables.test/t00_all_tunables.expected index bc43b22fea..d360d323d3 100644 --- a/tests/tunables.test/t00_all_tunables.expected +++ b/tests/tunables.test/t00_all_tunables.expected @@ -42,6 +42,7 @@ (name='altersc_latency_inc', description='How many msec to add to altersc_queue_latency if altersc_latency_thr still reached', type='INTEGER', value='1000', read_only='N') (name='altersc_latency_thr', description='Threahoold for alter schema change impact on queue time, as msec/sec increase', type='INTEGER', value='5', read_only='N') (name='altersc_sampling_sec', description='Sample average of master queue time every this many seconds', type='INTEGER', value='5', read_only='N') +(name='always_reload_analyze', description='Reload analyze data on every query. (Default: off)', type='BOOLEAN', value='OFF', read_only='N') (name='always_send_cnonce', description='Always send cnonce to master. (Default: on)', type='BOOLEAN', value='ON', read_only='N') (name='analyze_comp_threads', description='Number of thread to use when generating samples for computing index statistics. (Default: 10)', type='INTEGER', value='10', read_only='Y') (name='analyze_comp_threshold', description='Index file size above which we'll do sampling, rather than scan the entire index. (Default: 104857600)', type='INTEGER', value='104857600', read_only='Y') @@ -456,6 +457,7 @@ (name='lkr_part', description='', type='INTEGER', value='23', read_only='Y') (name='llmeta', description='', type='BOOLEAN', value='ON', read_only='N') (name='llmeta_deadlock_poll', description='Max poll for llmeta on deadlock. (Default: 0ms)', type='INTEGER', value='0', read_only='N') +(name='llmeta_pagesize', description='Init-option for llmeta and metadb pagesizes. (Default: 4096)', type='INTEGER', value='0', read_only='Y') (name='load_cache_max_pages', description='Maximum number of pages that will load into cache. Setting to 0 means that there is no limit. (Default: 0)', type='INTEGER', value='0', read_only='N') (name='load_cache_threads', description='Number of threads loading pages to cache. (Default: 8)', type='INTEGER', value='8', read_only='N') (name='loadcache.dump_on_full', description='Dump status on full queue.', type='BOOLEAN', value='OFF', read_only='N')