分类: Mysql/postgreSQL
2008-05-11 17:29:02
mysql_install_db 脚本的目的是生成新的MySQL授权表。它不覆盖已有的MySQL授权表,并且它不影响任何其它数据。
如果你想要重新创建授权表,首先停止mysqld服务器(如果它正运行)。然后重新命名数据目录下的MySQL目录并保存,然后运行mysql_install_db。例如:
shell> mv mysql-data-directory/mysql mysql-data-directory/mysql-old
shell> mysql_install_db --user=mysql
本节列出了运行mysql_install_db时你可能遇到的问题:
· mysql_install_db fails to install the grant tables
你会发现mysql_install_db不能安装 授权表,显示下面的消息后终止:
Starting mysqld daemon with databases from XXXXXX
mysqld ended
在这种情况下,你应该很小心地检验日志文件!日志文件应该位于目录“XXXXXX”,用错误消息命名,并且应该指出为什么mysqld没启动。如果你不理解发生的事情,邮寄一份错误报告,包含日志文件!参见1.7.1.3节,“如何通报缺陷和问题”。
· 已经有一个amysqld进程在运行
表示服务器在运行,这种情况下可能已经创建了授权表。如果如此,则不再需要运行mysql_install_db,因为只需要运行一次(当你首次安装MySQL时)。
· 当一个服务器正运行时,安装第二个服务器不工作
这只有在当你已经有已存在的MySQL安装但是想要把新安装放在一个不同的地方时才会发生。例如,你可能已经有了一个产品安装,但为了测试想要同时运行2个安装。通常当你试着运行第二个服务器时,发生的问题是它试图和第一个使用同样的套接字和端口。在这种情况下,你将遇到错误消息:
Can't start server: Bind on TCP/IP port:
Address already in use
Can't start server: Bind on unix socket...
关于设置多个服务器的说明,参见5.12节,“在同一台机器上运行多个MySQL服务器”。
· 你没有“ /tmp ”的写权限
如果你没有写权限在默认位置(在“/tmp”里)创建一个Unix套接字文件,或没有在“/tmp”创建临时文件的许可,在运行mysql_install_db或mysqld服务器时,你将遇到一个错误。
你可以在开始mysql_install_db或mysqld之前执行以下命令指定一个不同的Unix套接字文件位置和临时目录:
shell> TMPDIR=/some_tmp_dir/
shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysql.sock
shell> export TMPDIR MYSQL_UNIX_PORT
some_tmp_dir应该是你有写许可的某个目录的全路径。
然后,你应当能够用这些命令运行mysql_install_db并启动服务器:
shell> bin/mysql_install_db --user=mysql
shell> bin/mysqld_safe --user=mysql &
如果mysql_install_db位于scripts目录下,首先修改命令scripts/mysql_install_db。
通常你可以用以下方法启动mysqld服务器:
· 直接调用mysqld。该方法适合任何平台。
· 作为Windows服务运行MySQL服务器。可以在支持服务的Windows版本(例如 NT、2000、XP和2003)上实现。可以将服务设置为在Windows 启动时自动启动服务器,或根据需要启动的手动服务。相关说明参见2.3.12节,“以Windows服务方式启动MySQL”。
· 调用mysqld_safe,可以为mysqld确定正确的选项然后使用这些选项来运行。该脚本适用于基于BSD Unix的系统。请参见5.1.3节,“mysqld_safe:MySQL服务器启动脚本”。
· 调用mysql.server。该脚本主要用于使用系统V-style运行目录的系统的启动和关闭,它通常安装到mysql下。mysql.server脚本调用mysqld_safe来启动服务器。请参见5.1.4节,“mysql.server:MySQL服务器启动脚本”。
· 你可以在Mac OS X上安装一个单独的MySQL Startup Item安装包来使系统启动时自动启动MySQL。Startup Item调用mysql.server来启动服务器。详细介绍参见 2.5节,“在Mac OS X上安装MySQL”。
mysql.server和mysqld_safe脚本和Mac OS X Startup Item可以用来手动启动服务器,或自动启动系统。mysql.server和Startup Item还可以用来停止服务器。
mysql.server脚本可以被用来启动或停止服务器,通过用start或stop参数调用它:
shell> mysql.server start
shell> mysql.server stop
在mysql.server启动服务器之前,它把目录改变到MySQL安装目录,然后调用safe_mysqld。如果你想要作为一些特定的用户运行服务器,在/etc/my.cnf选项文件的[mysqld]组增加相应user选项,如本节后面所示。(如果你有在一个非标准的地点安装的二进制分发版,你可能需要编辑mysql.server。修改它,运行safe_mysqld前,cd到正确的目录。注意如果你修改mysql.server,那么某个时候升级MySQL时,你的修改版本将被覆盖,因此你应该做一个你可重新安装的编辑过的版本的拷贝)。
mysql.server stop通过向服务器发出一个信号停止它。你可手动执行mysqladmin shutdown关闭服务器。
要想在服务器上自动启动和停止MySQL,应在“/etc/rc * 文件中适当的地方增加启动、停止命令。
如果你使用Linux服务器RPM安装软件包(MySQL-server-VERSION.rpm),mysql.server脚本安装在/etc/init.d目录中,名为MySQL。你不需要手动安装它。关于Linux RPM软件包的详细信息参见2.4节,“在Linux下安装MySQL”。
一些供应商提供的RPM软件包安装的启动脚本名字不同,例如mysqld。
如果从不自动安装mysql.server的源码分发版或二进制分发版格式来安装MySQL,可以手动安装它。可以在MySQL安装目录下或MySQL 源码树的support-files目录中找到脚本。
要想手动安装mysql.server,用名称mysql将它复制到/etc/init.d目录,然后将它变为可执行文件。只需要将位置更改为mysql.serveris所在并执行这些命令的相应目录:
shell> cp mysql.server /etc/init.d/mysql
shell> chmod +x /etc/init.d/mysql
旧的Red Hat系统使用/etc/rc.d/init.d目录,不使用/etc/init.d。相应地调节前面的命令。也可以首先创建指向/etc/rc.d/init.d的符号连接/etc/init.d:
shell> cd /etc
shell> ln -s rc.d/init.d .
安装脚本后,用来激活它以便在系统启动时运行所需要的命令取决于你的操作系统。在Linux中,你可以使用chkconfig:
shell> chkconfig --addMySQL
在一些Linux系统中,还需要下面的命令来完全激活MySQL脚本:
shell> chkconfig --level 345MySQL on
在FreeBSD中,启动脚本通常应当位于/usr/local/etc/rc.d/。手册的rc(8)页内说明只有该目录脚本的基本名匹配*.sh shell文件名模式,脚本才会执行。目录内的其它文件或目录将被忽略掉。换句话说,在FreeBSD中,应当将mysql.server脚本安装为 /usr/local/etc/rc.d/mysql.server.sh以便自动启动。
前面设置的另一种情况是,一些操作系统启动时也使用/etc/rc.local或/etc/init.d/boot.local 来启动其它服务。要想使用该方法启动MySQL,你可以在相应启动文件后面追加一条命令:
/bin/sh -c 'cd /usr/local/mysql; ./bin/mysqld_safe --user=mysql &'
对于其它系统,查阅操作系统的文档来查看安装启动脚本的方法。
你也可以在一个全局“/etc/my.cnf”文件中增加mysql.server的选项。一个典型的“/etc/my.cnf”文件可能看起来像这样:
[mysqld]
datadir=/usr/local/mysql/var
socket=/var/tmp/mysql.sock
port=3306
user=mysql
[mysql.server]
basedir=/usr/local/mysql
mysql.server脚本使用下列变量:basedir、datadir和pid-file。定义后,必须将它们放到选项文件中,不能放到命令行。mysql.server只识别start和stop命令行参数。
下面的表显示了服务器和每个启动脚本从选项文件读取哪个选项组:
脚本 |
选项组 |
mysqld |
[mysqld], [server], [mysqld-major-version] |
mysql.server |
[mysqld], [mysql.server], [server] |
mysqld_safe |
[mysqld], [server], [mysqld_safe] |
[mysqld-major-version]意味着名为[mysqld-5.0]的组,[mysqld-5.1]用于版本为5.0.x、5.1.x等的服务器。该特性可以用来指定只被给定发布系列的服务器读取的选项。
为了向后兼容,mysql.server还读取[mysql_server]组,mysqld_safe还读取[safe_mysqld]组。然而,当使用MySQL 5.1时,你应当更新选项文件,使用[mysql.server]和[mysqld_safe]组。
如果启动服务器时有问题,可以尝试:
· 指定你使用的储存引擎需要的任何特殊选项。
· 确保服务器知道从哪里找到数据目录。
· 确保服务器可以使用数据目录。数据目录和内容的所有权和允许必须设置成服务器可以访问和修改它们。
· 检查错误日志查看服务器为何不启动。
· 验证服务器想要使用的网络接口可用。
一些储存引擎有一些选项可以控制其行为。你可以创建一个my.cnf文件并为计划使用的引擎设置启动选项。如果你将要使用支持事务处理表 (InnoDB,BDB)的储存引擎,应确保启动服务器之前按照你的期望对它们进行了配置:
· 如果你正使用InnoDB表,参阅InnoDB-specific启动选项。如果你未指定选项,InnoDB使用默认值作为配置选项。请参见15.2.3节,“InnoDB配置”。
· 如果你正使用BDB (Berkeley DB)表,你应当熟悉不同的BDB-specific启动选项。请参见15.5.3节,“BDB启动选项”。
当mysqld服务器启动时,它进入数据目录。在这里它可以找到数据库并写入日志文件。在Unix中,服务器还在数据目录中写pid(过程 ID)文件。
当编译服务器时确定数据目录。这是服务器默认寻找数据目录的位置。如果数据目录位于系统中的其它位置,服务器不能正确工作。用--verbose和--help选项调用mysqld你可以找出默认路径设定值。
如果默认值与你的系统中的MySQL安装布局不匹配,你可以在命令行中为mysqld 或mysqld_safe指定选项来覆盖它们。你还可以在选项文件中列出选项。
要想明显指定数据目录的位置,使用--datadir选项。一般情况下,你可以告诉mysqld基本目录的位置,MySQL安装在该目录下,并且它在该目录中寻找数据目录。你可以使用--basedir选项来实现。
要想检查指定路径选项的结果,用--verbose和--help选项调用mysqld。例如,如果你进入mysqld的安装目录,然后运行下面的命令,它显示启动服务器的结果,基本目录为/usr/local:
shell> ./mysqld --basedir=/usr/local --verbose --help
你可以指定其它选项,例如--datadir,但是请注意--verbose和--help必须为最后的选项。
一旦你确定了你想要的路径设定值,用--verbose和-- help启动服务器。
如果mysqld正在运行,执行下列命令你可以找出它所使用的路径设定值:
shell> mysqladmin variables
或:
shell> mysqladmin -h host_name variables
host_name是MySQL服务器主机的名称。
如果启动mysqld时遇到Errcode 13(意味着Permission denied),这意味着数据目录或其内容的访问权限不允许服务器访问。此时,你需要更改所调用文件和目录的权限,使服务器有权使用它们。你还可以用root启动服务器,但是这样会造成安全问题,应当避免。
在Unix中,进入数据目录,检查数据目录和其内容的所有权,确保服务器可以访问。例如,如果数据目录是/usr/local/mysql/var,使用命令:
shell> ls -la /usr/local/mysql/var
如果数据目录或其文件或子目录不属于你运行服务器使用的账户,将所有权改为该账户:
shell> chown –R mySQL /usr/local/mysql/var
shell> chgrp –R mySQL /usr/local/mysql/var
如果服务器不能正确启动,检查错误日志文件,看看是否可以找到原因。日志文件位于数据目录(在Windows中一般为C:\Program Files\MySQL\MySQL Server 5.1\data,Unix二进制分发版为/usr/local/mysql/data,Unix源码分发版为/usr/local/var)。查找数据目录中的host_name.err和host_name.log文件,其中host_name是你的服务器主机名。然后检查文件的最后几行。在Unix中,可以使用tail来显示:
shell> tail host_name.err
shell> tail host_name.log
错误日志包含指示服务器不能启动的信息。例如,你可以看见日志中:
000729 14:50:10 bdb: Recovery function for LSN 1 27595 failed
000729 14:50:10 bdb: warning: ./test/t1.db: No such file or directory
000729 14:50:10 Can't init databases
这意味着你没有用--bdb-no-recover选项启动mysqld,Berkeley DB恢复数据库时发现其日志文件有一些问题。要想继续,你应当将旧的Berkeley DB 日志文件从数据库目录移到其它地方,以后你可以在那儿检查它们。BDB日志文件以log.0000000001开头,按顺序命名。
如果你运行支持BDB 表的mysqld,mysqld启动时内核崩溃,该可能是由于BDB 恢复日志的问题。此时,你可以尝试用--bdb-no-recover启动mysqld。如果有帮助,你应当从数据目录移走所有BDB日志文件并尝试不用--bdb-no-recover选项重新启动mysqld。
如果出现下面的错误,说明其它程序(也许是另一个mysqld服务器)正使用mysqld正试图使用的TCP/IP端口或Unix 套接字文件:
Can't start server: Bind on TCP/IP port: Address already in use
Can't start server: Bind 在Unix中 socket...
使用ps来确定是否另有一个mysqld服务器正在运行。如果如此,关闭服务器重新启动mysqld。(如果另一个服务器正运行,你的确想要运行多个服务器,你可以在5.12节,“在同一台机器上运行多个MySQL服务器”中发现相关信息)。
如果没有其它服务器在运行,尝试执行命令 telnet your-host-name tcp-ip-port-number。(默认MySQL端口号是3306)。然后按两次Enter(回车)键。如果出现telnet: Unable to connect to remote host: Connection refused错误消息,其它程序正使用mysqld试图使用的 TCP/IP端口。你需要跟踪这是哪个程序并禁用它,或让mysqld用--port选项帧听其它端口。此时,当通过TCP/IP协议连接服务器时,你还需要为客户端程序指定端口号。
端口不能访问的另一个原因可能是防火墙正运行,阻挡了与它的连接。如果如此,修改防火墙设置允许对该端口的访问。
如果服务器已经启动但是你不能与它连接,你应当确保在/etc/hosts中有下面所示条目:
127.0.0.1 localhost
该问题只发生在没有工作线程库,并且MySQL必须配置为使用MIT-pthreads的系统。
如果你不能启动mysqld,你可以使用--debug选项尝试编写一个跟踪文件来找到问题。请参见E.1.2节,“创建跟踪文件”。
关于在Windows安装中排错的详细信息,参见2.3.14节,“在Windows环境下对MySQL安装的故障诊断与排除”。
MySQL安装过程包括设置含有授权表的MySQL数据库:
· Windows分发版包含预初始化的授权表,可以自动安装。
· 在Unix中,用mysql_install_db程序来安装 授权表。可以通过一些安装方法来运行该程序。否则你需要手动执行。详细信息参见2.9.2节,“Unix下安装后的过程”。
授权表定义了初始MySQL用户账户和访问权限。按照以下步骤对这些账户进行设置:
· 用用户root 创建两个账户。这些账户为超用户账户,可以执行任何操作。初始root账户的密码为空,因此任何人可以用root账户不用任何密码来连接MySQL服务器,并具有所有权限。
o 在Windows中,一个root账户用来从本机连接MySQL服务器,另一个允许从任何主机连接。
o 在Unix中,两个root账户均用于从本机连接。必须从本机进行连接,一个账户主机名应指定为localhost,另一个账户为实际的主机名或IP号。
· 创建了两个匿名用户账户,每个账户的用户名均为空。匿名账户没有密码,因此任何人可以使用匿名账户来连接MySQL服务器。
o 在Windows中,一个匿名账户用来从本机进行连接。它具有所有权限,同root 账户一样。另一个可以从任何主机上连接,具有test数据库或其它以test开始的数据库的所有权限。
o 在Unix中,两个匿名账户均用于从本机连接。必须从本机进行连接,一个账户主机名应指定为localhost,另一个账户为实际的主机名或IP号。两个账户具有test数据库或其它以test开始的数据库的所有权限。
如前面所述,所有初始账户均没有密码。这意味着在你执行下述操作前,MySQL安装未受保护:
· 如果你想要防止客户端不使用密码用匿名用户来连接,你应当为匿名账户指定密码或删掉匿名账户。
· 你应当为MySQL root账户指定密码。
下面的说明描述了如何为初始MySQL账户设置密码,先为匿名账户设置然后为root账户设置。在例子中用实际密码替换“newpwd”。说明还包括如果你不想用匿名账户访问,如何删掉匿名账户。
你可能想要在以后设置密码,因此不需要在进一步的设置或测试中指定密码。但是,一定要在实际生产作业、使用安装前设置好密码。
要想为匿名账户指定密码,可以使用SET PASSWORD或UPDATE。在两种情况中,一定要使用PASSWORD()函数为密码加密。
在Windows中使用PASSWORD的方法:
shell> mysql -u root
mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR ''@'%' = PASSWORD('newpwd');
在Unix中使用PASSWORD的方法:
shell> mysql -u root
mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR ''@'host_name' = PASSWORD('newpwd');
用服务器主机名替换第二个SET PASSWORD语句中的host_name。这是指定的user表中的root non-localhost记录的Host列名。如果你不知道是哪个主机名,在SET PASSWORD之前执行下面的语句:
mysql> SELECT Host, User FROM mysql.user;
查找在User列有root和在Host列没有localhost的记录。然后在第二个SET PASSWORD语句中使用该Host值。
为匿名账户指定密码的另一种方法是使用UPDATE直接修改用户表。用root连接服务器,运行UPDATE语句为相应user表记录的Password列指定一个值。在Windows和Unix中的过程是相同的。下面的UPDATE语句同时为两个匿名账户指定密码:
shell> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('newpwd')
-> WHERE User = '';
mysql> FLUSH PRIVILEGES;
在user表中直接使用UPDATE更新密码后,必须让服务器用FLUSH PRIVILEGES重新读授权表。否则,重新启动服务器前,不会使用更改。
如果你宁愿删除匿名账户,操作方法是:
shell> mysql -u root
mysql> DELETE FROM mysql.user WHERE User = '';
mysql> FLUSH PRIVILEGES;
可以在Windows和Unix中使用DELETE语句。在Windows中,如果你只想删掉具有与root相同权限的匿名账户,方法为:
shell> mysql -u root
mysql> DELETE FROM mysql.user WHERE Host='localhost' AND User='';
mysql> FLUSH PRIVILEGES;
该账户允许匿名访问,但是拥有全部的权限,因此删掉它可以提高安全。
你可以用几种方法为root账户指定密码。以下介绍了三种方法:
· 使用SET PASSWORD语句
· 使用mysqladmin命令行客户端程序
· 使用UPDATE语句
要想使用SET PASSWORD指定密码,用root连接服务器并执行两个SET PASSWORD语句。一定要使用PASSWORD()函数来加密密码。
在Windows中的语句:
shell> mysql -u root
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR 'root'@'%' = PASSWORD('newpwd');
在Unix中的语句:
shell> mysql -u root
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR 'root'@'host_name' = PASSWORD('newpwd');
用服务器主机名替换第二个SET PASSWORD语句中的host_name。这是你指定匿名账户密码的主机名。
要想使用mysqladmin为root账户指定密码,执行下面的命令:
shell> mysqladmin -u root password "newpwd"
shell> mysqladmin -u root -h host_name password "newpwd"
上述命令适用于Windows和Unix。用服务器主机名替换第二个命令中的host_name。不一定需要将密码用双引号引起来,但是你如果密码中包含空格或专用于命令解释的其它字符,则需要用双引号引起来。
你还可以使用UPDATE直接修改user表。下面的UPDATE语句可以同时为两个root账户指定密码:
shell> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('newpwd')
-> WHERE User = 'root';
mysql> FLUSH PRIVILEGES;
UPDATE语句适用于Windows和Unix。
设置完密码后,当你连接服务器时你必须提供相应密码。例如,如果你想要用mysqladmin 关闭服务器,可以使用下面的命令:
shell> mysqladmin -u root -p shutdown
Enter password: (enter root password here)
注释:如果你设置了root密码后忘记了密码,从A.4.1节,“如何复位根用户密码”中查阅重设密码的方法。
你可以使用GRANT语句设置新账户。相关说明参见5.8.2节,“向MySQL增加新用户账户”。
做为一般原则,我们建议从一个发布系列升级到另一个发布系列时,你应当先升级到它的下一个系列而不要跳过。例如,如果你目前正运行MySQL 3.23,想要升级到较新的系列,要升级到MySQL 4.0而不要升级到5.0或5.1。
下面的项列出了升级时的相关信息:
· 从MySQL 5.0升级到5.1前,请阅读2.10.1节,“从5.0版升级”和附录D:MySQL变更史。其中提供了MySQL 5.1相对于MySQL 5.0的新特性或不同特性。如果你想要从MySQL 5.0以前的发布系列升级,应当依次升级到下一个发布系列,直到达到MySQL 5.0,然后再升级到MySQL 5.1。关于从MySQL 5.0升级的信息,参见MySQL 5.0 参考手册;对于更早的发布,参见MySQL 4.1参考手册。
· 在升级前应先备份数据库。
· 如果在Windows中运行MySQL服务器,参见2.3.15节,“在Windows下升级MySQL”。
· 从MySQL 5.0升级到5.1更改MySQL数据库中的 授权表;增加了列和表以支持新功能。为了充分利用这些特性,应确保授权表是最新的。升级授权表的过程参见2.10.2节,“升级授权表”。在升级前,你可能想要使用mysqldump来转储表;升级后,可以使用mysql或mysqlimport重建、重装 授权表来重载dump(备份)文件。
· 如果你正复制,关于升级复制设置的信息参见6.6节,“升级复制设置”。
· 如果安装包括mysqld-max服务器的MySQL-Max分发版,则后面要升级到非Max版的MySQL,mysqld_safe仍然试图运行旧的mysqld-max服务器。如果升级,应当手动删掉旧的mysqld-max服务器以确保mysqld_safe运行新的mysqld服务器。
只要你的MySQL版本属于相同的发布系列,总是可以在不同的版本之间的相同架构上移动MySQL格式文件和数据文件。目前的产品发布系列是5.1。如果运行MySQL时更改字符集,必须对所有MyISAM表运行myisamchk -r -q --set-character-set=charset。否则,索引顺序将会出错,因为更改字符集也会更改排序。
如果你使用新版本时比较小心,在安装新的MySQL前可以重新命名旧的mysqld。例如,如果你想要从MySQL 5.0.13升级到5.1.10, 将当前的服务器从mysqld重新命名为mysqld-5.0.13。如果新的mysqld出现问题,只需要关闭并用旧的mysqld重新启动。
升级后,如果你遇到重新编译的客户端程序问题,例如Commands out of sync或不期望的内核转储,可能是编译程序时使用了旧的头文件或库文件。出现这种情况,应当检查mysql.h文件和libmysqlclient.a库的日期,以验证它们是否来自新的MySQL分发版。如果不是,用新的头文件和库重新编译程序。
如果出现问题,例如新mysqld服务器不启动或没有密码不能连接,验证是否使用了以前安装的旧my.cnf文件。可以用--print-defaults选项检查(例如,mysqld --print-defaults)。如果显示程序名之外的其它内容,说明有一个活动my.cnf文件影响了服务器或客户端操作。
当安装新的MySQL发布时,最好重建并重装Perl DBD::mysql 模块。同样适用于其它MySQL接口,例如PHP mysql扩展名和Python MySQLdb模块。
当从5.0升级到5.0.10或更高版本时请注意必须运行mysql_fix_privilege_tables(或在Windows中运行mysql_fix_privilege_tables.sql)。否则,不能创建保存的过程。相关过程参见2.10.2节,“升级授权表”。
一些发布对授权表(MySQL数据库中的表)的结构进行了更改以增加新的权限或特性。当你更新到新版本 MySQL时,要想确保授权表最新,应当运行mysql_fix_privilege_tables脚本来更新 授权表。相关过程参见5.4节,“mysql_fix_privilege_tables:升级MySQL系统表”。
如果你从MySQL 4.1或更早版本升级,授权表升级过程为CREATE VIEW和SHOW VIEW权限增加了视图相关的列。这些权限位于全局和数据库 级。在这种情况下,MySQL 5.1版MySQL_fix_privilege_ tables将user表中的Create_priv值复制到Create_view_priv和 Show_view_priv列。
你可以在支持相同浮点格式的不同架构之间为MyISAM表复制.frm、.MYI和.MYD文件。(MySQL关注所有字节交换问题)。请参见15.1节,“MyISAM存储引擎”。
如果你需要在不同的架构之间转移数据库,可以使用mysqldump创建含有SQL语句的文件。然后你可以将文件转移到其它机器上,并将它输入到MySQL客户端。
使用mysqldump --help来看有哪些选项可用。如果你正将数据移动到更新版本的MySQL,你应当使用mysqldump –opt来利用各种优化性能来产生更小、可以更快处理的转储文件。
在两台机器之间移动数据库的最简单(尽管不是最快)的方法是在数据库所在的机器上运行下面的命令:
shell> mysqladmin -h 'other_hostname' create db_name
shell> mysqldump --opt db_name | mysql -h 'other_hostname' db_name
如果你想要从远程机器通过慢速网络复制数据库,可以使用:
shell> mysqladmin create db_name
shell> mysqldump -h 'other_hostname' --opt --compress db_name | mysql db_name
还可以将结果保存到文件中,然后将文件转移到目标机器上并将文件装载到数据库中。例如,可以在源机器上使用下面的命令将数据库备份到文件中:
shell> mysqldump --quick db_name | gzip > db_name.contents.gz
(该例子中创建的文件是压缩格式)。将含有数据库内容的文件到目标机上并运行命令:
shell> mysqladmin create db_name
shell> gunzip < db_name.contents.gz | mysql db_name
还可以使用mysqldump和mysqlimport来转移数据库。对于大的表,比只是使用mysqldump要快得多。在下面的命令中,DUMPDIR代表用来保存mysqldump输出的目录全路径名。
首先,创建保存输出文件的目录并备份数据库:
shell> mkdir DUMPDIR
shell>mysqldump --tab=DUMPDIR db_name
然后将DUMPDIR目录中的文件转移到目标机上相应的目录中并将文件装载到MySQL:
shell> mysqladmin create db_name # create database
shell> cat DUMPDIR/*.sql | mysql db_name # create tables in database
shell> mysqlimport db_name DUMPDIR/*.txt # load data into tables
不要忘记复制MySQL数据库,因为授权表保存在该数据库中。你可能需要在新机器上用MySQL root用户运行命令,直到产生MySQL数据库。
将mysql数据库导入目标机器后,执行mysqladmin flush-privileges,以便服务器重载授权表信息。
本节描述了旧版本MySQL比新版本工作得好的情况下,如何降级到旧的MySQL版本。
如果你在同一发布系列(例如,从 5.0.13 到5.0.12)内降级,一般规则是只需要在旧版本的顶部安装新的二进制。不需要对数据库进行任何操作。但是,最好是先进行备份。
下面的项列出了进行降级时应执行的操作:
· 阅读你将要降级的发布系列的升级部分,确定它没有你需要的功能。2.10节,“升级MySQL”。
· 如果该版本有降级部分,你也应当阅读。
只要MySQL版本属于相同的发布系列,你总是可以在不同的版本之间的相同架构上移动MySQL格式文件和数据文件。目前的产品发布系列是5.1。
如果你从一个发布系列降级到另一个发布系列,表储存格式可能不兼容。在这种情况下,你可以在降级嵌使用mysqldump来转储表。降级后,使用mysql或mysqlimport重载转储文件来重新创建表。请参见2.10.3节,“将MySQL数据库拷贝到另一台机器”。
表格式不向下兼容的一般迹象是降级时不能打开表。在这种情况下,使用下面的过程:
1. 停止你想要降级到的旧的MySQL服务器。
2. 重新启动将被降级的新的MySQL服务器。
3. 使用mysqldump创建一个dump(转储)文件来转储不能被旧服务器访问的所有表。
4. 停止新MySQL服务器,重新启动旧MySQL服务器。
将dump(转储)文件重载入旧服务器。表应当可访问。
请注意这些问题的大多数出现在旧的Linux 版本中。如果你运行最新的版本,可能不会发现这些问题。
警告:我们已经发现在SMP系统中Linux 2.2.14 和MySQL会出现一些奇怪的问题。我们还收到来自一些MySQL用户的报告说他们用内核2.2.14使用MySQL时遇到了严重的稳定性问题。如果你正使用该内核,应当升级到2.2.19 (或更新版)或到2.4内核。如果你有一个多CPU盒,应当考虑使用2.4,因为它能大大加速。你的系统将会更稳定。
当使用LinuxThreads时,你应当至少可以看见有三个mysqld 进程在运行。这些实际上是线程。有一个线程是LinuxThreads管理器,一个线程处理连接,另一个线程处理告警和信号。
二进制发布用-staticis连接,说明一般情况你不需要关心系统库的版本。你也不需要安装LinuxThreads。用-staticis连接的程序稍微大于动态连接程序,但也稍微快一些(3-5%)。但是,静态连接程序的一个问题是你不能使用用户定义函数(UDF)。如果你将要写或使用UDF(只适用于C或C++ 编程人员),你必须使用动态链接自己编译MySQL。
二进制分发版的一个已知问题是在使用libc的旧的Linux系统(例如Red Hat 4.x或Slackware)上,你会遇到一些(非致命)主机名解析问题。如果系统使用libc没有使用glibc2,你可能会遇到一些主机名解析和getpwnam()问题。这是因为glibc依靠一些外部库来执行主机名解析和getpwent(), 即使用-staticis编译也如此。这些问题出现在两个方面:
· 当运行mysql_install_db时,你会看见下面的错误消息:
· Sorry, the host 'xxxx' could not be looked up
你可以通过执行mysql_install_db --force来解决该问题,并不在mysql_install_db中执行resolveip测试。不利方面是 你不能在授权表中使用主机名:除了localhost,必须使用IP号。如果你正使用不支持—force的旧版本MySQL,必须使用文本编辑器手动卸载mysql_install中的resolveip测试。
· 当你尝试用--user选项运行mysqld时你还会看见下面的错误:
· getpwnam: No such file or directory
要解决该问题,使用su命令启动mysqld,不要指定--user选项。这样使系统自己更改mysqld进程的用户ID,mysqld不再需要这样做。
另一个解决办法可以解决两个问题,即不使用二进制分发版。获得MySQL源码分发版(RPM或tar.gz格式)并安装。
在一些Linux 2.2版本中,当客户端通过TCP/IP建立大量与mysqld服务器的新连接时,你可能会遇到错误Resource temporarily unavailable。该问题是Linux在你关闭TCP/IP套接字的时间和系统实际释放该套接字的时间之间有一个延迟。只有有限数目的TCP/IP时段有空间,因此如果客户端试图在短时间内建立许多新TCP/IP连接时,你会遇到源不可用错误。例如,当你通过TCP/IP运行MySQL test-connect基准测试时你会看见该错误。
我们已经多次向不同的 Linux 邮件列表询问该问题,但是一直没有找到合适的解决办法。唯一知道的“解决办法”是客户端使用永久连接,或,如果你在同一机器上运行数据库服务器和客户端,使用Unix套接字文件来连接,不要使用TCP/IP连接。
MySQL在Linux上使用 LinuxThreads 。如果你正在使用一个没有glibc2的老的Linux版本,你必须在尝试编译MySQL前安装LinuxThreads。你可以从 http://dev.mysql.com/downloads/os-linux.html获得LinuxThreads。
注意:当你执行INSERT DELAYED时,所用的包括2.1.1及以前的glibc版本在pthread_互斥_timedwait()处理上有一个致命错误,如果你正在使用INSERT DELAYED,我们建议先升级glibc。
请注意Linux 内核和LinuxThreads库默认情况下最多可以处理1,024个线程。如果你计划使用超过1,000个并行连接,需要对LinuxThreads进行一些更改,如下所示:
· 将sysdeps/unix/sysv/linux/bits/local_lim.h中的PTHREAD_THREADS_MAX 增加到4096,将LinuxThreads/internals.h 中的STACK_SIZE减少到256KB。路径相对于glibc的根目录。(请注意如果STACK_SIZE为默认值2MB,MySQL有600-1000个连接时不稳定)。
· 重新编译LinuxThreads,生成新的libpthreads.a库,并重新连接MySQL。
可以从查阅关于LinuxThreads线程限制的详细信息。
还有一个问题会严重影响MySQL的性能,特别是在SMP系统中。在glibc 2.1的LinuxThreads中,对于拥有很多只是短时间内占有互斥体的线程的程序,不能很好地执行互斥。结果出现荒谬的现象:在许多情况下,如果你使用未修改的LinuxThreads连接MySQL,从SMP中去掉卸载处理器实际上会提高MySQL的性能。我们提供了一个glibc 2.1.3的补丁来纠正该行为()。
在glibc 2.2.2中,MySQL使用修改后的互斥,这样甚至比打了补丁的glibc 2.1.3还要好得多。但是,需要注意的是在某些条件下,当前glibc 2.2.2中的互斥代码会高旋,影响了MySQL的性能。通过优化mysqld进程到最高优先级,可以降低在这种情况下出现这种问题的可能性。我们还可以通过补丁来纠正高旋问题,可以从下载。它集成高旋的纠正、线程最大数目和堆栈空间于一体。你需要用补丁patch -p0 在LinuxThreads目录下使用。我们 希望在将来的glibc 2.2发布中能以某种形式将它包括进来。在任何情况下,如果你连接glibc 2.2.2,仍然需要纠正STACK_SIZE和 PTHREAD_THREADS_MAX。我们希望在将来能将默认值纠正到某种程度上可以接受的值,适合高负荷MySQL设置,因此用来产生你自己的构建的 命令可以简化到到./configure; make; make install。
我们建议你使用这些补丁来构建专用的libpthreads.a静态版本,并只使用它同MySQL实现静态链接。我们知道这些补丁对于MySQL很安全 并大大改善了它的性能,但是我们还不能断言它在其它应用程序上的效果如何。如果你需要将其它使用LinuxThreads的应用程序同打了补丁的静态版本的库连接,或构建一个打了补丁的共享版本,并将它安装到系统中,你将自己承担风险。
如果你在安装MySQL的过程中遇到任何奇怪的问题,或一些常用实用工具被悬挂起来,很可能是库或编译器相关问题。在这种情况下,使用我们的二进制来解决。
如果你连接你自己的MySQL客户端程序,运行时你会看见下面的错误:
ld.so.1: fatal: libmysqlclient.so.#:
open failed: No such file or directory
使用下面的方法可以避免该问题:
· 用-Wl,r/full/path/to/libmysqlclient.so标记连接客户端,不要使用-Lpath)。
· 将libmysqclient.so复制到/usr/lib。
· 运行客户端程序前,将libmysqlclient.so所在目录的路径名增加到LD_RUN_PATH环境变量。
如果使用Fujitsu编译器 (fcc/FCC),编译MySQ时可能会出现一些问题,因为Linux头文件主要面向gcc。以下的configure行应当结合fcc/FCC使用:
CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE \
-DCONST=const -DNO_STRTOLL_PROTO" \
CXX=FCC CXXFLAGS="-O -K fast -K lib \
-K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE \
-DCONST=const -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO \
'-D_EXTERN_INLINE=static __inline'" \
./configure \
--prefix=/usr/local/mysql --enable-assembler \
--with-mysqld-ldflags=-all-static --disable-shared \
--with-low-memory
在MySQL安装目录或MySQL源码树下的support-files目录下可以找到mysql.server。你可以将它安装为/etc/init.d/mysql,以便自动启动和关闭MySQL。请参见2.9.2.2节,“自动启动和停止MySQL”。
如果MySQL不能打开足够的文件或连接,可能是你没有将Linux配置为处理足够的文件。
在Linux 2.2及以上版本中,你可以检查分配的文件的数目:
shell> cat /proc/sys/fs/file -max
shell> cat /proc/sys/fs/dquot-max
shell> cat /proc/sys/fs/super-max
如果有超过16MB的内存,应当在启动脚本中增加如下内容(例如,在SuSE Linux中:/etc/init.d/boot.local):
echo 65536 > /proc/sys/fs/file-max
echo 8192 > /proc/sys/fs/dquot-max
echo 1024 > /proc/sys/fs/super-max
还可以用root从命令行运行echo命令,但是下一次重新启动计算机时这些设定值会丢掉。
另外,可以使用许多Linux分发版使用的sysctl工具设置启动参数(包括SuSE Linux 8.0和以后版本)。将下面的值放到文件 /etc/sysctl.conf中:
# Increase some values for MySQL
fs.file-max = 65536
fs.dquot-max = 8192
fs.super-max = 1024
你还应将以下内容加入/etc/my.cnf:
[mysqld_safe]
open-files-limit=8192
这样服务器连接和打开文件的总数目可以达到8,192。
LinuxThreads的STACK_SIZE常数控制在寻址空间中线程堆栈的占用空间。它需要足够大,以保证每个线程堆栈有足够的空间,但是应足够小,防止某些线程的堆栈运行全局mysqld数据。遗憾的是,根据我们的发现,如果你用mmap()映射目前正使用的寻址,Linux成功运行 后不会映射映射区,将会清空整个地址页上的数据而不会返回错误信息。因此,mysqld或其它线程应用程序的安全依靠创建线程的代码的“绅士”行为。用户必须采取措施以确保在任何时间运行线程的数目相对线程堆栈应足够低,以防止全局堆内存。使用mysqld时,你应当为max_connections变量设置合理的值强制该行为。
如果你自己构建MySQL,你可以为LinuxThreads打补丁以便更好地使用堆栈。请参见2.12.1.3节,“Linux源码分发版说明”。如果你不想为LinuxThreads打补丁,你应当将max_connections的值设置为不超过500。如果你有大的关键字缓冲区、大的堆内存表,或其它使mysqld分配大量内存的东西,或如果你用2GB的补丁运行2.2内核,max_connections的值应当更低。如果你正使用我们的二进制或RPM版本,可以安全地将max_connections设置为1500(假定没有大的关键字缓冲区或有大量数据的堆内存表。将LinuxThreads中的STACK_SIZE降低得越低,可以安全地创建越多的线程。我们推荐的值的范围为128KB到256KB。
如果你正使用大量的并行连接,在2.2内核中你可能会遇到一个“特性”,即通过对进程的分支或克隆子进程的行为进行罚分,来试图防止轰炸攻击。这样你增加并行客户端的数量时,MySQL不能正确响应。在单CPU系统中,我们已经发现该现象,即线程创建地很慢;连接MySQL的时间很长(长达1分钟),并且关闭的时间也很长。在多CPU系统中,我们已经观察到随着客户端数目的增加,查询速度逐渐下降。在寻求解决办法的过程中,我们收到了一个用户的内核补丁,他声称该补丁可以解决他的问题。从可以下载该补丁。我们已经在开发和生产系统上对该补丁进行了广泛的测试。它可以大大改善MySQL的性能,而不会造成任何问题,我们向仍然在2.2内核运行高负荷服务器的用户推荐它。
在2.4内核中已经对该问题进行了修复,因此如果你不满意当前系统的性能,不要为2.2 内核打补丁,在SMP系统中升级到2.4版要容易地多,升级不仅可以修复错误,还可以使SMP更好地加速。
我们已经在双CPU机器上在2.4内核中对MySQL进行了测试,发现MySQL的比例要好得多。1,000名客户查询时,还看不到速度有实质上的下降,MySQL的比例因子(最大吞吐量与一个客户端的吞吐量的比例)为180%。我们在四-CPU系统中也观察到了类似的结果:当客户数目上升到1,000名时还没有实质上的减慢, 比例因子为300%。根据这些结果,对于使用2.2内核的高负荷SMP服务器,我们绝对建议升级到 2.4内核。
我们已经发现,在2.4内核中应使用可能的最高优先级来运行mysqld进程,以获得最佳性能。可以通过为mysqld_safe加renice -20 $$命令来实现。在四-CPU系统中的测试中,提高优先级在400个客户时会使吞吐量增加60%。
我们目前还想搜集关于MySQL在four-way和eight-way系统上用2.4内核执行的性能的更详细信息。如果你访问了这些系统并进行了一些基准测试,请将结果用email发送到<>。我们将对它们进行审查以包括进手册中。
如果用ps运行mysqld服务器进程时发现进程死掉了,一半是MySQL中有缺陷或数据库表崩溃了。请参见A.4.2节,“如果MySQL依然崩溃,应作些什么”。
如果mysqld死掉并给出SIGSEGV信号,要想在Linux中对内核进行调试,你可以用--core-file选项启动mysqld。注意你还可能需要通过向mysqld_safe添加ulimit -c 1000000或用--core-file-size=1000000启动mysqld_safe来加大内核文件的大小。请参见5.1.3节,“mysqld_safe:MySQL服务器启动脚本”。
MySQL需要5.4.12或更新版本的libc。已知它可以在libc 5.4.46中工作。glibc 2.0.6和更新版本应当也可以工作。Red Hat的glibc RPM有一些问题,因此如果你遇到问题,应看看是否有更新版。已知glibc 2.0.7-19和2.0.7-29 RPM可以工作。
如果你正使用Red Hat 8.0或更新的glibc 2.2.x库,你会看见mysqld执行gethostbyaddr()时会死掉。这是因为新的glibc库在执行该调用时需要大于128KB的堆栈空间。要想修复该问题,用--thread-stack=192K选项启动mysqld。(在MySQL 4以前的版本中应使用-O thread_stack=192K)。 在MySQL 4.0.10和以上版本中,该堆栈空间值即为默认值,因此你不会看见该问题。
如果你正使用gcc 3.0和以上版本编译MySQL,在编译MySQL前你必须先安装libstdc++v3库;如果不这样做,在联接过程中会遇到关于丢失__cxa_pure_virtual符号的错误。
在一些旧的Linux分发版中,configure会生成如下错误:
Syntax error in sched.h. Change _P to __P in the
/usr/include/sched.h file.
See the Installation chapter in the Reference Manual.
只需要按照错误消息的提示操作。对只有一条下划线的_P名再增加一条下划线,然后重新尝试。
编译时可能会出现警告。下面的警告可以忽略:
mysqld.cc -o objs-thread/mysqld.o
mysqld.cc: In function `void init_signals()':
mysqld.cc:315: warning: assignment of negative value `-1' to
`long unsigned int'
mysqld.cc: In function `void * signal_hand(void *)':
mysqld.cc:346: warning: assignment of negative value `-1' to
`long unsigned int'
如果mysqld启动时总是出现转储内核, 问题可能是你使用了旧的/lib/libc.a。尝试重新对其命名,然后删掉sql/mysqld并重新执行make install然后再次尝试。已经报导在部分Slackware安装中出现了该问题。
当链接mysqld时如果出现下面的错误,说明libg++.a安装不正确:
/usr/lib/libc.a(putc.o): In function `_IO_putc':
putc.o(.text+0x0): multiple definiti在of `_IO_putc'
你可以使用libg++.a运行configure来避免该问题:
shell> CXX=gcc ./configure
我们已经用我们的基准和测试套件在Alpha中测试了MySQL 5.1,看起来工作得不错。
我们目前在配置Alpha EV6处理器的Compaq DS20机器上,在SuSE Linux 7.0中对AXP、内核2.4.4-SMP、Compaq C编译器(V6.2-505)和Compaq C++编译器(V6.3-006)构建MySQL二进制软件包。
你可以从找到上述编译器。使用这些编译器,得到的MySQL性能比gcc要好9-14%。
在Alpha版MySQL中,我们在编译选项中使用-arch generic标记,可以确保二进制在所有Alpha处理器中运行。我们还采用静态编译以避免库问题。configure命令应为:
CC=ccc CFLAGS="-fast -arch generic" CXX=cxx \
CXXFLAGS="-fast -arch generic -noexceptions -nortti" \
./configure --prefix=/usr/local/mysql --disable-shared \
--with-extra-charsets=complex --enable-thread-safe-client \
--with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
如果想要使用egcs,可以使用下面的configure行:
CFLAGS="-O3 -fomit-frame-pointer" CXX=gcc \
CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors \
-fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --disable-shared
已知的在Linux-Alpha中运行MySQL的问题:
· 在gdb 4.18 中不能调试线程应用程序。你应当使用gdb 5.1。
· 使用gcc时如果你尝试静态链接mysqld,启动时映像会导致转储内核。换句话说,使用gcc时不要使用--with-mysqld-ldflags=-all-static。
要想让MySQL在Linux IA-64中编译,我们用 gcc 2.96构建时使用下面的configure命令:
CC=gcc \
CFLAGS="-O3 -fno-omit-frame-pointer" \
CXX=gcc \
CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
-fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql \
"--with-comment=Official MySQL binary" \
--with-extra-charsets=complex
在IA-64中,MySQL客户端二进制使用共享库。这意味着如果你将我们的二进制分发版安装到/usr/local/mysql之外的其它位置,需要将libmysqlclient.so安装目录路径加到/etc/ld.so.conf文件或LD_LIBRARY_PATH环境变量中。