Commit 0bee3b8d authored by Marko Mäkelä's avatar Marko Mäkelä

Cleanup: Use Atomic_relaxed for dict_sys.row_id

parent edbde4a1
......@@ -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
......
......@@ -93,26 +93,15 @@ 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);
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--;
......
......@@ -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
/*****************************************************************************
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);
}
......@@ -1416,12 +1416,6 @@ class dict_sys_t
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 @@ class dict_sys_t
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;
/** 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);
......
......@@ -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);
}
}
......
......@@ -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);
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());
}
/***********************************************************//**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment