diff options
Diffstat (limited to 'storage/innobase/dict/dict0boot.cc')
-rw-r--r-- | storage/innobase/dict/dict0boot.cc | 288 |
1 files changed, 117 insertions, 171 deletions
diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc index 1414f21221f..e57121041d5 100644 --- a/storage/innobase/dict/dict0boot.cc +++ b/storage/innobase/dict/dict0boot.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2020, MariaDB Corporation. +Copyright (c) 2016, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -35,13 +35,14 @@ Created 4/18/1996 Heikki Tuuri #include "log0recv.h" #include "os0file.h" +/** The DICT_HDR page identifier */ +static constexpr page_id_t hdr_page_id{DICT_HDR_SPACE, DICT_HDR_PAGE_NO}; + /** @return the DICT_HDR block, x-latched */ -buf_block_t *dict_hdr_get(mtr_t* mtr) +static buf_block_t *dict_hdr_get(mtr_t *mtr) { - buf_block_t *block= buf_page_get(page_id_t(DICT_HDR_SPACE, DICT_HDR_PAGE_NO), - 0, RW_X_LATCH, mtr); - buf_block_dbg_add_level(block, SYNC_DICT_HEADER); - return block; + /* We assume that the DICT_HDR page is always readable and available. */ + return buf_page_get_gen(hdr_page_id, 0, RW_X_LATCH, nullptr, BUF_GET, mtr); } /**********************************************************************//** @@ -64,97 +65,83 @@ dict_hdr_get_new_id( if (table_id) { id = mach_read_from_8(DICT_HDR + DICT_HDR_TABLE_ID - + dict_hdr->frame); + + dict_hdr->page.frame); id++; mtr.write<8>(*dict_hdr, DICT_HDR + DICT_HDR_TABLE_ID - + dict_hdr->frame, id); + + dict_hdr->page.frame, id); *table_id = id; } if (index_id) { id = mach_read_from_8(DICT_HDR + DICT_HDR_INDEX_ID - + dict_hdr->frame); + + dict_hdr->page.frame); id++; mtr.write<8>(*dict_hdr, DICT_HDR + DICT_HDR_INDEX_ID - + dict_hdr->frame, id); + + dict_hdr->page.frame, id); *index_id = id; } if (space_id) { *space_id = mach_read_from_4(DICT_HDR + DICT_HDR_MAX_SPACE_ID - + dict_hdr->frame); + + dict_hdr->page.frame); if (fil_assign_new_space_id(space_id)) { mtr.write<4>(*dict_hdr, DICT_HDR + DICT_HDR_MAX_SPACE_ID - + dict_hdr->frame, *space_id); + + dict_hdr->page.frame, *space_id); } } mtr.commit(); } -/**********************************************************************//** -Writes the current value of the row id counter to the dictionary header file -page. */ -void -dict_hdr_flush_row_id(void) -/*=======================*/ +/** Update dict_sys.row_id in the dictionary header file page. */ +void dict_hdr_flush_row_id(row_id_t id) { - row_id_t id; - mtr_t mtr; - - ut_ad(mutex_own(&dict_sys.mutex)); - - id = dict_sys.row_id; - - mtr.start(); - - buf_block_t* d = dict_hdr_get(&mtr); - - mtr.write<8>(*d, DICT_HDR + DICT_HDR_ROW_ID + d->frame, id); - - mtr.commit(); + mtr_t mtr; + mtr.start(); + buf_block_t* d= dict_hdr_get(&mtr); + byte *row_id= DICT_HDR + DICT_HDR_ROW_ID + d->page.frame; + if (mach_read_from_8(row_id) < id) + mtr.write<8>(*d, row_id, id); + mtr.commit(); } -/*****************************************************************//** -Creates the file page for the dictionary header. This function is -called only at the database creation. -@return TRUE if succeed */ -static -ibool -dict_hdr_create( -/*============*/ - mtr_t* mtr) /*!< in: mtr */ +/** Create the DICT_HDR page on database initialization. +@return error code */ +dberr_t dict_create() { - buf_block_t* block; ulint root_page_no; - ut_ad(mtr); + dberr_t err; + mtr_t mtr; + mtr.start(); compile_time_assert(DICT_HDR_SPACE == 0); /* Create the dictionary header file block in a new, allocated file segment in the system tablespace */ - block = fseg_create(fil_system.sys_space, - DICT_HDR + DICT_HDR_FSEG_HEADER, mtr); - - ut_a(block->page.id() == page_id_t(DICT_HDR_SPACE, DICT_HDR_PAGE_NO)); - - buf_block_t* d = dict_hdr_get(mtr); + buf_block_t* d = fseg_create(fil_system.sys_space, + DICT_HDR + DICT_HDR_FSEG_HEADER, &mtr, + &err); + if (!d) { + goto func_exit; + } + ut_a(d->page.id() == hdr_page_id); /* Start counting row, table, index, and tree ids from DICT_HDR_FIRST_ID */ - mtr->write<8>(*d, DICT_HDR + DICT_HDR_ROW_ID + d->frame, - DICT_HDR_FIRST_ID); - mtr->write<8>(*d, DICT_HDR + DICT_HDR_TABLE_ID + d->frame, - DICT_HDR_FIRST_ID); - mtr->write<8>(*d, DICT_HDR + DICT_HDR_INDEX_ID + d->frame, - DICT_HDR_FIRST_ID); + mtr.write<8>(*d, DICT_HDR + DICT_HDR_ROW_ID + d->page.frame, + DICT_HDR_FIRST_ID); + mtr.write<8>(*d, DICT_HDR + DICT_HDR_TABLE_ID + d->page.frame, + DICT_HDR_FIRST_ID); + mtr.write<8>(*d, DICT_HDR + DICT_HDR_INDEX_ID + d->page.frame, + DICT_HDR_FIRST_ID); - ut_ad(!mach_read_from_4(DICT_HDR + DICT_HDR_MAX_SPACE_ID + d->frame)); + ut_ad(!mach_read_from_4(DICT_HDR + DICT_HDR_MAX_SPACE_ID + + d->page.frame)); /* Obsolete, but we must initialize it anyway. */ - mtr->write<4>(*d, DICT_HDR + DICT_HDR_MIX_ID_LOW + d->frame, - DICT_HDR_FIRST_ID); + mtr.write<4>(*d, DICT_HDR + DICT_HDR_MIX_ID_LOW + d->page.frame, + DICT_HDR_FIRST_ID); /* Create the B-tree roots for the clustered indexes of the basic system tables */ @@ -162,103 +149,102 @@ dict_hdr_create( /*--------------------------*/ root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, fil_system.sys_space, DICT_TABLES_ID, - nullptr, mtr); + nullptr, &mtr, &err); if (root_page_no == FIL_NULL) { - - return(FALSE); + goto func_exit; } - mtr->write<4>(*d, DICT_HDR + DICT_HDR_TABLES + d->frame, root_page_no); + mtr.write<4>(*d, DICT_HDR + DICT_HDR_TABLES + d->page.frame, + root_page_no); /*--------------------------*/ root_page_no = btr_create(DICT_UNIQUE, fil_system.sys_space, DICT_TABLE_IDS_ID, - nullptr, mtr); + nullptr, &mtr, &err); if (root_page_no == FIL_NULL) { - - return(FALSE); + goto func_exit; } - mtr->write<4>(*d, DICT_HDR + DICT_HDR_TABLE_IDS + d->frame, - root_page_no); + mtr.write<4>(*d, DICT_HDR + DICT_HDR_TABLE_IDS + d->page.frame, + root_page_no); /*--------------------------*/ root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, fil_system.sys_space, DICT_COLUMNS_ID, - nullptr, mtr); + nullptr, &mtr, &err); if (root_page_no == FIL_NULL) { - - return(FALSE); + goto func_exit; } - mtr->write<4>(*d, DICT_HDR + DICT_HDR_COLUMNS + d->frame, - root_page_no); + mtr.write<4>(*d, DICT_HDR + DICT_HDR_COLUMNS + d->page.frame, + root_page_no); /*--------------------------*/ root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, fil_system.sys_space, DICT_INDEXES_ID, - nullptr, mtr); + nullptr, &mtr, &err); if (root_page_no == FIL_NULL) { - - return(FALSE); + goto func_exit; } - mtr->write<4>(*d, DICT_HDR + DICT_HDR_INDEXES + d->frame, - root_page_no); + mtr.write<4>(*d, DICT_HDR + DICT_HDR_INDEXES + d->page.frame, + root_page_no); /*--------------------------*/ root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE, fil_system.sys_space, DICT_FIELDS_ID, - nullptr, mtr); + nullptr, &mtr, &err); if (root_page_no == FIL_NULL) { - - return(FALSE); + goto func_exit; } - mtr->write<4>(*d, DICT_HDR + DICT_HDR_FIELDS + d->frame, root_page_no); - /*--------------------------*/ - - return(TRUE); + mtr.write<4>(*d, DICT_HDR + DICT_HDR_FIELDS + d->page.frame, + root_page_no); +func_exit: + mtr.commit(); + return err ? err : dict_boot(); } /*****************************************************************//** Initializes the data dictionary memory structures when the database is started. This function is also called when the data dictionary is created. @return DB_SUCCESS or error code. */ -dberr_t -dict_boot(void) -/*===========*/ +dberr_t dict_boot() { dict_table_t* table; dict_index_t* index; mem_heap_t* heap; mtr_t mtr; - /* Be sure these constants do not ever change. To avoid bloat, - only check the *NUM_FIELDS* in each table */ - - ut_ad(DICT_NUM_COLS__SYS_TABLES == 8); - ut_ad(DICT_NUM_FIELDS__SYS_TABLES == 10); - ut_ad(DICT_NUM_FIELDS__SYS_TABLE_IDS == 2); - ut_ad(DICT_NUM_COLS__SYS_COLUMNS == 7); - ut_ad(DICT_NUM_FIELDS__SYS_COLUMNS == 9); - ut_ad(DICT_NUM_COLS__SYS_INDEXES == 8); - ut_ad(DICT_NUM_FIELDS__SYS_INDEXES == 10); - ut_ad(DICT_NUM_COLS__SYS_FIELDS == 3); - ut_ad(DICT_NUM_FIELDS__SYS_FIELDS == 5); - ut_ad(DICT_NUM_COLS__SYS_FOREIGN == 4); - ut_ad(DICT_NUM_FIELDS__SYS_FOREIGN == 6); - ut_ad(DICT_NUM_FIELDS__SYS_FOREIGN_FOR_NAME == 2); - ut_ad(DICT_NUM_COLS__SYS_FOREIGN_COLS == 4); - ut_ad(DICT_NUM_FIELDS__SYS_FOREIGN_COLS == 6); - - mtr_start(&mtr); + static_assert(DICT_NUM_COLS__SYS_TABLES == 8, "compatibility"); + static_assert(DICT_NUM_FIELDS__SYS_TABLES == 10, "compatibility"); + static_assert(DICT_NUM_FIELDS__SYS_TABLE_IDS == 2, "compatibility"); + static_assert(DICT_NUM_COLS__SYS_COLUMNS == 7, "compatibility"); + static_assert(DICT_NUM_FIELDS__SYS_COLUMNS == 9, "compatibility"); + static_assert(DICT_NUM_COLS__SYS_INDEXES == 8, "compatibility"); + static_assert(DICT_NUM_FIELDS__SYS_INDEXES == 10, "compatibility"); + static_assert(DICT_NUM_COLS__SYS_FIELDS == 3, "compatibility"); + static_assert(DICT_NUM_FIELDS__SYS_FIELDS == 5, "compatibility"); + static_assert(DICT_NUM_COLS__SYS_FOREIGN == 4, "compatibility"); + static_assert(DICT_NUM_FIELDS__SYS_FOREIGN == 6, "compatibility"); + static_assert(DICT_NUM_FIELDS__SYS_FOREIGN_FOR_NAME == 2, + "compatibility"); + static_assert(DICT_NUM_COLS__SYS_FOREIGN_COLS == 4, "compatibility"); + static_assert(DICT_NUM_FIELDS__SYS_FOREIGN_COLS == 6, "compatibility"); + mtr.start(); /* Create the hash tables etc. */ dict_sys.create(); + dberr_t err; + const buf_block_t *d = buf_page_get_gen(hdr_page_id, 0, RW_X_LATCH, + nullptr, BUF_GET, &mtr, &err); + if (!d) { + mtr.commit(); + return err; + } + heap = mem_heap_create(450); - mutex_enter(&dict_sys.mutex); + dict_sys.lock(SRW_LOCK_CALL); - /* Get the dictionary header */ - const byte* dict_hdr = &dict_hdr_get(&mtr)->frame[DICT_HDR]; + const byte* dict_hdr = &d->page.frame[DICT_HDR]; /* Because we only write new row ids to disk-based data structure (dictionary header) when it is divisible by @@ -270,9 +256,7 @@ dict_boot(void) ..._MARGIN, it will immediately be updated to the disk-based header. */ - dict_sys.row_id = DICT_HDR_ROW_ID_WRITE_MARGIN - + ut_uint64_align_up(mach_read_from_8(dict_hdr + DICT_HDR_ROW_ID), - DICT_HDR_ROW_ID_WRITE_MARGIN); + dict_sys.recover_row_id(mach_read_from_8(dict_hdr + DICT_HDR_ROW_ID)); if (ulint max_space_id = mach_read_from_4(dict_hdr + DICT_HDR_MAX_SPACE_ID)) { max_space_id--; @@ -282,9 +266,9 @@ dict_boot(void) /* Insert into the dictionary cache the descriptions of the basic system tables */ /*-------------------------*/ - table = dict_mem_table_create("SYS_TABLES", fil_system.sys_space, - 8, 0, 0, 0); - + table = dict_table_t::create(dict_sys.SYS_TABLE[dict_sys.SYS_TABLES], + fil_system.sys_space, + DICT_NUM_COLS__SYS_TABLES, 0, 0, 0); dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, MAX_FULL_NAME_LEN); dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 8); @@ -313,7 +297,7 @@ dict_boot(void) dict_mem_index_add_field(index, "NAME", 0); index->id = DICT_TABLES_ID; - dberr_t err = dict_index_add_to_cache( + err = dict_index_add_to_cache( index, mach_read_from_4(dict_hdr + DICT_HDR_TABLES)); ut_a(err == DB_SUCCESS); ut_ad(!table->is_instant()); @@ -330,9 +314,9 @@ dict_boot(void) ut_a(err == DB_SUCCESS); /*-------------------------*/ - table = dict_mem_table_create("SYS_COLUMNS", fil_system.sys_space, - 7, 0, 0, 0); - + table = dict_table_t::create(dict_sys.SYS_TABLE[dict_sys.SYS_COLUMNS], + fil_system.sys_space, + DICT_NUM_COLS__SYS_COLUMNS, 0, 0, 0); dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 8); dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4); dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0); @@ -363,16 +347,16 @@ dict_boot(void) UT_BITS_IN_BYTES(unsigned(table->indexes.start->n_nullable))); /*-------------------------*/ - table = dict_mem_table_create("SYS_INDEXES", fil_system.sys_space, - DICT_NUM_COLS__SYS_INDEXES, 0, 0, 0); + table = dict_table_t::create(dict_sys.SYS_TABLE[dict_sys.SYS_INDEXES], + fil_system.sys_space, + DICT_NUM_COLS__SYS_INDEXES, 0, 0, 0); dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 8); dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 8); dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0); dict_mem_table_add_col(table, heap, "N_FIELDS", DATA_INT, 0, 4); dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4); - /* SYS_INDEXES.SPACE is redundant and not being read; - SYS_TABLES.SPACE is being used instead. */ + /* SYS_INDEXES.SPACE is only read by in dict_drop_index_tree() */ dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4); dict_mem_table_add_col(table, heap, "PAGE_NO", DATA_INT, 0, 4); dict_mem_table_add_col(table, heap, "MERGE_THRESHOLD", DATA_INT, 0, 4); @@ -406,9 +390,9 @@ dict_boot(void) UT_BITS_IN_BYTES(unsigned(table->indexes.start->n_nullable))); /*-------------------------*/ - table = dict_mem_table_create("SYS_FIELDS", fil_system.sys_space, - 3, 0, 0, 0); - + table = dict_table_t::create(dict_sys.SYS_TABLE[dict_sys.SYS_FIELDS], + fil_system.sys_space, + DICT_NUM_COLS__SYS_FIELDS, 0, 0, 0); dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 8); dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4); dict_mem_table_add_col(table, heap, "COL_NAME", DATA_BINARY, 0, 0); @@ -434,16 +418,11 @@ dict_boot(void) table->indexes.start->n_core_null_bytes = static_cast<uint8_t>( UT_BITS_IN_BYTES(unsigned(table->indexes.start->n_nullable))); - mtr_commit(&mtr); - - /*-------------------------*/ - - /* Initialize the insert buffer table and index for each tablespace */ + mtr.commit(); err = ibuf_init_at_db_start(); - if (err == DB_SUCCESS - || srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { + if (err == DB_SUCCESS || srv_force_recovery >= SRV_FORCE_NO_DDL_UNDO) { err = DB_SUCCESS; /* Load definitions of other indexes on system tables */ @@ -451,44 +430,11 @@ dict_boot(void) dict_load_sys_table(dict_sys.sys_columns); dict_load_sys_table(dict_sys.sys_indexes); dict_load_sys_table(dict_sys.sys_fields); + dict_sys.unlock(); + dict_sys.load_sys_tables(); + } else { + dict_sys.unlock(); } - mutex_exit(&dict_sys.mutex); - - return(err); -} - -/*****************************************************************//** -Inserts the basic system table data into themselves in the database -creation. */ -static -void -dict_insert_initial_data(void) -/*==========================*/ -{ - /* Does nothing yet */ -} - -/*****************************************************************//** -Creates and initializes the data dictionary at the server bootstrap. -@return DB_SUCCESS or error code. */ -dberr_t -dict_create(void) -/*=============*/ -{ - mtr_t mtr; - - mtr_start(&mtr); - - dict_hdr_create(&mtr); - - mtr_commit(&mtr); - - dberr_t err = dict_boot(); - - if (err == DB_SUCCESS) { - dict_insert_initial_data(); - } - - return(err); + return err; } |