Приложение C. Ограничения и лимиты

Обсуждение здесь описывает ограничения, которые относятся к использованию особенностей MySQL, таких как подзапросы или представления.

C.1. Ограничения на сохраненные программы

Эти ограничения относятся к особенностям, описанным в главе 21.

Некоторые из ограничений, отмеченных здесь, относятся ко всем сохраненным подпрограммам, то есть, к хранимым процедурам и к сохраненным функциям. Есть также некоторые ограничения, определенные для сохраненных функций, но не для хранимых процедур.

Ограничения для сохраненных функций также относятся к триггерам. Есть также некоторые ограничения, определенные для триггеров.

Ограничения для хранимых процедур также относятся к предложению DO определений планировщика событий. Есть также некоторые ограничения, определенные для событий.

Запросы SQL, не разрешенные в сохраненных программах

Сохраненные программы не могут содержать произвольные запросы SQL. Следующие запросы не разрешены:

Ограничения для сохраненных функций

Следующие дополнительные операции не разрешены в пределах сохраненных функций. Они разрешаются в пределах хранимых процедур, кроме хранимых процедур, которые вызваны изнутри сохраненной функции или триггера. Например, если Вы используете FLUSH в хранимой процедуре, эту хранимую процедуру нельзя вызвать из сохраненной функции или триггера.

Ограничения для триггеров

Для триггеров применяются следующие дополнительные ограничения:

Конфликты имен в пределах сохраненных подпрограмм

Тот же самый идентификатор мог бы использоваться для обычного параметра, местной переменной и столбца таблицы. Кроме того, то же самое местное имя переменной может использоваться во вложенных блоках. Например:

CREATE PROCEDURE p (i INT)
BEGIN
  DECLARE i INT DEFAULT 0;
  SELECT i FROM t;
  BEGIN
    DECLARE i INT DEFAULT 1;
    SELECT i FROM t;
  END;
END;

В таких случаях идентификатор неоднозначен, и следующие правила приоритета применяются:

Поведение, что переменные имеют приоритет перед столбцами таблицы, нестандартно.

Соображения о репликации

Использование сохраненных подпрограмм может вызвать проблемы репликации. Эта проблема обсуждена далее в разделе 21.7.

Опция --replicate-wild-do-table=db_name.tbl_name относится к таблицам, представлениям и триггерам. Это не относится к хранимым процедурам, функциям или событиям. Чтобы фильтровать запросы, воздействующие на последние объекты, используйте одну или больше опций --replicate-*-db.

Отладка

Нет никаких средств отладки сохраненных подпрограмм.

Неподдержанный синтаксис из стандарта SQL:2003

Синтаксис MySQL основан на стандарте SQL:2003. Следующие элементы этого стандарта в настоящее время не поддерживаются:

Соображения параллелизма

Чтобы предотвратить проблемы взаимодействия между сеансами, когда клиент делает запрос, сервер использует снимок подпрограмм и триггеров, доступный для выполнения запроса. Таким образом, сервер вычисляет список процедур, функций и триггеров, которые могут использоваться во время выполнения запроса, загружает их, а затем продолжает выполнять запрос. В то время как запрос выполняется, он не видит изменений подпрограмм, выполненных другими сеансами.

Для максимального параллелизма сохраненные функции должны минимизировать свои побочные эффекты: в частности обновление таблицы в пределах сохраненной функции может уменьшить параллельные операции на этой таблице. Сохраненная функция приобретает табличные блокировки перед выполнением, чтобы избежать несогласованности в двоичном журнале из-за несоответствия порядка, в котором запросы выполняются с тем, когда они появляются в журнале. Когда основанный на запросе двоичное журналирование используется, зарегистрированы запросы, которые вызывают функцию, а не запросы, которые выполнены в пределах функции. Следовательно, сохраненные функции, которые обновляют те же самые основные таблицы, не выполняются параллельно. Напротив, хранимые процедуры не приобретают блокировки на уровне таблицы. Все запросы, выполненные в пределах хранимых процедур, записаны в двоичный журнал, даже для основанного на запросе двоичного журналирования. См. раздел 21.7.

Ограничения планировщика событий

Следующие ограничения являются определенными для планировщика событий:

C.2. Ограничения на условия обработки

SIGNAL, RESIGNAL и GET DIAGNOSTICS недопустимы как подготовленные. Например, это недопустимо:

PREPARE stmt1 FROM 'SIGNAL SQLSTATE "02000"';

Значения SQLSTATE класса '04' не обработаны особенно. Они обработаны так же, как другие исключения.

У стандартного SQL есть стек области диагностики, содержащий область диагностики для каждого вложенного контекста выполнения. Стандартный синтаксис SQL включает GET STACKED DIAGNOSTICS для того, чтобы обратиться к этим областям. MySQL не поддерживает ключевое слово STACKED, потому что есть единственная область диагностики, содержащая информацию из нового запроса. См. также раздел 14.6.7.7.

