List:Internals« Previous MessageNext Message »
From:Jan Lindstrom Date:July 20 2005 8:31am
Subject:bk commit into 5.0 tree (jan:1.1952)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of jan. When jan does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1952 05/07/20 09:30:52 jan@stripped +8 -0
  Added support for consistent cursor views to InnoDB. This patch is associated
  to bugs 11813, 11832, and 11833.

  sql/ha_innodb.h
    1.97 05/07/20 09:30:42 jan@stripped +24 -0
    Added support for consistent cursor views.

  sql/ha_innodb.cc
    1.226 05/07/20 09:30:42 jan@stripped +53 -0
    Added support for consistent cursor views.

  innobase/trx/trx0trx.c
    1.58 05/07/20 09:30:42 jan@stripped +2 -0
    Added support for consistent cursor views.

  innobase/row/row0sel.c
    1.95 05/07/20 09:30:41 jan@stripped +44 -17
    Added support for consistent cursor views.

  innobase/read/read0read.c
    1.7 05/07/20 09:30:41 jan@stripped +120 -0
    Added support for consistent cursor views.

  innobase/include/trx0trx.h
    1.51 05/07/20 09:30:41 jan@stripped +3 -0
    Added consistent cursor to the trx.

  innobase/include/read0types.h
    1.2 05/07/20 09:30:41 jan@stripped +2 -1
    Added cursor view struct.

  innobase/include/read0read.h
    1.4 05/07/20 09:30:41 jan@stripped +30 -0
    Added support for consistent cursor views.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	jan
# Host:	hundin.mysql.fi
# Root:	/home/jan/mysql-5.0

--- 1.3/innobase/include/read0read.h	2002-10-29 23:09:21 +02:00
+++ 1.4/innobase/include/read0read.h	2005-07-20 09:30:41 +03:00
@@ -69,6 +69,29 @@
 /*============*/
 	read_view_t*	view);	/* in: read view */
 
+/*************************************************************************
+Create an consistent cursor view for mysql */
+
+cursor_view_t*
+read_cursor_view_create_for_mysql(
+/*==============================*/
+	trx_t*		cr_trx);/* in: trx where cursor view is created */
+
+/*************************************************************************
+Close an consistent cursor view for mysql */
+
+void
+read_cursor_view_close_for_mysql(
+/*=============================*/
+	cursor_view_t*	cursor);/* in: cursor view to be closed */
+/*************************************************************************
+Set an consistent cursor view to a transaction for mysql */
+
+void 
+read_cursor_set_for_mysql(
+/*======================*/
+	trx_t*		trx,	/* in: transaction where cursor is set */
+	cursor_view_t*	cursor);/* in: consistent cursor view to be set */
 
 /* Read view lists the trx ids of those transactions for which a consistent
 read should not see the modifications to the database. */
@@ -98,6 +121,13 @@
 				NULL if used in purge */
 	UT_LIST_NODE_T(read_view_t) view_list;
 				/* List of read views in trx_sys */
+};
+
+struct cursor_view_struct{
+	mem_heap_t*	cursor_view_heap;
+				/* Memory heap for the cursor view */
+	read_view_t*	cursor_view;	
+				/* Consistent read view of the cursor*/
 };
 
 #ifndef UNIV_NONINL

--- 1.1/innobase/include/read0types.h	2001-02-17 14:19:06 +02:00
+++ 1.2/innobase/include/read0types.h	2005-07-20 09:30:41 +03:00
@@ -9,6 +9,7 @@
 #ifndef read0types_h
 #define read0types_h
 
-typedef struct read_view_struct	read_view_t;
+typedef struct read_view_struct		read_view_t;
+typedef struct cursor_view_struct	cursor_view_t;
 
 #endif

--- 1.50/innobase/include/trx0trx.h	2005-07-01 22:52:49 +03:00
+++ 1.51/innobase/include/trx0trx.h	2005-07-20 09:30:41 +03:00
@@ -605,6 +605,9 @@
 	mem_heap_t*	read_view_heap;	/* memory heap for the read view */
 	read_view_t*	read_view;	/* consistent read view or NULL */
 	/*------------------------------*/
+	cursor_view_t*	cursor;		/* consistent read view and heap 
+					for cursor or NULL */
+	/*------------------------------*/
 	UT_LIST_BASE_NODE_T(trx_named_savept_t) 
 			trx_savepoints;	/* savepoints set with SAVEPOINT ...,
 					oldest first */

