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)
{
handlerton *ht= hi->ht();
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_read_write())
hi->is_trx_read_write()))
{
TR_table trt(thd, true);
bool updated;
if (trt.update(updated))
if (trt.update())
goto err;
if (updated && all)
if (all)
trans_commit_stmt(thd);
break;
}
......@@ -4301,14 +4300,6 @@ bool handler::ha_commit_inplace_alter_table(TABLE *altered_table,
MDL_EXCLUSIVE) ||
!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);
}
......
......@@ -7428,11 +7428,22 @@ static bool mysql_inplace_alter_table(THD *thd,
DEBUG_SYNC(thd, "alter_table_inplace_before_commit");
THD_STAGE_INFO(thd, stage_alter_inplace_commit);
if (table->file->ha_commit_inplace_alter_table(altered_table,
ha_alter_info,
true))
{
goto rollback;
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,
ha_alter_info,
true))
{
goto rollback;
}
thd->drop_temporary_table(altered_table, NULL, false);
}
close_all_tables_for_name(thd, table->s,
......@@ -7442,8 +7453,6 @@ static bool mysql_inplace_alter_table(THD *thd,
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.
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)
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),
LEX_STRING_WITH_LEN(TRANSACTION_REG_NAME),
TRANSACTION_REG_NAME.str, rw ? TL_WRITE : TL_READ);
}
bool TR_table::open()
{
DBUG_ASSERT(!table);
open_tables_backup= new Open_tables_backup;
if (open_tables_backup)
open_log_table(thd, this, open_tables_backup);
else
if (!open_tables_backup)
{
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()
{
if (table)
{
thd->temporary_tables= NULL;
close_log_table(thd, open_tables_backup);
}
delete open_tables_backup;
}
......@@ -8532,9 +8548,9 @@ enum_tx_isolation TR_table::iso_level() const
return res;
}
bool TR_table::update(bool &updated)
bool TR_table::update()
{
if (!table)
if (!table && open())
return true;
DBUG_ASSERT(table->s);
......@@ -8542,6 +8558,7 @@ bool TR_table::update(bool &updated)
DBUG_ASSERT(hton);
DBUG_ASSERT(hton->flags & HTON_NATIVE_SYS_VERSIONING);
bool updated;
if ((updated= hton->vers_get_trt_data(*this)))
{
int error= table->file->ha_write_row(table->record[0]);
......@@ -8557,7 +8574,7 @@ bool TR_table::update(bool &updated)
#define newx new (thd->mem_root)
bool TR_table::query(ulonglong trx_id)
{
if (!table)
if (!table && open())
return false;
SQL_SELECT_auto select;
READ_RECORD info;
......@@ -8587,7 +8604,7 @@ bool TR_table::query(ulonglong trx_id)
bool TR_table::query(MYSQL_TIME &commit_time, bool backwards)
{
if (!table)
if (!table && open())
return false;
SQL_SELECT_auto select;
READ_RECORD info;
......@@ -8684,13 +8701,13 @@ bool TR_table::query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0,
return false;
}
bool TR_table::check() const
bool TR_table::check()
{
// InnoDB may not be loaded
if (!ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB))
return false;
if (!table)
if (open())
return true;
if (table->file->ht->db_type != DB_TYPE_INNODB)
......
......@@ -2946,12 +2946,13 @@ class TR_table: public TABLE_LIST
FIELD_COUNT
};
TR_table(THD *_thd, bool rw= false);
bool open();
~TR_table();
THD *get_thd() const { return thd; }
void store(uint field_id, ulonglong val);
void store(uint field_id, timeval 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
bool query(ulonglong trx_id);
bool query(MYSQL_TIME &commit_time, bool backwards);
......@@ -2979,7 +2980,7 @@ class TR_table: public TABLE_LIST
DBUG_ASSERT(iso_level <= ISO_SERIALIZABLE);
store(FLD_ISO_LEVEL, iso_level + 1);
}
bool check() const;
bool check();
};
#endif /* MYSQL_CLIENT */
......
......@@ -258,7 +258,7 @@ VTMD_table::update(THD *thd, const char* archive_name)
if (!result)
{
TR_table trt(thd, true);
result= trt.update(result);
result= trt.update();
}
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