В стандартном SQL первое условие касается значения SQLSTATE, возвращенного для предыдущего запроса SQL. В MySQL это не гарантируется, так что получив основную ошибку, Вы не можете сделать это:

GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;

Вместо этого надо:

GET DIAGNOSTICS @cno = NUMBER;
GET DIAGNOSTICS CONDITION @cno @errno = MYSQL_ERRNO;

C.3. Ограничения на серверные курсоры

Серверные курсоры осуществлены в C API через использование функции mysql_stmt_attr_set() . То же самое выполнение используется для курсоров в сохраненных подпрограммах. Серверный курсор позволяет набору результатов быть произведенным на стороне сервера, но не переданным клиенту за исключением тех строк, которые просит клиент. Например, если клиент выполняет запрос, но интересуется только первой строкой, остающиеся строки не переданы.

В MySQL серверный курсор осуществлен во внутреннюю временную таблицу. Первоначально это MEMORY, но преобразована в MyISAM, когда ее размер превышает минимальное значение переменных max_heap_table_size и tmp_table_size. Те же самые ограничения относятся к внутренним временным таблицам, составленным, чтобы держать набор результатов для курсора. См. раздел 9.4.4. Одно ограничение выполнения: для большого набора результатов, получение его строк через курсор могло бы быть медленным.

Курсоры только для чтения; Вы не можете использовать курсор, чтобы обновить строки.

UPDATE WHERE CURRENT OF и DELETE WHERE CURRENT OF не осуществлены, потому что обновляемые курсоры не поддержаны.

Курсоры являются непрокручиваемыми.

Курсоры не имеют имен. Обработчик действует как ID.

Вы можете иметь только единственный открытый курсор на готовый запрос. Если Вы нуждаетесь в нескольких курсорах, Вы должны подготовить несколько запросов.

Вы не можете использовать курсор для запроса, который производит набор результатов, если запрос не поддержан в готовом режиме. Это включает такие запросы, как CHECK TABLE, HANDLER READ и SHOW BINLOG EVENTS.

C.4. Ограничения на подзапросы

C.5. Ограничения на представления

Обработка представления не оптимизирована:

Есть общий принцип, что Вы не можете изменить таблицу и выбрать из той же самой таблицы в подзапросе. См. раздел C.4.

Тот же самый принцип также применяется, если Вы выбираете из представления, которое выбирает из таблицы, если представление выбирает из таблицы в подзапросе, и представление оценено, используя алгоритм слияния. Пример:

CREATE VIEW v1 AS
SELECT * FROM t2 WHERE EXISTS (SELECT 1 FROM t1 WHERE t1.a = t2.a);
UPDATE t1, v2 SET t1.a = 1 WHERE t1.b = v2.b;

Если представление оценено, используя временную таблицу, Вы можете выбрать из таблицы в представлении подзапроса и все еще изменять эту таблицу во внешнем запросе. В этом случае представление будет сохранено во временной таблице, и таким образом Вы действительно не выбираете из таблицы в подзапросе и изменяете ее в то же самое время. Это другая причина, по которой Вы могли бы хотеть вынудить MySQL использовать алгоритм temptable, определяя ALGORITHM = TEMPTABLE в определении представления.

Вы можете использовать DROP TABLE или ALTER TABLE, чтобы удалить или изменить таблицу, которая используется в определении представления. Никакое предупреждение не следует из DROP или ALTER даже при том, что это лишает законной силы представление. Вместо этого ошибка происходит позже, когда представление используется. CHECK TABLE может использоваться, чтобы проверить на представления, которые были лишены законной силы DROP или ALTER.

Относительно обновляемого представления, полная цель для представлений состоит в том, что, если какое-либо представление теоретически обновляемое, это должно быть обновляемо практически MySQL как можно быстрее. Многие теоретически обновляемые представления могут быть обновлены теперь, но ограничения все еще существуют. Для деталей см. раздел 21.5.3.

Там существует недостаток с текущим выполнением представлений. Если пользователю предоставляют основные привилегии, необходимые, чтобы создать представление (CREATE VIEW и SELECT), тот пользователь будет неспособен вызвать SHOW CREATE VIEW на том объекте, если пользователю также не предоставляют привилегию SHOW VIEW.

Тот недостаток может привести к проблемам, поддерживая базу данных с mysqldump, который может потерпеть неудачу из-за недостаточных привилегий. Эта проблема описана в Bug #22062.

Обходное решение проблемы для администратора: вручную предоставить привилегию SHOW VIEW пользователям, которым предоставляют CREATE VIEW, так как MySQL не предоставляет это неявно, когда представления создаются.

Представления не имеют индека, так что индексные подсказки не применяются. Использование индексных подсказок при выборе из представления не разрешено.

