r1 - 09 Sep 2008 - 07:22:21 - Main.yfangYou are here: YWiki >  MyTroubleShooting Web > MySQL5_0升级到5_1中mysql_upgrade失败的问题

MySQL5.0升级到5.1中mysql_upgrade失败的问题

问题描述

  • 时间 2008.8.30
  • 环境 CentOS4.6 MySQL5.0.18 MySQL 5.1.12
  • 问题简介 升级MySQL二进制程序到5.1后,mysqld启动失败
  • 症状 执行原来的服务启动脚本(/usr/local/app/mysql start)报错,事实上是我疏忽了,这个问题从升级的那一天开始就有了,不过我升级的是测试服务器,升级后也没做检查,mysql是使用daemontools启动的,一旦启动失败,会不断尝试启动,所以竟然也没有发现问题,只到前不久想要登录发现不行了,发现mysql.err居然超过1G,稍微看了一下确认是同样的错误
080908 17:28:06 [Note] Plugin 'InnoDB' disabled by command line option
/usr/local/mysql/bin/mysqld: Table 'mysql.plugin' doesn't exist
080908 17:28:06 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
080908 17:28:06 [ERROR] /usr/local/mysql/bin/mysqld: unknown option '--skip-isam'
080908 17:28:06 [ERROR] Aborting

080908 17:28:06 [Note] /usr/local/mysql/bin/mysqld: Shutdown complete
  • 这本来是一个很典型的问题,就是说MySQL5.1中增加了一些新的系统表,比如mysql.plugin,但是使用的仍是原来的数据库,自然就缺少这些表,从而启动失败,按照常理和官方的说法,应该执行mysql_upgrade进行系统结构升级,不过这个程序是一个客户端程序,换句话说一定要在mysqld服务正常运行时才能连上去检查升级系统表,现在连服务都起不来,怎么办呢?

问题的解决过程

  • 在最终成功解决问题之前做过一些尝试,下面罗列一下整个解决过程,如果没有耐心,可以直接看我最后的总结
  • 因为眼前的问题是服务不启动就不能升级,所以首要问题是让服务可以跑起来接收客户端连接,所以我先是把二进制程序换回原来5.0的版本,毫无疑问,非常顺利的启动了,接下来我想用新的5.1的mysql_upgrade去升级,未果,报出了下面的错误
root@Server[0]18:24:13# /usr/local/mysql-5.1.25/bin/mysql_upgrade -S /var/data/mysql.sock -uroot -p
Enter password:
Looking for 'mysql' in: /usr/local/mysql-5.1.25/bin/mysql
Looking for 'mysqlcheck' in: /usr/local/mysql-5.1.25/bin/mysqlcheck
Running 'mysqlcheck'...
/usr/local/mysql-5.1.25/bin/mysqlcheck: Got error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOR UPGRADE' at line 1 when executing 'CHECK TABLE ...  FOR UPGRADE'
FATAL ERROR: Upgrade failed
  • 这个也不行了,突然想到出奇招,还是使用5.1的二进制程序,然后更改启动参数,因为我只想要把data目录下的表结构升级而已,必须指定的参数只是data目录,于是我做了如下尝试
# 启用 --skip-grant-tables参数避开检查,先启动再说
root@Server[0]l11:36:01# /usr/local/mysql/bin/mysqld --datadir=/var/data/ --user=mysql --skip-grant-tables &
InnoDB: Error: log file ./ib_logfile0 is of different size 0 20971520 bytes
InnoDB: than specified in the .cnf file 0 5242880 bytes!
080909 11:36:01 [ERROR] Plugin 'InnoDB' init function returned error.
080909 11:36:01 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
080909 11:36:01 [ERROR] Can't open and lock privilege tables: Table 'mysql.servers' doesn't exist
080909 11:36:01 [ERROR] Column count of mysql.db is wrong. Expected 22, found 20. Created with MySQL 50018, now running 50125. Please use mysql_upgrade to fix this error.
080909 11:36:01 [ERROR] mysql.user has no `Event_priv` column at position 29
080909 11:36:01 [ERROR] Cannot open mysql.event
080909 11:36:01 [ERROR] Event Scheduler: An error occurred when initializing system tables.
080909 11:36:01 [Note] /usr/local/mysql/bin/mysqld: ready for connections.
Version: '5.1.25-rc-log'  socket: '/tmp/mysql.sock'  port: 3306  MySQL Community Server (GPL)

