diff --git a/bdb/llmeta.c b/bdb/llmeta.c index 8a006f76f8..9b5f5c47ea 100644 --- a/bdb/llmeta.c +++ b/bdb/llmeta.c @@ -118,7 +118,7 @@ typedef enum { data = no data does db use authentication? */ , - LLMETA_ACCESSCONTROL_TABLExNODE = 19 /* XXX Deprecated */ + LLMETA_ACCESSCONTROL_TABLExNODE = 19 /* XXX Deprecated */ , LLMETA_SQLITE_STAT1_PREV_DONT_USE = 20 /* store previous sqlite-stat1 records- dont use this. */ @@ -176,7 +176,8 @@ typedef enum { LLMETA_LUA_SFUNC_FLAG = 54, LLMETA_NEWSC_REDO_GENID = 55, /* 55 + TABLENAME + GENID -> MAX-LSN */ LLMETA_SCHEMACHANGE_STATUS_V2 = 56, - LLMETA_SCHEMACHANGE_LIST = 57, /* list of all sc-s in a uuid txh */ + LLMETA_SCHEMACHANGE_STATUS_VERSIONED = 57, + LLMETA_SCHEMACHANGE_LIST = 58, /* list of all sc-s in a uuid txh */ } llmetakey_t; struct llmeta_file_type_key { @@ -11336,14 +11337,18 @@ int bdb_del_view(tran_type *t, const char *view_name) coincide with the first 4 bytes of the rqid (fastseed) stored as the first member in old (7.0's) LLMETA_SCHEMACHANGE_STATUS payload. */ -static int buf_get_schemachange_key_type(void *p_buf, void *p_buf_end) +static int buf_get_schemachange_key_type(void *p_buf, void *p_buf_end, int *version) { int first = 0; if (p_buf >= p_buf_end) return -1; - buf_get(&first, sizeof(first), p_buf, p_buf_end); + p_buf = (void *)buf_get(&first, sizeof(first), p_buf, p_buf_end); + if (first == SC_VERSIONED) { + buf_get(version, sizeof(int), p_buf, p_buf_end); + return LLMETA_SCHEMACHANGE_STATUS_VERSIONED; + } if (first > SC_INVALID && first < SC_LAST) { return LLMETA_SCHEMACHANGE_STATUS_V2; } @@ -11353,9 +11358,18 @@ static int buf_get_schemachange_key_type(void *p_buf, void *p_buf_end) void *buf_get_schemachange(struct schema_change_type *s, void *p_buf, void *p_buf_end) { - int sc_key_type = buf_get_schemachange_key_type(p_buf, p_buf_end); + int version; + int sc_key_type = buf_get_schemachange_key_type(p_buf, p_buf_end, &version); switch (sc_key_type) { + case LLMETA_SCHEMACHANGE_STATUS_VERSIONED: + if (version == 2) { + p_buf = p_buf + sizeof(int) + sizeof(int); + return buf_get_schemachange_v2(s, (void *)p_buf, (void *)p_buf_end); + } else { + logmsg(LOGMSG_FATAL, "%s: unknown version %d\n", __func__, version); + abort(); + } case LLMETA_SCHEMACHANGE_STATUS: return buf_get_schemachange_v1(s, (void *)p_buf, (void *)p_buf_end); case LLMETA_SCHEMACHANGE_STATUS_V2: diff --git a/db/config.c b/db/config.c index 0d6d84eb74..166e093e51 100644 --- a/db/config.c +++ b/db/config.c @@ -447,6 +447,8 @@ static char *legacy_options[] = { "setattr max_sql_idle_time 864000", "retrieve_gen_from_ckp 0", "recovery_ckp 0", + "sc_versioned 0", + "sc_current_version 2", }; // clang-format on diff --git a/db/db_tunables.c b/db/db_tunables.c index 970fc7d480..2ea1d34297 100644 --- a/db/db_tunables.c +++ b/db/db_tunables.c @@ -304,6 +304,8 @@ extern int gbl_memp_dump_cache_threshold; extern int gbl_disable_ckp; extern int gbl_abort_on_illegal_log_put; extern int gbl_sc_close_txn; +extern int gbl_sc_versioned; +extern int gbl_sc_current_version; extern int gbl_master_sends_query_effects; extern int gbl_create_dba_user; extern int gbl_lock_dba_user; diff --git a/db/db_tunables.h b/db/db_tunables.h index 859811a2ee..3251e790cf 100644 --- a/db/db_tunables.h +++ b/db/db_tunables.h @@ -2385,6 +2385,10 @@ REGISTER_TUNABLE("wal_osync", "Open WAL files using the O_SYNC flag (Default: of NULL, NULL, NULL, NULL); REGISTER_TUNABLE("sc_headroom", "Percentage threshold for low headroom calculation. (Default: 10)", TUNABLE_DOUBLE, &gbl_sc_headroom, INTERNAL | SIGNED, NULL, NULL, NULL, NULL); +REGISTER_TUNABLE("sc_versioned", "Enable versioned schema changes (Default: on)", TUNABLE_BOOLEAN, &gbl_sc_versioned, 0, + NULL, NULL, NULL, NULL); +REGISTER_TUNABLE("sc_current_version", "Current schema-change version (Default: 2)", TUNABLE_INTEGER, + &gbl_sc_current_version, 0, NULL, NULL, NULL, NULL); REGISTER_TUNABLE("fdb_incoherence_percentage", "Generate random incoherent errors in remsql", TUNABLE_INTEGER, &gbl_fdb_incoherence_percentage, INTERNAL, NULL, percent_verify, NULL, NULL); REGISTER_TUNABLE("fdb_socket_timeout_ms", "Timeout ms for fdb communications. (Default: 10000)", TUNABLE_INTEGER, diff --git a/schemachange/sc_struct.c b/schemachange/sc_struct.c index 51af9ca502..aee7bd234f 100644 --- a/schemachange/sc_struct.c +++ b/schemachange/sc_struct.c @@ -132,6 +132,10 @@ static size_t _partition_packed_size(struct comdb2_partition *p) } } +/* When changing, increment & set legacy-defaults to old */ +int gbl_sc_current_version = 2; +int gbl_sc_versioned = 1; + size_t schemachange_packed_size(struct schema_change_type *s) { s->tablename_len = strlen(s->tablename) + 1; @@ -161,6 +165,15 @@ size_t schemachange_packed_size(struct schema_change_type *s) sizeof(s->usedbtablevers) + sizeof(s->qdb_file_ver) + _partition_packed_size(&s->partition); + if (gbl_sc_versioned) { + /* + if (sc_current_version == 3) { + s->packed_len += XXXX; + } + */ + s->packed_len += 8; + } + return s->packed_len; } @@ -189,6 +202,13 @@ void *buf_put_schemachange(struct schema_change_type *s, void *p_buf, void *p_bu if (p_buf >= p_buf_end) return NULL; + /* To change, increment SC_VERSION, and create new buf_get_schemachange_v[X] */ + if (gbl_sc_versioned) { + int neg1 = -1, vers = gbl_sc_current_version; + p_buf = buf_put(&neg1, sizeof(neg1), p_buf, p_buf_end); + p_buf = buf_put(&vers, sizeof(vers), p_buf, p_buf_end); + } + p_buf = buf_put(&s->kind, sizeof(s->kind), p_buf, p_buf_end); p_buf = buf_put(&s->rqid, sizeof(s->rqid), p_buf, p_buf_end); diff --git a/schemachange/schemachange.h b/schemachange/schemachange.h index 54cc2d3ee2..bae5a48666 100644 --- a/schemachange/schemachange.h +++ b/schemachange/schemachange.h @@ -90,6 +90,7 @@ struct timepart_view; /* in sync with do_schema_change_if */ enum schema_change_kind { + SC_VERSIONED = -1, SC_INVALID = 0, SC_LEGACY_QUEUE = 1, SC_LEGACY_MORESTRIPE = 2,