SHOW CREATE VIEW отображаетя определения, используя предложение AS alias_name для каждого столбца. Если столбец создается из выражения, псевдоним по умолчанию текст выражения, который может быть довольно длинным. Псевдонимы для имен столбцов в CREATE VIEW проверены по максимальной длине столбца в 64 символа (а не максимальной длине псевдонима в 256 символов). В результате, представления, создаваемые из вывода SHOW CREATE VIEW терпят неудачу, если какой-либо псевдоним столбца превышает 64 символа. Это может вызвать проблемы при следующих обстоятельствах для представлений со слишком длинными псевдонимами:

Обходное решение для этой проблемы должно изменить каждое проблематичное определение представления, чтобы использовать псевдонимы, которые обеспечивают более короткие имена столбцов. Тогда представление будет копировать должным образом, и может быть выведено и перезагружено, не вызывая ошибку. Чтобы изменить определение, удалите и пересоздайте представление снова с помощью DROP VIEW и CREATE VIEW или замените определение с помощью CREATE OR REPLACE VIEW.

Для проблем, которые происходят, перезагружая определения представления в файлах дампа, есть другое обходное решение: отредактировать файл дампа, чтобы изменить запрос CREATE VIEW. Однако, это не изменяет оригинальные определения представления, которые могут вызвать проблемы для последующих операций дампа.

C.6. Ограничения транзакций XA

Операционная поддержка XA ограничена механизмом хранения InnoDB.

Для external XA сервер MySQL действует как менеджер ресурсов, а клиент как менеджер по транзакциям. Для Internal XA механизмы хранения в пределах сервера MySQL являются менеджерами ресурсов, а сам сервер действует как менеджер по транзакциям. Внутренняя поддержка XA ограничена способностями отдельных механизмов хранения. Внутренний XA требуется для того, чтобы обработать транзакции XA, которые вовлекают больше, чем один механизм хранения. Выполнение внутреннего XA требует, чтобы механизм хранения поддержал двухфазную передачу на табличном уровне обработчика, в настоящее время это истина только для InnoDB.

Для XA START предложения JOIN и RESUME не поддержаны.

Для XA END предложение SUSPEND [FOR MIGRATE] не поддержано.

Требование, что bqual часть значения xid отличается для каждой транзакции XA в пределах глобальной транзакции является ограничением текущего выполнения XA в MySQL. Это не часть спецификации XA.

Транзакции XA записаны в двоичный журнал в виде двух частей. Когда запрос XA PREPARE выпущен, первая часть транзакции до XA PREPARE записана, используя начальный GTID. XA_prepare_log_event используется, чтобы идентифицировать такие транзакции в двоичном журнале. Когда XA COMMIT или XA ROLLBACK выпущен, вторая часть транзакции, содержащая только XA COMMIT или XA ROLLBACK записана, используя второй GTID. Отметьте что начальная часть транзакции, идентифицированной XA_prepare_log_event, не обязательно сопровождается XA COMMIT или XA ROLLBACK, который может вызвать чередованное двоичное журналирование любых двух транзакций XA. Две части транзакции XA могут даже появиться в различных двоичных файлах системного журнала. Это означает, что транзакция XA в состоянии PREPARED является теперь постоянной до явного запроса XA COMMIT или XA ROLLBACK, гарантируя, что транзакции XA совместимы с репликацией.

Следующие ограничения существуют для того, чтобы использовать XA:

До MySQL 5.7.7 транзакции XA не были совместимы с репликацией. Это потому, что транзакция XA, которая была в состоянии PREPARED, была бы отменена до прежнего уровня на чистом завершении работы сервера или обрыве связи с клиентом. Точно так же транзакция XA, которая была в состоянии PREPARED все еще существовала бы в состоянии PREPARED в случае, если сервер был завершен неправильно, а затем запущен снова, но содержание транзакции не могло быть записано в двоичный журнал. В обеих этих ситуациях транзакция XA не могла копироваться правильно.

C.7. Ограничения на наборы символов

C.8. Ограничения Performance Schema

Performance Schema избегает использования mutexes, чтобы собрать или произвести данные, таким образом нет никаких гарантий последовательности, и результаты могут иногда быть неправильными. Значения событий в таблицах performance_schema недетерминированы и неповторимы.

Если Вы сохраняете информацию о событии в другой таблице, Вы не должны предположить, что оригинальные события все еще будут доступны позже. Например, если Вы выбираете события из таблицы performance_schema во временную таблицу, намереваясь присоединиться к той таблице с оригинальной таблицей позже, не может быть никаких соответствий.

mysqldump и BACKUP DATABASE игнорируют таблицы в базе данных performance_schema.

Таблицы в базе данных performance_schema не могут быть заблокированы с LOCK TABLES, кроме таблиц setup_xxx.

