commit c9bf00c9b117aa885086a774fac2e332771f943b
Author: Sergei Golubchik <serg@mariadb.org>
Date:   Sat Feb 21 19:21:24 2015 +0100

    MDEV-5114

diff --git a/mysql-test/suite/rpl/r/rpl_seconds_behind_master.result b/mysql-test/suite/rpl/r/rpl_seconds_behind_master.result
new file mode 100644
index 0000000..0a013b0
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_seconds_behind_master.result
@@ -0,0 +1,15 @@
+include/master-slave.inc
+[connection master]
+SET @old_debug= @@global.debug_dbug;
+call mtr.add_suppression('Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT');
+include/rpl_reset.inc
+set global debug_dbug= '+d,dec_event_time_by_1_hour';
+CREATE TABLE t1 (a INT);
+include/assert.inc [Seconds_Behind_Master must be 0]
+LOCK TABLE t1 WRITE;
+INSERT INTO t1 VALUES (3);
+include/assert.inc [Seconds_Behind_Master must be greater than 3500]
+UNLOCK TABLES;
+DROP TABLE t1;
+SET @@global.debug_dbug= @old_debug;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_seconds_behind_master.test b/mysql-test/suite/rpl/t/rpl_seconds_behind_master.test
new file mode 100644
index 0000000..06b2771
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_seconds_behind_master.test
@@ -0,0 +1,96 @@
+# make the test only run once (STMT is actually needed because we rely
+# on SHOW PROCESS LIST output in some of the tests)
+--source include/have_binlog_format_statement.inc
+
+--source include/have_debug.inc
+--source include/master-slave.inc
+
+SET @old_debug= @@global.debug_dbug;
+call mtr.add_suppression('Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT');
+
+#
+# BUG#52166 test case
+#
+# What to test?
+#
+# We want to test that Seconds_Behind_Master does not spike when SQL
+# thread awakes to process a newly arrived event (queued by IO
+# thread). Additionally, we want to assert that while SQL thread is
+# waiting Seconds_Behind_Master will show zero.
+#
+# How to test?
+#
+#  1. Check that seconds behind master is set to 0 when SQL thread
+#     waits for more events. We do this by first waiting for process
+#     list to show SQL thread is indeed waiting and then inspect
+#     Seconds_Behind_Master value.
+#
+#  2. Check that seconds behind master is updated once after a newly
+#     received event starts to be processed. We do this by putting SQL
+#     thread on hold by locking explicitly table t1. We then wait for
+#     process list to show that SQL thread started processing the
+#     desired query. At that time we inspect the Seconds_Behind_Master
+#     and assert that it is in the desired time window.
+
+-- source include/rpl_reset.inc
+-- connection master
+
+# this will increase the timestamp +3600, so it becomes
+# clear at the slave that it must show 0 and not 3600
+set global debug_dbug= '+d,dec_event_time_by_1_hour';
+CREATE TABLE t1 (a INT);
+sync_slave_with_master;
+
+# ok, now wait for the SQL thread to sleep
+let $wait_timeout= 60; # Override default of 30 seconds with 60.
+let $show_statement= SHOW PROCESSLIST;
+let $field= State;
+let $condition= = 'Slave has read all relay log; waiting for the slave I/O thread to update it';
+-- source include/wait_show_condition.inc
+
+-- let $sbm= query_get_value("SHOW SLAVE STATUS", Seconds_Behind_Master, 1)
+let $assert_text= Seconds_Behind_Master must be 0;
+let $assert_cond= $sbm = 0;
+source include/assert.inc;
+
+-- connection slave
+LOCK TABLE t1 WRITE;
+
+-- connection master
+
+# Now we will be testing that seconds behind master
+# is set correctly once the event is dequeued and is executing.
+# To achieve this goal we will make the event timestamp
+# to be shifted 3600 seconds (so that time difference
+# becomes clear).
+#
+# 10 seconds, this will give us time at the slave to
+# show that Seconds_Behind_Master will increase when
+# this query starts to execute.
+#
+INSERT INTO t1 VALUES (3);
+
+-- connection slave
+
+# ok, now wait for the SQL thread to start the insert
+let $wait_timeout= 60; # Override default of 30 seconds with 60.
+let $show_statement= SHOW PROCESSLIST;
+let $field= Info;
+let $condition= = 'INSERT INTO t1 VALUES (3)';
+-- source include/wait_show_condition.inc
+
+-- let $sbm= query_get_value("SHOW SLAVE STATUS", Seconds_Behind_Master, 1)
+let $assert_text= Seconds_Behind_Master must be greater than 3500;
+let $assert_cond= 3500 < $sbm;
+source include/assert.inc;
+
+UNLOCK TABLES;
+
+-- connection master
+DROP TABLE t1;
+sync_slave_with_master;
+-- connection master
+
+SET @@global.debug_dbug= @old_debug;
+
+-- source include/rpl_end.inc
diff --git a/sql/log_event.cc b/sql/log_event.cc
index dd272ac..ec98011 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1241,6 +1241,7 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
   }
 
   now= get_time();                               // Query start time
+  DBUG_EXECUTE_IF("dec_event_time_by_1_hour", now= now - 3600;);
 
   /*
     Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
