From fd73c6dda4dcc8cfff494e296c1cef21dfd64660 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Thu, 22 Feb 2018 19:14:58 +0300 Subject: [PATCH] Vers IB: Mark unversioned fields in system versioning tables Some fields in system-versioned table may be unversioned. SQL layer marks unversioned. And this patch makes InnoDB mark unversioned too because of two reasons: 1) by default fields are versioned 2) most of fields are expected to be versioned dtype_t::vers_sys_field(): fixed return true on row_start/row_end dict_col_t::vers_sys_field(): fixed return true on row_start/row_end --- storage/innobase/dict/dict0mem.cc | 17 +++++++++-------- storage/innobase/handler/ha_innodb.cc | 6 +++--- storage/innobase/handler/handler0alter.cc | 6 +++--- storage/innobase/include/data0type.h | 14 ++++++++------ storage/innobase/include/dict0mem.h | 11 +++++++---- storage/innobase/include/row0upd.h | 9 +++++++-- storage/innobase/trx/trx0rec.cc | 4 ++-- 7 files changed, 39 insertions(+), 28 deletions(-) diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 11936616cd2..f96b87995f8 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -312,14 +312,15 @@ dict_mem_table_add_col( dict_mem_fill_column_struct(col, i, mtype, prtype, len); - switch (prtype & DATA_VERSIONED) { - case DATA_VERS_START: - ut_ad(!table->vers_start); - table->vers_start = i; - break; - case DATA_VERS_END: - ut_ad(!table->vers_end); - table->vers_end = i; + if ((prtype & DATA_UNVERSIONED) != DATA_UNVERSIONED) { + if (prtype & DATA_VERS_START) { + ut_ad(!table->vers_start); + table->vers_start = i; + } + if (prtype & DATA_VERS_END) { + ut_ad(!table->vers_end); + table->vers_end = i; + } } } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b4f3a27b5af..3c12d05757b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -11265,9 +11265,9 @@ create_table_info_t::create_table_def() vers_row = DATA_VERS_START; } else if (i == m_form->s->row_end_field) { vers_row = DATA_VERS_END; - } else if (!(field->flags - & VERS_UPDATE_UNVERSIONED_FLAG)) { - vers_row = DATA_VERSIONED; + } else if (field->flags + & VERS_UPDATE_UNVERSIONED_FLAG) { + vers_row = DATA_UNVERSIONED; } } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index b775bfa40ee..79b96770553 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -5009,9 +5009,9 @@ new_clustered_failed: } else if (i == altered_table->s->row_end_field) { field_type |= DATA_VERS_END; - } else if (!(field->flags - & VERS_UPDATE_UNVERSIONED_FLAG)) { - field_type |= DATA_VERSIONED; + } else if (field->flags + & VERS_UPDATE_UNVERSIONED_FLAG) { + field_type |= DATA_UNVERSIONED; } } diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h index 7e1c362cf8d..897ad19f71e 100644 --- a/storage/innobase/include/data0type.h +++ b/storage/innobase/include/data0type.h @@ -192,8 +192,7 @@ be less than 256 */ /** System Versioning */ #define DATA_VERS_START 16384U /* start system field */ #define DATA_VERS_END 32768U /* end system field */ -/** system-versioned user data column */ -#define DATA_VERSIONED (DATA_VERS_START|DATA_VERS_END) +#define DATA_UNVERSIONED (DATA_VERS_START|DATA_VERS_END) /* unversioned user field */ /** Check whether locking is disabled (never). */ #define dict_table_is_locking_disabled(table) false @@ -543,18 +542,21 @@ struct dtype_t{ in bytes */ /** @return whether this is system field */ - bool vers_sys_field() const { return prtype & DATA_VERSIONED; } + bool vers_sys_field() const + { + return vers_sys_start() || vers_sys_end(); + } /** @return whether this is system versioned user field */ - bool is_versioned() const { return !(~prtype & DATA_VERSIONED); } + bool is_versioned() const { return (prtype & DATA_UNVERSIONED) == 0; } /** @return whether this is the system field start */ bool vers_sys_start() const { - return (prtype & DATA_VERSIONED) == DATA_VERS_START; + return (prtype & DATA_UNVERSIONED) == DATA_VERS_START; } /** @return whether this is the system field end */ bool vers_sys_end() const { - return (prtype & DATA_VERSIONED) == DATA_VERS_END; + return (prtype & DATA_UNVERSIONED) == DATA_VERS_END; } }; diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index d962c69c0c8..6b470247cf2 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -653,7 +653,10 @@ struct dict_col_t{ bool is_nullable() const { return !(prtype & DATA_NOT_NULL); } /** @return whether this is system field */ - bool vers_sys_field() const { return prtype & DATA_VERSIONED; } + bool vers_sys_field() const + { + return vers_sys_start() || vers_sys_end(); + } /** @return whether table of this system field is TRX_ID-based */ bool vers_native() const { @@ -662,16 +665,16 @@ struct dict_col_t{ return mtype == DATA_INT; } /** @return whether this is system versioned */ - bool is_versioned() const { return !(~prtype & DATA_VERSIONED); } + bool is_versioned() const { return (prtype & DATA_UNVERSIONED) == 0; } /** @return whether this is the system version start */ bool vers_sys_start() const { - return (prtype & DATA_VERSIONED) == DATA_VERS_START; + return (prtype & DATA_UNVERSIONED) == DATA_VERS_START; } /** @return whether this is the system version end */ bool vers_sys_end() const { - return (prtype & DATA_VERSIONED) == DATA_VERS_END; + return (prtype & DATA_UNVERSIONED) == DATA_VERS_END; } /** @return whether this is an instantly-added column */ diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h index d010e15eab7..213cd42a297 100644 --- a/storage/innobase/include/row0upd.h +++ b/storage/innobase/include/row0upd.h @@ -474,11 +474,16 @@ struct upd_t{ return(false); } - /** Determine if the update affects a system versioned column. */ + /** Determine if the update affects a system versioned column or row_end. */ bool affects_versioned() const { for (ulint i = 0; i < n_fields; i++) { - if (fields[i].new_val.type.vers_sys_field()) { + dtype_t type = fields[i].new_val.type; + if (type.is_versioned()) { + return true; + } + // versioned DELETE is UPDATE SET row_end=NOW + if (type.vers_sys_end()) { return true; } } diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index f3f04ab5e1c..41d9b1a5fad 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -2089,8 +2089,8 @@ trx_undo_report_row_operation( if (!time.is_versioned() && index->table->versioned_by_id() && (!rec /* INSERT */ - || !update /* DELETE */ - || update->affects_versioned())) { + || (update + && update->affects_versioned()))) { time.set_versioned(limit); } }