Использование обратных кавычек (``) в MySQL при включенной репликации

История

Недавно я настроил репликацию на своем сервере MySQL. Я пошел по пути репликации Мастер-Мастер (2 сервера, каждый является Мастером и Ведомым по отношению к другому, как описано здесь - http://brendanschwartz.com/post/12702901390/mysql-master-master-репликация).

Я начал замечать, что некоторые запросы терпят неудачу или показывают неожиданное поведение, используя PhpMyAdmin на WAMP. Например, вдруг:

-- 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. Затем я понял, что он также работает с PhpMyAdmin на моей собственной машине, основанной на Linux, а версия PhpMyAdmin намного новее.

Однако у меня возникают проблемы с обратными кавычками при попытке выполнить некоторые запросы из обычной оболочки, например:

# 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, для debian-linux-gnu (x86_64) с использованием readline 6.3

Мои вопросы:

  1. Почему обратные кавычки плохо подходят для репликации? Вероятно ли, что у меня возникнут проблемы с обратными кавычками, или мой опыт связан с эзотерическими проблемами, специфичными для платформы?
  2. Есть ли рекомендуемый способ решения этой проблемы?
  3. My thinking is to get rid of all the backticks in the code. My column names are all in plain English alphabet and camelCase so I shouldn't need to use backticks anyway.
    1. I thought maybe I could switch to sql_mode = ANSI_QUOTES but I'm worried such a big change would require thorough testing of the entire system because I'm not sure how it would affect other aspects of the queries such as the values, etc.
    2. Я также подумал, что проблема может заключаться в том, что обратные кавычки стали частью имени, но это не соответствует поведению, и я проверил.

Я был бы признателен за любой вклад, который кто-либо имеет в отношении этой проблемы.


person SimpleAnecdote    schedule 12.03.2015    source источник


Ответы (1)


Прежде всего, я предлагаю сохранить обратные кавычки и использовать их. Без их использования вы рискуете сломать приложение после обновления MySQL. Просто взгляните на недавно введенные зарезервированные слова для MySQL 5.6 (или любой более ранней версии) - они нечувствительны к регистру, поэтому верблюжий регистр вам здесь не поможет (maxValue или reSignal). Если вы используете любой из них в качестве имен таблиц или столбцов, ваше приложение сломается. Просто не рискуйте.

Теперь к вам вопросы:

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

Вы случайно не видели сообщение об ошибке? Обратные кавычки в оболочке (bash) на самом деле используются для выполнения кода. Таким образом, echo "host is `hostname`" выполнит команду hostname и заменит этот заполнитель выводом (терминалом) этой команды. Таким образом, строка изменяется на host is computer0815, и она будет передана echo.

Поскольку у вас, вероятно, нет команды с именем columnName, dbName или tableName, оболочка, возможно, заменила их пустой строкой (и выдала ошибки), поэтому запрос, видимый MySQL, читается как SELECT FROM .;, который явно недействителен и, следовательно, не выполнен.

Подсказка: попробуйте еще раз использовать одинарные кавычки ' вместо двойных кавычек ", чтобы избежать расширения оболочки.

  1. Обратные кавычки не плохи для репликации. Я использую их везде и никогда не сталкивался с ошибкой из-за них — даже при репликации.
  2. Как запросы терпят неудачу? Они не работают в phpMyAdmin, и вы получаете сообщение об ошибке? Они терпят неудачу в приложении? Вы получаете ошибку? Внимательно проанализируйте сообщение об ошибке — это приблизит вас к тому, что не так.
  3. Кавычки ANSI не связаны с обратными кавычками, но вместо двойных кавычек ". Таким образом, WHERE `login` = "name" будет проверять, чтобы столбец login был строкой name (без кавычек ANSI) или чтобы столбец login имел то же значение, что и столбец name (кавычки ANSI). Если вы цитируете свои строки, используя одинарные кавычки ', как в WHERE `login` = 'name', включенные или отключенные кавычки ANSI не будут иметь никакого значения.

Чтобы получить дополнительную (подробную) справку, пожалуйста, подробно объясните, почему запросы терпят неудачу или почему вы считаете, что запросы терпят неудачу.

person Shi    schedule 14.05.2015