diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-08-12 11:17:45 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-09-02 13:22:28 +0300 |
commit | 2e814d4702d71a04388386a9f591d14a35980bfe (patch) | |
tree | f3f9b48d116a3738c5e71f3a360ca61f16cfb632 /storage/innobase/include/rem0rec.ic | |
parent | 848d211c5c4df00b819cd84d7530cf7d29bb0524 (diff) | |
download | mariadb-git-2e814d4702d71a04388386a9f591d14a35980bfe.tar.gz |
Merge InnoDB 5.7 from mysql-5.7.9.
Contains also
MDEV-10547: Test multi_update_innodb fails with InnoDB 5.7
The failure happened because 5.7 has changed the signature of
the bool handler::primary_key_is_clustered() const
virtual function ("const" was added). InnoDB was using the old
signature which caused the function not to be used.
MDEV-10550: Parallel replication lock waits/deadlock handling does not work with InnoDB 5.7
Fixed mutexing problem on lock_trx_handle_wait. Note that
rpl_parallel and rpl_optimistic_parallel tests still
fail.
MDEV-10156 : Group commit tests fail on 10.2 InnoDB (branch bb-10.2-jan)
Reason: incorrect merge
MDEV-10550: Parallel replication can't sync with master in InnoDB 5.7 (branch bb-10.2-jan)
Reason: incorrect merge
Diffstat (limited to 'storage/innobase/include/rem0rec.ic')
-rw-r--r-- | storage/innobase/include/rem0rec.ic | 191 |
1 files changed, 118 insertions, 73 deletions
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic index 5811a77a48b..4d2cbcb4944 100644 --- a/storage/innobase/include/rem0rec.ic +++ b/storage/innobase/include/rem0rec.ic @@ -26,6 +26,7 @@ Created 5/30/1994 Heikki Tuuri #include "mach0data.h" #include "ut0byte.h" #include "dict0dict.h" +#include "dict0boot.h" #include "btr0types.h" /* Compact flag ORed to the extra size returned by rec_get_offsets() */ @@ -136,7 +137,6 @@ and the shift needed to obtain each bit-field of the record. */ /***********************************************************//** Sets the value of the ith field SQL null bit of an old-style record. */ -UNIV_INTERN void rec_set_nth_field_null_bit( /*=======================*/ @@ -146,7 +146,6 @@ rec_set_nth_field_null_bit( /***********************************************************//** Sets an old-style record field to SQL null. The physical size of the field is not changed. */ -UNIV_INTERN void rec_set_nth_field_sql_null( /*=======================*/ @@ -238,7 +237,7 @@ rec_set_bit_field_2( /******************************************************//** The following function is used to get the pointer of the next chained record on the same page. -@return pointer to the next chained record, or NULL if none */ +@return pointer to the next chained record, or NULL if none */ UNIV_INLINE const rec_t* rec_get_next_ptr_const( @@ -294,7 +293,7 @@ rec_get_next_ptr_const( /******************************************************//** The following function is used to get the pointer of the next chained record on the same page. -@return pointer to the next chained record, or NULL if none */ +@return pointer to the next chained record, or NULL if none */ UNIV_INLINE rec_t* rec_get_next_ptr( @@ -308,7 +307,7 @@ rec_get_next_ptr( /******************************************************//** The following function is used to get the offset of the next chained record on the same page. -@return the page offset of the next chained record, or 0 if none */ +@return the page offset of the next chained record, or 0 if none */ UNIV_INLINE ulint rec_get_next_offs( @@ -418,7 +417,7 @@ rec_set_next_offs_new( /******************************************************//** The following function is used to get the number of fields in an old-style record. -@return number of data fields */ +@return number of data fields */ UNIV_INLINE ulint rec_get_n_fields_old( @@ -458,7 +457,7 @@ rec_set_n_fields_old( /******************************************************//** The following function retrieves the status bits of a new-style record. -@return status bits */ +@return status bits */ UNIV_INLINE ulint rec_get_status( @@ -479,7 +478,7 @@ rec_get_status( /******************************************************//** The following function is used to get the number of fields in a record. -@return number of data fields */ +@return number of data fields */ UNIV_INLINE ulint rec_get_n_fields( @@ -508,10 +507,32 @@ rec_get_n_fields( } } +/** Confirms the n_fields of the entry is sane with comparing the other +record in the same page specified +@param[in] index index +@param[in] rec record of the same page +@param[in] entry index entry +@return true if n_fields is sane */ +UNIV_INLINE +bool +rec_n_fields_is_sane( + dict_index_t* index, + const rec_t* rec, + const dtuple_t* entry) +{ + return(rec_get_n_fields(rec, index) + == dtuple_get_n_fields(entry) + /* a record for older SYS_INDEXES table + (missing merge_threshold column) is acceptable. */ + || (index->table->id == DICT_INDEXES_ID + && rec_get_n_fields(rec, index) + == dtuple_get_n_fields(entry) - 1)); +} + /******************************************************//** The following function is used to get the number of records owned by the previous directory record. -@return number of owned records */ +@return number of owned records */ UNIV_INLINE ulint rec_get_n_owned_old( @@ -538,7 +559,7 @@ rec_set_n_owned_old( /******************************************************//** The following function is used to get the number of records owned by the previous directory record. -@return number of owned records */ +@return number of owned records */ UNIV_INLINE ulint rec_get_n_owned_new( @@ -566,9 +587,22 @@ rec_set_n_owned_new( } } +#ifdef UNIV_DEBUG +/** Check if the info bits are valid. +@param[in] bits info bits to check +@return true if valid */ +inline +bool +rec_info_bits_valid( + ulint bits) +{ + return(0 == (bits & ~(REC_INFO_DELETED_FLAG | REC_INFO_MIN_REC_FLAG))); +} +#endif /* UNIV_DEBUG */ + /******************************************************//** The following function is used to retrieve the info bits of a record. -@return info bits */ +@return info bits */ UNIV_INLINE ulint rec_get_info_bits( @@ -576,9 +610,11 @@ rec_get_info_bits( const rec_t* rec, /*!< in: physical record */ ulint comp) /*!< in: nonzero=compact page format */ { - return(rec_get_bit_field_1( - rec, comp ? REC_NEW_INFO_BITS : REC_OLD_INFO_BITS, - REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT)); + const ulint val = rec_get_bit_field_1( + rec, comp ? REC_NEW_INFO_BITS : REC_OLD_INFO_BITS, + REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT); + ut_ad(rec_info_bits_valid(val)); + return(val); } /******************************************************//** @@ -590,6 +626,7 @@ rec_set_info_bits_old( rec_t* rec, /*!< in: old-style physical record */ ulint bits) /*!< in: info bits */ { + ut_ad(rec_info_bits_valid(bits)); rec_set_bit_field_1(rec, bits, REC_OLD_INFO_BITS, REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT); } @@ -602,6 +639,7 @@ rec_set_info_bits_new( rec_t* rec, /*!< in/out: new-style physical record */ ulint bits) /*!< in: info bits */ { + ut_ad(rec_info_bits_valid(bits)); rec_set_bit_field_1(rec, bits, REC_NEW_INFO_BITS, REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT); } @@ -622,7 +660,7 @@ rec_set_status( /******************************************************//** The following function is used to retrieve the info and status bits of a record. (Only compact records have status bits.) -@return info bits */ +@return info bits */ UNIV_INLINE ulint rec_get_info_and_status_bits( @@ -663,7 +701,7 @@ rec_set_info_and_status_bits( /******************************************************//** The following function tells if record is delete marked. -@return nonzero if delete marked */ +@return nonzero if delete marked */ UNIV_INLINE ulint rec_get_deleted_flag( @@ -733,7 +771,7 @@ rec_set_deleted_flag_new( /******************************************************//** The following function tells if a new-style record is a node pointer. -@return TRUE if node pointer */ +@return TRUE if node pointer */ UNIV_INLINE ibool rec_get_node_ptr_flag( @@ -746,7 +784,7 @@ rec_get_node_ptr_flag( /******************************************************//** The following function is used to get the order number of an old-style record in the heap of the index page. -@return heap order number */ +@return heap order number */ UNIV_INLINE ulint rec_get_heap_no_old( @@ -774,7 +812,7 @@ rec_set_heap_no_old( /******************************************************//** The following function is used to get the order number of a new-style record in the heap of the index page. -@return heap order number */ +@return heap order number */ UNIV_INLINE ulint rec_get_heap_no_new( @@ -802,7 +840,7 @@ rec_set_heap_no_new( /******************************************************//** The following function is used to test whether the data offsets in the record are stored in one-byte or two-byte format. -@return TRUE if 1-byte form */ +@return TRUE if 1-byte form */ UNIV_INLINE ibool rec_get_1byte_offs_flag( @@ -839,7 +877,7 @@ rec_set_1byte_offs_flag( Returns the offset of nth field end if the record is stored in the 1-byte offsets form. If the field is SQL null, the flag is ORed in the returned value. -@return offset of the start of the field, SQL null flag ORed */ +@return offset of the start of the field, SQL null flag ORed */ UNIV_INLINE ulint rec_1_get_field_end_info( @@ -894,7 +932,7 @@ the fields. */ /**********************************************************//** The following function returns the number of allocated elements for an array of offsets. -@return number of elements */ +@return number of elements */ UNIV_INLINE ulint rec_offs_get_n_alloc( @@ -928,7 +966,7 @@ rec_offs_set_n_alloc( /**********************************************************//** The following function returns the number of fields in a record. -@return number of fields */ +@return number of fields */ UNIV_INLINE ulint rec_offs_n_fields( @@ -947,7 +985,7 @@ rec_offs_n_fields( /************************************************************//** Validates offsets returned by rec_get_offsets(). -@return TRUE if valid */ +@return TRUE if valid */ UNIV_INLINE ibool rec_offs_validate( @@ -1025,7 +1063,7 @@ rec_offs_make_valid( /************************************************************//** The following function is used to get an offset to the nth data field in a record. -@return offset from the origin of rec */ +@return offset from the origin of rec */ UNIV_INLINE ulint rec_get_nth_field_offs( @@ -1062,7 +1100,7 @@ rec_get_nth_field_offs( /******************************************************//** Determine if the offsets are for a record in the new compact format. -@return nonzero if compact format */ +@return nonzero if compact format */ UNIV_INLINE ulint rec_offs_comp( @@ -1076,7 +1114,7 @@ rec_offs_comp( /******************************************************//** Determine if the offsets are for a record containing externally stored columns. -@return nonzero if externally stored */ +@return nonzero if externally stored */ UNIV_INLINE ulint rec_offs_any_extern( @@ -1089,7 +1127,7 @@ rec_offs_any_extern( /******************************************************//** 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 */ +@return first field containing a null BLOB pointer, or NULL if none found */ UNIV_INLINE const byte* rec_offs_any_null_extern( @@ -1125,7 +1163,7 @@ rec_offs_any_null_extern( /******************************************************//** Returns nonzero if the extern bit is set in nth field of rec. -@return nonzero if externally stored */ +@return nonzero if externally stored */ UNIV_INLINE ulint rec_offs_nth_extern( @@ -1140,7 +1178,7 @@ rec_offs_nth_extern( /******************************************************//** Returns nonzero if the SQL NULL bit is set in nth field of rec. -@return nonzero if SQL NULL */ +@return nonzero if SQL NULL */ UNIV_INLINE ulint rec_offs_nth_sql_null( @@ -1155,7 +1193,7 @@ rec_offs_nth_sql_null( /******************************************************//** Gets the physical size of a field. -@return length of field */ +@return length of field */ UNIV_INLINE ulint rec_offs_nth_size( @@ -1174,7 +1212,7 @@ rec_offs_nth_size( /******************************************************//** Returns the number of extern bits set in a record. -@return number of externally stored fields */ +@return number of externally stored fields */ UNIV_INLINE ulint rec_offs_n_extern( @@ -1202,7 +1240,7 @@ offsets form. If the field is SQL null, the flag is ORed in the returned value. This function and the 2-byte counterpart are defined here because the C-compiler was not able to sum negative and positive constant offsets, and warned of constant arithmetic overflow within the compiler. -@return offset of the start of the PREVIOUS field, SQL null flag ORed */ +@return offset of the start of the PREVIOUS field, SQL null flag ORed */ UNIV_INLINE ulint rec_1_get_prev_field_end_info( @@ -1220,7 +1258,7 @@ rec_1_get_prev_field_end_info( Returns the offset of n - 1th field end if the record is stored in the 2-byte offsets form. If the field is SQL null, the flag is ORed in the returned value. -@return offset of the start of the PREVIOUS field, SQL null flag ORed */ +@return offset of the start of the PREVIOUS field, SQL null flag ORed */ UNIV_INLINE ulint rec_2_get_prev_field_end_info( @@ -1271,7 +1309,7 @@ rec_2_set_field_end_info( /******************************************************//** Returns the offset of nth field start if the record is stored in the 1-byte offsets form. -@return offset of the start of the field */ +@return offset of the start of the field */ UNIV_INLINE ulint rec_1_get_field_start_offs( @@ -1294,7 +1332,7 @@ rec_1_get_field_start_offs( /******************************************************//** Returns the offset of nth field start if the record is stored in the 2-byte offsets form. -@return offset of the start of the field */ +@return offset of the start of the field */ UNIV_INLINE ulint rec_2_get_field_start_offs( @@ -1319,7 +1357,7 @@ The following function is used to read the offset of the start of a data field in the record. The start of an SQL null field is the end offset of the previous non-null field, or 0, if none exists. If n is the number of the last field + 1, then the end offset of the last field is returned. -@return offset of the start of the field */ +@return offset of the start of the field */ UNIV_INLINE ulint rec_get_field_start_offs( @@ -1347,7 +1385,7 @@ rec_get_field_start_offs( Gets the physical size of an old-style field. Also an SQL null may have a field of size > 0, if the data type is of a fixed size. -@return field size in bytes */ +@return field size in bytes */ UNIV_INLINE ulint rec_get_nth_field_size( @@ -1415,7 +1453,7 @@ The following function returns the data size of an old-style physical record, that is the sum of field lengths. SQL null fields are counted as length 0 fields. The value returned by the function is the distance from record origin to record end in bytes. -@return size */ +@return size */ UNIV_INLINE ulint rec_get_data_size_old( @@ -1450,7 +1488,7 @@ The following function returns the data size of a physical record, that is the sum of field lengths. SQL null fields are counted as length 0 fields. The value returned by the function is the distance from record origin to record end in bytes. -@return size */ +@return size */ UNIV_INLINE ulint rec_offs_data_size( @@ -1470,7 +1508,7 @@ rec_offs_data_size( Returns the total size of record minus data size of record. The value returned by the function is the distance from record start to record origin in bytes. -@return size */ +@return size */ UNIV_INLINE ulint rec_offs_extra_size( @@ -1486,7 +1524,7 @@ rec_offs_extra_size( /**********************************************************//** Returns the total size of a physical record. -@return size */ +@return size */ UNIV_INLINE ulint rec_offs_size( @@ -1499,7 +1537,7 @@ rec_offs_size( #ifdef UNIV_DEBUG /**********************************************************//** Returns a pointer to the end of the record. -@return pointer to end */ +@return pointer to end */ UNIV_INLINE byte* rec_get_end( @@ -1513,7 +1551,7 @@ rec_get_end( /**********************************************************//** Returns a pointer to the start of the record. -@return pointer to start */ +@return pointer to start */ UNIV_INLINE byte* rec_get_start( @@ -1526,16 +1564,17 @@ rec_get_start( } #endif /* UNIV_DEBUG */ -/***************************************************************//** -Copies a physical record to a buffer. -@return pointer to the origin of the copy */ +/** Copy a physical record to a buffer. +@param[in] buf buffer +@param[in] rec physical record +@param[in] offsets array returned by rec_get_offsets() +@return pointer to the origin of the copy */ UNIV_INLINE rec_t* rec_copy( -/*=====*/ - void* buf, /*!< in: buffer */ - const rec_t* rec, /*!< in: physical record */ - const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ + void* buf, + const rec_t* rec, + const ulint* offsets) { ulint extra_len; ulint data_len; @@ -1556,7 +1595,7 @@ rec_copy( /**********************************************************//** Returns the extra size of an old-style physical record if we know its data size and number of fields. -@return extra size */ +@return extra size */ UNIV_INLINE ulint rec_get_converted_extra_size( @@ -1576,7 +1615,7 @@ rec_get_converted_extra_size( /**********************************************************//** The following function returns the size of a data tuple when converted to a physical record. -@return size */ +@return size */ UNIV_INLINE ulint rec_get_converted_size( @@ -1592,12 +1631,19 @@ rec_get_converted_size( ut_ad(dtuple); ut_ad(dtuple_check_typed(dtuple)); - ut_ad(dict_index_is_univ(index) + ut_ad(dict_index_is_ibuf(index) + || dtuple_get_n_fields(dtuple) - == (((dtuple_get_info_bits(dtuple) & REC_NEW_STATUS_MASK) - == REC_STATUS_NODE_PTR) - ? dict_index_get_n_unique_in_tree(index) + 1 - : dict_index_get_n_fields(index))); + == (((dtuple_get_info_bits(dtuple) & REC_NEW_STATUS_MASK) + == REC_STATUS_NODE_PTR) + ? dict_index_get_n_unique_in_tree_nonleaf(index) + 1 + : dict_index_get_n_fields(index)) + + /* a record for older SYS_INDEXES table + (missing merge_threshold column) is acceptable. */ + || (index->table->id == DICT_INDEXES_ID + && dtuple_get_n_fields(dtuple) + == dict_index_get_n_fields(index) - 1)); if (dict_table_is_comp(index->table)) { return(rec_get_converted_size_comp(index, @@ -1622,7 +1668,7 @@ rec_get_converted_size( support multiple page sizes. At that time, we will need to consider the node pointer on these universal btrees. */ - if (dict_index_is_univ(index)) { + if (dict_index_is_ibuf(index)) { /* This is for the insert buffer B-tree. All fields in the leaf tuple ascend to the parent node plus the child page pointer. */ @@ -1651,22 +1697,21 @@ rec_get_converted_size( } #ifndef UNIV_HOTBACKUP -/************************************************************//** -Folds a prefix of a physical record to a ulint. Folds only existing fields, -that is, checks that we do not run out of the record. -@return the folded value */ +/** Fold a prefix of a physical record. +@param[in] rec index record +@param[in] offsets return value of rec_get_offsets() +@param[in] n_fields number of complete fields to fold +@param[in] n_bytes number of bytes to fold in the last field +@param[in] index_id index tree ID +@return the folded value */ UNIV_INLINE ulint rec_fold( -/*=====*/ - const rec_t* rec, /*!< in: the physical record */ - const ulint* offsets, /*!< in: array returned by - rec_get_offsets() */ - ulint n_fields, /*!< in: number of complete - fields to fold */ - ulint n_bytes, /*!< in: number of bytes to fold - in an incomplete last field */ - index_id_t tree_id) /*!< in: index tree id */ + const rec_t* rec, + const ulint* offsets, + ulint n_fields, + ulint n_bytes, + index_id_t tree_id) { ulint i; const byte* data; @@ -1676,7 +1721,7 @@ rec_fold( ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec_validate(rec, offsets)); - ut_ad(n_fields + n_bytes > 0); + ut_ad(n_fields > 0 || n_bytes > 0); n_fields_rec = rec_offs_n_fields(offsets); ut_ad(n_fields <= n_fields_rec); |