--- 1.6/innobase/read/read0read.c	2005-01-16 14:16:09 +02:00
+++ 1.7/innobase/read/read0read.c	2005-07-20 09:30:41 +03:00
@@ -258,3 +258,123 @@
 			(ulong) ut_dulint_get_low(read_view_get_nth_trx_id(view, i)));
 	}
 }
+
+/*************************************************************************
+Create an consistent cursor view for mysql */
+
+cursor_view_t*
+read_cursor_view_create_for_mysql(
+/*==============================*/
+	trx_t*	cr_trx)	/* in: trx where cursor view is created */
+{
+	cursor_view_t*	cursor;
+	read_view_t*	view;
+	trx_t*		trx;
+	ulint		n;
+
+	ut_a(cr_trx);
+
+	cursor = mem_alloc(sizeof(cursor_view_t));
+
+	mutex_enter(&kernel_mutex);
+	
+	cursor->cursor_view_heap = mem_heap_create(256);
+	cursor->cursor_view = read_view_create_low(
+				UT_LIST_GET_LEN(trx_sys->trx_list), 
+					cursor->cursor_view_heap);
+
+	cr_trx->cursor = cursor;
+
+	view = cursor->cursor_view;
+	
+	view->creator = cr_trx;
+
+	/* No future transactions should be visible in the view */
+
+  	view->low_limit_no = trx_sys->max_trx_id;
+	view->low_limit_id = view->low_limit_no;
+
+	view->can_be_too_old = FALSE;
+
+	n = 0;
+	trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
+
+	/* No active transaction should be visible, not even cr_trx !*/
+
+	while (trx) {
+                if (trx->conc_state == TRX_ACTIVE ||
+			trx->conc_state == TRX_PREPARED) {
+
+			read_view_set_nth_trx_id(view, n, trx->id);
+
+			n++;
+
+			/* NOTE that a transaction whose trx number is <
+			trx_sys->max_trx_id can still be active, if it is
+			in the middle of its commit! Note that when a
+			transaction starts, we initialize trx->no to
+			ut_dulint_max. */
+
+			if (ut_dulint_cmp(view->low_limit_no, trx->no) > 0) {
+
+				view->low_limit_no = trx->no;
+			}	
+		}
+
+		trx = UT_LIST_GET_NEXT(trx_list, trx);
+	}
+
+	view->n_trx_ids = n;		
+
+	if (n > 0) {
+		/* The last active transaction has the smallest id: */
+		view->up_limit_id = read_view_get_nth_trx_id(view, n - 1);
+	} else {
+		view->up_limit_id = view->low_limit_id;
+	}
+
+	UT_LIST_ADD_FIRST(view_list, trx_sys->view_list, view);
+	
+	mutex_exit(&kernel_mutex);
+
+	return(cursor);
+}
+
+/*************************************************************************
+Close an consistent cursor view for mysql */
+
+void
+read_cursor_view_close_for_mysql(
+/*=============================*/
+	cursor_view_t*	cursor)	/* in: cursor view to be closed */
+{
+	ut_a(cursor && cursor->cursor_view && cursor->cursor_view_heap);
+
+	mutex_enter(&kernel_mutex);
+
+	read_view_close(cursor->cursor_view);
+
+	mutex_exit(&kernel_mutex);
+
+	mem_heap_free(cursor->cursor_view_heap);
+
+	mem_free(cursor);
+}
+	
+/*************************************************************************
+Set an consistent cursor view to a transaction for mysql */
+
+void 
+read_cursor_set_for_mysql(
+/*======================*/
+	trx_t*		trx,	/* in: transaction where cursor is set */
+	cursor_view_t*	cursor)	/* in: consistent cursor view to be set */
+{
+	ut_a(trx && cursor);
+
+	mutex_enter(&kernel_mutex);
+
+	trx->cursor = cursor;
+
+	mutex_exit(&kernel_mutex);
+}

--- 1.94/innobase/row/row0sel.c	2005-07-02 00:39:22 +03:00
+++ 1.95/innobase/row/row0sel.c	2005-07-20 09:30:41 +03:00
@@ -2629,6 +2629,7 @@
 	dict_index_t*	clust_index;
 	rec_t*		clust_rec;
 	rec_t*		old_vers;
