Использование обратных символов (``) в MySQL, когда репликация включена
История
Я недавно настроил репликацию на моем сервере MySQL. Я пошел по пути репликации Master - Master (2 сервера, каждый из которых является Master и Slave для другого, как описано здесь - http://brendanschwartz.com/post/12702901390/mysql-master-master-replication).
Я начал замечать, что некоторые запросы не работают или отображают непредвиденное поведение при использовании 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
Мои вопросы:
- Почему именно обратные помехи плохи для репликации? Могу ли я столкнуться с проблемами с обратными ссылками или мой опыт был связан с эзотерическими, специфичными для платформы проблемами?
- Есть ли рекомендуемый способ решения этой проблемы?
- Я думаю, чтобы избавиться от всех недостатков в коде. Все имена моих столбцов в простом английском алфавите и camelCase, поэтому мне не нужно использовать обратные пометки в любом случае.
- Я думал, может быть, я мог бы переключиться на
sql_mode = ANSI_QUOTES
но я боюсь, что такое большое изменение потребует тщательного тестирования всей системы, потому что я не уверен, как это повлияет на другие аспекты запросов, такие как значения и т. д. - Я также подумал, что проблема может заключаться в том, что обратные звуки стали частью названия, но это не соответствует поведению, и я проверил.
- Я думал, может быть, я мог бы переключиться на
Я был бы признателен за любой вклад в этот вопрос.
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
,
Как вы, вероятно, не назвала commandd columnName
, dbName
или же tableName
оболочка, возможно, заменила их пустой строкой (и выдает ошибки), поэтому запрос, видимый MySQL, читается как SELECT FROM .;
что явно недействительно и, следовательно, не удалось.
Подсказка: попробуйте еще раз, используя одинарные кавычки '
вместо двойных кавычек "
чтобы избежать расширения оболочки.
- Обратные пометки не плохо для репликации. Я использую их везде, и я никогда не сталкивался с ошибкой из-за них - даже в репликации.
- Как запросы терпят неудачу? Они терпят неудачу в phpMyAdmin, и вы получаете ошибку? Они терпят неудачу в приложении? Вы получаете ошибку? Внимательно проанализируйте сообщение об ошибке - оно приблизит вас к тому, что не так.
- Кавычки ANSI не связаны с обратными кавычками, но вместо этого к двойным кавычкам
"
, Так чтоWHERE `login` = "name"
проверим колонкуlogin
быть строкойname
(без кавычек ANSI) или для столбцаlogin
иметь то же значение, что и столбецname
(Цитаты ANSI). Если вы цитируете свои строки, используя одинарные кавычки'
как вWHERE `login` = 'name'
включенные или отключенные кавычки ANSI не будут иметь никакого значения.
Чтобы получить дополнительную (подробную) помощь, пожалуйста, подробно объясните, как сбои запросов или почему вы считаете, что запросы не срабатывают.