Bug #13900 DATETIME data changes after inserting a new row in a InnoDB table

Submitted: 10 Oct 2005 15:54 Modified: 20 Oct 2005 20:38
Reporter: Thoralf Rickert Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S2 (Serious)
Version:5.0.13-rc OS:Linux (Linux Debian Sarge)
Assigned to: Marko Mäkelä CPU Architecture:Any

[10 Oct 2005 15:54] Thoralf Rickert
Description:
I think I've found a strange bug and try to find a solution for two days - but nothing. I can reproduce it every time with different data in a MySQL 5.0.13-rc environment. I couldn't reproduce it with mysql 4.0.

I'd like to insert some rows in a InnoDB table with a transaction. After a while an old row changes the data of a DATETIME field. I've downgraded my problem to a very simple example.

How to repeat:
Here is the SQL code:

DROP DATABASE test;
CREATE DATABASE test;
use test;
CREATE TABLE store ( id BIGINT NOT NULL AUTO_INCREMENT, website VARCHAR (255), exists_since_time DATETIME, PRIMARY KEY(id) ) Type=InnoDB;

BEGIN;
INSERT INTO store ( website, exists_since_time ) VALUES ( NULL, NULL );
UPDATE store SET website = '', exists_since_time = '2002-04-01 00:00:00' WHERE ID = 1;

INSERT INTO store ( website, exists_since_time ) VALUES ( NULL, NULL );
UPDATE store SET website = '', exists_since_time = '1995-01-05 00:00:00' WHERE ID = 2;

INSERT INTO store ( website, exists_since_time ) VALUES ( NULL, NULL );
UPDATE store SET website = '', exists_since_time = NULL WHERE ID = 3;

INSERT INTO store ( website, exists_since_time ) VALUES ( NULL, NULL );
UPDATE store SET website = '', exists_since_time = '1999-02-02 00:00:00' WHERE ID = 4;

INSERT INTO store ( website, exists_since_time ) VALUES ( NULL, NULL );
UPDATE store SET website = '', exists_since_time = '2000-04-01 00:00:00' WHERE ID = 5;

INSERT INTO store ( website, exists_since_time ) VALUES ( NULL, NULL );
UPDATE store SET website = '', exists_since_time = NULL WHERE ID = 6;
COMMIT;

After this the second row contains a special character (0x01) in the "exist_since_time" column. See this:

mysql> select * from store;
+----+---------+---------------------+
| id | website | exists_since_time   |
+----+---------+---------------------+
|  1 |         | 2002-04-01 00:00:00 |
|  2 |         | ?720-24-47 77:58:08 |
|  3 | NULL    | NULL                |
|  4 |         | 1999-02-02 00:00:00 |
|  5 |         | 2000-04-01 00:00:00 |
|  6 | NULL    | NULL                |
+----+---------+---------------------+

When I comment out the last INSERT and UPDATE and rerun the script, the second row is correct:

+----+---------+---------------------+
| id | website | exists_since_time   |
+----+---------+---------------------+
|  1 |         | 2002-04-01 00:00:00 |
|  2 |         | 1995-01-05 00:00:00 |
|  3 | NULL    | NULL                |
|  4 |         | 1999-02-02 00:00:00 |
|  5 |         | 2000-04-01 00:00:00 |
+----+---------+---------------------+

So, this could NOT be a problem with the SQL syntax during inserting and updating the second row...

Here is the installation procedure (from source):

#>./configure --prefix=/usr/local/mysql5 --with-charset=latin1
#>make
#>make install

and the configuration file changes:

default-character-set = latin1
collation-server = latin1_german2_ci

Suggested fix:
I don't have a fix but a workaround:

Making first all INSERTs and then all UPDATEs is okay.
But I produce the SQL in a for-loop and lose the data. So I don't know the data after the first loop.
[10 Oct 2005 16:19] MySQL Verification Team
mysql> select * from store;
+----+---------+---------------------+
| id | website | exists_since_time   |
+----+---------+---------------------+
|  1 |         | 2002-04-01 00:00:00 |
|  2 |         | 720-24-47 77:58:08 |
|  3 | NULL    | NULL                |
|  4 |         | 1999-02-02 00:00:00 |
|  5 |         | 2000-04-01 00:00:00 |
|  6 | NULL    | NULL                |
+----+---------+---------------------+
6 rows in set (0.00 sec)
-------------------------------------
mysql> select * from store;
+----+---------+---------------------+
| id | website | exists_since_time   |
+----+---------+---------------------+
|  1 |         | 2002-04-01 00:00:00 |
|  2 |         | 1995-01-05 00:00:00 |
|  3 | NULL    | NULL                |
|  4 |         | 1999-02-02 00:00:00 |
|  5 |         | 2000-04-01 00:00:00 |
+----+---------+---------------------+
5 rows in set (0.00 sec)

mysql> select version();
+-----------------+
| version()       |
+-----------------+
| 5.0.15-rc-debug |
+-----------------+
1 row in set (0.00 sec)
[10 Oct 2005 21:54] Heikki Tuuri
I think I have found the bug.
[14 Oct 2005 20:16] Heikki Tuuri
Marko has now emailed the patch to Elliot.
[17 Oct 2005 15:34] Elliot Murphy
Tried applying patch on Friday, saw test failures, emailed to Marko today. Also rerunning tests.
[17 Oct 2005 18:11] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/internals/31185
[17 Oct 2005 18:17] Elliot Murphy
Tried again with a fresh tree, tests are passing now.
Will push in a couple of hours, fix will be available for 5.0.16
[18 Oct 2005 18:49] Elliot Murphy
Pushed for 5.0.16
[20 Oct 2005 20:38] Paul DuBois
Noted in 5.0.16 changelog.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.061 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.