diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1cbfab558fe..f25a26ba55e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -100,6 +100,8 @@ #include "rpl_handler.h" +#include "transaction.h" + #ifdef HAVE_SYS_PRCTL_H #include #endif @@ -6024,6 +6026,26 @@ int mysqld_main(int argc, char **argv) if (Events::init((THD*) 0, opt_noacl || opt_bootstrap)) unireg_abort(1); + if (!opt_bootstrap) + { + THD *thd = new THD(0); + thd->thread_stack= (char*) &thd; + thd->store_globals(); + + { + TR_table trt(thd); + if (trt.check()) + { + sql_print_error("%s schema is incorrect", trt.table_name); + delete thd; + unireg_abort(1); + } + } + + trans_commit_stmt(thd); + delete thd; + } + if (WSREP_ON) { if (opt_bootstrap) diff --git a/sql/table.cc b/sql/table.cc index 451f2829a5b..c6df927f15c 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -8684,6 +8684,61 @@ bool TR_table::query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0, return false; } +bool TR_table::check() const +{ + // InnoDB may not be loaded + if (!ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB)) + return false; + + if (!table) + return true; + + if (table->file->ht->db_type != DB_TYPE_INNODB) + return true; + + if (table->s->fields != 5) + return true; + + if (table->field[FLD_TRX_ID]->type() != MYSQL_TYPE_LONGLONG) + return true; + + if (table->field[FLD_COMMIT_ID]->type() != MYSQL_TYPE_LONGLONG) + return true; + + if (table->field[FLD_BEGIN_TS]->type() != MYSQL_TYPE_TIMESTAMP) + return true; + + if (table->field[FLD_COMMIT_TS]->type() != MYSQL_TYPE_TIMESTAMP) + return true; + + if (table->field[FLD_ISO_LEVEL]->type() != MYSQL_TYPE_STRING || + !(table->field[FLD_ISO_LEVEL]->flags & ENUM_FLAG)) + return true; + + Field_enum *iso_level= static_cast(table->field[FLD_ISO_LEVEL]); + st_typelib *typelib= iso_level->typelib; + + if (typelib->count != 4) + return true; + + if (strcmp(typelib->type_names[0], "READ-UNCOMMITTED") || + strcmp(typelib->type_names[1], "READ-COMMITTED") || + strcmp(typelib->type_names[2], "REPEATABLE-READ") || + strcmp(typelib->type_names[3], "SERIALIZABLE")) + { + return true; + } + + if (!table->key_info || !table->key_info->key_part) + return true; + + if (strcmp(table->key_info->key_part->field->field_name.str, + "transaction_id")) + return true; + + return false; +} + void vers_select_conds_t::resolve_units(bool timestamps_only) { DBUG_ASSERT(type != FOR_SYSTEM_TIME_UNSPECIFIED); diff --git a/sql/table.h b/sql/table.h index 28a3d6c579f..58b656b68ad 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2979,6 +2979,7 @@ public: DBUG_ASSERT(iso_level <= ISO_SERIALIZABLE); store(FLD_ISO_LEVEL, iso_level + 1); } + bool check() const; }; #endif /* MYSQL_CLIENT */