MySQL lower_case_table_names导致PHP连接错误

时间:2015-08-06 04:23:59

标签: php mysql database mysqli

在MySQL中,lower_case_table_names全局变量确定在将表名写入磁盘时是否保留字母大小写,以及表名匹配是否区分大小写。根据{{​​3}}:

  

如果您使用的是InnoDB或MySQL Cluster(NDB)表,则应进行设置   在所有平台上将此变量设置为1以强制将名称转换为   小写。

我的网站位于带有MySQL 5.6.23和PHP 5.5.25的Apache 2.4上。我的大多数表都是MyISAM,但我想将它们转换为InnoDB。根据上面的指令,我试图在MySQL的配置文件中设置lower_case_table_names=1。但是,重新启动服务器后,我无法再使用mysqli扩展从我的PHP代码连接到数据库。代码$this->mysqli = new \mysqli($host,$user,$pwd,$db_name,$port);返回mysqli->connect_error = "Access denied for user 'username'@'localhost' (using password: YES)"。我确信登录凭据很好,原因如下:

  • 在PHP环境之外,我可以使用连接到数据库 相同的凭据,使用远程工具(SQLyog)。
  • 如果我从配置文件中删除lower_case_table_names=1行 重新启动服务器,事情再次发挥作用。

在MySQL服务器启动序列期间 - 当lower_case_table_names=1时 - 错误日志显示3个警告:

  • [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
  • [Warning] 'db' entry '%_ldap_ou=addressbook cpldap@localhost' had database in mixed case that has been forced to lowercase because lower_case_table_names is set. It will not be possible to remove this privilege using REVOKE.
  • [Warning] 'db' entry 'logaholicdb_host logaholic@localhost' had database in mixed case that has been forced to lowercase because lower_case_table_names is set. It will not be possible to remove this privilege using REVOKE.

在两个配置下也记录了几个[Note]个条目。删除lower_case_table_names=1行后,仅显示第一个警告。被拒绝访问的用户对相关数据库具有以下权限(SHOW GRANTS FOR 'username'@'localhost';

的结果
  
      
  • 上授予使用权。以'用户名'@'localhost'通过密码识别'* 6DF294D9BAA539074CFC4DD08E77909FE53CFCE1'
  •   
  • GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,REFERENCES,INDEX,ALTER,CREATE TEMPORARY TABLES,LOCK TABLES,EXECUTE,CREATE   查看,显示视图,创建常规,更改常规my_db。* TO   '用户名' @ 'localhost' 的
  •   

为什么连接失败,我该如何解决?

2 个答案:

答案 0 :(得分:1)

步骤1:首先通过mysqldump命令备份你的数据库(所有故事)。

步骤2:现在更改小写的配置设置。

步骤3:现在重启mysql服务。

步骤4:现在恢复备份。

默认情况下,所有以小写字母写在磁盘上的表名称甚至可以通过lower / upper / camel case来调用它们,但实际上它们将以小写形式存储在服务器上。

答案 1 :(得分:0)

经过进一步研究,这是我发现的。

破坏我的网站的问题实际上并不是建立与MySQL的连接。我之前拒绝访问的错误是由另一个问题引起的。我的调试会话是查询具有不同访问权限的开发数据库,​​因此在调试问题时我认为连接失败是原因 - 这是调试本身的问题。其他东西实际上打破了我的网站。

最终我发现设置lower_case_table_names=1似乎会破坏名称为大写字母的任何表上的SQL查询执行。例如,我有一个名为tblCountries的表。如果我运行查询SELECT * FROM tblCountries,MySQL将返回错误tblcountries does not exist。请注意,错误包含小写' c'。

对没有大写的表名的查询似乎工作正常:SELECT * FROM user有效,因为该表名(user)没有大写。所以我尝试使用查询tblCountriestblcountries重命名为RENAME TABLE 'tblCountries' to 'tblcountries',但MySQL失败并显示错误Can't find file: './db_name/tblcountries.frm' (errno: 2 - No such file or directory)

这两个问题似乎都表明服务器在运行查询之前将所有内容都放在小写字母中。实际上,虽然没有文件tblcountries.frm,但在光盘上,文件tblCountries.frm以及文件tblCountries.MYDtblCountries.MYI一起存在。如果我通过替换' C'来手动重命名所有三个文件。使用' c',相同的查询SELECT * FROM tblCountries成功执行。

所以我至少有两个选择,但不知道哪个更好,或者是否有第三个最佳选择:

1)删除lower_case_table_names=1选项以在执行查询时使服务器尊重字母大小写;然后对每个表执行RENAME TABLE 'tblCountries' to 'tblcountries'以删除所有大写字母;最后,当所有大写字母被移除后,重新插入lower_case_table_names=1

2)只需像tblCountries.frm那样手动重命名磁盘上的文件。这似乎是一种更简单的方法,但我对MySQL的了解不足以了解它是否会给我带来更多问题。