# 到这里,服务竟然起来了,真高兴啊,继续下一步升级
root@Server[0]11:36:01# mysql_upgrade
Looking for 'mysql' in: /usr/local/mysql-5.1.25/bin/mysql
Looking for 'mysqlcheck' in: /usr/local/mysql-5.1.25/bin/mysqlcheck
Running 'mysqlcheck'...
mysql.class_select
Error    : Unknown table engine 'InnoDB'
error    : Corrupt
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.func                                         OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.host                                         OK
mysql.proc                                         OK
mysql.procs_priv                                   OK
mysql.tables_priv                                  OK
mysql.time_zone                                    OK
mysql.time_zone_leap_second                        OK
mysql.time_zone_name                               OK
mysql.time_zone_transition                         OK
mysql.time_zone_transition_type                    OK
mysql.user                                         OK
world.City
Error    : Unknown table engine 'InnoDB'
error    : Corrupt
world.Country                                      OK
world.CountryLanguage                              OK
world.DeletedCity                                  OK
world.audit_triggers                               OK
world.d_table                                      OK
world.dotriggers
Warning  : Triggers for table `world`.`dotriggers` have no creation context
status   : OK
world.model
Error    : Unknown table engine 'InnoDBig'
error    : Corrupt
world.model_uses_firmware
Error    : Unknown table engine 'InnoDBde'
error    : Corrupt
world.t                                            OK
yfang.user                                         OK

Repairing tables
mysql.class_select
Error    : Unknown table engine 'InnoDB'
error    : Corrupt
world.City
Error    : Unknown table engine 'InnoDB'
error    : Corrupt
world.model
Error    : Unknown table engine 'InnoDB'
error    : Corrupt
world.model_uses_firmware
Error    : Unknown table engine 'InnoDB?'
error    : Corrupt
Running 'mysql_fix_privilege_tables'...
OK

# 看上去成功了
# 中间报了一些innodb的错误,不去理会,应该是配置或是这个半阴半阳状态下问题,这个以后再解决
# 接下来停止这个服务 mysqladmin shutdown 之,然后以正常参数启动mysqld服务……

# 非常遗憾,并没有一次成功,报错信息如下
root@Server[0]11:40:03# mysql_service start
080909 11:40:05  InnoDB: Started; log sequence number 0 576947
080909 11:40:05 [ERROR] /usr/local/mysql/bin/mysqld: unknown option '--skip-bdb'
080909 11:40:05 [ERROR] Aborting

080909 11:40:05  InnoDB: Starting shutdown...
080909 11:40:07  InnoDB: Shutdown completed; log sequence number 0 576947
080909 11:40:07 [Note] /usr/local/mysql/bin/mysqld: Shutdown complete

# 这个问题很简单,原来的my.cnf中配置了skip-dbd参数,这个参数在5.1中已经废除了,所以报错,只要注释掉它就好了
# 再次尝试启动,成功!
# 从此王子和公主过上了快乐幸福的生活…… (其实我后面还做了一些检查,都是正常的,Innodb也没有任何问题,从略)

解决方案总结

  • 1. 备份数据,这个就不用说了
  • 2. 首先更新二进制程序到新的版本
  • 3. 启动mysqld时使用skip grant tables 参数避开系统检查,只需把data目录指定对就好了
# 例如
/usr/local/mysql/bin/mysqld --datadir=/var/data/ --user=mysql --skip-grant-tables &
  • 4. 执行mysql_upgrade,这时应该就会顺利进行下来了
  • 5. 停止mysqld
  • 6. 按照原来的my.cnf运行正常服务(这一步失败很可能由于参数不兼容引起,比如bdb相关的所有参数5.1开始都不再支持,总之这一步很容易处理)
  • 7. 检查表有没有问题,比如执行mysqlcheck --all-databases 等等

参考资料

Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r1 | More topic actions
 
Powered by YWiki
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding YWiki? Send feedback