![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Эта глава описывает некоторые общие проблемы и сообщения об ошибках, с
которыми пользователи столкнулись. Вы узнаете, как точно определить
происходящее, и что делать, чтобы решить возникшую проблему. Вы также найдете
здесь соответствующие решения для некоторых общих проблем. Когда Вы сталкиваетесь с проблемами, первое, что Вы должны сделать, это
однозначно выяснить, которая программа или часть оборудования
вызывает данные проблемы. Если после того, как Вы исследовали все другие возможности и заключили,
что проблема заключается в клиенте или сервере MySQL, самое время сделать
отчет об ошибке для списка рассылки или группы поддержки. В отчете ошибки
попробуйте дать очень детальное описание того, как система ведет себя, и что
с ней случается. Вы должны также установить, почему Вы думаете, что это
вызвано именно MySQL. Учтите все ситуации в этой главе. Установите любые
проблемы точно, как они появляются, когда Вы исследуете вашу систему.
Используйте метод "вырезать и вставить" для любого вывода, сообщений об
ошибках из программ и журналов. Если сбоит программа, всегда полезно знать следующее: При посылке отчета об ошибке Вы должны обязательно следовать правилам,
описанным в этом руководстве. Этот раздел перечисляет некоторые ошибки, с которыми пользователи часто
сталкиваются. Здесь Вы найдете описания ошибок, и как решить проблему. Обратитесь к разделам
"10.5 Как работает система привилегий" и
особенно "10.10 Причины ошибки
Наиболее общая причина для ошибки Другая общая причина получения такой ошибки состоит в том, что Вы закрыли
соединение, а теперь пробуете выполнить запрос на закрытом подключении. Вы можете проверять, что MySQL работает, выполняя Если Вы имеете скрипт, Вы только должны снова выдать запрос клиенту, чтобы
сделать автоматическое переподключение. Вы обычно можете получать следующие коды ошибки в этом случае: Вы можете также получать эти ошибки, если Вы посылаете неправильной или
слишком большой запрос серверу. Если Клиент MySQL под ОС Unix может соединяться с сервером Под Windows Вы можете соединяться только через TCP/IP, если сервер
Сообщение error (2002) Начните с проверки ( Если процесс Обратите внимание на использование апострофов вместо кавычек с командой
Имеются некоторые причины, по которым может происходить ошибка Если Вы получаете сообщение об ошибке Если Вы получаете сообщение об ошибке: Это означает, что По умолчанию Обратите внимание, что, если Вы получаете это сообщение об ошибках для
данного компьютера, Вы должны сначала проверить, что не имеется чего-нибудь
неправильного с TCP/IP подключениями. Если Ваши TCP/IP подключения не
работают, увеличение переменной Если Вы получаете ошибку Если Вы нуждаетесь в большем количестве подключений, чем значение по
умолчанию (100), то перезапустите Обратите внимание, что Максимальное количество подключений зависит от того, как хороша библиотека
потоков на данной платформе. Linux или Solaris могут поддерживать 500-1000
одновременных подключений в зависимости от того, сколько RAM Вы имеете, и
что Ваша клиентура делает. Если Вы получаете ошибку Наиболее типичный случай, когда это случается: когда Вы пробовали
создавать таблицу типа, который не поддержан Вашей версией
Вы можете проверять тип таблицы:
Вы можете проверять, какие расширения поддерживает Ваша версия
Если Вы выдаете запрос и получаете нечто вроде следующей ошибки: Обратите внимание, что ошибка относится к клиенту Чтобы выправить проблему, сначала проверьте, что Ваш запрос правилен.
Является ли приемлемым, чтобы он возвратил так много строк? Если да, Вы
можете использовать Когда клиент MySQL или сервер Если Вы используете клиента Если Вы используете другую клиентуру, которая не позволяет Вам определять
максимальный размер пакета (типа Вы можете также получать странные проблемы с большими пакетами, если Вы
используете большие blob'ы, но не дали Начиная с Если Вы находите ошибки, подобные следующей, в Вашем файле регистрации:
Это означает, что что-то из следующего случилось: Когда вышеупомянутое случается, переменная сервера
Переменная сервера Обратите внимание, что вышеупомянутое может указывать, что кто-то пробует
врываться в Вашу базу данных! Другие причины для проблем с клиентами и прерванными подключениями.
Эта ошибка происходит в старых версиях MySQL, когда расположенная в памяти
временная таблица становится больше, чем Вы можете также запустить В MySQL Version 3.23 временная таблица в памяти будет автоматически
преобразована в дисковую Если для некоторых запросов Вы получаете ошибку типа:
Это означает, что MySQL не может создать временный файл для набора
результатов в заданном временном каталоге. Для исправления запустите
Считается, что каталог c:\temp существует. Проверьте также код ошибки, который Вы получаете через
Если Вы получаете Это может случаться, например, если Вы используете
Если Вы получаете следующую ошибку: Это означает, что, когда Возможные причины для этой проблемы: Если Вы получаете ошибку Обратите внимание, что MySQL использует каталоги и файлы, чтобы сохранить
базы данных и таблицы, так что имена баз данных и таблиц чувствительны к
регистру! В Windows это не так, но все ссылки к данной таблице внутри запроса
должны использовать тот же самый регистр. Вы можете проверить, какие таблицы Вы имеете в текущей базе данных, через
Если Вы получаете ошибку подобно: Это означает одно из следующего: Если Вы получаете Проблема здесь состоит в том, что Чтобы сообщать, чтобы Чтобы изменять число описателей файла, доступных
Обратите внимание, что, если Вы выполняете оболочку Если Вы компонуете Вашу программу и получаете ошибки для невызванных
символов, которые начинаются с Вы должны быть способны решить это, добавляя
Если Вы получаете ошибки Если Вы получаете ошибки Если Вы получаете ошибки Это обычно означает, что библиотека компилируется на системе, которая не
на 100%, совместима с Вашей. В этом случае Вы должны загрузить последний
исходник MySQL и откомпилировать библиотеку непосредственно. Если Вы пробуете выполнять программу и получаете ошибки для невызванных
символов, которые начинаются с Другой способ решать эту проблему состоит в том, чтобы скомпоновать Вашу
программу статически с опцией MySQL-сервер Обратите внимание, что доступ к MySQL как Если Вы имеете проблемы с правами доступа к файлам, например, если
То системная переменная
По умолчанию MySQL создаст
базу данных и каталоги В MySQL Version 3.23.25 и выше MySQL считает, что значения
Все версии MySQL проверены на многих платформах прежде, чем они выпущены.
Это не означает, что не имеется любых ошибок в MySQL, но это означает, что их
там очень мало. Сначала Вы должны пробовать выяснять, состоит ли проблема в том, что
Много сбоев MySQL вызваны разрушенным индексом или файлами данных. MySQL
модифицирует данные относительно диска через системный вызов
Вышеупомянутое означает, что обычно Вы не должны получить разрушенные
таблицы и файлы, если: Поскольку очень трудно узнать, почему что-то терпит крах, сначала
попробуйте проверить следующее: Если Вы забыли пароль пользователя Обратите внимание, что после того, как Вы запустили Когда диск полностью заполнится, MySQL делает следующее: Чтобы облегчить проблему, Вы можете предпринять следующие действия: Исключительные ситуации: Вы используете Все вышеприведенные команды могут использовать большие временные файлы,
которые остались после них на диске, что вызовет большие проблемы для
остальной части системы. Если MySQL переполняет диск при выполнении любой из
вышеупомянутых операций, он удалит большие временные файлы и отметит таблицу
как поврежденную (исключение: MySQL использует значение системной переменной MySQLсоздает все временные файлы как скрытые. Это гарантирует, что
временные файлы будут удалены, если При сортировке ( Здесь Для некоторого запроса Если Вы имеете проблемы с тем фактом, что любой может удалять сокет
MySQL /tmp/mysql.sock, Вы можете, на большинстве версий Unix,
защитить Вашу файловую систему /tmp, устанавливая липкий бит на ней.
Зайдите в систему как Это защитит Вашу файловую систему /tmp так, чтобы файлы могли
быть удалены только их владельцами или суперпользователем ( Вы можете проверять, установлен ли липкий бит, выполняя
Вы можете изменять место, где MySQL помещают файл сокета, так: Вы можете проверять, что сокет работает, с помощью команды: Если Вы имеете проблему с По умолчанию поиск в MySQL нечувствителен к регистру (хотя имеются
некоторые наборы символов, которые всегда чувствительны, например,
Простые операции сравнения ( В старых версиях MySQL Если Вы хотите, чтобы столбец всегда обработался в режиме чувствительности
к регистру, объявите его как Если Вы используете китайские данные в так называемом кодировании big5, Вы
должны сделать все символьные столбцы Формат значения Как дополнительное удобство MySQL автоматически преобразовывает дату в
число, если дата используется в числовом контексте (и наоборот). Также
достаточно интеллектуально обрабатывается ослабленная форма строки при
модифицировании и в предложении Специальная дата Потому, что MySQL выполняет преобразования, описанные выше, следующие
инструкции всегда работают: Однако, следующее работать не будет: Обратите внимание, что MySQL не делает никакой проверки, является или нет
дата правильной. Если Вы сохраняете неправильную дату, типа
Концепция значения Обе инструкции вставляют значение в столбец В SQL значение Если Вы хотите искать значения столбца, которые являются
Чтобы искать значения В MySQL как и во многих других SQL-серверах, Вы не можете индексировать
столбцы, которые могут иметь значения При чтении данных через При использовании Чтобы помочь СУБД с обработкой
Для некоторых типов столбцов значения Вы можете использовать псевдоним, чтобы обратиться к столбцу в
Обратите внимание, что ANSI SQL не позволяет Вам обращаться к псевдониму в
предложении Инструкция Поскольку MySQL не поддерживает подвыборы или использование больше, чем
одной таблицы в инструкции Если общее количество символов в запросе со связанными столбцами
( Если Вы имеете сложный запрос, который имеет много таблиц, а он не
возвращает никаких строк, Вы должны использовать следующую процедуру, чтобы
выяснить, что неправильно с Вашим запросом: Если Проблема может состоять в том, что MySQL потерпел крах в предыдущем
Если что-то идет неправильно с операцией переименования, MySQL пробует
отменить изменения. Если что-то идет совсем уж неправильно (этого не должно
случиться, конечно), MySQL может оставить старую таблицу как B-xxx,
поскольку простое переименование на уровне системы должно вернуть Ваши данные
обратно в целости и сохранности. Вы должны всегда определять порядок, в котором Вы желаете получить данные:
Возвратит столбцы в порядке Возвратит столбцы в порядке Вы не должны в прикладной программе использовать
Если по какой-то причине Вы все же хотите изменять порядок столбцов, Вы
можете сделать это следующим образом: Следующее представляет собой список всех ограничений, действительных для
временных таблиц (
11 Проблемы и общие ошибки
11.1 Как определять, что вызывает проблемы
В этом случае Вы должны начать с проверки всех Ваших кабелей и выполнить
какую-нибудь диагностическую программу, чтобы проверить Ваши аппаратные
средства! Вы должны также проверить, имеются ли любые заплаты, модификации
или сервисные пакеты для Вашей операционной системы, которые могли бы,
вероятно, решить эти проблемы. Проверьте также, что все Ваши библиотеки
(подобно glibc) современны. Всегда хорошо использовать машину с памятью ECC,
чтобы обнаружить проблемы памяти пораньше.
kbd_mode -a
.
top
, ps
, taskmanager
или некоторую
подобную программу, чтобы установить, которая программа занимает весь CPU
или блокирует машину.
top
, df
или подобной
программы, не исчерпана ли память, место на диске или иной критический ресурс.
top
. Позвольте программе поработать некоторое время, она может
оценивать что-то тяжелое.
mysqld
вызывает проблемы, Вы можете сделать
mysqladmin -u root ping
или mysqladmin -u root
processlist
?
mysql
), когда Вы пробуете соединяться с сервером MySQL? Клиент
зависает? Вы получаете любой вывод из программы?11.2 Общие ошибки при использовании MySQL
11.2.1 Ошибка
Access denied
Access denied
".11.2.2 Ошибка
MySQL server has gone away
MySQL server has gone away
состоит в том, что у сервера кончилось время ожидания, и он закрыл
подключение. По умолчанию сервер закрывает подключение после 8 часов
отсутствия активности. Вы можете изменять срок, устанавливая переменную
wait_timeout
, когда Вы запускаете mysqld
mysqladmin
version
и исследуя uptime.
CR_SERVER_GONE_ERROR
Клиент не может послать
запрос на сервер. CR_SERVER_LOST
Клиент не получал ошибку при
записи на сервер, но и не получил полный ответ (или любой ответ) на запрос.
mysqld
получает пакет,
который является слишком большим или вне правил, он считает, что что-то
пошло неправильно с клиентом и закрывает подключение. Если Вы нуждаетесь в
больших запросах (например, если Вы работаете с большими столбцами
BLOB
), Вы можете увеличить ограничение запроса, запуская
mysqld
с опцией -O max_allowed_packet=#
(по
умолчанию 1M). Память дополнительного пространства распределена по
требованию, так что mysqld
использует большее количество памяти
только, когда Вы выдаете большой запрос, или когда mysqld
должен
возвратить большую строку результатов!11.2.3 Ошибка
Can't connect
to [local] MySQL server
mysqld
двумя различными способами: Unix-сокеты, которые подключают через файл в
файловой системе (значение по умолчанию /tmp/mysqld.sock) или по
протоколу TCP/IP, который соединяется через номер порта. Unix-сокеты быстрее,
чем TCP/IP, но могут использоваться только при соединении с сервером на том
же самом компьютере. Они применяются, если Вы не определяете hostname, или
если Вы определяете специальное имя localhost
.mysqld
запущен под Win95/Win98. Если же использована NT, Вы
можете также соединяться с именованными каналами. Имя такого именованного
канала MySQL. Если Вы не задаете hostname при соединении с сервером, клиент
сначала попробует соединяться с именованным каналом, и если это не работает,
то соединится с TCP/IP портом. Вы можете заставить использовать именованный
канал под Windows, указав точку (.
) как hostname.Can't connect to ...
обычно означает,
что не имеется сервера MySQL на системе, что Вы используете неправильный файл
сокета или не тот TCP/IP порт при попытке соединиться с mysqld
.
ps
или через администратор задач под
Windows), что вообще имеется процесс, управляющий mysqld
на
Вашем сервере! Если не имеется никакого процесса mysqld
, Вы
должны обратиться к администратору и попросить его запустить сервер.
mysqld
работает, Вы можете проверять сервер,
пробуя различные подключения (номер порта и имя пути сокета):
shell> mysqladmin version
shell> mysqladmin variables
shell> mysqladmin -h `hostname` version variables
shell> mysqladmin -h `hostname` --port=3306 version
shell> mysqladmin -h 'ip for your host' version
shell> mysqladmin --socket=/tmp/mysql.sock version
hostname
: они заставляют вывод hostname
(то есть,
текущий hostname) вставиться в mysqladmin
.Can't
connect to local MySQL server
:mysqld
не запущен.
mysqld
использует пакет MIT-pthreads. Однако, все версии
MIT-pthreads не поддерживают Unix-сокеты. На системе без поддержки сокетов Вы
должны всегда определять hostname явно при соединении с сервером. Попробуйте
использовать эту команду, чтобы Ваше проверить подключение:
shell> mysqladmin -h `hostname` version
mysqld
, (по
умолчанию это /tmp/mysqld.sock). Вы могли бы иметь задачу для
планировщика cron
, которая удаляет старые файлы из каталога
/tmp, и сокет вместе с ними). Вы можете всегда выполнять
mysqladmin version
и проверять, что каталог сокета в самом деле
существует. Подробности в разделе
"11.4.5 Как защитить или
сменить файл сокета MySQL /tmp/mysql.sock".
mysqld
с опцией
--socket=/path/to/socket
. Если Вы изменяете имя пути сокета для
сервера, не забудьте поставить об этом в известность клиентов. Вы можете
сделать это, обеспечивая путь к сокету как параметр клиента. Подробности в
разделе "11.4.5 Как защитить
файл сокета MySQL /tmp/mysql.sock".
mysqld
(например, скриптом
mysql_zap
прежде, чем Вы сможете запустить новый сервер MySQL).
mysqld
так, чтобы он использовал каталог, к
которому Вы можете обращаться.Can't connect to MySQL server
on some_hostname
, Вы можете попробовать следующие вещи, чтобы
выяснить, какова проблема:telnet
your-host-name tcp-ip-port-number
с двойным нажатием
RETURN
. Если имеется сервер MySQL, слушающий на этом порте, Вы
должны получить ответ, который включает номер версии. Если Вы получаете
ошибку подобно telnet: Unable to connect to remote host: Connection
refused
, стало быть там не имеется никакого сервера. Куда он делся?
Это уже другой вопрос, ищите...
mysqld
на локальной машине и
проверить TCP/IP порт, на который mysqld
сконфигурирован
(переменная port
) с помощью mysqladmin variables
.
mysqld
не запущен с параметром
--skip-networking
.11.2.4 Ошибка
Host '...' is blocked
Host 'hostname' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'
mysqld
получил много
(max_connect_errors
) запросов подключения с компьютера
hostname
, которые были прерваны в середине. После
max_connect_errors
потерпевших неудачу запросов
mysqld
считает, что что-то неправильно (подобно нападению
хакеров) и блокирует дальнейшие соединения с этой машины, пока кто-то не
выполняет команду mysqladmin flush-hosts
.mysqld
блокирует компьютер после 10 ошибок
подключения. Вы можете легко корректировать это, запуская сервер так:
shell> safe_mysqld -O max_connect_errors=10000 &
max_connect_errors
не поможет!
11.2.5 Ошибка
Too many connections
Too many connections
, когда Вы
пробуете соединиться с MySQL, это означает, что уже имеется
max_connections
клиентов, работающих с сервером.mysqld
с большим значением для
переменной max_connections
.mysqld
фактически позволяет
(max_connections
+1) подключений. Последнее подключение
зарезервировано для пользователя с привилегией process.
Не давая эту привилегию нормальным пользователям (они не должны нуждаться в
ней), администратор с этой привилегией может войти и использовать
SHOW PROCESSLIST
, чтобы выяснить то, что могло бы быть
неправильно. Подробности приведены в разделе "
4.10 Синтаксис команды SHOW
".11.2.6
Ошибка
Some non-transactional changed tables couldn't be rolled back
Warning: Some non-transactional changed
tables couldn't be rolled back
при попытке сделать
ROLLBACK
, это означает, что некоторые из таблиц, которые Вы
использовали, не поддерживали транзакции. На эти таблицы не будет
воздействовать инструкция ROLLBACK
.mysqld
. Если mysqld
не поддерживает тип таблицы
(или если тип таблицы заблокирован опцией запуска), он взамен создаст таблицу
такого типа, который больше всего подходит к тому, который Вы запросили,
вероятно, это будет MyISAM
.
SHOW TABLE STATUS LIKE 'table_name'.
Подробности в разделе "4.10.2
SHOW TABLE STATUS
".
mysqld
следующей командой:show variables like 'have_%'
. Подробности в разделе
"4.10.4 SHOW VARIABLES
".11.2.7 Ошибка
Out of memory
mysql: Out of memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
ERROR 2008: MySQL client ran out of memory
mysql
.
Причина для этой ошибки: клиент не имеет достаточно памяти, чтобы сохранить
целиком полученный результат.mysql --quick
, который использует
mysql_use_result()
, чтобы получить набор результатов. Это
помещает меньшее количество нагрузки на клиента (но больше на сервер).11.2.8 Ошибка
Packet too large
mysqld
получает пакет больше,
чем max_allowed_packet
байт, он выдает ошибку Packet too
large
и закрывает подключение.mysql
, Вы можете определять
больший буфер, запуская клиента командой
mysql --set-variable=max_allowed_packet=8M
.DBI
), Вы должны установить
размер пакета, когда Вы запускаете сервер. Вы используете опцию командной
строки для mysqld
, чтобы установить
max_allowed_packet
к большему размеру. Например, если Вы
ожидаете сохранять полную длину BLOB
в таблицу, Вы будете должны
запустить сервер с опцией --set-variable=max_allowed_packet=16M
.
mysqld
доступ к
достаточной памяти, чтобы обработать запрос. Если Вы подозреваете, что дело
обстоит именно так, попробуйте добавить ulimit -d 256000
к
скрипту safe_mysqld
и перезапустить mysqld
.11.2.9
Ошибки связи и прерванные подключения
MySQL 3.23.40
Вы получаете только ошибку
Aborted connection
при запуске mysqld
с опцией
--warnings
.
010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh'
mysql_close()
перед
выходом.
wait_timeout
или
interactive_timeout
без того, чтобы делать любые запросы.
Aborted_clients
будет увеличена.Aborted_connects
растет:connect_timeout
секунд, чтобы
получить подключенный пакет.max_allowed_packet
слишком маленький, или запросы требуют
большее количество памяти, чем Вы имеете для mysqld
.11.2.10 Ошибка
The table is full
tmp_table_size
байт.
Чтобы избежать этой проблемы, Вы можете использовать опцию -O
tmp_table_size=#
, чтобы увеличить размер временной таблицы или
использовать опцию SQL_BIG_TABLES
прежде, чем Вы выдаете
проблематичный запрос.mysqld
с опцией
--big-tables
. Это действует точно также, как использование для
всех запросов SQL_BIG_TABLES
.MyISAM
после того, как размер таблицы
станет больше, чем tmp_table_size
.11.2.11 Ошибка
Can't create/write to file
Can't create/write to file '\\sqla3fe_0.ism'.
mysqld
с опцией --tmpdir=path
или добавьте к файлу
опцией сервера следующее:
[mysqld]
tmpdir=C:/temp
perror
. Причиной может быть также полный диск;
shell> perror 28
Error code 28: No space left on device
11.2.12 Ошибка на клиенте
Commands out of sync
Commands out of sync; You can't run this command
now
в Вашем коде пользователя, стало быть Вы вызываете функции
пользователя в неправильном порядке!mysql_use_result()
и пробуете выполнять новый запрос прежде, чем
Вы вызвали mysql_free_result()
. Это может также случаться, если
Вы пробуете выполнять два запроса, которые возвращают данные, без
обязательного вызова функции mysql_use_result()
или
mysql_store_result()
между ними.11.2.13 Ошибка
Ignoring user
Found wrong password for user: 'some_user@some_host'; Ignoring user
mysqld
запустился или перезагрузил
таблицы привилегий, он нашел запись в таблице user
с
недопустимым паролем. В результате запись просто игнорируется системой.mysqld
со старой
таблицей user
. Вы можете проверить это, выполняя mysqlshow
mysql user
, чтобы видеть, является ли поле пароля короче, чем 16
символов. Если это так, Вы можете исправлять это дело запуском скрипта
scripts/add_long_password
.
mysqld
с опцией --old-protocol
. Модифицируйте
пользователя в таблице user
с новым паролем или перезапустите
mysqld
с опцией --old-protocol
.
user
без того, чтобы использовать функцию PASSWORD()
. Примените
mysql
, чтобы модифицировать пользователя в таблице
user
с новым паролем. Удостоверьтесь, что вызвана функция
PASSWORD()
:
mysql> update user set password=PASSWORD('your password')
where user='XXX';
11.2.14
Ошибка
Table 'xxx' doesn't exist
Table 'xxx' doesn't exist
или
Can't find file: 'xxx' (errno: 2)
, это означает, что таблица с
именем xxx
не существует в текущей (актуальной) базе данных.SHOW TABLES
. Подробности в разделе "
4.10 Синтаксис SHOW
".11.2.15
Ошибка
Can't initialize character set xxx
MySQL Connection Failed: Can't initialize character set xxx
--with-charset=xxx
или --with-extra-charsets=xxx
.
Все стандартные двоичные файлы MySQL компилируются с
--with-extra-character-sets=complex
, что допускает поддержку для
всех многобайтных наборов символов.
mysqld
, и файлы определения набора символов не в том месте, где
клиент ожидает находить их. В этом случае Вы должны:
--character-sets-dir=path-to-charset-dir
.
11.2.16 Файл не найден
ERROR '...' not found (errno: 23)
,
Can't open file: ... (errno: 24)
или любую другую ошибку с
errno 23
или errno 24
из MySQL, это означает, что
Вы не распределили достаточно описателей файла для MySQL. Вы можете
использовать утилитку perror
, чтобы получить описание того, что
код ошибки означает:
shell> perror 23
File table overflow
shell> perror 24
Too many open files
shell> perror 11
Resource temporarily unavailable
mysqld
пробует хранить
открытыми слишком много файлов одновременно. Вы можете сообщать, чтобы
mysqld
не открывал так много файлов сразу, или увеличить число
описателей файла, доступных для mysqld
.mysqld
хранил открытым меньшее
количество файлов одновременно, Вы можете сделать кэш таблицы меньшим,
используя опцию -O table_cache=32
при вызове
safe_mysqld
(значение по умолчанию 64). Уменьшение значения
max_connections
также уменьшит число открытых файлов (значение
по умолчанию: 90).mysqld
, Вы можете использовать опцию
--open-files-limit=#
при вызове safe_mysqld
или
-O open-files-limit=#
при запуске mysqld
. Самый
простой способ сделать это состоит в том, чтобы добавить опцию к Вашему
файлу опции. Если Вы имеете старую версию mysqld
, которая не
поддерживает это, Вы можете отредактировать скрипт safe_mysqld
.
Имеется прокомментированная строка ulimit -n 256
в скрипте. Вы
можете удалять символ #
, чтобы раскомментировать строку и
изменить число 256, чтобы воздействовать на число описателей файла.ulimit
(и open-files-limit
) может увеличивать
число описателей файла, но только до ограничения, наложенного операционной
системой. Имеется также жесткое ограничение, которое может быть перекрыто
только, если Вы запускаете safe_mysqld
или mysqld
как root (только не забудьте, что Вы должны также использовать опцию
--user=..
в этом случае). Если Вы должны увеличить ограничение
OS на число описателей файла, доступных каждому процессу, консультируйтесь с
документацией для Вашей операционной системы.tcsh
,
ulimit
не будет работать! tcsh
также сообщит
неправильные значения, когда Вы спросите о текущих ограничениях. В этом
случае Вы должны запустить safe_mysqld
из sh
.11.3 Проблемы при установке
11.3.1 Проблемы компоновки с библиотекой
клиентов MySQL
mysql_
, подобно следующему:
/tmp/ccFKsdPa.o: In function `main':
/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init'
/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x57): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error'
/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close'
-Lpath-to-the-mysql-library -lmysqlclient
В САМОМ КОНЦЕ
строки для компоновщика.undefined reference
для функций
uncompress
или compress
, добавьте -lz
В САМОМ КОНЦЕ строки для компоновщика.undefined reference
для функций,
которые должны существовать в Вашей системе, подобно connect
,
проверьте man-страницу для рассматриваемой функции, чтобы выяснить, какую
библиотеку Вы должны добавить.undefined reference
для функций,
которые не существуют в Вашей системе, подобно следующему:
mf_format.o(.text+0x201): undefined reference to `__lxstat'
mysql_
, или о том, что библиотека
mysqlclient
не может быть найдена, это означает, что Ваша
система не может найти общую библиотеку libmysqlclient.so
.libmysqlclient.so
, к системной переменной
LD_LIBRARY_PATH
.
libmysqlclient.so
, к системной переменной
LD_LIBRARY
.
libmysqlclient.so
в место, где система ищет общие
библиотеки, например, /lib, и модифицируйте общедоступную
библиотечную информацию, выполняя ldconfig
.-static
или удалить динамические
библиотеки MySQL перед компоновкой Вашего кода. Во втором случае Вы должны
убедиться, что никакие другие программы не используют динамические библиотеки!
11.3.2 Как запустить MySQL от
имени нормального пользователя
mysqld
может быть запущен и выполняться любым
пользователем. Чтобы mysqld
работал как Unix-пользователь
user_name
, Вы должны сделать следующие шаги:mysqladmin shutdown
).
user_name
имел права на чтение и запись:
shell> chown -R user_name /path/to/mysql/datadir
Если каталоги или файлы внутри каталога данных MySQL представляют собой
символические ссылки, Вы будете также должны следовать за теми связями и
изменять каталоги и файлы, на которые они указывают. Увы,
chown -R
не может следовать за ссылками для Вас.
user_name
или, если Вы
используете MySQL Version 3.22 или позже, как Unix-пользователь
root
с опцией --user=user_name
.
mysqld
переключится на Unix-пользователя user_name
перед принятием любых подключений.
user
, которая определяет имя
пользователя, к группе [mysqld]
файла /etc/my.cnf (или
my.cnf) в каталоге данных сервера. Например:
[mysqld]
user=user_name
root
указанием
-u root
в командной строке, не имеет никакого отношения
к запуску MySQL как root
. Права доступа и имена пользователей
MySQL полностью независимы от имен в Unix. Единственное подключение с именем
пользователя Unix происходит, если Вы не указали опцию -u
, когда
Вы вызываете программу пользователя. Клиент пробует подключиться, используя
Ваше Unix-имя входа в систему как имя пользователя MySQL.11.3.3 Проблемы с доступом к файлам
mysql
выдает такое сообщение об ошибке, когда создаете таблицу:
ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)
UMASK
может быть установлена неправильно, когда запускается
mysqld
. Значение по умолчанию для umask: 0660
.
Вы можете изменять это поведение, запуская safe_mysqld
так:
shell> UMASK=384 # = 600 in octal
shell> export UMASK
shell> /path/to/safe_mysqld &
RAID
с правами доступа 0700. Вы можете
изменять это поведение, устанавливая переменную UMASK_DIR
.
Если Вы устанавливаете ее, новые каталоги будут созданы с объединением
UMASK
и UMASK_DIR
. Например, если Вы хотите давать
группе доступ ко всем новым каталогам, Вы можете сделать:
shell> UMASK_DIR=504 # =770 в аосьмеричном формате.
shell> export UMASK_DIR
shell> /path/to/safe_mysqld &
UMASK
и UMASK_DIR
заданы в восьмеричном формате,
если они начинаются с ноля.11.4
Проблемы, связанные с администрированием
11.4.1 Что делать, если MySQL падает
mysqld
падает, или ее корень надо искать на клиенте. Вы можете
проверять время работы сервера mysqld
командой mysqladmin
version
. Если mysqld
свалился, Вы можете находить причину
этого в файле mysql-data-directory/hostname.err.write()
после каждой инструкции SQL, но прежде, чем пользователю
сообщают относительно результата. Это не так, если Вы работаете с опцией
delayed_key_writes
, когда только данные будут записаны. Это
означает, что данные в безопасности, даже если сбоит mysqld
,
если ОС гарантируют, что данные будут сброшены из кэша на диск. Вы можете
заставить MySQL сбрасывать кэш принудительно после каждой команды SQL,
запуская mysqld
с опцией --flush
.mysqld
в середине модификации.
mysqld
, которая разрушила его
в середине модификации.
mysqld
на тех же
самых данных в системе, которая не поддерживает хорошие блокировки файловой
системы (обычно обрабатываемые сервером lockd
), или была указана
опция --skip-locking
при запуске сервера.
mysqld
запутался.
ALTER TABLE
на
восстановленной копии таблицы.mysqld
с помощью mysqladmin
shutdown
, запустите myisamchk --silent --force */*.MYI
на
всех таблицах и перезапустите сервер mysqld
. Это гарантирует,
что Вы запустились с чистого состояния.
mysqld --log
и попробуйте определить из
информации в файле регистрации, уничтожает или нет некоторый специфический
запрос сервер. Приблизительно 95% всех ошибок связаны со специфическим
запросом! Обычно это один из последних запросов в журнале. Если Вы можете
повторить процесс уничтожения MySQL одним из запросов даже, когда Вы проверили
все таблицы перед выполнением запроса, то ошибка локализована. Готовьте отчет
об ошибке. Подробности в разделе "Приложение
3. Как сообщать о проблемах и сбоях".
fork_test.pl
и
fork2_test.pl
.
--skip-locking
для mysqld
.
На некоторых системах администратор блокировок lockd
не работает
правильно. Опция --skip-locking
сообщает, чтобы
mysqld
не использовал внешнюю блокировку. Это означает, что Вы
не сможете выполнять несколько серверов mysqld
на тех же самых
данных, и что Вы должны быть внимательны, если Вы используете
myisamchk
, но может быть поучительно опробовать опцию как тест.
mysqladmin -u root processlist
, когда
mysqld
работает, но не отвечает? Иногда mysqld
не
завис даже при том, что Вы могли бы думать именно так. Проблема может
состоять в том, что все подключения находятся в использовании, или может
иметься некоторая внутренняя проблема блокировки. Вызов mysqladmin
processlist
обычно будет способен делать подключение даже в этих
случаях и может обеспечивать полезную информацию относительно текущего числа
подключений и их состояния.
mysqladmin -i 5 status
или
mysqladmin -i 5 -r status
, чтобы произвести статистику в то
время, как Вы выполняете другие Ваши запросы.
BLOB/TEXT
(только VARCHAR
),
Вы можете пробовать изменять все VARCHAR
на CHAR
с
помощью команды ALTER TABLE
. Это вынудит MySQL использовать
строки фиксированных размеров. Они берут небольшое дополнительное
пространство, но намного более терпимы к искажению! Текущий динамический код
строки был в использовании в MySQL AB по крайней мере 3 года без всяких
проблем, но строки динамической длины вообще более склонны к ошибкам, так что
посмотрите, что получится.11.4.2 Как сбрасывать забытый пароль
root
для MySQL, Вы можете
восстанавливать его следующей процедурой:mysqld
отправкой ему команды
kill
(но не kill -9
!). Идентификатор процесса будет
сохранен в .pid
-файле, который обычно хранится в каталоге для
баз данных MySQL:
kill `cat /mysql-data-directory/hostname.pid`
Вы должны быть Unix-пользователем root
или тем пользователем, от
имени которого выполняется сервер.
mysqld
с опцией
--skip-grant-tables
.
mysqld
командой mysql -h hostname
mysql
и смените пароль командой GRANT
. Подробности в
разделе "10.1 Синтаксис GRANT
и
REVOKE
". Вы можете также делать это с помощью команды
mysqladmin -h hostname -u user password new_password
.
mysqladmin -h hostname
flush-privileges
или командой SQL FLUSH PRIVILEGES
.mysqld
с
опцией --skip-grant-tables
, любое использование команды
GRANT
даст Вам ошибку Unknown command
, пока Вы не
выполните FLUSH PRIVILEGES
.11.4.3 Как MySQL обрабатывает полный диск
mysqladmin kill
потоку. Он
будет прерван, когда в следующий раз проверит диск (через минуту).
REPAIR
или
OPTIMIZE
, индексы созданы в пакете после LOAD DATA
INFILE
, или выполнена инструкция ALTER TABLE
.ALTER TABLE
, в этом случае старая
таблица будет оставлена неизменной).11.4.4 Где MySQL хранит временные файлы
TMPDIR
как имя
пути каталога, чтобы сохранить временные файлы. Если Вы не имеете
TMPDIR
, MySQL использует системное значение по умолчанию,
которое является обычно /tmp или /usr/tmp. Если файловая
система, содержащая Ваш временный каталог слишком маленькая, Вы должны
отредактировать скрипт safe_mysqld
, чтобы установить
TMPDIR
так, чтобы указать на каталог в файловой системе, где Вы
имеете достаточно места. Вы можете также устанавливать временный каталог,
используя опцию --tmpdir
при вызове mysqld
.mysqld
завершен. Недостаток
использования скрытых файлов в том, что Вы не будете видеть большой временный
файл, заполняющий файловую систему, в которой размещен временный каталог.ORDER BY
или GROUP BY
) MySQL
обычно использует один или два временных файла. Максимальное дисковое
пространство, необходимое для сортировки:
(Длина сортируемых данных+sizeof(database pointer))*
число совпадающих строк*2
sizeof(database pointer)
обычно 4, но может расти в
будущем для действительно больших таблиц.SELECT
MySQL также создает временные
SQL-таблицы. Они не скрыты и имеют имена формы SQL_*.ALTER TABLE
создает временную таблицу в том же самом
каталоге, где находится и первоначальная таблица.11.4.5 Как защитить или сменить файл
сокета MySQL /tmp/mysql.sock
root
и скомандуйте:
shell> chmod +t /tmp
root
).
ls -ld /tmp
. Если последний бит прав доступа равен
t
, липкий бит установлен./etc/my.cnf
:
[client]
socket=path-for-socket-file
[mysqld]
socket=path-for-socket-file
safe_mysqld
и для
большинства клиентов опцией --socket=path-for-socket-file
.
MYSQL_UNIX_PORT
.
shell> mysqladmin --socket=/path/to/socket version
11.4.6 Проблемы с временными зонами
SELECT NOW()
, возвращающим значения
в GMT, а не по Вашему местному времени, Вы должны установить системную
переменную TZ
к Вашему текущему часовому поясу. Это должно быть
выполнено для среды, в которой выполняется сервер, например, в скрипте
safe_mysqld
или в mysql.server
.11.5 Проблемы с запросами
11.5.1 Чувствительность к регистру в поиске
czech
). Это означает, что, если Вы ищете col_name LIKE
'a%'
, Вы получите все значения столбца, которые начинаются с
A
или a
. Если Вы хотите сделать этот поиск с учетом
регистра, используйте нечто подобное INSTR(col_name, "A")=1
,
чтобы проверить префикс. Или используйте STRCMP(col_name,"A")=0
,
если значение столбца было точно "A"
.>=, >, =, < ,<=
,
сортировка и группировка) основаны на значении сорта каждого символа. Символы
с тем же самым значением сорта обрабатываются как тот же самый символ.LIKE
выполнялся по значениям,
приведенным к верхнему регистру. В более новых версиях MySQL
LIKE
работает точно так же, как другие операторы сравнения.BINARY
. Подробности в разделе
"7.3 Синтаксис CREATE TABLE
".BINARY
. Это работает
потому, что порядок сортировки символов кодирования big5 основан на
порядке ASCII кодов.11.5.2
Проблемы использования столбцов
DATE
DATE
всегда YYYY-MM-DD
. Согласно
ANSI SQL, никакой другой формат не позволяется. Вы должны использовать этот
формат в выражениях UPDATE
и в предложении WHERE инструкций
SELECT
. Например:
mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05';
WHERE
, которое сравнивает дату
со столбцом TIMESTAMP
, DATE
или
DATETIME
. Ослабленная форма означает, что любой символ
пунктуации может использоваться как разделитель между частями. Например,
1998-08-15
и 1998#08#15
являются эквивалентными.
MySQL может также преобразовывать строку не содержащую никаких разделителей
(типа 19980815
), если она имеет смысл как дата.0000-00-00
может быть сохранена и получена
как 0000-00-00
. При использовании даты 0000-00-00
через MyODBC, это будет автоматически преобразовано в
NULL
в MyODBC Version 2.50.12 и выше потому,
что ODBC не может обрабатывать этот вид даты.
mysql> INSERT INTO tbl_name (idate) VALUES (19970505);
mysql> INSERT INTO tbl_name (idate) VALUES ('19970505');
mysql> INSERT INTO tbl_name (idate) VALUES ('97-05-05');
mysql> INSERT INTO tbl_name (idate) VALUES ('1997.05.05');
mysql> INSERT INTO tbl_name (idate) VALUES ('1997 05 05');
mysql> INSERT INTO tbl_name (idate) VALUES ('0000-00-00');
mysql> SELECT idate FROM tbl_name WHERE idate >= '1997-05-05';
mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT idate FROM tbl_name WHERE idate >= '19970505';
mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0;
STRCMP()
представляет собой строковую функцию, так что это
преобразовывает idate
в строку и выполняет сравнение строк. Но
она не конвертирует 19970505
в дату и не сравнивает даты.1998-2-31
, неправильная дата будет сохранена. Если дата не может
быть преобразована в любое приемлемое значение, 0
будет сохранен
в поле DATE
. Это главным образом проблема быстродействия.11.5.3
Проблемы со значениями
NULL
NULL
представляет собой общий источник
беспорядка для новичков в SQL, которые часто думают, что NULL
та же самая вещь, что и пустая строка ''
. Дело обстоит не так!
Например, следующие инструкции полностью различны:
mysql> INSERT INTO my_table (phone) VALUES (NULL);
mysql> INSERT INTO my_table (phone) VALUES ("");
phone
, но первые
вставят значение NULL
, а вторая вставляет пустую строку.
Значение первой может быть расценено как "номер телефона неизвестен", а
значение второй как "не имеет никакого телефона".NULL
всегда неправильно в сравнении с любым
другим значением. Выражение, которое содержит NULL
, всегда
производит значение NULL
, если иное не обозначено в документации
для операторов и функций, включаемых в выражение. Все столбцы в следующем
примере возвращают именно NULL
:
mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL);
NULL
, Вы не можете использовать тест =NULL
.
Следующая инструкция не возвращает никаких строк потому, что
expr=NULL
всегда равно FALSE для любого выражения:
mysql> SELECT * FROM my_table WHERE phone = NULL;
NULL
, Вы должны использовать тест
IS NULL
. Следующее показывает, как найти номер телефона
NULL
и пустой номер телефона:
mysql> SELECT * FROM my_table WHERE phone IS NULL;
mysql> SELECT * FROM my_table WHERE phone = "";
NULL
. Вы должны объявить
столбцы для индекса как NOT NULL
. Наоборот, Вы не можете
вставлять NULL
в индексированный столбец.LOAD DATA
INFILE
, пустые столбцы модифицируются с ''
. Если Вы
хотите иметь в столбце значение NULL
, Вы должны использовать
\N
в текстовом файле. Литеральное слово 'NULL'
может также с успехом использоваться при некоторых обстоятельствах.
Подробности есть в разделе "8.9 Синтаксис
LOAD DATA INFILE
".ORDER BY
значения NULL
будут
представлены первыми. Если Вы сортируете в порядке по убыванию, используя
DESC
, значения NULL
, понятно, окажутся в хвосте.
При использовании GROUP BY
, все значения NULL
будут
расценены как равные.NULL
, Вы можете использовать
операторы IS NULL
и IS NOT NULL
, а также функцию
IFNULL()
. Производительность улучшится.NULL
обработаны особо. Если Вы вставляете NULL
в первый столбец типа
TIMESTAMP
в таблице, реально будут вставлены текущая дата и
время. Если Вы вставляете NULL
в столбец с поддержкой
AUTO_INCREMENT
, вставится следующее число в последовательности.
11.5.4 Проблемы с
alias
GROUP BY
, ORDER BY
или в части HAVING
.
Псевдонимы могут также использоваться, чтобы дать столбцам лучшие имена:
SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0;
SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0;
SELECT id AS "Customer identity" FROM table_name;
WHERE
. Это потому, что, когда код WHERE
выполнен, значение столбца не может быть определено. Например, следующий
запрос строго запрещен:
SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id;
WHERE
выполнена, чтобы определить, которые строки
должны быть включены в часть GROUP BY
в то время, как
HAVING
используется, чтобы решить, которые строки из набора
результатов должны использоваться.11.5.5
Удаление строк из связанных таблиц
DELETE
, Вы должны использовать
следующий подход, чтобы удалить строки из двух связанных таблиц:SELECT
строки, основываясь на некотором условии
WHERE
в основной таблице.
DELETE
строки в основной таблице, основываясь на том
же самом условии.
DELETE FROM связанная_таблица WHERE связанные_столбцы
IN (выбранные_строки)
.related_column
) больше, чем 1048576 (значение по умолчанию
для max_allowed_packet
), Вы должны расчленить его на меньшие
части и выполнить много инструкций DELETE
. Вы, вероятно,
достигнете пика производительности при удалении 100-1000
related_column
на запрос, если related_column
является индексом. В противном случае быстродействие независимо от числа
параметров в предложении IN
.11.5.6 Решение проблем с несоответствием строк
EXPLAIN
и выправьте его, если
Вы можете найти что-то такое, что является очевидно неправильным. Подробности
в разделе "14.2.1 Синтаксис
EXPLAIN
(получение информации о SELECT
)".
WHERE
.
LIMIT 10
.
SELECT
для столбца, который должен был
соответствовать в таблице, которая была последней удалена из запроса.
FLOAT
или DOUBLE
с
числовыми столбцами, которые имеют десятичные числа, Вы не можете
использовать =
. Эта проблема общая в большинстве компьютерных
языков потому, что значения с плавающей запятой не точные значения:
mysql> SELECT * FROM table_name WHERE float_column=3.5;
->
mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55;
В большинстве случаев замена FLOAT
на DOUBLE
исправит это дело.
mysql test <
query.sql
, который показывает Ваши проблемы. Вы можете создавать файл
теста с помощью mysqldump --quick database tables >
query.sql
. Откройте файл в редакторе, удалите некоторые строки и
добавьте Вашу инструкцию выбора в конце файла. Проверьте, что Вы все еще
имеете Вашу проблему:
shell> mysqladmin create test2
shell> mysql test2 < query.sql
Отправьте файл теста, используя mysqlbug
на
mysql@lists.mysql.com.11.6 Проблемы с определениями таблиц
11.6.1 Проблемы с
ALTER TABLE
ALTER TABLE
изменяет таблицу на текущий набор символов. Если
Вы в течение ALTER TABLE
получаете ошибку дублирования ключа, то
причиной является то, что новые наборы символов отображают разные ключи к
тому же самому значению, или что таблица разрушена, тогда Вы должны выполнить
REPAIR TABLE
на таблице.ALTER TABLE
падает с ошибкой подобно этой:
Error on rename of './database/name.frm' to
'./database/B-a.frm' (Errcode: 17)
ALTER TABLE
, и имеется старая таблица с именем A-что-то
или B-что-то. В этом случае идите в каталог данных MySQL, и удалите
там все файлы, которые имеют имена, начинающиеся с A-
или
B-
. Вы можете перемещать их в другое место вместо того, чтобы
удалить их сразу.ALTER TABLE
работает следующим образом:11.6.2 Как менять порядок столбцов в таблице
SELECT col_name1, col_name2, col_name3 FROM tbl_name;
col_name1
, col_name2
,
col_name3
в то время, как:
SELECT col_name1, col_name3, col_name2 FROM tbl_name;
col_name1
,
col_name3
, col_name2
.SELECT *
и получать столбцы, основываясь на их позиции потому,
что порядок, в котором столбцы возвращены, НЕЛЬЗЯ
ГАРАНТИРОВАТЬ через какое-то время. Простое изменение Вашей базы
данных может заставить Вашу прикладную программу развалиться полностью.INSERT INTO new_table SELECT fields-in-new_table-order
FROM old_table
.
old_table
.
ALTER TABLE new_table RENAME old_table
.11.6.3 Проблемы с TEMPORARY TABLE
TEMPORARY TABLES
).HEAP
,
ISAM
или MyISAM
.
select * from temporary_table, temporary_table as t2;
Это планируется исправить в версии 4.0.
RENAME
для таблиц
TEMPORARY
. Обратите внимание, что ALTER TABLE org_name
RENAME new_name
тем не менее работает вполне корректно! Это
планируется исправить в версии 4.0.
Найди своих коллег! |