Skip to content

Commit 0b89a42

Browse files
dr-mmidenok
authored andcommitted
Remove the flag vers_update_trt
THD::vers_update_trt, trx_t::vers_update_trt, trx_savept_t::vers_update_trt: Remove. Instead, determine from trx_t::mod_tables whether versioned columns were affected by the transaction. handlerton::prepare_commit_versioned: Replaces vers_get_trt_data. Return the transaction start ID and also the commit ID, in case the transaction modified any system-versioned columns (0 if not). TR_table::store_data(): Remove (merge with update() below). TR_table::update(): Add the parameters start_id, end_id. ha_commit_trans(): Remove a condition on SQLCOM_ALTER_TABLE. If we need something special for ALTER TABLE...ALGORITHM=INPLACE, that can be done inside InnoDB by modifying trx_t::mod_tables. innodb_prepare_commit_versioned(): Renamed from innodb_get_trt_data(). Check trx_t::mod_tables to see if any changes to versioned columns are present. trx_mod_table_time_t: A pair of logical timestamps, replacing the undo_no_t in trx_mod_tables_t. Keep track of not only the first modification to a persistent table in each transaction, but also the first modification of a versioned column in a table. dtype_t, dict_col_t: Add the accessor is_any_versioned(), to check if the type refers to a system-versioned user or system column. upd_t::affects_versioned(): Check if an update affects a versioned column. trx_undo_report_row_operation(): If a versioned column is affected by the update, invoke trx_mod_table_time_t::set_versioned(). trx_rollback_to_savepoint_low(): If all changes to versioned columns were rolled back, invoke trx_mod_table_time_t::rollback_versioned(), so that trx_mod_table_time_t::is_versioned() will no longer hold.
1 parent 03fbfee commit 0b89a42

File tree

21 files changed

+185
-138
lines changed

21 files changed

+185
-138
lines changed

mysql-test/suite/versioning/r/alter.result

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,6 @@ add period for system_time(trx_start, trx_end),
344344
add system versioning;
345345
call verify_vtq;
346346
No A B C D
347-
1 1 1 1 1
348347
show create table t;
349348
Table Create Table
350349
t CREATE TABLE `t` (
@@ -362,7 +361,6 @@ No A B C D
362361
alter table t add system versioning, algorithm=copy;
363362
call verify_vtq;
364363
No A B C D
365-
1 1 1 1 1
366364
show create table t;
367365
Table Create Table
368366
t CREATE TABLE `t` (
@@ -415,7 +413,6 @@ No A B C D
415413
alter table t add system versioning, algorithm=inplace;
416414
call verify_vtq;
417415
No A B C D
418-
1 1 1 1 1
419416
show create table t;
420417
Table Create Table
421418
t CREATE TABLE `t` (

sql/handler.cc

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,15 +1414,31 @@ int ha_commit_trans(THD *thd, bool all)
14141414
goto err;
14151415
}
14161416

1417-
if (rw_trans || thd->lex->sql_command == SQLCOM_ALTER_TABLE)
1417+
if (rw_trans && use_transaction_registry)
14181418
{
1419-
if (use_transaction_registry && thd->vers_update_trt)
1419+
ulonglong trx_start_id= 0, trx_end_id= 0;
1420+
for (Ha_trx_info *ha_info= trans->ha_list; ha_info;
1421+
ha_info= ha_info->next())
14201422
{
1423+
if (ulonglong (*prepare)(THD*,ulonglong*)= ha_info->ht()->
1424+
prepare_commit_versioned)
1425+
{
1426+
trx_end_id= prepare(thd, &trx_start_id);
1427+
if (trx_end_id)
1428+
break; // FIXME: use a common ID for cross-engine transactions
1429+
}
1430+
}
1431+
1432+
if (trx_end_id)
1433+
{
1434+
DBUG_ASSERT(trx_start_id);
14211435
TR_table trt(thd, true);
1422-
if (trt.update())
1436+
if (trt.update(trx_start_id, trx_end_id))
14231437
goto err;
1424-
if (all)
1438+
#if 1 // FIXME: fix this properly, and remove TR_table::was_updated()
1439+
if (all) // avoid a crash in versioning.rpl_stmt
14251440
commit_one_phase_2(thd, false, &thd->transaction.stmt, false);
1441+
#endif
14261442
}
14271443
}
14281444

sql/handler.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,6 @@ struct handler_iterator {
980980
class handler;
981981
class group_by_handler;
982982
struct Query;
983-
class TR_table;
984983
typedef class st_select_lex SELECT_LEX;
985984
typedef struct st_order ORDER;
986985

@@ -1390,10 +1389,12 @@ struct handlerton
13901389
/*
13911390
System Versioning
13921391
*/
1393-
/** Fill TRT record for update.
1394-
@param[out] trt TRT table which record[0] will be filled with
1395-
transaction data. */
1396-
void (*vers_get_trt_data)(TR_table &trt);
1392+
/** Determine if system-versioned data was modified by the transaction.
1393+
@param[in,out] thd current session
1394+
@param[out] trx_id transaction start ID
1395+
@return transaction commit ID
1396+
@retval 0 if no system-versioned data was affected by the transaction */
1397+
ulonglong (*prepare_commit_versioned)(THD *thd, ulonglong *trx_id);
13971398
};
13981399

13991400

sql/sql_class.cc

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -710,11 +710,6 @@ extern "C" void thd_kill_timeout(THD* thd)
710710
mysql_mutex_unlock(&thd->LOCK_thd_data);
711711
}
712712

713-
void thd_vers_update_trt(THD * thd, bool value)
714-
{
715-
thd->vers_update_trt= value;
716-
}
717-
718713
THD::THD(my_thread_id id, bool is_wsrep_applier)
719714
:Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION,
720715
/* statement id */ 0),
@@ -1347,8 +1342,6 @@ void THD::init(void)
13471342
wsrep_skip_wsrep_GTID = false;
13481343
#endif /* WITH_WSREP */
13491344

1350-
vers_update_trt = false;
1351-
13521345
if (variables.sql_log_bin)
13531346
variables.option_bits|= OPTION_BIN_LOG;
13541347
else

sql/sql_class.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4565,10 +4565,6 @@ class THD :public Statement,
45654565
/* Handling of timeouts for commands */
45664566
thr_timer_t query_timer;
45674567

4568-
// Storage engine may set this to true is we want to write a row to
4569-
// transaction_registry table on transaction commit.
4570-
bool vers_update_trt;
4571-
45724568
public:
45734569
void set_query_timer()
45744570
{

sql/sql_table.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7442,10 +7442,16 @@ static bool mysql_inplace_alter_table(THD *thd,
74427442

74437443
{
74447444
TR_table trt(thd, true);
7445-
if (thd->vers_update_trt && trt != *table_list)
7445+
if (trt == *table_list || !use_transaction_registry);
7446+
else if (ulonglong (*prepare)(THD*,ulonglong*)= table->file->ht->
7447+
prepare_commit_versioned)
74467448
{
7447-
if (use_transaction_registry && trt.update())
7448-
return true;
7449+
ulonglong trx_start_id, trx_end_id= prepare(thd, &trx_start_id);
7450+
if (trx_end_id && trt.update(trx_start_id, trx_end_id))
7451+
{
7452+
my_error(ER_UNKNOWN_ERROR, MYF(0));
7453+
goto rollback;
7454+
}
74497455
}
74507456

74517457
if (table->file->ha_commit_inplace_alter_table(altered_table,

sql/table.cc

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8525,48 +8525,30 @@ void TR_table::store(uint field_id, timeval ts)
85258525
table->field[field_id]->set_notnull();
85268526
}
85278527

8528-
void TR_table::store_data(ulonglong trx_id, ulonglong commit_id, timeval commit_ts)
8529-
{
8530-
timeval start_time= {static_cast<int>(thd->start_time),
8531-
static_cast<int>(thd->start_time_sec_part)};
8532-
store(FLD_TRX_ID, trx_id);
8533-
store(FLD_COMMIT_ID, commit_id);
8534-
store(FLD_BEGIN_TS, start_time);
8535-
if (thd->start_time_ge(commit_ts.tv_sec, commit_ts.tv_usec))
8536-
{
8537-
thd->start_time_inc();
8538-
commit_ts.tv_sec= thd->start_time;
8539-
commit_ts.tv_usec= thd->start_time_sec_part;
8540-
}
8541-
store(FLD_COMMIT_TS, commit_ts);
8542-
store_iso_level(thd->tx_isolation);
8543-
}
8544-
85458528
enum_tx_isolation TR_table::iso_level() const
85468529
{
85478530
enum_tx_isolation res= (enum_tx_isolation) ((*this)[FLD_ISO_LEVEL]->val_int() - 1);
85488531
DBUG_ASSERT(res <= ISO_SERIALIZABLE);
85498532
return res;
85508533
}
85518534

8552-
bool TR_table::update()
8535+
bool TR_table::update(ulonglong start_id, ulonglong end_id)
85538536
{
85548537
if (!table && open())
85558538
return true;
85568539

8557-
DBUG_ASSERT(table->s);
8558-
handlerton *hton= table->s->db_type();
8559-
DBUG_ASSERT(hton);
8560-
DBUG_ASSERT(hton->flags & HTON_NATIVE_SYS_VERSIONING);
8561-
DBUG_ASSERT(thd->vers_update_trt);
8540+
timeval start_time= {thd->start_time, long(thd->start_time_sec_part)};
8541+
thd->set_current_time();
8542+
timeval end_time= {thd->start_time, long(thd->start_time_sec_part)};
8543+
store(FLD_TRX_ID, start_id);
8544+
store(FLD_COMMIT_ID, end_id);
8545+
store(FLD_BEGIN_TS, start_time);
8546+
store(FLD_COMMIT_TS, end_time);
8547+
store_iso_level(thd->tx_isolation);
85628548

8563-
hton->vers_get_trt_data(*this);
85648549
int error= table->file->ha_write_row(table->record[0]);
85658550
if (error)
8566-
{
85678551
table->file->print_error(error, MYF(0));
8568-
}
8569-
thd->vers_update_trt= false;
85708552
return error;
85718553
}
85728554

sql/table.h

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2983,26 +2983,15 @@ class TR_table: public TABLE_LIST
29832983
*/
29842984
void store(uint field_id, timeval ts);
29852985
/**
2986-
Stores value to internal transaction_registry TABLE object.
2987-
2988-
@param[in] current (InnoDB) transaction id
2989-
@param[in] InnoDB transaction counter at the time of transaction commit
2990-
@param[in] transaction commit timestamp
2991-
*/
2992-
void store_data(ulonglong trx_id, ulonglong commit_id, timeval commit_ts);
2993-
/**
2994-
Writes a row from internal TABLE object to transaction_registry table.
2986+
Update the transaction_registry right before commit.
2987+
@param start_id transaction identifier at start
2988+
@param end_id transaction identifier at commit
29952989
2996-
@retval true on error, false otherwise.
2997-
*/
2998-
bool update();
2999-
/**
3000-
Checks whether a row with specified transaction_id exists in a
3001-
transaction_registry table.
3002-
3003-
@param[in] transacton_id value
3004-
@retval true if exists, false it not exists or an error occured
3005-
*/
2990+
@retval false on success
2991+
@retval true on error (the transaction must be rolled back)
2992+
*/
2993+
bool update(ulonglong start_id, ulonglong end_id);
2994+
// return true if found; false if not found or error
30062995
bool query(ulonglong trx_id);
30072996
/**
30082997
Gets a row from transaction_registry with the closest commit_timestamp to

sql/vtmd.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,13 @@ VTMD_table::update(THD *thd, const char* archive_name)
255255
}
256256

257257
quit:
258-
if (!result && use_transaction_registry)
258+
if (result || !use_transaction_registry);
259+
else if (ulonglong (*prepare)(THD*,ulonglong*)= vtmd.table->file->ht->
260+
prepare_commit_versioned)
259261
{
260-
DBUG_ASSERT(thd->vers_update_trt);
261262
TR_table trt(thd, true);
262-
result= trt.update();
263+
ulonglong trx_start_id, trx_end_id= prepare(thd, &trx_start_id);
264+
result= trx_end_id && trt.update(trx_start_id, trx_end_id);
263265
}
264266

265267
close_log_table(thd, &open_tables_backup);

storage/innobase/handler/ha_innodb.cc

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3623,22 +3623,37 @@ static const char* ha_innobase_exts[] = {
36233623
NullS
36243624
};
36253625

3626-
void innodb_get_trt_data(TR_table& trt) {
3627-
THD* thd = trt.get_thd();
3628-
trx_t* trx = thd_to_trx(thd);
3629-
ut_a(trx);
3630-
ut_a(trx->vers_update_trt);
3631-
mutex_enter(&trx_sys->mutex);
3632-
trx_id_t commit_id = trx_sys_get_new_trx_id();
3633-
ulint sec = 0;
3634-
ulint usec = 0;
3635-
ut_usectime(&sec, &usec);
3636-
mutex_exit(&trx_sys->mutex);
3626+
/** Determine if system-versioned data was modified by the transaction.
3627+
@param[in,out] thd current session
3628+
@param[out] trx_id transaction start ID
3629+
@return transaction commit ID
3630+
@retval 0 if no system-versioned data was affected by the transaction */
3631+
static ulonglong innodb_prepare_commit_versioned(THD* thd, ulonglong *trx_id)
3632+
{
3633+
if (const trx_t* trx = thd_to_trx(thd)) {
3634+
*trx_id = trx->id;
3635+
3636+
for (trx_mod_tables_t::const_iterator t
3637+
= trx->mod_tables.begin();
3638+
t != trx->mod_tables.end(); t++) {
3639+
if (t->second.is_versioned()) {
3640+
DBUG_ASSERT(t->first->versioned());
3641+
DBUG_ASSERT(trx->undo_no);
3642+
DBUG_ASSERT(trx->rsegs.m_redo.rseg);
3643+
3644+
mutex_enter(&trx_sys->mutex);
3645+
trx_id_t commit_id = trx_sys_get_new_trx_id();
3646+
mutex_exit(&trx_sys->mutex);
3647+
3648+
return commit_id;
3649+
}
3650+
}
3651+
3652+
return 0;
3653+
}
36373654

3638-
// silent downgrade cast warning on win64
3639-
timeval commit_ts = {static_cast<int>(sec), static_cast<int>(usec)};
3640-
trt.store_data(trx->id, commit_id, commit_ts);
3641-
trx->vers_update_trt = false;
3655+
*trx_id = 0;
3656+
return 0;
36423657
}
36433658

36443659
/*********************************************************************//**
@@ -3709,7 +3724,8 @@ innobase_init(
37093724
innobase_hton->table_options = innodb_table_option_list;
37103725

37113726
/* System Versioning */
3712-
innobase_hton->vers_get_trt_data = innodb_get_trt_data;
3727+
innobase_hton->prepare_commit_versioned
3728+
= innodb_prepare_commit_versioned;
37133729

37143730
innodb_remember_check_sysvar_funcs();
37153731

@@ -4894,8 +4910,6 @@ innobase_rollback_to_savepoint(
48944910
dberr_t error = trx_rollback_to_savepoint_for_mysql(
48954911
trx, name, &mysql_binlog_cache_pos);
48964912

4897-
thd_vers_update_trt(thd, trx->vers_update_trt);
4898-
48994913
if (error == DB_SUCCESS && trx->fts_trx != NULL) {
49004914
fts_savepoint_rollback(trx, name);
49014915
}
@@ -8376,10 +8390,6 @@ ha_innobase::write_row(
83768390
/* Step-5: Execute insert graph that will result in actual insert. */
83778391
error = row_insert_for_mysql((byte*) record, m_prebuilt, vers_set_fields);
83788392

8379-
if (m_prebuilt->trx->vers_update_trt) {
8380-
thd_vers_update_trt(m_user_thd, true);
8381-
}
8382-
83838393
DEBUG_SYNC(m_user_thd, "ib_after_row_insert");
83848394

83858395
/* Step-6: Handling of errors related to auto-increment. */
@@ -9199,10 +9209,6 @@ ha_innobase::update_row(
91999209
}
92009210
}
92019211

9202-
if (m_prebuilt->trx->vers_update_trt) {
9203-
thd_vers_update_trt(m_user_thd, true);
9204-
}
9205-
92069212
if (error == DB_SUCCESS && autoinc) {
92079213
/* A value for an AUTO_INCREMENT column
92089214
was specified in the UPDATE statement. */
@@ -9321,10 +9327,6 @@ ha_innobase::delete_row(
93219327

93229328
error = row_update_for_mysql(m_prebuilt, vers_set_fields);
93239329

9324-
if (m_prebuilt->trx->vers_update_trt) {
9325-
thd_vers_update_trt(m_user_thd, true);
9326-
}
9327-
93289330
innobase_srv_conc_exit_innodb(m_prebuilt);
93299331

93309332
/* Tell the InnoDB server that there might be work for

0 commit comments

Comments
 (0)