summaryrefslogtreecommitdiff
path: root/storage/innobase/include/dict0dict.ic
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/dict0dict.ic')
-rw-r--r--storage/innobase/include/dict0dict.ic328
1 files changed, 292 insertions, 36 deletions
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index f6585ea8205..83953c9325a 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -29,6 +29,7 @@ Created 1/8/1996 Heikki Tuuri
#include "rem0types.h"
#include "fsp0fsp.h"
#include "srv0srv.h"
+#include "sync0rw.h" /* RW_S_LATCH */
/*********************************************************************//**
Gets the minimum number of bytes per character.
@@ -223,6 +224,22 @@ dict_table_get_first_index(
}
/********************************************************************//**
+Gets the last index on the table.
+@return index, NULL if none exists */
+UNIV_INLINE
+dict_index_t*
+dict_table_get_last_index(
+/*=======================*/
+ const dict_table_t* table) /*!< in: table */
+{
+ ut_ad(table);
+ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
+
+ return(UT_LIST_GET_LAST((const_cast<dict_table_t*>(table))
+ ->indexes));
+}
+
+/********************************************************************//**
Gets the next index on the table.
@return index, NULL if none left */
UNIV_INLINE
@@ -365,6 +382,56 @@ dict_table_get_n_cols(
return(table->n_cols);
}
+/********************************************************************//**
+Gets the approximately estimated number of rows in the table.
+@return estimated number of rows */
+UNIV_INLINE
+ib_uint64_t
+dict_table_get_n_rows(
+/*==================*/
+ const dict_table_t* table) /*!< in: table */
+{
+ ut_ad(table->stat_initialized);
+
+ return(table->stat_n_rows);
+}
+
+/********************************************************************//**
+Increment the number of rows in the table by one.
+Notice that this operation is not protected by any latch, the number is
+approximate. */
+UNIV_INLINE
+void
+dict_table_n_rows_inc(
+/*==================*/
+ dict_table_t* table) /*!< in/out: table */
+{
+ if (table->stat_initialized) {
+ ib_uint64_t n_rows = table->stat_n_rows;
+ if (n_rows < 0xFFFFFFFFFFFFFFFFULL) {
+ table->stat_n_rows = n_rows + 1;
+ }
+ }
+}
+
+/********************************************************************//**
+Decrement the number of rows in the table by one.
+Notice that this operation is not protected by any latch, the number is
+approximate. */
+UNIV_INLINE
+void
+dict_table_n_rows_dec(
+/*==================*/
+ dict_table_t* table) /*!< in/out: table */
+{
+ if (table->stat_initialized) {
+ ib_uint64_t n_rows = table->stat_n_rows;
+ if (n_rows > 0) {
+ table->stat_n_rows = n_rows - 1;
+ }
+ }
+}
+
#ifdef UNIV_DEBUG
/********************************************************************//**
Gets the nth column of a table.
@@ -458,12 +525,11 @@ dict_table_has_fts_index(
}
/********************************************************************//**
-Validate and return the table flags.
-@return Same as input after validating it as dict_table_t::flags.
-If there is an error, trigger assertion failure. */
+Validate the table flags.
+@return true if valid. */
UNIV_INLINE
-ulint
-dict_tf_validate(
+bool
+dict_tf_is_valid(
/*=============*/
ulint flags) /*!< in: table flags */
{
@@ -473,31 +539,43 @@ dict_tf_validate(
ulint unused = DICT_TF_GET_UNUSED(flags);
/* Make sure there are no bits that we do not know about. */
- ut_a(unused == 0);
+ if (unused != 0) {
- if (atomic_blobs) {
+ return(false);
+
+ } else if (atomic_blobs) {
/* Barracuda row formats COMPRESSED and DYNAMIC build on
the page structure introduced for the COMPACT row format
by allowing keys in secondary indexes to be made from
data stored off-page in the clustered index. */
- ut_a(compact);
- } else {
+
+ if (!compact) {
+ return(false);
+ }
+
+ } else if (zip_ssize) {
+
/* Antelope does not support COMPRESSED row format. */
- ut_a(!zip_ssize);
+ return(false);
}
if (zip_ssize) {
+
/* COMPRESSED row format must have compact and atomic_blobs
- bits set. */
- ut_a(compact);
- ut_a(atomic_blobs);
+ bits set and validate the number is within allowed range. */
- /* Validate the number is within allowed range. */
- ut_a(zip_ssize <= PAGE_ZIP_SSIZE_MAX);
+ if (!compact
+ || !atomic_blobs
+ || zip_ssize > PAGE_ZIP_SSIZE_MAX) {
+
+ return(false);
+ }
}
- /* Return the flags sent if we did not crash. */
- return(flags);
+ /* CREATE TABLE ... DATA DIRECTORY is supported for any row format,
+ so the DATA_DIR flag is compatible with all other table flags. */
+
+ return(true);
}
/********************************************************************//**
@@ -517,9 +595,7 @@ dict_sys_tables_type_validate(
ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(type);
ulint unused = DICT_TF_GET_UNUSED(type);
- /* If the format is UNIV_FORMAT_A, table->flags == 0, but
- SYS_TABLES.TYPE == 1, which is defined as SYS_TABLE_TYPE_ANTELOPE.
- The low order bit of SYS_TABLES.TYPE is always set to 1.
+ /* The low order bit of SYS_TABLES.TYPE is always set to 1.
If the format is UNIV_FORMAT_B or higher, this field is the same
as dict_table_t::flags. Zero is not allowed here. */
if (!low_order_bit) {
@@ -527,12 +603,9 @@ dict_sys_tables_type_validate(
}
if (redundant) {
- /* This is Redundant row format, only the first bit
- should be set in SYS_TABLES.TYPE */
- if (type != SYS_TABLE_TYPE_ANTELOPE) {
+ if (zip_ssize || atomic_blobs) {
return(ULINT_UNDEFINED);
}
- return(DICT_TF_REDUNDANT);
}
/* Make sure there are no bits that we do not know about. */
@@ -569,6 +642,11 @@ dict_sys_tables_type_validate(
}
}
+ /* There is nothing to validate for the data_dir field.
+ CREATE TABLE ... DATA DIRECTORY is supported for any row
+ format, so the DATA_DIR flag is compatible with any other
+ table flags. However, it is not used with TEMPORARY tables.*/
+
/* Return the validated SYS_TABLES.TYPE. */
return(type);
}
@@ -584,7 +662,7 @@ dict_tf_get_rec_format(
/*===================*/
ulint flags) /*!< in: dict_table_t::flags */
{
- dict_tf_validate(flags);
+ ut_a(dict_tf_is_valid(flags));
if (!DICT_TF_GET_COMPACT(flags)) {
return(REC_FORMAT_REDUNDANT);
@@ -640,7 +718,8 @@ dict_tf_set(
/*========*/
ulint* flags, /*!< in/out: table flags */
rec_format_t format, /*!< in: file format */
- ulint zip_ssize) /*!< in: zip shift size */
+ ulint zip_ssize, /*!< in: zip shift size */
+ bool use_data_dir) /*!< in: table uses DATA DIRECTORY */
{
switch (format) {
case REC_FORMAT_REDUNDANT:
@@ -662,6 +741,10 @@ dict_tf_set(
ut_ad(zip_ssize == 0);
break;
}
+
+ if (use_data_dir) {
+ *flags |= (1 << DICT_TF_POS_DATA_DIR);
+ }
}
/********************************************************************//**
@@ -679,15 +762,61 @@ UNIV_INLINE
ulint
dict_tf_to_fsp_flags(
/*=================*/
- ulint flags) /*!< in: dict_table_t::flags */
+ ulint table_flags) /*!< in: dict_table_t::flags */
{
+ ulint fsp_flags;
+
+ DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure",
+ return(ULINT_UNDEFINED););
+
/* Adjust bit zero. */
- flags = (flags == DICT_TF_COMPACT) ? 0 : flags;
+ fsp_flags = DICT_TF_HAS_ATOMIC_BLOBS(table_flags) ? 1 : 0;
+
+ /* ZIP_SSIZE and ATOMIC_BLOBS are at the same position. */
+ fsp_flags |= table_flags & DICT_TF_MASK_ZIP_SSIZE;
+ fsp_flags |= table_flags & DICT_TF_MASK_ATOMIC_BLOBS;
/* In addition, tablespace flags also contain the page size. */
- flags = fsp_flags_set_page_size(flags, UNIV_PAGE_SIZE);
+ fsp_flags |= fsp_flags_set_page_size(fsp_flags, UNIV_PAGE_SIZE);
+
+ /* The DATA_DIR flag is in a different position in fsp_flag */
+ fsp_flags |= DICT_TF_HAS_DATA_DIR(table_flags)
+ ? FSP_FLAGS_MASK_DATA_DIR : 0;
- return(fsp_flags_validate(flags));
+ ut_a(fsp_flags_is_valid(fsp_flags));
+
+ return(fsp_flags);
+}
+
+/********************************************************************//**
+Convert a 32 bit integer from SYS_TABLES.TYPE to dict_table_t::flags
+The following chart shows the translation of the low order bit.
+Other bits are the same.
+========================= Low order bit ==========================
+ | REDUNDANT | COMPACT | COMPRESSED and DYNAMIC
+SYS_TABLES.TYPE | 1 | 1 | 1
+dict_table_t::flags | 0 | 1 | 1
+==================================================================
+@return ulint containing SYS_TABLES.TYPE */
+UNIV_INLINE
+ulint
+dict_sys_tables_type_to_tf(
+/*=======================*/
+ ulint type, /*!< in: SYS_TABLES.TYPE field */
+ ulint n_cols) /*!< in: SYS_TABLES.N_COLS field */
+{
+ ulint flags;
+ ulint redundant = !(n_cols & DICT_N_COLS_COMPACT);
+
+ /* Adjust bit zero. */
+ flags = redundant ? 0 : 1;
+
+ /* ZIP_SSIZE, ATOMIC_BLOBS & DATA_DIR are the same. */
+ flags |= type & (DICT_TF_MASK_ZIP_SSIZE
+ | DICT_TF_MASK_ATOMIC_BLOBS
+ | DICT_TF_MASK_DATA_DIR);
+
+ return(flags);
}
/********************************************************************//**
@@ -706,13 +835,19 @@ dict_tf_to_sys_tables_type(
/*=======================*/
ulint flags) /*!< in: dict_table_t::flags */
{
- if (!DICT_TF_HAS_ATOMIC_BLOBS(flags)) {
- ut_a(flags == DICT_TF_REDUNDANT
- || flags == DICT_TF_COMPACT);
- return(SYS_TABLE_TYPE_ANTELOPE);
- }
+ ulint type;
+
+ ut_a(dict_tf_is_valid(flags));
+
+ /* Adjust bit zero. It is always 1 in SYS_TABLES.TYPE */
+ type = 1;
+
+ /* ZIP_SSIZE, ATOMIC_BLOBS & DATA_DIR are the same. */
+ type |= flags & (DICT_TF_MASK_ZIP_SSIZE
+ | DICT_TF_MASK_ATOMIC_BLOBS
+ | DICT_TF_MASK_DATA_DIR);
- return(dict_tf_validate(flags));
+ return(type);
}
/********************************************************************//**
@@ -1064,6 +1199,103 @@ dict_index_get_space_reserve(void)
return(UNIV_PAGE_SIZE / 16);
}
+/********************************************************************//**
+Gets the status of online index creation.
+@return the status */
+UNIV_INLINE
+enum online_index_status
+dict_index_get_online_status(
+/*=========================*/
+ const dict_index_t* index) /*!< in: secondary index */
+{
+ enum online_index_status status;
+
+ status = (enum online_index_status) index->online_status;
+
+ /* Without the index->lock protection, the online
+ status can change from ONLINE_INDEX_CREATION to
+ ONLINE_INDEX_COMPLETE (or ONLINE_INDEX_ABORTED) in
+ row_log_apply() once log application is done. So to make
+ sure the status is ONLINE_INDEX_CREATION or ONLINE_INDEX_COMPLETE
+ you should always do the recheck after acquiring index->lock */
+
+#ifdef UNIV_DEBUG
+ switch (status) {
+ case ONLINE_INDEX_COMPLETE:
+ case ONLINE_INDEX_CREATION:
+ case ONLINE_INDEX_ABORTED:
+ case ONLINE_INDEX_ABORTED_DROPPED:
+ return(status);
+ }
+ ut_error;
+#endif /* UNIV_DEBUG */
+ return(status);
+}
+
+/********************************************************************//**
+Sets the status of online index creation. */
+UNIV_INLINE
+void
+dict_index_set_online_status(
+/*=========================*/
+ dict_index_t* index, /*!< in/out: index */
+ enum online_index_status status) /*!< in: status */
+{
+ ut_ad(!(index->type & DICT_FTS));
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_EX));
+#endif /* UNIV_SYNC_DEBUG */
+#ifdef UNIV_DEBUG
+ switch (dict_index_get_online_status(index)) {
+ case ONLINE_INDEX_COMPLETE:
+ case ONLINE_INDEX_CREATION:
+ break;
+ case ONLINE_INDEX_ABORTED:
+ ut_ad(status == ONLINE_INDEX_ABORTED_DROPPED);
+ break;
+ case ONLINE_INDEX_ABORTED_DROPPED:
+ ut_error;
+ }
+#endif /* UNIV_DEBUG */
+
+ index->online_status = status;
+ ut_ad(dict_index_get_online_status(index) == status);
+}
+
+/********************************************************************//**
+Determines if a secondary index is being or has been created online,
+or if the table is being rebuilt online, allowing concurrent modifications
+to the table.
+@retval true if the index is being or has been built online, or
+if this is a clustered index and the table is being or has been rebuilt online
+@retval false if the index has been created or the table has been
+rebuilt completely */
+UNIV_INLINE
+bool
+dict_index_is_online_ddl(
+/*=====================*/
+ const dict_index_t* index) /*!< in: index */
+{
+#ifdef UNIV_DEBUG
+ if (dict_index_is_clust(index)) {
+ switch (dict_index_get_online_status(index)) {
+ case ONLINE_INDEX_CREATION:
+ return(true);
+ case ONLINE_INDEX_COMPLETE:
+ return(false);
+ case ONLINE_INDEX_ABORTED:
+ case ONLINE_INDEX_ABORTED_DROPPED:
+ break;
+ }
+ ut_ad(0);
+ return(false);
+ }
+#endif /* UNIV_DEBUG */
+
+ return(UNIV_UNLIKELY(dict_index_get_online_status(index)
+ != ONLINE_INDEX_COMPLETE));
+}
+
/**********************************************************************//**
Check whether a column exists in an FTS index.
@return ULINT_UNDEFINED if no match else the offset within the vector */
@@ -1147,4 +1379,28 @@ dict_index_is_corrupted(
|| (index->table && index->table->corrupted));
}
+/********************************************************************//**
+Check if the tablespace for the table has been discarded.
+@return true if the tablespace has been discarded. */
+UNIV_INLINE
+bool
+dict_table_is_discarded(
+/*====================*/
+ const dict_table_t* table) /*!< in: table to check */
+{
+ return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_DISCARDED));
+}
+
+/********************************************************************//**
+Check if it is a temporary table.
+@return true if temporary table flag is set. */
+UNIV_INLINE
+bool
+dict_table_is_temporary(
+/*====================*/
+ const dict_table_t* table) /*!< in: table to check */
+{
+ return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY));
+}
+
#endif /* !UNIV_HOTBACKUP */