Commit 5994b687 authored by Aleksey Midenkov's avatar Aleksey Midenkov

Daemon: TRT check doesn't abort [fixes #335]

Added schema check logging messages.
parent 0b40a981
...@@ -1416,7 +1416,7 @@ int ha_commit_trans(THD *thd, bool all) ...@@ -1416,7 +1416,7 @@ int ha_commit_trans(THD *thd, bool all)
if (rw_trans || thd->lex->sql_command == SQLCOM_ALTER_TABLE) if (rw_trans || thd->lex->sql_command == SQLCOM_ALTER_TABLE)
{ {
if (opt_transaction_registry && thd->vers_update_trt) if (use_transaction_registry && thd->vers_update_trt)
{ {
TR_table trt(thd, true); TR_table trt(thd, true);
if (trt.update()) if (trt.update())
......
...@@ -535,6 +535,7 @@ ulong feature_files_opened_with_delayed_keys= 0, feature_check_constraint= 0; ...@@ -535,6 +535,7 @@ ulong feature_files_opened_with_delayed_keys= 0, feature_check_constraint= 0;
ulonglong denied_connections; ulonglong denied_connections;
my_decimal decimal_zero; my_decimal decimal_zero;
my_bool opt_transaction_registry= 1; my_bool opt_transaction_registry= 1;
my_bool use_transaction_registry= 1;
/* /*
Maximum length of parameter value which can be set through Maximum length of parameter value which can be set through
...@@ -6027,25 +6028,35 @@ int mysqld_main(int argc, char **argv) ...@@ -6027,25 +6028,35 @@ int mysqld_main(int argc, char **argv)
if (Events::init((THD*) 0, opt_noacl || opt_bootstrap)) if (Events::init((THD*) 0, opt_noacl || opt_bootstrap))
unireg_abort(1); unireg_abort(1);
if (!opt_bootstrap && opt_transaction_registry) if (opt_transaction_registry)
{
use_transaction_registry= true;
if (opt_bootstrap)
{
use_transaction_registry= false;
}
else
{ {
THD *thd = new THD(0); THD *thd = new THD(0);
thd->thread_stack= (char*) &thd; thd->thread_stack= (char*) &thd;
thd->store_globals(); thd->store_globals();
{ {
TR_table trt(thd); TR_table trt(thd);
if (trt.check()) if (trt.check())
{ {
sql_print_error("%s schema is incorrect", trt.table_name); use_transaction_registry= false;
delete thd;
unireg_abort(1);
} }
} }
trans_commit_stmt(thd); trans_commit_stmt(thd);
delete thd; delete thd;
} }
}
else
use_transaction_registry= false;
if (opt_transaction_registry && !use_transaction_registry)
sql_print_information("Disabled transaction registry.");
if (WSREP_ON) if (WSREP_ON)
{ {
......
...@@ -313,6 +313,7 @@ extern ulong encryption_algorithm; ...@@ -313,6 +313,7 @@ extern ulong encryption_algorithm;
extern const char *encryption_algorithm_names[]; extern const char *encryption_algorithm_names[];
extern const char *quoted_string; extern const char *quoted_string;
extern my_bool opt_transaction_registry; extern my_bool opt_transaction_registry;
extern my_bool use_transaction_registry;
#ifdef HAVE_PSI_INTERFACE #ifdef HAVE_PSI_INTERFACE
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
......
...@@ -7432,7 +7432,7 @@ static bool mysql_inplace_alter_table(THD *thd, ...@@ -7432,7 +7432,7 @@ static bool mysql_inplace_alter_table(THD *thd,
TR_table trt(thd, true); TR_table trt(thd, true);
if (thd->vers_update_trt && trt != *table_list) if (thd->vers_update_trt && trt != *table_list)
{ {
if (opt_transaction_registry && trt.update()) if (use_transaction_registry && trt.update())
return true; return true;
} }
......
...@@ -8699,57 +8699,108 @@ bool TR_table::query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0, ...@@ -8699,57 +8699,108 @@ bool TR_table::query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0,
return false; return false;
} }
void TR_table::warn_schema_incorrect(const char *reason)
{
if (MYSQL_VERSION_ID == table->s->mysql_version)
{
sql_print_error("`%s.%s` schema is incorrect: %s.", db, table_name, reason);
}
else
{
sql_print_error("`%s.%s` schema is incorrect: %s. Created with MariaDB %d, "
"now running %d.", db, table_name, reason, MYSQL_VERSION_ID,
static_cast<int>(table->s->mysql_version));
}
}
bool TR_table::check() bool TR_table::check()
{ {
// InnoDB may not be loaded
if (!ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB)) if (!ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB))
return false; {
sql_print_information("`%s.%s` requires InnoDB storage engine.", db, table_name);
return true;
}
if (open()) if (open())
{
sql_print_warning("`%s.%s` does not exist (open failed).", db, table_name);
return true; return true;
}
if (table->file->ht->db_type != DB_TYPE_INNODB) if (table->file->ht->db_type != DB_TYPE_INNODB)
{
warn_schema_incorrect("Wrong table engine (expected InnoDB)");
return true; return true;
}
#define WARN_SCHEMA(...) \
char reason[128]; \
snprintf(reason, 128, __VA_ARGS__); \
warn_schema_incorrect(reason);
if (table->s->fields != 5) if (table->s->fields != FIELD_COUNT)
{
WARN_SCHEMA("Wrong field count (expected %d)", FIELD_COUNT);
return true; return true;
}
if (table->field[FLD_TRX_ID]->type() != MYSQL_TYPE_LONGLONG) if (table->field[FLD_TRX_ID]->type() != MYSQL_TYPE_LONGLONG)
{
WARN_SCHEMA("Wrong field %d type (expected BIGINT UNSIGNED)", FLD_TRX_ID);
return true; return true;
}
if (table->field[FLD_COMMIT_ID]->type() != MYSQL_TYPE_LONGLONG) if (table->field[FLD_COMMIT_ID]->type() != MYSQL_TYPE_LONGLONG)
{
WARN_SCHEMA("Wrong field %d type (expected BIGINT UNSIGNED)", FLD_COMMIT_ID);
return true; return true;
}
if (table->field[FLD_BEGIN_TS]->type() != MYSQL_TYPE_TIMESTAMP) if (table->field[FLD_BEGIN_TS]->type() != MYSQL_TYPE_TIMESTAMP)
{
WARN_SCHEMA("Wrong field %d type (expected TIMESTAMP(6))", FLD_BEGIN_TS);
return true; return true;
}
if (table->field[FLD_COMMIT_TS]->type() != MYSQL_TYPE_TIMESTAMP) if (table->field[FLD_COMMIT_TS]->type() != MYSQL_TYPE_TIMESTAMP)
{
WARN_SCHEMA("Wrong field %d type (expected TIMESTAMP(6))", FLD_COMMIT_TS);
return true; return true;
}
if (table->field[FLD_ISO_LEVEL]->type() != MYSQL_TYPE_STRING || if (table->field[FLD_ISO_LEVEL]->type() != MYSQL_TYPE_STRING ||
!(table->field[FLD_ISO_LEVEL]->flags & ENUM_FLAG)) !(table->field[FLD_ISO_LEVEL]->flags & ENUM_FLAG))
{
wrong_enum:
WARN_SCHEMA("Wrong field %d type (expected ENUM('READ-UNCOMMITTED', "
"'READ-COMMITTED', 'REPEATABLE-READ', 'SERIALIZABLE'))",
FLD_ISO_LEVEL);
return true; return true;
}
Field_enum *iso_level= static_cast<Field_enum *>(table->field[FLD_ISO_LEVEL]); Field_enum *iso_level= static_cast<Field_enum *>(table->field[FLD_ISO_LEVEL]);
st_typelib *typelib= iso_level->typelib; st_typelib *typelib= iso_level->typelib;
if (typelib->count != 4) if (typelib->count != 4)
return true; goto wrong_enum;
if (strcmp(typelib->type_names[0], "READ-UNCOMMITTED") || if (strcmp(typelib->type_names[0], "READ-UNCOMMITTED") ||
strcmp(typelib->type_names[1], "READ-COMMITTED") || strcmp(typelib->type_names[1], "READ-COMMITTED") ||
strcmp(typelib->type_names[2], "REPEATABLE-READ") || strcmp(typelib->type_names[2], "REPEATABLE-READ") ||
strcmp(typelib->type_names[3], "SERIALIZABLE")) strcmp(typelib->type_names[3], "SERIALIZABLE"))
{ {
return true; goto wrong_enum;
} }
if (!table->key_info || !table->key_info->key_part) if (!table->key_info || !table->key_info->key_part)
return true; goto wrong_pk;
if (strcmp(table->key_info->key_part->field->field_name.str, if (strcmp(table->key_info->key_part->field->field_name.str, "transaction_id"))
"transaction_id")) {
wrong_pk:
WARN_SCHEMA("Wrong PRIMARY KEY (expected `transaction_id`)");
return true; return true;
}
return false; return false;
} }
......
...@@ -2967,6 +2967,8 @@ class TR_table: public TABLE_LIST ...@@ -2967,6 +2967,8 @@ class TR_table: public TABLE_LIST
DBUG_ASSERT(iso_level <= ISO_SERIALIZABLE); DBUG_ASSERT(iso_level <= ISO_SERIALIZABLE);
store(FLD_ISO_LEVEL, iso_level + 1); store(FLD_ISO_LEVEL, iso_level + 1);
} }
void warn_schema_incorrect(const char *reason);
bool check(); bool check();
public: public:
......
...@@ -255,7 +255,7 @@ VTMD_table::update(THD *thd, const char* archive_name) ...@@ -255,7 +255,7 @@ VTMD_table::update(THD *thd, const char* archive_name)
} }
quit: quit:
if (!result && opt_transaction_registry) if (!result && use_transaction_registry)
{ {
DBUG_ASSERT(thd->vers_update_trt); DBUG_ASSERT(thd->vers_update_trt);
TR_table trt(thd, true); TR_table trt(thd, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment