[Commits] 2159ee55407: MDEV-10139 Support for InnoDB SEQUENCE objects

marko.makela at mariadb.com marko.makela at mariadb.com
Fri Mar 24 12:52:21 EET 2017


revision-id: 2159ee554073a0b3ec6f9520d3c9ac61565b1704 (mariadb-10.2.2-376-g2159ee55407)
parent(s): 245979f5e02303b1a8336d13578d1c030af7d685
author: Marko Mäkelä
committer: Marko Mäkelä
timestamp: 2017-03-24 12:32:45 +0200
message:

MDEV-10139 Support for InnoDB SEQUENCE objects

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.

---
 storage/innobase/row/row0ins.cc | 24 ++++++++++++++++++++++--
 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 @@ row_ins_step(
 
 		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 @@ row_search_mvcc(
 		/* 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 */


More information about the commits mailing list