summaryrefslogtreecommitdiff
path: root/storage/innobase/include
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2016-09-06 09:43:16 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2016-09-08 15:49:03 +0300
commitfec844aca88e1c6b9c36bb0b811e92d9d023ffb9 (patch)
tree3e8602113e591b163bf23fffe95c8908cac88ea3 /storage/innobase/include
parent2e814d4702d71a04388386a9f591d14a35980bfe (diff)
downloadmariadb-git-fec844aca88e1c6b9c36bb0b811e92d9d023ffb9.tar.gz
Merge InnoDB 5.7 from mysql-5.7.14.
Contains also: MDEV-10549 mysqld: sql/handler.cc:2692: int handler::ha_index_first(uchar*): Assertion `table_share->tmp_table != NO_TMP_TABLE || m_lock_type != 2' failed. (branch bb-10.2-jan) Unlike MySQL, InnoDB still uses THR_LOCK in MariaDB MDEV-10548 Some of the debug sync waits do not work with InnoDB 5.7 (branch bb-10.2-jan) enable tests that were fixed in MDEV-10549 MDEV-10548 Some of the debug sync waits do not work with InnoDB 5.7 (branch bb-10.2-jan) fix main.innodb_mysql_sync - re-enable online alter for partitioned innodb tables
Diffstat (limited to 'storage/innobase/include')
-rw-r--r--storage/innobase/include/api0api.h9
-rw-r--r--storage/innobase/include/btr0btr.h47
-rw-r--r--storage/innobase/include/btr0bulk.h2
-rw-r--r--storage/innobase/include/btr0sea.h7
-rw-r--r--storage/innobase/include/btr0sea.ic6
-rw-r--r--storage/innobase/include/btr0types.h2
-rw-r--r--storage/innobase/include/buf0buf.h65
-rw-r--r--storage/innobase/include/buf0buf.ic71
-rw-r--r--storage/innobase/include/buf0checksum.h7
-rw-r--r--storage/innobase/include/buf0dblwr.h4
-rw-r--r--storage/innobase/include/buf0flu.h29
-rw-r--r--storage/innobase/include/buf0rea.h7
-rw-r--r--storage/innobase/include/data0data.h38
-rw-r--r--storage/innobase/include/data0data.ic31
-rw-r--r--storage/innobase/include/db0err.h13
-rw-r--r--storage/innobase/include/dict0crea.h14
-rw-r--r--storage/innobase/include/dict0defrag_bg.h93
-rw-r--r--storage/innobase/include/dict0dict.h137
-rw-r--r--storage/innobase/include/dict0dict.ic101
-rw-r--r--storage/innobase/include/dict0load.h10
-rw-r--r--storage/innobase/include/dict0mem.h185
-rw-r--r--storage/innobase/include/dict0stats.h36
-rw-r--r--storage/innobase/include/dict0stats_bg.h46
-rw-r--r--storage/innobase/include/dict0types.h29
-rw-r--r--storage/innobase/include/dyn0buf.h22
-rw-r--r--storage/innobase/include/fil0crypt.ic2
-rw-r--r--storage/innobase/include/fil0fil.h472
-rw-r--r--storage/innobase/include/fsp0file.h42
-rw-r--r--storage/innobase/include/fsp0fsp.h117
-rw-r--r--storage/innobase/include/fsp0fsp.ic27
-rw-r--r--storage/innobase/include/fsp0space.h21
-rw-r--r--storage/innobase/include/fsp0sysspace.h24
-rw-r--r--storage/innobase/include/fsp0types.h30
-rw-r--r--storage/innobase/include/fts0ast.h7
-rw-r--r--storage/innobase/include/fts0fts.h95
-rw-r--r--storage/innobase/include/fts0priv.h56
-rw-r--r--storage/innobase/include/fts0priv.ic17
-rw-r--r--storage/innobase/include/fut0fut.h4
-rw-r--r--storage/innobase/include/gis0rtree.h21
-rw-r--r--storage/innobase/include/ha0ha.h2
-rw-r--r--storage/innobase/include/ha_prototypes.h16
-rw-r--r--storage/innobase/include/ibuf0ibuf.h8
-rw-r--r--storage/innobase/include/lock0lock.h48
-rw-r--r--storage/innobase/include/lock0prdt.h23
-rw-r--r--storage/innobase/include/lock0priv.h75
-rw-r--r--storage/innobase/include/log0log.h72
-rw-r--r--storage/innobase/include/log0log.ic7
-rw-r--r--storage/innobase/include/log0recv.h16
-rw-r--r--storage/innobase/include/mach0data.h29
-rw-r--r--storage/innobase/include/mach0data.ic2
-rw-r--r--storage/innobase/include/mem0mem.h2
-rw-r--r--storage/innobase/include/mem0mem.ic2
-rw-r--r--storage/innobase/include/mtr0log.ic24
-rw-r--r--storage/innobase/include/mtr0mtr.h44
-rw-r--r--storage/innobase/include/mtr0mtr.ic2
-rw-r--r--storage/innobase/include/os0atomic.h79
-rw-r--r--storage/innobase/include/os0atomic.ic11
-rw-r--r--storage/innobase/include/os0file.h358
-rw-r--r--storage/innobase/include/os0file.ic11
-rw-r--r--storage/innobase/include/os0thread.h9
-rw-r--r--storage/innobase/include/page0cur.h3
-rw-r--r--storage/innobase/include/page0page.h24
-rw-r--r--storage/innobase/include/page0types.h15
-rw-r--r--storage/innobase/include/page0zip.h52
-rw-r--r--storage/innobase/include/page0zip.ic3
-rw-r--r--storage/innobase/include/pars0pars.h18
-rw-r--r--storage/innobase/include/que0que.h16
-rw-r--r--storage/innobase/include/read0read.h2
-rw-r--r--storage/innobase/include/read0types.h4
-rw-r--r--storage/innobase/include/rem0cmp.h21
-rw-r--r--storage/innobase/include/rem0rec.h81
-rw-r--r--storage/innobase/include/rem0rec.ic2
-rw-r--r--storage/innobase/include/row0ftsort.h2
-rw-r--r--storage/innobase/include/row0ins.h8
-rw-r--r--storage/innobase/include/row0log.h17
-rw-r--r--storage/innobase/include/row0merge.h86
-rw-r--r--storage/innobase/include/row0mysql.h72
-rw-r--r--storage/innobase/include/row0purge.h2
-rw-r--r--storage/innobase/include/row0row.h10
-rw-r--r--storage/innobase/include/row0sel.h9
-rw-r--r--storage/innobase/include/row0umod.h2
-rw-r--r--storage/innobase/include/row0undo.h4
-rw-r--r--storage/innobase/include/row0upd.h62
-rw-r--r--storage/innobase/include/row0vers.h9
-rw-r--r--storage/innobase/include/srv0mon.h10
-rw-r--r--storage/innobase/include/srv0srv.h34
-rw-r--r--storage/innobase/include/srv0start.h11
-rw-r--r--storage/innobase/include/sync0arr.h6
-rw-r--r--storage/innobase/include/sync0rw.h14
-rw-r--r--storage/innobase/include/sync0sync.h5
-rw-r--r--storage/innobase/include/sync0types.h7
-rw-r--r--storage/innobase/include/trx0rec.h4
-rw-r--r--storage/innobase/include/trx0rseg.h7
-rw-r--r--storage/innobase/include/trx0sys.h21
-rw-r--r--storage/innobase/include/trx0sys.ic8
-rw-r--r--storage/innobase/include/trx0trx.h62
-rw-r--r--storage/innobase/include/trx0types.h2
-rw-r--r--storage/innobase/include/trx0undo.h11
-rw-r--r--storage/innobase/include/univ.i46
-rw-r--r--storage/innobase/include/ut0counter.h8
-rw-r--r--storage/innobase/include/ut0crc32.h2
-rw-r--r--storage/innobase/include/ut0dbg.h2
-rw-r--r--storage/innobase/include/ut0lst.h1
-rw-r--r--storage/innobase/include/ut0mem.h2
-rw-r--r--storage/innobase/include/ut0new.h11
-rw-r--r--storage/innobase/include/ut0rnd.h2
-rw-r--r--storage/innobase/include/ut0rnd.ic2
-rw-r--r--storage/innobase/include/ut0ut.h35
-rw-r--r--storage/innobase/include/ut0wqueue.h1
109 files changed, 2449 insertions, 1175 deletions
diff --git a/storage/innobase/include/api0api.h b/storage/innobase/include/api0api.h
index 127f8e1949e..ec02febee74 100644
--- a/storage/innobase/include/api0api.h
+++ b/storage/innobase/include/api0api.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -1030,4 +1030,11 @@ ib_ut_strerr(
/*=========*/
ib_err_t num); /*!< in: error number */
+/** Check the table whether it contains virtual columns.
+@param[in] crsr InnoDB Cursor
+@return true if table contains virtual column else false. */
+ib_bool_t
+ib_is_virtual_table(
+ ib_crsr_t crsr);
+
#endif /* api0api_h */
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
index e350e01ff5b..c177f23824f 100644
--- a/storage/innobase/include/btr0btr.h
+++ b/storage/innobase/include/btr0btr.h
@@ -179,7 +179,7 @@ dberr_t
btr_root_adjust_on_import(
/*======================*/
const dict_index_t* index) /*!< in: index tree */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**************************************************************//**
Gets the height of the B-tree (the level of the root, when the leaf
@@ -191,7 +191,7 @@ btr_height_get(
/*===========*/
dict_index_t* index, /*!< in: index tree */
mtr_t* mtr) /*!< in/out: mini-transaction */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Gets a buffer page and declares its latching order level.
@param[in] page_id page id
@@ -254,7 +254,7 @@ index_id_t
btr_page_get_index_id(
/*==================*/
const page_t* page) /*!< in: index page */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#ifndef UNIV_HOTBACKUP
/********************************************************//**
Gets the node level field in an index page.
@@ -264,7 +264,7 @@ ulint
btr_page_get_level_low(
/*===================*/
const page_t* page) /*!< in: index page */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#define btr_page_get_level(page, mtr) btr_page_get_level_low(page)
/********************************************************//**
Gets the next index page number.
@@ -275,7 +275,7 @@ btr_page_get_next(
/*==============*/
const page_t* page, /*!< in: index page */
mtr_t* mtr) /*!< in: mini-transaction handle */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************//**
Gets the previous index page number.
@return prev page number */
@@ -285,7 +285,7 @@ btr_page_get_prev(
/*==============*/
const page_t* page, /*!< in: index page */
mtr_t* mtr) /*!< in: mini-transaction handle */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**************************************************************//**
Releases the latch on a leaf page and bufferunfixes it. */
UNIV_INLINE
@@ -310,7 +310,7 @@ btr_node_ptr_get_child_page_no(
/*===========================*/
const rec_t* rec, /*!< in: node pointer record */
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Create the root node for a new index tree.
@param[in] type type of the index
@@ -374,7 +374,7 @@ btr_root_raise_and_insert(
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr) /*!< in: mtr */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*************************************************************//**
Reorganizes an index page.
@@ -399,7 +399,7 @@ btr_page_reorganize_low(
page_cur_t* cursor, /*!< in/out: page cursor */
dict_index_t* index, /*!< in: the index tree of the page */
mtr_t* mtr) /*!< in/out: mini-transaction */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*************************************************************//**
Reorganizes an index page.
@@ -429,7 +429,7 @@ btr_page_get_split_rec_to_left(
rec_t** split_rec)/*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple should be first */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*************************************************************//**
Decides if the page should be split at the convergence point of
inserts converging to right.
@@ -441,7 +441,7 @@ btr_page_get_split_rec_to_right(
rec_t** split_rec)/*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple should be first */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*************************************************************//**
Splits an index page to halves and inserts the tuple. It is assumed
@@ -465,7 +465,7 @@ btr_page_split_and_insert(
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr) /*!< in: mtr */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************//**
Inserts a data tuple to a tree on a non-leaf level. It is assumed
that mtr holds an x-latch on the tree. */
@@ -478,8 +478,7 @@ btr_insert_on_non_leaf_level_func(
dtuple_t* tuple, /*!< in: the record to be inserted */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
- mtr_t* mtr) /*!< in: mtr */
- MY_ATTRIBUTE((nonnull(4,5)));
+ mtr_t* mtr); /*!< in: mtr */
# define btr_insert_on_non_leaf_level(f,i,l,t,m) \
btr_insert_on_non_leaf_level_func(f,i,l,t,__FILE__,__LINE__,m)
#endif /* !UNIV_HOTBACKUP */
@@ -511,7 +510,7 @@ btr_check_node_ptr(
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: index page */
mtr_t* mtr) /*!< in: mtr */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#endif /* UNIV_DEBUG */
/*************************************************************//**
Tries to merge the page first to the left immediate brother if such a
@@ -543,8 +542,7 @@ btr_discard_page(
/*=============*/
btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on
the root page */
- mtr_t* mtr) /*!< in: mtr */
- MY_ATTRIBUTE((nonnull));
+ mtr_t* mtr); /*!< in: mtr */
#endif /* !UNIV_HOTBACKUP */
/****************************************************************//**
Parses the redo log record for setting an index record as the predefined
@@ -571,7 +569,7 @@ btr_parse_page_reorganize(
bool compressed,/*!< in: true if compressed page */
buf_block_t* block, /*!< in: page to be reorganized, or NULL */
mtr_t* mtr) /*!< in: mtr or NULL */
- MY_ATTRIBUTE((nonnull(1,2,3), warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#ifndef UNIV_HOTBACKUP
/**************************************************************//**
Gets the number of pages in a B-tree.
@@ -583,7 +581,7 @@ btr_get_size(
ulint flag, /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
mtr_t* mtr) /*!< in/out: mini-transaction where index
is s-latched */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**************************************************************//**
Gets the number of reserved and used pages in a B-tree.
@return number of pages reserved, or ULINT_UNDEFINED if the index
@@ -620,7 +618,7 @@ btr_page_alloc(
mtr_t* init_mtr) /*!< in/out: mini-transaction
for x-latching and initializing
the page */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**************************************************************//**
Frees a file page used in an index tree. NOTE: cannot free field external
storage pages because the page must contain info on its level. */
@@ -653,7 +651,7 @@ btr_page_free_low(
ulint level, /*!< in: page level (ULINT_UNDEFINED=BLOB) */
bool blob, /*!< in: blob page */
mtr_t* mtr) /*!< in: mtr */
- __attribute__((nonnull));
+ MY_ATTRIBUTE((nonnull(1,2)));
/**************************************************************//**
Gets the root node of a tree and x- or s-latches it.
@return root page, x- or s-latched */
@@ -695,7 +693,6 @@ btr_page_reorganize_block(
#ifdef UNIV_BTR_PRINT
/*************************************************************//**
Prints size info of a B-tree. */
-UNIV_INTERN
void
btr_print_size(
/*===========*/
@@ -703,7 +700,6 @@ btr_print_size(
MY_ATTRIBUTE((nonnull));
/**************************************************************//**
Prints directories and other info of all nodes in the index. */
-UNIV_INTERN
void
btr_print_index(
/*============*/
@@ -724,18 +720,17 @@ btr_index_rec_validate(
ibool dump_on_error) /*!< in: TRUE if the function
should print hex dump of record
and page on error */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**************************************************************//**
Checks the consistency of an index tree.
@return DB_SUCCESS if ok, error code if not */
-UNIV_INTERN
dberr_t
btr_validate_index(
/*===============*/
dict_index_t* index, /*!< in: index */
const trx_t* trx, /*!< in: transaction or 0 */
bool lockout)/*!< in: true if X-latch index is intended */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*************************************************************//**
Removes a page from the level list of pages. */
diff --git a/storage/innobase/include/btr0bulk.h b/storage/innobase/include/btr0bulk.h
index 64ffa89c0ae..a1887c3df2b 100644
--- a/storage/innobase/include/btr0bulk.h
+++ b/storage/innobase/include/btr0bulk.h
@@ -260,7 +260,7 @@ private:
FlushObserver* m_flush_observer;
/** Operation result DB_SUCCESS or error code */
- dberr_t m_err;
+ dberr_t m_err;
};
typedef std::vector<PageBulk*, ut_allocator<PageBulk*> >
diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
index 659944f327e..12659037904 100644
--- a/storage/innobase/include/btr0sea.h
+++ b/storage/innobase/include/btr0sea.h
@@ -328,6 +328,13 @@ extern rw_lock_t** btr_search_latches;
/** The adaptive hash index */
extern btr_search_sys_t* btr_search_sys;
+#ifdef UNIV_SEARCH_PERF_STAT
+/** Number of successful adaptive hash index lookups */
+extern ulint btr_search_n_succ;
+/** Number of failed adaptive hash index lookups */
+extern ulint btr_search_n_hash_fail;
+#endif /* UNIV_SEARCH_PERF_STAT */
+
/** After change in n_fields or n_bytes in info, this many rounds are waited
before starting the hash analysis again: this is to save CPU time when there
is no hope in building a hash index. */
diff --git a/storage/innobase/include/btr0sea.ic b/storage/innobase/include/btr0sea.ic
index 4fd76810ea0..5f7c39ba500 100644
--- a/storage/innobase/include/btr0sea.ic
+++ b/storage/innobase/include/btr0sea.ic
@@ -200,7 +200,8 @@ btr_get_search_latch(const dict_index_t* index)
{
ut_ad(index != NULL);
- ulint ifold = ut_fold_ulint_pair(index->id, index->space);
+ ulint ifold = ut_fold_ulint_pair(static_cast<ulint>(index->id),
+ static_cast<ulint>(index->space));
return(btr_search_latches[ifold % btr_ahi_parts]);
}
@@ -215,7 +216,8 @@ btr_get_search_table(const dict_index_t* index)
{
ut_ad(index != NULL);
- ulint ifold = ut_fold_ulint_pair(index->id, index->space);
+ ulint ifold = ut_fold_ulint_pair(static_cast<ulint>(index->id),
+ static_cast<ulint>(index->space));
return(btr_search_sys->hash_tables[ifold % btr_ahi_parts]);
}
diff --git a/storage/innobase/include/btr0types.h b/storage/innobase/include/btr0types.h
index 734b33e4221..19c21982011 100644
--- a/storage/innobase/include/btr0types.h
+++ b/storage/innobase/include/btr0types.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
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
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 6e147ce95c5..c4bc107044d 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -109,6 +109,9 @@ extern buf_block_t* back_block2; /*!< second block, for page reorganize */
#endif /* !UNIV_HOTBACKUP */
#endif /* !UNIV_INNOCHECKSUM */
+/** Magic value to use instead of checksums when they are disabled */
+#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
+
#ifndef UNIV_INNOCHECKSUM
/** @brief States of a control block
@see buf_page_t
@@ -679,7 +682,7 @@ ulint
buf_page_get_freed_page_clock(
/*==========================*/
const buf_page_t* bpage) /*!< in: block */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Reads the freed_page_clock of a buffer block.
@return freed_page_clock */
@@ -688,7 +691,7 @@ ulint
buf_block_get_freed_page_clock(
/*===========================*/
const buf_block_t* block) /*!< in: block */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Tells if a block is still close enough to the MRU end of the LRU list
@@ -834,8 +837,7 @@ buf_page_is_corrupted(
bool is_log_enabled,
FILE* log_file
#endif /* UNIV_INNOCHECKSUM */
-) __attribute__((warn_unused_result));
-
+) MY_ATTRIBUTE((warn_unused_result));
#ifndef UNIV_INNOCHECKSUM
#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
@@ -857,7 +859,7 @@ ulint
buf_block_get_lock_hash_val(
/*========================*/
const buf_block_t* block) /*!< in: block */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
#ifdef UNIV_DEBUG
/*********************************************************************//**
Finds a block in the buffer pool that points to a
@@ -1039,7 +1041,7 @@ enum buf_page_state
buf_block_get_state(
/*================*/
const buf_block_t* block) /*!< in: pointer to the control block */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Sets the state of a block. */
UNIV_INLINE
@@ -1064,7 +1066,7 @@ ibool
buf_page_in_file(
/*=============*/
const buf_page_t* bpage) /*!< in: pointer to control block */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Determines if a block should be on unzip_LRU list.
@@ -1074,7 +1076,7 @@ ibool
buf_page_belongs_to_unzip_LRU(
/*==========================*/
const buf_page_t* bpage) /*!< in: pointer to control block */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Gets the mutex of a block.
@@ -1084,7 +1086,7 @@ BPageMutex*
buf_page_get_mutex(
/*===============*/
const buf_page_t* bpage) /*!< in: pointer to control block */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Get the flush type of a page.
@@ -1094,7 +1096,7 @@ buf_flush_t
buf_page_get_flush_type(
/*====================*/
const buf_page_t* bpage) /*!< in: buffer page */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Set the flush type of a page. */
UNIV_INLINE
@@ -1121,7 +1123,7 @@ enum buf_io_fix
buf_page_get_io_fix(
/*================*/
const buf_page_t* bpage) /*!< in: pointer to the control block */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Gets the io_fix state of a block.
@return io_fix state */
@@ -1130,7 +1132,7 @@ enum buf_io_fix
buf_block_get_io_fix(
/*================*/
const buf_block_t* block) /*!< in: pointer to the control block */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
@@ -1176,7 +1178,7 @@ ibool
buf_page_can_relocate(
/*==================*/
const buf_page_t* bpage) /*!< control block being relocated */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Determine if a block has been flagged old.
@@ -1186,7 +1188,7 @@ ibool
buf_page_is_old(
/*============*/
const buf_page_t* bpage) /*!< in: control block */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Flag a block old. */
UNIV_INLINE
@@ -1203,7 +1205,7 @@ unsigned
buf_page_is_accessed(
/*=================*/
const buf_page_t* bpage) /*!< in: control block */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Flag a block accessed. */
UNIV_INLINE
@@ -1222,7 +1224,7 @@ buf_block_t*
buf_page_get_block(
/*===============*/
buf_page_t* bpage) /*!< in: control block, or NULL */
- MY_ATTRIBUTE((pure));
+ MY_ATTRIBUTE((warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
/*********************************************************************//**
@@ -1233,7 +1235,7 @@ buf_frame_t*
buf_block_get_frame(
/*================*/
const buf_block_t* block) /*!< in: pointer to the control block */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#else /* UNIV_DEBUG */
# define buf_block_get_frame(block) (block)->frame
#endif /* UNIV_DEBUG */
@@ -1244,13 +1246,14 @@ if applicable. */
#define buf_block_get_page_zip(block) \
((block)->page.zip.data ? &(block)->page.zip : NULL)
#ifndef UNIV_HOTBACKUP
-/*******************************************************************//**
-Gets the block to whose frame the pointer is pointing to.
+
+/** Get a buffer block from an adaptive hash index pointer.
+This function does not return if the block is not identified.
+@param[in] ptr pointer to within a page frame
@return pointer to block, never NULL */
buf_block_t*
-buf_block_align(
-/*============*/
- const byte* ptr); /*!< in: pointer to a frame */
+buf_block_from_ahi(const byte* ptr);
+
/********************************************************************//**
Find out if a pointer belongs to a buf_block_t. It can be a pointer to
the buf_block_t itself or a member of it
@@ -1271,18 +1274,6 @@ buf_pointer_is_block_field(
#define buf_pool_is_block_lock(l) \
buf_pointer_is_block_field((const void*)(l))
-#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
-/*********************************************************************//**
-Gets the compressed page descriptor corresponding to an uncompressed page
-if applicable.
-@return compressed page descriptor, or NULL */
-UNIV_INLINE
-const page_zip_des_t*
-buf_frame_get_page_zip(
-/*===================*/
- const byte* ptr); /*!< in: pointer to the page */
-#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
-
/** Inits a page for read to the buffer buf_pool. If the page is
(1) already in buf_pool, or
(2) if we specify to read only ibuf pages and the page is not an ibuf page, or
@@ -1322,7 +1313,7 @@ ulint
buf_pool_index(
/*===========*/
const buf_pool_t* buf_pool) /*!< in: buffer pool */
- MY_ATTRIBUTE((nonnull, const));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Returns the buffer pool instance given a page instance
@return buf_pool */
@@ -1465,7 +1456,7 @@ buf_page_t*
buf_pool_watch_set(
const page_id_t& page_id,
rw_lock_t** hash_lock)
- MY_ATTRIBUTE((warn_unused_result));
+MY_ATTRIBUTE((warn_unused_result));
/** Stop watching if the page has been read in.
buf_pool_watch_set(space,offset) must have returned NULL before.
@@ -1482,7 +1473,7 @@ has returned NULL and before invoking buf_pool_watch_unset(space,offset).
ibool
buf_pool_watch_occurred(
const page_id_t& page_id)
- MY_ATTRIBUTE((warn_unused_result));
+MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Get total buffer pool statistics. */
diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
index bd75c7a3d22..bf7799774c6 100644
--- a/storage/innobase/include/buf0buf.ic
+++ b/storage/innobase/include/buf0buf.ic
@@ -1,8 +1,8 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2014, 2015, MariaDB Corporation.
+Copyright (c) 2014, 2016, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -50,6 +50,11 @@ struct buf_chunk_t{
alloc method and later passed to the
deallocate method. */
buf_block_t* blocks; /*!< array of buffer control blocks */
+
+ /** Get the size of 'mem' in bytes. */
+ size_t mem_size() const {
+ return(mem_pfx.m_size);
+ }
};
/*********************************************************************//**
@@ -315,7 +320,8 @@ buf_page_set_state(
break;
case BUF_BLOCK_FILE_PAGE:
if (!(state == BUF_BLOCK_NOT_USED
- || state == BUF_BLOCK_REMOVE_HASH)) {
+ || state == BUF_BLOCK_REMOVE_HASH
+ || state == BUF_BLOCK_FILE_PAGE)) {
const char *old_state_name = buf_get_state_name((buf_block_t*)bpage);
bpage->state = state;
@@ -326,10 +332,11 @@ buf_page_set_state(
old_state_name,
state,
buf_get_state_name((buf_block_t*)bpage));
+ ut_a(state == BUF_BLOCK_NOT_USED
+ || state == BUF_BLOCK_REMOVE_HASH
+ || state == BUF_BLOCK_FILE_PAGE);
}
- ut_a(state == BUF_BLOCK_NOT_USED
- || state == BUF_BLOCK_REMOVE_HASH);
break;
case BUF_BLOCK_REMOVE_HASH:
ut_a(state == BUF_BLOCK_MEMORY);
@@ -770,23 +777,6 @@ buf_frame_align(
return(frame);
}
-#ifndef UNIV_HOTBACKUP
-#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
-/*********************************************************************//**
-Gets the compressed page descriptor corresponding to an uncompressed page
-if applicable.
-@return compressed page descriptor, or NULL */
-UNIV_INLINE
-const page_zip_des_t*
-buf_frame_get_page_zip(
-/*===================*/
- const byte* ptr) /*!< in: pointer to the page */
-{
- return(buf_block_get_page_zip(buf_block_align(ptr)));
-}
-#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
-#endif /* !UNIV_HOTBACKUP */
-
/**********************************************************************//**
Gets the space id, page offset, and byte offset within page of a
pointer pointing to a buffer frame containing a file page. */
@@ -1421,6 +1411,25 @@ buf_get_nth_chunk_block(
return(chunk->blocks);
}
+/********************************************************************//**
+Get buf frame. */
+UNIV_INLINE
+void *
+buf_page_get_frame(
+/*===============*/
+ const buf_page_t* bpage) /*!< in: buffer pool page */
+{
+ /* In encryption/compression buffer pool page may contain extra
+ buffer where result is stored. */
+ if (bpage->slot && bpage->slot->out_buf) {
+ return bpage->slot->out_buf;
+ } else if (bpage->zip.data) {
+ return bpage->zip.data;
+ } else {
+ return ((buf_block_t*) bpage)->frame;
+ }
+}
+
/** Verify the possibility that a stored page is not in buffer pool.
@param[in] withdraw_clock withdraw clock when stored the page
@retval true if the page might be relocated */
@@ -1452,22 +1461,4 @@ buf_pool_size_align(
}
}
-/********************************************************************//**
-Get buf frame. */
-UNIV_INLINE
-void *
-buf_page_get_frame(
-/*===============*/
- const buf_page_t* bpage) /*!< in: buffer pool page */
-{
- /* In encryption/compression buffer pool page may contain extra
- buffer where result is stored. */
- if (bpage->slot && bpage->slot->out_buf) {
- return bpage->slot->out_buf;
- } else if (bpage->zip.data) {
- return bpage->zip.data;
- } else {
- return ((buf_block_t*) bpage)->frame;
- }
-}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/include/buf0checksum.h b/storage/innobase/include/buf0checksum.h
index 684c378e066..9405251dc74 100644
--- a/storage/innobase/include/buf0checksum.h
+++ b/storage/innobase/include/buf0checksum.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -30,9 +30,6 @@ Created Aug 11, 2011 Vasil Dimov
#include "buf0types.h"
-/** Magic value to use instead of checksums when they are disabled */
-#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
-
/** Calculates the CRC32 checksum of a page. The value is stored to the page
when it is written to a file and also checked for a match when reading from
the file. When reading we allow both normal CRC32 and CRC-legacy-big-endian
@@ -70,6 +67,7 @@ buf_calc_page_old_checksum(
/*=======================*/
const byte* page); /*!< in: buffer page */
+
/********************************************************************//**
Return a printable string describing the checksum algorithm.
@return algorithm name */
@@ -79,5 +77,6 @@ buf_checksum_algorithm_name(
srv_checksum_algorithm_t algo); /*!< in: algorithm */
extern ulong srv_checksum_algorithm;
+extern bool legacy_big_endian_checksum;
#endif /* buf0checksum_h */
diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h
index 1f8f23edd4e..eb13c3b35e5 100644
--- a/storage/innobase/include/buf0dblwr.h
+++ b/storage/innobase/include/buf0dblwr.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -43,7 +43,7 @@ extern ibool buf_dblwr_being_created;
Creates the doublewrite buffer to a new InnoDB installation. The header of the
doublewrite buffer is placed on the trx system header page.
@return true if successful, false if not. */
-__attribute__((warn_unused_result))
+MY_ATTRIBUTE((warn_unused_result))
bool
buf_dblwr_create(void);
/*==================*/
diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h
index 1d38c679f81..40083798d48 100644
--- a/storage/innobase/include/buf0flu.h
+++ b/storage/innobase/include/buf0flu.h
@@ -36,14 +36,18 @@ Created 11/5/1995 Heikki Tuuri
/** Flag indicating if the page_cleaner is in active state. */
extern bool buf_page_cleaner_is_active;
-/** Event to synchronise with the flushing. */
-extern os_event_t buf_flush_event;
+#ifdef UNIV_DEBUG
-class ut_stage_alter_t;
+/** Value of MySQL global variable used to disable page cleaner. */
+extern my_bool innodb_page_cleaner_disabled_debug;
+
+#endif /* UNIV_DEBUG */
/** Event to synchronise with the flushing. */
extern os_event_t buf_flush_event;
+class ut_stage_alter_t;
+
/** Handled page counters for a single flush */
struct flush_counters_t {
ulint flushed; /*!< number of dirty pages flushed */
@@ -101,7 +105,7 @@ buf_flush_page_try(
/*===============*/
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
buf_block_t* block) /*!< in/out: buffer control block */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
# endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
/** Do flushing batch of a given type.
NOTE: The calling thread is not allowed to own any latches on pages!
@@ -124,6 +128,7 @@ buf_flush_do_batch(
lsn_t lsn_limit,
flush_counters_t* n);
+
/** This utility flushes dirty blocks from the end of the flush list of all
buffer pool instances.
NOTE: The calling thread is not allowed to own any latches on pages!
@@ -216,6 +221,22 @@ buf_flush_ready_for_replace(
/*========================*/
buf_page_t* bpage); /*!< in: buffer control block, must be
buf_page_in_file(bpage) and in the LRU list */
+
+#ifdef UNIV_DEBUG
+/** Disables page cleaner threads (coordinator and workers).
+It's used by: SET GLOBAL innodb_page_cleaner_disabled_debug = 1 (0).
+@param[in] thd thread handle
+@param[in] var pointer to system variable
+@param[out] var_ptr where the formal string goes
+@param[in] save immediate result from check function */
+void
+buf_flush_page_cleaner_disabled_debug_update(
+ THD* thd,
+ struct st_mysql_sys_var* var,
+ void* var_ptr,
+ const void* save);
+#endif /* UNIV_DEBUG */
+
/******************************************************************//**
page_cleaner thread tasked with flushing dirty pages from the buffer
pools. As of now we'll have only one coordinator of this thread.
diff --git a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h
index f2ec11f1783..9c97a5147c1 100644
--- a/storage/innobase/include/buf0rea.h
+++ b/storage/innobase/include/buf0rea.h
@@ -126,13 +126,6 @@ buf_read_ibuf_merge_pages(
to get read in, before this
function returns */
const ulint* space_ids, /*!< in: array of space ids */
- const ib_uint64_t* space_versions,/*!< in: the spaces must have
- this version number
- (timestamp), otherwise we
- discard the read; we use this
- to cancel reads if DISCARD +
- IMPORT may have changed the
- tablespace size */
const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h
index 24b0a791535..5537d70548a 100644
--- a/storage/innobase/include/data0data.h
+++ b/storage/innobase/include/data0data.h
@@ -70,8 +70,8 @@ void
dfield_set_type(
/*============*/
dfield_t* field, /*!< in: SQL data field */
- const dtype_t* type) /*!< in: pointer to data type struct */
- MY_ATTRIBUTE((nonnull));
+ const dtype_t* type); /*!< in: pointer to data type struct */
+
/*********************************************************************//**
Gets length of field data.
@return length of data; UNIV_SQL_NULL if SQL null data */
@@ -116,6 +116,23 @@ dfield_set_ext(
/*===========*/
dfield_t* field) /*!< in/out: field */
MY_ATTRIBUTE((nonnull));
+
+/** Gets spatial status for "external storage"
+@param[in,out] field field */
+UNIV_INLINE
+spatial_status_t
+dfield_get_spatial_status(
+ const dfield_t* field);
+
+/** Sets spatial status for "external storage"
+@param[in,out] field field
+@param[in] spatial_status spatial status */
+UNIV_INLINE
+void
+dfield_set_spatial_status(
+ dfield_t* field,
+ spatial_status_t spatial_status);
+
/*********************************************************************//**
Sets pointer to the data and length in a field. */
UNIV_INLINE
@@ -134,7 +151,7 @@ dfield_write_mbr(
/*=============*/
dfield_t* field, /*!< in: field */
const double* mbr) /*!< in: data */
- __attribute__((nonnull(1)));
+ MY_ATTRIBUTE((nonnull(1)));
/*********************************************************************//**
Sets a data field to SQL NULL. */
UNIV_INLINE
@@ -159,8 +176,8 @@ void
dfield_copy_data(
/*=============*/
dfield_t* field1, /*!< out: field to copy to */
- const dfield_t* field2) /*!< in: field to copy from */
- MY_ATTRIBUTE((nonnull));
+ const dfield_t* field2); /*!< in: field to copy from */
+
/*********************************************************************//**
Copies a data field to another. */
UNIV_INLINE
@@ -408,7 +425,7 @@ int
dtuple_coll_cmp(
const dtuple_t* tuple1,
const dtuple_t* tuple2)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Fold a prefix given as the number of fields of a tuple.
@param[in] tuple index record
@param[in] n_fields number of complete fields to fold
@@ -422,7 +439,7 @@ dtuple_fold(
ulint n_fields,
ulint n_bytes,
index_id_t tree_id)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************************//**
Sets types of fields binary in a tuple. */
UNIV_INLINE
@@ -544,7 +561,7 @@ dtuple_convert_big_rec(
dtuple_t* entry, /*!< in/out: index entry */
ulint* n_ext) /*!< in/out: number of
externally stored columns */
- MY_ATTRIBUTE((nonnull(1,4), malloc, warn_unused_result));
+ MY_ATTRIBUTE((malloc, warn_unused_result));
/**************************************************************//**
Puts back to entry the data stored in vector. Note that to ensure the
fields in entry can accommodate the data, vector must have been created
@@ -572,7 +589,10 @@ dtuple_big_rec_free(
/** Structure for an SQL data field */
struct dfield_t{
void* data; /*!< pointer to data */
- unsigned ext; /*!< TRUE=externally stored, FALSE=local */
+ unsigned ext:1; /*!< TRUE=externally stored, FALSE=local */
+ unsigned spatial_status:2;
+ /*!< spatial status of externally stored field
+ in undo log for purge */
unsigned len; /*!< data length; UNIV_SQL_NULL if SQL null */
dtype_t type; /*!< type of data */
diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic
index c6c155c6b61..dc51735d340 100644
--- a/storage/innobase/include/data0data.ic
+++ b/storage/innobase/include/data0data.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -157,6 +157,34 @@ dfield_set_ext(
field->ext = 1;
}
+/** Gets spatial status for "external storage"
+@param[in,out] field field */
+UNIV_INLINE
+spatial_status_t
+dfield_get_spatial_status(
+ const dfield_t* field)
+{
+ ut_ad(field);
+ ut_ad(dfield_is_ext(field));
+
+ return(static_cast<spatial_status_t>(field->spatial_status));
+}
+
+/** Sets spatial status for "external storage"
+@param[in,out] field field
+@param[in] spatial_status spatial status */
+UNIV_INLINE
+void
+dfield_set_spatial_status(
+ dfield_t* field,
+ spatial_status_t spatial_status)
+{
+ ut_ad(field);
+ ut_ad(dfield_is_ext(field));
+
+ field->spatial_status = spatial_status;
+}
+
/*********************************************************************//**
Sets pointer to the data and length in a field. */
UNIV_INLINE
@@ -227,6 +255,7 @@ dfield_copy_data(
field1->data = field2->data;
field1->len = field2->len;
field1->ext = field2->ext;
+ field1->spatial_status = field2->spatial_status;
}
/*********************************************************************//**
diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h
index 5297d6b0daf..32f9117af84 100644
--- a/storage/innobase/include/db0err.h
+++ b/storage/innobase/include/db0err.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -137,6 +137,7 @@ enum dberr_t {
/*< Too many words in a phrase */
DB_TABLESPACE_TRUNCATED, /*!< tablespace was truncated */
+
DB_DECRYPTION_FAILED, /* Tablespace encrypted and
decrypt operation failed because
of missing key management plugin,
@@ -157,6 +158,12 @@ enum dberr_t {
DB_IO_NO_PUNCH_HOLE_TABLESPACE, /*!< The tablespace doesn't support
punch hole */
+ DB_IO_DECRYPT_FAIL, /*!< Failure to decrypt a page
+ after reading it from disk */
+
+ DB_IO_NO_ENCRYPT_TABLESPACE, /*!< The tablespace doesn't support
+ encrypt */
+
DB_IO_PARTIAL_FAILED, /*!< Partial IO request failed */
DB_FORCED_ABORT, /*!< Transaction was forced to rollback
@@ -169,6 +176,10 @@ enum dberr_t {
DB_COMPUTE_VALUE_FAILED, /*!< Compute generated value failed */
+ DB_NO_FK_ON_S_BASE_COL, /*!< Cannot add foreign constrain
+ placed on the base column of
+ stored column */
+
/* The following are partial failure codes */
DB_FAIL = 1000,
DB_OVERFLOW,
diff --git a/storage/innobase/include/dict0crea.h b/storage/innobase/include/dict0crea.h
index 7915d694c2d..f9ef39fa8c6 100644
--- a/storage/innobase/include/dict0crea.h
+++ b/storage/innobase/include/dict0crea.h
@@ -213,6 +213,20 @@ dict_create_add_foreigns_to_dictionary(
const dict_table_t* table,
trx_t* trx)
MY_ATTRIBUTE((nonnull, warn_unused_result));
+
+/** Check if a foreign constraint is on columns server as base columns
+of any stored column. This is to prevent creating SET NULL or CASCADE
+constraint on such columns
+@param[in] local_fk_set set of foreign key objects, to be added to
+the dictionary tables
+@param[in] table table to which the foreign key objects in
+local_fk_set belong to
+@return true if yes, otherwise, false */
+bool
+dict_foreigns_has_s_base_col(
+ const dict_foreign_set& local_fk_set,
+ const dict_table_t* table);
+
/****************************************************************//**
Creates the tablespaces and datafiles system tables inside InnoDB
at server bootstrap or server start if they are not found or are
diff --git a/storage/innobase/include/dict0defrag_bg.h b/storage/innobase/include/dict0defrag_bg.h
new file mode 100644
index 00000000000..eb2a6e6824f
--- /dev/null
+++ b/storage/innobase/include/dict0defrag_bg.h
@@ -0,0 +1,93 @@
+/*****************************************************************************
+
+Copyright (c) 2016, MariaDB Corporation. All rights Reserved.
+
+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, Suite 500, Boston, MA 02110-1335 USA
+
+*****************************************************************************/
+
+/**************************************************//**
+@file include/dict0defrag_bg.h
+Code used for background table and index
+defragmentation
+
+Created 25/08/2016 Jan Lindström
+*******************************************************/
+
+#ifndef dict0defrag_bg_h
+#define dict0defrag_bg_h
+
+#include "univ.i"
+
+#include "dict0types.h"
+#include "os0event.h"
+#include "os0thread.h"
+
+/*****************************************************************//**
+Initialize the defrag pool, called once during thread initialization. */
+void
+dict_defrag_pool_init(void);
+/*========================*/
+
+/*****************************************************************//**
+Free the resources occupied by the defrag pool, called once during
+thread de-initialization. */
+void
+dict_defrag_pool_deinit(void);
+/*==========================*/
+
+/*****************************************************************//**
+Add an index in a table to the defrag pool, which is processed by the
+background stats gathering thread. Only the table id and index id are
+added to the list, so the table can be closed after being enqueued and
+it will be opened when needed. If the table or index does not exist later
+(has been DROPped), then it will be removed from the pool and skipped. */
+void
+dict_stats_defrag_pool_add(
+/*=======================*/
+ const dict_index_t* index); /*!< in: table to add */
+
+/*****************************************************************//**
+Delete a given index from the auto defrag pool. */
+void
+dict_stats_defrag_pool_del(
+/*=======================*/
+ const dict_table_t* table, /*!<in: if given, remove
+ all entries for the table */
+ const dict_index_t* index); /*!< in: index to remove */
+
+/*****************************************************************//**
+Get the first index that has been added for updating persistent defrag
+stats and eventually save its stats. */
+void
+dict_defrag_process_entries_from_defrag_pool();
+/*===========================================*/
+
+/*********************************************************************//**
+Save defragmentation result.
+@return DB_SUCCESS or error code */
+dberr_t
+dict_stats_save_defrag_summary(
+/*============================*/
+ dict_index_t* index) /*!< in: index */
+ MY_ATTRIBUTE((warn_unused_result));
+
+/*********************************************************************//**
+Save defragmentation stats for a given index.
+@return DB_SUCCESS or error code */
+dberr_t
+dict_stats_save_defrag_stats(
+/*============================*/
+ dict_index_t* index) /*!< in: index */
+ MY_ATTRIBUTE((warn_unused_result));
+#endif /* dict0defrag_bg_h */
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index af7b91f9662..5022245c195 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -125,7 +125,7 @@ dict_table_open_on_id(
table_id_t table_id, /*!< in: table id */
ibool dict_locked, /*!< in: TRUE=data dictionary locked */
dict_table_op_t table_op) /*!< in: operation to perform */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Returns a table object based on table id.
@@ -309,7 +309,7 @@ ulint
dict_col_get_index_pos(
const dict_col_t* col,
const dict_index_t* index)
- __attribute__((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/****************************************************************//**
If the given column name is reserved for InnoDB system columns, return
@@ -389,7 +389,7 @@ dict_table_add_system_columns(
void
dict_table_set_big_rows(
dict_table_t* table)
- __attribute__((nonnull));
+ MY_ATTRIBUTE((nonnull));
/**********************************************************************//**
Adds a table object to the dictionary cache. */
void
@@ -531,7 +531,7 @@ dict_create_foreign_constraints(
size_t sql_length,
const char* name,
ibool reject_fks)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement.
@return DB_SUCCESS or DB_CANNOT_DROP_CONSTRAINT if syntax error or the
@@ -565,7 +565,7 @@ dict_table_open_on_name(
ibool dict_locked,
ibool try_drop,
dict_err_ignore_t ignore_err)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Tries to find an index whose first fields are the columns in the array,
@@ -598,7 +598,7 @@ dict_foreign_find_index(
/*!< out: column number where
error happened */
dict_index_t** err_index)
- /*!< out: index where error
+ /*!< out: index where error
happened */
MY_ATTRIBUTE((nonnull(1,3), warn_unused_result));
@@ -624,7 +624,7 @@ dict_table_get_col_name_for_mysql(
const dict_table_t* table, /*!< in: table */
const char* col_name)/*!< in: MySQL table column name */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-
+
/** Returns a virtual column's name.
@param[in] table table object
@param[in] col_nr virtual column number(nth virtual column)
@@ -634,7 +634,8 @@ dict_table_get_v_col_name(
const dict_table_t* table,
ulint col_nr);
-/**********************************************************************//**
+/** Check if the table has a given column.
+@param[in] table table object
@param[in] col_name column name
@param[in] col_nr column number guessed, 0 as default
@return column number if the table has the specified column,
@@ -656,6 +657,7 @@ dict_print_info_on_foreign_keys(
of SHOW TABLE STATUS */
trx_t* trx, /*!< in: transaction */
dict_table_t* table); /*!< in: table */
+
/**********************************************************************//**
Outputs info on a foreign key of a table in a format suitable for
CREATE TABLE. */
@@ -665,6 +667,7 @@ dict_print_info_on_foreign_key_in_create_format(
trx_t* trx, /*!< in: transaction */
dict_foreign_t* foreign, /*!< in: foreign key constraint */
ibool add_newline); /*!< in: whether to add a newline */
+
/*********************************************************************//**
Tries to find an index whose first fields are the columns in the array,
in the same order and is not marked for deletion and is not the same
@@ -756,7 +759,7 @@ ulint
dict_index_is_clust(
/*================*/
const dict_index_t* index) /*!< in: index */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Check if index is auto-generated clustered index.
@param[in] index index
@@ -775,7 +778,7 @@ ulint
dict_index_is_unique(
/*=================*/
const dict_index_t* index) /*!< in: index */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Check whether the index is a Spatial Index.
@return nonzero for Spatial Index, zero for other indexes */
@@ -784,7 +787,7 @@ ulint
dict_index_is_spatial(
/*==================*/
const dict_index_t* index) /*!< in: index */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Check whether the index contains a virtual column.
@param[in] index index
@return nonzero for index on virtual column, zero for other indexes */
@@ -800,7 +803,7 @@ ulint
dict_index_is_ibuf(
/*===============*/
const dict_index_t* index) /*!< in: index */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Check whether the index is a secondary index or the insert buffer tree.
@return nonzero for insert buffer, zero for other indexes */
@@ -809,7 +812,7 @@ ulint
dict_index_is_sec_or_ibuf(
/*======================*/
const dict_index_t* index) /*!< in: index */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Get all the FTS indexes on a table.
@param[in] table table
@@ -830,7 +833,7 @@ ulint
dict_table_get_n_user_cols(
/*=======================*/
const dict_table_t* table) /*!< in: table */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Gets the number of user-defined virtual and non-virtual columns in a table
in the dictionary cache.
@param[in] table table
@@ -849,7 +852,7 @@ ulint
dict_table_get_n_sys_cols(
/*======================*/
const dict_table_t* table) /*!< in: table */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Gets the number of all non-virtual columns (also system) in a table
in the dictionary cache.
@@ -859,7 +862,7 @@ ulint
dict_table_get_n_cols(
/*==================*/
const dict_table_t* table) /*!< in: table */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Gets the number of virtual columns in a table in the dictionary cache.
@param[in] table the table to check
@@ -885,7 +888,7 @@ ib_uint64_t
dict_table_get_n_rows(
/*==================*/
const dict_table_t* table) /*!< in: table */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Increment the number of rows in the table by one.
Notice that this operation is not protected by any latch, the number is
@@ -1005,6 +1008,7 @@ dict_tf_get_format(
/*===============*/
ulint flags) /*!< in: dict_table_t::flags */
MY_ATTRIBUTE((warn_unused_result));
+
/** Set the various values in a dict_table_t::flags pointer.
@param[in,out] flags, Pointer to a 4 byte Table Flags
@param[in] format, File Format
@@ -1053,11 +1057,13 @@ fil_space_t::flags | 0 | 0 | 1 | 1
==================================================================
@param[in] table_flags dict_table_t::flags
@param[in] is_temp whether the tablespace is temporary
+@param[in] is_encrypted whether the tablespace is encrypted
@return tablespace flags (fil_space_t::flags) */
ulint
dict_tf_to_fsp_flags(
ulint table_flags,
- bool is_temp)
+ bool is_temp,
+ bool is_encrypted = false)
MY_ATTRIBUTE((const));
/** Extract the page size from table flags.
@@ -1067,7 +1073,7 @@ UNIV_INLINE
const page_size_t
dict_tf_get_page_size(
ulint flags)
-__attribute__((const));
+MY_ATTRIBUTE((const));
/** Determine the extent size (in pages) for the given table
@param[in] table the table whose extent size is being
@@ -1084,7 +1090,7 @@ UNIV_INLINE
const page_size_t
dict_table_page_size(
const dict_table_t* table)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
@@ -1194,7 +1200,7 @@ dict_index_add_to_cache(
dict_index_t* index,
ulint page_no,
ibool strict)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Adds an index to the dictionary cache, with possible indexing newly
added column.
@@ -1215,7 +1221,7 @@ dict_index_add_to_cache_w_vcol(
const dict_add_v_col_t* add_v,
ulint page_no,
ibool strict)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Gets the number of fields in the internal representation of an index,
@@ -1269,7 +1275,7 @@ UNIV_INLINE
ulint
dict_index_get_n_unique_in_tree_nonleaf(
const dict_index_t* index)
- __attribute__((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/********************************************************************//**
Gets the number of user-defined ordering fields in the index. In the internal
representation we add the row id to the ordering fields to make all indexes
@@ -1327,9 +1333,9 @@ dict_index_get_nth_col_pos(
/*=======================*/
const dict_index_t* index, /*!< in: index */
ulint n, /*!< in: column number */
- ulint* prefix_col_pos) /*!< out: col num if prefix
- */
- __attribute__((warn_unused_result));
+ ulint* prefix_col_pos) /*!< out: col num if prefix */
+ MY_ATTRIBUTE((nonnull(1), warn_unused_result));
+
/** Looks for column n in an index.
@param[in] index index
@param[in] n column number
@@ -1362,7 +1368,7 @@ dict_index_contains_col_or_prefix(
ulint n, /*!< in: column number */
bool is_virtual)
/*!< in: whether it is a virtual col */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Looks for a matching field in an index. The column has to be the same. The
column in index must be complete, or must contain a prefix longer than the
@@ -1386,7 +1392,7 @@ dict_table_get_nth_col_pos(
const dict_table_t* table, /*!< in: table */
ulint n, /*!< in: column number */
ulint* prefix_col_pos) /*!< out: col num if prefix */
- __attribute__((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((nonnull(1), warn_unused_result));
/********************************************************************//**
Returns the position of a system column in an index.
@return position, ULINT_UNDEFINED if not contained */
@@ -1668,6 +1674,7 @@ dict_tables_have_same_db(
const char* name2) /*!< in: table name in the form
dbname '/' tablename */
MY_ATTRIBUTE((nonnull, warn_unused_result));
+
/** Get an index by name.
@param[in] table the table where to look for the index
@param[in] name the index name to look for
@@ -1679,19 +1686,13 @@ dict_table_get_index_on_name(
dict_table_t* table,
const char* name,
bool committed=true)
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
+
/** Get an index by name.
@param[in] table the table where to look for the index
@param[in] name the index name to look for
@param[in] committed true=search for committed,
-false=search for uncommitted */
-dict_index_t*
-dict_table_find_index_on_id(
-/*========================*/
- const dict_table_t* table, /*!< in: table instance */
- index_id_t id) /*!< in: index id */
- __attribute__((nonnull, warn_unused_result));
-/**********************************************************************//**
+false=search for uncommitted
@return index, NULL if does not exist */
inline
const dict_index_t*
@@ -1715,7 +1716,7 @@ dict_table_is_fts_column(
ib_vector_t* indexes,/* in: vector containing only FTS indexes */
ulint col_no, /* in: col number to search for */
bool is_virtual)/*!< in: whether it is a virtual column */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Prevent table eviction by moving a table to the non-LRU list from the
LRU list if it is not already there. */
@@ -1724,7 +1725,8 @@ void
dict_table_prevent_eviction(
/*========================*/
dict_table_t* table) /*!< in: table to prevent eviction */
- __attribute__((nonnull));
+ MY_ATTRIBUTE((nonnull));
+
/**********************************************************************//**
Move a table to the non LRU end of the LRU list. */
void
@@ -1732,6 +1734,7 @@ dict_table_move_from_lru_to_non_lru(
/*================================*/
dict_table_t* table) /*!< in: table to move from LRU to non-LRU */
MY_ATTRIBUTE((nonnull));
+
/** Looks for an index with the given id given a table instance.
@param[in] table table instance
@param[in] id index id
@@ -1741,6 +1744,7 @@ dict_table_find_index_on_id(
const dict_table_t* table,
index_id_t id)
MY_ATTRIBUTE((nonnull(1)));
+
/**********************************************************************//**
Move to the most recently used segment of the LRU list. */
void
@@ -1990,7 +1994,7 @@ bool
dict_table_is_discarded(
/*====================*/
const dict_table_t* table) /*!< in: table to check */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Check if it is a temporary table.
@@ -2000,7 +2004,17 @@ bool
dict_table_is_temporary(
/*====================*/
const dict_table_t* table) /*!< in: table to check */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
+
+/********************************************************************//**
+Check if it is a encrypted table.
+@return true if table encryption flag is set. */
+UNIV_INLINE
+bool
+dict_table_is_encrypted(
+/*====================*/
+ const dict_table_t* table) /*!< in: table to check */
+ MY_ATTRIBUTE((warn_unused_result));
/** Check whether the table is intrinsic.
An intrinsic table is a special kind of temporary table that
@@ -2018,7 +2032,16 @@ UNIV_INLINE
bool
dict_table_is_intrinsic(
const dict_table_t* table)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
+
+/** Check if the table is in a shared tablespace (System or General).
+@param[in] id Space ID to check
+@return true if id is a shared tablespace, false if not. */
+UNIV_INLINE
+bool
+dict_table_in_shared_tablespace(
+ const dict_table_t* table)
+ MY_ATTRIBUTE((warn_unused_result));
/** Check whether locking is disabled for this table.
Currently this is done for intrinsic table as their visibility is limited
@@ -2030,7 +2053,7 @@ UNIV_INLINE
bool
dict_table_is_locking_disabled(
const dict_table_t* table)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Turn-off redo-logging if temporary table. */
@@ -2105,7 +2128,7 @@ ulint
dict_index_node_ptr_max_size(
/*=========================*/
const dict_index_t* index) /*!< in: index */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*****************************************************************//**
Get index by first field of the index
@return index which is having first field matches
@@ -2149,12 +2172,34 @@ dict_table_decode_n_col(
ulint* n_v_col);
/** Look for any dictionary objects that are found in the given tablespace.
-@param[in] space Tablespace ID to search for.
+@param[in] space_id Tablespace ID to search for.
@return true if tablespace is empty. */
bool
-dict_tablespace_is_empty(
+dict_space_is_empty(
ulint space_id);
+/** Find the space_id for the given name in sys_tablespaces.
+@param[in] name Tablespace name to search for.
+@return the tablespace ID. */
+ulint
+dict_space_get_id(
+ const char* name);
+
+/** Free the virtual column template
+@param[in,out] vc_templ virtual column template */
+UNIV_INLINE
+void
+dict_free_vc_templ(
+ dict_vcol_templ_t* vc_templ);
+
+/** Check whether the table have virtual index.
+@param[in] table InnoDB table
+@return true if the table have virtual index, false otherwise. */
+UNIV_INLINE
+bool
+dict_table_have_virtual_index(
+ dict_table_t* table);
+
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index 9aa25b0a9c5..1a038d4f104 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates
+Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2016, MariaDB Corporation
This program is free software; you can redistribute it and/or modify it under
@@ -338,6 +338,21 @@ dict_index_is_unique(
}
/********************************************************************//**
+Check whether the index is an universal index tree.
+@return nonzero for universal tree, zero for other indexes */
+UNIV_INLINE
+ulint
+dict_index_is_univ(
+/*===============*/
+ const dict_index_t* index) /*!< in: index */
+{
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+
+ return(index->type & DICT_UNIVERSAL);
+}
+
+/********************************************************************//**
Check whether the index is a Spatial Index.
@return nonzero for Spatial Index, zero for other indexes */
UNIV_INLINE
@@ -711,7 +726,7 @@ dict_tf_is_valid(
}
}
- if (page_compression || page_compression_level) {
+ if (page_compression || page_compression_level) {
/* Page compression format must have compact and
atomic_blobs and page_compression_level requires
page_compression */
@@ -774,6 +789,7 @@ dict_tf2_is_valid(
bool file_per_table = ((flags2 & DICT_TF2_USE_FILE_PER_TABLE) != 0);
bool shared_space = DICT_TF_HAS_SHARED_SPACE(flags);
+
if (file_per_table && shared_space) {
return(false);
}
@@ -869,13 +885,13 @@ dict_sys_tables_type_validate(
format, so the DATA_DIR flag is compatible with any other
table flags. However, it is not used with TEMPORARY tables. */
- if (page_compression || page_compression_level) {
+ if (page_compression || page_compression_level) {
/* page compressed row format must have low_order_bit and
atomic_blobs bits set and the DICT_N_COLS_COMPACT flag
should be in N_COLS, but we already know about the
low_order_bit and DICT_N_COLS_COMPACT flags. */
- if (!atomic_blobs || !page_compression) {
+ if (!atomic_blobs || !page_compression) {
ib::error() << "SYS_TABLES::TYPE=" << type
<< " page_compression:" << page_compression
<< " page_compression_level:" << page_compression_level
@@ -1008,7 +1024,7 @@ dict_tf_set(
if (page_compressed) {
*flags |= (1 << DICT_TF_POS_ATOMIC_BLOBS)
- | (1 << DICT_TF_POS_PAGE_COMPRESSION)
+ | (1 << DICT_TF_POS_PAGE_COMPRESSION)
| (page_compression_level << DICT_TF_POS_PAGE_COMPRESSION_LEVEL);
ut_ad(zip_ssize == 0);
@@ -1067,7 +1083,7 @@ dict_tf_init(
if (page_compressed) {
flags |= (1 << DICT_TF_POS_ATOMIC_BLOBS)
- | (1 << DICT_TF_POS_PAGE_COMPRESSION)
+ | (1 << DICT_TF_POS_PAGE_COMPRESSION)
| (page_compression_level << DICT_TF_POS_PAGE_COMPRESSION_LEVEL);
ut_ad(zip_ssize == 0);
@@ -1706,9 +1722,11 @@ dict_max_v_field_len_store_undo(
for UNIV_FORMAT_B, upto col->max_prefix or
2) REC_VERSION_56_MAX_INDEX_COL_LEN, whichever is less */
if (dict_table_get_format(table) >= UNIV_FORMAT_B) {
- max_log_len = (col->max_prefix > 0)
- ? col->max_prefix
- : DICT_MAX_FIELD_LEN_BY_FORMAT(table);
+ if (DATA_BIG_COL(col) && col->max_prefix > 0) {
+ max_log_len = col->max_prefix;
+ } else {
+ max_log_len = DICT_MAX_FIELD_LEN_BY_FORMAT(table);
+ }
} else {
max_log_len = REC_ANTELOPE_MAX_INDEX_COL_LEN;
}
@@ -1786,6 +1804,18 @@ dict_table_is_temporary(
return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY));
}
+/********************************************************************//**
+Check if it is a encrypted table.
+@return true if table encrypted flag is set. */
+UNIV_INLINE
+bool
+dict_table_is_encrypted(
+/*====================*/
+ const dict_table_t* table) /*!< in: table to check */
+{
+ return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_ENCRYPTION));
+}
+
/** Check whether the table is intrinsic.
An intrinsic table is a special kind of temporary table that
is invisible to the end user. It can be created internally by InnoDB, the MySQL
@@ -1806,6 +1836,18 @@ dict_table_is_intrinsic(
return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_INTRINSIC));
}
+/** Check if the table is in a shared tablespace (System or General).
+@param[in] id Space ID to check
+@return true if id is a shared tablespace, false if not. */
+UNIV_INLINE
+bool
+dict_table_in_shared_tablespace(
+ const dict_table_t* table)
+{
+ return(is_system_tablespace(table->space)
+ || DICT_TF_HAS_SHARED_SPACE(table->flags));
+}
+
/** Check whether locking is disabled for this table.
Currently this is done for intrinsic table as their visibility is limited
to the connection only.
@@ -2003,4 +2045,45 @@ dict_table_decode_n_col(
*n_col = num & 0xFFFF;
}
+/** Free the virtual column template
+@param[in,out] vc_templ virtual column template */
+void
+dict_free_vc_templ(
+ dict_vcol_templ_t* vc_templ)
+{
+ if (vc_templ->vtempl != NULL) {
+ ut_ad(vc_templ->n_v_col > 0);
+ for (ulint i = 0; i < vc_templ->n_col
+ + vc_templ->n_v_col; i++) {
+ if (vc_templ->vtempl[i] != NULL) {
+ ut_free(vc_templ->vtempl[i]);
+ }
+ }
+ ut_free(vc_templ->default_rec);
+ ut_free(vc_templ->vtempl);
+ vc_templ->vtempl = NULL;
+ }
+}
+
+/** Check whether the table have virtual index.
+@param[in] table InnoDB table
+@return true if the table have virtual index, false otherwise. */
+UNIV_INLINE
+bool
+dict_table_have_virtual_index(
+ dict_table_t* table)
+{
+ for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(table);
+ col_no++) {
+ const dict_v_col_t* col
+ = dict_table_get_nth_v_col(table, col_no);
+
+ if (col->m_col.ord_part) {
+ return(true);
+ }
+ }
+
+ return(false);
+}
+
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h
index 8e62022de85..6d01c38c432 100644
--- a/storage/innobase/include/dict0load.h
+++ b/storage/innobase/include/dict0load.h
@@ -184,6 +184,14 @@ dict_save_data_dir_path(
dict_table_t* table, /*!< in/out: table */
char* filepath); /*!< in: filepath of tablespace */
+/** Get the first filepath from SYS_DATAFILES for a given space_id.
+@param[in] space_id Tablespace ID
+@return First filepath (caller must invoke ut_free() on it)
+@retval NULL if no SYS_DATAFILES entry was found. */
+char*
+dict_get_first_path(
+ ulint space_id);
+
/** Make sure the data_file_name is saved in dict_table_t if needed.
Try to read it from the fil_system first, then from SYS_DATAFILES.
@param[in] table Table object
@@ -262,7 +270,7 @@ dict_load_foreigns(
which must be loaded
subsequently to load all the
foreign key constraints. */
- __attribute__((nonnull(1), warn_unused_result));
+ MY_ATTRIBUTE((nonnull(1), warn_unused_result));
/********************************************************************//**
This function opens a system table, and return the first record.
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 98ce7d3bd33..4fac0648bcb 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -49,6 +49,8 @@ Created 1/8/1996 Heikki Tuuri
#include "buf0buf.h"
#include "gis0type.h"
#include "os0once.h"
+#include "ut0new.h"
+
#include "fil0fil.h"
#include <my_crypt.h>
#include "fil0crypt.h"
@@ -67,6 +69,8 @@ combination of types */
auto-generated clustered indexes,
also DICT_UNIQUE will be set */
#define DICT_UNIQUE 2 /*!< unique index */
+#define DICT_UNIVERSAL 4 /*!< index which can contain records from any
+ other index */
#define DICT_IBUF 8 /*!< insert buffer tree */
#define DICT_CORRUPT 16 /*!< bit to store the corrupted flag
in SYS_INDEXES.TYPE */
@@ -170,9 +174,9 @@ DEFAULT=0, ON = 1, OFF = 2
+ DICT_TF_WIDTH_SHARED_SPACE \
+ DICT_TF_WIDTH_PAGE_COMPRESSION \
+ DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL \
- + DICT_TF_WIDTH_ATOMIC_WRITES \
- + DICT_TF_WIDTH_PAGE_ENCRYPTION \
- + DICT_TF_WIDTH_PAGE_ENCRYPTION_KEY)
+ + DICT_TF_WIDTH_ATOMIC_WRITES \
+ + DICT_TF_WIDTH_PAGE_ENCRYPTION \
+ + DICT_TF_WIDTH_PAGE_ENCRYPTION_KEY)
/** A mask of all the known/used bits in table flags */
#define DICT_TF_BIT_MASK (~(~0 << DICT_TF_BITS))
@@ -305,7 +309,7 @@ ROW_FORMAT=REDUNDANT. InnoDB engines do not check these flags
for unknown bits in order to protect backward incompatibility. */
/* @{ */
/** Total number of bits in table->flags2. */
-#define DICT_TF2_BITS 8
+#define DICT_TF2_BITS 9
#define DICT_TF2_UNUSED_BIT_MASK (~0U << DICT_TF2_BITS)
#define DICT_TF2_BIT_MASK ~DICT_TF2_UNUSED_BIT_MASK
@@ -339,6 +343,9 @@ FTS, etc.... Intrinsic table has all the properties of the normal table except
it is not created by user and so not visible to end-user. */
#define DICT_TF2_INTRINSIC 128
+/** Encryption table bit. */
+#define DICT_TF2_ENCRYPTION 256
+
/* @} */
#define DICT_TF2_FLAG_SET(table, flag) \
@@ -431,13 +438,22 @@ dict_mem_table_add_v_col(
ulint len,
ulint pos,
ulint num_base);
+
+/** Adds a stored column definition to a table.
+@param[in] table table
+@param[in] num_base number of base columns. */
+void
+dict_mem_table_add_s_col(
+ dict_table_t* table,
+ ulint num_base);
+
/**********************************************************************//**
Renames a column of a table in the data dictionary cache. */
void
dict_mem_table_col_rename(
/*======================*/
dict_table_t* table, /*!< in/out: table */
- unsigned nth_col,/*!< in: column index */
+ ulint nth_col,/*!< in: column index */
const char* from, /*!< in: old column name */
const char* to, /*!< in: new column name */
bool is_virtual);
@@ -532,6 +548,27 @@ dict_mem_referenced_table_name_lookup_set(
dict_foreign_t* foreign, /*!< in/out: foreign struct */
ibool do_alloc); /*!< in: is an alloc needed */
+/** Fills the dependent virtual columns in a set.
+Reason for being dependent are
+1) FK can be present on base column of virtual columns
+2) FK can be present on column which is a part of virtual index
+@param[in,out] foreign foreign key information. */
+void
+dict_mem_foreign_fill_vcol_set(
+ dict_foreign_t* foreign);
+
+/** Fill virtual columns set in each fk constraint present in the table.
+@param[in,out] table innodb table object. */
+void
+dict_mem_table_fill_foreign_vcol_set(
+ dict_table_t* table);
+
+/** Free the vcol_set from all foreign key constraint on the table.
+@param[in,out] table innodb table object. */
+void
+dict_mem_table_free_foreign_vcol_set(
+ dict_table_t* table);
+
/** Create a temporary tablename like "#sql-ibtid-inc where
tid = the Table ID
inc = a randomly initialized number that is incremented for each file
@@ -696,6 +733,21 @@ struct dict_add_v_col_t{
const char** v_col_name;
};
+/** Data structure for a stored column in a table. */
+struct dict_s_col_t {
+ /** Stored column ptr */
+ dict_col_t* m_col;
+ /** array of base col ptr */
+ dict_col_t** base_col;
+ /** number of base columns */
+ ulint num_base;
+ /** column pos in table */
+ ulint s_pos;
+};
+
+/** list to put stored column for create_table_info_t */
+typedef std::list<dict_s_col_t, ut_allocator<dict_s_col_t> > dict_s_col_list;
+
/** @brief DICT_ANTELOPE_MAX_INDEX_COL_LEN is measured in bytes and
is the maximum indexed column length (or indexed prefix length) in
ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT. Also, in any format,
@@ -726,6 +778,7 @@ be REC_VERSION_56_MAX_INDEX_COL_LEN (3072) bytes */
/** Defines the maximum fixed length column size */
#define DICT_MAX_FIXED_COL_LEN DICT_ANTELOPE_MAX_INDEX_COL_LEN
+
#ifdef WITH_WSREP
#define WSREP_MAX_SUPPORTED_KEY_LENGTH 3500
#endif /* WITH_WSREP */
@@ -982,6 +1035,9 @@ struct dict_index_t{
parser; /*!< fulltext parser plugin */
bool is_ngram;
/*!< true if it's ngram parser */
+ bool has_new_v_col;
+ /*!< whether it has a newly added virtual
+ column in ALTER */
#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(dict_index_t)
indexes;/*!< list of indexes of the table */
@@ -1106,6 +1162,11 @@ enum online_index_status {
ONLINE_INDEX_ABORTED_DROPPED
};
+/** Set to store the virtual columns which are affected by Foreign
+key constraint. */
+typedef std::set<dict_v_col_t*, std::less<dict_v_col_t*>,
+ ut_allocator<dict_v_col_t*> > dict_vcol_set;
+
/** Data structure for a foreign key constraint; an example:
FOREIGN KEY (A, B) REFERENCES TABLE2 (C, D). Most fields will be
initialized to 0, NULL or FALSE in dict_mem_foreign_create(). */
@@ -1141,6 +1202,9 @@ struct dict_foreign_t{
does not generate new indexes
implicitly */
dict_index_t* referenced_index;/*!< referenced index */
+
+ dict_vcol_set* v_cols; /*!< set of virtual columns affected
+ by foreign key constraint. */
};
std::ostream&
@@ -1189,6 +1253,24 @@ struct dict_foreign_with_index {
const dict_index_t* m_index;
};
+#ifdef WITH_WSREP
+/** A function object to find a foreign key with the given index as the
+foreign index. Return the foreign key with matching criteria or NULL */
+struct dict_foreign_with_foreign_index {
+
+ dict_foreign_with_foreign_index(const dict_index_t* index)
+ : m_index(index)
+ {}
+
+ bool operator()(const dict_foreign_t* foreign) const
+ {
+ return(foreign->foreign_index == m_index);
+ }
+
+ const dict_index_t* m_index;
+};
+#endif
+
/* A function object to check if the foreign constraint is between different
tables. Returns true if foreign key constraint is between different tables,
false otherwise. */
@@ -1273,6 +1355,10 @@ dict_foreign_free(
/*==============*/
dict_foreign_t* foreign) /*!< in, own: foreign key struct */
{
+ if (foreign->v_cols != NULL) {
+ UT_DELETE(foreign->v_cols);
+ }
+
mem_heap_free(foreign->heap);
}
@@ -1332,12 +1418,42 @@ generate a specific template for it. */
typedef ut_list_base<lock_t, ut_list_node<lock_t> lock_table_t::*>
table_lock_list_t;
+/** mysql template structure defined in row0mysql.cc */
+struct mysql_row_templ_t;
+
+/** Structure defines template related to virtual columns and
+their base columns */
+struct dict_vcol_templ_t {
+ /** number of regular columns */
+ ulint n_col;
+
+ /** number of virtual columns */
+ ulint n_v_col;
+
+ /** array of templates for virtual col and their base columns */
+ mysql_row_templ_t** vtempl;
+
+ /** table's database name */
+ std::string db_name;
+
+ /** table name */
+ std::string tb_name;
+
+ /** share->table_name */
+ std::string share_name;
+
+ /** MySQL record length */
+ ulint rec_len;
+
+ /** default column value if any */
+ byte* default_rec;
+};
+
/* This flag is for sync SQL DDL and memcached DML.
if table->memcached_sync_count == DICT_TABLE_IN_DDL means there's DDL running on
the table, DML from memcached will be blocked. */
#define DICT_TABLE_IN_DDL -1
-struct innodb_col_templ_t;
/** These are used when MySQL FRM and InnoDB data dictionary are
in inconsistent state. */
typedef enum {
@@ -1363,6 +1479,7 @@ struct dict_table_t {
void* thd; /*!< thd */
fil_space_crypt_t *crypt_data; /*!< crypt data if present */
+
/** Release the table handle. */
inline void release();
@@ -1417,6 +1534,8 @@ struct dict_table_t {
5 whether the table is being created its own tablespace,
6 whether the table has been DISCARDed,
7 whether the aux FTS tables names are in hex.
+ 8 whether the table is instinc table.
+ 9 whether the table has encryption setting.
Use DICT_TF2_FLAG_IS_SET() to parse this flag. */
unsigned flags2:DICT_TF2_BITS;
@@ -1470,6 +1589,13 @@ struct dict_table_t {
/** Array of virtual column descriptions. */
dict_v_col_t* v_cols;
+ /** List of stored column descriptions. It is used only for foreign key
+ check during create table and copy alter operations.
+ During copy alter, s_cols list is filled during create table operation
+ and need to preserve till rename table operation. That is the
+ reason s_cols is a part of dict_table_t */
+ dict_s_col_list* s_cols;
+
/** Column names packed in a character string
"name1\0name2\0...nameN\0". Until the string contains n_cols, it will
be allocated from a temporary heap. The final string will be allocated
@@ -1650,15 +1776,22 @@ struct dict_table_t {
/** The state of the background stats thread wrt this table.
See BG_STAT_NONE, BG_STAT_IN_PROGRESS and BG_STAT_SHOULD_QUIT.
Writes are covered by dict_sys->mutex. Dirty reads are possible. */
-#define BG_SCRUB_IN_PROGRESS ((byte)(1 << 2))
+
+ #define BG_SCRUB_IN_PROGRESS ((byte)(1 << 2))
/*!< BG_SCRUB_IN_PROGRESS is set in
stats_bg_flag when the background
scrub code is working on this table. The DROP
TABLE code waits for this to be cleared
before proceeding. */
-#define BG_IN_PROGRESS (BG_STAT_IN_PROGRESS | BG_SCRUB_IN_PROGRESS)
+ #define BG_STAT_SHOULD_QUIT (1 << 1)
+
+ #define BG_IN_PROGRESS (BG_STAT_IN_PROGRESS | BG_SCRUB_IN_PROGRESS)
+
+ /** The state of the background stats thread wrt this table.
+ See BG_STAT_NONE, BG_STAT_IN_PROGRESS and BG_STAT_SHOULD_QUIT.
+ Writes are covered by dict_sys->mutex. Dirty reads are possible. */
byte stats_bg_flag;
bool stats_error_printed;
@@ -1752,8 +1885,10 @@ public:
but just need a increased counter to track consistent view while
proceeding SELECT as part of UPDATE. */
ib_uint64_t sess_trx_id;
+
#endif /* !UNIV_HOTBACKUP */
- ibool is_encrypted;
+
+ bool is_encrypted;
#ifdef UNIV_DEBUG
/** Value of 'magic_n'. */
@@ -1764,10 +1899,13 @@ public:
#endif /* UNIV_DEBUG */
/** mysql_row_templ_t for base columns used for compute the virtual
columns */
- innodb_col_templ_t* vc_templ;
+ dict_vcol_templ_t* vc_templ;
- /** whether above vc_templ comes from purge allocation */
- bool vc_templ_purge;
+ /** encryption key, it's only for export/import */
+ byte* encryption_key;
+
+ /** encryption iv, it's only for export/import */
+ byte* encryption_iv;
};
/*******************************************************************//**
@@ -1871,29 +2009,20 @@ dict_table_autoinc_own(
}
#endif /* UNIV_DEBUG */
-/** whether a col is used in spatial index or regular index */
-enum col_spatial_status {
- /** Not used in gis index. */
- SPATIAL_NONE = 0,
-
- /** Used in both spatial index and regular index. */
- SPATIAL_MIXED = 1,
-
- /** Only used in spatial index. */
- SPATIAL_ONLY = 2
-};
-
/** Check whether the col is used in spatial index or regular index.
@param[in] col column to check
-@return col_spatial_status */
+@return spatial status */
inline
-col_spatial_status
+spatial_status_t
dict_col_get_spatial_status(
const dict_col_t* col)
{
- col_spatial_status spatial_status = SPATIAL_NONE;
+ spatial_status_t spatial_status = SPATIAL_NONE;
- ut_ad(col->ord_part);
+ /* Column is not a part of any index. */
+ if (!col->ord_part) {
+ return(spatial_status);
+ }
if (DATA_GEOMETRY_MTYPE(col->mtype)) {
if (col->max_prefix == 0) {
diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h
index 40f254bd743..8941b399f7d 100644
--- a/storage/innobase/include/dict0stats.h
+++ b/storage/innobase/include/dict0stats.h
@@ -233,6 +233,42 @@ dict_stats_empty_defrag_stats(
dict_index_t* index); /*!< in: index to clear defragmentation stats */
+/*********************************************************************//**
+Renames an index in InnoDB persistent stats storage.
+This function creates its own transaction and commits it.
+@return DB_SUCCESS or error code. DB_STATS_DO_NOT_EXIST will be returned
+if the persistent stats do not exist. */
+dberr_t
+dict_stats_rename_index(
+/*====================*/
+ const dict_table_t* table, /*!< in: table whose index
+ is renamed */
+ const char* old_index_name, /*!< in: old index name */
+ const char* new_index_name) /*!< in: new index name */
+ MY_ATTRIBUTE((warn_unused_result));
+
+/** Save an individual index's statistic into the persistent statistics
+storage.
+@param[in] index index to be updated
+@param[in] last_update timestamp of the stat
+@param[in] stat_name name of the stat
+@param[in] stat_value value of the stat
+@param[in] sample_size n pages sampled or NULL
+@param[in] stat_description description of the stat
+@param[in,out] trx in case of NULL the function will
+allocate and free the trx object. If it is not NULL then it will be
+rolled back only in the case of error, but not freed.
+@return DB_SUCCESS or error code */
+dberr_t
+dict_stats_save_index_stat(
+ dict_index_t* index,
+ lint last_update,
+ const char* stat_name,
+ ib_uint64_t stat_value,
+ ib_uint64_t* sample_size,
+ const char* stat_description,
+ trx_t* trx);
+
#ifndef UNIV_NONINL
#include "dict0stats.ic"
#endif
diff --git a/storage/innobase/include/dict0stats_bg.h b/storage/innobase/include/dict0stats_bg.h
index e04d9ab5ab9..50c2591332e 100644
--- a/storage/innobase/include/dict0stats_bg.h
+++ b/storage/innobase/include/dict0stats_bg.h
@@ -39,6 +39,11 @@ extern os_event_t dict_stats_event;
extern mysql_pfs_key_t dict_stats_recalc_pool_mutex_key;
#endif /* HAVE_PSI_INTERFACE */
+#ifdef UNIV_DEBUG
+/** Value of MySQL global used to disable dict_stats thread. */
+extern my_bool innodb_dict_stats_disabled_debug;
+#endif /* UNIV_DEBUG */
+
/*****************************************************************//**
Add a table to the recalc pool, which is processed by the
background stats gathering thread. Only the table id is added to the
@@ -58,28 +63,6 @@ dict_stats_recalc_pool_del(
/*=======================*/
const dict_table_t* table); /*!< in: table to remove */
-/*****************************************************************//**
-Add an index in a table to the defrag pool, which is processed by the
-background stats gathering thread. Only the table id and index id are
-added to the list, so the table can be closed after being enqueued and
-it will be opened when needed. If the table or index does not exist later
-(has been DROPped), then it will be removed from the pool and skipped. */
-UNIV_INTERN
-void
-dict_stats_defrag_pool_add(
-/*=======================*/
- const dict_index_t* index); /*!< in: table to add */
-
-/*****************************************************************//**
-Delete a given index from the auto defrag pool. */
-UNIV_INTERN
-void
-dict_stats_defrag_pool_del(
-/*=======================*/
- const dict_table_t* table, /*!<in: if given, remove
- all entries for the table */
- const dict_index_t* index); /*!< in: index to remove */
-
/** Yield the data dictionary latch when waiting
for the background thread to stop accessing a table.
@param trx transaction holding the data dictionary locks */
@@ -129,6 +112,21 @@ void
dict_stats_thread_deinit();
/*======================*/
+#ifdef UNIV_DEBUG
+/** Disables dict stats thread. It's used by:
+ SET GLOBAL innodb_dict_stats_disabled_debug = 1 (0).
+@param[in] thd thread handle
+@param[in] var pointer to system variable
+@param[out] var_ptr where the formal string goes
+@param[in] save immediate result from check function */
+void
+dict_stats_disabled_debug_update(
+ THD* thd,
+ struct st_mysql_sys_var* var,
+ void* var_ptr,
+ const void* save);
+#endif /* UNIV_DEBUG */
+
/*****************************************************************//**
This is the thread for background stats gathering. It pops tables, from
the auto recalc list and proceeds them, eventually recalculating their
@@ -141,6 +139,10 @@ DECLARE_THREAD(dict_stats_thread)(
void* arg); /*!< in: a dummy parameter
required by os_thread_create */
+/** Shutdown the dict stats thread. */
+void
+dict_stats_shutdown();
+
# ifndef UNIV_NONINL
# include "dict0stats_bg.ic"
# endif
diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h
index 5e6e5621686..ae002dd9487 100644
--- a/storage/innobase/include/dict0types.h
+++ b/storage/innobase/include/dict0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved.
+Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved.
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
@@ -104,4 +104,31 @@ typedef ib_mutex_t DictSysMutex;
extern uint ibuf_debug;
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
+/** Shift for spatial status */
+#define SPATIAL_STATUS_SHIFT 12
+
+/** Mask to encode/decode spatial status. */
+#define SPATIAL_STATUS_MASK (3 << SPATIAL_STATUS_SHIFT)
+
+#if SPATIAL_STATUS_MASK < REC_VERSION_56_MAX_INDEX_COL_LEN
+# error SPATIAL_STATUS_MASK < REC_VERSION_56_MAX_INDEX_COL_LEN
+#endif
+
+/** whether a col is used in spatial index or regular index
+Note: the spatial status is part of persistent undo log,
+so we should not modify the values in MySQL 5.7 */
+enum spatial_status_t {
+ /* Unkown status (undo format in 5.7.9) */
+ SPATIAL_UNKNOWN = 0,
+
+ /** Not used in gis index. */
+ SPATIAL_NONE = 1,
+
+ /** Used in both spatial index and regular index. */
+ SPATIAL_MIXED = 2,
+
+ /** Only used in spatial index. */
+ SPATIAL_ONLY = 3
+};
+
#endif
diff --git a/storage/innobase/include/dyn0buf.h b/storage/innobase/include/dyn0buf.h
index 7e2995ccabd..3126c8e4683 100644
--- a/storage/innobase/include/dyn0buf.h
+++ b/storage/innobase/include/dyn0buf.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2013, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -62,7 +62,7 @@ public:
Gets the number of used bytes in a block.
@return number of bytes used */
ulint used() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(static_cast<ulint>(m_used & ~DYN_BLOCK_FULL_FLAG));
}
@@ -71,7 +71,7 @@ public:
Gets pointer to the start of data.
@return pointer to data */
byte* start()
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(m_data);
}
@@ -79,7 +79,7 @@ public:
/**
@return start of data - non const version */
byte* begin()
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(m_data);
}
@@ -87,7 +87,7 @@ public:
/**
@return end of used data - non const version */
byte* end()
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(begin() + m_used);
}
@@ -95,7 +95,7 @@ public:
/**
@return start of data - const version */
const byte* begin() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(m_data);
}
@@ -103,7 +103,7 @@ public:
/**
@return end of used data - const version */
const byte* end() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(begin() + m_used);
}
@@ -216,7 +216,7 @@ public:
@param size in bytes of the buffer; MUST be <= MAX_DATA_SIZE!
@return pointer to the buffer */
byte* open(ulint size)
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
ut_ad(size > 0);
ut_ad(size <= MAX_DATA_SIZE);
@@ -319,7 +319,7 @@ public:
Returns the size of the total stored data.
@return data size in bytes */
ulint size() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
#ifdef UNIV_DEBUG
ulint total_size = 0;
@@ -375,7 +375,7 @@ public:
/**
@return the first block */
block_t* front()
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
ut_ad(UT_LIST_GET_LEN(m_list) > 0);
return(UT_LIST_GET_FIRST(m_list));
@@ -384,7 +384,7 @@ public:
/**
@return true if m_first_block block was not filled fully */
bool is_small() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(m_heap == NULL);
}
diff --git a/storage/innobase/include/fil0crypt.ic b/storage/innobase/include/fil0crypt.ic
index 1a91aee750e..65ca4def85f 100644
--- a/storage/innobase/include/fil0crypt.ic
+++ b/storage/innobase/include/fil0crypt.ic
@@ -17,7 +17,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
*****************************************************************************/
/**************************************************//**
-@file include/fil0fil.h
+@file include/fil0crypt.ic
The low-level file system encryption support functions
Created 04/01/2015 Jan Lindström
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index d04355c3912..4171bed1611 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2016, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -33,7 +33,6 @@ Created 10/25/1995 Heikki Tuuri
#include "log0recv.h"
#include "dict0types.h"
#include "page0size.h"
-#include "hash0hash.h"
#ifndef UNIV_HOTBACKUP
#include "ibuf0types.h"
#else
@@ -45,6 +44,53 @@ Created 10/25/1995 Heikki Tuuri
#include <list>
#include <vector>
+#ifdef UNIV_HOTBACKUP
+#include <cstring>
+/** determine if file is intermediate / temporary.These files are created during
+reorganize partition, rename tables, add / drop columns etc.
+@param[in] filepath asbosolute / relative or simply file name
+@retvalue true if it is intermediate file
+@retvalue false if it is normal file */
+inline
+bool
+is_intermediate_file(const std::string& filepath)
+{
+ std::string file_name = filepath;
+
+ // extract file name from relative or absolute file name
+ std::size_t pos = file_name.rfind(OS_PATH_SEPARATOR);
+ if (pos != std::string::npos)
+ file_name = file_name.substr(++pos);
+
+ transform(file_name.begin(), file_name.end(),
+ file_name.begin(), ::tolower);
+
+ if (file_name[0] != '#') {
+ pos = file_name.rfind("#tmp#.ibd");
+ if (pos != std::string::npos)
+ return true;
+ else
+ return false; /* normal file name */
+ }
+
+ std::vector<std::string> file_name_patterns = {"#sql-", "#sql2-",
+ "#tmp#", "#ren#"};
+
+ /* search for the unsupported patterns */
+ for (auto itr = file_name_patterns.begin();
+ itr != file_name_patterns.end();
+ itr++) {
+
+ if (0 == std::strncmp(file_name.c_str(),
+ itr->c_str(), itr->length())){
+ return true;
+ }
+ }
+
+ return false;
+}
+#endif /* UNIV_HOTBACKUP */
+
extern const char general_space_name[];
// Forward declaration
@@ -54,6 +100,7 @@ class truncate_t;
struct fil_node_t;
struct fil_space_t;
struct btr_create_t;
+
/* structure containing encryption specification */
typedef struct fil_space_crypt_struct fil_space_crypt_t;
@@ -92,12 +139,6 @@ struct fil_node_t;
struct fil_space_t {
char* name; /*!< Tablespace name */
ulint id; /*!< space id */
- ib_uint64_t tablespace_version;
- /*!< in DISCARD/IMPORT this timestamp
- is used to check if we should ignore
- an insert buffer merge request for a
- page because it actually was for the
- previous incarnation of the space */
lsn_t max_lsn;
/*!< LSN of the most recent
fil_names_write_if_was_clean().
@@ -181,17 +222,29 @@ struct fil_space_t {
/** Compression algorithm */
Compression::Type compression_type;
+ /** Encryption algorithm */
+ Encryption::Type encryption_type;
+
+ /** Encrypt key */
+ byte encryption_key[ENCRYPTION_KEY_LEN];
+
+ /** Encrypt key length*/
+ ulint encryption_klen;
+
+ /** Encrypt initial vector */
+ byte encryption_iv[ENCRYPTION_KEY_LEN];
+
+ /** MariaDB encryption data */
+ fil_space_crypt_t* crypt_data;
+
+ /** Space file block size */
+ ulint file_block_size;
+
+ /** True if we have already printed compression failure */
bool printed_compression_failure;
- /*!< true if we have already printed
- compression failure */
- fil_space_crypt_t* crypt_data;
- /* Tablespace crypt information or
- NULL */
- bool read_page0;
- /*!< true if page 0 of this tablespace
- is read */
- ulint file_block_size;/*!< file system block size */
+ /** True if page 0 of tablespace is read */
+ bool read_page0;
/** Release the reserved free extents.
@param[in] n_reserved number of reserved extents */
@@ -205,54 +258,53 @@ struct fil_space_t {
/** File node of a tablespace or the log data space */
struct fil_node_t {
- fil_space_t* space; /*!< backpointer to the space where this node
- belongs */
- char* name; /*!< path to the file */
- bool is_open;/*!< true if file is open */
- os_file_t handle; /*!< OS handle to the file, if file open */
- os_event_t sync_event;/*!< Condition event to group and
- serialize calls to fsync */
- bool is_raw_disk;/*!< true if the 'file' is actually a raw
- device or a raw disk partition */
- ulint size; /*!< size of the file in database pages, 0 if
- not known yet; the possible last incomplete
- megabyte may be ignored if space == 0 */
+ /** tablespace containing this file */
+ fil_space_t* space;
+ /** file name; protected by fil_system->mutex and log_sys->mutex. */
+ char* name;
+ /** whether this file is open */
+ bool is_open;
+ /** file handle (valid if is_open) */
+ os_file_t handle;
+ /** event that groups and serializes calls to fsync */
+ os_event_t sync_event;
+ /** whether the file actually is a raw device or disk partition */
+ bool is_raw_disk;
+ /** size of the file in database pages (0 if not known yet);
+ the possible last incomplete megabyte may be ignored
+ if space->id == 0 */
+ ulint size;
+ /** initial size of the file in database pages;
+ FIL_IBD_FILE_INITIAL_SIZE by default */
ulint init_size;
- /*!< initial size of the file in database pages,
- defaults to FIL_IBD_FILE_INITIAL_SIZE. */
+ /** maximum size of the file in database pages (0 if unlimited) */
ulint max_size;
- /*!< maximum size of the file in database pages;
- 0 if there is no maximum size. */
+ /** count of pending i/o's; is_open must be true if nonzero */
ulint n_pending;
- /*!< count of pending i/o's on this file;
- closing of the file is not allowed if
- this is > 0 */
+ /** count of pending flushes; is_open must be true if nonzero */
ulint n_pending_flushes;
- /*!< count of pending flushes on this file;
- closing of the file is not allowed if
- this is > 0 */
+ /** whether the file is currently being extended */
bool being_extended;
- /*!< true if the node is currently
- being extended. */
- int64_t modification_counter;/*!< when we write to the file we
- increment this by one */
- int64_t flush_counter;/*!< up to what
- modification_counter value we have
- flushed the modifications to disk */
+ /** number of writes to the file since the system was started */
+ int64_t modification_counter;
+ /** the modification_counter of the latest flush to disk */
+ int64_t flush_counter;
+ /** link to other files in this tablespace */
UT_LIST_NODE_T(fil_node_t) chain;
- /*!< link field for the file chain */
+ /** link to the fil_system->LRU list (keeping track of open files) */
UT_LIST_NODE_T(fil_node_t) LRU;
- /*!< link field for the LRU list */
- ulint magic_n;/*!< FIL_NODE_MAGIC_N */
- /** true if the FS where the file is located supports PUNCH HOLE */
+ /** whether the file system of this file supports PUNCH HOLE */
bool punch_hole;
- /** Block size to use for punching holes */
- ulint block_size;
+ /** block size to use for punching holes */
+ ulint block_size;
- /** True if atomic write is enabled for this file */
+ /** whether atomic write is enabled for this file */
bool atomic_write;
+
+ /** FIL_NODE_MAGIC_N */
+ ulint magic_n;
};
/** Value of fil_node_t::magic_n */
@@ -263,12 +315,14 @@ enum ib_extention {
NO_EXT = 0,
IBD = 1,
ISL = 2,
- CFG = 3
+ CFG = 3,
+ CFP = 4
};
extern const char* dot_ext[];
#define DOT_IBD dot_ext[IBD]
#define DOT_ISL dot_ext[ISL]
#define DOT_CFG dot_ext[CFG]
+#define DOT_CPF dot_ext[CFP]
/** Wrapper for a path to a directory.
This folder may or may not yet esist. Since not all directory paths
@@ -473,6 +527,7 @@ static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2;
#define FIL_PAGE_SPACE_ID FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID
#define FIL_PAGE_DATA 38U /*!< start of the data on the page */
+
/* Following are used when page compression is used */
#define FIL_PAGE_COMPRESSED_SIZE 2 /*!< Number of bytes used to store
actual payload data size on
@@ -512,6 +567,10 @@ static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2;
in FIL_PAGE_TYPE is replaced with this
value when flushing pages. */
#define FIL_PAGE_COMPRESSED 14 /*!< Compressed page */
+#define FIL_PAGE_ENCRYPTED 15 /*!< Encrypted page */
+#define FIL_PAGE_COMPRESSED_AND_ENCRYPTED 16
+ /*!< Compressed and Encrypted page */
+#define FIL_PAGE_ENCRYPTED_RTREE 17 /*!< Encrypted R-tree page */
/** Used by i_s.cc to index into the text description. */
#define FIL_PAGE_TYPE_LAST FIL_PAGE_TYPE_UNKNOWN
@@ -540,6 +599,20 @@ extern ulint fil_n_pending_tablespace_flushes;
/** Number of files currently open */
extern ulint fil_n_file_opened;
+/** Look up a tablespace.
+The caller should hold an InnoDB table lock or a MDL that prevents
+the tablespace from being dropped during the operation,
+or the caller should be in single-threaded crash recovery mode
+(no user connections that could drop tablespaces).
+If this is not the case, fil_space_acquire() and fil_space_release()
+should be used instead.
+@param[in] id tablespace ID
+@return tablespace, or NULL if not found */
+fil_space_t*
+fil_space_get(
+ ulint id)
+ MY_ATTRIBUTE((warn_unused_result));
+
/** The tablespace memory cache; also the totality of logs (the log
data space) is stored here; below we talk about tablespaces, but also
the ib_logfiles form a 'space' and it is handled here */
@@ -602,30 +675,13 @@ struct fil_system_t {
potential space_id reuse */
};
-#ifndef UNIV_HOTBACKUP
-/** Look up a tablespace.
-The caller should hold an InnoDB table lock or a MDL that prevents
-the tablespace from being dropped during the operation,
-or the caller should be in single-threaded crash recovery mode
-(no user connections that could drop tablespaces).
-If this is not the case, fil_space_acquire() and fil_space_release()
-should be used instead.
-@param[in] id tablespace ID
-@return tablespace, or NULL if not found */
-fil_space_t*
-fil_space_get(
- ulint id)
- __attribute__((warn_unused_result));
+/** The tablespace memory cache. This variable is NULL before the module is
+initialized. */
+extern fil_system_t* fil_system;
-/*******************************************************************//**
-Returns the version number of a tablespace, -1 if not found.
-@return version number, -1 if the tablespace does not exist in the
-memory cache */
-UNIV_INTERN
-ib_uint64_t
-fil_space_get_version(
-/*==================*/
- ulint id); /*!< in: space id */
+#include "fil0crypt.h"
+
+#ifndef UNIV_HOTBACKUP
/** Returns the latch of a file space.
@param[in] id space id
@param[out] flags tablespace flags
@@ -658,7 +714,7 @@ fil_space_set_imported(
@return whether it is a temporary tablespace */
bool
fsp_is_temporary(ulint id)
-__attribute__((warn_unused_result, pure));
+MY_ATTRIBUTE((warn_unused_result, pure));
# endif /* UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
@@ -680,7 +736,7 @@ fil_node_create(
bool is_raw,
bool atomic_write,
ulint max_pages = ULINT_MAX)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Create a space memory object and put it to the fil_system hash table.
The tablespace name is independent from the tablespace file-name.
@@ -693,12 +749,12 @@ Error messages are issued to the server log.
@retval NULL on failure (such as when the same tablespace exists) */
fil_space_t*
fil_space_create(
- const char* name, /*!< in: space name */
- ulint id, /*!< in: space id */
+ const char* name,
+ ulint id,
ulint flags,
fil_type_t purpose, /*!< in: FIL_TABLESPACE, or FIL_LOG if log */
fil_space_crypt_t* crypt_data) /*!< in: crypt data */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************************//**
Assigns a new space id for a new single-table tablespace. This works simply by
@@ -820,22 +876,15 @@ fil_set_max_space_id_if_bigger(
/*===========================*/
ulint max_id);/*!< in: maximum known id */
#ifndef UNIV_HOTBACKUP
-/*******************************************************************//**
-Increments the count of pending operation, if space is not being deleted.
-@return TRUE if being deleted, and operation should be skipped */
-UNIV_INTERN
-ibool
-fil_inc_pending_ops(
-/*================*/
- ulint id, /*!< in: space id */
- ibool print_err); /*!< in: need to print error or not */
-/*******************************************************************//**
-Decrements the count of pending operations. */
-UNIV_INTERN
-void
-fil_decr_pending_ops(
-/*=================*/
- ulint id); /*!< in: space id */
+
+/** Write the flushed LSN to the page header of the first page in the
+system tablespace.
+@param[in] lsn flushed LSN
+@return DB_SUCCESS or error number */
+dberr_t
+fil_write_flushed_lsn(
+ lsn_t lsn)
+MY_ATTRIBUTE((warn_unused_result));
/** Acquire a tablespace when it could be dropped concurrently.
Used by background threads that do not necessarily hold proper locks
@@ -845,7 +894,7 @@ for concurrency control.
fil_space_t*
fil_space_acquire(
ulint id)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Acquire a tablespace that may not exist.
Used by background threads that do not necessarily hold proper locks
@@ -855,7 +904,7 @@ for concurrency control.
fil_space_t*
fil_space_acquire_silent(
ulint id)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Release a tablespace acquired with fil_space_acquire().
@param[in,out] space tablespace to release */
@@ -919,6 +968,7 @@ private:
};
#endif /* !UNIV_HOTBACKUP */
+
/********************************************************//**
Creates the database directory for a table if it does not exist yet. */
void
@@ -968,7 +1018,7 @@ fil_op_replay_rename(
ulint first_page_no,
const char* name,
const char* new_name)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Deletes an IBD tablespace, either general or single-table.
The tablespace must be cached in the memory cache. This will delete the
@@ -1084,8 +1134,6 @@ fil_make_filepath(
ib_extention suffix,
bool strip_name);
-#include "fil0crypt.h"
-
/** Creates a new General or Single-Table tablespace
@param[in] space_id Tablespace ID
@param[in] name Tablespace name in dbname/tablename format.
@@ -1104,9 +1152,8 @@ fil_ibd_create(
ulint size,
fil_encryption_t mode, /*!< in: encryption mode */
ulint key_id) /*!< in: encryption key_id */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
-#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
right in it. If does not succeed, prints an error message to the .err log. This
@@ -1146,7 +1193,7 @@ fil_ibd_open(
const char* tablename,
const char* path_in,
dict_table_t* table) /*!< in: table */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
enum fil_load_status {
/** The tablespace file(s) were found and valid. */
@@ -1169,9 +1216,8 @@ fil_ibd_load(
ulint space_id,
const char* filename,
fil_space_t*& space)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
-#endif /* !UNIV_HOTBACKUP */
/***********************************************************************//**
A fault-tolerant function that tries to read the next file name in the
@@ -1268,6 +1314,11 @@ fil_space_get_n_reserved_extents(
aligned
@param[in] message message for aio handler if non-sync aio
used, else ignored
+@param[in,out] write_size Actual write size initialized
+ after fist successfull trim
+ operation for this page and if
+ nitialized we do not trim again if
+ Actual page
@return DB_SUCCESS, DB_TABLESPACE_DELETED or DB_TABLESPACE_TRUNCATED
if we are trying to do i/o on a tablespace which does not exist */
@@ -1281,11 +1332,7 @@ fil_io(
ulint len,
void* buf,
void* message,
- ulint* write_size); /*!< in/out: Actual write size initialized
- after fist successfull trim
- operation for this page and if
- initialized we do not trim again if
- actual page size does not decrease. */
+ ulint* write_size);
/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
handler for completed requests. The aio array of pending requests is divided
@@ -1477,6 +1524,10 @@ struct PageCallback {
@return the space id of the tablespace */
virtual ulint get_space_id() const UNIV_NOTHROW = 0;
+ /**
+ @retval the space flags of the tablespace being iterated over */
+ virtual ulint get_space_flags() const UNIV_NOTHROW = 0;
+
/** Set the tablespace table size.
@param[in] page a page belonging to the tablespace */
void set_page_size(const buf_frame_t* page) UNIV_NOTHROW;
@@ -1515,7 +1566,7 @@ fil_tablespace_iterate(
dict_table_t* table,
ulint n_io_buffers,
PageCallback& callback)
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Looks for a pre-existing fil_space_t with the given tablespace ID
@@ -1575,16 +1626,71 @@ fil_node_next(
@param[in] new_table new table
@param[in] tmp_name temporary table name
@param[in,out] mtr mini-transaction
-@return whether the operation succeeded */
-bool
+@return innodb error code */
+dberr_t
fil_mtr_rename_log(
const dict_table_t* old_table,
const dict_table_t* new_table,
const char* tmp_name,
mtr_t* mtr)
- MY_ATTRIBUTE((nonnull));
+ MY_ATTRIBUTE((warn_unused_result));
+
+/****************************************************************//**
+Acquire fil_system mutex */
+void
+fil_system_enter(void);
+/*==================*/
+/****************************************************************//**
+Release fil_system mutex */
+void
+fil_system_exit(void);
+/*==================*/
+
+/*******************************************************************//**
+Returns the table space by a given id, NULL if not found. */
+fil_space_t*
+fil_space_found_by_id(
+/*==================*/
+ ulint id); /*!< in: space id */
+
+/*******************************************************************//**
+Returns the table space by a given id, NULL if not found. */
+fil_space_t*
+fil_space_get_by_id(
+/*================*/
+ ulint id); /*!< in: space id */
+
+/******************************************************************
+Get id of first tablespace or ULINT_UNDEFINED if none */
+UNIV_INTERN
+ulint
+fil_get_first_space();
+/*=================*/
-/** Note that a non-predefined persistent tablespace has been modified
+/******************************************************************
+Get id of next tablespace or ULINT_UNDEFINED if none */
+UNIV_INTERN
+ulint
+fil_get_next_space(
+ ulint id); /*!< in: space id */
+
+/******************************************************************
+Get id of first tablespace that has node or ULINT_UNDEFINED if none */
+UNIV_INTERN
+ulint
+fil_get_first_space_safe();
+/*======================*/
+
+/******************************************************************
+Get id of next tablespace that has node or ULINT_UNDEFINED if none */
+UNIV_INTERN
+ulint
+fil_get_next_space_safe(
+/*====================*/
+ ulint id); /*!< in: previous space id */
+
+
+/*******************************************************************//**
by redo log.
@param[in,out] space tablespace */
void
@@ -1601,30 +1707,49 @@ fil_names_dirty_and_write(
fil_space_t* space,
mtr_t* mtr);
-/** Set the compression type for the tablespace
-@param[in] space Space ID of tablespace for which to set
-@param[in] algorithm Text representation of the algorithm
+/** Set the compression type for the tablespace of a table
+@param[in] table Table that should be compressesed
+@param[in] algorithm Text representation of the algorithm
@return DB_SUCCESS or error code */
dberr_t
fil_set_compression(
- ulint space_id,
+ dict_table_t* table,
const char* algorithm)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
-/**
-@param[in] space_id Space ID to check
+/** Get the compression type for the tablespace
+@param[in] space_id Space ID to check
@return the compression algorithm */
Compression::Type
fil_get_compression(
- ulint space_id)
- __attribute__((warn_unused_result));
+ ulint space_id)
+ MY_ATTRIBUTE((warn_unused_result));
+
+/** Set the encryption type for the tablespace
+@param[in] space Space ID of tablespace for which to set
+@param[in] algorithm Encryption algorithm
+@param[in] key Encryption key
+@param[in] iv Encryption iv
+@return DB_SUCCESS or error code */
+dberr_t
+fil_set_encryption(
+ ulint space_id,
+ Encryption::Type algorithm,
+ byte* key,
+ byte* iv)
+ MY_ATTRIBUTE((warn_unused_result));
+
+/**
+@return true if the re-encrypt success */
+bool
+fil_encryption_rotate();
/** Write MLOG_FILE_NAME records if a persistent tablespace was modified
for the first time since the latest fil_names_clear().
@param[in,out] space tablespace
@param[in,out] mtr mini-transaction
@return whether any MLOG_FILE_NAME record was written */
-inline __attribute__((warn_unused_result))
+inline MY_ATTRIBUTE((warn_unused_result))
bool
fil_names_write_if_was_clean(
fil_space_t* space,
@@ -1701,72 +1826,6 @@ void fil_no_punch_hole(fil_node_t* node);
void test_make_filepath();
#endif /* UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH */
-/*******************************************************************//**
-Return space flags */
-UNIV_INLINE
-ulint
-fil_space_flags(
-/*===========*/
- fil_space_t* space); /*!< in: space */
-
-#endif /* !UNIV_INNOCHECKSUM */
-
-/****************************************************************//**
-Acquire fil_system mutex */
-void
-fil_system_enter(void);
-/*==================*/
-/****************************************************************//**
-Release fil_system mutex */
-void
-fil_system_exit(void);
-/*==================*/
-
-#ifndef UNIV_INNOCHECKSUM
-/*******************************************************************//**
-Returns the table space by a given id, NULL if not found. */
-fil_space_t*
-fil_space_found_by_id(
-/*==================*/
- ulint id); /*!< in: space id */
-
-/*******************************************************************//**
-Returns the table space by a given id, NULL if not found. */
-fil_space_t*
-fil_space_get_by_id(
-/*================*/
- ulint id); /*!< in: space id */
-
-/******************************************************************
-Get id of first tablespace or ULINT_UNDEFINED if none */
-UNIV_INTERN
-ulint
-fil_get_first_space();
-/*=================*/
-
-/******************************************************************
-Get id of next tablespace or ULINT_UNDEFINED if none */
-UNIV_INTERN
-ulint
-fil_get_next_space(
-/*===============*/
- ulint id); /*!< in: space id */
-
-/******************************************************************
-Get id of first tablespace that has node or ULINT_UNDEFINED if none */
-UNIV_INTERN
-ulint
-fil_get_first_space_safe();
-/*======================*/
-
-/******************************************************************
-Get id of next tablespace that has node or ULINT_UNDEFINED if none */
-UNIV_INTERN
-ulint
-fil_get_next_space_safe(
-/*====================*/
- ulint id); /*!< in: previous space id */
-
/*******************************************************************//**
Returns the block size of the file space
@@ -1779,15 +1838,24 @@ fil_space_get_block_size(
ulint offset, /*!< in: page offset */
ulint len); /*!< in: page len */
-#endif /* UNIV_INNOCHECKSUM */
+/*******************************************************************//**
+Increments the count of pending operation, if space is not being deleted.
+@return TRUE if being deleted, and operation should be skipped */
+UNIV_INTERN
+ibool
+fil_inc_pending_ops(
+/*================*/
+ ulint id, /*!< in: space id */
+ ibool print_err); /*!< in: need to print error or not */
+/*******************************************************************//**
+Decrements the count of pending operations. */
+UNIV_INTERN
+void
+fil_decr_pending_ops(
+/*=================*/
+ ulint id); /*!< in: space id */
-/** Write the flushed LSN to the page header of the first page in the
-system tablespace.
-@param[in] lsn flushed LSN
-@return DB_SUCCESS or error number */
-dberr_t
-fil_write_flushed_lsn(
- lsn_t lsn);
+#endif /* UNIV_INNOCHECKSUM */
#ifndef UNIV_INNOCHECKSUM
#ifndef UNIV_NONINL
diff --git a/storage/innobase/include/fsp0file.h b/storage/innobase/include/fsp0file.h
index a08ebff9509..83aa370abf0 100644
--- a/storage/innobase/include/fsp0file.h
+++ b/storage/innobase/include/fsp0file.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -68,6 +68,8 @@ public:
m_atomic_write(),
m_last_os_error(),
m_file_info(),
+ m_encryption_key(NULL),
+ m_encryption_iv(NULL),
m_crypt_info()
{
/* No op */
@@ -92,6 +94,8 @@ public:
m_atomic_write(),
m_last_os_error(),
m_file_info(),
+ m_encryption_key(NULL),
+ m_encryption_iv(NULL),
m_crypt_info()
{
ut_ad(m_name != NULL);
@@ -114,6 +118,8 @@ public:
m_atomic_write(file.m_atomic_write),
m_last_os_error(),
m_file_info(),
+ m_encryption_key(NULL),
+ m_encryption_iv(NULL),
m_crypt_info()
{
m_name = mem_strdup(file.m_name);
@@ -172,6 +178,8 @@ public:
it should be reread if needed */
m_first_page_buf = NULL;
m_first_page = NULL;
+ m_encryption_key = NULL;
+ m_encryption_iv = NULL;
/* Do not copy crypt info it is read from first page */
m_crypt_info = NULL;
@@ -200,7 +208,7 @@ public:
are enforced.
@return DB_SUCCESS or error code */
virtual dberr_t open_read_write(bool read_only_mode)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Initialize OS specific file info. */
void init_file_info();
@@ -237,12 +245,14 @@ public:
successfully opened in order for this function to validate it.
@param[in] space_id The expected tablespace ID.
@param[in] flags The expected tablespace flags.
+ @param[in] for_import is it for importing
@retval DB_SUCCESS if tablespace is valid, DB_ERROR if not.
m_is_valid is also set true on success, else false. */
dberr_t validate_to_dd(
- ulint space_id,
- ulint flags)
- __attribute__((warn_unused_result));
+ ulint space_id,
+ ulint flags,
+ bool for_import)
+ MY_ATTRIBUTE((warn_unused_result));
/** Validates this datafile for the purpose of recovery.
The file should exist and be successfully opened. We initially
@@ -253,19 +263,21 @@ public:
@retval DB_SUCCESS if tablespace is valid, DB_ERROR if not.
m_is_valid is also set true on success, else false. */
dberr_t validate_for_recovery()
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Checks the consistency of the first page of a datafile when the
tablespace is opened. This occurs before the fil_space_t is created
so the Space ID found here must not already be open.
m_is_valid is set true on success, else false.
@param[out] flush_lsn contents of FIL_PAGE_FILE_FLUSH_LSN
+ @param[in] for_import if it is for importing
(only valid for the first file of the system tablespace)
@retval DB_SUCCESS on if the datafile is valid
@retval DB_CORRUPTION if the datafile is not readable
@retval DB_TABLESPACE_EXISTS if there is a duplicate space_id */
- dberr_t validate_first_page(lsn_t* flush_lsn = 0)
- __attribute__((warn_unused_result));
+ dberr_t validate_first_page(lsn_t* flush_lsn,
+ bool for_import)
+ MY_ATTRIBUTE((warn_unused_result));
/** Get Datafile::m_name.
@return m_name */
@@ -370,7 +382,7 @@ private:
are enforced.
@return DB_SUCCESS or error code */
dberr_t open_or_create(bool read_only_mode)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Reads a few significant fields from the first page of the
datafile, which must already be open.
@@ -378,7 +390,7 @@ private:
are enforced.
@return DB_SUCCESS or DB_IO_ERROR if page cannot be read */
dberr_t read_first_page(bool read_first_page)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Free the first page from memory when it is no longer needed. */
void free_first_page();
@@ -480,8 +492,14 @@ public:
struct stat m_file_info;
#endif /* WIN32 */
+ /** Encryption key read from first page */
+ byte* m_encryption_key;
+
+ /** Encryption iv read from first page */
+ byte* m_encryption_iv;
+
/** Encryption information */
- fil_space_crypt_t* m_crypt_info;
+ fil_space_crypt_t* m_crypt_info;
};
@@ -551,7 +569,7 @@ public:
are enforced.
@return DB_SUCCESS or error code */
dberr_t open_read_write(bool read_only_mode)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************
Global Static Functions; Cannot refer to data members.
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 17be27a8ce5..3709c4a4f24 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -42,6 +42,7 @@ Created 12/18/1995 Heikki Tuuri
#endif /* !UNIV_INNOCHECKSUM */
#include "fsp0types.h"
+
#define FSP_FLAGS_POS_DATA_DIR_ORACLE (FSP_FLAGS_POS_ATOMIC_BLOBS \
+ FSP_FLAGS_WIDTH_ATOMIC_BLOBS \
+ FSP_FLAGS_WIDTH_PAGE_SSIZE)
@@ -49,6 +50,7 @@ Created 12/18/1995 Heikki Tuuri
#define FSP_FLAGS_MASK_DATA_DIR_ORACLE \
((~(~0 << FSP_FLAGS_WIDTH_DATA_DIR)) \
<< FSP_FLAGS_POS_DATA_DIR_ORACLE)
+
#define FSP_FLAGS_HAS_DATA_DIR_ORACLE(flags) \
((flags & FSP_FLAGS_MASK_DATA_DIR_ORACLE) \
>> FSP_FLAGS_POS_DATA_DIR_ORACLE)
@@ -118,6 +120,7 @@ descriptor page, but used only in the first. */
FSP_FREE_LIMIT at a time */
/* @} */
+#ifndef UNIV_INNOCHECKSUM
/* @defgroup File Segment Inode Constants (moved from fsp0fsp.c) @{ */
@@ -254,7 +257,6 @@ the extent are free and which contain old tuple version to clean. */
/* @} */
-#ifndef UNIV_INNOCHECKSUM
/**********************************************************************//**
Initializes the file space system. */
void
@@ -334,6 +336,40 @@ page_size_t
fsp_header_get_page_size(
const page_t* page);
+/** Decoding the encryption info
+from the first page of a tablespace.
+@param[in/out] key key
+@param[in/out] iv iv
+@param[in] encryption_info encrytion info.
+@return true if success */
+bool
+fsp_header_decode_encryption_info(
+ byte* key,
+ byte* iv,
+ byte* encryption_info);
+
+/** Reads the encryption key from the first page of a tablespace.
+@param[in] fsp_flags tablespace flags
+@param[in/out] key tablespace key
+@param[in/out] iv tablespace iv
+@param[in] page first page of a tablespace
+@return true if success */
+bool
+fsp_header_get_encryption_key(
+ ulint fsp_flags,
+ byte* key,
+ byte* iv,
+ page_t* page);
+
+/** Check the encryption key from the first page of a tablespace.
+@param[in] fsp_flags tablespace flags
+@param[in] page first page of a tablespace
+@return true if success */
+bool
+fsp_header_check_encryption_key(
+ ulint fsp_flags,
+ page_t* page);
+
/**********************************************************************//**
Writes the space id and flags to a tablespace header. The flags contain
row type, physical/compressed page size, and logical/uncompressed page
@@ -346,6 +382,17 @@ fsp_header_init_fields(
ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
0, or table->flags if newer than COMPACT */
+/** Rotate the encryption info in the space header.
+@param[in] space tablespace
+@param[in] encrypt_info buffer for re-encrypt key.
+@param[in,out] mtr mini-transaction
+@return true if success. */
+bool
+fsp_header_rotate_encryption(
+ fil_space_t* space,
+ byte* encrypt_info,
+ mtr_t* mtr);
+
/** Initializes the space header of a new created space and creates also the
insert buffer tree root if space == 0.
@param[in] space_id space id
@@ -458,8 +505,8 @@ fseg_alloc_free_page_general(
If init_mtr!=mtr, but the page is already
latched in mtr, do not initialize the page. */
MY_ATTRIBUTE((warn_unused_result, nonnull));
-/**********************************************************************//**
-Reserves free pages from a tablespace. All mini-transactions which may
+
+/** Reserves free pages from a tablespace. All mini-transactions which may
use several pages from the tablespace should call this function beforehand
and reserve enough free extents so that they certainly will be able
to do their operation, like a B-tree page split, fully. Reservations
@@ -478,23 +525,33 @@ The purpose is to avoid dead end where the database is full but the
user cannot free any space because these freeing operations temporarily
reserve some space.
-Single-table tablespaces whose size is < 32 pages are a special case. In this
-function we would liberally reserve several 64 page extents for every page
-split or merge in a B-tree. But we do not want to waste disk space if the table
-only occupies < 32 pages. That is why we apply different rules in that special
-case, just ensuring that there are 3 free pages available.
-@return TRUE if we were able to make the reservation */
+Single-table tablespaces whose size is < FSP_EXTENT_SIZE pages are a special
+case. In this function we would liberally reserve several extents for
+every page split or merge in a B-tree. But we do not want to waste disk space
+if the table only occupies < FSP_EXTENT_SIZE pages. That is why we apply
+different rules in that special case, just ensuring that there are n_pages
+free pages available.
+
+@param[out] n_reserved number of extents actually reserved; if we
+ return true and the tablespace size is <
+ FSP_EXTENT_SIZE pages, then this can be 0,
+ otherwise it is n_ext
+@param[in] space_id tablespace identifier
+@param[in] n_ext number of extents to reserve
+@param[in] alloc_type page reservation type (FSP_BLOB, etc)
+@param[in,out] mtr the mini transaction
+@param[in] n_pages for small tablespaces (tablespace size is
+ less than FSP_EXTENT_SIZE), number of free
+ pages to reserve.
+@return true if we were able to make the reservation */
bool
fsp_reserve_free_extents(
-/*=====================*/
- ulint* n_reserved,/*!< out: number of extents actually reserved; if we
- return TRUE and the tablespace size is < 64 pages,
- then this can be 0, otherwise it is n_ext */
- ulint space_id,/*!< in: space id */
- ulint n_ext, /*!< in: number of extents to reserve */
+ ulint* n_reserved,
+ ulint space_id,
+ ulint n_ext,
fsp_reserve_t alloc_type,
- /*!< in: page reservation type */
- mtr_t* mtr); /*!< in/out: mini-transaction */
+ mtr_t* mtr,
+ ulint n_pages = 2);
/** Calculate how many KiB of new data we will be able to insert to the
tablespace without running out of space.
@@ -551,7 +608,7 @@ fseg_free_step(
bool ahi, /*!< in: whether we may need to drop
the adaptive hash index */
mtr_t* mtr) /*!< in/out: mini-transaction */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Frees part of a segment. Differs from fseg_free_step because this function
leaves the header page unfreed.
@@ -564,7 +621,7 @@ fseg_free_step_not_header(
bool ahi, /*!< in: whether we may need to drop
the adaptive hash index */
mtr_t* mtr) /*!< in/out: mini-transaction */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Checks if a page address is an extent descriptor page address.
@param[in] page_id page id
@@ -629,6 +686,7 @@ fsp_flags_are_equal(
@param[in] has_data_dir This tablespace is in a remote location.
@param[in] is_shared This tablespace can be shared by many tables.
@param[in] is_temporary This tablespace is temporary.
+@param[in] is_encrypted This tablespace is encrypted.
@return tablespace flags after initialization */
UNIV_INLINE
ulint
@@ -640,7 +698,8 @@ fsp_flags_init(
bool is_temporary,
bool page_compression,
ulint page_compression_level,
- ulint atomic_writes);
+ ulint atomic_writes,
+ bool is_encrypted = false);
/** Convert a 32 bit integer tablespace flags to the 32 bit table flags.
This can only be done for a tablespace that was built as a file-per-table
@@ -687,7 +746,7 @@ xdes_get_descriptor(
ulint offset,
const page_size_t& page_size,
mtr_t* mtr)
-__attribute__((warn_unused_result));
+MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Gets a descriptor bit of a page.
@@ -710,11 +769,11 @@ ulint
xdes_calc_descriptor_page(
const page_size_t& page_size,
ulint offset);
-#endif /* !UNIV_INNOCHECKSUM */
+#endif /* !UNIV_INNOCHECKSUM */
-/*********************************************************************/
-/* @return offset into fsp header where crypt data is stored */
+/*********************************************************************//**
+@return offset into fsp header where crypt data is stored */
UNIV_INTERN
ulint
fsp_header_get_crypt_offset(
@@ -722,10 +781,9 @@ fsp_header_get_crypt_offset(
const page_size_t& page_size,/*!< in: page size */
ulint* max_size); /*!< out: free space after offset */
-#define fsp_page_is_free(space,page,mtr) \
- fsp_page_is_free_func(space,page,mtr, __FILE__, __LINE__)
#ifndef UNIV_INNOCHECKSUM
+
/**********************************************************************//**
Checks if a single page is free.
@return true if free */
@@ -738,7 +796,12 @@ fsp_page_is_free_func(
mtr_t* mtr, /*!< in/out: mini-transaction */
const char *file,
ulint line);
-#endif
+
+#define fsp_page_is_free(space,page,mtr) \
+ fsp_page_is_free_func(space,page,mtr, __FILE__, __LINE__)
+
+#endif /* UNIV_INNOCHECKSUM */
+
#ifndef UNIV_NONINL
#include "fsp0fsp.ic"
#endif
diff --git a/storage/innobase/include/fsp0fsp.ic b/storage/innobase/include/fsp0fsp.ic
index e204ac3c69f..475dd238728 100644
--- a/storage/innobase/include/fsp0fsp.ic
+++ b/storage/innobase/include/fsp0fsp.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, SkySQL Ab. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, 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
@@ -181,10 +181,11 @@ fsp_flags_set_page_size(
@param[in] has_data_dir This tablespace is in a remote location.
@param[in] is_shared This tablespace can be shared by many tables.
@param[in] is_temporary This tablespace is temporary.
+@param[in] is_encrypted This tablespace is encrypted.
@param[in] page_compressed Table uses page compression
@param[in] page_compression_level Page compression level
@param[in] atomic_writes Table uses atomic writes
-@return tablespace flags after initialization */
+@@return tablespace flags after initialization */
UNIV_INLINE
ulint
fsp_flags_init(
@@ -195,7 +196,8 @@ fsp_flags_init(
bool is_temporary,
bool page_compression,
ulint page_compression_level,
- ulint atomic_writes)
+ ulint atomic_writes,
+ bool is_encrypted)
{
ut_ad(page_size.physical() <= page_size.logical());
ut_ad(!page_size.is_compressed() || atomic_blobs);
@@ -229,6 +231,10 @@ fsp_flags_init(
flags |= FSP_FLAGS_MASK_TEMPORARY;
}
+ if (is_encrypted) {
+ flags |= FSP_FLAGS_MASK_ENCRYPTION;
+ }
+
/* In addition, tablespace flags also contain if the page
compression is used for this table. */
if (page_compression) {
@@ -247,6 +253,8 @@ fsp_flags_init(
flags |= FSP_FLAGS_SET_ATOMIC_WRITES(flags, atomic_writes);
}
+ ut_ad(fsp_flags_is_valid(flags));
+
return(flags);
}
@@ -329,4 +337,15 @@ xdes_calc_descriptor_page(
return(ut_2pow_round(offset, page_size.physical()));
}
+
+/** Calculates the descriptor array size.
+@param[in] page_size page size
+@return size of descriptor array */
+UNIV_INLINE
+ulint
+xdes_arr_size(
+ const page_size_t& page_size)
+{
+ return(page_size.physical()/FSP_EXTENT_SIZE);
+}
#endif /* !UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/include/fsp0space.h b/storage/innobase/include/fsp0space.h
index 5fdb12a922f..603c71b4aa6 100644
--- a/storage/innobase/include/fsp0space.h
+++ b/storage/innobase/include/fsp0space.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -100,7 +100,7 @@ public:
m_path = mem_strdupl(path, len);
ut_ad(m_path != NULL);
- os_normalize_path_for_win(m_path);
+ os_normalize_path(m_path);
}
/** Set tablespace path and filename members.
@@ -171,15 +171,24 @@ public:
/** Free the memory allocated by the Tablespace object */
void shutdown();
- /**
- @return ULINT_UNDEFINED if the size is invalid else the sum of sizes */
- ulint get_sum_of_sizes() const;
+ /** @return the sum of the file sizes of each Datafile */
+ ulint get_sum_of_sizes() const
+ {
+ ulint sum = 0;
+
+ for (files_t::const_iterator it = m_files.begin();
+ it != m_files.end(); ++it) {
+ sum += it->m_size;
+ }
+
+ return(sum);
+ }
/** Open or Create the data files if they do not exist.
@param[in] is_temp whether this is a temporary tablespace
@return DB_SUCCESS or error code */
dberr_t open_or_create(bool is_temp)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Delete all the data files. */
void delete_files();
diff --git a/storage/innobase/include/fsp0sysspace.h b/storage/innobase/include/fsp0sysspace.h
index 42778f7d8e6..226d53ebd50 100644
--- a/storage/innobase/include/fsp0sysspace.h
+++ b/storage/innobase/include/fsp0sysspace.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -152,6 +152,15 @@ public:
* ((1024 * 1024) / UNIV_PAGE_SIZE));
}
+ /** Roundoff to MegaBytes is similar as done in
+ SysTablespace::parse_units() function.
+ @return the pages when given size of file (bytes). */
+ ulint get_pages_from_size(os_offset_t size)
+ {
+ return (ulint)((size / (1024 * 1024))
+ * ((1024 * 1024) / UNIV_PAGE_SIZE));
+ }
+
/**
@return next increment size */
ulint get_increment() const;
@@ -167,7 +176,7 @@ public:
bool create_new_db,
ulint* sum_new_sizes,
lsn_t* flush_lsn)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
private:
/** Check the tablespace header for this tablespace.
@@ -289,17 +298,6 @@ is_system_tablespace(
|| id == srv_tmp_space.space_id());
}
-/** Check if it is a shared tablespace.
-@param[in] id Space ID to check
-@return true if id is a shared tablespace, false if not. */
-UNIV_INLINE
-bool
-is_shared_tablespace(
- ulint id)
-{
- return(is_system_tablespace(id));
-}
-
/** Check if shared-system or undo tablespace.
@return true if shared-system or undo tablespace */
UNIV_INLINE
diff --git a/storage/innobase/include/fsp0types.h b/storage/innobase/include/fsp0types.h
index 33f630a3574..73fd6341d94 100644
--- a/storage/innobase/include/fsp0types.h
+++ b/storage/innobase/include/fsp0types.h
@@ -1,6 +1,7 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2014, 2016, 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
@@ -62,7 +63,7 @@ page size | file space extent size
#define FSP_EXTENT_SIZE_MAX (4194304 / UNIV_PAGE_SIZE_MAX)
/** File space extent size (one megabyte) in pages for MIN page size */
-#define FSP_EXTENT_SIZE_MIN (1048576U / UNIV_PAGE_SIZE_MIN)
+#define FSP_EXTENT_SIZE_MIN (1048576 / UNIV_PAGE_SIZE_MIN)
/** On a page of any file segment, data may be put starting from this
offset */
@@ -190,7 +191,7 @@ so they should have a file format number plus the DICT_TF_COMPACT bit set.
bool
fsp_flags_is_valid(
ulint flags)
- __attribute__((warn_unused_result, const));
+ MY_ATTRIBUTE((warn_unused_result, const));
/** Check if tablespace is system temporary.
@param[in] space_id verify is checksum is enabled for given space.
@@ -249,6 +250,9 @@ was created with CREATE TABLESPACE and can be shared by multiple tables. */
is a temporary tablespace and everything in it is temporary, meaning that
it is for a single client and should be deleted upon startup if it exists. */
#define FSP_FLAGS_WIDTH_TEMPORARY 1
+/** Width of the encryption flag. This flag indicates that the tablespace
+is a tablespace with encryption. */
+#define FSP_FLAGS_WIDTH_ENCRYPTION 1
/** Number of flag bits used to indicate the page compression and compression level */
#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1
@@ -265,6 +269,7 @@ it is for a single client and should be deleted upon startup if it exists. */
+ FSP_FLAGS_WIDTH_DATA_DIR \
+ FSP_FLAGS_WIDTH_SHARED \
+ FSP_FLAGS_WIDTH_TEMPORARY \
+ + FSP_FLAGS_WIDTH_ENCRYPTION \
+ FSP_FLAGS_WIDTH_PAGE_COMPRESSION \
+ FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL \
+ FSP_FLAGS_WIDTH_ATOMIC_WRITES )
@@ -292,9 +297,12 @@ it is for a single client and should be deleted upon startup if it exists. */
/** Zero relative shift position of the start of the TEMPORARY bit */
#define FSP_FLAGS_POS_TEMPORARY (FSP_FLAGS_POS_SHARED \
+ FSP_FLAGS_WIDTH_SHARED)
-/** Zero relative shift position of the PAGE_COMPRESSION field */
-#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_TEMPORARY \
+/** Zero relative shift position of the start of the ENCRYPTION bit */
+#define FSP_FLAGS_POS_ENCRYPTION (FSP_FLAGS_POS_TEMPORARY \
+ FSP_FLAGS_WIDTH_TEMPORARY)
+/** Zero relative shift position of the PAGE_COMPRESSION field */
+#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_ENCRYPTION \
+ + FSP_FLAGS_WIDTH_ENCRYPTION)
/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL (FSP_FLAGS_POS_PAGE_COMPRESSION \
+ FSP_FLAGS_WIDTH_PAGE_COMPRESSION)
@@ -302,8 +310,8 @@ it is for a single client and should be deleted upon startup if it exists. */
#define FSP_FLAGS_POS_ATOMIC_WRITES (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL \
+ FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)
/** Zero relative shift position of the start of the UNUSED bits */
-#define FSP_FLAGS_POS_UNUSED (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL \
- + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)
+#define FSP_FLAGS_POS_UNUSED (FSP_FLAGS_POS_ATOMIC_WRITES \
+ + FSP_FLAGS_WIDTH_ATOMIC_WRITES)
/** Bit mask of the POST_ANTELOPE field */
@@ -334,6 +342,10 @@ it is for a single client and should be deleted upon startup if it exists. */
#define FSP_FLAGS_MASK_TEMPORARY \
((~(~0U << FSP_FLAGS_WIDTH_TEMPORARY)) \
<< FSP_FLAGS_POS_TEMPORARY)
+/** Bit mask of the ENCRYPTION field */
+#define FSP_FLAGS_MASK_ENCRYPTION \
+ ((~(~0U << FSP_FLAGS_WIDTH_ENCRYPTION)) \
+ << FSP_FLAGS_POS_ENCRYPTION)
/** Bit mask of the PAGE_COMPRESSION field */
#define FSP_FLAGS_MASK_PAGE_COMPRESSION \
((~(~0 << FSP_FLAGS_WIDTH_PAGE_COMPRESSION)) \
@@ -375,6 +387,10 @@ it is for a single client and should be deleted upon startup if it exists. */
#define FSP_FLAGS_GET_TEMPORARY(flags) \
((flags & FSP_FLAGS_MASK_TEMPORARY) \
>> FSP_FLAGS_POS_TEMPORARY)
+/** Return the contents of the ENCRYPTION field */
+#define FSP_FLAGS_GET_ENCRYPTION(flags) \
+ ((flags & FSP_FLAGS_MASK_ENCRYPTION) \
+ >> FSP_FLAGS_POS_ENCRYPTION)
/** Return the contents of the UNUSED bits */
#define FSP_FLAGS_GET_UNUSED(flags) \
(flags >> FSP_FLAGS_POS_UNUSED)
diff --git a/storage/innobase/include/fts0ast.h b/storage/innobase/include/fts0ast.h
index f0f00a40193..87b7cf709c8 100644
--- a/storage/innobase/include/fts0ast.h
+++ b/storage/innobase/include/fts0ast.h
@@ -195,6 +195,13 @@ fts_ast_state_free(
/*===============*/
fts_ast_state_t*state); /*!< in: state instance
to free */
+/** Check only union operation involved in the node
+@param[in] node ast node to check
+@return true if the node contains only union else false. */
+bool
+fts_ast_node_check_union(
+ fts_ast_node_t* node);
+
/******************************************************************//**
Traverse the AST - in-order traversal.
@return DB_SUCCESS if all went well */
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index 210b9b700e4..2d256472ef6 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -66,7 +66,7 @@ optimize using a 4 byte Doc ID for FIC merge sort to reduce sort size */
#define MAX_DOC_ID_OPT_VAL 1073741824
/** Document id type. */
-typedef ib_uint64_t doc_id_t;
+typedef ib_id_t doc_id_t;
/** doc_id_t printf format */
#define FTS_DOC_ID_FORMAT IB_ID_FMT
@@ -103,7 +103,6 @@ those defined in mysql file ft_global.h */
should not exceed FTS_DOC_ID_MAX_STEP */
#define FTS_DOC_ID_MAX_STEP 65535
-
/** Maximum possible Fulltext word length */
#define FTS_MAX_WORD_LEN HA_FT_MAXBYTELEN
@@ -128,6 +127,7 @@ should not exceed FTS_DOC_ID_MAX_STEP */
/* BLOB COLUMN, 0 means VARIABLE SIZE */
#define FTS_INDEX_ILIST_LEN 0
+
/** Variable specifying the FTS parallel sort degree */
extern ulong fts_sort_pll_degree;
@@ -515,7 +515,7 @@ fts_create_common_tables(
index */
const char* name, /*!< in: table name */
bool skip_doc_id_index) /*!< in: Skip index on doc id */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Wrapper function of fts_create_index_tables_low(), create auxiliary
tables for an FTS index
@@ -526,7 +526,7 @@ fts_create_index_tables(
trx_t* trx, /*!< in: transaction handle */
const dict_index_t* index) /*!< in: the FTS index
instance */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Creates the column specific ancillary tables needed for supporting an
FTS index on the given table. row_mysql_lock_data_dictionary must have
@@ -541,15 +541,14 @@ fts_create_index_tables_low(
instance */
const char* table_name, /*!< in: the table name */
table_id_t table_id) /*!< in: the table id */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Add the FTS document id hidden column. */
void
fts_add_doc_id_column(
/*==================*/
dict_table_t* table, /*!< in/out: Table with FTS index */
- mem_heap_t* heap) /*!< in: temporary memory heap, or NULL */
- MY_ATTRIBUTE((nonnull(1)));
+ mem_heap_t* heap); /*!< in: temporary memory heap, or NULL */
/*********************************************************************//**
Drops the ancillary tables needed for supporting an FTS index on the
@@ -560,9 +559,8 @@ dberr_t
fts_drop_tables(
/*============*/
trx_t* trx, /*!< in: transaction */
- dict_table_t* table) /*!< in: table has the FTS
+ dict_table_t* table); /*!< in: table has the FTS
index */
- MY_ATTRIBUTE((nonnull));
/******************************************************************//**
The given transaction is about to be committed; do whatever is necessary
from the FTS system's POV.
@@ -571,23 +569,27 @@ dberr_t
fts_commit(
/*=======*/
trx_t* trx) /*!< in: transaction */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-
-/*******************************************************************//**
-FTS Query entry point.
+ MY_ATTRIBUTE((warn_unused_result));
+
+/** FTS Query entry point.
+@param[in] trx transaction
+@param[in] index fts index to search
+@param[in] flags FTS search mode
+@param[in] query_str FTS query
+@param[in] query_len FTS query string len in bytes
+@param[in,out] result result doc ids
+@param[in] limit limit value
@return DB_SUCCESS if successful otherwise error code */
dberr_t
fts_query(
-/*======*/
- trx_t* trx, /*!< in: transaction */
- dict_index_t* index, /*!< in: FTS index to search */
- uint flags, /*!< in: FTS search mode */
- const byte* query, /*!< in: FTS query */
- ulint query_len, /*!< in: FTS query string len
- in bytes */
- fts_result_t** result) /*!< out: query result, to be
- freed by the caller.*/
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ trx_t* trx,
+ dict_index_t* index,
+ uint flags,
+ const byte* query_str,
+ ulint query_len,
+ fts_result_t** result,
+ ulonglong limit)
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Retrieve the FTS Relevance Ranking result for doc with doc_id
@@ -704,8 +706,7 @@ Run OPTIMIZE on the given table.
dberr_t
fts_optimize_table(
/*===============*/
- dict_table_t* table) /*!< in: table to optimiza */
- MY_ATTRIBUTE((nonnull));
+ dict_table_t* table); /*!< in: table to optimiza */
/**********************************************************************//**
Startup the optimize thread and create the work queue. */
@@ -728,7 +729,7 @@ fts_drop_index_tables(
/*==================*/
trx_t* trx, /*!< in: transaction */
dict_index_t* index) /*!< in: Index to drop */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Remove the table from the OPTIMIZER's list. We do wait for
@@ -738,41 +739,32 @@ fts_optimize_remove_table(
/*======================*/
dict_table_t* table); /*!< in: table to remove */
+/** Shutdown fts optimize thread. */
+void
+fts_optimize_shutdown();
+
/** Send sync fts cache for the table.
@param[in] table table to sync */
-UNIV_INTERN
void
fts_optimize_request_sync_table(
dict_table_t* table);
/**********************************************************************//**
-Signal the optimize thread to prepare for shutdown. */
-void
-fts_optimize_start_shutdown(void);
-/*==============================*/
-
-/**********************************************************************//**
-Inform optimize to clean up. */
-void
-fts_optimize_end(void);
-/*===================*/
-
-/**********************************************************************//**
Take a FTS savepoint. */
void
fts_savepoint_take(
/*===============*/
trx_t* trx, /*!< in: transaction */
fts_trx_t* fts_trx, /*!< in: fts transaction */
- const char* name) /*!< in: savepoint name */
- MY_ATTRIBUTE((nonnull));
+ const char* name); /*!< in: savepoint name */
+
/**********************************************************************//**
Refresh last statement savepoint. */
void
fts_savepoint_laststmt_refresh(
/*===========================*/
- trx_t* trx) /*!< in: transaction */
- MY_ATTRIBUTE((nonnull));
+ trx_t* trx); /*!< in: transaction */
+
/**********************************************************************//**
Release the savepoint data identified by name. */
void
@@ -832,19 +824,21 @@ fts_drop_index_split_tables(
/*========================*/
trx_t* trx, /*!< in: transaction */
dict_index_t* index) /*!< in: fts instance */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Run SYNC on the table, i.e., write out data from the cache to the
FTS auxiliary INDEX table and clear the cache at the end.
@param[in,out] table fts table
@param[in] unlock_cache whether unlock cache when write node
@param[in] wait whether wait for existing sync to finish
+@param[in] has_dict whether has dict operation lock
@return DB_SUCCESS on success, error code on failure. */
dberr_t
fts_sync_table(
dict_table_t* table,
bool unlock_cache,
- bool wait);
+ bool wait,
+ bool has_dict);
/****************************************************************//**
Free the query graph but check whether dict_sys->mutex is already
@@ -1027,8 +1021,7 @@ fts_drop_index(
/*===========*/
dict_table_t* table, /*!< in: Table where indexes are dropped */
dict_index_t* index, /*!< in: Index to be dropped */
- trx_t* trx) /*!< in: Transaction for the drop */
- MY_ATTRIBUTE((nonnull));
+ trx_t* trx); /*!< in: Transaction for the drop */
/****************************************************************//**
Rename auxiliary tables for all fts index for a table
@@ -1053,12 +1046,12 @@ fts_check_cached_index(
consistent state. For now consistency is check only by ensuring
index->page_no != FIL_NULL
@param[out] base_table table has host fts index
-@param[in,out] trx trx handler
-@return true if check certifies auxillary tables are sane false otherwise. */
-bool
-fts_is_corrupt(
+@param[in,out] trx trx handler */
+void
+fts_check_corrupt(
dict_table_t* base_table,
trx_t* trx);
+
#endif /*!< fts0fts.h */
diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h
index f7a2d2c72f2..1fd33c2b103 100644
--- a/storage/innobase/include/fts0priv.h
+++ b/storage/innobase/include/fts0priv.h
@@ -121,7 +121,7 @@ fts_parse_sql(
fts_table_t* fts_table, /*!< in: FTS aux table */
pars_info_t* info, /*!< in: info struct, or NULL */
const char* sql) /*!< in: SQL string to evaluate */
- MY_ATTRIBUTE((nonnull(3), malloc, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Evaluate a parsed SQL statement
@@ -131,7 +131,7 @@ fts_eval_sql(
/*=========*/
trx_t* trx, /*!< in: transaction */
que_t* graph) /*!< in: Parsed statement */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Construct the name of an ancillary FTS table for the given table.
@@ -140,8 +140,9 @@ for param 'table_name'. */
void
fts_get_table_name(
/*===============*/
- const fts_table_t* fts_table, /*!< in: FTS aux table info */
- char* table_name); /*!< in/out: aux table name */
+ const fts_table_t*
+ fts_table, /*!< in: FTS aux table info */
+ char* table_name); /*!< in/out: aux table name */
/******************************************************************//**
Construct the column specification part of the SQL string for selecting the
@@ -164,7 +165,7 @@ fts_get_select_columns_str(
dict_index_t* index, /*!< in: FTS index */
pars_info_t* info, /*!< in/out: parser info */
mem_heap_t* heap) /*!< in: memory heap */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** define for fts_doc_fetch_by_doc_id() "option" value, defines whether
we want to get Doc whose ID is equal to or greater or smaller than supplied
@@ -189,8 +190,7 @@ fts_doc_fetch_by_doc_id(
fts_sql_callback
callback, /*!< in: callback to read
records */
- void* arg) /*!< in: callback arg */
- MY_ATTRIBUTE((nonnull(6)));
+ void* arg); /*!< in: callback arg */
/*******************************************************************//**
Callback function for fetch that stores the text of an FTS document,
@@ -200,8 +200,8 @@ ibool
fts_query_expansion_fetch_doc(
/*==========================*/
void* row, /*!< in: sel_node_t* */
- void* user_arg) /*!< in: fts_doc_t* */
- MY_ATTRIBUTE((nonnull));
+ void* user_arg); /*!< in: fts_doc_t* */
+
/********************************************************************
Write out a single word's data as new entry/entries in the INDEX table.
@return DB_SUCCESS if all OK. */
@@ -213,7 +213,7 @@ fts_write_node(
fts_table_t* fts_table, /*!< in: the FTS aux index */
fts_string_t* word, /*!< in: word in UTF-8 */
fts_node_t* node) /*!< in: node columns */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Check fts token
1. for ngram token, check whether the token contains any words in stopwords
@@ -274,7 +274,7 @@ fts_bsearch(
int lower, /*!< in: lower bound of array*/
int upper, /*!< in: upper bound of array*/
doc_id_t doc_id) /*!< in: doc id to lookup */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Free document. */
void
@@ -359,7 +359,7 @@ fts_parse_sql_no_dict_lock(
fts_table_t* fts_table, /*!< in: table with FTS index */
pars_info_t* info, /*!< in: parser info */
const char* sql) /*!< in: SQL string to evaluate */
- MY_ATTRIBUTE((nonnull(3), malloc, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Get value from config table. The caller must ensure that enough
@@ -388,7 +388,7 @@ fts_config_get_index_value(
this parameter name */
fts_string_t* value) /*!< out: value read from
config table */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Set the value in the config table for name.
@@ -413,7 +413,7 @@ fts_config_set_ulint(
fts_table_t* fts_table, /*!< in: the indexed FTS table */
const char* name, /*!< in: param name */
ulint int_value) /*!< in: value */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Set the value specific to an FTS index in the config table.
@@ -427,7 +427,7 @@ fts_config_set_index_value(
this parameter name */
fts_string_t* value) /*!< out: value read from
config table */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Increment the value in the config table for column name.
@@ -440,7 +440,7 @@ fts_config_increment_value(
const char* name, /*!< in: increment config value
for this parameter name */
ulint delta) /*!< in: increment by this much */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Increment the per index value in the config table for column name.
@@ -464,7 +464,7 @@ fts_config_get_index_ulint(
dict_index_t* index, /*!< in: FTS index */
const char* name, /*!< in: param name */
ulint* int_value) /*!< out: value */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Set an ulint value int the config table.
@@ -476,7 +476,7 @@ fts_config_set_index_ulint(
dict_index_t* index, /*!< in: FTS index */
const char* name, /*!< in: param name */
ulint int_value) /*!< in: value */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Get an ulint value from the config table.
@@ -499,7 +499,7 @@ fts_cache_find_word(
index_cache, /*!< in: cache to search */
const fts_string_t*
text) /*!< in: word to search for */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Check cache for deleted doc id.
@@ -510,7 +510,7 @@ fts_cache_is_deleted_doc_id(
const fts_cache_t*
cache, /*!< in: cache ito search */
doc_id_t doc_id) /*!< in: doc id to search for */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Append deleted doc ids to vector and sort the vector. */
@@ -543,7 +543,7 @@ fts_get_total_word_count(
trx_t* trx, /*!< in: transaction */
dict_index_t* index, /*!< in: for this index */
ulint* total) /*!< out: total words */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#endif
/******************************************************************//**
Search the index specific cache for a particular FTS index.
@@ -555,7 +555,7 @@ fts_find_index_cache(
cache, /*!< in: cache to search */
const dict_index_t*
index) /*!< in: index to search for */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Write the table id to the given buffer (including final NUL). Buffer must be
@@ -567,10 +567,10 @@ fts_write_object_id(
/*================*/
ib_id_t id, /*!< in: a table/index id */
char* str, /*!< in: buffer to write the id to */
- bool hex_format MY_ATTRIBUTE((unused)))
+ bool hex_format MY_ATTRIBUTE((unused)));
/*!< in: true for fixed hex format,
false for old ambiguous format */
- MY_ATTRIBUTE((nonnull));
+
/******************************************************************//**
Read the table id from the string generated by fts_write_object_id().
@return TRUE if parse successful */
@@ -580,7 +580,7 @@ fts_read_object_id(
/*===============*/
ib_id_t* id, /*!< out: a table id */
const char* str) /*!< in: buffer to read from */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Get the table id.
@@ -593,7 +593,7 @@ fts_get_table_id(
char* table_id) /*!< out: table id, must be at least
FTS_AUX_MIN_TABLE_ID_LENGTH bytes
long */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Add the table to add to the OPTIMIZER's list. */
@@ -617,7 +617,7 @@ fts_get_table_name_prefix(
/*======================*/
const fts_table_t*
fts_table) /*!< in: Auxiliary table type */
- MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Add node positions. */
@@ -637,7 +637,7 @@ fts_config_create_index_param_name(
/*===============================*/
const char* param, /*!< in: base name of param */
const dict_index_t* index) /*!< in: index for config */
- MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#ifndef UNIV_NONINL
#include "fts0priv.ic"
diff --git a/storage/innobase/include/fts0priv.ic b/storage/innobase/include/fts0priv.ic
index 9de3be215dc..fa2cdd44a36 100644
--- a/storage/innobase/include/fts0priv.ic
+++ b/storage/innobase/include/fts0priv.ic
@@ -46,31 +46,26 @@ fts_write_object_id(
/* Use this to construct old(5.6.14 and 5.7.3) windows
ambiguous aux table names */
DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name",
- return(sprintf(str, "%016llu", id)););
+ return(sprintf(str, "%016llu", (ulonglong) id)););
#else /* _WIN32 */
/* Use this to construct old(5.6.14 and 5.7.3) windows
ambiguous aux table names */
DBUG_EXECUTE_IF("innodb_test_wrong_windows_fts_aux_table_name",
- return(sprintf(str, "%016lu", id)););
+ return(sprintf(str, "%016llu", (ulonglong) id)););
DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name",
- return(sprintf(str, "%016lx", id)););
+ return(sprintf(str, "%016llx", (ulonglong) id)););
#endif /* _WIN32 */
/* As above, but this is only for those tables failing to rename. */
if (!hex_format) {
-#ifdef _WIN32
- // FIXME: Use ut_snprintf(), so does following one.
- return(sprintf(str, "%016llu", id));
-#else /* _WIN32 */
- return(sprintf(str, "%016lu", id));
-#endif /* _WIN32 */
+ return(sprintf(str, "%016llu", (ulonglong) id));
}
- return(sprintf(str, "%016lx", id));
+ return(sprintf(str, "%016llx", (ulonglong) id));
}
/******************************************************************//**
@@ -86,7 +81,7 @@ fts_read_object_id(
/* NOTE: this func doesn't care about whether current table
is set with HEX_NAME, the user of the id read here will check
if the id is HEX or DEC and do the right thing with it. */
- return(sscanf(str, "%016lx", id) == 1);
+ return(sscanf(str, UINT64PFx, id) == 1);
}
/******************************************************************//**
diff --git a/storage/innobase/include/fut0fut.h b/storage/innobase/include/fut0fut.h
index ab04a700d4f..0b8b8b0e43b 100644
--- a/storage/innobase/include/fut0fut.h
+++ b/storage/innobase/include/fut0fut.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -50,7 +50,7 @@ fut_get_ptr(
rw_lock_type_t rw_latch,
mtr_t* mtr,
buf_block_t** ptr_block = NULL)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#ifndef UNIV_NONINL
#include "fut0fut.ic"
diff --git a/storage/innobase/include/gis0rtree.h b/storage/innobase/include/gis0rtree.h
index 316cab888b3..436374fd6b2 100644
--- a/storage/innobase/include/gis0rtree.h
+++ b/storage/innobase/include/gis0rtree.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2014, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -70,7 +70,7 @@ Created 2013/03/27 Jimmy Yang and Allen Lai
/* Define it for rtree search mode checking. */
#define RTREE_SEARCH_MODE(mode) \
- (((mode) >= PAGE_CUR_CONTAIN) && ((mode <= PAGE_CUR_RTREE_LOCATE)))
+ (((mode) >= PAGE_CUR_CONTAIN) && ((mode <= PAGE_CUR_RTREE_GET_FATHER)))
/* Geometry data header */
#define GEO_DATA_HEADER_SIZE 4
@@ -320,6 +320,23 @@ rtr_get_mbr_from_tuple(
#define rtr_page_get_father_node_ptr(of,heap,sea,cur,mtr) \
rtr_page_get_father_node_ptr_func(of,heap,sea,cur,__FILE__,__LINE__,mtr)
+/* Get the rtree page father.
+@param[in] offsets work area for the return value
+@param[in] index rtree index
+@param[in] block child page in the index
+@param[in] mtr mtr
+@param[in] sea_cur search cursor, contains information
+ about parent nodes in search
+@param[in] cursor cursor on node pointer record,
+ its page x-latched */
+void
+rtr_page_get_father(
+ dict_index_t* index,
+ buf_block_t* block,
+ mtr_t* mtr,
+ btr_cur_t* sea_cur,
+ btr_cur_t* cursor);
+
/************************************************************//**
Returns the upper level node pointer to a R-Tree page. It is assumed
that mtr holds an x-latch on the tree.
diff --git a/storage/innobase/include/ha0ha.h b/storage/innobase/include/ha0ha.h
index 11c12c4ebc3..15a99ddf683 100644
--- a/storage/innobase/include/ha0ha.h
+++ b/storage/innobase/include/ha0ha.h
@@ -211,7 +211,7 @@ struct ha_node_t {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
buf_block_t* block; /*!< buffer block containing the data, or NULL */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- const rec_t* data; /*!< pointer to the data */
+ const rec_t* data; /*!< pointer to the data */
};
#ifdef UNIV_DEBUG
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index 9bf8cd2b281..837c377f448 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -37,6 +37,7 @@ simple headers.
class THD;
class Field;
struct fts_string_t;
+//typedef struct charset_info_st CHARSET_INFO;
/*********************************************************************//**
Wrapper around MySQL's copy_and_convert function.
@@ -162,7 +163,7 @@ checkpoint when necessary.*/
UNIV_INTERN
void
innobase_mysql_log_notify(
-/*===============*/
+/*======================*/
ib_uint64_t write_lsn, /*!< in: LSN written to log file */
ib_uint64_t flush_lsn); /*!< in: LSN flushed to disk */
@@ -342,6 +343,14 @@ thd_set_lock_wait_time(
THD* thd, /*!< in/out: thread handle */
ulint value); /*!< in: time waited for the lock */
+/** Get status of innodb_tmpdir.
+@param[in] thd thread handle, or NULL to query
+ the global innodb_tmpdir.
+@retval NULL if innodb_tmpdir="" */
+const char*
+thd_innodb_tmpdir(
+ THD* thd);
+
/**********************************************************************//**
Get the current setting of the table_cache_size global parameter. We do
a dirty read because for one there is no synchronization object and
@@ -531,7 +540,6 @@ innobase_convert_to_system_charset(
const char* from, /* in: identifier to convert */
ulint len, /* in: length of 'to', in bytes */
uint* errors); /* out: error return */
-
/**********************************************************************
Check if the length of the identifier exceeds the maximum allowed.
The input to this function is an identifier in charset my_charset_filename.
@@ -606,7 +614,7 @@ ICP_RESULT
innobase_index_cond(
/*================*/
void* file) /*!< in/out: pointer to ha_innobase */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Gets information on the durability property requested by thread.
@@ -625,7 +633,7 @@ enum durability_properties
thd_requested_durability(
/*=====================*/
const THD* thd) /*!< in: thread handle */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Update the system variable with the given value of the InnoDB
buffer pool size.
diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h
index c4d83833fb7..f3fd5e9a364 100644
--- a/storage/innobase/include/ibuf0ibuf.h
+++ b/storage/innobase/include/ibuf0ibuf.h
@@ -244,7 +244,7 @@ ibool
ibuf_inside(
/*========*/
const mtr_t* mtr) /*!< in: mini-transaction */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/** Checks if a page address is an ibuf bitmap page (level 3 page) address.
@param[in] page_id page id
@@ -362,20 +362,16 @@ ibuf_delete_for_discarded_space(
@param[in] full If true, do a full contraction based
on PCT_IO(100). If false, the size of contract batch is determined
based on the current size of the change buffer.
-@param[in] space_id tablespace for which to contract, or
-ULINT_UNDEFINED to contract for all tablespaces
@return a lower limit for the combined size in bytes of entries which
will be merged from ibuf trees to the pages read, 0 if ibuf is
empty */
ulint
ibuf_merge_in_background(
- bool full,
- ulint space_id);
+ bool full);
/** Contracts insert buffer trees by reading pages referring to space_id
to the buffer pool.
@returns number of pages merged.*/
-UNIV_INTERN
ulint
ibuf_merge_space(
/*=============*/
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 84050f374fb..eb554e02bc0 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -285,7 +285,7 @@ lock_rec_insert_check_and_lock(
inserted record maybe should inherit
LOCK_GAP type locks from the successor
record */
- MY_ATTRIBUTE((nonnull(2,3,4,6,7), warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Enqueues a waiting request for a lock which cannot be granted immediately.
@@ -381,7 +381,7 @@ lock_clust_rec_modify_check_and_lock(
dict_index_t* index, /*!< in: clustered index */
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
que_thr_t* thr) /*!< in: query thread */
- MY_ATTRIBUTE((warn_unused_result, nonnull));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Checks if locks of other transactions prevent an immediate modify
(delete mark or delete unmark) of a secondary index record.
@@ -401,7 +401,7 @@ lock_sec_rec_modify_check_and_lock(
que_thr_t* thr, /*!< in: query thread
(can be NULL if BTR_NO_LOCKING_FLAG) */
mtr_t* mtr) /*!< in/out: mini-transaction */
- MY_ATTRIBUTE((warn_unused_result, nonnull(2,3,4,6)));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Like lock_clust_rec_read_check_and_lock(), but reads a
secondary index record.
@@ -485,7 +485,7 @@ lock_clust_rec_read_check_and_lock_alt(
ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
que_thr_t* thr) /*!< in: query thread */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Checks that a record is seen in a consistent read.
@return true if sees, or false if an earlier version of the record
@@ -511,11 +511,12 @@ clustered index record might be needed */
bool
lock_sec_rec_cons_read_sees(
/*========================*/
- const rec_t* rec, /*!< in: user record which should be read or
- passed over by a read cursor */
- const dict_index_t* index, /*!< in: clustered index */
- const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
- const ReadView* view); /*!< in: consistent read view */
+ const rec_t* rec, /*!< in: user record which
+ should be read or passed over
+ by a read cursor */
+ const dict_index_t* index, /*!< in: index */
+ const ReadView* view) /*!< in: consistent read view */
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Locks the specified database table in the mode given. If the lock cannot
be granted immediately, the query thread is put to wait.
@@ -529,7 +530,7 @@ lock_table(
in dictionary cache */
lock_mode mode, /*!< in: lock mode */
que_thr_t* thr) /*!< in: query thread */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Creates a table IX lock object for a resurrected transaction. */
void
@@ -537,6 +538,19 @@ lock_table_ix_resurrect(
/*====================*/
dict_table_t* table, /*!< in/out: table */
trx_t* trx); /*!< in/out: transaction */
+
+/** Sets a lock on a table based on the given mode.
+@param[in] table table to lock
+@param[in,out] trx transaction
+@param[in] mode LOCK_X or LOCK_S
+@return error code or DB_SUCCESS. */
+dberr_t
+lock_table_for_trx(
+ dict_table_t* table,
+ trx_t* trx,
+ enum lock_mode mode)
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
+
/*************************************************************//**
Removes a granted record lock of a transaction from the queue and grants
locks to other transactions waiting in the queue if they now are entitled
@@ -634,8 +648,7 @@ ibool
lock_is_table_exclusive(
/*====================*/
const dict_table_t* table, /*!< in: table */
- const trx_t* trx) /*!< in: transaction */
- MY_ATTRIBUTE((nonnull));
+ const trx_t* trx); /*!< in: transaction */
/*********************************************************************//**
Checks if a lock request lock1 has to wait for request lock2.
@return TRUE if lock1 has to wait for lock2 to be removed */
@@ -680,7 +693,7 @@ lock_print_info_summary(
/*====================*/
FILE* file, /*!< in: file where to print */
ibool nowait) /*!< in: whether to wait for the lock mutex */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Prints transaction lock wait and MVCC state.
@param[in,out] file file where to print
@@ -707,7 +720,7 @@ ulint
lock_number_of_rows_locked(
/*=======================*/
const trx_lock_t* trx_lock) /*!< in: transaction locks */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Return the number of table locks for a transaction.
@@ -716,7 +729,7 @@ ulint
lock_number_of_tables_locked(
/*=========================*/
const trx_lock_t* trx_lock) /*!< in: transaction locks */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************************//**
Gets the type of a lock. Non-inline version for using outside of the
@@ -900,7 +913,7 @@ lock_check_trx_id_sanity(
const rec_t* rec, /*!< in: user record */
dict_index_t* index, /*!< in: index */
const ulint* offsets) /*!< in: rec_get_offsets(rec, index) */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************************//**
Check if the transaction holds any locks on the sys tables
or its records.
@@ -921,7 +934,7 @@ lock_trx_has_rec_x_lock(
const dict_table_t* table, /*!< in: table to check */
const buf_block_t* block, /*!< in: buffer block of the record */
ulint heap_no)/*!< in: record heap number */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#endif /* UNIV_DEBUG */
/**
@@ -1141,6 +1154,7 @@ lock_update_split_and_merge(
const buf_block_t* right_block);/*!< in: right page from which merged */
#endif /* WITH_WSREP */
+
#ifndef UNIV_NONINL
#include "lock0lock.ic"
#endif
diff --git a/storage/innobase/include/lock0prdt.h b/storage/innobase/include/lock0prdt.h
index 8941a134a8f..6c61f07a4e8 100644
--- a/storage/innobase/include/lock0prdt.h
+++ b/storage/innobase/include/lock0prdt.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -203,22 +203,25 @@ lock_prdt_rec_move(
const buf_block_t* donator); /*!< in: buffer block containing
the donating record */
-/*********************************************************************//**
-Check whether there are R-tree Page lock on a buffer page
+/** Check whether there are R-tree Page lock on a buffer page
+@param[in] trx trx to test the lock
+@param[in] space space id for the page
+@param[in] page_no page number
@return true if there is none */
bool
lock_test_prdt_page_lock(
/*=====================*/
- ulint space, /*!< in: space id for the page */
- ulint page_no); /*!< in: page number */
+ const trx_t* trx,
+ ulint space,
+ ulint page_no);
-/*************************************************************//**
-Removes predicate lock objects set on an index page which is discarded. */
+/** Removes predicate lock objects set on an index page which is discarded.
+@param[in] block page to be discarded
+@param[in] lock_hash lock hash */
void
-lock_prdt_free_from_discard_page(
+lock_prdt_page_free_from_discard(
/*=============================*/
- const buf_block_t* block, /*!< in: page to be discarded */
+ const buf_block_t* block,
hash_table_t* lock_hash);
- /*!< in: lock hash */
#endif
diff --git a/storage/innobase/include/lock0priv.h b/storage/innobase/include/lock0priv.h
index 06573d261fb..0b2ab1bfcfe 100644
--- a/storage/innobase/include/lock0priv.h
+++ b/storage/innobase/include/lock0priv.h
@@ -729,20 +729,23 @@ public:
Create a lock for a transaction and initialise it.
@param[in, out] trx Transaction requesting the new lock
@param[in] owns_trx_mutex true if caller owns the trx_t::mutex
+ @param[in] add_to_hash add the lock to hash table
@param[in] prdt Predicate lock (optional)
@return new lock instance */
lock_t* create(
trx_t* trx,
bool owns_trx_mutex,
+ bool add_to_hash,
const lock_prdt_t*
prdt = NULL);
+
lock_t* create(
lock_t* const c_lock,
trx_t* trx,
bool owns_trx_mutex,
+ bool add_to_hash,
const lock_prdt_t*
prdt = NULL);
-
/**
Check of the lock is on m_rec_id.
@param[in] lock Lock to compare with
@@ -765,19 +768,6 @@ public:
ulint size);
private:
- /**
- Enqueue a lock wait for a high priority transaction, jump the record
- lock wait queue and if the transaction at the head of the queue is
- itself waiting roll it back.
- @param[in, out] wait_for The lock that the joining
- transaction is waiting for
- @param[in] prdt Predicate for the predicate lock
- @return NULL if the lock was granted */
- lock_t* enqueue_priority(
- const lock_t* wait_for,
- const lock_prdt_t*
- prdt);
-
/*
@return the record lock size in bytes */
size_t lock_size() const
@@ -795,15 +785,47 @@ private:
void mark_trx_for_rollback(trx_t* trx);
/**
- Add the lock to the head of the record lock {space, page_no} wait
- queue and the transaction's lock list. If the transactions holding
- blocking locks are already marked for termination then they are not
- added to the hit list.
- @param[in, out] lock Lock being requested
- @param[in] wait_for The blocking lock
- @param[in] kill_trx true if the transaction that m_trx
- is waiting for should be killed */
- void jump_queue(lock_t* lock, const lock_t* wait_for, bool kill_trx);
+ Jump the queue for the record over all low priority transactions and
+ add the lock. If all current granted locks are compatible, grant the
+ lock. Otherwise, mark all granted transaction for asynchronous
+ rollback and add to hit list.
+ @param[in, out] lock Lock being requested
+ @param[in] conflict_lock First conflicting lock from the head
+ @return true if the lock is granted */
+ bool jump_queue(lock_t* lock, const lock_t* conflict_lock);
+
+ /** Find position in lock queue and add the high priority transaction
+ lock. Intention and GAP only locks can be granted even if there are
+ waiting locks in front of the queue. To add the High priority
+ transaction in a safe position we keep the following rule.
+
+ 1. If the lock can be granted, add it before the first waiting lock
+ in the queue so that all currently waiting locks need to do conflict
+ check before getting granted.
+
+ 2. If the lock has to wait, add it after the last granted lock or the
+ last waiting high priority transaction in the queue whichever is later.
+ This ensures that the transaction is granted only after doing conflict
+ check with all granted transactions.
+ @param[in] lock Lock being requested
+ @param[in] conflict_lock First conflicting lock from the head
+ @param[out] high_priority high priority transaction ahead in queue
+ @return true if the lock can be granted */
+ bool
+ lock_add_priority(
+ lock_t* lock,
+ const lock_t* conflict_lock,
+ bool* high_priority);
+
+ /** Iterate over the granted locks and prepare the hit list for ASYNC Rollback.
+ If the transaction is waiting for some other lock then wake up with deadlock error.
+ Currently we don't mark following transactions for ASYNC Rollback.
+ 1. Read only transactions
+ 2. Background transactions
+ 3. Other High priority transactions
+ @param[in] lock Lock being requested
+ @param[in] conflict_lock First conflicting lock from the head */
+ void make_trx_hit_list(lock_t* lock, const lock_t* conflict_lock);
/**
Setup the requesting transaction state for lock grant
@@ -811,11 +833,6 @@ private:
void set_wait_state(lock_t* lock);
/**
- Rollback the transaction that is blocking the requesting transaction
- @param[in, out] lock The blocking lock */
- void rollback_blocking_trx(lock_t* lock) const;
-
- /**
Add the lock to the record lock hash and the transaction's lock list
@param[in,out] lock Newly created record lock to add to the
rec hash and the transaction lock list
@@ -987,7 +1004,7 @@ lock_clust_rec_some_has_impl(
const rec_t* rec, /*!< in: user record */
const dict_index_t* index, /*!< in: clustered index */
const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Gets the first or next record lock on a page.
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index e67eef4a26c..c1f25704217 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2009, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -39,11 +39,7 @@ Created 12/9/1995 Heikki Tuuri
#include "sync0rw.h"
#endif /* !UNIV_HOTBACKUP */
#include "log0crypt.h"
-
-
-#define LSN_MAX IB_UINT64_MAX
-
-#define LSN_PF UINT64PF
+#include "log0types.h"
/** Redo log buffer */
struct log_t;
@@ -178,7 +174,7 @@ log_init(void);
/******************************************************************//**
Inits a log group to the log system.
@return true if success, false if not */
-__attribute__((warn_unused_result))
+MY_ATTRIBUTE((warn_unused_result))
bool
log_group_init(
/*===========*/
@@ -564,7 +560,9 @@ or the MySQL version that created the redo log file. */
/** The redo log format identifier corresponding to the current format version.
Stored in LOG_HEADER_FORMAT. */
#define LOG_HEADER_FORMAT_CURRENT 1
-/* @} */
+
+// JAN: TODO: Shoud 32 here be LOG_HEADER_CREATOR_END ?
+// Problem: Log format 5.6 == 5.7 ?
#define LOG_CHECKPOINT_ARRAY_END (32 + 32 * 8)
#define LOG_CRYPT_VER (20 + LOG_CHECKPOINT_ARRAY_END)
#define LOG_CRYPT_MAX_ENTRIES (5)
@@ -575,6 +573,7 @@ Stored in LOG_HEADER_FORMAT. */
#define LOG_CHECKPOINT_SIZE (20 + LOG_CHECKPOINT_ARRAY_END + \
LOG_CRYPT_SIZE)
+/* @} */
#define LOG_CHECKPOINT_1 OS_FILE_LOG_BLOCK_SIZE
/* first checkpoint field in the log
@@ -600,7 +599,9 @@ typedef ib_mutex_t FlushOrderMutex;
/** Log group consists of a number of log files, each of the same size; a log
group is implemented as a space in the sense of the module fil0fil.
-The fields are protected by log_sys->mutex. */
+Currently, this is only protected by log_sys->mutex. However, in the case
+of log_write_up_to(), we will access some members only with the protection
+of log_sys->write_mutex, which should affect nothing for now. */
struct log_group_t{
/** log group identifier (always 0) */
ulint id;
@@ -642,11 +643,14 @@ struct log_t{
same memory cache line */
lsn_t lsn; /*!< log sequence number */
ulint buf_free; /*!< first free offset within the log
- buffer */
+ buffer in use */
#ifndef UNIV_HOTBACKUP
char pad2[CACHE_LINE_SIZE];/*!< Padding */
LogSysMutex mutex; /*!< mutex protecting the log */
- char pad3[CACHE_LINE_SIZE];/*!< Padding */
+ char pad3[CACHE_LINE_SIZE]; /*!< Padding */
+ LogSysMutex write_mutex; /*!< mutex protecting writing to log
+ file and accessing to log_group_t */
+ char pad4[CACHE_LINE_SIZE];/*!< Padding */
FlushOrderMutex log_flush_order_mutex;/*!< mutex to serialize access to
the flush list when we are putting
dirty blocks in the list. The idea
@@ -656,12 +660,22 @@ struct log_t{
insertions in the flush_list happen
in the LSN order. */
#endif /* !UNIV_HOTBACKUP */
- byte* buf_ptr; /* unaligned log buffer */
- byte* buf; /*!< log buffer */
- ulint buf_size; /*!< log buffer size in bytes */
+ byte* buf_ptr; /*!< unaligned log buffer, which should
+ be of double of buf_size */
+ byte* buf; /*!< log buffer currently in use;
+ this could point to either the first
+ half of the aligned(buf_ptr) or the
+ second half in turns, so that log
+ write/flush to disk don't block
+ concurrent mtrs which will write
+ log to this buffer */
+ bool first_in_use; /*!< true if buf points to the first
+ half of the aligned(buf_ptr), false
+ if the second half */
+ ulint buf_size; /*!< log buffer size of each in bytes */
ulint max_buf_free; /*!< recommended maximum value of
- buf_free, after which the buffer is
- flushed */
+ buf_free for the buffer in use, after
+ which the buffer is flushed */
bool check_flush_or_checkpoint;
/*!< this is set when there may
be need to flush the log buffer, or
@@ -687,11 +701,6 @@ struct log_t{
volatile bool is_extending; /*!< this is set to true during extend
the log buffer size */
lsn_t write_lsn; /*!< last written lsn */
- ulint write_end_offset;/*!< the data in buffer has
- been written up to this offset
- when the current write ends:
- this field will then be copied
- to buf_next_to_write */
lsn_t current_flush_lsn;/*!< end lsn for the current running
write + flush operation */
lsn_t flushed_to_disk_lsn;
@@ -786,12 +795,33 @@ struct log_t{
/** Test if log sys mutex is owned. */
#define log_mutex_own() mutex_own(&log_sys->mutex)
+/** Test if log sys write mutex is owned. */
+#define log_write_mutex_own() mutex_own(&log_sys->write_mutex)
+
/** Acquire the log sys mutex. */
#define log_mutex_enter() mutex_enter(&log_sys->mutex)
+/** Acquire the log sys write mutex. */
+#define log_write_mutex_enter() mutex_enter(&log_sys->write_mutex)
+
+/** Acquire all the log sys mutexes. */
+#define log_mutex_enter_all() do { \
+ mutex_enter(&log_sys->write_mutex); \
+ mutex_enter(&log_sys->mutex); \
+} while (0)
+
/** Release the log sys mutex. */
#define log_mutex_exit() mutex_exit(&log_sys->mutex)
+/** Release the log sys write mutex.*/
+#define log_write_mutex_exit() mutex_exit(&log_sys->write_mutex)
+
+/** Release all the log sys mutexes. */
+#define log_mutex_exit_all() do { \
+ mutex_exit(&log_sys->mutex); \
+ mutex_exit(&log_sys->write_mutex); \
+} while (0)
+
/** Calculate the offset of an lsn within a log group.
@param[in] lsn log sequence number
@param[in] group log group
diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic
index caf497606d8..a53f8770cea 100644
--- a/storage/innobase/include/log0log.ic
+++ b/storage/innobase/include/log0log.ic
@@ -439,15 +439,14 @@ Gets the last lsn that is fully flushed to disk.
UNIV_INLINE
ib_uint64_t
log_get_flush_lsn(void)
-/*=============*/
{
ib_uint64_t lsn;
- mutex_enter(&(log_sys->mutex));
+ log_mutex_enter();
lsn = log_sys->flushed_to_disk_lsn;
- mutex_exit(&(log_sys->mutex));
+ log_mutex_exit();
return(lsn);
}
@@ -458,7 +457,7 @@ Gets the current lsn with a trylock
UNIV_INLINE
lsn_t
log_get_lsn_nowait(void)
-/*=============*/
+/*====================*/
{
lsn_t lsn=0;
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index 85b326e6500..bd7118654f3 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -35,6 +35,7 @@ Created 9/20/1997 Heikki Tuuri
#include "ut0new.h"
#include <list>
+#include <vector>
#ifdef UNIV_HOTBACKUP
extern bool recv_replay_file_ops;
@@ -278,6 +279,16 @@ struct recv_dblwr_t {
list pages;
};
+/* Recovery encryption information */
+typedef struct recv_encryption {
+ ulint space_id; /*!< the page number */
+ byte* key; /*!< encryption key */
+ byte* iv; /*!< encryption iv */
+} recv_encryption_t;
+
+typedef std::vector<recv_encryption_t, ut_allocator<recv_encryption_t> >
+ encryption_list_t;
+
/** Recovery system data structure */
struct recv_sys_t{
#ifndef UNIV_HOTBACKUP
@@ -346,6 +357,9 @@ struct recv_sys_t{
addresses in the hash table */
recv_dblwr_t dblwr;
+
+ encryption_list_t* /*!< Encryption information list */
+ encryption_list;
};
/** The recovery system */
@@ -404,7 +418,7 @@ extern ulint recv_n_pool_free_frames;
/******************************************************//**
Checks the 4-byte checksum to the trailer checksum field of a log
block. */
-ibool
+bool
log_block_checksum_is_ok(
/*===================================*/
const byte* block, /*!< in: pointer to a log block */
diff --git a/storage/innobase/include/mach0data.h b/storage/innobase/include/mach0data.h
index 07e23139542..4d32e2e7170 100644
--- a/storage/innobase/include/mach0data.h
+++ b/storage/innobase/include/mach0data.h
@@ -53,7 +53,7 @@ ulint
mach_read_from_1(
/*=============*/
const byte* b) /*!< in: pointer to byte */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************//**
The following function is used to store data in two consecutive
bytes. We store the most significant byte to the lower address. */
@@ -72,7 +72,7 @@ ulint
mach_read_from_2(
/*=============*/
const byte* b) /*!< in: pointer to two bytes */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************//**
The following function is used to convert a 16-bit data item
@@ -114,7 +114,7 @@ ulint
mach_read_from_3(
/*=============*/
const byte* b) /*!< in: pointer to 3 bytes */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************//**
The following function is used to store data in four consecutive
bytes. We store the most significant byte to the lowest address. */
@@ -133,7 +133,7 @@ ulint
mach_read_from_4(
/*=============*/
const byte* b) /*!< in: pointer to four bytes */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************//**
Writes a ulint in a compressed form (1..5 bytes).
@return stored size in bytes */
@@ -159,8 +159,7 @@ advanced by the number of bytes consumed
UNIV_INLINE
ib_uint32_t
mach_read_next_compressed(
- const byte** b)
- MY_ATTRIBUTE((nonnull, pure));
+ const byte** b);
/*******************************************************//**
The following function is used to store data in 6 consecutive
bytes. We store the most significant byte to the lowest address. */
@@ -179,7 +178,7 @@ ib_uint64_t
mach_read_from_6(
/*=============*/
const byte* b) /*!< in: pointer to 6 bytes */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************//**
The following function is used to store data in 7 consecutive
bytes. We store the most significant byte to the lowest address. */
@@ -198,7 +197,7 @@ ib_uint64_t
mach_read_from_7(
/*=============*/
const byte* b) /*!< in: pointer to 7 bytes */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************//**
The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */
@@ -217,7 +216,7 @@ ib_uint64_t
mach_read_from_8(
/*=============*/
const byte* b) /*!< in: pointer to 8 bytes */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************//**
Writes a 64-bit integer in a compressed form (5..9 bytes).
@return size in bytes */
@@ -252,7 +251,7 @@ ib_uint64_t
mach_u64_read_much_compressed(
/*==========================*/
const byte* b) /*!< in: pointer to memory from where to read */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/** Read a 32-bit integer in a compressed form.
@param[in,out] ptr pointer to memory where to read;
advanced by the number of bytes consumed, or set NULL if out of space
@@ -281,7 +280,7 @@ double
mach_double_read(
/*=============*/
const byte* b) /*!< in: pointer to memory from where to read */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************//**
Writes a double. It is stored in a little-endian format. */
UNIV_INLINE
@@ -298,7 +297,7 @@ float
mach_float_read(
/*============*/
const byte* b) /*!< in: pointer to memory from where to read */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************//**
Writes a float. It is stored in a little-endian format. */
UNIV_INLINE
@@ -316,7 +315,7 @@ mach_read_from_n_little_endian(
/*===========================*/
const byte* buf, /*!< in: from where to read */
ulint buf_size) /*!< in: from how many bytes to read */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE
@@ -334,7 +333,7 @@ ulint
mach_read_from_2_little_endian(
/*===========================*/
const byte* buf) /*!< in: from where to read */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE
@@ -387,7 +386,7 @@ ulint
mach_read_ulint(
const byte* ptr,
mlog_id_t type)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
#endif /* !UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/include/mach0data.ic b/storage/innobase/include/mach0data.ic
index 88c88cf2e76..ece4a37bcce 100644
--- a/storage/innobase/include/mach0data.ic
+++ b/storage/innobase/include/mach0data.ic
@@ -42,6 +42,7 @@ mach_write_to_1(
b[0] = (byte) n;
}
+
#endif /* !UNIV_INNOCHECKSUM */
/*******************************************************//**
@@ -948,4 +949,3 @@ mach_read_ulint(
#endif /* !UNIV_HOTBACKUP */
#endif /* !UNIV_INNOCHECKSUM */
-
diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h
index 72791e23574..f8fdb53e132 100644
--- a/storage/innobase/include/mem0mem.h
+++ b/storage/innobase/include/mem0mem.h
@@ -207,7 +207,7 @@ mem_heap_is_top(
mem_heap_t* heap,
const void* buf,
ulint buf_sz)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*****************************************************************//**
Allocate a new chunk of memory from a memory heap, possibly discarding
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index d20a1647654..3b4109ee52d 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
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
diff --git a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic
index 07aa08ed9df..4015fe36d19 100644
--- a/storage/innobase/include/mtr0log.ic
+++ b/storage/innobase/include/mtr0log.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -214,11 +214,8 @@ mlog_write_initial_log_record_fast(
ulint space;
ulint offset;
- ut_ad(mtr->memo_contains_page_flagged(
- ptr,
- MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX));
-
- ut_ad(ptr && log_ptr);
+ ut_ad(log_ptr);
+ ut_d(mtr->memo_modify_page(ptr));
page = (const byte*) ut_align_down(ptr, UNIV_PAGE_SIZE);
space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
@@ -247,18 +244,7 @@ mlog_write_initial_log_record_fast(
}
}
- log_ptr = mlog_write_initial_log_record_low(
- type, space, offset, log_ptr, mtr);
-
-#ifdef UNIV_DEBUG
- /* We now assume that all x-latched pages have been modified! */
- buf_block_t* block = (buf_block_t*) buf_block_align(ptr);
-
- if (!mtr->memo_contains(mtr->get_memo(), block, MTR_MEMO_MODIFY)) {
- mtr->memo_push(block, MTR_MEMO_MODIFY);
- }
-#endif /* UNIV_DEBUG */
-
- return(log_ptr);
+ return(mlog_write_initial_log_record_low(type, space, offset,
+ log_ptr, mtr));
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index d3aa191c27a..4a1d867015d 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -37,7 +37,6 @@ Created 11/26/1995 Heikki Tuuri
/** Start a mini-transaction. */
#define mtr_start(m) (m)->start()
-
/** Start a mini-transaction. */
#define mtr_start_trx(m, t) (m)->start((t))
@@ -105,8 +104,7 @@ savepoint. */
/** Check if memo contains the given page.
@return TRUE if contains */
#define mtr_memo_contains_page(m, p, t) \
- (m)->memo_contains_page( \
- (m)->get_memo(), (p), (t))
+ (m)->memo_contains_page_flagged((p), (t))
#endif /* UNIV_DEBUG */
/** Print info of an mtr handle. */
@@ -280,7 +278,7 @@ struct mtr_t {
/** Return current size of the buffer.
@return savepoint */
ulint get_savepoint() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
ut_ad(is_active());
ut_ad(m_impl.m_magic_n == MTR_MAGIC_N);
@@ -310,7 +308,7 @@ struct mtr_t {
/** Get the logging mode.
@return logging mode */
inline mtr_log_t get_log_mode() const
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Change the logging mode.
@param mode logging mode
@@ -379,7 +377,7 @@ struct mtr_t {
@param type) MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES
@return value read */
inline ulint read_ulint(const byte* ptr, mlog_id_t type) const
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Locks a rw-latch in S mode.
NOTE: use mtr_s_lock().
@@ -418,6 +416,10 @@ struct mtr_t {
@param type object type: MTR_MEMO_S_LOCK, ...
@return bool if lock released */
bool memo_release(const void* object, ulint type);
+ /** Release a page latch.
+ @param[in] ptr pointer to within a page frame
+ @param[in] type object type: MTR_MEMO_PAGE_X_FIX, ... */
+ void release_page(const void* ptr, mtr_memo_type_t type);
/** Note that the mini-transaction has modified data. */
void set_modified()
@@ -494,18 +496,7 @@ struct mtr_t {
mtr_buf_t* memo,
const void* object,
ulint type)
- __attribute__((warn_unused_result));
-
- /** Check if memo contains the given page.
- @param memo memo stack
- @param ptr pointer to buffer frame
- @param type type of object
- @return true if contains */
- static bool memo_contains_page(
- mtr_buf_t* memo,
- const byte* ptr,
- ulint type)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Check if memo contains the given item.
@param object object to search
@@ -515,11 +506,18 @@ struct mtr_t {
bool memo_contains_flagged(const void* ptr, ulint flags) const;
/** Check if memo contains the given page.
- @param ptr buffer frame
- @param flags specify types of object with OR of
+ @param[in] ptr pointer to within buffer frame
+ @param[in] flags specify types of object with OR of
MTR_MEMO_PAGE_S_FIX... values
- @return true if contains */
- bool memo_contains_page_flagged(const byte* ptr, ulint flags) const;
+ @return the block
+ @retval NULL if not found */
+ buf_block_t* memo_contains_page_flagged(
+ const byte* ptr,
+ ulint flags) const;
+
+ /** Mark the given latched page as modified.
+ @param[in] ptr pointer to within buffer frame */
+ void memo_modify_page(const byte* ptr);
/** Print info of an mtr handle. */
void print() const;
@@ -594,7 +592,7 @@ struct mtr_t {
@param block block being x-fixed
@return true if the mtr is dirtying a clean page. */
static bool is_block_dirtied(const buf_block_t* block)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
private:
/** Look up the system tablespace. */
diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic
index 6c61f8da9f0..b3d9b052d52 100644
--- a/storage/innobase/include/mtr0mtr.ic
+++ b/storage/innobase/include/mtr0mtr.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
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
diff --git a/storage/innobase/include/os0atomic.h b/storage/innobase/include/os0atomic.h
index 1368176d0b8..7ac429cfc14 100644
--- a/storage/innobase/include/os0atomic.h
+++ b/storage/innobase/include/os0atomic.h
@@ -1,5 +1,5 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -208,6 +208,8 @@ amount to decrement. There is no atomic substract function on Windows */
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
+#if defined(HAVE_GCC_SYNC_BUILTINS)
+
# define os_compare_and_swap(ptr, old_val, new_val) \
__sync_bool_compare_and_swap(ptr, old_val, new_val)
@@ -220,9 +222,63 @@ compare to, new_val is the value to swap in. */
# define os_compare_and_swap_uint32(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
+#else
+
+UNIV_INLINE
+bool
+os_compare_and_swap_ulint(volatile ulint* ptr, ulint old_val, ulint new_val)
+{
+#ifdef HAVE_IB_GCC_ATOMIC_SEQ_CST
+ return __atomic_compare_exchange_n(ptr, &old_val, new_val, 0,
+ __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+#else
+ return __sync_bool_compare_and_swap(ptr, old_val, new_val);
+#endif
+}
+
+UNIV_INLINE
+bool
+os_compare_and_swap_lint(volatile lint* ptr, lint old_val, lint new_val)
+{
+#ifdef HAVE_IB_GCC_ATOMIC_SEQ_CST
+ return __atomic_compare_exchange_n(ptr, &old_val, new_val, 0,
+ __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+#else
+ return __sync_bool_compare_and_swap(ptr, old_val, new_val);
+#endif
+}
+
+UNIV_INLINE
+bool
+os_compare_and_swap_uint32(volatile ib_uint32_t* ptr, ib_uint32_t old_val, ib_uint32_t new_val)
+{
+#ifdef HAVE_IB_GCC_ATOMIC_SEQ_CST
+ return __atomic_compare_exchange_n(ptr, &old_val, new_val, 0,
+ __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+#else
+ return __sync_bool_compare_and_swap(ptr, old_val, new_val);
+#endif
+}
+
+#endif /* HAVE_GCC_SYNC_BUILTINS */
+
# ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
+#if defined(HAVE_GCC_SYNC_BUILTINS)
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
+#else
+UNIV_INLINE
+bool
+os_compare_and_swap_thread_id(volatile os_thread_id_t* ptr, os_thread_id_t old_val, os_thread_id_t new_val)
+{
+#ifdef HAVE_IB_GCC_ATOMIC_SEQ_CST
+ return __atomic_compare_exchange_n(ptr, &old_val, new_val, 0,
+ __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+#else
+ return __sync_bool_compare_and_swap(ptr, old_val, new_val);
+#endif
+}
+#endif /* HAVE_GCC_SYNC_BUILTINS */
# define INNODB_RW_LOCKS_USE_ATOMICS
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes and rw_locks use GCC atomic builtins"
@@ -235,8 +291,19 @@ compare to, new_val is the value to swap in. */
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
+#if defined(HAVE_GCC_SYNC_BUILTINS)
+# define os_atomic_increment(ptr, amount) \
+ __sync_add_and_fetch(ptr, amount)
+#else
+#ifdef HAVE_IB_GCC_ATOMIC_SEQ_CST
+# define os_atomic_increment(ptr, amount) \
+ __atomic_add_fetch(ptr, amount, __ATOMIC_SEQ_CST)
+#else
# define os_atomic_increment(ptr, amount) \
__sync_add_and_fetch(ptr, amount)
+#endif
+
+#endif /* HAVE_GCC_SYNC_BUILTINS */
# define os_atomic_increment_lint(ptr, amount) \
os_atomic_increment(ptr, amount)
@@ -253,8 +320,18 @@ amount of increment. */
/* Returns the resulting value, ptr is pointer to target, amount is the
amount to decrement. */
+#if defined(HAVE_GCC_SYNC_BUILTINS)
+# define os_atomic_decrement(ptr, amount) \
+ __sync_sub_and_fetch(ptr, amount)
+#else
+#ifdef HAVE_IB_GCC_ATOMIC_SEQ_CST
+# define os_atomic_decrement(ptr, amount) \
+ __atomic_sub_fetch(ptr, amount, __ATOMIC_SEQ_CST)
+#else
# define os_atomic_decrement(ptr, amount) \
__sync_sub_and_fetch(ptr, amount)
+#endif
+#endif /* HAVE_GCC_SYNC_BUILTINS */
# define os_atomic_decrement_lint(ptr, amount) \
os_atomic_decrement(ptr, amount)
diff --git a/storage/innobase/include/os0atomic.ic b/storage/innobase/include/os0atomic.ic
index 651f7b512c9..1f1c460bc47 100644
--- a/storage/innobase/include/os0atomic.ic
+++ b/storage/innobase/include/os0atomic.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -152,7 +152,11 @@ os_atomic_test_and_set(
/* Silence a compiler warning about unused ptr. */
(void) ptr;
+#if defined(__powerpc__) || defined(__aarch64__)
+ __atomic_exchange(ptr, &new_val, &ret, __ATOMIC_SEQ_CST);
+#else
__atomic_exchange(ptr, &new_val, &ret, __ATOMIC_RELEASE);
+#endif
return(ret);
}
@@ -172,8 +176,13 @@ os_atomic_val_compare_and_swap(
/* Silence a compiler warning about unused ptr. */
(void) ptr;
+#if defined(__powerpc__) || defined(__aarch64__)
+ __atomic_compare_exchange(ptr, &old_val, &new_val, false,
+ __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+#else
__atomic_compare_exchange(ptr, &old_val, &new_val, false,
__ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
+#endif
return(old_val);
}
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index 5aa1843c236..5e36cfc2ac0 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -137,6 +137,7 @@ static const ulint OS_FILE_READ_WRITE = 444;
/** Used by MySQLBackup */
static const ulint OS_FILE_READ_ALLOW_DELETE = 555;
+
/* Options for file_create */
static const ulint OS_FILE_AIO = 61;
static const ulint OS_FILE_NORMAL = 62;
@@ -154,6 +155,7 @@ static const ulint OS_FILE_NOT_FOUND = 71;
static const ulint OS_FILE_DISK_FULL = 72;
static const ulint OS_FILE_ALREADY_EXISTS = 73;
static const ulint OS_FILE_PATH_ERROR = 74;
+
/** wait for OS aio resources to become available again */
static const ulint OS_FILE_AIO_RESOURCES_RESERVED = 75;
@@ -230,32 +232,32 @@ struct Compression {
@param[in] page Page contents
@return true if it is a compressed page */
static bool is_compressed_page(const byte* page)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Check wether the compression algorithm is supported.
@param[in] algorithm Compression algorithm to check
@param[out] type The type that algorithm maps to
@return DB_SUCCESS or error code */
static dberr_t check(const char* algorithm, Compression* type)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Validate the algorithm string.
@param[in] algorithm Compression algorithm to check
@return DB_SUCCESS or error code */
static dberr_t validate(const char* algorithm)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Convert to a "string".
@param[in] type The compression type
@return the string representation */
static const char* to_string(Type type)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Convert the meta data to a std::string.
@param[in] meta Page Meta data
@return the string representation */
static std::string to_string(const meta_t& meta)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Deserizlise the page header compression meta-data
@param[in] header Pointer to the page header
@@ -268,7 +270,7 @@ struct Compression {
@param[in] algorithm Compression algorithm to check
@return true if no algorithm requested */
static bool is_none(const char* algorithm)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Decompress the page data contents. Page type must be
FIL_PAGE_COMPRESSED, if not then the source contents are
@@ -285,12 +287,215 @@ struct Compression {
byte* src,
byte* dst,
ulint dst_len)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Compression type */
Type m_type;
};
+/** Encryption key length */
+static const ulint ENCRYPTION_KEY_LEN = 32;
+
+/** Encryption magic bytes size */
+static const ulint ENCRYPTION_MAGIC_SIZE = 3;
+
+/** Encryption magic bytes for 5.7.11, it's for checking the encryption information
+version. */
+static const char ENCRYPTION_KEY_MAGIC_V1[] = "lCA";
+
+/** Encryption magic bytes for 5.7.12+, it's for checking the encryption information
+version. */
+static const char ENCRYPTION_KEY_MAGIC_V2[] = "lCB";
+
+/** Encryption master key prifix */
+static const char ENCRYPTION_MASTER_KEY_PRIFIX[] = "INNODBKey";
+
+/** Encryption master key prifix size */
+static const ulint ENCRYPTION_MASTER_KEY_PRIFIX_LEN = 9;
+
+/** Encryption master key prifix size */
+static const ulint ENCRYPTION_MASTER_KEY_NAME_MAX_LEN = 100;
+
+/** UUID of server instance, it's needed for composing master key name */
+static const ulint ENCRYPTION_SERVER_UUID_LEN = 36;
+
+/** Encryption information total size for 5.7.11: magic number + master_key_id +
+key + iv + checksum */
+static const ulint ENCRYPTION_INFO_SIZE_V1 = (ENCRYPTION_MAGIC_SIZE \
+ + (ENCRYPTION_KEY_LEN * 2) \
+ + 2 * sizeof(ulint));
+
+/** Encryption information total size: magic number + master_key_id +
+key + iv + server_uuid + checksum */
+static const ulint ENCRYPTION_INFO_SIZE_V2 = (ENCRYPTION_MAGIC_SIZE \
+ + (ENCRYPTION_KEY_LEN * 2) \
+ + ENCRYPTION_SERVER_UUID_LEN \
+ + 2 * sizeof(ulint));
+
+class IORequest;
+
+/** Encryption algorithm. */
+struct Encryption {
+
+ /** Algorithm types supported */
+ enum Type {
+
+ /** No encryption */
+ NONE = 0,
+
+ /** Use AES */
+ AES = 1,
+ };
+
+ /** Encryption information format version */
+ enum Version {
+
+ /** Version in 5.7.11 */
+ ENCRYPTION_VERSION_1 = 0,
+
+ /** Version in > 5.7.11 */
+ ENCRYPTION_VERSION_2 = 1,
+ };
+
+ /** Default constructor */
+ Encryption() : m_type(NONE) { };
+
+ /** Specific constructor
+ @param[in] type Algorithm type */
+ explicit Encryption(Type type)
+ :
+ m_type(type)
+ {
+#ifdef UNIV_DEBUG
+ switch (m_type) {
+ case NONE:
+ case AES:
+
+ default:
+ ut_error;
+ }
+#endif /* UNIV_DEBUG */
+ }
+
+ /** Copy constructor */
+ Encryption(const Encryption& other)
+ :
+ m_type(other.m_type),
+ m_key(other.m_key),
+ m_klen(other.m_klen),
+ m_iv(other.m_iv)
+ { };
+
+ /** Check if page is encrypted page or not
+ @param[in] page page which need to check
+ @return true if it is a encrypted page */
+ static bool is_encrypted_page(const byte* page)
+ MY_ATTRIBUTE((warn_unused_result));
+
+ /** Check the encryption option and set it
+ @param[in] option encryption option
+ @param[in/out] encryption The encryption type
+ @return DB_SUCCESS or DB_UNSUPPORTED */
+ dberr_t set_algorithm(const char* option, Encryption* type)
+ MY_ATTRIBUTE((warn_unused_result));
+
+ /** Validate the algorithm string.
+ @param[in] algorithm Encryption algorithm to check
+ @return DB_SUCCESS or error code */
+ static dberr_t validate(const char* algorithm)
+ MY_ATTRIBUTE((warn_unused_result));
+
+ /** Convert to a "string".
+ @param[in] type The encryption type
+ @return the string representation */
+ static const char* to_string(Type type)
+ MY_ATTRIBUTE((warn_unused_result));
+
+ /** Check if the string is "empty" or "none".
+ @param[in] algorithm Encryption algorithm to check
+ @return true if no algorithm requested */
+ static bool is_none(const char* algorithm)
+ MY_ATTRIBUTE((warn_unused_result));
+
+ /** Generate random encryption value for key and iv.
+ @param[in,out] value Encryption value */
+ static void random_value(byte* value);
+
+ /** Create new master key for key rotation.
+ @param[in,out] master_key master key */
+ static void create_master_key(byte** master_key);
+
+ /** Get master key by key id.
+ @param[in] master_key_id master key id
+ @param[in] srv_uuid uuid of server instance
+ @param[in,out] master_key master key */
+ static void get_master_key(ulint master_key_id,
+ char* srv_uuid,
+ byte** master_key);
+
+ /** Get current master key and key id.
+ @param[in,out] master_key_id master key id
+ @param[in,out] master_key master key
+ @param[in,out] version encryption information version */
+ static void get_master_key(ulint* master_key_id,
+ byte** master_key,
+ Encryption::Version* version);
+
+ /** Encrypt the page data contents. Page type can't be
+ FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED,
+ FIL_PAGE_ENCRYPTED_RTREE.
+ @param[in] type IORequest
+ @param[in,out] src page data which need to encrypt
+ @param[in] src_len Size of the source in bytes
+ @param[in,out] dst destination area
+ @param[in,out] dst_len Size of the destination in bytes
+ @return buffer data, dst_len will have the length of the data */
+ byte* encrypt(
+ const IORequest& type,
+ byte* src,
+ ulint src_len,
+ byte* dst,
+ ulint* dst_len)
+ MY_ATTRIBUTE((warn_unused_result));
+
+ /** Decrypt the page data contents. Page type must be
+ FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED,
+ FIL_PAGE_ENCRYPTED_RTREE, if not then the source contents are
+ left unchanged and DB_SUCCESS is returned.
+ @param[in] type IORequest
+ @param[in,out] src Data read from disk, decrypt
+ data will be copied to this page
+ @param[in] src_len source data length
+ @param[in,out] dst Scratch area to use for decrypt
+ @param[in] dst_len Size of the scratch area in bytes
+ @return DB_SUCCESS or error code */
+ dberr_t decrypt(
+ const IORequest& type,
+ byte* src,
+ ulint src_len,
+ byte* dst,
+ ulint dst_len)
+ MY_ATTRIBUTE((warn_unused_result));
+
+ /** Encrypt type */
+ Type m_type;
+
+ /** Encrypt key */
+ byte* m_key;
+
+ /** Encrypt key length*/
+ ulint m_klen;
+
+ /** Encrypt initial vector */
+ byte* m_iv;
+
+ /** Current master key id */
+ static ulint master_key_id;
+
+ /** Current uuid of server instance */
+ static char uuid[ENCRYPTION_SERVER_UUID_LEN + 1];
+};
+
/** Types for AIO operations @{ */
/** No transformations during read/write, write as is. */
@@ -379,42 +584,42 @@ public:
/** @return true if ignore missing flag is set */
static bool ignore_missing(ulint type)
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return((type & IGNORE_MISSING) == IGNORE_MISSING);
}
/** @return true if it is a read request */
bool is_read() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return((m_type & READ) == READ);
}
/** @return true if it is a write request */
bool is_write() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return((m_type & WRITE) == WRITE);
}
/** @return true if it is a redo log write */
bool is_log() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return((m_type & LOG) == LOG);
}
/** @return true if the simulated AIO thread should be woken up */
bool is_wake() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return((m_type & DO_NOT_WAKE) == 0);
}
/** @return true if partial read warning disabled */
bool is_partial_io_warning_disabled() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return((m_type & DISABLE_PARTIAL_IO_WARNINGS)
== DISABLE_PARTIAL_IO_WARNINGS);
@@ -428,21 +633,21 @@ public:
/** @return true if missing files should be ignored */
bool ignore_missing() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(ignore_missing(m_type));
}
/** @return true if punch hole should be used */
bool punch_hole() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return((m_type & PUNCH_HOLE) == PUNCH_HOLE);
}
/** @return true if the read should be validated */
bool validate() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
ut_a(is_read() ^ is_write());
@@ -471,7 +676,7 @@ public:
/** @return the block size to use for IO */
ulint block_size() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(m_block_size);
}
@@ -514,21 +719,21 @@ public:
/** Get the compression algorithm.
@return the compression algorithm */
Compression compression_algorithm() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(m_compression);
}
/** @return true if the page should be compressed */
bool is_compressed() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return(compression_algorithm().m_type != Compression::NONE);
}
/** @return true if the page read should not be transformed. */
bool is_compression_enabled() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return((m_type & NO_COMPRESSION) == 0);
}
@@ -539,6 +744,54 @@ public:
m_type |= NO_COMPRESSION;
}
+ /** Set encryption algorithm
+ @param[in] type The encryption algorithm to use */
+ void encryption_algorithm(Encryption::Type type)
+ {
+ if (type == Encryption::NONE) {
+ return;
+ }
+
+ m_encryption.m_type = type;
+ }
+
+ /** Set encryption key and iv
+ @param[in] key The encryption key to use
+ @param[in] key_len length of the encryption key
+ @param[in] iv The encryption iv to use */
+ void encryption_key(byte* key,
+ ulint key_len,
+ byte* iv)
+ {
+ m_encryption.m_key = key;
+ m_encryption.m_klen = key_len;
+ m_encryption.m_iv = iv;
+ }
+
+ /** Get the encryption algorithm.
+ @return the encryption algorithm */
+ Encryption encryption_algorithm() const
+ MY_ATTRIBUTE((warn_unused_result))
+ {
+ return(m_encryption);
+ }
+
+ /** @return true if the page should be encrypted. */
+ bool is_encrypted() const
+ MY_ATTRIBUTE((warn_unused_result))
+ {
+ return(m_encryption.m_type != Encryption::NONE);
+ }
+
+ /** Clear all encryption related flags */
+ void clear_encrypted()
+ {
+ m_encryption.m_key = NULL;
+ m_encryption.m_klen = 0;
+ m_encryption.m_iv = NULL;
+ m_encryption.m_type = Encryption::NONE;
+ }
+
/** Note that the IO is for double write recovery. */
void dblwr_recover()
{
@@ -547,7 +800,7 @@ public:
/** @return true if the request is from the dblwr recovery */
bool is_dblwr_recover() const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
return((m_type & DBLWR_RECOVER) == DBLWR_RECOVER);
}
@@ -555,6 +808,14 @@ public:
/** @return true if punch hole is supported */
static bool is_punch_hole_supported()
{
+
+ /* In this debugging mode, we act as if punch hole is supported,
+ and then skip any calls to actually punch a hole here.
+ In this way, Transparent Page Compression is still being tested. */
+ DBUG_EXECUTE_IF("ignore_punch_hole",
+ return(true);
+ );
+
#if defined(HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE) || defined(_WIN32)
return(true);
#else
@@ -571,6 +832,9 @@ private:
/** Compression algorithm */
Compression m_compression;
+
+ /** Encryption algorithm */
+ Encryption m_encryption;
};
/* @} */
@@ -626,13 +890,13 @@ enum os_file_type_t {
of this size from the thread stack; that is why this should not be made much
bigger than 4000 bytes. The maximum path length used by any storage engine
in the server must be at least this big. */
-#define OS_FILE_MAX_PATH 4000
/* MySQL 5.7 my_global.h */
#ifndef FN_REFLEN_SE
#define FN_REFLEN_SE 4000
#endif
+#define OS_FILE_MAX_PATH 4000
#if (FN_REFLEN_SE < OS_FILE_MAX_PATH)
# error "(FN_REFLEN_SE < OS_FILE_MAX_PATH)"
#endif
@@ -661,10 +925,9 @@ is null then it will create the file in the mysql server configuration
parameter (--tmpdir).
@param[in] path location for creating temporary file
@return temporary file handle, or NULL on error */
-UNIV_INTERN
FILE*
-os_file_create_tmpfile();
-
+os_file_create_tmpfile(
+ const char* path);
#endif /* !UNIV_HOTBACKUP */
/** The os_file_opendir() function opens a directory stream corresponding to the
@@ -757,7 +1020,7 @@ os_file_create_simple_no_error_handling_func(
ulint access_type,
bool read_only,
bool* success)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Tries to disable OS caching on an opened file descriptor.
@param[in] fd file descriptor to alter
@@ -796,7 +1059,7 @@ os_file_create_func(
ulint type,
bool read_only,
bool* success)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Deletes a file. The file has to be closed before calling this.
@param[in] name file path as a null-terminated string
@@ -991,7 +1254,7 @@ pfs_os_file_create_simple_func(
bool* success,
const char* src_file,
ulint src_line)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** NOTE! Please use the corresponding macro
os_file_create_simple_no_error_handling(), not directly this function!
@@ -1022,7 +1285,7 @@ pfs_os_file_create_simple_no_error_handling_func(
bool* success,
const char* src_file,
ulint src_line)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** NOTE! Please use the corresponding macro os_file_create(), not directly
this function!
@@ -1051,12 +1314,12 @@ pfs_os_file_create_func(
const char* name,
ulint create_mode,
ulint purpose,
- ulint access_type,
+ ulint type,
bool read_only,
bool* success,
const char* src_file,
ulint src_line)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** NOTE! Please use the corresponding macro os_file_close(), not directly
this function!
@@ -1266,7 +1529,7 @@ to original un-instrumented file I/O APIs */
# define os_file_create(key, name, create, purpose, type, read_only, \
success) \
os_file_create_func(name, create, purpose, type, read_only, \
- success)
+ success)
# define os_file_create_simple(key, name, create_mode, access, \
read_only, success) \
@@ -1321,7 +1584,7 @@ os_file_close_no_error_handling(os_file_t file);
os_file_size_t
os_file_get_size(
const char* filename)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Gets a file size.
@param[in] file handle to a file
@@ -1344,7 +1607,7 @@ os_file_set_size(
os_file_t file,
os_offset_t size,
bool read_only)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Truncates a file at its current position.
@param[in/out] file file to be truncated
@@ -1401,7 +1664,7 @@ os_file_read_func(
void* buf,
os_offset_t offset,
ulint n)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Rewind file to its start, read at most size - 1 bytes from it to str, and
NUL-terminate str. All errors are silently ignored. This function is
@@ -1434,7 +1697,7 @@ os_file_read_no_error_handling_func(
os_offset_t offset,
ulint n,
ulint* o)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** NOTE! Use the corresponding macro os_file_write(), not directly this
function!
@@ -1453,7 +1716,7 @@ os_file_write_func(
const void* buf,
os_offset_t offset,
ulint n)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Check the existence and type of the given file.
@param[in] path pathname of the file
@@ -1652,11 +1915,14 @@ os_file_get_status(
bool read_only);
#if !defined(UNIV_HOTBACKUP)
-/** Creates a temporary file that will be deleted on close.
+/** Creates a temporary file in the location specified by the parameter
+path. If the path is NULL then it will be created on --tmpdir location.
+This function is defined in ha_innodb.cc.
@param[in] path location for creating temporary file
@return temporary file descriptor, or < 0 on error */
int
-innobase_mysql_tmpfile();
+innobase_mysql_tmpfile(
+ const char* path);
#endif /* !UNIV_HOTBACKUP */
@@ -1689,7 +1955,7 @@ os_file_punch_hole(
os_file_t fh,
os_offset_t off,
os_offset_t len)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Check if the file system supports sparse files.
@@ -1706,7 +1972,7 @@ bool
os_is_sparse_file_supported(
const char* path,
os_file_t fh)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Decompress the page data contents. Page type must be FIL_PAGE_COMPRESSED, if
not then the source contents are left unchanged and DB_SUCCESS is returned.
@@ -1723,21 +1989,13 @@ os_file_decompress_page(
byte* src,
byte* dst,
ulint dst_len)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Normalizes a directory path for the current OS:
On Windows, we convert '/' to '\', else we convert '\' to '/'.
@param[in,out] str A null-terminated directory and file path */
void os_normalize_path(char* str);
-/** Normalizes a directory path for Windows: converts '/' to '\'.
-@param[in,out] str A null-terminated Windows directory and file path */
-#ifdef _WIN32
-#define os_normalize_path_for_win(str) os_normalize_path(str)
-#else
-#define os_normalize_path_for_win(str)
-#endif
-
/* Determine if a path is an absolute path or not.
@param[in] OS directory or file path to evaluate
@retval true if an absolute path
diff --git a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic
index ec90548dd64..74d0b2c83a8 100644
--- a/storage/innobase/include/os0file.ic
+++ b/storage/innobase/include/os0file.ic
@@ -219,6 +219,11 @@ an asynchronous i/o operation.
@param[in,out] m2 message for the AIO handler (can be used to
identify a completed AIO operation); ignored
if mode is OS_AIO_SYNC
+@param[in,out] write_size Actual write size initialized
+ after fist successfull trim
+ operation for this page and if
+ initialized we do not trim again if
+ actual page size
@param[in] src_file file name where func invoked
@param[in] src_line line where the func invoked
@return DB_SUCCESS if request was queued successfully, FALSE if fail */
@@ -235,11 +240,7 @@ pfs_os_aio_func(
bool read_only,
fil_node_t* m1,
void* m2,
- ulint* write_size,/*!< in/out: Actual write size initialized
- after fist successfull trim
- operation for this page and if
- initialized we do not trim again if
- actual page size does not decrease. */
+ ulint* write_size,
const char* src_file,
ulint src_line)
{
diff --git a/storage/innobase/include/os0thread.h b/storage/innobase/include/os0thread.h
index 32fd1c785c0..0be2fa89d06 100644
--- a/storage/innobase/include/os0thread.h
+++ b/storage/innobase/include/os0thread.h
@@ -117,14 +117,11 @@ os_thread_create_func(
os_thread_id_t* thread_id); /*!< out: id of the created
thread, or NULL */
-/*****************************************************************//**
-Exits the current thread. */
+/** Exits the current thread. */
void
-os_thread_exit(
-/*===========*/
- void* exit_value) /*!< in: exit value; in Windows this void*
- is cast as a DWORD */
+os_thread_exit()
UNIV_COLD MY_ATTRIBUTE((noreturn));
+
/*****************************************************************//**
Returns the thread identifier of current thread.
@return current thread identifier */
diff --git a/storage/innobase/include/page0cur.h b/storage/innobase/include/page0cur.h
index 58be8b0aa2e..c111717d868 100644
--- a/storage/innobase/include/page0cur.h
+++ b/storage/innobase/include/page0cur.h
@@ -159,9 +159,10 @@ page_cur_tuple_insert(
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr, /*!< in: mini-transaction handle, or NULL */
- bool use_cache = false);
+ bool use_cache = false)
/*!< in: if true, then use record cache to
hold the tuple converted record. */
+ MY_ATTRIBUTE((nonnull(1,2,3,4,5), warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
/***********************************************************//**
Inserts a record next to page cursor. Returns pointer to inserted record if
diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
index 8d1e5b17542..3bb622127fb 100644
--- a/storage/innobase/include/page0page.h
+++ b/storage/innobase/include/page0page.h
@@ -264,7 +264,7 @@ page_header_get_offs(
/*=================*/
const page_t* page, /*!< in: page */
ulint field) /*!< in: PAGE_FREE, ... */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/*************************************************************//**
Returns the pointer stored in the given header field, or NULL. */
@@ -530,7 +530,7 @@ bool
page_is_leaf(
/*=========*/
const page_t* page) /*!< in: page */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
Determine whether the page is empty.
@return true if the page is empty (PAGE_N_RECS = 0) */
@@ -539,7 +539,7 @@ bool
page_is_empty(
/*==========*/
const page_t* page) /*!< in: page */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/** Determine whether a page is an index root page.
@param[in] page page frame
@return true if the page is a root page of an index */
@@ -547,7 +547,7 @@ UNIV_INLINE
bool
page_is_root(
const page_t* page)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
Determine whether the page contains garbage.
@return true if the page contains garbage (PAGE_GARBAGE is not 0) */
@@ -556,7 +556,7 @@ bool
page_has_garbage(
/*=============*/
const page_t* page) /*!< in: page */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
Gets the pointer to the next record on the page.
@return pointer to next record */
@@ -656,7 +656,7 @@ ibool
page_rec_is_user_rec(
/*=================*/
const rec_t* rec) /*!< in: record */
- MY_ATTRIBUTE((const));
+ MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
TRUE if the record is the supremum record on a page.
@return TRUE if the supremum record */
@@ -665,7 +665,7 @@ ibool
page_rec_is_supremum(
/*=================*/
const rec_t* rec) /*!< in: record */
- MY_ATTRIBUTE((const));
+ MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
TRUE if the record is the infimum record on a page.
@@ -675,7 +675,7 @@ ibool
page_rec_is_infimum(
/*================*/
const rec_t* rec) /*!< in: record */
- MY_ATTRIBUTE((const));
+ MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
true if the record is the first user record on a page.
@@ -686,7 +686,7 @@ page_rec_is_first(
/*==============*/
const rec_t* rec, /*!< in: record */
const page_t* page) /*!< in: page */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
true if the record is the second user record on a page.
@@ -697,7 +697,7 @@ page_rec_is_second(
/*===============*/
const rec_t* rec, /*!< in: record */
const page_t* page) /*!< in: page */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
true if the record is the last user record on a page.
@@ -708,7 +708,7 @@ page_rec_is_last(
/*=============*/
const rec_t* rec, /*!< in: record */
const page_t* page) /*!< in: page */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
true if the record is the second last user record on a page.
@@ -719,7 +719,7 @@ page_rec_is_second_last(
/*====================*/
const rec_t* rec, /*!< in: record */
const page_t* page) /*!< in: page */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/***************************************************************//**
Looks for the record which owns the given record.
diff --git a/storage/innobase/include/page0types.h b/storage/innobase/include/page0types.h
index 5dabcf2e67d..fe56468c454 100644
--- a/storage/innobase/include/page0types.h
+++ b/storage/innobase/include/page0types.h
@@ -75,13 +75,14 @@ enum page_cur_mode_t {
which extend it */
/* These search mode is for search R-tree index. */
- PAGE_CUR_CONTAIN = 7,
- PAGE_CUR_INTERSECT = 8,
- PAGE_CUR_WITHIN = 9,
- PAGE_CUR_DISJOINT = 10,
- PAGE_CUR_MBR_EQUAL = 11,
- PAGE_CUR_RTREE_INSERT = 12,
- PAGE_CUR_RTREE_LOCATE = 13
+ PAGE_CUR_CONTAIN = 7,
+ PAGE_CUR_INTERSECT = 8,
+ PAGE_CUR_WITHIN = 9,
+ PAGE_CUR_DISJOINT = 10,
+ PAGE_CUR_MBR_EQUAL = 11,
+ PAGE_CUR_RTREE_INSERT = 12,
+ PAGE_CUR_RTREE_LOCATE = 13,
+ PAGE_CUR_RTREE_GET_FATHER = 14
};
diff --git a/storage/innobase/include/page0zip.h b/storage/innobase/include/page0zip.h
index 20643b60bfa..7b5df3d306b 100644
--- a/storage/innobase/include/page0zip.h
+++ b/storage/innobase/include/page0zip.h
@@ -2,7 +2,6 @@
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2016, 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
@@ -88,7 +87,7 @@ ulint
page_zip_get_size(
/*==============*/
const page_zip_des_t* page_zip) /*!< in: compressed page */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Set the size of a compressed page in bytes. */
UNIV_INLINE
@@ -113,7 +112,7 @@ page_zip_rec_needs_ext(
ulint comp,
ulint n_fields,
const page_size_t& page_size)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Determine the guaranteed free space on an empty page.
@@ -124,6 +123,15 @@ page_zip_empty_size(
ulint n_fields, /*!< in: number of columns in the index */
ulint zip_size) /*!< in: compressed page size in bytes */
MY_ATTRIBUTE((const));
+
+/** Check whether a tuple is too big for compressed table
+@param[in] index dict index object
+@param[in] entry entry for the index
+@return true if it's too big, otherwise false */
+bool
+page_zip_is_too_big(
+ const dict_index_t* index,
+ const dtuple_t* entry);
#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
@@ -243,7 +251,7 @@ page_zip_max_ins_size(
/*==================*/
const page_zip_des_t* page_zip,/*!< in: compressed page */
ibool is_clust)/*!< in: TRUE if clustered index */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Determine if enough space is available in the modification log.
@@ -257,7 +265,7 @@ page_zip_available(
ulint length, /*!< in: combined size of the record */
ulint create) /*!< in: nonzero=add the record to
the heap */
- MY_ATTRIBUTE((nonnull, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Write data to the uncompressed header portion of a page. The data must
@@ -553,26 +561,6 @@ void
page_zip_reset_stat_per_index();
/*===========================*/
-#ifndef UNIV_HOTBACKUP
-/** Check if a pointer to an uncompressed page matches a compressed page.
-When we IMPORT a tablespace the blocks and accompanying frames are allocted
-from outside the buffer pool.
-@param ptr pointer to an uncompressed page frame
-@param page_zip compressed page descriptor
-@return TRUE if ptr and page_zip refer to the same block */
-# define PAGE_ZIP_MATCH(ptr, page_zip) \
- (((page_zip)->m_external \
- && (page_align(ptr) + UNIV_PAGE_SIZE == (page_zip)->data)) \
- || buf_frame_get_page_zip(ptr) == (page_zip))
-#else /* !UNIV_HOTBACKUP */
-/** Check if a pointer to an uncompressed page matches a compressed page.
-@param ptr pointer to an uncompressed page frame
-@param page_zip compressed page descriptor
-@return TRUE if ptr and page_zip refer to the same block */
-# define PAGE_ZIP_MATCH(ptr, page_zip) \
- (page_align(ptr) + UNIV_PAGE_SIZE == (page_zip)->data)
-#endif /* !UNIV_HOTBACKUP */
-
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE UNIV_INLINE_ORIGINAL
@@ -581,20 +569,6 @@ from outside the buffer pool.
#ifndef UNIV_NONINL
# include "page0zip.ic"
#endif
-
-/** Issue a warning when the checksum that is stored in the page is valid,
-but different than the global setting innodb_checksum_algorithm.
-@param[in] current_algo current checksum algorithm
-@param[in] page_checksum page valid checksum
-@param[in] space_id tablespace id
-@param[in] page_no page number */
-void
-page_warn_strict_checksum(
- srv_checksum_algorithm_t curr_algo,
- srv_checksum_algorithm_t page_checksum,
- ulint space_id,
- ulint page_no);
-
#endif /* !UNIV_INNOCHECKSUM */
#endif /* page0zip_h */
diff --git a/storage/innobase/include/page0zip.ic b/storage/innobase/include/page0zip.ic
index cbb3660a6ae..9963fe01c82 100644
--- a/storage/innobase/include/page0zip.ic
+++ b/storage/innobase/include/page0zip.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2005, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@@ -351,7 +351,6 @@ page_zip_write_header(
{
ulint pos;
- ut_ad(PAGE_ZIP_MATCH(str, page_zip));
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h
index f52b35c1918..7e153d0c19b 100644
--- a/storage/innobase/include/pars0pars.h
+++ b/storage/innobase/include/pars0pars.h
@@ -33,6 +33,7 @@ Created 11/19/1996 Heikki Tuuri
#include "row0types.h"
#include "trx0types.h"
#include "ut0vec.h"
+#include "row0mysql.h"
/** Type of the user functions. The first argument is always InnoDB-supplied
and varies in type, while 'user_arg' is a user-supplied argument. The
@@ -418,18 +419,21 @@ que_fork_t*
pars_stored_procedure_call(
/*=======================*/
sym_node_t* sym_node); /*!< in: stored procedure name */
-/******************************************************************//**
-Completes a query graph by adding query thread and fork nodes
+/** Completes a query graph by adding query thread and fork nodes
above it and prepares the graph for running. The fork created is of
type QUE_FORK_MYSQL_INTERFACE.
+@param[in] node root node for an incomplete query
+ graph, or NULL for dummy graph
+@param[in] trx transaction handle
+@param[in] heap memory heap from which allocated
+@param[in] prebuilt row prebuilt structure
@return query thread node to run */
que_thr_t*
pars_complete_graph_for_exec(
-/*=========================*/
- que_node_t* node, /*!< in: root node for an incomplete
- query graph, or NULL for dummy graph */
- trx_t* trx, /*!< in: transaction handle */
- mem_heap_t* heap) /*!< in: memory heap from which allocated */
+ que_node_t* node,
+ trx_t* trx,
+ mem_heap_t* heap,
+ row_prebuilt_t* prebuilt)
MY_ATTRIBUTE((nonnull(2,3), warn_unused_result));
/****************************************************************//**
diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h
index 68a1115ae97..3e90e0b25e3 100644
--- a/storage/innobase/include/que0que.h
+++ b/storage/innobase/include/que0que.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -74,14 +74,16 @@ que_node_set_parent(
/*================*/
que_node_t* node, /*!< in: graph node */
que_node_t* parent);/*!< in: parent */
-/***********************************************************************//**
-Creates a query graph thread node.
+/** Creates a query graph thread node.
+@param[in] parent parent node, i.e., a fork node
+@param[in] heap memory heap where created
+@param[in] prebuilt row prebuilt structure
@return own: query thread node */
que_thr_t*
que_thr_create(
-/*===========*/
- que_fork_t* parent, /*!< in: parent node, i.e., a fork node */
- mem_heap_t* heap); /*!< in: memory heap where created */
+ que_fork_t* parent,
+ mem_heap_t* heap,
+ row_prebuilt_t* prebuilt);
/**********************************************************************//**
Frees a query graph, but not the heap where it was created. Does not free
explicit cursor declarations, they are freed in que_graph_free. */
@@ -398,6 +400,8 @@ struct que_thr_t{
ulint fk_cascade_depth; /*!< maximum cascading call depth
supported for foreign key constraint
related delete/updates */
+ row_prebuilt_t* prebuilt; /*!< prebuilt structure processed by
+ the query thread */
};
#define QUE_THR_MAGIC_N 8476583
diff --git a/storage/innobase/include/read0read.h b/storage/innobase/include/read0read.h
index 9ba6acf65aa..129341be77c 100644
--- a/storage/innobase/include/read0read.h
+++ b/storage/innobase/include/read0read.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved.
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
diff --git a/storage/innobase/include/read0types.h b/storage/innobase/include/read0types.h
index 230aac49ec0..c83c7e04f11 100644
--- a/storage/innobase/include/read0types.h
+++ b/storage/innobase/include/read0types.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -161,7 +161,7 @@ public:
bool changes_visible(
trx_id_t id,
const table_name_t& name) const
- __attribute__((warn_unused_result))
+ MY_ATTRIBUTE((warn_unused_result))
{
ut_ad(id > 0);
diff --git a/storage/innobase/include/rem0cmp.h b/storage/innobase/include/rem0cmp.h
index 4016900ff7f..a59479849a8 100644
--- a/storage/innobase/include/rem0cmp.h
+++ b/storage/innobase/include/rem0cmp.h
@@ -62,7 +62,7 @@ cmp_data_data(
ulint len1,
const byte* data2,
ulint len2)
- __attribute__((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Compare two data fields.
@param[in] dfield1 data field; must have type field set
@@ -92,7 +92,22 @@ cmp_dtuple_rec_with_gis(
const rec_t* rec,
const ulint* offsets,
page_cur_mode_t mode)
- __attribute__((nonnull));
+ MY_ATTRIBUTE((nonnull));
+
+/** Compare a GIS data tuple to a physical record in rtree non-leaf node.
+We need to check the page number field, since we don't store pk field in
+rtree non-leaf node.
+@param[in] dtuple data tuple
+@param[in] rec R-tree record
+@param[in] offsets rec_get_offsets(rec)
+@param[in] mode compare mode
+@retval negative if dtuple is less than rec */
+int
+cmp_dtuple_rec_with_gis_internal(
+ const dtuple_t* dtuple,
+ const rec_t* rec,
+ const ulint* offsets);
+
/** Compare a data tuple to a physical record.
@param[in] dtuple data tuple
@param[in] rec B-tree record
@@ -134,7 +149,7 @@ cmp_dtuple_rec_with_match_bytes(
const ulint* offsets,
ulint* matched_fields,
ulint* matched_bytes)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Compare a data tuple to a physical record.
@see cmp_dtuple_rec_with_match
@param[in] dtuple data tuple
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index 0edb73ebfee..8490e7c9c88 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -101,7 +101,7 @@ rec_get_next_ptr_const(
/*===================*/
const rec_t* rec, /*!< in: physical record */
ulint comp) /*!< in: nonzero=compact page format */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to get the pointer of the next chained record
on the same page.
@@ -112,7 +112,7 @@ rec_get_next_ptr(
/*=============*/
rec_t* rec, /*!< in: physical record */
ulint comp) /*!< in: nonzero=compact page format */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to get the offset of the
next chained record on the same page.
@@ -123,7 +123,7 @@ rec_get_next_offs(
/*==============*/
const rec_t* rec, /*!< in: physical record */
ulint comp) /*!< in: nonzero=compact page format */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to set the next record offset field
of an old-style record. */
@@ -153,7 +153,7 @@ ulint
rec_get_n_fields_old(
/*=================*/
const rec_t* rec) /*!< in: physical record */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to get the number of fields
in a record.
@@ -164,7 +164,7 @@ rec_get_n_fields(
/*=============*/
const rec_t* rec, /*!< in: physical record */
const dict_index_t* index) /*!< in: record descriptor */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Confirms the n_fields of the entry is sane with comparing the other
record in the same page specified
@@ -178,7 +178,7 @@ rec_n_fields_is_sane(
dict_index_t* index,
const rec_t* rec,
const dtuple_t* entry)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to get the number of records owned by the
@@ -189,7 +189,7 @@ ulint
rec_get_n_owned_old(
/*================*/
const rec_t* rec) /*!< in: old-style physical record */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to set the number of owned records. */
UNIV_INLINE
@@ -208,7 +208,7 @@ ulint
rec_get_n_owned_new(
/*================*/
const rec_t* rec) /*!< in: new-style physical record */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to set the number of owned records. */
UNIV_INLINE
@@ -229,7 +229,7 @@ rec_get_info_bits(
/*==============*/
const rec_t* rec, /*!< in: physical record */
ulint comp) /*!< in: nonzero=compact page format */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to set the info bits of a record. */
UNIV_INLINE
@@ -256,7 +256,7 @@ ulint
rec_get_status(
/*===========*/
const rec_t* rec) /*!< in: physical record */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to set the status bits of a new-style record. */
@@ -278,7 +278,7 @@ rec_get_info_and_status_bits(
/*=========================*/
const rec_t* rec, /*!< in: physical record */
ulint comp) /*!< in: nonzero=compact page format */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to set the info and status
bits of a record. (Only compact records have status bits.) */
@@ -299,7 +299,7 @@ rec_get_deleted_flag(
/*=================*/
const rec_t* rec, /*!< in: physical record */
ulint comp) /*!< in: nonzero=compact page format */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to set the deleted bit. */
UNIV_INLINE
@@ -327,7 +327,7 @@ ibool
rec_get_node_ptr_flag(
/*==================*/
const rec_t* rec) /*!< in: physical record */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to get the order number
of an old-style record in the heap of the index page.
@@ -337,7 +337,7 @@ ulint
rec_get_heap_no_old(
/*================*/
const rec_t* rec) /*!< in: physical record */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to set the heap number
field in an old-style record. */
@@ -357,7 +357,7 @@ ulint
rec_get_heap_no_new(
/*================*/
const rec_t* rec) /*!< in: physical record */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to set the heap number
field in a new-style record. */
@@ -377,7 +377,7 @@ ibool
rec_get_1byte_offs_flag(
/*====================*/
const rec_t* rec) /*!< in: physical record */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
The following function is used to set the 1-byte offsets flag. */
@@ -400,7 +400,7 @@ rec_1_get_field_end_info(
/*=====================*/
const rec_t* rec, /*!< in: record */
ulint n) /*!< in: field index */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Returns the offset of nth field end if the record is stored in the 2-byte
@@ -414,7 +414,7 @@ rec_2_get_field_end_info(
/*=====================*/
const rec_t* rec, /*!< in: record */
ulint n) /*!< in: field index */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Returns nonzero if the field is stored off-page.
@@ -426,7 +426,7 @@ rec_2_is_field_extern(
/*==================*/
const rec_t* rec, /*!< in: record */
ulint n) /*!< in: field index */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Determine how many of the first n columns in a compact
@@ -545,7 +545,7 @@ rec_get_nth_field_size(
/*===================*/
const rec_t* rec, /*!< in: record */
ulint n) /*!< in: index of the field */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/************************************************************//**
The following function is used to get an offset to the nth
data field in a record.
@@ -570,7 +570,7 @@ ulint
rec_offs_comp(
/*==========*/
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Determine if the offsets are for a record containing
externally stored columns.
@@ -580,7 +580,7 @@ ulint
rec_offs_any_extern(
/*================*/
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Determine if the offsets are for a record containing null BLOB pointers.
@return first field containing a null BLOB pointer, or NULL if none found */
@@ -590,7 +590,7 @@ rec_offs_any_null_extern(
/*=====================*/
const rec_t* rec, /*!< in: record */
const ulint* offsets) /*!< in: rec_get_offsets(rec) */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Returns nonzero if the extern bit is set in nth field of rec.
@return nonzero if externally stored */
@@ -600,7 +600,7 @@ rec_offs_nth_extern(
/*================*/
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: nth field */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Mark the nth field as externally stored.
@param[in] offsets array returned by rec_get_offsets()
@@ -618,7 +618,7 @@ rec_offs_nth_sql_null(
/*==================*/
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: nth field */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Gets the physical size of a field.
@return length of field */
@@ -628,7 +628,7 @@ rec_offs_nth_size(
/*==============*/
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
ulint n) /*!< in: nth field */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Returns the number of extern bits set in a record.
@@ -638,7 +638,7 @@ ulint
rec_offs_n_extern(
/*==============*/
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/***********************************************************//**
This is used to modify the value of an already existing field in a record.
The previous value must have exactly the same size as the new value. If len
@@ -670,7 +670,7 @@ ulint
rec_get_data_size_old(
/*==================*/
const rec_t* rec) /*!< in: physical record */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
The following function returns the number of allocated elements
for an array of offsets.
@@ -680,7 +680,7 @@ ulint
rec_offs_get_n_alloc(
/*=================*/
const ulint* offsets)/*!< in: array for rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
The following function sets the number of allocated elements
for an array of offsets. */
@@ -702,7 +702,7 @@ ulint
rec_offs_n_fields(
/*==============*/
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
The following function returns the data size of a physical
record, that is the sum of field lengths. SQL null fields
@@ -714,7 +714,7 @@ ulint
rec_offs_data_size(
/*===============*/
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
Returns the total size of record minus data size of record.
The value returned by the function is the distance from record
@@ -725,7 +725,7 @@ ulint
rec_offs_extra_size(
/*================*/
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
Returns the total size of a physical record.
@return size */
@@ -734,7 +734,7 @@ ulint
rec_offs_size(
/*==========*/
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#ifdef UNIV_DEBUG
/**********************************************************//**
Returns a pointer to the start of the record.
@@ -745,7 +745,7 @@ rec_get_start(
/*==========*/
const rec_t* rec, /*!< in: pointer to record */
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
Returns a pointer to the end of the record.
@return pointer to end */
@@ -755,7 +755,7 @@ rec_get_end(
/*========*/
const rec_t* rec, /*!< in: pointer to record */
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#else /* UNIV_DEBUG */
# define rec_get_start(rec, offsets) ((rec) - rec_offs_extra_size(offsets))
# define rec_get_end(rec, offsets) ((rec) + rec_offs_data_size(offsets))
@@ -786,7 +786,7 @@ rec_get_converted_size_temp(
const dtuple_t* v_entry,/*!< in: dtuple contains virtual column
data */
ulint* extra) /*!< out: extra size */
- MY_ATTRIBUTE((warn_unused_result, nonnull(1)));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Determine the offset to each field in temporary file.
@@ -845,7 +845,7 @@ rec_fold(
ulint n_fields,
ulint n_bytes,
index_id_t tree_id)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
/*********************************************************//**
Builds a physical record out of a data tuple and
@@ -860,7 +860,7 @@ rec_convert_dtuple_to_rec(
const dtuple_t* dtuple, /*!< in: data tuple */
ulint n_ext) /*!< in: number of
externally stored columns */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************//**
Returns the extra size of an old-style physical record if we know its
data size and number of fields.
@@ -898,7 +898,7 @@ rec_get_converted_size_comp(
const dfield_t* fields, /*!< in: array of data fields */
ulint n_fields,/*!< in: number of data fields */
ulint* extra) /*!< out: extra size */
- MY_ATTRIBUTE((nonnull(1)));
+ MY_ATTRIBUTE((nonnull(1,3)));
/**********************************************************//**
The following function returns the size of a data tuple when converted to
a physical record.
@@ -962,7 +962,7 @@ rec_print_mbr_rec(
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- __attribute__((nonnull));
+ MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Prints a physical record. */
void
@@ -1124,6 +1124,7 @@ int wsrep_rec_get_foreign_key(
dict_index_t* index_ref, /* in: index for referenced table */
ibool new_protocol); /* in: protocol > 1 */
#endif /* WITH_WSREP */
+
#ifndef UNIV_NONINL
#include "rem0rec.ic"
#endif
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
index 4d2cbcb4944..b855a39da9e 100644
--- a/storage/innobase/include/rem0rec.ic
+++ b/storage/innobase/include/rem0rec.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
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
diff --git a/storage/innobase/include/row0ftsort.h b/storage/innobase/include/row0ftsort.h
index c06327c243e..7e39fe33d9f 100644
--- a/storage/innobase/include/row0ftsort.h
+++ b/storage/innobase/include/row0ftsort.h
@@ -94,7 +94,7 @@ struct fts_psort_t {
ulint state; /*!< parent thread state */
fts_doc_list_t fts_doc_list; /*!< doc list to process */
fts_psort_common_t* psort_common; /*!< ptr to all psort info */
- os_thread_id_t thread_hdl; /*!< thread handler */
+ os_thread_t thread_hdl; /*!< thread handler */
dberr_t error; /*!< db error during psort */
ulint memory_used; /*!< memory used by fts_doc_list */
ib_mutex_t mutex; /*!< mutex for fts_doc_list */
diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h
index 48a3044f1d6..4038c32b9c0 100644
--- a/storage/innobase/include/row0ins.h
+++ b/storage/innobase/include/row0ins.h
@@ -97,7 +97,7 @@ row_ins_clust_index_entry_low(
bool dup_chk_only)
/*!< in: if true, just do duplicate check
and return. don't execute actual insert. */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/***************************************************************//**
Tries to insert an entry into a secondary index. If a record with exactly the
@@ -125,7 +125,7 @@ row_ins_sec_index_entry_low(
bool dup_chk_only)
/*!< in: if true, just do duplicate check
and return. don't execute actual insert. */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Sets the values of the dtuple fields in entry from the values of appropriate
columns in row.
@param[in] index index handler
@@ -178,7 +178,7 @@ row_ins_clust_index_entry(
bool dup_chk_only)
/*!< in: if true, just do duplicate check
and return. don't execute actual insert. */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/***************************************************************//**
Inserts an entry into a secondary index. Tries first optimistic,
then pessimistic descent down the tree. If the entry matches enough
@@ -194,7 +194,7 @@ row_ins_sec_index_entry(
bool dup_chk_only)
/*!< in: if true, just do duplicate check
and return. don't execute actual insert. */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/***********************************************************//**
Inserts a row to a table. This is a high-level function used in
SQL execution graphs.
diff --git a/storage/innobase/include/row0log.h b/storage/innobase/include/row0log.h
index 80571eb3b3d..c8db44f23b3 100644
--- a/storage/innobase/include/row0log.h
+++ b/storage/innobase/include/row0log.h
@@ -56,8 +56,9 @@ row_log_allocate(
const dtuple_t* add_cols,
/*!< in: default values of
added columns, or NULL */
- const ulint* col_map)/*!< in: mapping of old column
+ const ulint* col_map,/*!< in: mapping of old column
numbers to new ones, or NULL if !table */
+ const char* path) /*!< in: where to create temporary file */
MY_ATTRIBUTE((nonnull(1), warn_unused_result));
/******************************************************//**
@@ -112,6 +113,16 @@ row_log_table_get_error(
that is being rebuilt online */
MY_ATTRIBUTE((nonnull, warn_unused_result));
+/** Check whether a virtual column is indexed in the new table being
+created during alter table
+@param[in] index cluster index
+@param[in] v_no virtual column number
+@return true if it is indexed, else false */
+bool
+row_log_col_is_indexed(
+ const dict_index_t* index,
+ ulint v_no);
+
/******************************************************//**
Logs a delete operation to a table that is being rebuilt.
This will be merged in row_log_table_apply_delete(). */
@@ -208,7 +219,7 @@ row_log_table_apply(
dict_table_t* old_table,
struct TABLE* table,
ut_stage_alter_t* stage)
-__attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************//**
Get the latest transaction ID that has invoked row_log_online_op()
@@ -235,7 +246,7 @@ row_log_apply(
dict_index_t* index,
struct TABLE* table,
ut_stage_alter_t* stage)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#ifdef HAVE_PSI_STAGE_INTERFACE
/** Estimate how much work is to be done by the log apply phase
diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h
index 4493df5e0bd..f3b5860910c 100644
--- a/storage/innobase/include/row0merge.h
+++ b/storage/innobase/include/row0merge.h
@@ -152,6 +152,7 @@ row_merge_dup_report(
row_merge_dup_t* dup, /*!< in/out: for reporting duplicates */
const dfield_t* entry) /*!< in: duplicate index entry */
MY_ATTRIBUTE((nonnull));
+
/*********************************************************************//**
Sets an exclusive lock on a table, for the duration of creating indexes.
@return error code or DB_SUCCESS */
@@ -161,7 +162,8 @@ row_merge_lock_table(
trx_t* trx, /*!< in/out: transaction */
dict_table_t* table, /*!< in: table to lock */
enum lock_mode mode) /*!< in: LOCK_X or LOCK_S */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((nonnull(1,2), warn_unused_result));
+
/*********************************************************************//**
Drop indexes that were created before an error occurred.
The data dictionary must have been locked exclusively by the caller,
@@ -172,6 +174,7 @@ row_merge_drop_indexes_dict(
trx_t* trx, /*!< in/out: dictionary transaction */
table_id_t table_id)/*!< in: table identifier */
MY_ATTRIBUTE((nonnull));
+
/*********************************************************************//**
Drop those indexes which were created before an error occurred.
The data dictionary must have been locked exclusively by the caller,
@@ -184,6 +187,7 @@ row_merge_drop_indexes(
ibool locked) /*!< in: TRUE=table locked,
FALSE=may need to do a lazy drop */
MY_ATTRIBUTE((nonnull));
+
/*********************************************************************//**
Drop all partially created indexes during crash recovery. */
void
@@ -195,7 +199,8 @@ UNIV_PFS_IO defined, register the file descriptor with Performance Schema.
@param[in] path location for creating temporary merge files.
@return File descriptor */
int
-row_merge_file_create_low(void)
+row_merge_file_create_low(
+ const char* path)
MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Destroy a merge file. And de-register the file from Performance Schema
@@ -214,7 +219,9 @@ char*
row_make_new_pathname(
/*==================*/
dict_table_t* table, /*!< in: table to be renamed */
- const char* new_name); /*!< in: new name */
+ const char* new_name) /*!< in: new name */
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
+
/*********************************************************************//**
Rename the tables in the data dictionary. The data dictionary must
have been locked exclusively by the caller, because the transaction
@@ -242,7 +249,8 @@ row_merge_rename_index_to_add(
trx_t* trx, /*!< in/out: transaction */
table_id_t table_id, /*!< in: table identifier */
index_id_t index_id) /*!< in: index identifier */
- MY_ATTRIBUTE((nonnull));
+ MY_ATTRIBUTE((nonnull(1), warn_unused_result));
+
/*********************************************************************//**
Rename an index in the dictionary that is to be dropped. The data
dictionary must have been locked exclusively by the caller, because
@@ -254,7 +262,8 @@ row_merge_rename_index_to_drop(
trx_t* trx, /*!< in/out: transaction */
table_id_t table_id, /*!< in: table identifier */
index_id_t index_id) /*!< in: index identifier */
- MY_ATTRIBUTE((nonnull));
+ MY_ATTRIBUTE((nonnull(1), warn_unused_result));
+
/** Create the index and load in to the dictionary.
@param[in,out] trx trx (sets error_state)
@param[in,out] table the index is on this table
@@ -270,7 +279,9 @@ row_merge_create_index(
dict_table_t* table,
const index_def_t* index_def,
const dict_add_v_col_t* add_v,
- const char** col_names);
+ const char** col_names)
+ MY_ATTRIBUTE((warn_unused_result));
+
/*********************************************************************//**
Check if a transaction can use an index.
@return TRUE if index can be used by the transaction else FALSE */
@@ -278,7 +289,9 @@ ibool
row_merge_is_index_usable(
/*======================*/
const trx_t* trx, /*!< in: transaction */
- const dict_index_t* index); /*!< in: index to check */
+ const dict_index_t* index) /*!< in: index to check */
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
+
/*********************************************************************//**
Drop a table. The caller must have ensured that the background stats
thread is not processing the table. This can be done by calling
@@ -290,7 +303,7 @@ row_merge_drop_table(
/*=================*/
trx_t* trx, /*!< in: transaction */
dict_table_t* table) /*!< in: table instance to drop */
- MY_ATTRIBUTE((nonnull));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Build indexes on a table by reading a clustered index, creating a temporary
file containing index entries, merge sorting these index entries and inserting
@@ -317,6 +330,8 @@ existing order
ALTER TABLE. stage->begin_phase_read_pk() will be called at the beginning of
this function and it will be passed to other functions for further accounting.
@param[in] add_v new virtual columns added along with indexes
+@param[in] eval_table mysql table used to evaluate virtual column
+ value, see innobase_get_computed_value().
@return DB_SUCCESS or error code */
dberr_t
row_merge_build_indexes(
@@ -334,8 +349,9 @@ row_merge_build_indexes(
ib_sequence_t& sequence,
bool skip_pk_sort,
ut_stage_alter_t* stage,
- const dict_add_v_col_t* add_v)
-__attribute__((warn_unused_result));
+ const dict_add_v_col_t* add_v,
+ struct TABLE* eval_table)
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Write a buffer to a block. */
@@ -346,6 +362,7 @@ row_merge_buf_write(
const merge_file_t* of, /*!< in: output file */
row_merge_block_t* block) /*!< out: buffer for writing to file */
MY_ATTRIBUTE((nonnull));
+
/********************************************************************//**
Sort a buffer. */
void
@@ -355,6 +372,7 @@ row_merge_buf_sort(
row_merge_dup_t* dup) /*!< in/out: reporter of duplicates
(NULL if non-unique index) */
MY_ATTRIBUTE((nonnull(1)));
+
/********************************************************************//**
Write a merge block to the file system.
@return TRUE if request was successful, FALSE if fail */
@@ -367,7 +385,8 @@ row_merge_write(
const void* buf, /*!< in: data */
fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
void* crypt_buf, /*!< in: crypt buf or NULL */
- ulint space); /*!< in: space id */
+ ulint space) /*!< in: space id */
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Empty a sort buffer.
@@ -384,7 +403,9 @@ row_merge_buf_empty(
@return file descriptor, or -1 on failure */
int
row_merge_file_create(
- merge_file_t* merge_file);
+ merge_file_t* merge_file,
+ const char* path)
+ MY_ATTRIBUTE((warn_unused_result, nonnull));
/** Merge disk files.
@param[in] trx transaction
@@ -392,6 +413,12 @@ row_merge_file_create(
@param[in,out] file file containing index entries
@param[in,out] block 3 buffers
@param[in,out] tmpfd temporary file handle
+@param[in] update_progress true, if we should update progress status
+@param[in] pct_progress total progress percent until now
+@param[in] pct_ocst current progress percent
+@param[in] crypt_data tale crypt data
+@param[in] crypt_block crypt buf or NULL
+@param[in] space space_id
@param[in,out] stage performance schema accounting object, used by
ALTER TABLE. If not NULL, stage->begin_phase_sort() will be called initially
and then stage->inc() will be called for each record processed.
@@ -399,21 +426,20 @@ and then stage->inc() will be called for each record processed.
dberr_t
row_merge_sort(
/*===========*/
- trx_t* trx, /*!< in: transaction */
- const row_merge_dup_t* dup, /*!< in: descriptor of
- index being created */
- merge_file_t* file, /*!< in/out: file containing
- index entries */
- row_merge_block_t* block, /*!< in/out: 3 buffers */
- int* tmpfd, /*!< in/out: temporary file handle */
- const bool update_progress, /*!< in: update progress status variable or not */
- const float pct_progress, /*!< in: total progress percent until now */
- const float pct_cost, /*!< in: current progress percent */
- fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
- row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
- ulint space, /*!< in: space id */
+ trx_t* trx,
+ const row_merge_dup_t* dup,
+ merge_file_t* file,
+ row_merge_block_t* block,
+ int* tmpfd,
+ const bool update_progress,
+ const float pct_progress,
+ const float pct_cost,
+ fil_space_crypt_t* crypt_data,
+ row_merge_block_t* crypt_block,
+ ulint space,
ut_stage_alter_t* stage = NULL)
- __attribute__((nonnull(1,2,3,4,5)));
+ MY_ATTRIBUTE((warn_unused_result));
+
/*********************************************************************//**
Allocate a sort buffer.
@return own: sort buffer */
@@ -422,6 +448,7 @@ row_merge_buf_create(
/*=================*/
dict_index_t* index) /*!< in: secondary index */
MY_ATTRIBUTE((warn_unused_result, nonnull, malloc));
+
/*********************************************************************//**
Deallocate a sort buffer. */
void
@@ -429,6 +456,7 @@ row_merge_buf_free(
/*===============*/
row_merge_buf_t* buf) /*!< in,own: sort buffer to be freed */
MY_ATTRIBUTE((nonnull));
+
/*********************************************************************//**
Destroy a merge file. */
void
@@ -436,6 +464,7 @@ row_merge_file_destroy(
/*===================*/
merge_file_t* merge_file) /*!< in/out: merge file structure */
MY_ATTRIBUTE((nonnull));
+
/********************************************************************//**
Read a merge block from the file system.
@return TRUE if request was successful, FALSE if fail */
@@ -449,7 +478,8 @@ row_merge_read(
row_merge_block_t* buf, /*!< out: data */
fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_buf, /*!< in: crypt buf or NULL */
- ulint space); /*!< in: space id */
+ ulint space) /*!< in: space id */
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Read a merge record.
@@ -470,5 +500,5 @@ row_merge_read_rec(
fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
ulint space) /*!< in: space id */
- __attribute__((nonnull(1,2,3,4,6,7,8), warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#endif /* row0merge.h */
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index 5b195734be9..2d508c1a7df 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -130,7 +130,7 @@ row_mysql_read_geometry(
MySQL format */
ulint col_len) /*!< in: BLOB reference length
(not BLOB length) */
- __attribute__((nonnull(1,2), warn_unused_result));
+ MY_ATTRIBUTE((nonnull(1,2), warn_unused_result));
/**************************************************************//**
Pad a column with spaces. */
void
@@ -229,6 +229,7 @@ row_lock_table_autoinc_for_mysql(
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in the MySQL
table handle */
MY_ATTRIBUTE((nonnull, warn_unused_result));
+
/*********************************************************************//**
Sets a table lock on the table mentioned in prebuilt.
@return error code or DB_SUCCESS */
@@ -253,7 +254,7 @@ dberr_t
row_insert_for_mysql(
const byte* mysql_rec,
row_prebuilt_t* prebuilt)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Builds a dummy query graph used in selects. */
@@ -289,7 +290,7 @@ dberr_t
row_update_for_mysql(
const byte* mysql_rec,
row_prebuilt_t* prebuilt)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Delete all rows for the given table by freeing/truncating indexes.
@param[in,out] table table handler
@@ -297,7 +298,7 @@ row_update_for_mysql(
dberr_t
row_delete_all_rows(
dict_table_t* table)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
@@ -381,13 +382,14 @@ row_create_table_for_mysql(
dict_table_t* table, /*!< in, own: table definition
(will be freed, or on DB_SUCCESS
added to the data dictionary cache) */
- const char* compression,
- /*!< in: compression algorithm to use,
- can be NULL */
+ const char* compression,
+ /*!< in: compression algorithm to use,
+ can be NULL */
trx_t* trx, /*!< in/out: transaction */
bool commit, /*!< in: if true, commit the transaction */
fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id);/*!< in: encryption key_id */
+ ulint key_id) /*!< in: encryption key_id */
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Does an index creation operation for MySQL. TODO: currently failure
@@ -407,7 +409,7 @@ row_create_index_for_mysql(
then checked for not being too
large. */
dict_table_t* handler) /* ! in/out: table handler. */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
@@ -438,7 +440,7 @@ row_table_add_foreign_constraints(
size_t sql_length,
const char* name,
ibool reject_fks)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
The master thread in srv0srv.cc calls this regularly to drop tables which
@@ -489,8 +491,8 @@ row_drop_table_for_mysql(
trx_t* trx, /*!< in: dictionary transaction handle */
bool drop_db,/*!< in: true=dropping whole database */
ibool create_failed,/*!<in: TRUE=create table failed
- because e.g. foreign key column
- type mismatch. */
+ because e.g. foreign key column
+ type mismatch. */
bool nonatomic = true,
/*!< in: whether it is permitted
to release and reacquire dict_operation_lock */
@@ -557,7 +559,7 @@ row_rename_partitions_for_mysql(
const char* old_name,
const char* new_name,
trx_t* trx)
- __attribute__((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
Scans an index for either COOUNT(*) or CHECK TABLE.
@@ -576,7 +578,7 @@ row_scan_index_for_mysql(
false=count the rows only */
ulint* n_rows) /*!< out: number of entries
seen in the consistent read */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Initialize this module */
void
@@ -910,6 +912,14 @@ struct row_prebuilt_t {
/** Disable prefetch. */
bool m_no_prefetch;
+ /** Return materialized key for secondary index scan */
+ bool m_read_virtual_key;
+
+ /** The MySQL table object */
+ TABLE* m_mysql_table;
+
+ /** limit value to avoid fts result overflow */
+ ulonglong m_fts_limit;
};
/** Callback for row_mysql_sys_index_iterate() */
@@ -926,22 +936,42 @@ struct SysIndexCallback {
@param[in,out] row the data row
@param[in] col virtual column
@param[in] index index on the virtual column
-@param[in,out] my_rec MySQL record to store the rows
@param[in,out] local_heap heap memory for processing large data etc.
@param[in,out] heap memory heap that copies the actual index row
@param[in] ifield index field
-@param[in] in_purge whether this is called by purge
+@param[in] thd MySQL thread handle
+@param[in,out] mysql_table mysql table object
+@param[in] old_table during ALTER TABLE, this is the old table
+ or NULL.
+@param[in] parent_update update vector for the parent row
+@param[in] foreign foreign key information
@return the field filled with computed value */
dfield_t*
innobase_get_computed_value(
const dtuple_t* row,
const dict_v_col_t* col,
const dict_index_t* index,
- byte* my_rec,
mem_heap_t** local_heap,
mem_heap_t* heap,
const dict_field_t* ifield,
- bool in_purge);
+ THD* thd,
+ TABLE* mysql_table,
+ const dict_table_t* old_table,
+ upd_t* parent_update,
+ dict_foreign_t* foreign);
+
+/** Get the computed value by supplying the base column values.
+@param[in,out] table the table whose virtual column template to be built */
+void
+innobase_init_vc_templ(
+ dict_table_t* table);
+
+/** Change dbname and table name in table->vc_templ.
+@param[in,out] table the table whose virtual column template
+dbname and tbname to be renamed. */
+void
+innobase_rename_vc_templ(
+ dict_table_t* table);
#define ROW_PREBUILT_FETCH_MAGIC_N 465765687
@@ -964,4 +994,10 @@ innobase_get_computed_value(
#include "row0mysql.ic"
#endif
+#ifdef UNIV_DEBUG
+/** Wait for the background drop list to become empty. */
+void
+row_wait_for_background_drop_list_empty();
+#endif /* UNIV_DEBUG */
+
#endif /* row0mysql.h */
diff --git a/storage/innobase/include/row0purge.h b/storage/innobase/include/row0purge.h
index f640dfaf62f..32a989833bc 100644
--- a/storage/innobase/include/row0purge.h
+++ b/storage/innobase/include/row0purge.h
@@ -44,7 +44,7 @@ purge_node_t*
row_purge_node_create(
que_thr_t* parent,
mem_heap_t* heap)
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/***********************************************************//**
Determines if it is possible to remove a secondary index entry.
diff --git a/storage/innobase/include/row0row.h b/storage/innobase/include/row0row.h
index 4fd93283884..93ff90d020e 100644
--- a/storage/innobase/include/row0row.h
+++ b/storage/innobase/include/row0row.h
@@ -159,9 +159,9 @@ row_build(
row_ext_t** ext, /*!< out, own: cache of
externally stored column
prefixes, or NULL */
- mem_heap_t* heap) /*!< in: memory heap from which
+ mem_heap_t* heap); /*!< in: memory heap from which
the memory needed is allocated */
- MY_ATTRIBUTE((nonnull(2,3,9)));
+
/** An inverse function to row_build_index_entry. Builds a row from a
record in a clustered index, with possible indexing on ongoing
addition of new virtual columns.
@@ -212,7 +212,7 @@ row_rec_to_index_entry_low(
stored columns */
mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************************//**
Converts an index record to a typed data tuple. NOTE that externally
stored (often big) fields are NOT copied to heap.
@@ -227,7 +227,7 @@ row_rec_to_index_entry(
stored columns */
mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record.
@@ -249,7 +249,7 @@ row_build_row_ref(
as long as the row reference is used! */
mem_heap_t* heap) /*!< in: memory heap from which the memory
needed is allocated */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record. */
diff --git a/storage/innobase/include/row0sel.h b/storage/innobase/include/row0sel.h
index 1d308320b6f..3e6863208af 100644
--- a/storage/innobase/include/row0sel.h
+++ b/storage/innobase/include/row0sel.h
@@ -174,7 +174,7 @@ row_search_for_mysql(
row_prebuilt_t* prebuilt,
ulint match_mode,
ulint direction)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Searches for rows in the database using cursor.
function is meant for temporary table that are not shared accross connection
@@ -201,7 +201,7 @@ row_search_no_mvcc(
row_prebuilt_t* prebuilt,
ulint match_mode,
ulint direction)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/** Searches for rows in the database using cursor.
Function is mainly used for tables that are shared accorss connection and
@@ -238,7 +238,7 @@ row_search_mvcc(
row_prebuilt_t* prebuilt,
ulint match_mode,
ulint direction)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/********************************************************************//**
Count rows in a R-Tree leaf level.
@@ -253,10 +253,9 @@ row_count_rtree_recs(
position the cursor at the start or
the end of the index, depending on
'mode' */
- ulint* n_rows) /*!< out: number of entries
+ ulint* n_rows); /*!< out: number of entries
seen in the consistent read */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
/*******************************************************************//**
Checks if MySQL at the moment is allowed for this table to retrieve a
consistent read result, or store it to the query cache.
diff --git a/storage/innobase/include/row0umod.h b/storage/innobase/include/row0umod.h
index 11430952036..a1bb42035a9 100644
--- a/storage/innobase/include/row0umod.h
+++ b/storage/innobase/include/row0umod.h
@@ -42,7 +42,7 @@ row_undo_mod(
/*=========*/
undo_node_t* node, /*!< in: row undo node */
que_thr_t* thr) /*!< in: query thread */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#ifndef UNIV_NONINL
#include "row0umod.ic"
diff --git a/storage/innobase/include/row0undo.h b/storage/innobase/include/row0undo.h
index 1f700e441c7..3d5b3574afa 100644
--- a/storage/innobase/include/row0undo.h
+++ b/storage/innobase/include/row0undo.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -56,7 +56,7 @@ bool
row_undo_search_clust_to_pcur(
/*==========================*/
undo_node_t* node) /*!< in/out: row undo node */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/***********************************************************//**
Undoes a row operation in a table. This is a high-level function used
in SQL execution graphs.
diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h
index 84a10c0f4c9..3c1033fe419 100644
--- a/storage/innobase/include/row0upd.h
+++ b/storage/innobase/include/row0upd.h
@@ -112,8 +112,8 @@ upd_get_field_by_field_no(
/*======================*/
const upd_t* update, /*!< in: update vector */
ulint no, /*!< in: field_no */
- bool is_virtual) /*!< in: if it is a virtual column */
- MY_ATTRIBUTE((warn_unused_result, nonnull, pure));
+ bool is_virtual) /*!< in: if it is a virtual column */
+ MY_ATTRIBUTE((warn_unused_result));
/*********************************************************************//**
Writes into the redo log the values of trx id and roll ptr and enough info
to determine their positions within a clustered index record.
@@ -222,24 +222,32 @@ row_upd_build_sec_rec_difference_binary(
const dtuple_t* entry, /*!< in: entry to insert */
mem_heap_t* heap) /*!< in: memory heap from which allocated */
MY_ATTRIBUTE((warn_unused_result, nonnull));
-/***************************************************************//**
-Builds an update vector from those fields, excluding the roll ptr and
+/** Builds an update vector from those fields, excluding the roll ptr and
trx id fields, which in an index entry differ from a record that has
the equal ordering fields. NOTE: we compare the fields as binary strings!
+@param[in] index clustered index
+@param[in] entry clustered index entry to insert
+@param[in] rec clustered index record
+@param[in] offsets rec_get_offsets(rec,index), or NULL
+@param[in] no_sys skip the system columns
+ DB_TRX_ID and DB_ROLL_PTR
+@param[in] trx transaction (for diagnostics),
+ or NULL
+@param[in] heap memory heap from which allocated
+@param[in,out] mysql_table NULL, or mysql table object when
+ user thread invokes dml
@return own: update vector of differing fields, excluding roll ptr and
trx id */
upd_t*
row_upd_build_difference_binary(
-/*============================*/
- dict_index_t* index, /*!< in: clustered index */
- const dtuple_t* entry, /*!< in: entry to insert */
- const rec_t* rec, /*!< in: clustered index record */
- const ulint* offsets,/*!< in: rec_get_offsets(rec,index), or NULL */
- bool no_sys, /*!< in: skip the system columns
- DB_TRX_ID and DB_ROLL_PTR */
- trx_t* trx, /*!< in: transaction (for diagnostics),
- or NULL */
- mem_heap_t* heap) /*!< in: memory heap from which allocated */
+ dict_index_t* index,
+ const dtuple_t* entry,
+ const rec_t* rec,
+ const ulint* offsets,
+ bool no_sys,
+ trx_t* trx,
+ mem_heap_t* heap,
+ TABLE* mysql_table)
MY_ATTRIBUTE((nonnull(1,2,3,7), warn_unused_result));
/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
@@ -377,12 +385,16 @@ row_upd_changes_some_index_ord_field_binary(
/*========================================*/
const dict_table_t* table, /*!< in: table */
const upd_t* update);/*!< in: update vector for the row */
-/***********************************************************//**
-Stores to the heap the row on which the node->pcur is positioned. */
+/** Stores to the heap the row on which the node->pcur is positioned.
+@param[in] node row update node
+@param[in] thd mysql thread handle
+@param[in,out] mysql_table NULL, or mysql table object when
+ user thread invokes dml */
void
row_upd_store_row(
-/*==============*/
- upd_node_t* node); /*!< in: row update node */
+ upd_node_t* node,
+ THD* thd,
+ TABLE* mysql_table);
/***********************************************************//**
Updates a row in a table. This is a high-level function used
in SQL execution graphs.
@@ -434,7 +446,9 @@ struct upd_field_t{
the clustered index, but in updating
a secondary index record in btr0cur.cc
this is the position in the secondary
- index */
+ index. If this field is a virtual
+ column, then field_no represents
+ the nth virtual column in the table */
#ifndef UNIV_HOTBACKUP
unsigned orig_len:16; /*!< original length of the locally
stored part of an externally stored
@@ -515,11 +529,6 @@ struct upd_node_t{
ibool in_mysql_interface;
/* TRUE if the update node was created
for the MySQL interface */
- upd_node_t* cascade_node;/* NULL or an update node template which
- is used to implement ON DELETE/UPDATE CASCADE
- or ... SET NULL for foreign keys */
- mem_heap_t* cascade_heap;/* NULL or a mem heap where the cascade
- node is created */
dict_foreign_t* foreign;/* NULL or pointer to a foreign key
constraint if this update node is used in
doing an ON DELETE or ON UPDATE operation */
@@ -550,6 +559,11 @@ struct upd_node_t{
cascade nodes are stored here, so that memory
can be freed. */
+ mem_heap_t* cascade_heap;
+ /*!< NULL or a mem heap where cascade_upd_nodes
+ are created. This heap is owned by the node
+ that has cascade_top=true. */
+
sel_node_t* select; /*!< query graph subtree implementing a base
table cursor: the rows returned will be
updated */
diff --git a/storage/innobase/include/row0vers.h b/storage/innobase/include/row0vers.h
index cd476acb6a1..489db305fac 100644
--- a/storage/innobase/include/row0vers.h
+++ b/storage/innobase/include/row0vers.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -118,8 +118,7 @@ row_vers_build_for_consistent_read(
if the history is missing or the record
does not exist in the view, that is,
it was freshly inserted afterwards */
- const dtuple_t**vrow) /*!< out: reports virtual column info if any */
- MY_ATTRIBUTE((nonnull(1,2,3,4,5,6,7)));
+ const dtuple_t**vrow); /*!< out: reports virtual column info if any */
/*****************************************************************//**
Constructs the last committed version of a clustered index record,
@@ -144,9 +143,9 @@ row_vers_build_for_semi_consistent_read(
const rec_t** old_vers,/*!< out: rec, old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
- const dtuple_t**vrow) /*!< out: holds virtual column info if any
+ const dtuple_t**vrow); /*!< out: holds virtual column info if any
is updated in the view */
- MY_ATTRIBUTE((nonnull(1,2,3,4,5)));
+
#ifndef UNIV_NONINL
#include "row0vers.ic"
diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h
index 2dee270df4c..14c1d62c127 100644
--- a/storage/innobase/include/srv0mon.h
+++ b/storage/innobase/include/srv0mon.h
@@ -107,8 +107,14 @@ enum monitor_type_t {
/** Counter minimum value is initialized to be max value of
mon_type_t (int64_t) */
-#define MIN_RESERVED INT_MAX64
-#define MAX_RESERVED (~MIN_RESERVED)
+#ifndef INT64_MAX
+#define INT64_MAX (9223372036854775807LL)
+#endif
+#ifndef INT64_MIN
+#define INT64_MIN (-9223372036854775807LL-1)
+#endif
+#define MIN_RESERVED INT64_MAX
+#define MAX_RESERVED INT64_MIN
/** This enumeration defines internal monitor identifier used internally
to identify each particular counter. Its value indexes into two arrays,
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 2c46f7ce3ae..be6461edec1 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -58,6 +58,8 @@ Created 10/10/1995 Heikki Tuuri
#include "ut0counter.h"
#include "fil0fil.h"
+struct fil_space_t;
+
/* Global counters used inside InnoDB. */
struct srv_stats_t {
typedef ib_counter_t<ulint, 64> ulint_ctr_64_t;
@@ -297,8 +299,8 @@ extern my_bool srv_use_atomic_writes;
extern ulong innodb_compression_algorithm;
/* Number of flush threads */
-#define MTFLUSH_MAX_WORKER 64
-#define MTFLUSH_DEFAULT_WORKER 8
+#define MTFLUSH_MAX_WORKER 64
+#define MTFLUSH_DEFAULT_WORKER 8
/* Number of threads used for multi-threaded flush */
extern long srv_mtflush_threads;
@@ -372,6 +374,7 @@ extern my_bool srv_flush_sync;
/* When this event is reset we do not allow any file writes to take place. */
extern os_event_t srv_allow_writes_event;
#endif /* WITH_INNODB_DISALLOW_WRITES */
+
/* If this flag is TRUE, then we will load the indexes' (and tables') metadata
even if they are marked as "corrupted". Mostly it is for DBA to process
corrupted index and table */
@@ -414,6 +417,7 @@ extern my_bool srv_random_read_ahead;
extern ulong srv_read_ahead_threshold;
extern ulint srv_n_read_io_threads;
extern ulint srv_n_write_io_threads;
+
/* Defragmentation, Origianlly facebook default value is 100, but it's too high */
#define SRV_DEFRAGMENT_FREQUENCY_DEFAULT 40
extern my_bool srv_defragment;
@@ -481,6 +485,7 @@ extern my_bool srv_stats_sample_traditional;
extern ibool srv_use_doublewrite_buf;
extern ulong srv_doublewrite_batch_size;
+extern ulong srv_checksum_algorithm;
extern double srv_max_buf_pool_modified_pct;
extern my_bool srv_force_primary_key;
@@ -529,6 +534,9 @@ extern my_bool srv_ibuf_disable_background_merge;
#ifdef UNIV_DEBUG
extern my_bool srv_sync_debug;
extern my_bool srv_purge_view_update_only_debug;
+
+/** Value of MySQL global used to disable master thread. */
+extern my_bool srv_master_thread_disabled_debug;
#endif /* UNIV_DEBUG */
#define SRV_SEMAPHORE_WAIT_EXTENSION 7200
@@ -594,6 +602,7 @@ extern mysql_pfs_key_t srv_lock_timeout_thread_key;
extern mysql_pfs_key_t srv_master_thread_key;
extern mysql_pfs_key_t srv_monitor_thread_key;
extern mysql_pfs_key_t srv_purge_thread_key;
+extern mysql_pfs_key_t srv_worker_thread_key;
extern mysql_pfs_key_t trx_rollback_clean_thread_key;
/* This macro register the current thread and its key with performance
@@ -951,11 +960,26 @@ bool
srv_is_tablespace_truncated(ulint space_id);
/** Check if tablespace was truncated.
-@param space_id space_id to check for truncate action
+@param[in] space space object to check for truncate action
@return true if tablespace was truncated and we still have an active
MLOG_TRUNCATE REDO log record. */
bool
-srv_was_tablespace_truncated(ulint space_id);
+srv_was_tablespace_truncated(const fil_space_t* space);
+
+#ifdef UNIV_DEBUG
+/** Disables master thread. It's used by:
+ SET GLOBAL innodb_master_thread_disabled_debug = 1 (0).
+@param[in] thd thread handle
+@param[in] var pointer to system variable
+@param[out] var_ptr where the formal string goes
+@param[in] save immediate result from check function */
+void
+srv_master_thread_disabled_debug_update(
+ THD* thd,
+ struct st_mysql_sys_var* var,
+ void* var_ptr,
+ const void* save);
+#endif /* UNIV_DEBUG */
/** Status variables to be passed to MySQL */
struct export_var_t{
@@ -990,6 +1014,7 @@ struct export_var_t{
ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
+ ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
ulint innodb_log_waits; /*!< srv_log_waits */
ulint innodb_log_write_requests; /*!< srv_log_write_requests */
ulint innodb_log_writes; /*!< srv_log_writes */
@@ -1136,6 +1161,7 @@ struct srv_slot_t{
# define srv_start_raw_disk_in_use 0
# define srv_file_per_table 1
#endif /* !UNIV_HOTBACKUP */
+
#ifdef WITH_WSREP
UNIV_INTERN
void
diff --git a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h
index 9db27ef2965..0dd98e5b19b 100644
--- a/storage/innobase/include/srv0start.h
+++ b/storage/innobase/include/srv0start.h
@@ -125,6 +125,17 @@ srv_get_meta_data_filename(
char* filename,
ulint max_len);
+/** Get the encryption-data filename from the table name for a
+single-table tablespace.
+@param[in] table table object
+@param[out] filename filename
+@param[in] max_len filename max length */
+void
+srv_get_encryption_data_filename(
+ dict_table_t* table,
+ char* filename,
+ ulint max_len);
+
/** Log sequence number at shutdown */
extern lsn_t srv_shutdown_lsn;
/** Log sequence number immediately after startup */
diff --git a/storage/innobase/include/sync0arr.h b/storage/innobase/include/sync0arr.h
index db04e0e7b22..1a3cc93f0e9 100644
--- a/storage/innobase/include/sync0arr.h
+++ b/storage/innobase/include/sync0arr.h
@@ -1,6 +1,7 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2016, 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
@@ -29,7 +30,7 @@ Created 9/5/1995 Heikki Tuuri
#include "univ.i"
#include "os0thread.h"
-/** Synchonization cell */
+/** Synchronization wait array cell */
struct sync_cell_t;
/** Synchronization wait array */
@@ -128,7 +129,6 @@ Get an instance of the sync wait array. */
UNIV_INLINE
sync_array_t*
sync_array_get();
-
/**********************************************************************//**
Prints info of the wait array without using any mutexes/semaphores. */
UNIV_INTERN
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index 8e76af327a4..64bbf4c4aac 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -171,6 +171,18 @@ unlocking, not the corresponding function. */
#define rw_lock_sx_lock_nowait(M, P) \
rw_lock_sx_lock_low((M), (P), __FILE__, __LINE__)
+#define rw_lock_sx_lock(L) \
+ rw_lock_sx_lock_func((L), 0, __FILE__, __LINE__)
+
+#define rw_lock_sx_lock_inline(M, P, F, L) \
+ rw_lock_sx_lock_func((M), (P), (F), (L))
+
+#define rw_lock_sx_lock_gen(M, P) \
+ rw_lock_sx_lock_func((M), (P), __FILE__, __LINE__)
+
+#define rw_lock_sx_lock_nowait(M, P) \
+ rw_lock_sx_lock_low((M), (P), __FILE__, __LINE__)
+
# ifdef UNIV_DEBUG
# define rw_lock_sx_unlock(L) rw_lock_sx_unlock_func(0, L)
# define rw_lock_sx_unlock_gen(L, P) rw_lock_sx_unlock_func(P, L)
@@ -552,7 +564,7 @@ rw_lock_own_flagged(
const rw_lock_t* lock, /*!< in: rw-lock */
rw_lock_flags_t flags) /*!< in: specify lock types with
OR of the rw_lock_flag_t values */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#endif /* UNIV_DEBUG */
/******************************************************************//**
Checks if somebody has locked the rw-lock in the specified mode.
diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
index b6a80e8a93c..7fddada10f8 100644
--- a/storage/innobase/include/sync0sync.h
+++ b/storage/innobase/include/sync0sync.h
@@ -70,6 +70,7 @@ extern mysql_pfs_key_t ibuf_bitmap_mutex_key;
extern mysql_pfs_key_t ibuf_mutex_key;
extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
extern mysql_pfs_key_t log_sys_mutex_key;
+extern mysql_pfs_key_t log_sys_write_mutex_key;
extern mysql_pfs_key_t log_cmdq_mutex_key;
extern mysql_pfs_key_t log_flush_order_mutex_key;
extern mysql_pfs_key_t mutex_list_mutex_key;
@@ -135,9 +136,7 @@ extern mysql_pfs_key_t index_online_log_key;
extern mysql_pfs_key_t dict_table_stats_key;
extern mysql_pfs_key_t trx_sys_rw_lock_key;
extern mysql_pfs_key_t hash_table_locks_key;
-# ifdef UNIV_DEBUG
-extern mysql_pfs_key_t buf_chunk_map_latch_key;
-# endif /* UNIV_DEBUG */
+extern mysql_pfs_key_t master_key_id_mutex_key;
#endif /* UNIV_PFS_RWLOCK */
/** Prints info of the sync system.
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
index 10f1a6e9d6f..0036135c1f0 100644
--- a/storage/innobase/include/sync0types.h
+++ b/storage/innobase/include/sync0types.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -223,6 +223,7 @@ enum latch_level_t {
SYNC_POOL,
SYNC_POOL_MANAGER,
+
SYNC_SEARCH_SYS,
SYNC_WORK_QUEUE,
@@ -234,6 +235,7 @@ enum latch_level_t {
SYNC_RECV,
SYNC_LOG_FLUSH_ORDER,
SYNC_LOG,
+ SYNC_LOG_WRITE,
SYNC_PAGE_CLEANER,
SYNC_PURGE_QUEUE,
SYNC_TRX_SYS_HEADER,
@@ -324,6 +326,7 @@ enum latch_id_t {
LATCH_ID_IBUF,
LATCH_ID_IBUF_PESSIMISTIC_INSERT,
LATCH_ID_LOG_SYS,
+ LATCH_ID_LOG_WRITE,
LATCH_ID_LOG_FLUSH_ORDER,
LATCH_ID_LIST,
LATCH_ID_MUTEX_LIST,
@@ -386,8 +389,10 @@ enum latch_id_t {
LATCH_ID_HASH_TABLE_RW_LOCK,
LATCH_ID_BUF_CHUNK_MAP_LATCH,
LATCH_ID_SYNC_DEBUG_MUTEX,
+ LATCH_ID_MASTER_KEY_ID_MUTEX,
LATCH_ID_SCRUB_STAT_MUTEX,
LATCH_ID_DEFRAGMENT_MUTEX,
+ LATCH_ID_BTR_DEFRAGMENT_MUTEX,
LATCH_ID_MTFLUSH_THREAD_MUTEX,
LATCH_ID_MTFLUSH_MUTEX,
LATCH_ID_FIL_CRYPT_MUTEX,
diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h
index 24c36825dd7..b7a2deac63e 100644
--- a/storage/innobase/include/trx0rec.h
+++ b/storage/innobase/include/trx0rec.h
@@ -331,6 +331,9 @@ info, and verify the column is still indexed, and output its position
@param[in] ptr undo log pointer
@param[in] first_v_col if this is the first virtual column, which
has the version marker
+@param[in,out] is_undo_log his function is used to parse both undo log,
+ and online log for virtual columns. So
+ check to see if this is undo log
@param[out] field_no the column number
@return remaining part of undo log record after reading these values */
const byte*
@@ -338,6 +341,7 @@ trx_undo_read_v_idx(
const dict_table_t* table,
const byte* ptr,
bool first_v_col,
+ bool* is_undo_log,
ulint* field_no);
#ifndef UNIV_HOTBACKUP
diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h
index e0d6c4f1da6..b9cbd387a62 100644
--- a/storage/innobase/include/trx0rseg.h
+++ b/storage/innobase/include/trx0rseg.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -122,9 +122,8 @@ rseg array in trx_sys at a database startup. */
void
trx_rseg_array_init(
/*================*/
- trx_sysf_t* sys_header, /*!< in/out: trx system header */
- purge_pq_t* purge_queue, /*!< in: rseg queue */
- mtr_t* mtr); /*!< in/out: mtr */
+ purge_pq_t* purge_queue); /*!< in: rseg queue */
+
/***************************************************************************
Free's an instance of the rollback segment in memory. */
void
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index 7d26bf5b23e..ddf535158b6 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -252,7 +252,7 @@ bool
trx_in_rw_trx_list(
/*============*/
const trx_t* in_trx) /*!< in: transaction */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#endif /* UNIV_DEBUG */
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
/***********************************************************//**
@@ -277,9 +277,7 @@ trx_sys_update_mysql_binlog_offset(
int64_t offset, /*!< in: position in that log file */
ulint field, /*!< in: offset of the MySQL log info field in
the trx sys header */
-#ifdef WITH_WSREP
trx_sysf_t* sys_header, /*!< in: trx sys header */
-#endif /* WITH_WSREP */
mtr_t* mtr); /*!< in: mtr */
/*****************************************************************//**
Prints to stderr the MySQL binlog offset info in the trx system header if
@@ -291,25 +289,29 @@ trx_sys_print_mysql_binlog_offset(void);
/** Update WSREP checkpoint XID in sys header. */
void
trx_sys_update_wsrep_checkpoint(
- const XID* xid, /*!< in: WSREP XID */
- trx_sysf_t* sys_header, /*!< in: sys_header */
- mtr_t* mtr); /*!< in: mtr */
+/*============================*/
+ const XID* xid, /*!< in: WSREP XID */
+ trx_sysf_t* sys_header, /*!< in: sys_header */
+ mtr_t* mtr); /*!< in: mtr */
void
/** Read WSREP checkpoint XID from sys header. */
trx_sys_read_wsrep_checkpoint(
- XID* xid); /*!< out: WSREP XID */
+/*==========================*/
+ XID* xid); /*!< out: WSREP XID */
#endif /* WITH_WSREP */
-/*****************************************************************//**
-Initializes the tablespace tag system. */
+
+/** Initializes the tablespace tag system. */
void
trx_sys_file_format_init(void);
/*==========================*/
+
/*****************************************************************//**
Closes the tablespace tag system. */
void
trx_sys_file_format_close(void);
/*===========================*/
+
/********************************************************************//**
Tags the system table space with minimum format id if it has not been
tagged yet.
@@ -318,6 +320,7 @@ redo log application during recovery has finished. */
void
trx_sys_file_format_tag_init(void);
/*==============================*/
+
/*****************************************************************//**
Shutdown/Close the transaction system. */
void
diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic
index 2b1ff55c228..6158aea0c48 100644
--- a/storage/innobase/include/trx0sys.ic
+++ b/storage/innobase/include/trx0sys.ic
@@ -105,9 +105,11 @@ trx_sysf_get(
block = buf_page_get(page_id_t(TRX_SYS_SPACE, TRX_SYS_PAGE_NO),
univ_page_size, RW_X_LATCH, mtr);
- buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
+ if (block) {
+ buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
- header = TRX_SYS + buf_block_get_frame(block);
+ header = TRX_SYS + buf_block_get_frame(block);
+ }
return(header);
}
@@ -423,7 +425,7 @@ trx_sys_get_new_trx_id()
{
#ifndef WITH_WSREP
/* wsrep_fake_trx_id violates this assert */
- ut_ad(mutex_own(&trx_sys->mutex));
+ ut_ad(trx_sys_mutex_own());
#endif /* WITH_WSREP */
/* VERY important: after the database is started, max_trx_id value is
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 3c53c45a720..839c3d057e7 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -247,17 +247,16 @@ Commits a transaction. */
void
trx_commit(
/*=======*/
- trx_t* trx) /*!< in/out: transaction */
- MY_ATTRIBUTE((nonnull));
+ trx_t* trx); /*!< in/out: transaction */
+
/****************************************************************//**
Commits a transaction and a mini-transaction. */
void
trx_commit_low(
/*===========*/
trx_t* trx, /*!< in/out: transaction */
- mtr_t* mtr) /*!< in/out: mini-transaction (will be committed),
+ mtr_t* mtr); /*!< in/out: mini-transaction (will be committed),
or NULL if trx made no modifications */
- MY_ATTRIBUTE((nonnull(1)));
/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
@@ -299,15 +298,14 @@ holding lock_sys->mutex */
trx_t *
trx_get_trx_by_xid(
/*===============*/
- const XID* xid); /*!< in: X/Open XA transaction identifier */
+ XID* xid); /*!< in: X/Open XA transaction identifier */
/**********************************************************************//**
If required, flushes the log to disk if we called trx_commit_for_mysql()
with trx->flush_log_later == TRUE. */
void
trx_commit_complete_for_mysql(
/*==========================*/
- trx_t* trx) /*!< in/out: transaction */
- MY_ATTRIBUTE((nonnull));
+ trx_t* trx); /*!< in/out: transaction */
/**********************************************************************//**
Marks the latest SQL statement ended. */
void
@@ -377,9 +375,8 @@ trx_print_low(
/*!< in: lock_number_of_rows_locked(&trx->lock) */
ulint n_trx_locks,
/*!< in: length of trx->lock.trx_locks */
- ulint heap_size)
+ ulint heap_size);
/*!< in: mem_heap_get_size(trx->lock.lock_heap) */
- MY_ATTRIBUTE((nonnull));
/**********************************************************************//**
Prints info about a transaction.
@@ -390,9 +387,8 @@ trx_print_latched(
/*==============*/
FILE* f, /*!< in: output stream */
const trx_t* trx, /*!< in: transaction */
- ulint max_query_len) /*!< in: max query length to print,
+ ulint max_query_len); /*!< in: max query length to print,
or 0 to use the default max length */
- MY_ATTRIBUTE((nonnull));
/**********************************************************************//**
Prints info about a transaction.
@@ -402,9 +398,8 @@ trx_print(
/*======*/
FILE* f, /*!< in: output stream */
const trx_t* trx, /*!< in: transaction */
- ulint max_query_len) /*!< in: max query length to print,
+ ulint max_query_len); /*!< in: max query length to print,
or 0 to use the default max length */
- MY_ATTRIBUTE((nonnull));
/**********************************************************************//**
Determine if a transaction is a dictionary operation.
@@ -414,7 +409,7 @@ enum trx_dict_op_t
trx_get_dict_operation(
/*===================*/
const trx_t* trx) /*!< in: transaction */
- MY_ATTRIBUTE((warn_unused_result, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/**********************************************************************//**
Flag a transaction a dictionary operation. */
UNIV_INLINE
@@ -438,7 +433,7 @@ trx_state_eq(
/*=========*/
const trx_t* trx, /*!< in: transaction */
trx_state_t state) /*!< in: state */
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
# ifdef UNIV_DEBUG
/**********************************************************************//**
Asserts that a transaction has been started.
@@ -448,7 +443,7 @@ ibool
trx_assert_started(
/*===============*/
const trx_t* trx) /*!< in: transaction */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
# endif /* UNIV_DEBUG */
/**********************************************************************//**
@@ -1055,10 +1050,7 @@ struct trx_t {
the coordinator using the XA API, and
is set to false after commit or
rollback. */
- unsigned active_commit_ordered:1;/* 1 if owns prepare mutex, if
- this is set to 1 then registered should
- also be set to 1. This is used in the
- XA code */
+ unsigned active_commit_ordered:1;/* 1 if owns prepare mutex */
/*------------------------------*/
bool check_unique_secondary;
/*!< normally TRUE, but if the user
@@ -1067,11 +1059,7 @@ struct trx_t {
for secondary indexes when we decide
if we can use the insert buffer for
them, we set this FALSE */
- bool support_xa; /*!< normally we do the XA two-phase
- commit steps, but by setting this to
- FALSE, one can save CPU time and about
- 150 bytes in the undo log size as then
- we skip XA steps */
+ bool support_xa; /*!< normally we do the XA two-phase */
bool flush_log_later;/* In 2PC, we hold the
prepare_commit mutex across
both phases. In that case, we
@@ -1570,18 +1558,30 @@ private:
{
ut_ad(trx_mutex_own(trx));
- while (is_forced_rollback(trx)) {
-
- if (!is_started(trx)) {
+ ulint loop_count = 0;
+ /* start with optimistic sleep time - 20 micro seconds. */
+ ulint sleep_time = 20;
- return;
- }
+ while (is_forced_rollback(trx)) {
/* Wait for the async rollback to complete */
trx_mutex_exit(trx);
- os_thread_sleep(20);
+ loop_count++;
+ /* If the wait is long, don't hog the cpu. */
+ if (loop_count < 100) {
+ /* 20 microseconds */
+ sleep_time = 20;
+ } else if (loop_count < 1000) {
+ /* 1 millisecond */
+ sleep_time = 1000;
+ } else {
+ /* 100 milliseconds */
+ sleep_time = 100000;
+ }
+
+ os_thread_sleep(sleep_time);
trx_mutex_enter(trx);
}
diff --git a/storage/innobase/include/trx0types.h b/storage/innobase/include/trx0types.h
index e9de23862af..37a53f900eb 100644
--- a/storage/innobase/include/trx0types.h
+++ b/storage/innobase/include/trx0types.h
@@ -37,7 +37,7 @@ Created 3/26/1996 Heikki Tuuri
//#include <unordered_set>
/** printf(3) format used for printing DB_TRX_ID and other system fields */
-#define TRX_ID_FMT UINT32PF
+#define TRX_ID_FMT IB_ID_FMT
/** maximum length that a formatted trx_t::id could take, not including
the terminating NUL character. */
diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h
index e1024271606..60fbb9d2304 100644
--- a/storage/innobase/include/trx0undo.h
+++ b/storage/innobase/include/trx0undo.h
@@ -1,7 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2016, 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
@@ -28,7 +27,6 @@ Created 3/26/1996 Heikki Tuuri
#define trx0undo_h
#ifndef UNIV_INNOCHECKSUM
-
#include "univ.i"
#include "trx0types.h"
#include "mtr0mtr.h"
@@ -76,7 +74,7 @@ bool
trx_undo_trx_id_is_insert(
/*======================*/
const byte* trx_id) /*!< in: DB_TRX_ID, followed by DB_ROLL_PTR */
- MY_ATTRIBUTE((nonnull, pure, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
/*****************************************************************//**
Writes a roll ptr to an index page. In case that the size changes in
@@ -249,13 +247,16 @@ trx_undo_free_last_page_func(
Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
void
-trx_undo_truncate_end(
+trx_undo_truncate_end_func(
/*=======================*/
trx_t* trx, /*!< in: transaction whose undo log it is */
trx_undo_t* undo, /*!< in/out: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
- MY_ATTRIBUTE((nonnull));
+ MY_ATTRIBUTE((nonnull(1,2)));
+
+#define trx_undo_truncate_end(trx, undo, limit) \
+ trx_undo_truncate_end_func(trx, undo, limit)
/** Truncate the head of an undo log.
NOTE that only whole pages are freed; the header page is not
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 0d3a3a0dfcc..6907bfec583 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2016, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -45,7 +45,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 7
-#define INNODB_VERSION_BUGFIX 9
+#define INNODB_VERSION_BUGFIX 14
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
@@ -199,7 +199,7 @@ command. */
#define UNIV_ENABLE_UNIT_TEST_ROW_RAW_FORMAT_INT
*/
-#if defined(HAVE_valgrind)&& defined(HAVE_VALGRIND_MEMCHECK_H)
+#if defined HAVE_VALGRIND
# define UNIV_DEBUG_VALGRIND
#endif /* HAVE_VALGRIND */
#if 0
@@ -259,13 +259,20 @@ and the insert buffer must be empty when the database is started */
that are only referenced from within InnoDB, not from MySQL. We disable the
GCC visibility directive on all Sun operating systems because there is no
easy way to get it to work. See http://bugs.mysql.com/bug.php?id=52263. */
-#define MY_ATTRIBUTE __attribute__
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(sun) || defined(__INTEL_COMPILER)
-# define UNIV_INTERN MY_ATTRIBUTE((visibility ("hidden")))
+# define UNIV_INTERN __attribute__((visibility ("hidden")))
#else
# define UNIV_INTERN
#endif
+#ifndef MY_ATTRIBUTE
+#if defined(__GNUC__)
+# define MY_ATTRIBUTE(A) __attribute__(A)
+#else
+# define MY_ATTRIBUTE(A)
+#endif
+#endif
+
#if defined(COMPILER_HINTS) \
&& defined __GNUC__ \
&& (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3)
@@ -482,30 +489,27 @@ macro ULINTPF. */
#ifdef _WIN32
/* Use the integer types and formatting strings defined in Visual Studio. */
-# define UINT32PF "%lu"
+# define UINT32PF "%u"
# define UINT64PF "%llu"
# define UINT64PFx "%016llx"
+# define UINT64scan "llu"
typedef unsigned __int64 ib_uint64_t;
typedef unsigned __int32 ib_uint32_t;
#else
-// JAN: TODO: Use formating strings defined in the C99 standard
-/* Use the integer types and formatting strings defined in the C99 standard. */
-//# define UINT32PF "%" PRIu32
-//# define UINT64PF "%" PRIu64
-//# define UINT64PFx "%016" PRIx64
-# define UINT32PF "%lu"
+# define UINT32PF "%u"
+#if SIZEOF_LONG == 8
+# define UINT64PF "%lu"
+# define UINT64PFx "%016lx"
+# define UINT64scan "lu"
+#else
# define UINT64PF "%llu"
# define UINT64PFx "%016llx"
+# define UINT64scan "llu"
+#endif
typedef uint64_t ib_uint64_t;
typedef uint32_t ib_uint32_t;
#endif /* _WIN32 */
-/* JAN: TODO: Fix server to use c99 when possible. */
-#define IB_ID_FMT UINT64PF
-
-/* Type used for all log sequence number storage and arithmetics */
-typedef ib_uint64_t lsn_t;
-
#ifdef _WIN64
typedef unsigned __int64 ulint;
typedef __int64 lint;
@@ -542,13 +546,13 @@ typedef long int lint;
#define IB_UINT64_MAX ((ib_uint64_t) (~0ULL))
/** The generic InnoDB system object identifier data type */
-typedef ib_uint64_t ib_id_t;
-#define IB_ID_MAX IB_UINT64_MAX
+typedef ib_uint64_t ib_id_t;
+#define IB_ID_MAX (~(ib_id_t) 0)
+#define IB_ID_FMT UINT64PF
#ifndef UINTMAX_MAX
#define UINTMAX_MAX IB_UINT64_MAX
#endif
-
/** This 'ibool' type is used within Innobase. Remember that different included
headers may define 'bool' differently. Do not assume that 'bool' is a ulint! */
#define ibool ulint
diff --git a/storage/innobase/include/ut0counter.h b/storage/innobase/include/ut0counter.h
index 7c704988139..175427df333 100644
--- a/storage/innobase/include/ut0counter.h
+++ b/storage/innobase/include/ut0counter.h
@@ -34,13 +34,17 @@ Created 2012/04/12 by Sunny Bains
/** CPU cache line size */
#ifndef UNIV_HOTBACKUP
# ifdef CPU_LEVEL1_DCACHE_LINESIZE
-# define CACHE_LINE_SIZE CPU_LEVEL1_DCACHE_LINESIZE
+# define CACHE_LINE_SIZE CPU_LEVEL1_DCACHE_LINESIZE
# else
# error CPU_LEVEL1_DCACHE_LINESIZE is undefined
# endif /* CPU_LEVEL1_DCACHE_LINESIZE */
#else
-# define CACHE_LINE_SIZE 64
+#ifdef powerpc
+#define CACHE_LINE_SIZE 128
+#else
+# define CACHE_LINE_SIZE 64
#endif /* __powerpc__ */
+#endif /* UNIV_HOTBACKUP */
/** Default number of slots to use in ib_counter_t */
#define IB_N_SLOTS 64
diff --git a/storage/innobase/include/ut0crc32.h b/storage/innobase/include/ut0crc32.h
index 2066fa00684..91af6a910ff 100644
--- a/storage/innobase/include/ut0crc32.h
+++ b/storage/innobase/include/ut0crc32.h
@@ -56,6 +56,6 @@ extern ut_crc32_func_t ut_crc32_byte_by_byte;
/** Flag that tells whether the CPU supports CRC32 or not */
extern bool ut_crc32_sse2_enabled;
-extern bool ut_crc32_power8_enabled;
+extern bool ut_crc32_power8_enabled;
#endif /* ut0crc32_h */
diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h
index cf80c1aa0ad..1a61ed84a38 100644
--- a/storage/innobase/include/ut0dbg.h
+++ b/storage/innobase/include/ut0dbg.h
@@ -44,7 +44,7 @@ ut_dbg_assertion_failed(
const char* expr, /*!< in: the failed assertion */
const char* file, /*!< in: source file containing the assertion */
ulint line) /*!< in: line number of the assertion */
- UNIV_COLD MY_ATTRIBUTE((nonnull(2)));
+ UNIV_COLD MY_ATTRIBUTE((nonnull(2), noreturn));
/** Abort execution if EXPR does not evaluate to nonzero.
@param EXPR assertion expression that should hold */
diff --git a/storage/innobase/include/ut0lst.h b/storage/innobase/include/ut0lst.h
index 371e6457a9e..09733da20a0 100644
--- a/storage/innobase/include/ut0lst.h
+++ b/storage/innobase/include/ut0lst.h
@@ -318,7 +318,6 @@ ut_list_insert(
++list.count;
}
-
/*******************************************************************//**
Removes a node from a two-way linked list.
@param list the base node (not a pointer to it)
diff --git a/storage/innobase/include/ut0mem.h b/storage/innobase/include/ut0mem.h
index be7b72b1c19..6d56be4d820 100644
--- a/storage/innobase/include/ut0mem.h
+++ b/storage/innobase/include/ut0mem.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
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
diff --git a/storage/innobase/include/ut0new.h b/storage/innobase/include/ut0new.h
index c9e9dcf05f7..6f3c06cf978 100644
--- a/storage/innobase/include/ut0new.h
+++ b/storage/innobase/include/ut0new.h
@@ -227,6 +227,11 @@ struct ut_new_pfx_t {
allocated block and its users are responsible for maintaining it
and passing it later to ut_allocator::deallocate_large(). */
size_t m_size;
+#if SIZEOF_VOIDP == 4
+ /** Pad the header size to a multiple of 64 bits on 32-bit systems,
+ so that the payload will be aligned to 64 bits. */
+ size_t pad;
+#endif
};
/** Allocator class for allocating memory from inside std::* containers. */
@@ -335,6 +340,10 @@ public:
size_t total_bytes = n_elements * sizeof(T);
#ifdef UNIV_PFS_MEMORY
+ /* The header size must not ruin the 64-bit alignment
+ on 32-bit systems. Some allocated structures use
+ 64-bit fields. */
+ ut_ad((sizeof(ut_new_pfx_t) & 7) == 0);
total_bytes += sizeof(ut_new_pfx_t);
#endif /* UNIV_PFS_MEMORY */
@@ -398,7 +407,7 @@ public:
free(pfx);
#else
- free(ptr);
+ // free(ptr);
#endif /* UNIV_PFS_MEMORY */
}
diff --git a/storage/innobase/include/ut0rnd.h b/storage/innobase/include/ut0rnd.h
index 09e66034c4f..aa5b4b6745d 100644
--- a/storage/innobase/include/ut0rnd.h
+++ b/storage/innobase/include/ut0rnd.h
@@ -99,7 +99,7 @@ ulint
ut_fold_string(
/*===========*/
const char* str) /*!< in: null-terminated string */
- MY_ATTRIBUTE((warn_unused_result, pure));
+ MY_ATTRIBUTE((warn_unused_result));
/***********************************************************//**
Looks for a prime number slightly greater than the given argument.
The prime is chosen so that it is not near any power of 2.
diff --git a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic
index 8abf775869c..503c9482ea3 100644
--- a/storage/innobase/include/ut0rnd.ic
+++ b/storage/innobase/include/ut0rnd.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index f36cd367270..5a1c3989f4d 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -172,7 +172,7 @@ ut_pair_cmp(
ulint a_l,
ulint b_h,
ulint b_l)
- __attribute__((warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/*************************************************************//**
Calculates fast the remainder of n/m when m is a power of two.
@@ -345,7 +345,7 @@ ut_get_year_month_day(
Runs an idle loop on CPU. The argument gives the desired delay
in microseconds on 100 MHz Pentium + Visual C++.
@return dummy value */
-void
+ulint
ut_delay(
/*=====*/
ulint delay); /*!< in: delay in microseconds on 100 MHz Pentium */
@@ -367,7 +367,7 @@ ut_print_buf_hex(
std::ostream& o, /*!< in/out: output stream */
const void* buf, /*!< in: memory buffer */
ulint len) /*!< in: length of the buffer */
- __attribute__((nonnull));
+ MY_ATTRIBUTE((nonnull));
/*************************************************************//**
Prints the contents of a memory buffer in hex and ascii. */
void
@@ -376,7 +376,7 @@ ut_print_buf(
std::ostream& o, /*!< in/out: output stream */
const void* buf, /*!< in: memory buffer */
ulint len) /*!< in: length of the buffer */
- __attribute__((nonnull));
+ MY_ATTRIBUTE((nonnull));
#ifndef UNIV_HOTBACKUP
/* Forward declaration of transaction handle */
@@ -403,26 +403,17 @@ as in SQL database_name.identifier. */
void
ut_print_name(
/*==========*/
- FILE* f, /*!< in: output stream */
+ FILE* ef, /*!< in: stream */
const trx_t* trx, /*!< in: transaction */
const char* name); /*!< in: table name to print */
-/**********************************************************************//**
-Outputs a fixed-length string, quoted as an SQL identifier.
-If the string contains a slash '/', the string will be
-output as two identifiers separated by a period (.),
-as in SQL database_name.identifier. */
-UNIV_INTERN
-std::string
-ut_get_name(
-/*=========*/
- const trx_t* trx, /*!< in: transaction (NULL=no quotes) */
- ibool table_id,/*!< in: TRUE=print a table name,
- FALSE=print other identifier */
- const char* name); /*!< in: name to print */
-/**********************************************************************//**
-Formats a table or index name, quoted as an SQL identifier. If the name
-contains a slash '/', the result will contain two identifiers separated by
-a period (.), as in SQL database_name.identifier.
+/** Format a table name, quoted as an SQL identifier.
+If the name contains a slash '/', the result will contain two
+identifiers separated by a period (.), as in SQL
+database_name.table_name.
+@see table_name_t
+@param[in] name table or index name
+@param[out] formatted formatted result, will be NUL-terminated
+@param[in] formatted_size size of the buffer in bytes
@return pointer to 'formatted' */
char*
ut_format_name(
diff --git a/storage/innobase/include/ut0wqueue.h b/storage/innobase/include/ut0wqueue.h
index 0cc284f7e0d..771d8d6ae5c 100644
--- a/storage/innobase/include/ut0wqueue.h
+++ b/storage/innobase/include/ut0wqueue.h
@@ -96,7 +96,6 @@ void*
ib_wqueue_nowait(
/*=============*/
ib_wqueue_t* wq); /*<! in: work queue */
-
/********************************************************************
Get number of items on queue.
@return number of items on queue */