Oddities with the MySQL “Table upgrade required” message

Here’s an obscure thing we spent some time on today that doesn’t affect our customers, but might be useful to someone else searching the Internet. The problem was a MySQL database table that, as far as we can tell, worked perfectly… except that it shows this message when we run CHECK TABLE:

Table upgrade required. Please do "REPAIR TABLE `users`" to fix it!

Hmm. Well, that error message seems odd, but what the heck. After making sure there’s a current backup, let’s give it a shot:

mysql> REPAIR TABLE users;

+---------------------+--------+----------+-----------------------------+
| Table               | Op     | Msg_type | Msg_text                    |
+---------------------+--------+----------+-----------------------------+
| database.users      | repair | status   | Table is already up to date |
+---------------------+--------+----------+-----------------------------+

And yet, CHECK TABLE still says there’s a problem:

mysql> CHECK TABLE users;

+---------------------+-------+----------+-------------------------------------+
| Table               | Op    | Msg_type | Msg_text                            |
+---------------------+-------+----------+-------------------------------------+
| database.users      | check | error    | Table upgrade required. Please do   |
|                     |       |          |  "REPAIR TABLE `users`" to fix it!  |
+---------------------+-------+----------+-------------------------------------+

Hmmm. We tried every reasonable combination of REPAIR TABLE and myisamchk options we could think of, but nothing helped. Then we tried unreasonable options, including the frightening REPAIR TABLE table USE_FRM option. In our experience USE_FRM usually ends up doing the same thing as DELETE FROM table, and this time was no exception. (And that’s why you make a backup first.)

Well, let’s take a look at the table status (with the uninteresting bits removed):

mysql> show table status;

+-------+--------+---------+-----+---------------------+
| Name  | Engine | Version | ... | Create_time         |
+-------+--------+---------+-----+---------------------+
| good  | MyISAM |      10 | ... | 2007-06-08 09:44:01 |
| users | MyISAM |       7 | ... | 2005-03-15 12:03:11 |
+-------+--------+---------+-----+---------------------+

Sure enough, the bad “users” table is a different version than a good table that doesn’t have this problem. And the bad table was created when we were still using MySQL 4.1.x. This table should have been changed when we upgraded to MySQL 5, and it should be possible to fix now. Why on earth won’t REPAIR TABLE fix it?

We puzzled over this for some time, and eventually just decided to reload it from a dump. But here’s the strange thing: it wouldn’t reload from the dump, either!

ERROR 1060 (42S21) at line 20: Duplicate column name 'user_id'

What the heck? So we looked closely at the dump file, and it somehow contains this line:

PRIMARY KEY (user_id,user_id)

MySQL thinks this table has a composite (two-column) primary key, but on the same column twice, which doesn’t make any sense. So we fix the dump to look like this:

PRIMARY KEY (user_id)

And everything works perfectly when the table is reloaded.

So if CHECK TABLE tells you a table upgrade is required, but REPAIR TABLE won’t fix it, check whether you can actually reload a dump of that table. You might find something unusual and easily fixable in the dump.

7 Comments

  1. here you can find a small perl script to fix such duplicate primary key mysqldump automatically. Tested on debian etch.

    Usage is:
    1) download and save file as “fix_duplicate_pk”, and “chmod +x” it.
    2) mysqldump -A > broken_dump.txt
    3) ./fix_duplicate_pk fixed_dump.txt
    4) diff broken_dump.txt fixed_dump.txt # visual verify to make sure it didn’t “overfix” (shouldn’t happen, but…)
    5) mysql < fixed_dump.txt

    make sure nobody is modifying your mysql tables between steps 2 and 5, of course.
    Thanks for the blog which gave me the hint about mysql breakage!

  2. I got the same strange error messages, it was impossible to repair the tables.
    However, when I finally tried ‘optimize table’ I found out why.

    ‘Can’t create new tempfile:’…

    It was simply wrong owner of the database directory, root instead of mysql.
    A chown and then mysqlcheck -r worked again. 🙂

  3. I had the same problem as this, where REPAIR TABLE wasn’t upgrading the MyISAM version. Re-importing the tables showed that two of the fields had unacceptable default values (dates).

    Thanks.

  4. Pretty good this site

  5. Simply repairing all my tables worked for me when upgrading to MySQL 5. True, some huge tables took about 10 minutes to fix, but no more “Table upgrade required” messages, and no problems.

  6. Hi, very good web site. Thanks.

  7. Thanks for the info, it worked like a charm for me. I just generated a dum and then restored it and everything started working properly.