Таблицы в базе данных performance_schema не могут быть индексированы.

Результаты для запросов, которые обращаются к таблицам в performance_schema, не сохранены в кэше запроса.

Таблицы в базе данных performance_schema не реплицируются.

Performance Schema недоступна в встроенном сервере libmysqld.

Типы таймеров могли бы измениться, в зависимости от платформы. Таблица performance_timers показывает, какие таймеры событий доступны. Если значения в этой таблице для данного имени таймера NULL, этот таймер не поддержан на Вашей платформе.

Инструменты, которые относятся к механизмам хранения, не могли бы быть осуществлены для всех механизмов хранения. Инструментовка каждого имеющего отношение к третьей стороне механизма ответственность автора механизма.

C.9. Ограничения на подключаемую аутентификацию

Первая часть этого раздела описывает общие ограничения на применимость структуры аутентификации, описанной в разделе 7.3.9. Вторая часть описывает, как имеющие отношение к третьей стороне разработчики могут определить степень, до которой плагин может использовать в своих интересах возможности аутентификации.

Термин нативная авторизация, используемый здесь, относится к аутентификации по паролям, сохраненным в таблице mysql.user. Это прежний метод аутентификации, обеспеченный более старыми серверами MySQL, прежде, чем аутентификация плагинами была осуществлена. Это остается методом по умолчанию, хотя теперь это осуществлено, используя плагины. Нативная авторизация Windows обращается к аутентификации, используя авторизацию пользователя, который уже вошел в систему к Windows, как осуществлено плагином Windows Native Authentication (Windows plugin для краткости).

Общие ограничения авторизации плагинами

Аутентификация и имеющие отношение к третьей стороне соединители

Имеющие отношение к третьей стороне разработчики соединителя могут использовать следующие направляющие линии, чтобы определить готовность соединителя использовать в своих интересах плагиновую аутентификацию:

C.10. Лимиты в MySQL

Этот раздел перечисляет текущие лимиты в MySQL 8.0.

C.10.1. Лимиты на Join

Максимальное количество таблиц, на которые можно сослаться в единственном соединении, 61. Это включает соединение, обработанное, сливая полученные таблицы (подзапросы) и представления в предложении FROM во внешнем блоке запроса (см. раздел 9.2.1.18.3). Это также относится к числу таблиц, на которые можно сослаться в определении представления.

C.10.2. Лимиты на число баз данных и таблиц

У MySQL нет никакого предела числа баз данных. У основной файловой системы может быть предел числа каталогов.

У MySQL нет никакого предела числа таблиц. У основной файловой системы может быть предел числа файлов, которые представляют таблицы. Отдельные механизмы хранения могут наложить определенные для механизма ограничения. InnoDB разрешает до 4 миллиардов таблиц.

C.10.3. Лимит размера таблиц

Эффективный максимальный табличный размер для баз данных MySQL обычно определяется ограничениями операционной системы на размеры файла, а не внутренними пределами MySQL. Следующая таблица приводит некоторые примеры пределов размера файла операционной системы. Это только грубое руководство и не предназначено, чтобы быть истиной в последней инстанции. Для получения самой современной информации проверьте документацию для Вашей операционной системы.

ОСЛимит размера файла
Win32 на FAT/FAT322GB/4GB
Win32 на NTFS2TB (можно и больше)
Linux 2.2-Intel 32-bit2GB (LFS: 4GB)
Linux 2.4+(на файловой системе ext3) 4TB
Solaris 9/1016TB
OS X на HFS+2TB

Пользователи Windows, пожалуйста, отметьте, что FAT и VFAT (FAT32) НЕ считаются подходящими для производственного использования с MySQL. Используйте NTFS вместо этого.

В Linux 2.2 Вы можете создать таблицы MyISAM больше 2GB в размере при использовании патча Large File Support (LFS) для файловой системы ext2. Актуальнейшие дистрибутивы Linux основаны на ядре 2.4 или выше и включают все необходимые патчи LFS. На Linux 2.4 патчи также существуют для ReiserFS, чтобы получить поддержку больших файлов (до 2TB). С JFS и XFS в Linux возможны файлы в петабайт и даже более.

Для подробного обзора о LFS в Linux см. страницу Andreas Jaeger's Large File Support in Linux на http://www.suse.de/~aj/linux_lfs.html.

Если Вы действительно сталкиваетесь с ошибкой полной таблицы, есть несколько причин, почему это, возможно, произошло:

C.10.4. Лимиты на число столбцов и размер строк в таблице

Есть жесткий предел 4096 столбцов на таблицу, но эффективный максимум может быть меньше для данной таблицы. Точный предел зависит от нескольких взаимодействующих факторов.

C.10.5. Ограничения в Windows

Следующие ограничения применяются к использованию MySQL на платформе Windows: