mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
SQL: TRT failure fixes [closes #318]
Unclosed stmt transaction TRT failure in inplace Related to #305
This commit is contained in:
@ -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,
|
|||||||
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,11 +7428,22 @@ 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);
|
||||||
|
|
||||||
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,
|
close_all_tables_for_name(thd, table->s,
|
||||||
@ -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.
|
||||||
|
37
sql/table.cc
37
sql/table.cc
@ -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
|
|||||||
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)
|
|||||||
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)
|
|||||||
#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)
|
|||||||
|
|
||||||
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,
|
|||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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 @@ quit:
|
|||||||
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);
|
||||||
|
Reference in New Issue
Block a user