B.3.7 Известные проблемы в MySQL
В этом разделе перечислены известные проблемы в последних версиях MySQL.
Сведения о проблемах, специфичных для платформы, см. в руководстве по установке и отладке в разделе 2.1, «Общие рекомендации по установке», и разделе 7.9, «Отладка MySQL».
Известны следующие проблемы:
Оптимизация подзапросов для
INне так эффективна, как для=.Даже если вы используете
lower_case_table_names=2(что позволяет MySQL запоминать регистр, используемый для баз данных и имён таблиц), MySQL не запоминает регистр имён баз данных для функцииDATABASE()или в различных логах (на системах с регистронезависимым сравнением).Удаление ограничения
FOREIGN KEYне работает в репликации, потому что ограничение может иметь другое имя на реплике.REPLACE(иLOAD DATAс опциейREPLACE) не вызываетON DELETE CASCADE.DISTINCTсORDER BYне работает внутриGROUP_CONCAT(), если вы не используете все и только те столбцы, которые находятся в спискеDISTINCT.При вставке большого целого значения (между 263 и 264−1) в столбец decimal или string, оно вставляется как отрицательное значение, так как число оценивается в контексте знакового целого числа.
-
При использовании двоичного логгирования на основе операторов, сервер-источник записывает выполненные запросы в двоичный лог. Это очень быстрый, компактный и эффективный метод логгирования, который отлично работает в большинстве случаев. Однако возможно, что данные на источнике и реплике станут разными, если запрос спроектирован таким образом, что изменение данных является недетерминированным (как правило, не рекомендуется, даже вне репликации).
Например:
Операторы
CREATE TABLE ... SELECTилиINSERT ... SELECT, которые вставляют нулевые илиNULLзначения в столбецAUTO_INCREMENT.Оператор
DELETE, если вы удаляете строки из таблицы, которая имеет внешние ключи сON DELETE CASCADEсвойствами.REPLACE ... SELECT,INSERT IGNORE ... SELECTесли у вас есть дублирующие значения ключей во вставляемых данных.
Только если предыдущие запросы не имеют
ORDER BYпункта, гарантирующего детерминированный порядок.Например, для
INSERT ... SELECTбезORDER BY,SELECTможет возвращать строки в разном порядке (что приводит к разным рангам строк, следовательно, к разному числу в столбцеAUTO_INCREMENT), в зависимости от выбора оптимизаторов на источнике и реплике.Запрос оптимизируется по-разному на источнике и реплике только в том случае, если:
Таблица хранится с помощью другого движка хранилища на источнике, чем на реплике. (Можно использовать разные движки хранилища на источнике и реплике. Например, вы можете использовать
InnoDBна источнике, ноMyISAMна реплике, если у реплики меньше доступного дискового пространства.)Размер буферов MySQL (
key_buffer_sizeи так далее) отличаются на источнике и реплике.Источник и реплика используют разные версии MySQL, а код оптимизатора отличается между этими версиями.
Эта проблема также может повлиять на восстановление базы данных с помощью mysqlbinlog|mysql.
Самый простой способ избежать этой проблемы — добавить
ORDER BYпункт в вышеупомянутые недетерминированные запросы, чтобы гарантировать, что строки всегда хранятся или изменяются в одном и том же порядке. Использование формата логгирования на основе строк или смешанного формата также предотвращает проблему. Имена файлов журнала основаны на имени хоста сервера, если вы не укажете имя файла с опцией запуска. Чтобы сохранить те же имена файлов журнала, если вы измените имя своего хоста на другое, вы должны явно использовать такие опции, как
--log-bin=. См. Раздел 7.1.7, «Опции команды сервера». В качестве альтернативы переименуйте старые файлы, чтобы отразить изменение имени вашего хоста. Если это двоичные журналы, вы должны отредактировать файл индекса двоичного журнала и исправить имена файлов двоичного журнала там тоже. (То же самое верно для релейных журналов на реплике.)old_host_name-binmysqlbinlog не удаляет временные файлы, оставшиеся после оператора
LOAD DATA. См. Раздел 6.6.9, «mysqlbinlog — утилита для обработки двоичных журналов».RENAMEне работает с таблицамиTEMPORARYили таблицами, используемыми в таблицеMERGE.При использовании
SET CHARACTER SET, вы не можете использовать переведённые символы в именах баз данных, таблиц и столбцов.Сервер использует только первые
max_sort_lengthбайтов при сравнении значений данных. Это означает, что значения не могут надёжно использоваться вGROUP BY,ORDER BYилиDISTINCT, если они отличаются только после первыхmax_sort_lengthбайтов. Чтобы обойти это, увеличьте значение переменной. Значение по умолчанию дляmax_sort_lengthравно 1024 и может быть изменено во время запуска сервера или во время выполнения.Численные вычисления выполняются с помощью
BIGINTилиDOUBLE(оба обычно имеют длину 64 бита). Какая точность получается, зависит от функции. Общее правило заключается в том, что битовые функции выполняются с точностьюBIGINT,IF()иELT()с точностьюBIGINTилиDOUBLE, а остальные — с точностьюDOUBLE. Вы должны стараться избегать использования беззнаковых 64-битных значений, если они представляют собой значения, большие, чем 63 бита (9223372036854775807), для чего-либо, кроме битовых полей.Вы можете иметь до 255 столбцов типа
ENUMиSETв одной таблице.В функциях
MIN(),MAX()и других агрегатных функциях MySQL в настоящее время сравнивает столбцы типаENUMиSETпо их строковому значению, а не по относительному положению строки в наборе.-
В операторе
UPDATEстолбцы обновляются слева направо. Если вы ссылаетесь на обновлённый столбец, вы получаете обновлённое значение, а не исходное. Например, следующий оператор увеличиваетKEYна2, а не1:mysql>
UPDATEtbl_nameSET KEY=KEY+1,KEY=KEY+1; -
Вы можете ссылаться на несколько временных таблиц в одном запросе, но вы не можете ссылаться на какую-либо временную таблицу более одного раза. Например, следующее не работает:
mysql>
SELECT * FROM temp_table, temp_table AS t2;ERROR 1137: Can't reopen table: 'temp_table' -
Оптимизатор может обрабатывать
DISTINCTпо-разному, когда вы используете “скрытые” столбцы в соединении, чем когда вы этого не делаете. В соединении скрытые столбцы учитываются как часть результата (даже если они не отображаются), тогда как в обычных запросах скрытые столбцы не участвуют в сравненииDISTINCT.Пример этого:
SELECT DISTINCT mp3id FROM band_downloads WHERE userid = 9 ORDER BY id DESC;и
SELECT DISTINCT band_downloads.mp3id FROM band_downloads,band_mp3 WHERE band_downloads.userid = 9 AND band_mp3.id = band_downloads.mp3id ORDER BY band_downloads.id DESC;Во втором случае вы можете получить две одинаковые строки в наборе результатов (потому что значения в скрытом столбце
idмогут отличаться).Обратите внимание, что это происходит только для запросов, которые не имеют столбцов
ORDER BYв результате. Если вы выполняете
PROCEDUREна запросе, который возвращает пустой набор, в некоторых случаяхPROCEDUREне преобразует столбцы.Создание таблицы типа
MERGEне проверяет, совместимы ли базовые таблицы с соответствующими типами.
Если вы используете
ALTER TABLEдля добавленияUNIQUEиндекса в таблицу, используемую вMERGEтаблице, а затем добавляете обычный индекс вMERGEтаблицу, порядок ключей в таблицах будет отличаться, если в таблице был старый, не-UNIQUEключ. Это происходит потому, чтоALTER TABLEпомещаетUNIQUEиндексы перед обычными индексами, чтобы как можно раньше обнаруживать дублирующие ключи.
© 2025 Oracle
Licensed under the GPLv2 License.