summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-03-24 12:32:45 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2017-03-24 12:32:45 +0200
commit2159ee554073a0b3ec6f9520d3c9ac61565b1704 (patch)
treeb5ed547ef866e3fd294c4aeda36ba8b495964851
parent245979f5e02303b1a8336d13578d1c030af7d685 (diff)
downloadmariadb-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.cc24
-rw-r--r--storage/innobase/row/row0sel.cc10
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 */