Где в Linux находятся базы MySQL
Чаще всего базы данных MySQL на Linux хосте находятся в директории /var/lib/mysql.
Но перед тем, как резервировать эту папку, нужно все же быть уверенным, что именно тут находятся актуальные файлы базы данных. Как это проверить?
1) Самое простое и не самое точное: смотрим дату обновлений файлов в папке /var/lib/mysql. Если даты свежие, значит весьма вероятно, база данных лежит тут.
2) файл конфигурации «my.cnf»
MySQL (MariaDB) хранят настройки в файлах с расширением .cnf. По-умолчанию — файл my.cnf.
Скорее всего, это файл находится в /etc/my.cnf.
Лучше не гадать, а найти файлы my.cnf на хосте:
# find / -type f -name my.cnf
/etc/my.cnf
У меня в этом файле была единственная ссылка на директорию /etc/my.cnf.d, в которой были файлы:
auth_gssapi.cnf
client.cnf
enable_encryption.preset
mariadb-server.cnf
mysql-clients.cnf
В файле /etc/my.cnf.d/mariadb-server.cnf:
смотрим секцию mysqld:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/run/mariadb/mariadb.pid
Директория с базой данных: /var/lib/mysql
3) как еще можно искать конфиг базы mysql?
# mysql —help | grep /my.cnf
/etc/my.cnf ~/.my.cnf
# mysqladmin —help | grep /my.cnf
/etc/my.cnf ~/.my.cnf
Зная файл конфига, вы легко найдете расположение базы данных.
4) изврат, но почему бы и да?
Используя команду lsof, можно посмотреть, какие файлы задействованы базой данных:
# lsof -u mysql
.
mysqld 1084 mysql 17r DIR 253,0 4096 394860 /var/lib/mysql
mysqld 1084 mysql 18uW REG 253,0 114688 657855 /var/lib/mysql/postfix/domain_admins.ibd
mysqld 1084 mysql 19uW REG 253,0 98304 657859 /var/lib/mysql/postfix/vacation_notification.ibd
mysqld 1084 mysql 20uW REG 253,0 131072 657863 /var/lib/mysql/postfix/alias_domain.ibd
mysqld 1084 mysql 21uW REG 253,0 98304 657866 /var/lib/mysql/postfix/domain.ibd
mysqld 1084 mysql 22uW REG 253,0 114688 657856 /var/lib/mysql/postfix/mailbox.ibd
Сразу несколько файлов задействованы в директории /var/lib/mysql.
lsof вообще команда крайне полезная.
Авторизуйтесь для добавления комментариев!

