Bug #48326 current_timestamp and now() don't produce the same value for a given statement
Submitted: 26 Oct 2009 18:03 Modified: 24 Nov 2009 9:02
Reporter: Rishi Malik Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: General Severity:S2 (Serious)
Version:5.0.75, 5.1 bzr OS:Linux (5.0.75-0ubuntu10.2-log)
Assigned to: CPU Architecture:Any

[26 Oct 2009 18:03] Rishi Malik
Description:
Documentation suggests that current_timestamp and now() are synonyms. When inserting into a table with a column has current_timestamp, and inserting into a column using now(), I get different times.

How to repeat:
CREATE TABLE `test_table` (
  `id` int(11) NOT NULL auto_increment,
  `nonset` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `queryset` timestamp NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

mysql> show global variables like 'time_zone%';
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| time_zone     | SYSTEM | 
+---------------+--------+
1 row in set (0.00 sec)

System timezone is GB/London.

Set your system clock to 2009-10-25 01:48:24 BST.

Run

mysql> insert into test_table(queryset) values(now());

mysql> select nonset,unix_timestamp(nonset),queryset,unix_timestamp(queryset) from test_table;
+---------------------+------------------------+---------------------+--------------------------+
| nonset              | unix_timestamp(nonset) | queryset            | unix_timestamp(queryset) |
+---------------------+------------------------+---------------------+--------------------------+
| 2009-10-25 01:48:53 |             1256431733 | 2009-10-25 01:48:53 |               1256435333 | 
+---------------------+------------------------+---------------------+--------------------------+

Note that the unix timestamps differ by one hour. In this case, the mysql client and server are running on the same machine. 

Suggested fix:
Unknown. I would expect that current_timestamp and now() would have the same values for a given insert statement. However, they appear to differ in timezone, (BST vs GMT).
[26 Oct 2009 20:05] Peter Laursen
Looks like related to 'daylight saving time'. I do not know how the British handle this (they only get up around 10 in the morning anyway!), but here in Denmark DST stopped the night between last Saturday and last Sunday. I get (CET - with no DST): 

CREATE TABLE `test_table` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `nonset` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `queryset` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY  (`id`)
) ENGINE=MYISAM DEFAULT CHARSET=latin1;

SHOW GLOBAL VARIABLES LIKE 'time_zone%';
/*
Variable_name  Value 
-------------  ------
time_zone      SYSTEM
*/

INSERT INTO test_table(queryset) VALUES(NOW());

SELECT nonset,UNIX_TIMESTAMP(nonset),queryset,UNIX_TIMESTAMP(queryset) FROM test_table;
/*
             nonset  unix_timestamp(nonset)             queryset  unix_timestamp(queryset)
-------------------  ----------------------  -------------------  ------------------------
2009-10-26 20:58:33              1256587113  2009-10-26 20:58:33                1256587113
*/ 

One possibility is that now() and current_timestamp is *stored* identically but *returned* differently to the client.  Maybe it was interesting to see something like:

SELECT nonset,HEX(UNIX_TIMESTAMP(nonset)),queryset,HEX(UNIX_TIMESTAMP(queryset)) FROM test_table;
and
SELECT nonset,MD5(UNIX_TIMESTAMP(nonset)),queryset,MD5(UNIX_TIMESTAMP(queryset)) FROM test_table;

Peter
(not a MySQL person)
[26 Oct 2009 21:28] Peter Laursen
OK .. my last comment was probably mistaken if read literally.  The INSERT and SELECT statements are independent. SELECT cannot see if "now()" or "current_timestamp" were used when INSERTing.  However a HEX() would still be interesting to see what is actually stored.  If they are stored identically then a TIMESTAMP DEFAULT CURRENT_TIMESTAMP and a TIMESTAMP with no or a 'fixed string' default are returned differently when returned as unix_timestamp's.
[27 Oct 2009 10:21] Rishi Malik
Daylight savings may have an impact on this. The date picked (2009-10-25 01:48:24 BST ) is about 11 minutes before the UK switched daylight savings time. This problem does not appear to occur after the switch at 2:00am. In fact, further testing shows that the problem only occurs between 01:00 and 02:00. Setting the time to values before that, or after that on the same day produce identical values for current_timestamp and now(). 

Output of the HEX and MD5 querys are below. I believe it is showing that mysql has stored a different value internally.

mysql> SELECT nonset,HEX(UNIX_TIMESTAMP(nonset)),queryset,HEX(UNIX_TIMESTAMP(queryset)) FROM test_table;
+---------------------+-----------------------------+---------------------+-------------------------------+
| nonset              | HEX(UNIX_TIMESTAMP(nonset)) | queryset            | HEX(UNIX_TIMESTAMP(queryset)) |
+---------------------+-----------------------------+---------------------+-------------------------------+
| 2009-10-25 01:51:46 | 4AE3A122                    | 2009-10-25 01:51:46 | 4AE3AF32                      | 
+---------------------+-----------------------------+---------------------+-------------------------------+

mysql> SELECT nonset,MD5(UNIX_TIMESTAMP(nonset)),queryset,MD5(UNIX_TIMESTAMP(queryset)) FROM test_table;
+---------------------+----------------------------------+---------------------+----------------------------------+
| nonset              | MD5(UNIX_TIMESTAMP(nonset))      | queryset            | MD5(UNIX_TIMESTAMP(queryset))    |
+---------------------+----------------------------------+---------------------+----------------------------------+
| 2009-10-25 01:51:46 | 61e61fefb95996b45a7f5da0a503dcd5 | 2009-10-25 01:51:46 | ebfa7a40df4a77837fdd3b2d663dff82 | 
+---------------------+----------------------------------+---------------------+----------------------------------+
[18 Nov 2009 11:14] Sveta Smirnova
Thank you for the report.

Verified as described.

In my case problem repeatable at Oct 25 02:49:38 MSD 2009, but not repeatable at Oct  25 01:49:33 MSD 2009:

CREATE TABLE `test_table` (
`id` int(11) NOT NULL auto_increment,
`nonset` timestamp NOT NULL default CURRENT_TIMESTAMP,
`queryset` timestamp NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
;
show global variables like 'time_zone%';
Variable_name   Value
time_zone       SYSTEM
вс окт 25 02:49:38 MSD 2009
insert into test_table(queryset) values(now());
select nonset,queryset,unix_timestamp(nonset) as un,unix_timestamp(queryset) as us from test_table;
nonset  2009-10-25 02:49:38
queryset        2009-10-25 02:49:38
un      1256424578
us      1256428178
[24 Nov 2009 9:02] Sveta Smirnova
Bug is repeatable with DATETIME column:

CREATE TABLE `test_table` (
`id` int(11) NOT NULL auto_increment,
`nonset` timestamp NOT NULL default CURRENT_TIMESTAMP,
`queryset` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
;
show global variables like 'time_zone%';
Variable_name   Value
time_zone       SYSTEM
вс окт 25 02:51:07 MSD 2009
insert into test_table(queryset) values(now());
select nonset,queryset,unix_timestamp(nonset) as un,unix_timestamp(queryset) as us from test_table;
nonset  2009-10-25 02:51:07
queryset        2009-10-25 02:51:07
un      1256424667
us      1256428267

But there is 1 thing needed to repeat the bug. Please look at the time:

вс окт 25 02:51:07 MSD 2009

According to DST changes timezone should be named MSK. Bug only repeatable if timezone listed as MSD while it should be MSK. This is possible to set using regular OS tools.
[9 Feb 2014 20:42] Josh Snyder
I can reproduce this issue in MySQL Server 5.6.16.  I originally encountered it in Percona Server 5.5.29.

As far as I can tell, the issue occurs whenever a daylight savings time transition occurs that causes a given hour to validly occur in two different timezones.  In the America/Los_Angeles zone, for instance, Sun Nov 3 2013 01:00:00-01:59:59 occurs in both the PDT and PST timezones.  This is because the clock jumps back by one hour, so that the second succeeding 01:59:59 PDT is 01:00:00 PST.

This minimal test case uses unix timestamp 1383465600 (Sun Nov 3 01:00:00 PDT 2013) as an example.  I executed it on a system in the America/Los_Angeles timezone.

> show variables like 'time_zone';
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| time_zone     | SYSTEM |
+---------------+--------+
1 row in set (0.00 sec)
> create table time_test (id int primary key, timestamp timestamp default current_timestamp) engine=innodb;
> set timestamp = 1383465600;
> insert into time_test (id) values (1);
> insert into time_test (id, timestamp) values (2, now());
> insert into time_test (id, timestamp) values (3, current_timestamp());
> insert into time_test (id, timestamp) values (4, current_timestamp);
> select id, timestamp, unix_timestamp(timestamp) from time_test;
+----+---------------------+---------------------------+
| id | timestamp           | unix_timestamp(timestamp) |
+----+---------------------+---------------------------+
|  1 | 2013-11-03 01:00:00 |                1383465600 |
|  2 | 2013-11-03 01:00:00 |                1383469200 |
|  3 | 2013-11-03 01:00:00 |                1383469200 |
|  4 | 2013-11-03 01:00:00 |                1383469200 |
+----+---------------------+---------------------------+

This demonstrates that for all cases where a time function is used explictly, MySQL has inserted a different value into the table than the one specified by `SET timestamp`.  I believe this is because the values of the `now` and `current_timestamp` functions are being converted into local time for display, and then converted back into unix time for storage.  When doing the conversion from display to unix time, MySQL has to make a choice for which timezone corresponds to '2013-11-03 01:00:00'.

I have not been able to find any documentation of this pitfall.  In fact, the documentation states that CURRENT_TIMESTAMP should have the same value as an auto-update of a timestamp column.  "To update an auto-updated column even when other columns do not change, explicitly set it to the value it should have (for example, set it to CURRENT_TIMESTAMP)." [1].

[1] http://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html