Spec-Zone.ru › MySQL 8.4

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=old_host_name-bin. Смотрите Раздел 7.1.7, «Параметры командной строки сервера». В качестве альтернативы, переименуйте старые файлы, чтобы они отражали изменение имени хоста. Если это двоичные лог-файлы, вы должны также отредактировать файл индекса двоичного лога и исправить имена двоичных лог-файлов там. (То же самое относится к реплицированным логам на реплике.)

  • mysqlbinlog не удаляет временные файлы, оставшиеся после инструкции 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> UPDATE tbl_name SET 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.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/known-issues.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API