Почтовый сервер Mikrotik VPN 3proxy Шифрование Squid Резервное копирование Защита почты Виртуальные машины Настройка сервера java kvm Групповые политики SELinux OpenVPN IPFW WDS Lightsquid Samba firewalld systemd Mobile libvirt Remote desktop WiFi Iptables NAT Postfix Dovecot Удаление данных Софт Безопасность Winbox User agent Хостинг Передача данных Онлайн сервисы Privacy LetsEncrypt VPN сервер Настройка прокси RRDTool sendmail Rsync Linux SSH Система Windows Синхронизация Облако fail2ban FreeBSD
Где указывается сокет подключения для phpmyadmin?
У меня сокет mysql находиться по пути /var/lib/mysql/mysql.sock. Sql сервер запущен. Зайти в mysql я могу. Но phpmyadmin при установке почему то пытается соединиться с mysql на стандартном сокете /var/run/mysqld/mysqld.sock. Указывал в /etc/phpmyadmin/config.inc.php сокет, не помогает. Не могу понять куда копать, подскажите пожалуйста.
- Вопрос задан более трёх лет назад
- 861 просмотр
Комментировать
Решения вопроса 1
nessero @nessero Автор вопроса
решил проблему в /etc/phpmyadmin/config-db.php нужно было указать $dbserver = ‘127.0.0.1’ и в /etc/phpmyadmin/config.inc.php добавить строчку $cfg[‘Servers’][$i][‘socket’] = ‘/var/lib/mysql/mysql.sock’;
Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
Ответы на вопрос 0
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- JavaScript
- +1 ещё
Выгрузка JS кода в php, но не просто?
- 1 подписчик
- 6 часов назад
- 54 просмотра
Mysql sock где находится
Если возникают проблемы с тем, что кто угодно может удалить коммуникационный сокет MySQL `/tmp/mysql.sock', то в большинстве версий Unix можно защитить содержимое `/tmp', установив на каталоге «липучий» (sticky) бит. Войдите в систему как пользователь root и выполните следующую команду:
shell> chmod +t /tmp
Это защитит ваш каталог `/tmp': теперь удалять в нем файлы смогут только их владельцы или суперпользователь ( root ).
Проверить, установлен ли «липучий» (sticky) бит, можно, выполнив ls -ld /tmp . Если последним битом прав является t , то бит установлен.
Изменить путь к каталогу, где MySQL открывает сокет-файл, можно, воспользовавшись одним из следующих способов:
-
Укажите путь в глобальном или локальном файле опций. Например, поместите в `/etc/my.cnf':
[client] socket=path-for-socket-file [mysqld] socket=path-for-socket-file
Проверить, работает ли сокет, можно следующей командой:
shell> mysqladmin --socket=/path/to/socket version
8 Проблемы и общие ошибки
Эта глава описывает некоторые общие проблемы и сообщения об ошибках, с которыми пользователи столкнулись. Вы узнаете, как точно определить происходящее, и что делать, чтобы решить возникшую проблему. Вы также найдете здесь соответствующие решения для некоторых общих проблем.
8.1 Как определять, что вызывает проблемы
Когда Вы сталкиваетесь с проблемами, первое, что Вы должны сделать, это однозначно выяснить, которая программа или часть оборудования вызывает данные проблемы.
- Если Вы имеете один из следующих признаков, то это, вероятно, аппаратные средства (подобно памяти, системной плате, CPU или жесткому диску) или ядерная проблема:
- Клавиатура не работает. Это может обычно проверяться, нажимая Caps Lock. Если индикатор Caps Lock не изменяется, Вы должны заменить Вашу клавиатуру. При выполнении этого, Вы должны попробовать перезагрузить Ваш компьютер и проверить все кабели, идущие на клавиатуру.
- Указатель мышки не двигается.
- Машина не отвечает на сетевые запросы с удаленной машины.
- Различные, не связанные друг с другом, программы не ведут себя правильно.
- Если Ваша система неожиданно перезагружена (дефектная программа уровня пользователя никогда не может этого сделать).
Если после того, как Вы исследовали все другие возможности и заключили, что проблема заключается в клиенте или сервере MySQL, самое время сделать отчет об ошибке для списка рассылки или группы поддержки. В отчете ошибки попробуйте дать очень детальное описание того, как система ведет себя, и что с ней случается. Вы должны также установить, почему Вы думаете, что это вызвано именно MySQL. Учтите все ситуации в этой главе. Установите любые проблемы точно, как они появляются, когда Вы исследуете вашу систему. Используйте метод «вырезать и вставить» для любого вывода, сообщений об ошибках из программ и журналов.
Если сбоит программа, всегда полезно знать следующее:
- Программа в запросе получила ошибку segmentation fault (core dumped)?
- Программа захватывает CPU целиком и полностью? Проверьте через top . Позвольте программе поработать некоторое время, она может оценивать что-то тяжелое.
- Если это сервер mysqld вызывает проблемы, Вы можете сделать mysqladmin -u root ping или mysqladmin -u root processlist ?
- Что говорит программа пользователя (попробуйте, например, mysql ), когда Вы пробуете соединяться с сервером MySQL? Клиент зависает? Вы получаете любой вывод из программы?
При посылке отчета об ошибке Вы должны обязательно следовать правилам, описанным в этом руководстве.
8.2 Общие ошибки при использовании MySQL
Этот раздел перечисляет некоторые ошибки, с которыми пользователи часто сталкиваются. Здесь Вы найдете описания ошибок, и как решить проблему.
8.2.1 Ошибка Access denied
8.2.2 Ошибка MySQL server has gone away
Наиболее общая причина для ошибки MySQL server has gone away состоит в том, что у сервера кончилось время ожидания, и он закрыл подключение. По умолчанию сервер закрывает подключение после 8 часов отсутствия активности. Вы можете изменять срок, устанавливая переменную wait_timeout , когда Вы запускаете mysqld
Другая общая причина получения такой ошибки состоит в том, что Вы закрыли соединение, а теперь пробуете выполнить запрос на закрытом подключении.
Вы можете проверять, что MySQL работает, выполняя mysqladmin version и исследуя uptime.
Если Вы имеете скрипт, Вы только должны снова выдать запрос клиенту, чтобы сделать автоматическое переподключение.
Вы обычно можете получать следующие коды ошибки в этом случае:
CR_SERVER_GONE_ERROR Клиент не может послать запрос на сервер. CR_SERVER_LOST Клиент не получал ошибку при записи на сервер, но и не получил полный ответ (или любой ответ) на запрос. Вы можете также получать эти ошибки, если Вы посылаете неправильной или слишком большой запрос серверу. Если mysqld получает пакет, который является слишком большим или вне правил, он считает, что что-то пошло неправильно с клиентом и закрывает подключение. Если Вы нуждаетесь в больших запросах (например, если Вы работаете с большими столбцами BLOB ), Вы можете увеличить ограничение запроса, запуская mysqld с опцией -O max_allowed_packet=# (по умолчанию 1M). Память дополнительного пространства распределена по требованию, так что mysqld использует большее количество памяти только, когда Вы выдаете большой запрос, или когда mysqld должен возвратить большую строку результатов!
8.2.3 Ошибка Can’t connect to [local] MySQL server
Клиент MySQL под ОС Unix может соединяться с сервером mysqld двумя различными способами: Unix-сокеты, которые подключают через файл в файловой системе (значение по умолчанию /tmp/mysqld.sock ) или по протоколу TCP/IP, который соединяется через номер порта. Unix-сокеты быстрее, чем TCP/IP, но могут использоваться только при соединении с сервером на том же самом компьютере. Они применяются, если Вы не определяете hostname, или если Вы определяете специальное имя localhost .
Под Windows Вы можете соединяться только через TCP/IP, если сервер mysqld запущен под Win95/Win98. Если же использована NT, Вы можете также соединяться с именованными каналами. Имя такого именованного канала MySQL. Если Вы не задаете hostname при соединении с сервером, клиент сначала попробует соединяться с именованным каналом, и если это не работает, то соединится с TCP/IP портом. Вы можете заставить использовать именованный канал под Windows, указав точку ( . ) как hostname.
Сообщение error (2002) Can’t connect to . обычно означает, что не имеется сервера MySQL на системе, что Вы используете неправильный файл сокета или не тот TCP/IP порт при попытке соединиться с mysqld .
Начните с проверки ( ps или через администратор задач под Windows), что вообще имеется процесс, управляющий mysqld на Вашем сервере! Если не имеется никакого процесса mysqld , Вы должны его запустить. Подробности в разделе «2.4.2 Проблемы с запуском сервера MySQL».
Если процесс 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 не запущен.
- Вы работаете на системе, которая использует MIT-PTHREADS. Если Вы работаете на системе, которая не имеет местной поддержки потоков, mysqld использует пакет MIT-pthreads. Подробности в разделе «2.2.2 ОС, поддерживаемые MySQL». Однако, все версии MIT-pthreads не поддерживают Unix-сокеты. На системе без поддержки сокетов Вы должны всегда определять hostname явно при соединении с сервером. Попробуйте использовать эту команду, чтобы проверить подключение:
shell> mysqladmin -h `hostname` version
Если Вы получаете сообщение об ошибке 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 .
Если Вы получаете сообщение об ошибке:
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 &
Обратите внимание, что, если Вы получаете это сообщение об ошибках для данного компьютера, Вы должны сначала проверить, что не имеется чего-нибудь неправильного с TCP/IP подключениями. Если Ваши TCP/IP подключения не работают, увеличение переменной max_connect_errors не поможет!
Если Вы получаете ошибку Too many connections , когда Вы пробуете соединиться с MySQL, это означает, что уже имеется max_connections клиентов, работающих с сервером.
Если Вы нуждаетесь в большем количестве подключений, чем значение по умолчанию (100), то перезапустите mysqld с большим значением для переменной max_connections .
Обратите внимание, что mysqld фактически позволяет ( max_connections +1) подключений. Последнее подключение зарезервировано для пользователя с привилегией process . Не давая эту привилегию нормальным пользователям (они не должны нуждаться в ней), администратор с этой привилегией может войти и использовать SHOW PROCESSLIST , чтобы выяснить то, что могло бы быть неправильно. Подробности в разделе «4.5.5 Синтаксис команды SHOW «.
Максимальное количество подключений зависит от того, как хороша библиотека потоков на данной платформе. Linux или Solaris могут поддерживать 500-1000 одновременных подключений в зависимости от того, сколько RAM Вы имеете, и что Ваша клиентура делает.
8.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.5.5.2 SHOW TABLE STATUS «.
Вы можете проверять, какие расширения поддерживает Ваша версия mysqld следующей командой:
show variables like ‘have_%’ . Подробности в разделе «4.5.5.4 Синтаксис SHOW VARIABLES «.
8.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() , чтобы получить набор результатов. Это помещает меньшее количество нагрузки на клиента (но больше на сервер).
8.2.8 Ошибка Packet too large
Когда клиент MySQL или сервер 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 .
Вы можете также получать странные проблемы с большими пакетами, если Вы используете большие blob’ы, но не дали mysqld доступ к достаточной памяти, чтобы обработать запрос. Если Вы подозреваете, что дело обстоит именно так, попробуйте добавить ulimit -d 256000 к скрипту safe_mysqld и перезапустить mysqld .
Начиная с 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 секунд, чтобы получить подключенный пакет.
Обратите внимание, что вышеупомянутое может указывать, что кто-то пробует врываться в Вашу базу данных!
- Использование дуплексного протокола Ethernet в половинном и полном режимах с Linux. Многие драйверы Ethernet для Linux имеют эту ошибку. Вы должны проверить ее наличие, пересылая огромный файл через ftp между двумя машинами. Если передача входит в режим «burst-pause-burst-pause . «, значит Вы испытываете дуплексный синдром Linux. Единственное решение для этой проблемы: правильно настроить драйвер.
- Некоторые проблемы с библиотекой потоков, которая вызывает прерывания на разных вызовах чтения.
- Неправильно настроен протокол TCP/IP.
- Где-то накрылась сеть: кабель, коммутатор, концентратор.
- max_allowed_packet слишком маленький, или запросы требуют большее количество памяти, чем Вы имеете для mysqld .
8.2.10 Ошибка The table is full
Эта ошибка происходит в старых версиях MySQL, когда расположенная в памяти временная таблица становится больше, чем tmp_table_size байт. Чтобы избежать этой проблемы, Вы можете использовать опцию -O tmp_table_size=# , чтобы увеличить размер временной таблицы или использовать опцию SQL_BIG_TABLES прежде, чем Вы выдаете проблематичный запрос.
Вы можете также запустить mysqld с опцией —big-tables . Это действует точно также, как использование для всех запросов SQL_BIG_TABLES .
В MySQL Version 3.23 временная таблица в памяти будет автоматически преобразована в дисковую MyISAM после того, как размер таблицы станет больше, чем tmp_table_size .
8.2.11 Ошибка Can’t create/write to file
Если для некоторых запросов Вы получаете ошибку типа:
Can't create/write to file '\\sqla3fe_0.ism'.
Это означает, что MySQL не может создать временный файл для набора результатов в заданном временном каталоге. Для исправления запустите mysqld с опцией —tmpdir=path или добавьте к файлу опцией сервера следующее:
[mysqld] tmpdir=C:/temp
Считается, что каталог c:\temp существует.
Проверьте также код ошибки, который Вы получаете через perror . Причиной может быть также полный диск;
shell> perror 28 Error code 28: No space left on device
8.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() между ними.
8.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 .
- Пользователь имеет старый пароль (длиной 8 символов), и Вы не запускали mysqld с опцией —old-protocol . Модифицируйте пользователя в таблице user с новым паролем или перезапустите mysqld с опцией —old-protocol .
- Вы определили пароль в таблице user без того, чтобы использовать функцию PASSWORD() . Примените mysql , чтобы модифицировать пользователя в таблице user с новым паролем. Удостоверьтесь, что вызвана функция PASSWORD() :
mysql> update user set password=PASSWORD('your password') where user='XXX';8.2.14 Ошибка Table ‘xxx’ doesn’t exist
Если Вы получаете ошибку Table ‘xxx’ doesn’t exist или Can’t find file: ‘xxx’ (errno: 2) , это означает, что таблица с именем xxx не существует в текущей (актуальной) базе данных.
Обратите внимание, что MySQL использует каталоги и файлы, чтобы сохранить базы данных и таблицы, так что имена баз данных и таблиц чувствительны к регистру! В Windows это не так, но все ссылки к данной таблице внутри запроса должны использовать тот же самый регистр.
Вы можете проверить, какие таблицы Вы имеете в текущей базе данных, через SHOW TABLES . Подробности в разделе » 4.5.5 Синтаксис SHOW «.
8.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 .
- Копируйте символьные файлы определения туда, где их ищет клиент.
Если Вы получаете 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 .
8.3 Проблемы при установке
Если Вы компонуете Вашу программу и получаете ошибки для невызванных символов, которые начинаются с mysql_ , подобно следующему:
/tmp/ccFKsdP8.o: In function `main': /tmp/ccFKsdP8.o(.text+0xb): undefined reference to `mysql_init' /tmp/ccFKsdP8.o(.text+0x31): undefined reference to `mysql_real_connect' /tmp/ccFKsdP8.o(.text+0x57): undefined reference to `mysql_real_connect' /tmp/ccFKsdP8.o(.text+0x69): undefined reference to `mysql_error' /tmp/ccFKsdP8.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'
Это обычно означает, что библиотека компилируется на системе, которая не на 100%, совместима с Вашей. В этом случае Вы должны загрузить последний исходник MySQL и откомпилировать библиотеку непосредственно.
Если Вы пробуете выполнять программу и получаете ошибки для невызванных символов, которые начинаются с mysql_ , или о том, что библиотека mysqlclient не может быть найдена, это означает, что Ваша система не может найти общую библиотеку libmysqlclient.so .
- Добавьте путь к каталогу, где Вы имеете libmysqlclient.so , к системной переменной LD_LIBRARY_PATH .
- Добавьте путь к каталогу, где Вы имеете libmysqlclient.so , к системной переменной LD_LIBRARY .
- Копируйте libmysqlclient.so в место, где система ищет общие библиотеки, например, /lib , и модифицируйте общедоступную библиотечную информацию, выполняя ldconfig .
Другой способ решать эту проблему состоит в том, чтобы скомпоновать Вашу программу статически с опцией -static или удалить динамические библиотеки MySQL перед компоновкой Вашего кода. Во втором случае Вы должны убедиться, что никакие другие программы не используют динамические библиотеки!
MySQL-сервер mysqld может быть запущен и выполняться любым пользователем. Чтобы mysqld работал как Unix-пользователь user_name , Вы должны сделать следующие шаги:
- Завершите сервер, если он запущен ( mysqladmin shutdown ).
- Измените каталоги баз данных и файлы так, чтобы user_name имел права на чтение и запись:
shell> chown -R user_name /path/to/mysql/datadir
[mysqld] user=user_name
Обратите внимание, что доступ к MySQL как root указанием -u root в командной строке, не имеет никакого отношения к запуску MySQL как root . Права доступа и имена пользователей MySQL полностью независимы от имен в Unix. Единственное подключение с именем пользователя Unix происходит, если Вы не указали опцию -u , когда Вы вызываете программу пользователя. Клиент пробует подключиться, используя Ваше Unix-имя входа в систему как имя пользователя MySQL.
8.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 &
По умолчанию MySQL создаст базу данных и каталоги RAID с правами доступа 0700. Вы можете изменять это поведение, устанавливая переменную UMASK_DIR . Если Вы устанавливаете ее, новые каталоги будут созданы с объединением UMASK и UMASK_DIR . Например, если Вы хотите давать группе доступ ко всем новым каталогам, Вы можете сделать:
shell> UMASK_DIR=504 # = 770 в аосьмеричном формате. shell> export UMASK_DIR shell> /path/to/safe_mysqld &
В MySQL Version 3.23.25 и выше MySQL считает, что значения UMASK и UMASK_DIR заданы в восьмеричном формате, если они начинаются с ноля.
Все версии MySQL проверены на многих платформах прежде, чем они выпущены. Это не означает, что не имеется любых ошибок в MySQL, но это означает, что их там очень мало.
Сначала Вы должны пробовать выяснять, состоит ли проблема в том, что mysqld падает, или ее корень надо искать на клиенте. Вы можете проверять время работы сервера mysqld командой mysqladmin version . Если mysqld свалился, Вы можете находить причину этого в файле mysql-data-directory/hostname.err .
Много сбоев MySQL вызваны разрушенным индексом или файлами данных. MySQL модифицирует данные относительно диска через системный вызов write() после каждой инструкции SQL, но прежде, чем пользователю сообщают относительно результата. Это не так, если Вы работаете с опцией delayed_key_writes , когда только данные будут записаны. Это означает, что данные в безопасности, даже если сбоит mysqld , если ОС гарантируют, что данные будут сброшены из кэша на диск. Вы можете заставить MySQL сбрасывать кэш принудительно после каждой команды SQL, запуская mysqld с опцией —flush .
Вышеупомянутое означает, что обычно Вы не должны получить разрушенные таблицы и файлы, если:
- Кто-то уничтожил mysqld в середине модификации.
- Вы нашли неизвестную ошибку в mysqld , которая разрушила его в середине модификации.
- Кто-то управляет файлами данных или индекса вне mysqld без того, чтобы блокировать таблицу.
- Если Вы управляете несколькими серверами mysqld на тех же самых данных в системе, которая не поддерживает хорошие блокировки файловой системы (обычно обрабатываемые сервером lockd ), или была указана опция —skip-locking при запуске сервера.
- Вы имеете поврежденный файл индекса или данных, который содержит очень неправильные данные, в результате mysqld запутался.
- Вы нашли ошибку в коде памяти. Это не очень вероятно, но это по крайней мере возможно. В этом случае Вы можете пробовать изменять файл к другому драйверу базы данных использованием ALTER TABLE на восстановленной копии таблицы.
Поскольку очень трудно узнать, почему что-то терпит крах, сначала попробуйте проверить следующее:
- Завершите mysqld с помощью mysqladmin shutdown , запустите myisamchk —silent —force */*.MYI на всех таблицах и перезапустите сервер mysqld . Это гарантирует, что Вы запустились с чистого состояния.
- Используйте mysqld —log и попробуйте определить из информации в файле регистрации, уничтожает или нет некоторый специфический запрос сервер. Приблизительно 95% всех ошибок связаны со специфическим запросом! Обычно это один из последних запросов в журнале. Если Вы можете повторить процесс уничтожения MySQL одним из запросов даже, когда Вы проверили все таблицы перед выполнением запроса, то ошибка локализована. Готовьте отчет об ошибке. Подробности в разделе «1.4.1 Как сообщать об ошибках и проблемах».
- Попытайтесь сделать тестовый образец, который авторы пакета могут использовать, чтобы воспроизвести проблему. Подробности в разделе «6.1.6 Создание случая теста, когда Вы испытываете искажение таблицы».
- Попробуйте управлять включенным тестом mysql-test и эталонными тестами MySQL. Подробности в разделе «5.1.4 Пакет тестов MySQL Benchmark Suite». Они должны проверить MySQL довольно хорошо. Вы можете также добавлять к эталонным тестам код, который моделирует Вашу прикладную программу. Эталонные тесты могут быть найдены в каталоге bench дистрибутива исходного кода или, для двоичных дистрибутивов, в каталоге sql-bench под Вашим каталогом установок MySQL.
- Попробуйте выполнить fork_test.pl и fork2_test.pl .
- Если Вы конфигурируете MySQL для отладки, будет намного проще собрать информацию относительно возможных ошибок, если что-то идет неправильно. Реконфигурируйте MySQL с опцией —with-debug или с —with-debug=full для скрипта configure , чтобы конфигурировать и затем перетранслировать пакет. Подробности в разделе «6.1 Отладка сервера MySQL».
- При конфигурировании MySQL для отладки неплохо включить безопасный распределитель памяти, это может находить некоторые ошибки. Это также обеспечивает много вывода относительно того, что случается с пакетом.
- Вы применили самые последние заплатки для Вашей операционной системы?
- Используйте опцию —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 , чтобы произвести статистику в то время, как Вы выполняете другие Ваши запросы.
- Попробуйте следующее:
- Запустите mysqld из gdb (или в другом отладчике. Подробности в разделе » 6.1.3 Отладка mysqld под gdb».
- Выполните тестовые скрипты.
- Просмотрите обратную трассировку и локальные переменные в 3 самых низких уровнях. В gdb Вы можете делать это следующими командами, когда mysqld развалился под gdb:
backtrace info local up info local up info local
8.4.2 Как сбрасывать забытый пароль
Если Вы забыли пароль пользователя root для MySQL, Вы можете восстанавливать его следующей процедурой:
Завершите сервер mysqld отправкой ему команды kill (но не kill -9 !). Идентификатор процесса будет сохранен в .pid -файле, который обычно хранится в каталоге для баз данных MySQL:kill `cat /mysql-data-directory/hostname.pid`
Обратите внимание, что после того, как Вы запустили mysqld с опцией —skip-grant-tables , любое использование команды GRANT даст Вам ошибку Unknown command , пока Вы не выполните FLUSH PRIVILEGES .
Когда диск полностью заполнится, MySQL делает следующее:
- Он проверяет раз в минуту, чтобы видеть, имеется или нет достаточно места, чтобы записать текущую строку. Если имеется достаточно места на диске, работа продолжается, как будто ничто не случилось.
- Каждые 5-6 минут в журнал пишется предупреждение о полном диске.
Чтобы облегчить проблему, Вы можете предпринять следующие действия:
- Чтобы продолжать работу, Вы должны только освободить достаточно места, чтобы вставить все записи.
- Чтобы прервать поток, пошлите mysqladmin kill потоку. Он будет прерван, когда в следующий раз проверит диск (через минуту).
- Обратите внимание, что другие потоки могут ждать таблицу, которая вызвала переполнение диска. Если Вы имеете несколько блокированных потоков, уничтожение того, который переполнил диск, позволит другим продолжаться.
Исключительные ситуации: Вы используете REPAIR или OPTIMIZE , индексы созданы в пакете после LOAD DATA INFILE , или выполнена инструкция ALTER TABLE .
Все вышеприведенные команды могут использовать большие временные файлы, которые остались после них на диске, что вызовет большие проблемы для остальной части системы. Если MySQL переполняет диск при выполнении любой из вышеупомянутых операций, он удалит большие временные файлы и отметит таблицу как поврежденную (исключение: ALTER TABLE , в этом случае старая таблица будет оставлена неизменной).
MySQL использует значение системной переменной TMPDIR как имя пути каталога, чтобы сохранить временные файлы. Если Вы не имеете TMPDIR , MySQL использует системное значение по умолчанию, которое является обычно /tmp или /usr/tmp . Если файловая система, содержащая Ваш временный каталог слишком маленькая, Вы должны отредактировать скрипт safe_mysqld , чтобы установить TMPDIR так, чтобы указать на каталог в файловой системе, где Вы имеете достаточно места. Вы можете также устанавливать временный каталог, используя опцию —tmpdir при вызове mysqld .
MySQL создает все временные файлы как скрытые. Это гарантирует, что временные файлы будут удалены, если mysqld завершен. Недостаток использования скрытых файлов в том, что Вы не будете видеть большой временный файл, заполняющий файловую систему, в которой размещен временный каталог.
При сортировке ( ORDER BY или GROUP BY ) MySQL обычно использует один или два временных файла. Максимальное дисковое пространство, необходимое для сортировки:
(Длина сортируемых данных+sizeof(database pointer))* число совпадающих строк*2
Здесь sizeof(database pointer) обычно 4, но может расти в будущем для действительно больших таблиц.
Для некоторого запроса SELECT MySQL также создает временные SQL-таблицы. Они не скрыты и имеют имена формы SQL_* .
ALTER TABLE создает временную таблицу в том же самом каталоге, где находится и первоначальная таблица.
Если Вы имеете проблемы с тем фактом, что любой может удалять сокет MySQL /tmp/mysql.sock , Вы можете, на большинстве версий Unix, защитить Вашу файловую систему /tmp , устанавливая липкий бит на ней. Зайдите в систему как root и скомандуйте:
shell> chmod +t /tmp
Это защитит Вашу файловую систему /tmp так, чтобы файлы могли быть удалены только их владельцами или суперпользователем ( root ).
Вы можете проверять, установлен ли липкий бит, выполняя ls -ld /tmp . Если последний бит прав доступа равен t , липкий бит установлен.
Вы можете изменять место, где MySQL помещают файл сокета, так:
Определите путь в глобальном или локальном файле опций. Например, поместите в /etc/my.cnf :[client] socket=path-for-socket-file [mysqld] socket=path-for-socket-file
Вы можете проверять, что сокет работает, с помощью команды:
shell> mysqladmin --socket=/path/to/socket version
Если Вы имеете проблему с SELECT NOW() , возвращающим значения в GMT, а не по Вашему местному времени, Вы должны установить системную переменную TZ к Вашему текущему часовому поясу. Это должно быть выполнено для среды, в которой выполняется сервер, например, в скрипте safe_mysqld или в mysql.server .
8.5 Проблемы с запросами
По умолчанию поиск в MySQL нечувствителен к регистру (хотя имеются некоторые наборы символов, которые всегда чувствительны, например, czech ). Это означает, что, если Вы ищете col_name LIKE ‘a%’ , Вы получите все значения столбца, которые начинаются с A или a . Если Вы хотите сделать этот поиск с учетом регистра, используйте нечто подобное INSTR(col_name, «A»)=1 , чтобы проверить префикс. Или используйте STRCMP(col_name,»A»)=0 , если значение столбца было точно «A» .
В старых версиях MySQL LIKE выполнялся по значениям, приведенным к верхнему регистру. В более новых версиях MySQL LIKE работает точно так же, как другие операторы сравнения.
Если Вы хотите, чтобы столбец всегда обработался в режиме чувствительности к регистру, объявите его как BINARY .
Если Вы используете китайские данные в так называемом кодировании big5, Вы должны сделать все символьные столбцы BINARY . Это работает потому, что порядок сортировки символов кодирования big5 основан на порядке ASCII кодов.
Формат значения DATE всегда YYYY-MM-DD . Согласно ANSI SQL, никакой другой формат не позволяется. Вы должны использовать этот формат в выражениях UPDATE и в предложении WHERE инструкций SELECT . Например:
mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05';
Как дополнительное удобство MySQL автоматически преобразовывает дату в число, если дата используется в числовом контексте (и наоборот). Также достаточно интеллектуально обрабатывается ослабленная форма строки при модифицировании и в предложении 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 выполняет преобразования, описанные выше, следующие инструкции всегда работают:
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 в дату и не сравнивает даты.
Обратите внимание, что MySQL не делает никакой проверки, является или нет дата правильной. Если Вы сохраняете неправильную дату, типа 1998-2-31 , неправильная дата будет сохранена. Если дата не может быть преобразована в любое приемлемое значение, 0 будет сохранен в поле DATE . Это главным образом проблема быстродействия.
8.5.3 Проблемы со значениями NULL
Концепция значения NULL представляет собой общий источник беспорядка для новичков в SQL, которые часто думают, что NULL та же самая вещь, что и пустая строка ( » ). Дело обстоит не так! Например, следующие инструкции полностью различны:
mysql> INSERT INTO my_table (phone) VALUES (NULL); mysql> INSERT INTO my_table (phone) VALUES ("");Обе инструкции вставляют значение в столбец phone , но первые вставят значение NULL , а вторая вставляет пустую строку. Значение первой может быть расценено как «номер телефона неизвестен», а значение второй как «не имеет никакого телефона». Есть разница?
В SQL значение 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 = "";
В MySQL, как и во многих других SQL-серверах, Вы не можете индексировать столбцы, которые могут иметь значения NULL . Вы должны объявить столбцы для индекса как NOT NULL . Наоборот, Вы не можете вставлять NULL в индексированный столбец.
При чтении данных через LOAD DATA INFILE , пустые столбцы модифицируются с » . Если Вы хотите иметь в столбце значение NULL , Вы должны использовать \N в текстовом файле. Литеральное слово NULL может также использоваться.
При использовании ORDER BY значения NULL будут представлены первыми. Если Вы сортируете в порядке по убыванию, используя DESC , значения NULL , понятно, окажутся в хвосте. При использовании GROUP BY , все значения NULL будут расценены как равные.
Чтобы помочь СУБД с обработкой NULL , Вы можете использовать операторы IS NULL и IS NOT NULL , а также функцию IFNULL() . Производительность улучшится.
Для некоторых типов столбцов значения NULL обработаны особо. Если Вы вставляете NULL в первый столбец типа TIMESTAMP в таблице, реально будут вставлены текущая дата и время. Если Вы вставляете NULL в столбец с поддержкой AUTO_INCREMENT , вставится следующее число в последовательности.
8.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;
Обратите внимание, что ANSI SQL не позволяет Вам обращаться к псевдониму в предложении WHERE . Это потому, что, когда код WHERE выполнен, значение столбца не может быть определено. Например, следующий запрос строго запрещен :
SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id;
Инструкция WHERE выполнена, чтобы определить, которые строки должны быть включены в часть GROUP BY в то время, как HAVING используется, чтобы решить, которые строки из набора результатов должны использоваться.
8.5.5 Удаление строк из связанных таблиц
Поскольку MySQL не поддерживает подвыборы или использование больше, чем одной таблицы в инструкции DELETE , Вы должны использовать следующий подход, чтобы удалить строки из двух связанных таблиц:
- SELECT строки, основываясь на некотором условии WHERE в основной таблице.
- DELETE строки в основной таблице, основываясь на том же самом условии.
- DELETE FROM связанная_таблица WHERE связанные_столбцы IN (выбранные_строки) .
Если общее количество символов в запросе со связанными столбцами ( related_column ) больше, чем 1048576 (значение по умолчанию для max_allowed_packet ), Вы должны расчленить его на меньшие части и выполнить много инструкций DELETE . Вы, вероятно, достигнете пика производительности при удалении 100-1000 related_column на запрос, если related_column является индексом. В противном случае быстродействие независимо от числа параметров в предложении IN .
8.5.6 Решение проблем с несоответствием строк
Если Вы имеете сложный запрос, который имеет много таблиц, а он не возвращает никаких строк, Вы должны использовать следующую процедуру, чтобы выяснить, что неправильно с Вашим запросом:
- Проверьте запрос с помощью EXPLAIN и выправьте его, если Вы можете найти что-то такое, что является очевидно неправильным. Подробности в разделе «5.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;
shell> mysqladmin create test2 shell> mysql test2 < query.sql
8.6 Проблемы с определениями таблиц
8.6.1 Проблемы с ALTER TABLE
ALTER TABLE изменяет таблицу на текущий набор символов. Если Вы в течение ALTER TABLE получаете ошибку дублирования ключа, то причиной является то, что новые наборы символов отображают разные ключи к тому же самому значению, или что таблица разрушена, тогда Вы должны выполнить REPAIR TABLE на таблице.
Если ALTER TABLE падает с ошибкой подобно этой:
Error on rename of './database/name.frm' to './database/B-8.frm' (Errcode: 17)
Проблема может состоять в том, что MySQL потерпел крах в предыдущем ALTER TABLE , и имеется старая таблица с именем A-что-то или B-что-то . В этом случае идите в каталог данных MySQL, и удалите там все файлы, которые имеют имена, начинающиеся с A- или B- . Вы можете перемещать их в другое место вместо того, чтобы удалить их сразу.
ALTER TABLE работает следующим образом:
- Создает новую таблицу под именем A-xxx с нужными изменениями.
- Все строки из старой таблицы копируются в A-xxx .
- Старая таблица переименуется в B-xxx .
- Таблица A-xxx переименуется в старую таблицу.
- Таблица B-xxx удаляется.
Если что-то идет неправильно с операцией переименования, MySQL пробует отменить изменения. Если что-то идет совсем уж неправильно (этого не должно случиться, конечно), MySQL может оставить старую таблицу как B-xxx , поскольку простое переименование на уровне системы должно вернуть Ваши данные обратно в целости и сохранности.
8.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 .
8.6.3 Проблемы с TEMPORARY TABLE
Следующее представляет собой список всех ограничений, действительных для временных таблиц ( TEMPORARY TABLES ).
- Временные таблицы могут быть только типов HEAP , ISAM или MyISAM .
- Вы не можете использовать временные таблицы больше одного раза в запросе. Например, следующее работать не будет:
select * from temporary_table, temporary_table as t2;