Commit 72274c10 authored by Aleksey Midenkov's avatar Aleksey Midenkov

SQL: TRT failure fixes [closes #318]

Unclosed stmt transaction
TRT failure in inplace

Related to #305
parent cc6701a7
...@@ -1420,15 +1420,14 @@ int ha_commit_trans(THD *thd, bool all) ...@@ -1420,15 +1420,14 @@ int ha_commit_trans(THD *thd, bool all)
{ {
handlerton *ht= hi->ht(); handlerton *ht= hi->ht();
if ((ht->flags & HTON_NATIVE_SYS_VERSIONING) && if ((ht->flags & HTON_NATIVE_SYS_VERSIONING) &&
thd->lex->sql_command == SQLCOM_ALTER_TABLE ? (thd->lex->sql_command == SQLCOM_ALTER_TABLE ?
hi->is_trx_tmp_read_write() : hi->is_trx_tmp_read_write() :
hi->is_trx_read_write()) hi->is_trx_read_write()))
{ {
TR_table trt(thd, true); TR_table trt(thd, true);
bool updated; if (trt.update())
if (trt.update(updated))
goto err; goto err;
if (updated && all) if (all)
trans_commit_stmt(thd); trans_commit_stmt(thd);
break; break;
} }
...@@ -4301,14 +4300,6 @@ bool handler::ha_commit_inplace_alter_table(TABLE *altered_table, ...@@ -4301,14 +4300,6 @@ bool handler::ha_commit_inplace_alter_table(TABLE *altered_table,
MDL_EXCLUSIVE) || MDL_EXCLUSIVE) ||
!commit); !commit);
if (commit && native_versioned())
{
TR_table trt(ha_thd(), true);
bool updated;
if (trt.update(updated))
return true;
}
return commit_inplace_alter_table(altered_table, ha_alter_info, commit); return commit_inplace_alter_table(altered_table, ha_alter_info, commit);
} }
......
...@@ -7428,6 +7428,14 @@ static bool mysql_inplace_alter_table(THD *thd, ...@@ -7428,6 +7428,14 @@ static bool mysql_inplace_alter_table(THD *thd,
DEBUG_SYNC(thd, "alter_table_inplace_before_commit"); DEBUG_SYNC(thd, "alter_table_inplace_before_commit");
THD_STAGE_INFO(thd, stage_alter_inplace_commit); THD_STAGE_INFO(thd, stage_alter_inplace_commit);
{
TR_table trt(thd, true);
if (table->file->native_versioned())
{
if (trt.update())
return true;
}
if (table->file->ha_commit_inplace_alter_table(altered_table, if (table->file->ha_commit_inplace_alter_table(altered_table,
ha_alter_info, ha_alter_info,
true)) true))
...@@ -7435,6 +7443,9 @@ static bool mysql_inplace_alter_table(THD *thd, ...@@ -7435,6 +7443,9 @@ static bool mysql_inplace_alter_table(THD *thd,
goto rollback; goto rollback;
} }
thd->drop_temporary_table(altered_table, NULL, false);
}
close_all_tables_for_name(thd, table->s, close_all_tables_for_name(thd, table->s,
alter_ctx->is_table_renamed() ? alter_ctx->is_table_renamed() ?
HA_EXTRA_PREPARE_FOR_RENAME : HA_EXTRA_PREPARE_FOR_RENAME :
...@@ -7442,8 +7453,6 @@ static bool mysql_inplace_alter_table(THD *thd, ...@@ -7442,8 +7453,6 @@ static bool mysql_inplace_alter_table(THD *thd,
NULL); NULL);
table_list->table= table= NULL; table_list->table= table= NULL;
thd->drop_temporary_table(altered_table, NULL, false);
/* /*
Replace the old .FRM with the new .FRM, but keep the old name for now. Replace the old .FRM with the new .FRM, but keep the old name for now.
Rename to the new name (if needed) will be handled separately below. Rename to the new name (if needed) will be handled separately below.
......
...@@ -8484,22 +8484,38 @@ LEX_CSTRING *fk_option_name(enum_fk_option opt) ...@@ -8484,22 +8484,38 @@ LEX_CSTRING *fk_option_name(enum_fk_option opt)
return names + opt; return names + opt;
} }
TR_table::TR_table(THD* _thd, bool rw) : thd(_thd) TR_table::TR_table(THD* _thd, bool rw) :
thd(_thd), open_tables_backup(NULL)
{ {
init_one_table(LEX_STRING_WITH_LEN(MYSQL_SCHEMA_NAME), init_one_table(LEX_STRING_WITH_LEN(MYSQL_SCHEMA_NAME),
LEX_STRING_WITH_LEN(TRANSACTION_REG_NAME), LEX_STRING_WITH_LEN(TRANSACTION_REG_NAME),
TRANSACTION_REG_NAME.str, rw ? TL_WRITE : TL_READ); TRANSACTION_REG_NAME.str, rw ? TL_WRITE : TL_READ);
}
bool TR_table::open()
{
DBUG_ASSERT(!table);
open_tables_backup= new Open_tables_backup; open_tables_backup= new Open_tables_backup;
if (open_tables_backup) if (!open_tables_backup)
open_log_table(thd, this, open_tables_backup); {
else
my_error(ER_OUT_OF_RESOURCES, MYF(0)); my_error(ER_OUT_OF_RESOURCES, MYF(0));
return true;
}
All_tmp_tables_list *temporary_tables= thd->temporary_tables;
bool error= !open_log_table(thd, this, open_tables_backup);
thd->temporary_tables= temporary_tables;
return error;
} }
TR_table::~TR_table() TR_table::~TR_table()
{ {
if (table) if (table)
{
thd->temporary_tables= NULL;
close_log_table(thd, open_tables_backup); close_log_table(thd, open_tables_backup);
}
delete open_tables_backup; delete open_tables_backup;
} }
...@@ -8532,9 +8548,9 @@ enum_tx_isolation TR_table::iso_level() const ...@@ -8532,9 +8548,9 @@ enum_tx_isolation TR_table::iso_level() const
return res; return res;
} }
bool TR_table::update(bool &updated) bool TR_table::update()
{ {
if (!table) if (!table && open())
return true; return true;
DBUG_ASSERT(table->s); DBUG_ASSERT(table->s);
...@@ -8542,6 +8558,7 @@ bool TR_table::update(bool &updated) ...@@ -8542,6 +8558,7 @@ bool TR_table::update(bool &updated)
DBUG_ASSERT(hton); DBUG_ASSERT(hton);
DBUG_ASSERT(hton->flags & HTON_NATIVE_SYS_VERSIONING); DBUG_ASSERT(hton->flags & HTON_NATIVE_SYS_VERSIONING);
bool updated;
if ((updated= hton->vers_get_trt_data(*this))) if ((updated= hton->vers_get_trt_data(*this)))
{ {
int error= table->file->ha_write_row(table->record[0]); int error= table->file->ha_write_row(table->record[0]);
...@@ -8557,7 +8574,7 @@ bool TR_table::update(bool &updated) ...@@ -8557,7 +8574,7 @@ bool TR_table::update(bool &updated)
#define newx new (thd->mem_root) #define newx new (thd->mem_root)
bool TR_table::query(ulonglong trx_id) bool TR_table::query(ulonglong trx_id)
{ {
if (!table) if (!table && open())
return false; return false;
SQL_SELECT_auto select; SQL_SELECT_auto select;
READ_RECORD info; READ_RECORD info;
...@@ -8587,7 +8604,7 @@ bool TR_table::query(ulonglong trx_id) ...@@ -8587,7 +8604,7 @@ bool TR_table::query(ulonglong trx_id)
bool TR_table::query(MYSQL_TIME &commit_time, bool backwards) bool TR_table::query(MYSQL_TIME &commit_time, bool backwards)
{ {
if (!table) if (!table && open())
return false; return false;
SQL_SELECT_auto select; SQL_SELECT_auto select;
READ_RECORD info; READ_RECORD info;
...@@ -8684,13 +8701,13 @@ bool TR_table::query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0, ...@@ -8684,13 +8701,13 @@ bool TR_table::query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0,
return false; return false;
} }
bool TR_table::check() const bool TR_table::check()
{ {
// InnoDB may not be loaded // 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; return false;
if (!table) if (open())
return true; return true;
if (table->file->ht->db_type != DB_TYPE_INNODB) if (table->file->ht->db_type != DB_TYPE_INNODB)
......
...@@ -2946,12 +2946,13 @@ class TR_table: public TABLE_LIST ...@@ -2946,12 +2946,13 @@ class TR_table: public TABLE_LIST
FIELD_COUNT FIELD_COUNT
}; };
TR_table(THD *_thd, bool rw= false); TR_table(THD *_thd, bool rw= false);
bool open();
~TR_table(); ~TR_table();
THD *get_thd() const { return thd; } THD *get_thd() const { return thd; }
void store(uint field_id, ulonglong val); void store(uint field_id, ulonglong val);
void store(uint field_id, timeval ts); void store(uint field_id, timeval ts);
void store_data(ulonglong trx_id, ulonglong commit_id, timeval commit_ts); void store_data(ulonglong trx_id, ulonglong commit_id, timeval commit_ts);
bool update(bool &updated); bool update();
// return true if found; false if not found or error // return true if found; false if not found or error
bool query(ulonglong trx_id); bool query(ulonglong trx_id);
bool query(MYSQL_TIME &commit_time, bool backwards); bool query(MYSQL_TIME &commit_time, bool backwards);
...@@ -2979,7 +2980,7 @@ class TR_table: public TABLE_LIST ...@@ -2979,7 +2980,7 @@ 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);
} }
bool check() const; bool check();
}; };
#endif /* MYSQL_CLIENT */ #endif /* MYSQL_CLIENT */
......
...@@ -258,7 +258,7 @@ VTMD_table::update(THD *thd, const char* archive_name) ...@@ -258,7 +258,7 @@ VTMD_table::update(THD *thd, const char* archive_name)
if (!result) if (!result)
{ {
TR_table trt(thd, true); TR_table trt(thd, true);
result= trt.update(result); result= trt.update();
} }
close_log_table(thd, &open_tables_backup); close_log_table(thd, &open_tables_backup);
......
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