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, оно вставляется как отрицательное значение, так как число оценивается в контексте целого со знаком.
-
При использовании журналирования на основе инструкций (statement-based binary logging), исходный сервер записывает выполненные запросы в двоичный лог. Это очень быстрый, компактный и эффективный метод журналирования, который отлично работает в большинстве случаев. Однако возможно, что данные на источнике и реплике станут разными, если запрос разработан таким образом, что изменение данных является недетерминированным (как правило, не рекомендуется, даже вне репликации).
Например:
операторы
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. Следует избегать использования значений unsigned long long, которые могут быть больше 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.