1、概述 通常,从一个发布版本升级到另一个版本时,我们建议按照顺序来升级版本。例如,想要升级 MySQL 3.23 时,先升级到 MySQL 4.0,而不是直接升级到 MySQL 4.1 或 MySQL 5.0。 以下是在升级 MySQL 时需要注意的事项: 仔细阅读一下升级的目标版本的新特
1、概述
通常,从一个发布版本升级到另一个版本时,我们建议按照顺序来升级版本。例如,想要升级 MySQL 3.23 时,先升级到 MySQL 4.0,而不是直接升级到 MySQL 4.1 或 MySQL 5.0。
以下是在升级 MySQL 时需要注意的事项:
在同一个发布系列版本的MySQL间,可以随意拷贝格式文件和数据文件。如果在MySQL运行过程中改变了字符集,就需要对每个MyISAM表执行 "myisamchk -r -q --set-character-set=charset
" 命令修复一下。否则的话,索引的排序可能不正确,因为修改了字符集,就可能会改变索引的顺序。
通常情况下,升级到新版本不需要修改任何数据表。请检查MySQL发布事项中提到的升级需要注意的地方,如果发现不能直接升级的话,就先用 mysqldump 将数据导出来,然后再导回去。
如果担心升级失败,就先把旧版本的MySQL改个名字备份起来,以备所需。
同时,升级完之后可能还需要重新编译跟MySQL相关的程序,因为新版本的头文件和库文件可能有改变了。
如果升级后发生问题了,请先检查是否使用了旧的my.cnf配置文件,可以通过执行命令 "mysqld --print-defaults" 来打印出各种配置信息来确认。
升级的时候最好也升级类似Perl的 DBD::mysql 模块,同样,对PHP和Python而言也是一样。
2、从 MySQL 5.0 升级到 MySQL 5.1
从 5.0 升级到 5.1 的时候,必须要升级授权表。否则,可能某些存储过程无法运行。详情请看附录 "<strong>mysql_update</strong>
MySQL升级时检查数据表"。
以下是从 5.0 升级到 5.1 需要注意的事项:
<strong>mysql_update</strong>
MySQL升级时检查数据表"以下是升级到MySQL 5.1之后会发生的一些变化:
服务器部分:
不兼容的变化:MySQL 5.1 实现了支持无需重启服务器就能在运行时加载或卸载API插件。这个特性需要用到mysql.plugin表,可以运行 "mysql_upgrade" 命令来创建该表
插件安装在系统变量 plugin_dir
所指的目录下。这个变量也控制着用户自定义函数(UDFs)所在目录,这相对以前的版本有所改变。在MySQL 5.1中,所有的UDFs库必须都安装到 plugin_dir
目录下,从旧版本升级的时候,必须把那些库文件都移动到这个目录下
table_cache
改名为 table_open_cache
mysql
数据库的 general_log
和 slow_log
表中。如果启用日志记录,这2种方式都可以使用。选项 --log-output
用来控制这2种日志的记录方式SQL分:
TYPE = <em><code>engine_name
还仍然是 ENGINE = <em><code>engine_name
的同义语法,但有警告。从5.2开始,将完全删除这种语法,并报告错误。DROP TRIGGER
语法使用模式名而非数据表名(模式名是可选参数,如果忽略了,就使用当前的模式)
当从5.0升级到5.0.10及更高时,则必须删除触发器后重新创建它们,否则升级后就无法删除触发器了。建议如下:
SELECT CONCAT('CREATE TRIGGER ', t.TRIGGER_SCHEMA, '.', t.TRIGGER_NAME,<br> ' ', t.ACTION_TIMING, ' ', t.EVENT_MANIPULATION, ' ON ',<br> t.EVENT_OBJECT_SCHEMA, '.', t.EVENT_OBJECT_TABLE,<br> ' FOR EACH ROW ', t.ACTION_STATEMENT, '//' )<br>INTO OUTFILE '/tmp/triggers.sql'<br>FROM INFORMATION_SCHEMA.TRIGGERS AS t;<br>
将触发器导出到文件 "/tmp/triggers.sql" 中去。
shell>rm -f */*.TRG<br>
mysql> delimiter // ;<br>mysql> source /tmp/triggers.sql //<br>
SUPER
权限,现在,这个操作只需要有 TRIGGER
权限。这改善了权限安全状况INSTALL PLUGIN
" 和 "UNINSTALL PLUGIN
" 语句用于操作API插件。同样,创建 FULLTEXT
索引时,可以用 "WITH PARSER
" 子句关联解析器插件3、从 MySQL 4.1 升级到 MySQL 5.0
服务器部分:
InnoDB
和 MyISAM
表中空格结尾的 TEXT
字段索引顺序改变了。因此需要运行 "CHECK TABLE
" 语句修复数据表,如果出现错误,就运行 "OPTIMIZE TABLE
" 或 "REPAIR TABLE
" 语句修复,甚至重新转储(用mysqldump) BINARY
字段中填充的值已经改变了。填充的值现在是 0x00
而非空格了,并且在取值的时候不会去除末尾的空格DECIMAL
的实现方式已经改变了,5.0对 DECIMAL
的格式限制严格多了MyISAM
和 InnoDB
表中创建的 DECIMAL
字段升级到5.0.6之后会发生崩溃--allow-suspicious-udfs
选项来启用ISAM
类型存储引擎(作者:可以通过重新编译源代码支持,不过非常不建议这么做)MyISAM
的 RAID
选项,可以用 mysqldump 导出旧表然后重新导回去实现升级SQL部分:
USING
的连接,包括外部连接的衍生形式,都按照SQL:2003标准来处理了;这个变化导致减少了自然连接和使用 USING
的连接产生的结果字段数,并且还将按照更合理的顺序显示这些字段,逗号比较符的优先顺序和 JOIN
, LEFT JOIN
中的一样了 InnoDB
回滚当前全部事务,从5.0.13开始,就只回滚最近的SQL语句了CHAR()
函数返回二进制字符串,而不是按照连接字符集格式的字符串。子句 USING <em><code>charset_name
可以自定义返回结果的字符集NOW()
和 SYSDATE()
返回的结果一样。但从5.0.13开始,SYSDATE()
返回的是语句执行点的时间,这就可能和 NOW()
返回的结果不一样了,不过可以用 --sysdate-is-now
选项让 SYSDATE()
作为 NOW()
的同名函数GREATEST(<em><code>x
,NULL) 和 LEAST(<em><code>x
,NULL) 如果 x
不是 NULL
值,则返回 x
。从5.0.13开始,只要任何参数是 NULL
,就返回 NULL,跟Oracle一样
DATETIME
的加0后就转换成 YYYYMMDDHHMMSS
格式,现在变成 YYYYMMDDHHMMSS.000000
格式了LOAD DATA INFILE
和 SELECT ... INTO OUTFILE 中,
当 FIELDS TERMINATED BY
和 FIELDS ENCLOSED BY
的值都是空的时候,结果就被改变了。以前,字段都按照它显示的宽度来读写的。现在变成按照足够保存字段值的宽度来读写它。然而,对MySQL 4.0.12/5.0.6来说,那些在它们之前导出来的文件可能无法正确用 LOAD DATA INFILE
语句导入DECIMAL
用更有效的格式来存储DECIMAL
值和舍入精确值的时候采用精确数学FLOAT
或 DOUBLE
之间的比较碰巧没问题,但在5.0中可能就不行了VARCHAR
和 VARBINARY
字段中末尾的空格不再删除BIT
是一个独立的数据类型了,不再是 TINYINT(1)
的同名词了SCHEMA
和 SCHEMAS
被认为分别是 DATABASE
和 DATABASES
的同名词innodb_table_locks
,它导致 LOCK TABLE
时也可以请求 InnoDB
表锁。这个选项默认打开,不过可能在 AUTOCOMMIT=1
和 LOCK TABLES
应用中会导致死锁C API部分:
DECIMAL
数据类型的实现方式发生了变化,因此如果使用就版本的库文件需要注意这个问题在5.0.3中,ER_WARN_DATA_TRUNCATED
警告符号改名为 WARN_DATA_TRUNCATED
了MYSQL
结构体中的 reconnect
标志被 mysql_real_connect()
设为 0。 4、从 MySQL 4.0 升级到 MySQL 4.1
服务器部分:
不兼容的变化:以下好几个都是需要重建数据表的,可以使用 mysqldump 导出表后重新导回去
TIMESTAMP
字段的 InnoDB
表。则在升级到4.1.4及更高时需要重建表,因为存储格式发生变化了 InnoDB
表采用同一种字符集比较函数来比较那些 非latin1_swedish_ci
字符集且不是 BINARY
的字符串'a' > 'a/t'
,以前则不这样。可以用 mysqlcheck 来检查一下数据表MyISAM
现在使用更好的校验和算法了UTF8
字符集存储数据表名和字段名。如果有用标准 7字节 US-ASCII 范围之外的字符作为表名/字段名的话,需要重建表InnoDB
使用了多个表空间的缘故timezone
改成 system_time_zone
所有的数据表和非二进制字符串(
CHAR
, VARCHAR
, 和 TEXT
)的字段都有字符集
,二进制字符串字段包括 BINARY
, VARBINARY
, 和 BLOB
MySQL4.0中,如果有字段类型为
CHAR BINARY
或 VARCHAR BINARY
,则它们会被当作二进制字符串类型.frm
的格式稍作改进,新版本能兼容这个新格式,但是旧版本则不能--shared-memory
选项即可支持从本地客户端连接时使用共享内存--allow-suspicious-udfs
选项来启用客户端部分:
--opt
和 --quote-names
选项SQL部分:
TIMESTAMP
返回 'YYYY-MM-DD HH:MM:SS'
格式的字符串。在MySQL 4.0中,可以增加选项 --new
来获得MySQL 4.1中这方面的特性0xFFDF
被当成字符串而非数字SHOW TABLE STATUS
结果的 Type
字段改名为 Engine
了DATE
, DATETIME
, 或 TIME
类型的函数的结果会被转换成时间型AUTO_INCREMENT
字段不能设定 默认(DEFAULT)
值了LIMIT
不再接受负数参数了SERIALIZE
不再是 sql_mode
变量的有效值了,它的取代值是 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
C API部分:
MySQL 4.1中的密码哈希算法做了改进以提升安全性,不过会导致兼容性问题。使用MySQL 4.0及更早版本的客户端库文件会发生问题。
mysql_shutdown()
函数增加一个参数:SHUTDOWN
-levelmysql_real_query()
发生错误时返回 1
而非 -1
密码处理部分:
MySQL 4.1中的密码哈希算法做了改进以提升安全性,不过会导致兼容性问题。使用MySQL 4.0及更早版本的客户端库文件会发生问题。解决办法有:
5、附录
1、) 在Windows平台上升级MySQL步骤:
C:/> <strong><code>C:/mysql/bin/mysqld --remov</code></strong>e
C:/> <strong><code>C:/mysql/bin/mysqld --install</code></strong>
2、) 升级授权表
升级授权表之前一定要备份好 mysql
数据库,以备升级失败时使用旧的授权表。
在unix或类unix系统中,运行 mysql_fix_privilege_tables 脚本来升级授权表:
shell> <strong><code>mysql_fix_privilege_tables</code></strong>
必须在 mysqld
运行着的时候执行这个脚本,它尝试使用 root 帐号来连接服务器;因此,当 root 需要密码时,用如下方式来指定密码:
shell> <strong><code>mysql_fix_privilege_tables --password=root_password</code></strong>
在 MySQL 4.1之前,则是用如下形式来指定密码:
shell> <strong><code>mysql_fix_privilege_tables root_password</code></strong>
接下来 mysql_fix_privilege_tables
脚本会升级授权表,在这个过程中可能会有一些 Duplicate column name
警告信息,无需理会它们。待它运行完之后,重启一下服务器即可。
在windows平台上,授权表想要升级到4.0.15并不容易。从4.0.15开始,发行版中包含一个sql脚本:mysql_fix_privilege_tables.sql
,用 mysql 客户端运行它来升级授权表,运行类似如下命令:
C:/> <strong><code>C:/mysql/bin/mysql -u root -p mysql</code></strong><br>mysql> <strong><code>SOURCE C:/mysql/scripts/mysql_fix_privilege_tables.sql</code></strong>
把上面提到的目录改成真实的目录。
3、) 升级同步
请查看我翻译的文档"6.6 升级同步"
4、) mysql_update
MySQL升级时检查数据表
每次升级的时候都必须运行 mysql_upgrade 脚本。它检查了当前版本的MySQL下的所有数据库表的不兼容性,就会检查这些表;并且发现有问题时,也会修复这些表。mysql_update
同时升级了系统表,因此可以兼容新的权限机制并且使用新增的权限。
由于 mysql_update
会把检查过和修复过的表都标记上当前的MySQL版本号,因而保证了下一次在同一个MySQL版本下运行这个脚本时,都会再次报告哪些表需要修复或检查。
它还会把MySQL的版本号记录在数据文件目录下的一个文件中:mysql_upgrade.info
。这个文件用于标识当前发布版本检查表时哪些表可以略过,检查时想要忽略这个文件,只需附加上 --force
选项。
为了能检查和修复数据表,并且升级系统表,mysql_update
执行了一下命令:
mysqlcheck --check-upgrade --all-databases --auto-repair<br>mysql_fix_privilege_tables<br>
mysql_update
目前只支持类unix平台;在windows下,需要手工执行 mysqlcheck 命令,升级授权表请看附录"升级授权表"。
执行 mysql_update
时,MySQL服务器必须运行着,它有以下几个参数:
--help
显示帮助信息并且退出
--basedir=<em><code>path
设定MySQL的安装路径
--datadir=<em><code>path
设定MySQL的数据文件路径
--force
告诉 mysql_update
,在检查时忽略是否存在 mysql_upgrade.info
文件,强行检查该版本的MySQL数据表,不管是否已经检查过了
--user=<em><code>user_name
, -u <em><code>user_name
连接到MySQL的用户名,默认是 root
--verbose
冗余模式。发生问题时打印出更多的信息
其他的选项诸如 --password[=<em><code>password
] 是要传递给 mysqlcheck 和 mysql_fix_privilege_tables 脚本的,并不是必须的。