2

故事

我最近在我的 MySQL 服务器上设置了复制。我沿着主 - 主复制的路线走(2台服务器,每台都是主服务器和从属服务器,如此处所述 - http://brendanschwartz.com/post/12702901390/mysql-master-master-replication)。

我开始注意到一些查询失败或在 WAMP 上使用 PhpMyAdmin 显示意外行为。例如,突然:

-- This fails
SELECT * FROM `tableName` WHERE `columnName` = 10;
-- This succeeds
SELECT * FROM tableName WHERE columnName = 10;
-- In some queries, specific columns seem to be the issue
-- So even this might work, but not always
SELECT * FROM `tableName` WHERE columnName = 10;
-- Sometimes it's even due to specific columns
-- So this might succeed
SELECT * FROM `tableName` WHERE `anotherColumnName` = 10;

我很快意识到这可能是PhpMyAdmin 的错,因为通过 MySQL shell 进行操作是有效的。然后我意识到它在我自己的基于 Linux 的机器上也可以在 PhpMyAdmin 上运行,而且 PhpMyAdmin 版本要新得多。

但是,在尝试从常规 shell 运行一些查询时,我确实遇到了反引号问题,例如:

# From my bash shell, this fails
mysql -s -uUser -pPassword -e "SELECT `columnName` FROM `dbName`.`tableName`;"
# This succeeds
mysql -s -uUser -pPassword -e "SELECT columnName FROM dbName.tableName;"

我不相信巧合,所以我想我最好检查一下发生了什么。

到目前为止我所拥有的

我在网上搜索过它,发现反引号和复制可能存在问题,因为它保存在日志中的方式(我认为)。但它仍然不能完全回答复制如何仍然为我工作,但一些查询因反引号而失败。如果有的话,我的数据支持反引号没有问题。

我知道反引号的用途 - https://dba.stackexchange.com/questions/23129/benefits-of-using-backtick-in-mysql-queries

我的 MySQL 服务器正在运行:

  • Ubuntu 14.04.01(64 位服务器版)
  • MySQL Ver 14.14 Distrib 5.5.41,适用于使用 readline 6.3 的 debian-linux-gnu (x86_64)

我的问题是:

  1. 为什么反引号不利于复制?我是否可能会遇到反引号问题,或者我的经验是否是由于深奥的、特定于平台的问题?
  2. 有没有推荐的方法来处理这个问题?
  3. 我的想法是摆脱代码中的所有反引号。我的列名都是简单的英文字母和驼峰式,所以无论如何我都不应该使用反引号。
    1. 我想也许我可以切换到,sql_mode = ANSI_QUOTES但我担心这么大的变化需要对整个系统进行彻底测试,因为我不确定它会如何影响查询的其他方面,例如值等。
    2. 我还认为问题可能是反引号已成为名称的一部分,但它不符合行为,我检查了。

我将不胜感激任何人对此问题的任何意见。

4

1 回答 1

0

首先,我的建议是保留反引号并使用它们。如果不使用它们,您可能会冒着在更新 MySQL 后破坏应用程序的风险。只需查看MySQL 5.6(或任何更早版本)新引入的保留字- 它们不区分大小写,因此骆驼大小写在这里对您没有帮助(maxValuereSignal)。如果您将其中任何一个用作表名或列名,您的应用程序将会中断。只是不要冒险。

现在,向您提出问题:

# From my bash shell, this fails
mysql -s -uUser -pPassword -e "SELECT `columnName` FROM `dbName`.`tableName`;"

您是否偶然查看了错误消息?shell (bash) 中的反引号实际上用于代码执行。因此echo "host is `hostname`"将执行该命令hostname并将该占位符替换为该命令的(终端)输出。所以字符串被更改为host is computer0815,这将被馈送到echo.

由于您可能没有调用columnName, dbNameortableName的命令,shell 可能将它们替换为空字符串(并发出错误),因此 MySQL 看到的查询读取为SELECT FROM .;显然无效并因此失败。

提示:再次尝试使用单引号'而不是双引号"以避免 shell 扩展。

  1. 反引号对于复制来说并不坏。我在任何地方都使用它们,而且我从来没有因为它们而遇到过错误——甚至在复制中也没有。
  2. 查询如何失败?他们是否在 phpMyAdmin 中失败并且您收到错误消息?他们在申请中失败了吗?你有错误吗?仔细分析错误信息——它会让你更接近错误的地方。
  3. ANSI 引号与反引号无关,而是与双引号相关"。因此 aWHERE `login` = "name"将检查列是否login为字符串name(无 ANSI 引号)或列login是否具有与列相同的值name(ANSI 引号)。'如果您在启用或禁用 ANSI 引号中使用单引号引用您的字符串,WHERE `login` = 'name'则不会有任何区别。

为了获得更多(详细)帮助,请详细说明查询失败的原因或您认为查询失败的原因。

于 2015-05-14T01:39:52.460 回答