diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2017-03-24 12:32:45 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2017-03-24 12:32:45 +0200 |
commit | 2159ee554073a0b3ec6f9520d3c9ac61565b1704 (patch) | |
tree | b5ed547ef866e3fd294c4aeda36ba8b495964851 | |
parent | 245979f5e02303b1a8336d13578d1c030af7d685 (diff) | |
download | mariadb-git-10.3-sequence.tar.gz |
MDEV-10139 Support for InnoDB SEQUENCE objects10.3-sequence
Minor optimizations. The previous commit actually worked, but
it unnecessarily allocated a DB_ROW_ID for the single inserted
row at CREATE SEQUENCE. After the initial insert of the single
record, we will be updating the single record in-place. This is
crash-safe thanks to the redo log.
When it comes to the durability of the updates of SEQUENCE in
InnoDB, there is a clear analogy to MDEV-6076 Persistent AUTO_INCREMENT.
The updates would be made persistent by the InnoDB redo log flush
at transaction commit, provided that innodb_log_flush_at_trx_commit=1.
Similar to AUTO_INCREMENT, it is possible that the update of a SEQUENCE
in a middle of transaction becomes durable before the COMMIT/ROLLBACK of
the transaction, in case the InnoDB redo log is being flushed as a result
of the a commit or rollback of some other transaction, or as a result of
a redo log checkpoint that can be initiated at any time by operations that
are writing redo log.
row_ins_step(): Assign 0 to DB_ROW_ID and DB_TRX_ID, and skip
any locking for no-rollback tables. There will be only a single row
in no-rollback tables (or there must be a proper PRIMARY KEY).
row_search_mvcc(): Execute the READ UNCOMMITTED code path for
no-rollback tables.
-rw-r--r-- | storage/innobase/row/row0ins.cc | 24 | ||||
-rw-r--r-- | storage/innobase/row/row0sel.cc | 10 |
2 files changed, 28 insertions, 6 deletions
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index d2d938d7757..f596f3d8f27 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -3703,7 +3703,27 @@ row_ins_step( table during the search operation, and there is no need to set it again here. But we must write trx->id to node->trx_id_buf. */ - memset(node->trx_id_buf, 0, DATA_TRX_ID_LEN); + if (node->table->no_rollback()) { + /* No-rollback tables should only be accessed by a + single thread at a time. Concurrency control (mutual + exclusion) must be guaranteed by the SQL layer. */ + DBUG_ASSERT(node->table->n_ref_count == 1); + DBUG_ASSERT(node->ins_type == INS_DIRECT); + /* No-rollback tables can consist only of a single index. */ + DBUG_ASSERT(UT_LIST_GET_LEN(node->entry_list) == 1); + DBUG_ASSERT(UT_LIST_GET_LEN(node->table->indexes) == 1); + /* There should be no possibility for interruption and + restarting here. In theory, we could allow resumption + from the INS_NODE_INSERT_ENTRIES state here. */ + DBUG_ASSERT(node->state == INS_NODE_SET_IX_LOCK); + memset(node->trx_id_buf, 0, DATA_TRX_ID_LEN); + memset(node->row_id_buf, 0, DATA_ROW_ID_LEN); + node->index = dict_table_get_first_index(node->table); + node->entry = UT_LIST_GET_FIRST(node->entry_list); + node->state = INS_NODE_INSERT_ENTRIES; + goto do_insert; + } + trx_write_trx_id(node->trx_id_buf, trx->id); if (node->state == INS_NODE_SET_IX_LOCK) { @@ -3753,7 +3773,7 @@ same_trx: return(thr); } - +do_insert: /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */ err = row_ins(node, thr); diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 229bd567c48..106845f73fa 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4130,9 +4130,10 @@ row_search_mvcc( ulint direction) { DBUG_ENTER("row_search_mvcc"); + DBUG_ASSERT(prebuilt->index->table == prebuilt->table); dict_index_t* index = prebuilt->index; - ibool comp = dict_table_is_comp(index->table); + ibool comp = dict_table_is_comp(prebuilt->table); const dtuple_t* search_tuple = prebuilt->search_tuple; btr_pcur_t* pcur = prebuilt->pcur; trx_t* trx = prebuilt->trx; @@ -4514,7 +4515,7 @@ row_search_mvcc( que_thr_move_to_run_state_for_mysql(thr, trx); - clust_index = dict_table_get_first_index(index->table); + clust_index = dict_table_get_first_index(prebuilt->table); /* Do some start-of-statement preparations */ @@ -4543,7 +4544,7 @@ row_search_mvcc( prebuilt->sql_stat_start = FALSE; } else { wait_table_again: - err = lock_table(0, index->table, + err = lock_table(0, prebuilt->table, prebuilt->select_lock_type == LOCK_S ? LOCK_IS : LOCK_IX, thr); @@ -5072,7 +5073,8 @@ no_gap_lock: /* This is a non-locking consistent read: if necessary, fetch a previous version of the record */ - if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) { + if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED + || prebuilt->table->no_rollback()) { /* Do nothing: we let a non-locking SELECT read the latest version of the record */ |