Bug #68576 MySQL 5.6 crashes when mysql.user is in-compatible
Submitted: 5 Mar 2013 17:19 Modified: 6 Mar 2013 8:33
Reporter: Venu Anuganti Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server: DDL Severity:S1 (Critical)
Version:5.6.10 OS:Any
Assigned to: CPU Architecture:Any
Tags: 5.6, MySql Crash, mysql_upgrade

[5 Mar 2013 17:19] Venu Anuganti
Description:
MySQL 5.6 crashes with older version of mysql.user table

How to repeat:
Its common practice one to dump older mysql data to newer version esp mysql.user and any other user permission related tables. 

Here is a simple sequence of steps that causes 5.6 to crash

1. Install MySQL 5.6 on a fresh server (Linux, tested)
2. Get server up and running
3. Install MySQL 5.1/5.0/5.5 on any another server (or skip if you already have one)
4. Make sure you have few users and permissions set in older version
5. Dump mysql.user table from older mysql server 
6. Load the dump back in 5.6
7. Now access the table or run a simple GRANT. Server at this time crashes (and will be in infinite crash loop)

Suggested fix:
You need to validate if the given column exists in the table before pulling the records within dictionary; as sometimes people might be using older schema. Server needs its own sanity checks.

Workaround:
Once you load the system tables, before running any other command or restart; make sure to run mysql_upgrade
[5 Mar 2013 17:34] MySQL Verification Team
Hi Venu, this is a duplicate of a known bug #68385
[6 Mar 2013 8:33] Venu Anuganti
Shane, here is the fix/patch; as the field enum starts at 0 and table->s->fields starts at 1 as it has real fields count, you should skip the equality check, rather ">" should be good enough, instead of ">="

venu@ ~/work/mysql-5.6/sql 00:31:06# bzr diff
=== modified file 'sql/sql_acl.cc'
--- sql/sql_acl.cc	2013-01-15 15:37:35 +0000
+++ sql/sql_acl.cc	2013-03-06 07:52:50 +0000
@@ -3166,7 +3166,7 @@
     }

     /* if we have a password supplied we update the expiration field */
-    if (table->s->fields >= MYSQL_USER_FIELD_PASSWORD_EXPIRED &&
+    if (table->s->fields > MYSQL_USER_FIELD_PASSWORD_EXPIRED &&
         password_len > 0)
       table->field[MYSQL_USER_FIELD_PASSWORD_EXPIRED]->store("N", 1,
                                                              system_charset_info);