summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-11-20 12:28:47 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-11-24 15:43:13 +0200
commit0bee3b8d651a15d3a498508782302e939a2e1af8 (patch)
tree1400c542dd320f73d672cca2d61042f92cbd1eb1
parentedbde4a11fd0b6437202f8019a79911441b6fb32 (diff)
downloadmariadb-git-0bee3b8d651a15d3a498508782302e939a2e1af8.tar.gz
Cleanup: Use Atomic_relaxed for dict_sys.row_id
-rw-r--r--storage/innobase/CMakeLists.txt1
-rw-r--r--storage/innobase/dict/dict0boot.cc33
-rw-r--r--storage/innobase/include/dict0boot.h64
-rw-r--r--storage/innobase/include/dict0boot.ic78
-rw-r--r--storage/innobase/include/dict0dict.h29
-rw-r--r--storage/innobase/row/row0import.cc10
-rw-r--r--storage/innobase/row/row0ins.cc19
7 files changed, 66 insertions, 168 deletions
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index 67b5b856e0f..f12e253d797 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -105,7 +105,6 @@ SET(INNOBASE_SOURCES
include/data0types.h
include/db0err.h
include/dict0boot.h
- include/dict0boot.ic
include/dict0crea.h
include/dict0crea.ic
include/dict0defrag_bg.h
diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc
index bd2cf4ffdd8..f4f94e2ace9 100644
--- a/storage/innobase/dict/dict0boot.cc
+++ b/storage/innobase/dict/dict0boot.cc
@@ -93,27 +93,16 @@ dict_hdr_get_new_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->frame;
+ if (mach_read_from_8(row_id) < id)
+ mtr.write<8>(*d, row_id, id);
+ mtr.commit();
}
/*****************************************************************//**
@@ -270,9 +259,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--;
diff --git a/storage/innobase/include/dict0boot.h b/storage/innobase/include/dict0boot.h
index 857342b18bd..fb9d5b810e2 100644
--- a/storage/innobase/include/dict0boot.h
+++ b/storage/innobase/include/dict0boot.h
@@ -46,27 +46,39 @@ dict_hdr_get_new_id(
(not assigned if NULL) */
ulint* space_id); /*!< out: space id
(not assigned if NULL) */
-/**********************************************************************//**
-Writes the current value of the row id counter to the dictionary header file
-page. */
-void
-dict_hdr_flush_row_id(void);
-/*=======================*/
-/**********************************************************************//**
-Returns a new row id.
-@return the new id */
-UNIV_INLINE
-row_id_t
-dict_sys_get_new_row_id(void);
-/*=========================*/
+/** Update dict_sys.row_id in the dictionary header file page. */
+void dict_hdr_flush_row_id(row_id_t id);
+/** @return A new value for GEN_CLUST_INDEX(DB_ROW_ID) */
+inline row_id_t dict_sys_t::get_new_row_id()
+{
+ row_id_t id= row_id.fetch_add(1);
+ if (!(id % ROW_ID_WRITE_MARGIN))
+ dict_hdr_flush_row_id(id);
+ return id;
+}
+
+/** Ensure that row_id is not smaller than id, on IMPORT TABLESPACE */
+inline void dict_sys_t::update_row_id(row_id_t id)
+{
+ row_id_t sys_id= row_id;
+ while (id >= sys_id)
+ {
+ if (!row_id.compare_exchange_strong(sys_id, id))
+ continue;
+ if (!(id % ROW_ID_WRITE_MARGIN))
+ dict_hdr_flush_row_id(id);
+ break;
+ }
+}
+
/**********************************************************************//**
Writes a row id to a record or other 6-byte stored form. */
-UNIV_INLINE
-void
-dict_sys_write_row_id(
-/*==================*/
- byte* field, /*!< in: record field */
- row_id_t row_id);/*!< in: row id */
+inline void dict_sys_write_row_id(byte *field, row_id_t row_id)
+{
+ static_assert(DATA_ROW_ID_LEN == 6, "compatibility");
+ mach_write_to_6(field, row_id);
+}
+
/*****************************************************************//**
Initializes the data dictionary memory structures when the database is
started. This function is also called when the data dictionary is created.
@@ -87,12 +99,7 @@ dict_create(void)
/*********************************************************************//**
Check if a table id belongs to system table.
@return true if the table id belongs to a system table. */
-UNIV_INLINE
-bool
-dict_is_sys_table(
-/*==============*/
- table_id_t id) /*!< in: table id to check */
- MY_ATTRIBUTE((warn_unused_result));
+inline bool dict_is_sys_table(table_id_t id) { return id < DICT_HDR_FIRST_ID; }
/* Space id and page no where the dictionary header resides */
#define DICT_HDR_SPACE 0 /* the SYSTEM tablespace */
@@ -289,11 +296,4 @@ length of thos fields. */
#define DICT_FLD_LEN_SPACE 4
#define DICT_FLD_LEN_FLAGS 4
-/* When a row id which is zero modulo this number (which must be a power of
-two) is assigned, the field DICT_HDR_ROW_ID on the dictionary header page is
-updated */
-#define DICT_HDR_ROW_ID_WRITE_MARGIN 256
-
-#include "dict0boot.ic"
-
#endif
diff --git a/storage/innobase/include/dict0boot.ic b/storage/innobase/include/dict0boot.ic
deleted file mode 100644
index d920bddecee..00000000000
--- a/storage/innobase/include/dict0boot.ic
+++ /dev/null
@@ -1,78 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2020, 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
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/dict0boot.ic
-Data dictionary creation and booting
-
-Created 4/18/1996 Heikki Tuuri
-*******************************************************/
-
-/**********************************************************************//**
-Returns a new row id.
-@return the new id */
-UNIV_INLINE
-row_id_t
-dict_sys_get_new_row_id(void)
-/*=========================*/
-{
- row_id_t id;
-
- mutex_enter(&dict_sys.mutex);
-
- id = dict_sys.row_id;
-
- if (0 == (id % DICT_HDR_ROW_ID_WRITE_MARGIN)) {
-
- dict_hdr_flush_row_id();
- }
-
- dict_sys.row_id++;
-
- mutex_exit(&dict_sys.mutex);
-
- return(id);
-}
-
-/**********************************************************************//**
-Writes a row id to a record or other 6-byte stored form. */
-UNIV_INLINE
-void
-dict_sys_write_row_id(
-/*==================*/
- byte* field, /*!< in: record field */
- row_id_t row_id) /*!< in: row id */
-{
- compile_time_assert(DATA_ROW_ID_LEN == 6);
- mach_write_to_6(field, row_id);
-}
-
-/*********************************************************************//**
-Check if a table id belongs to system table.
-@return true if the table id belongs to a system table. */
-UNIV_INLINE
-bool
-dict_is_sys_table(
-/*==============*/
- table_id_t id) /*!< in: table id to check */
-{
- return(id < DICT_HDR_FIRST_ID);
-}
-
-
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 2d347feb7d6..a6b01ab6c43 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -1416,12 +1416,6 @@ public:
and DROP TABLE, as well as reading
the dictionary data for a table from
system tables */
- row_id_t row_id; /*!< the next row id to assign;
- NOTE that at a checkpoint this
- must be written to the dict system
- header and flushed to a file; in
- recovery this must be derived from
- the log records */
hash_table_t table_hash; /*!< hash table of the tables, based
on name */
/** hash table of persistent table IDs */
@@ -1439,14 +1433,31 @@ public:
UT_LIST_BASE_NODE_T(dict_table_t)
table_non_LRU; /*!< List of tables that can't be
evicted from the cache */
+
private:
bool m_initialised= false;
/** the sequence of temporary table IDs */
std::atomic<table_id_t> temp_table_id{DICT_HDR_FIRST_ID};
-
- /** hash table of temporary table IDs */
- hash_table_t temp_id_hash;
+ /** hash table of temporary table IDs */
+ hash_table_t temp_id_hash;
+ /** the next value of DB_ROW_ID, backed by DICT_HDR_ROW_ID
+ (FIXME: remove this, and move to dict_table_t) */
+ Atomic_relaxed<row_id_t> row_id;
+ /** The synchronization interval of row_id */
+ static constexpr size_t ROW_ID_WRITE_MARGIN= 256;
public:
+ /** @return A new value for GEN_CLUST_INDEX(DB_ROW_ID) */
+ inline row_id_t get_new_row_id();
+
+ /** Ensure that row_id is not smaller than id, on IMPORT TABLESPACE */
+ inline void update_row_id(row_id_t id);
+
+ /** Recover the global DB_ROW_ID sequence on database startup */
+ void recover_row_id(row_id_t id)
+ {
+ row_id= ut_uint64_align_up(id, ROW_ID_WRITE_MARGIN) + ROW_ID_WRITE_MARGIN;
+ }
+
/** @return a new temporary table ID */
table_id_t get_temporary_table_id() {
return temp_table_id.fetch_add(1, std::memory_order_relaxed);
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index ad097f4472c..4accc5dd990 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -2396,15 +2396,7 @@ row_import_set_sys_max_row_id(
if (row_id) {
/* Update the system row id if the imported index row id is
greater than the max system row id. */
-
- mutex_enter(&dict_sys.mutex);
-
- if (row_id >= dict_sys.row_id) {
- dict_sys.row_id = row_id + 1;
- dict_hdr_flush_row_id();
- }
-
- mutex_exit(&dict_sys.mutex);
+ dict_sys.update_row_id(row_id);
}
}
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index b3f0a33cedc..b86f4fe34ce 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -3501,22 +3501,9 @@ row_ins_alloc_row_id_step(
/*======================*/
ins_node_t* node) /*!< in: row insert node */
{
- row_id_t row_id;
-
- ut_ad(node->state == INS_NODE_ALLOC_ROW_ID);
-
- if (dict_index_is_unique(dict_table_get_first_index(node->table))) {
-
- /* No row id is stored if the clustered index is unique */
-
- return;
- }
-
- /* Fill in row id value to row */
-
- row_id = dict_sys_get_new_row_id();
-
- dict_sys_write_row_id(node->sys_buf, row_id);
+ ut_ad(node->state == INS_NODE_ALLOC_ROW_ID);
+ if (dict_table_get_first_index(node->table)->is_gen_clust())
+ dict_sys_write_row_id(node->sys_buf, dict_sys.get_new_row_id());
}
/***********************************************************//**