diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index fcc9ed05081594eb18e0812c72f437471cabe3d2..57b91844aca6bb78bcf8197f7cfba5d28def6ddc 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -1009,6 +1009,19 @@ struct trx_t{
 	/*------------------------------*/
 	char detailed_error[256];	/*!< detailed error message for last
 					error, or empty. */
+	/* Lock wait statistics */
+	ulint		n_rec_lock_waits;
+					/*!< Number of record lock waits,
+					might not be exactly correct. */
+	ulint		n_table_lock_waits;
+					/*!< Number of table lock waits,
+					might not be exactly correct. */
+	ulint		total_rec_lock_wait_time;
+					/*!< Total rec lock wait time up
+					to this moment. */
+	ulint		total_table_lock_wait_time;
+					/*!< Total table lock wait time
+					up to this moment. */
 };
 
 /* Transaction isolation levels (trx->isolation_level) */
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 6c6b406e38a769b11dedca272da7a66292240ba6..e41423c0cd38f2f7578e4cb847a48d84129664f4 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -2034,6 +2034,8 @@ lock_rec_enqueue_waiting(
 
 	MONITOR_INC(MONITOR_LOCKREC_WAIT);
 
+	trx->n_rec_lock_waits++;
+
 	return(DB_LOCK_WAIT);
 }
 
@@ -2454,6 +2456,15 @@ lock_grant(
 		}
 	}
 
+	/* Cumulate total lock wait time for statistics */
+	if (lock_get_type_low(lock) & LOCK_TABLE) {
+		lock->trx->total_table_lock_wait_time +=
+			(ulint)difftime(ut_time(), lock->trx->lock.wait_started);
+	} else {
+		lock->trx->total_rec_lock_wait_time +=
+			(ulint)difftime(ut_time(), lock->trx->lock.wait_started);
+	}
+
 	trx_mutex_exit(lock->trx);
 }
 
@@ -4458,6 +4469,7 @@ lock_table_enqueue_waiting(
 
 	trx->lock.wait_started = ut_time();
 	trx->lock.was_chosen_as_deadlock_victim = FALSE;
+	trx->n_table_lock_waits++;
 
 	ut_a(que_thr_stop(thr));
 
@@ -5458,6 +5470,14 @@ loop:
 				trx->read_view->up_limit_id);
 		}
 
+		/* Total trx lock waits and times */
+		fprintf(file, "Trx #rec lock waits %lu #table lock waits %lu\n",
+			trx->n_rec_lock_waits, trx->n_table_lock_waits);
+		fprintf(file, "Trx total rec lock wait time %lu SEC\n",
+			trx->total_rec_lock_wait_time);
+		fprintf(file, "Trx total table lock wait time %lu SEC\n",
+			trx->total_table_lock_wait_time);
+
 		if (trx->lock.que_state == TRX_QUE_LOCK_WAIT) {
 
 			fprintf(file,
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index c97be0e4f0327ee81a4b285c220a90b3d68d5199..fc1871d438e9d93a7db66d442e6dbc149be6b173 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -1,6 +1,7 @@
 /*****************************************************************************
 
 Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, MariaDB Corporation
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -1058,6 +1059,20 @@ struct trx_t{
 #define	DPAH_SIZE	8192
 	byte*		distinct_page_access_hash;
 	ibool		take_stats;
+
+	/* Lock wait statistics */
+	ulint		n_rec_lock_waits;
+					/*!< Number of record lock waits,
+					might not be exactly correct. */
+	ulint		n_table_lock_waits;
+					/*!< Number of table lock waits,
+					might not be exactly correct. */
+	ulint		total_rec_lock_wait_time;
+					/*!< Total rec lock wait time up
+					to this moment. */
+	ulint		total_table_lock_wait_time;
+					/*!< Total table lock wait time
+					up to this moment. */
 };
 
 /* Transaction isolation levels (trx->isolation_level) */
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index 38f74f9845f9066de38b92ba9a0c6dd11bfbf461..bbc19417b68737bf814f01b43620a8c0c7f60f72 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -2055,6 +2055,8 @@ lock_rec_enqueue_waiting(
 
 	MONITOR_INC(MONITOR_LOCKREC_WAIT);
 
+	trx->n_rec_lock_waits++;
+
 	return(DB_LOCK_WAIT);
 }
 
@@ -2474,6 +2476,15 @@ lock_grant(
 		}
 	}
 
+	/* Cumulate total lock wait time for statistics */
+	if (lock_get_type_low(lock) & LOCK_TABLE) {
+		lock->trx->total_table_lock_wait_time +=
+			(ulint)difftime(ut_time(), lock->trx->lock.wait_started);
+	} else {
+		lock->trx->total_rec_lock_wait_time +=
+			(ulint)difftime(ut_time(), lock->trx->lock.wait_started);
+	}
+
 	trx_mutex_exit(lock->trx);
 }
 
@@ -4484,6 +4495,7 @@ lock_table_enqueue_waiting(
 
 	trx->lock.wait_started = ut_time();
 	trx->lock.was_chosen_as_deadlock_victim = FALSE;
+	trx->n_table_lock_waits++;
 
 	if (UNIV_UNLIKELY(trx->take_stats)) {
 		ut_usectime(&sec, &ms);
@@ -5495,6 +5507,14 @@ loop:
 				trx->read_view->up_limit_id);
 		}
 
+		/* Total trx lock waits and times */
+		fprintf(file, "Trx #rec lock waits %lu #table lock waits %lu\n",
+			trx->n_rec_lock_waits, trx->n_table_lock_waits);
+		fprintf(file, "Trx total rec lock wait time %lu SEC\n",
+			trx->total_rec_lock_wait_time);
+		fprintf(file, "Trx total table lock wait time %lu SEC\n",
+			trx->total_table_lock_wait_time);
+
 		if (trx->lock.que_state == TRX_QUE_LOCK_WAIT) {
 
 			fprintf(file,