简体   繁体   English

MySQL lower_case_table_names导致PHP连接错误

[英]MySQL lower_case_table_names causes PHP connection error

In MySQL, the lower_case_table_names global variable determines whether letter case is preserved when a table name is written to disk, and whether matching of table names is case sensitive. 在MySQL中, lower_case_table_names全局变量确定将表名写入磁盘时是否保留字母大小写,以及表名的匹配是否区分大小写。 According to the docs : 根据文档

If you are using InnoDB or MySQL Cluster (NDB) tables, you should set this variable to 1 on all platforms to force names to be converted to lowercase. 如果您使用的是InnoDB或MySQL Cluster(NDB)表,则应在所有平台上将此变量设置为1,以强制将名称转换为小写。

My site is on a Apache 2.4 with MySQL 5.6.23 and PHP 5.5.25. 我的网站位于具有MySQL 5.6.23和PHP 5.5.25的Apache 2.4上。 Most of my tables are MyISAM but I would like to convert them to InnoDB. 我的大多数表都是MyISAM,但我想将它们转换为InnoDB。 In accordance with the directive above, I tried to set lower_case_table_names=1 in MySQL's config file. 按照上面的指令,我尝试在MySQL的配置文件中设置lower_case_table_names=1 However, after restarting the server, I can no longer connect to the database from my PHP code using the mysqli extension. 但是,重新启动服务器后,我无法再使用mysqli扩展程序从PHP代码连接到数据库。 The code $this->mysqli = new \\mysqli($host,$user,$pwd,$db_name,$port); 代码$this->mysqli = new \\mysqli($host,$user,$pwd,$db_name,$port); returns mysqli->connect_error = "Access denied for user 'username'@'localhost' (using password: YES)" . 返回mysqli->connect_error = "Access denied for user 'username'@'localhost' (using password: YES)" I am certain that the login credentials are good for the following reasons: 我确定登录凭据是好的,原因如下:

  • Outside of the PHP environment, I can connect to the database using the same credentials, with a remote tool (SQLyog). 在PHP环境之外,我可以使用相同的凭据通过远程工具(SQLyog)连接到数据库。
  • If I remove lower_case_table_names=1 line from the config file and restart the server, things work again. 如果我从配置文件中删除lower_case_table_names=1行,然后重新启动服务器,事情将再次起作用。

During the MySQL server startup sequence -- when lower_case_table_names=1 -- the error log shows 3 warnings: 在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.

