diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index df48a8a4b5a508194c36b556f992af828a1f58e1..33aebb250711f71e5198914776909283f3079df8 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -2139,9 +2139,12 @@ dict_foreign_find_index(
 	ulint		n_cols,	/* in: number of columns */
 	dict_index_t*	types_idx, /* in: NULL or an index to whose types the
 				   column types must match */
-	ibool		check_charsets)	/* in: whether to check charsets.
+	ibool		check_charsets,	/* in: whether to check charsets.
 					only has an effect if types_idx !=
 					NULL. */
+	ulint		check_null)
+				/* in: nonzero if none of the columns must
+				be declared NOT NULL */
 {
 #ifndef UNIV_HOTBACKUP
 	dict_index_t*	index;
@@ -2154,10 +2157,11 @@ dict_foreign_find_index(
 		if (dict_index_get_n_fields(index) >= n_cols) {
 
 			for (i = 0; i < n_cols; i++) {
-				col_name = dict_index_get_nth_field(index, i)
-							->col->name;
-				if (dict_index_get_nth_field(index, i)
-						->prefix_len != 0) {
+				dict_field_t*	field
+					= dict_index_get_nth_field(index, i);
+
+				col_name = field->col->name;
+				if (field->prefix_len != 0) {
 					/* We do not accept column prefix
 					indexes here */
 					
@@ -2169,6 +2173,13 @@ dict_foreign_find_index(
 				  	break;
 				}
 
+				if (check_null
+				    && (field->col->type.prtype
+					& DATA_NOT_NULL)) {
+
+					return(NULL);
+				}
+
 				if (types_idx && !cmp_types_are_equal(
 				     dict_index_get_nth_type(index, i),
 				     dict_index_get_nth_type(types_idx, i),
@@ -2290,7 +2301,7 @@ dict_foreign_add_to_cache(
 		index = dict_foreign_find_index(ref_table,
 			(const char**) for_in_cache->referenced_col_names,
 			for_in_cache->n_fields,
-			for_in_cache->foreign_index, check_charsets);
+			for_in_cache->foreign_index, check_charsets, FALSE);
 
 		if (index == NULL) {
 			dict_foreign_error_report(ef, for_in_cache,
@@ -2317,13 +2328,17 @@ dict_foreign_add_to_cache(
 		index = dict_foreign_find_index(for_table,
 			(const char**) for_in_cache->foreign_col_names,
 			for_in_cache->n_fields,
-			for_in_cache->referenced_index, check_charsets);
+			for_in_cache->referenced_index, check_charsets,
+			for_in_cache->type
+			& (DICT_FOREIGN_ON_DELETE_SET_NULL
+			   | DICT_FOREIGN_ON_UPDATE_SET_NULL));
 
 		if (index == NULL) {
 			dict_foreign_error_report(ef, for_in_cache,
 "there is no index in the table which would contain\n"
 "the columns as the first columns, or the data types in the\n"
-"table do not match to the ones in the referenced table.");
+"table do not match to the ones in the referenced table\n"
+"or one of the ON ... SET NULL columns is declared NOT NULL.");
 
 			if (for_in_cache == foreign) {
 				if (added_to_referenced_list) {
@@ -3125,7 +3140,8 @@ dict_create_foreign_constraints_low(
 	/* Try to find an index which contains the columns
 	as the first fields and in the right order */
 
-	index = dict_foreign_find_index(table, column_names, i, NULL, TRUE);
+	index = dict_foreign_find_index(table, column_names, i,
+					NULL, TRUE, FALSE);
 
 	if (!index) {
 		mutex_enter(&dict_foreign_err_mutex);
@@ -3390,7 +3406,7 @@ dict_create_foreign_constraints_low(
 
 	if (referenced_table) {
 		index = dict_foreign_find_index(referenced_table,
-			column_names, i, foreign->foreign_index, TRUE);
+			column_names, i, foreign->foreign_index, TRUE, FALSE);
 		if (!index) {
 			dict_foreign_free(foreign);
 			mutex_enter(&dict_foreign_err_mutex);
diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic
index 9c24f385f4fffe3ee91b13df5fec4da1b54457ef..1abbb503bab151ba541b4136440362621d762fbe 100644
--- a/innobase/include/rem0rec.ic
+++ b/innobase/include/rem0rec.ic
@@ -982,6 +982,9 @@ rec_offs_nth_size(
 {
 	ut_ad(rec_offs_validate(NULL, NULL, offsets));
 	ut_ad(n < rec_offs_n_fields(offsets));
+	if (!n) {
+		return(rec_offs_base(offsets)[1 + n] & REC_OFFS_MASK);
+	}
 	return((rec_offs_base(offsets)[1 + n] - rec_offs_base(offsets)[n])
 			& REC_OFFS_MASK);
 }
diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic
index a32a82d6e8b0cd5fdcbd6b1a9099b36c132b1125..e5c6f56d8ba19049f767e59f33200d798241e230 100644
--- a/innobase/include/sync0sync.ic
+++ b/innobase/include/sync0sync.ic
@@ -6,6 +6,16 @@ Mutex, the basic synchronization primitive
 Created 9/5/1995 Heikki Tuuri
 *******************************************************/
 
+#if defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
+/* %z0: Use the size of operand %0 which in our case is *m to determine
+instruction size, it should end up as xchgl. "1" in the input constraint,
+says that "in" has to go in the same place as "out".*/
+#define TAS(m, in, out) \
+	asm volatile ("xchg%z0 %2, %0" \
+	: "=g" (*(m)), "=r" (out) \
+	: "1" (in))	/* Note: "1" here refers to "=r" (out) */
+#endif
+
 /**********************************************************************
 Sets the waiters field in a mutex. */
 
@@ -85,20 +95,10 @@ mutex_test_and_set(
 
 	return(res);
 #elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
-	ulint*	lw;
 	ulint	res;
 
-	lw = &(mutex->lock_word);
-
-	/* In assembly we use the so-called AT & T syntax where
-	the order of operands is inverted compared to the ordinary Intel
-	syntax. The 'l' after the mnemonics denotes a 32-bit operation.
-	The line after the code tells which values come out of the asm
-	code, and the second line tells the input to the asm code. */
+	TAS(&mutex->lock_word, 1, res);
 
-	asm volatile("movl $1, %%eax; xchgl (%%ecx), %%eax" :
-	              "=eax" (res), "=m" (*lw) :
-	              "ecx" (lw));
 	return(res);
 #else
 	ibool	ret;
@@ -137,20 +137,9 @@ mutex_reset_lock_word(
         __asm   MOV     ECX, lw
         __asm   XCHG    EDX, DWORD PTR [ECX]                    
 #elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86)
-	ulint*	lw;
-
-	lw = &(mutex->lock_word);
-
-	/* In assembly we use the so-called AT & T syntax where
-	the order of operands is inverted compared to the ordinary Intel
-	syntax. The 'l' after the mnemonics denotes a 32-bit operation. */
+	ulint	res;
 
-	asm volatile("movl $0, %%eax; xchgl (%%ecx), %%eax" :
-	              "=m" (*lw) :
-	              "ecx" (lw) :
-		      "eax");	/* gcc does not seem to understand
-				that our asm code resets eax: tell it
-				explicitly that after the third ':' */
+	TAS(&mutex->lock_word, 0, res);
 #else
 	mutex->lock_word = 0;
 
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 06475c8ef7e9591dfcc9025500912ffca5607f9f..77dfca5fdf4ccc84da3dfeeaafa16903480dac6c 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -3259,12 +3259,6 @@ lock_deadlock_recursive(
 
 	*cost = *cost + 1;
 
-	if ((depth > LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK)
-		|| (*cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK)) {
-
-		return(LOCK_VICTIM_IS_START);
-	}
-
 	lock = wait_lock;
 
 	if (lock_get_type(wait_lock) == LOCK_REC) {
@@ -3296,11 +3290,18 @@ lock_deadlock_recursive(
 
 		if (lock_has_to_wait(wait_lock, lock)) {
 
+			ibool	too_far
+				= depth > LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK
+				|| *cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK;
+
 			lock_trx = lock->trx;
 
-			if (lock_trx == start) {
+			if (lock_trx == start || too_far) {
+
 				/* We came back to the recursion starting
-				point: a deadlock detected */
+				point: a deadlock detected; or we have
+				searched the waits-for graph too long */
+
 				FILE*	ef = lock_latest_err_file;
 				
 				rewind(ef);
@@ -3342,9 +3343,20 @@ lock_deadlock_recursive(
 				}
 #ifdef UNIV_DEBUG
 				if (lock_print_waits) {
-					fputs("Deadlock detected\n", stderr);
+					fputs("Deadlock detected"
+					      " or too long search\n",
+					      stderr);
 				}
 #endif /* UNIV_DEBUG */
+				if (too_far) {
+
+					fputs("TOO DEEP OR LONG SEARCH"
+					      " IN THE LOCK TABLE"
+					      " WAITS-FOR GRAPH\n", ef);
+
+					return(LOCK_VICTIM_IS_START);
+				}
+
 				if (ut_dulint_cmp(wait_lock->trx->undo_no,
 							start->undo_no) >= 0) {
 					/* Our recursion starting point
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index fe9e08d65bed11d895c9a4d0974b5c2246053a48..96c0f05111b71d1bedd924a47e3203698345c679 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -1822,14 +1822,14 @@ srv_export_innodb_status(void)
         export_vars.innodb_pages_written= buf_pool->n_pages_written;
         export_vars.innodb_row_lock_waits= srv_n_lock_wait_count;
         export_vars.innodb_row_lock_current_waits= srv_n_lock_wait_current_count;
-        export_vars.innodb_row_lock_time= srv_n_lock_wait_time / 10000;
+        export_vars.innodb_row_lock_time= srv_n_lock_wait_time / 1000;
 	if (srv_n_lock_wait_count > 0) {
 		export_vars.innodb_row_lock_time_avg = (ulint)
-			(srv_n_lock_wait_time / 10000 / srv_n_lock_wait_count);
+			(srv_n_lock_wait_time / 1000 / srv_n_lock_wait_count);
 	} else {
 		export_vars.innodb_row_lock_time_avg = 0;
 	}
-        export_vars.innodb_row_lock_time_max= srv_n_lock_max_wait_time / 10000;
+        export_vars.innodb_row_lock_time_max= srv_n_lock_max_wait_time / 1000;
         export_vars.innodb_rows_read= srv_n_rows_read;
         export_vars.innodb_rows_inserted= srv_n_rows_inserted;
         export_vars.innodb_rows_updated= srv_n_rows_updated;
diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c
index 1be5939303a06c18db5ad560a051039b29869a4e..feb03269d916cc06983a41317bd01e3afebc73be 100644
--- a/innobase/ut/ut0ut.c
+++ b/innobase/ut/ut0ut.c
@@ -20,6 +20,55 @@ Created 5/11/1994 Heikki Tuuri
 
 ibool	ut_always_false	= FALSE;
 
+#ifdef __WIN__
+/*********************************************************************
+NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
+epoch starts from 1970/1/1. For selection of constant see:
+http://support.microsoft.com/kb/167296/ */
+#define WIN_TO_UNIX_DELTA_USEC  ((ib_longlong) 11644473600000000ULL)
+
+
+/*********************************************************************
+This is the Windows version of gettimeofday(2).*/
+static
+int
+ut_gettimeofday(
+/*============*/
+				/* out: 0 if all OK else -1 */
+	struct timeval*	tv,	/* out: Values are relative to Unix epoch */
+	void*		tz)	/* in: not used */
+{
+	FILETIME	ft;
+	ib_longlong	tm;
+
+	if (!tv) {
+		errno = EINVAL;
+		return(-1);
+	}
+
+	GetSystemTimeAsFileTime(&ft);
+
+	tm = (ib_longlong) ft.dwHighDateTime << 32;
+	tm |= ft.dwLowDateTime;
+
+	ut_a(tm >= 0);	/* If tm wraps over to negative, the quotient / 10
+			does not work */
+
+	tm /= 10;	/* Convert from 100 nsec periods to usec */
+
+	/* If we don't convert to the Unix epoch the value for
+	struct timeval::tv_sec will overflow.*/
+	tm -= WIN_TO_UNIX_DELTA_USEC;
+
+	tv->tv_sec  = (long) (tm / 1000000L);
+	tv->tv_usec = (long) (tm % 1000000L);
+
+	return(0);
+}
+#else
+#define	ut_gettimeofday		gettimeofday
+#endif
+
 /*********************************************************************
 Get the quote character to be used in SQL identifiers.
 This definition must match the one in sql/ha_innodb.cc! */
@@ -82,17 +131,11 @@ ut_usectime(
 	ulint*	sec,	/* out: seconds since the Epoch */
 	ulint*	ms)	/* out: microseconds since the Epoch+*sec */
 {
-#ifdef __WIN__
-	SYSTEMTIME st;
-	GetLocalTime(&st);
-	*sec = (ulint) st.wSecond;
-	*ms  = (ulint) st.wMilliseconds;
-#else
 	struct timeval	tv;
-	gettimeofday(&tv,NULL);
+
+	ut_gettimeofday(&tv, NULL);
 	*sec = (ulint) tv.tv_sec;
 	*ms  = (ulint) tv.tv_usec;
-#endif
 }
 
 /**************************************************************
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 99f0d4100eef478166776db062062d94c3774dd1..0638152ba425dd5e9e07ccbf493731ce71e33022 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -2968,3 +2968,21 @@ a
 drop table t2, t1;
 create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
 ERROR HY000: The used table type doesn't support SPATIAL indexes
+CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL;
+ALTER TABLE t2 MODIFY a INT NOT NULL;
+ERROR HY000: Error on rename of '#sql-temporary' to './test/t2' (errno: 150)
+DELETE FROM t1;
+DROP TABLE t2,t1;
+CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY)
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4);
+DELETE FROM t1;
+INSERT INTO t1 VALUES ('DDD');
+SELECT * FROM t1;
+a
+DDD
+DROP TABLE t1;
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index aa25677bd998c89d9d46d197dc4c925d3c9002d1..e762d740d667a8b427bf210f0fc8cd66b79219c2 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -1976,6 +1976,34 @@ drop table t2, t1;
 --error ER_TABLE_CANT_HANDLE_SPKEYS
 create table t1 (g geometry not null, spatial gk(g)) engine=innodb;
 
+#
+# Bug #25927: Prevent ALTER TABLE ... MODIFY ... NOT NULL on columns
+# for which there is a foreign key constraint ON ... SET NULL.
+#
+
+CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL;
+--replace_regex /'\.\/test\/#sql-[0-9a-f_]*'/'#sql-temporary'/
+--error 1025
+ALTER TABLE t2 MODIFY a INT NOT NULL;
+DELETE FROM t1;
+DROP TABLE t2,t1;
+
+#
+# Bug #26835: table corruption after delete+insert
+#
+
+CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY)
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4);
+DELETE FROM t1;
+INSERT INTO t1 VALUES ('DDD');
+SELECT * FROM t1;
+DROP TABLE t1;
+
 #######################################################################
 #                                                                     #
 # Please, DO NOT TOUCH this file as well as the innodb.result file.   #
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index cbefa9d39493bac0479e47552eebdde165f64bac..217f59d4b7ea3ec228db2273e4555b0ba293b572 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -6066,6 +6066,15 @@ ha_innobase::external_lock(
 		        trx->isolation_level = innobase_map_isolation_level(
 						(enum_tx_isolation)
 						thd->variables.tx_isolation);
+
+	                      if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
+				  && trx->global_read_view) {
+
+				/* At low transaction isolation levels we let
+				each consistent read set its own snapshot */
+
+				read_view_close_for_mysql(trx);
+                        }
 		}
 
 		if (trx->isolation_level == TRX_ISO_SERIALIZABLE