commit d80207e743b4691a2f687b6ad2bf8be3b21515b8
Author: Laurynas Biveinis <laurynas.biveinis@gmail.com>
Date:   Thu Jun 1 17:10:45 2017 +0300

    Fix bug 77399 / 1466414 (Deadlocks missed by INFORMATION_SCHEMA.INNODB_METRICS lock_deadlocks counter)
    
    In case the joining transaction is selected as the deadlock victim,
    the InnoDB metrics deadlock counter will not be bumped. Fix by adding
    a bump there, and removing the bump in the search-too-deep code path
    to compensate for this case.

diff --git a/mysql-test/suite/innodb/r/innodb_deadlock_count.result b/mysql-test/suite/innodb/r/innodb_deadlock_count.result
new file mode 100644
index 00000000000..3a88f9be334
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_deadlock_count.result
@@ -0,0 +1,32 @@
+#
+# Bug 77399: Deadlocks missed by INFORMATION_SCHEMA.INNODB_METRICS lock_deadlocks counter
+#
+# Establish connection con1 (user=root)
+# Establish connection con2 (user=root)
+# Create test table
+create table t(a INT PRIMARY KEY, b INT) engine=InnoDB;
+# Insert two rows to test table
+insert into t values(2,1);
+insert into t values(1,2);
+SELECT COUNT INTO @start_metrics_val
+FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME='lock_deadlocks';
+# Switch to connection con1
+BEGIN;
+SELECT b FROM t WHERE a=1 FOR UPDATE;
+# Switch to connection con2
+BEGIN;
+SELECT b FROM t WHERE a=2 FOR UPDATE;
+# Switch to connection con1
+SELECT b FROM t WHERE a=2 FOR UPDATE;
+# Switch to connection con2
+SELECT b FROM t WHERE a=1 FOR UPDATE;
+# Switch to connection con1
+ROLLBACK;
+# Switch to connection con2
+ROLLBACK;
+# Switch to connection default
+SELECT COUNT INTO @lock_deadlocks_var FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME='lock_deadlocks';
+include/assert.inc [Exactly one deadlock should have been found]
+# Drop test table
+drop table t;
+SET GLOBAL innodb_monitor_reset = default;
diff --git a/mysql-test/suite/innodb/t/innodb_deadlock_count.test b/mysql-test/suite/innodb/t/innodb_deadlock_count.test
new file mode 100644
index 00000000000..3b7c3e2feff
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_deadlock_count.test
@@ -0,0 +1,71 @@
+--echo #
+--echo # Bug 77399: Deadlocks missed by INFORMATION_SCHEMA.INNODB_METRICS lock_deadlocks counter
+--echo #
+
+--source include/count_sessions.inc
+
+--echo # Establish connection con1 (user=root)
+connect (con1,localhost,root,,);
+--echo # Establish connection con2 (user=root)
+connect (con2,localhost,root,,);
+
+--echo # Create test table
+create table t(a INT PRIMARY KEY, b INT) engine=InnoDB;
+--echo # Insert two rows to test table
+insert into t values(2,1);
+insert into t values(1,2);
+
+connection default;
+SELECT COUNT INTO @start_metrics_val
+       FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME='lock_deadlocks';
+
+--disable_result_log
+
+--echo # Switch to connection con1
+connection con1;
+BEGIN; SELECT b FROM t WHERE a=1 FOR UPDATE;
+
+--echo # Switch to connection con2
+connection con2;
+BEGIN; SELECT b FROM t WHERE a=2 FOR UPDATE;
+
+--echo # Switch to connection con1
+connection con1;
+SEND SELECT b FROM t WHERE a=2 FOR UPDATE;
+
+--echo # Switch to connection con2
+connection con2;
+SEND SELECT b FROM t WHERE a=1 FOR UPDATE;
+
+--echo # Switch to connection con1
+connection con1;
+--error 0, ER_LOCK_DEADLOCK
+reap;
+ROLLBACK;
+
+--echo # Switch to connection con2
+connection con2;
+--error 0, ER_LOCK_DEADLOCK
+reap;
+ROLLBACK;
+
+--echo # Switch to connection default
+connection default;
+--enable_result_log
+
+--disconnect con1
+--disconnect con2
+
+SELECT COUNT INTO @lock_deadlocks_var FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME='lock_deadlocks';
+--let $assert_text= Exactly one deadlock should have been found
+--let $assert_cond= @lock_deadlocks_var - @start_metrics_val = 1
+--source include/assert.inc
+
+--echo # Drop test table
+drop table t;
+
+--disable_warnings
+SET GLOBAL innodb_monitor_reset = default;
+--enable_warnings
+
+--source include/wait_until_count_sessions.inc
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index eed5b6b8eb3..c9a197ece37 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -7489,8 +7489,6 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx)
 
 			rollback_print(victim_trx, lock);
 
-			MONITOR_INC(MONITOR_DEADLOCK);
-
 			break;
 
 		} else if (victim_trx != NULL && victim_trx != trx) {
@@ -7512,6 +7510,8 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx)
 		print("*** WE ROLL BACK TRANSACTION (2)\n");
 
 		lock_deadlock_found = true;
+
+		MONITOR_INC(MONITOR_DEADLOCK);
 	}
 
 	trx_mutex_enter(trx);