将bind-address = 127.0.0.1注释掉(即在行首加#),如下: 复制代码 代码如下: # Instead of skip-networking the default is now to listen only on # localhost which is more compatible and is not less secure. # bind-address = 127.0.0.1
然后,删除匿名用户。SQL如下: 复制代码 代码如下: delete from user where user="";
3.增加允许远程访问的用户或者允许现有用户的远程访问。 接着上面,删除匿名用户后,给root授予在任意主机(%)访问任意数据库的所有权限。SQL语句如下: 复制代码 代码如下: mysql> grant all privileges on *.* to "root"@"%" identified by "123456" with grant option;
如果需要指定访问主机,可以把%替换为主机的IP或者主机名。另外,这种方法会在数据库mysql的表user中,增加一条记录。如果不想增加记录,只是想把某个已存在的用户(例如root)修改成允许远程主机访问,则可以使用如下SQL来完成: 复制代码 代码如下: update user set host="%" where user="root" and host="localhost";
4.退出数据库 复制代码 代码如下: mysql> exit
在MySQL Shell执行完SQL后,需要退出到Bash执行系统命令,需要执行exit。因为这个太常用也太简单。以下内容就提示“退出”,不再重复列出这个命令。 5.重启数据库 完成上述所有步骤后,需要重启一下数据库,才能让修改的配置生效。执行如下命令重启数据库: 复制代码 代码如下: >sudo service mysql restart
到此为止,应该就可以远程访问数据库了。 当然,“雄关漫道真如铁”,世界并不是想象的那么图样图森破,可能还会遇到一些问题,影响到正常使用。下面,D瓜哥把自己遇到的一些问题整理处理,方便各位朋友参考解决。(退一步讲,没有这些问题来撑门面,D瓜哥该叫“终极解决办法”吗?!哈哈) 常见问题解答 华仔说的好啊,“出来混的都是要还的”。对于我们从事挨踢行业的小伙伴来说,“出来混的都是从问题堆里走的”。冯巩也说的好,“作为北京人,兜里没揣两千块钱都不好意思给别人打招呼”。D瓜哥想,对于干挨踢的小伙伴们来说,没遇到过问题,都不好意思说自己是干挨踢的。所以,对于一些常见的问题,或者说是常用操作可能引发的问题来说,有必要整理一下,方便以后随时查阅使用。 ERROR 1045 (28000)错误的原因以及解决办法 复制代码 代码如下: >mysql -uroot -p123456 Warning: Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user "root"@"localhost" (using password: YES)
如果没有按照上面流程,删除匿名用户,再或者你是按照网上查的资料来进行设置(大多都没有“删除匿名用户”这步),都可能导致这个问题。至于这个问题的原因说起来,D瓜哥感觉“怪怪”的。要说清楚这个原因,还得从MySQL数据库的用户认证机制说起。 MySQL中,用户相关的信息存在数据库mysql的user。然我们看一下该表的结构,命令以及返回值如下: 复制代码 代码如下: mysql> desc user; +------------------------+-----------------------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------------+-----------------------------------+------+-----+---------+-------+ | Host | char(60) | NO | PRI | | | | User | char(16) | NO | PRI | | | | Password | char(41) | NO | | | | | Select_priv | enum("N","Y") | NO | | N | | | Insert_priv | enum("N","Y") | NO | | N | | | Update_priv | enum("N","Y") | NO | | N | | | Delete_priv | enum("N","Y") | NO | | N | | | Create_priv | enum("N","Y") | NO | | N | | | Drop_priv | enum("N","Y") | NO | | N | | | Reload_priv | enum("N","Y") | NO | | N | | | Shutdown_priv | enum("N","Y") | NO | | N | | | Process_priv | enum("N","Y") | NO | | N | | | File_priv | enum("N","Y") | NO | | N | | | Grant_priv | enum("N","Y") | NO | | N | | | References_priv | enum("N","Y") | NO | | N | | | Index_priv | enum("N","Y") | NO | | N | | | Alter_priv | enum("N","Y") | NO | | N | | | Show_db_priv | enum("N","Y") | NO | | N | | | Super_priv | enum("N","Y") | NO | | N | | | Create_tmp_table_priv | enum("N","Y") | NO | | N | | | Lock_tables_priv | enum("N","Y") | NO | | N | | | Execute_priv | enum("N","Y") | NO | | N | | | Repl_slave_priv | enum("N","Y") | NO | | N | | | Repl_client_priv | enum("N","Y") | NO | | N | | | Create_view_priv | enum("N","Y") | NO | | N | | | Show_view_priv | enum("N","Y") | NO | | N | | | Create_routine_priv | enum("N","Y") | NO | | N | | | Alter_routine_priv | enum("N","Y") | NO | | N | | | Create_user_priv | enum("N","Y") | NO | | N | | | Event_priv | enum("N","Y") | NO | | N | | | Trigger_priv | enum("N","Y") | NO | | N | | | Create_tablespace_priv | enum("N","Y") | NO | | N | | | ssl_type | enum("","ANY","X509","SPECIFIED") | NO | | | | | ssl_cipher | blob | NO | | NULL | | | x509_issuer | blob | NO | | NULL | | | x509_subject | blob | NO | | NULL | | | max_questions | int(11) unsigned | NO | | 0 | | | max_updates | int(11) unsigned | NO | | 0 | | | max_connections | int(11) unsigned | NO | | 0 | | | max_user_connections | int(11) unsigned | NO | | 0 | | | plugin | char(64) | YES | | | | | authentication_string | text | YES | | NULL | | | password_expired | enum("N","Y") | NO | | N | | +------------------------+-----------------------------------+------+-----+---------+-------+ 43 rows in set (0.00 sec)
或者查看一下该表的建表语句。命令如下: 复制代码 代码如下: mysql> show create table user;
由于返回值中掺杂了一些不必要的无用信息,为了方便大家查看,D瓜哥对返回值做了简单的处理,只把最主要的建表语句部分提取出来。如下: 复制代码 代码如下: CREATE TABLE `user` ( `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT "", `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT "", `Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT "", `Select_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Insert_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Update_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Delete_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Create_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Drop_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Reload_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Shutdown_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Process_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `File_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Grant_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `References_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Index_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Alter_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Show_db_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Super_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Create_tmp_table_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Lock_tables_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Execute_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Repl_slave_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Repl_client_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Create_view_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Show_view_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Create_routine_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Alter_routine_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Create_user_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Event_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Trigger_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `Create_tablespace_priv` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", `ssl_type` enum("","ANY","X509","SPECIFIED") CHARACTER SET utf8 NOT NULL DEFAULT "", `ssl_cipher` blob NOT NULL, `x509_issuer` blob NOT NULL, `x509_subject` blob NOT NULL, `max_questions` int(11) unsigned NOT NULL DEFAULT "0", `max_updates` int(11) unsigned NOT NULL DEFAULT "0", `max_connections` int(11) unsigned NOT NULL DEFAULT "0", `max_user_connections` int(11) unsigned NOT NULL DEFAULT "0", `plugin` char(64) COLLATE utf8_bin DEFAULT "", `authentication_string` text COLLATE utf8_bin, `password_expired` enum("N","Y") CHARACTER SET utf8 NOT NULL DEFAULT "N", PRIMARY KEY (`Host`,`User`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT="Users and global privileges"
可以看到数据库中有如上这些用户。那么,如果有"root"@"localhost"登录时,怎么匹配呢? 根据MySQL官方文档MySQL :: MySQL 5.6 Reference Manual :: 6.2.4 Access Control, Stage 1: Connection Verification里是如下面这样说的: 复制代码 代码如下: When multiple matches are possible, the server must determine which of them to use. It resolves this issue as follows: Whenever the server reads the user table into memory, it sorts the rows. When a client attempts to connect, the server looks through the rows in sorted order. The server uses the first row that matches the client host name and user name. The server uses sorting rules that order rows with the most-specific Host values first. Literal host names and IP addresses are the most specific. (The specificity of a literal IP address is not affected by whether it has a netmask, so 192.168.1.13 and 192.168.1.0/255.255.255.0 are considered equally specific.) The pattern ‘%" means “any host” and is least specific. The empty string ” also means “any host” but sorts after ‘%". Rows with the same Host value are ordered with the most-specific User values first (a blank User value means “any user” and is least specific).
请注意这句话:“The server uses sorting rules that order rows with the most-specific Host values first. Literal host names and IP addresses are the most specific.” 那么,当从本地连接到数据库时,匿名用户将覆盖其他如"[any_username]"@"%"之类的用户。具体匹配过程如下: 在"root"@"localhost"可以匹配"root"@"%",""也可以匹配root,那么"root"@"localhost"也可以匹配""@"localhost"。根据上面的文档显示,主机(host)有比用户名称user更高的匹配优先级,则localhost比%有比更高的匹配优先级。所以,""@"localhost"比"root"@"%"匹配优先级更高,"root"@"localhost"就匹配到了""@"localhost"。根据我们上面的查询结果来看,""@"localhost"的密码为空,与登录时提供的密码123456不匹配。所以,就登录失败了。 说到这里,想必大家已经想到了解决方案:很简单,直接把匿名用户删掉就可以了。 但是,现在的问题时,在本地根本登录不上数据库,更别扯删除数据了。 怎么办?D瓜哥想到了三个解决办法,方法如下: ①、比较扯淡的解决方法,在另外一台电脑或者虚拟机上,远程连接这个数据库 这是我想到的一个比较扯淡的解决方法。既然我们已经允许了远程连接,那么我们就可以在另外一台电脑或者另外一个虚拟机上,远程连接到这个数据库,然后把删除匿名用户。步骤如下: 1.在远程电脑上连接到该数据库。命令如下: 复制代码 代码如下: mysql -h192.168.1.119 -uroot -p123456
2.然后,切换到mysql数据库。命令如下: 复制代码 代码如下: use mysql
3.删除匿名用户。SQL如下: 复制代码 代码如下: delete from user where user="";
除此之外,还可以修改MySQL的配置文件/etc/mysql/my.cnf,在[mysqld]的部分中加上一句:skip-grant-tables。但是,使用这种方式在重置完密码后,还要再重新删除这句话。D瓜哥个人感觉比较麻烦。仅做了解,不推荐使用这种方式。 3.登录数据库。命令如下: 复制代码 代码如下: mysql -uroot
4.切换到mysql数据库 复制代码 代码如下: mysql> use mysql
5.修改root帐号密码 复制代码 代码如下: mysql> update user set password=password("123456") where user="root";
6.退出,然后重启数据库 复制代码 代码如下: >sudo service mysql restart
现在,应该就可以使用新密码正常访问数据库了。 ERROR 2002 (HY000)错误的原因以及解决办法 在登录数据库的过程中,可能遇到如下错误: 复制代码 代码如下: mysql -uroot ERROR 2002 (HY000): Can"t connect to local MySQL server through socket "/var/run/mysqld/mysqld.sock" (2)
刚开始,D瓜哥以为是数据库没有正确创建mysqld.sock这个文件,到/var/run/mysqld/下查看了一下,确实没有这个文件。 这是怎么回事?怎么会没有这个文件呢?难道数据库没有启动起来。使用如下命令查看一下: 复制代码 代码如下: >ps aux | grep mysql
Shit,竟然什么都没有输出。看来确实是数据库没有启动起来。使用如下命令启动数据库: 复制代码 代码如下: >sudo service mysql start
然后就可以正常登录了。 关于这个问题,D瓜哥还想再多说两句:这个错误的根本原因是没有找到mysqld.sock文件,造成这个问题的原因有两种:一根本没有创建这个文件,也就是没有启动数据库,这也是D瓜哥在这里介绍的原因;另外一个原因也有可能是创建的目录不在默认目录,或者连接数据库时指定的这个文件目录和实际产生的目录不符。D瓜哥在网上查资料时,也印着了这个猜测。部分网友的问题就是D瓜哥所说的第二个原因造成的。所以,网上对于这个问题的解决方案还存在另外一个方法。因为D瓜哥没有遇到,而且情况又比较多,D瓜哥这里就不再过多介绍了。请遇到这个问题的朋友自行查资料解决。 ERROR 2003 (HY000)错误的原因以及解决办法。 复制代码 代码如下: $ mysql -h192.168.1.113 -uroot -p123456 Warning: Using a password on the command line interface can be insecure. ERROR 2003 (HY000): Can"t connect to MySQL server on "192.168.1.113" (111)
是说话,出现这个问题,D瓜哥也很蛋疼。不知这又是怎么搞的!不过,好在有错误代码(ERROR 2003 (HY000)),有了这个就有了打开解决方法之门的钥匙。解决方法垂手可得。 用Google百度一下,之后在StackOverflow上查到了原因:MySQL数据库的配置文件/etc/mysql/my.cnf中的bind-address = 127.0.0.1没有注释掉,导致MySQL只能接收本地的访问。 知道了原因,解决方法也就随之而来,注释掉这行,然后重启服务器。具体做法,参考本文开头部分。 ERROR 1130错误的原因以及解决办法 D瓜哥在查资料的过程中,还遇到别人提到的一个错误。日志如下: 复制代码 代码如下: ERROR 1130: Host "192.168.1.3" is not allowed to connect to this MySQL server