Skip to content

Commit cc6a705

Browse files
committed
Bug#35410528 : INSTANT DDL crashes 8.0.32 after upgrading from 5.7.41
Background: When tables are loaded in mem cache (dict_table_t) they go through fill_dict_table() which makes sure all in mem metadata is updated for the tables correctly. But in case of upgrade from 5.7, tables are loaded in dict_table_t cache from dict_load_table(). And then it remains in cache to be used. Issue: During upgrade, when the table is loaded from dict_load_table(), it doesn't set the initial/current/total/_column_count metadata of dict_table_t. Which causes issues when table is used after INSTANT ADD/DROP DDL. Note this is done only once and next server restarts, the table is loaded from fill_dict_table() function. And this is why if there is a restart after upgrade, the issue is not seen. Fix: Made sure when the table is loaded from dict_load_table() during upgrade, the column count metadata is also set correctly. Change-Id: I7729a9e03683737bfe8b3025203f31551b710f70
1 parent e8db2e7 commit cc6a705

File tree

2 files changed

+28
-28
lines changed

2 files changed

+28
-28
lines changed

storage/innobase/dict/dict0load.cc

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,56 +1621,48 @@ static inline space_id_t dict_check_sys_tables(bool validate) {
16211621
return max_space_id;
16221622
}
16231623

1624-
/** Loads definitions for table columns. */
1625-
static void dict_load_columns(dict_table_t *table, /*!< in/out: table */
1626-
mem_heap_t *heap) /*!< in/out: memory heap
1627-
for temporary storage */
1628-
{
1629-
dict_table_t *sys_columns;
1630-
dict_index_t *sys_index;
1631-
btr_pcur_t pcur;
1632-
dtuple_t *tuple;
1633-
dfield_t *dfield;
1634-
const rec_t *rec;
1635-
byte *buf;
1636-
ulint i;
1637-
mtr_t mtr;
1638-
ulint n_skipped = 0;
1639-
1624+
/** Load columns in an innodb cached table object from SYS_COLUMNS table.
1625+
@param[in, out] table Table cache object
1626+
@param[in, out] heap memory heap for temporary storage */
1627+
static void dict_load_columns(dict_table_t *table, mem_heap_t *heap) {
16401628
ut_ad(dict_sys_mutex_own());
16411629

1630+
mtr_t mtr;
16421631
mtr_start(&mtr);
16431632

1644-
sys_columns = dict_table_get_low("SYS_COLUMNS");
1645-
sys_index = UT_LIST_GET_FIRST(sys_columns->indexes);
1633+
dict_table_t *sys_columns = dict_table_get_low("SYS_COLUMNS");
1634+
dict_index_t *sys_index = UT_LIST_GET_FIRST(sys_columns->indexes);
16461635
ut_ad(!dict_table_is_comp(sys_columns));
16471636

16481637
ut_ad(name_of_col_is(sys_columns, sys_index, DICT_FLD__SYS_COLUMNS__NAME,
16491638
"NAME"));
16501639
ut_ad(name_of_col_is(sys_columns, sys_index, DICT_FLD__SYS_COLUMNS__PREC,
16511640
"PREC"));
16521641

1653-
tuple = dtuple_create(heap, 1);
1654-
dfield = dtuple_get_nth_field(tuple, 0);
1642+
dtuple_t *tuple = dtuple_create(heap, 1);
1643+
dfield_t *dfield = dtuple_get_nth_field(tuple, 0);
16551644

1656-
buf = static_cast<byte *>(mem_heap_alloc(heap, 8));
1645+
byte *buf = static_cast<byte *>(mem_heap_alloc(heap, 8));
16571646
mach_write_to_8(buf, table->id);
16581647

16591648
dfield_set_data(dfield, buf, 8);
16601649
dict_index_copy_types(tuple, sys_index, 1);
16611650

1651+
btr_pcur_t pcur;
16621652
pcur.open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, BTR_SEARCH_LEAF, &mtr,
16631653
UT_LOCATION_HERE);
16641654

16651655
ut_ad(table->n_t_cols == static_cast<ulint>(table->n_cols) +
16661656
static_cast<ulint>(table->n_v_cols));
16671657

1668-
for (i = 0; i + DATA_N_SYS_COLS < table->n_t_cols + n_skipped; i++) {
1658+
size_t non_v_cols = 0;
1659+
size_t n_skipped = 0;
1660+
for (size_t i = 0; i + DATA_N_SYS_COLS < table->n_t_cols + n_skipped; i++) {
16691661
const char *err_msg;
16701662
const char *name = nullptr;
16711663
ulint nth_v_col = ULINT_UNDEFINED;
16721664

1673-
rec = pcur.get_rec();
1665+
const rec_t *rec = pcur.get_rec();
16741666

16751667
ut_a(pcur.is_on_user_rec());
16761668

@@ -1684,6 +1676,11 @@ static void dict_load_columns(dict_table_t *table, /*!< in/out: table */
16841676
ib::fatal(UT_LOCATION_HERE, ER_IB_MSG_195) << err_msg;
16851677
}
16861678

1679+
if (nth_v_col == ULINT_UNDEFINED) {
1680+
/* Not a virtual column */
1681+
non_v_cols++;
1682+
}
1683+
16871684
/* Note: Currently we have one DOC_ID column that is
16881685
shared by all FTS indexes on a table. And only non-virtual
16891686
column can be used for FULLTEXT index */
@@ -1727,6 +1724,11 @@ static void dict_load_columns(dict_table_t *table, /*!< in/out: table */
17271724

17281725
pcur.close();
17291726
mtr_commit(&mtr);
1727+
1728+
/* The table is getting upgraded from 5.7 where there was no row version */
1729+
table->initial_col_count = table->current_col_count = table->total_col_count =
1730+
non_v_cols;
1731+
table->current_row_version = 0;
17301732
}
17311733

17321734
/** Loads definitions for index fields.

storage/innobase/include/dict0mem.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,7 @@ struct dict_table_t {
21322132
uint32_t total_col_count{0};
21332133

21342134
/** Set if table is upgraded instant table */
2135-
unsigned m_upgraded_instant : 1;
2135+
bool m_upgraded_instant{false};
21362136

21372137
/** table dynamic metadata status, protected by dict_persist->mutex */
21382138
std::atomic<table_dirty_status> dirty_status;
@@ -2531,13 +2531,11 @@ detect this and will eventually quit sooner. */
25312531
bool has_instant_drop_cols() const { return (get_n_instant_drop_cols() > 0); }
25322532

25332533
/** Set table to be upgraded table with INSTANT ADD columns in V1. */
2534-
void set_upgraded_instant() { m_upgraded_instant = 1; }
2534+
void set_upgraded_instant() { m_upgraded_instant = true; }
25352535

25362536
/** Checks if table is upgraded table with INSTANT ADD columns in V1.
25372537
@return true if it is, false otherwise */
2538-
bool is_upgraded_instant() const {
2539-
return (m_upgraded_instant == 1) ? true : false;
2540-
}
2538+
bool is_upgraded_instant() const { return m_upgraded_instant; }
25412539

25422540
/** Check whether the table is corrupted.
25432541
@return true if the table is corrupted, otherwise false */

0 commit comments

Comments
 (0)