+	read_view_t*	view;
 	ulint		err;
 	trx_t*		trx;
 
@@ -2713,22 +2714,30 @@
 		/* If the isolation level allows reading of uncommitted data,
 		then we never look for an earlier version */
 
-		if (trx->isolation_level > TRX_ISO_READ_UNCOMMITTED
-		    && !lock_clust_rec_cons_read_sees(clust_rec, clust_index,
-						*offsets, trx->read_view)) {
+		if (trx->isolation_level > TRX_ISO_READ_UNCOMMITTED) {
 
-			err = row_sel_build_prev_vers_for_mysql(
-					trx->read_view, clust_index,
+			if(trx->cursor) {
+				view = trx->cursor->cursor_view;
+			} else {
+				view = trx->read_view;
+			}
+
+			if(!lock_clust_rec_cons_read_sees(clust_rec,
+						clust_index, *offsets, view)) {
+
+				err = row_sel_build_prev_vers_for_mysql(
+					view, clust_index,
 					prebuilt, clust_rec,
 					offsets, offset_heap,
 					&old_vers, mtr);
 						
-			if (err != DB_SUCCESS) {
+				if (err != DB_SUCCESS) {
 
-				goto err_exit;
-			}
+					goto err_exit;
+				}
 
-			clust_rec = old_vers;
+				clust_rec = old_vers;
+			}
 		}
 
 		/* If we had to go to an earlier version of row or the
@@ -2963,6 +2972,7 @@
 	btr_pcur_t*	pcur		= prebuilt->pcur;
 	trx_t*		trx		= prebuilt->trx;
 	rec_t*		rec;
+	read_view_t*	view;
 	
 	ut_ad(index->type & DICT_CLUSTERED);
 	ut_ad(!prebuilt->templ_contains_blob);
@@ -2997,8 +3007,13 @@
 	*offsets = rec_get_offsets(rec, index, *offsets,
 					ULINT_UNDEFINED, heap);
 
-	if (!lock_clust_rec_cons_read_sees(rec, index,
-				*offsets, trx->read_view)) {
+	if (trx->cursor) {
+		view = trx->cursor->cursor_view;
+	} else {
+		view = trx->read_view;
+	}
+
+	if (!lock_clust_rec_cons_read_sees(rec, index, *offsets, view)) {
 
 		return(SEL_RETRY);
 	}
@@ -3056,6 +3071,7 @@
 	rec_t*		index_rec;
 	rec_t*		clust_rec;
 	rec_t*		old_vers;
+	read_view_t*	view;
 	ulint		err				= DB_SUCCESS;
 	ibool		unique_search			= FALSE;
 	ibool		unique_search_from_clust_index	= FALSE;
@@ -3279,11 +3295,17 @@
 		mode = PAGE_CUR_GE;
 
 		unique_search_from_clust_index = TRUE;
+	
+		if (trx->cursor) {
+			view = trx->cursor->cursor_view;
+		} else {
+			view = trx->read_view;
+		}
 
 		if (trx->mysql_n_tables_locked == 0
 		    && prebuilt->select_lock_type == LOCK_NONE
 		    && trx->isolation_level > TRX_ISO_READ_UNCOMMITTED
-		    && trx->read_view) {
+		    && view) {
 
 			/* This is a SELECT query done as a consistent read,
 			and the read view has already been allocated:
@@ -3440,7 +3462,7 @@
 	if (!prebuilt->sql_stat_start) {
 		/* No need to set an intention lock or assign a read view */
 
-		if (trx->read_view == NULL
+		if (trx->read_view == NULL && trx->cursor == NULL
 		    && prebuilt->select_lock_type == LOCK_NONE) {
 
 			fputs(
@@ -3737,6 +3759,12 @@
 		/* This is a non-locking consistent read: if necessary, fetch
 		a previous version of the record */
 
+		if (trx->cursor) {
+			view = trx->cursor->cursor_view;
+		} else {
+			view = trx->read_view;
+		}
+
 		if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) {
 
 			/* Do nothing: we let a non-locking SELECT read the
@@ -3751,10 +3779,10 @@
 
 			if (UNIV_LIKELY(srv_force_recovery < 5)
                             && !lock_clust_rec_cons_read_sees(rec, index,
-						offsets, trx->read_view)) {
+						offsets, view)) {
 
 				err = row_sel_build_prev_vers_for_mysql(
-						trx->read_view, clust_index,
+						view, clust_index,
 						prebuilt, rec,
 						&offsets, &heap,
 						&old_vers, &mtr);
@@ -3773,8 +3801,7 @@
 
 				rec = old_vers;
 			}
-		} else if (!lock_sec_rec_cons_read_sees(rec, index,
-							trx->read_view)) {
+		} else if (!lock_sec_rec_cons_read_sees(rec, index, view)) {
 			/* We are looking into a non-clustered index,
 			and to get the right version of the record we
 			have to look also into the clustered index: this

--- 1.57/innobase/trx/trx0trx.c	2005-07-01 20:43:58 +03:00
+++ 1.58/innobase/trx/trx0trx.c	2005-07-20 09:30:42 +03:00
@@ -162,6 +162,8 @@
 	trx->read_view_heap = mem_heap_create(256);
 	trx->read_view = NULL;
 
+	trx->cursor = NULL;
+
 	/* Set X/Open XA transaction identification to NULL */
 	memset(&trx->xid, 0, sizeof(trx->xid));
 	trx->xid.formatID = -1;

--- 1.225/sql/ha_innodb.cc	2005-07-06 09:38:21 +03:00
+++ 1.226/sql/ha_innodb.cc	2005-07-20 09:30:42 +03:00
@@ -129,6 +129,7 @@
 #include "../innobase/include/sync0sync.h"
 #include "../innobase/include/fil0fil.h"
 #include "../innobase/include/trx0xa.h"
+#include "../innobase/include/read0read.h"
 }
 
 #define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
@@ -7106,6 +7107,58 @@
 	} else {
 		return(XAER_NOTA);
 	}
+}
+
+/***********************************************************************
+This function creates an consistent cursor view. */
+
+void*
+innobase_create_cursor_view(void)
+/*=============================*/
+			/* out: Pointer to cursor view or NULL */
+{
+	THD*	thd;
+        trx_t* 	trx;
+
+	thd = (THD *)innobase_current_thd();
+	trx = check_trx_exists(thd);
+
+	return((void *)read_cursor_view_create_for_mysql(trx));
+}
+
+/***********************************************************************
+This function closes the consistent cursor view */
+
+void
+innobase_close_cursor_view(
+/*=======================*/
+	void*	cursor)	/* in: Consistent read view to be closed */
+{
+	cursor_view_t* cursor_view = (cursor_view_t*)cursor;
+
+	ut_a(cursor_view);
+
+	read_cursor_view_close_for_mysql(cursor_view);
+}
+
+/***********************************************************************
+This function sets the consistent cursor view to a transaction */
+
+void
+innobase_set_cursor_view(
+/*=====================*/
+	void*	cursor)	/* in: Consistent cursor view to be closed */
+{
+	trx_t*		trx;
+	THD*		thd;
+	cursor_view_t* 	cursor_view = (cursor_view_t*)cursor;
+
+	ut_a(cursor_view);
+
+	thd = (THD *)innobase_current_thd();
+	trx = check_trx_exists(thd);
+
+	read_cursor_set_for_mysql(trx, cursor_view);
 }
 
 #endif /* HAVE_INNOBASE_DB */

--- 1.96/sql/ha_innodb.h	2005-06-21 07:36:03 +03:00
+++ 1.97/sql/ha_innodb.h	2005-07-20 09:30:42 +03:00
@@ -322,3 +322,27 @@
 
 int innobase_repl_report_sent_binlog(THD *thd, char *log_file_name,
                                my_off_t end_offset);
+
+/***********************************************************************
+This function creates an consistent cursor view. */
+
+void*
+innobase_create_cursor_view(void);
+/*=============================*/
+			/* out: Pointer to cursor view or NULL */
+
+/***********************************************************************
+This function closes the consistent cursor view */
+
+void
+innobase_close_cursor_view(
+/*=======================*/
+	void*	cursor);/* in: Consistent read view to be closed */
+
+/***********************************************************************
+This function sets the consistent cursor view to a transaction */
+
+void
+innobase_set_cursor_view(
+/*=====================*/
+	void*	cursor);/* in: Consistent read view to be closed */
Thread
bk commit into 5.0 tree (jan:1.1952)Jan Lindstrom20 Jul