There are also several [Note] entries logged under both configs. 在两个配置下还记录了几个[Note]条目。 When the lower_case_table_names=1 line is removed, only the 1st warning appears. 删除lower_case_table_names=1行时,仅出现第一个警告。 The user getting denied access has the following privileges on the database in question (result of SHOW GRANTS FOR 'username'@'localhost'; ) 被拒绝访问的用户在有关数据库中具有以下特权( SHOW GRANTS FOR 'username'@'localhost';

  • GRANT USAGE ON . 允许使用 TO 'username'@'localhost' IDENTIFIED BY PASSWORD '*6DF294D9BAA539074CFC4DD08E77909FE53CFCE1' 到'username'@'localhost'由密码'* 6DF294D9BAA539074CFC4DD08E77909FE53CFCE1'标识
  • GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE ON my_db .* TO 'username'@'localhost' GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,参考文献,索引,更改,创建临时表,LOCK TABLES,EXECUTE,CREATE VIEW,SHOW VIEW,CREATE ROUTINE,ALTER日常ON my_db 。* TO '用户名' @'本地主机'

Why is the connection failing and how can I fix it? 为什么连接失败,如何解决?

Step1: First take backup of your db (all tales) by mysqldump command. 步骤1:首先通过mysqldump命令备份数据库(所有故事)。

Step2: Now change your configuration setting for lower case. 步骤2:现在将您的配置设置更改为小写。

Step3: Now restart mysql service. 步骤3:现在重新启动mysql服务。

Step4: Now restore the backup. 步骤4:现在还原备份。

By this all tables name written on disk in lower case by default and even you can call them either by lower/upper/camel case but actually they will be stored on server in lower case. 通过这种方式,所有表的名称默认情况下都以小写形式写在磁盘上,甚至您也可以以小写/大写/驼峰形式来调用它们,但实际上它们将以小写形式存储在服务器上。

Upon further research, here is what I've found. 经过进一步研究,这是我发现的。

The problem breaking my site was not actually with establishing a connection to MySQL. 破坏我的站点的问题实际上与建立与MySQL的连接无关。 The error that denied me access earlier was caused by another issue. 先前拒绝我访问的错误是由另一个问题引起的。 My debugging session was querying a development database with different access permissions, so when debugging the problem I thought the failed connection was the cause -- it was a problem with the debugging itself. 我的调试会话正在查询具有不同访问权限的开发数据库,​​因此在调试问题时,我认为连接失败是原因-这是调试本身的问题。 Something else was actually breaking my site. 实际上是其他原因破坏了我的网站。

Eventually I figured out that setting lower_case_table_names=1 seems to break SQL query execution on any table whose name has a capital letter. 最终我发现,设置lower_case_table_names=1似乎会破坏任何名称为大写字母的表的SQL查询执行。 For instance, I have a table named tblCountries . 例如,我有一个名为tblCountries的表。 If I run query SELECT * FROM tblCountries , MySQL returns error tblcountries does not exist . 如果我运行查询SELECT * FROM tblCountries ,MySQL返回错误tblcountries does not exist Notice the error has lowercase 'c'. 注意该错误具有小写字母“ c”。

Queries on a table name with no upper case seem to work just fine: SELECT * FROM user works because that table name ( user ) has no uppercase. 对没有大写字母的表名的查询似乎可以正常工作: SELECT * FROM user有效,因为该表名( user )没有大写字母。 So I tried renaming tblCountries to tblcountries with query RENAME TABLE 'tblCountries' to 'tblcountries' but MySQL failed with error Can't find file: './db_name/tblcountries.frm' (errno: 2 - No such file or directory) . 所以,我试图重新命名tblCountriestblcountries与查询RENAME TABLE 'tblCountries' to 'tblcountries' ,但MySQL的失败,错误Can't find file: './db_name/tblcountries.frm' (errno: 2 - No such file or directory)

Both of these issues seem to suggest that the server is putting everything in lower case before running the query. 这两个问题似乎都表明服务器在运行查询之前将所有内容都小写。 In fact, on disc although there is no file tblcountries.frm , the file tblCountries.frm exists along with files tblCountries.MYD and tblCountries.MYI . 实际上,在光盘上,尽管没有文件tblcountries.frm ,但文件tblCountries.frm与文件tblCountries.MYDtblCountries.MYI一起存在。 If I manually rename all three files by replacing 'C' with 'c', the same query SELECT * FROM tblCountries executes successfully. 如果我通过用'c'替换'C'来手动重命名所有三个文件,则相同的查询SELECT * FROM tblCountries成功执行。

So I have at least two options but don't know which is better or if there is a 3rd best option: 因此,我至少有两个选择,但是不知道哪个更好,或者是否有第三个最佳选择:

1) remove lower_case_table_names=1 option to make the server respect letter case when executing queries; 1)删除lower_case_table_names=1选项,以使服务器在执行查询时尊重字母大小写; then execute RENAME TABLE 'tblCountries' to 'tblcountries' with every table to remove all uppercases; 然后对每个表执行RENAME TABLE 'tblCountries' to 'tblcountries'以删除所有大写字母; finally when all uppercases have been removed, re-insert lower_case_table_names=1 . 最后,当所有大写字母都被删除后,重新插入lower_case_table_names=1

2) Just manually rename files on disk as I did with tblCountries.frm . 2)就像我使用tblCountries.frm一样手动重命名磁盘上的文件。 This seems like the easier method but I don't know enough about MySQL to know whether it will cause me more problems down the line. 这似乎是一种更简单的方法,但是我对MySQL的了解还不够多,无法确定它是否会给我带来更多的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM