На некоторых конфигурациях хостинга php вместо буквы “ш” (вообще, такой недостаток есть у двух букв - «ш» маленькая и «И» большая) выдавал “ерунду” - две кракозябры (видимо, непечатаемые символы). Иногда (возможно, после применения iconv) слова, содержащие букву “ш” вообще могли “пропасть”. Сайт в кодировке utf-8, база - также в utf-8. Проблема оказалась не в php (под подозрением находился iconv - на некоторых хостингах бывали проблемы с функциями перекодировки).
После сравнительно недолгих поисков выяснилось, что «ш» и «И», словно заколдованные буквы могут некорректно работать с базой в кодировке utf-8.
Решить все удалось очень просто - после соединения с базой нужно установить кодировку для:
SET CHARACTER SET ‘utf8′ –(этот вариант нашел в рекомендациях на нескольких форумах)
SET NAMES ‘utf8′ –(этот вариант помог)
(важно! именно utf8, а не utf-8 - вариант с дефисом как раз и выдавал результат)
Можно “подглядеть”, что творится на сервере с кодировками:
mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
Опубликовано Июль 23, 2010 | автор: levik | Нет комментариев »
Иногда, таблицы MySQL в формате MyISAM, несмотря на относительную надежность такого формата, все-же могут быть повреждены (corrupted). Одним из признаков может быть сообщение об ошибке Table is marked as crashed and should be repaired. Однако, иногда, сообщения об ошибке может не быть.
А запрос к mysql возвращает “пустой” результат. При этом на сайте могут пропадать страницы, комментарии, тексты. Если у вас пропали данные на сайте, попробуйте заглянуть в phpmyadmin - возможно напротив одной или нескольких таблиц стоит статус in use (используется). Тот же самый результат можно увидеть, выполнив запрос SHOW TABLES. Сервер попросту не может получить данные, так как считает, что таблица используется.
Как прекратить использование таблицы или снимаем in use
Помог волшебный запрос “Repair table table_in_use” (вместо table_in_use следует вставить имя таблицы со статусом “используется”). В результатах выполнения запроса была строчка следующего вида:
database_name.table_in_use repair info Found block that points outside data file at ...
После этого, информация о таблице стала корректно отображаться, запросы к ней возвращали нужные данные и “пропавшие” страницы вернулись на сайт.
И ещё. Сообщение “таблица используется” (table in use) может возникать в различных случаях. Скорее всего, это связано с некорректным завершением работы процесса mysql - либо программное завершение (возможно, наложены ограничения на потребление ресурсов сервера), либо аппаратная проблема (выключение компьютера, сбой при записи на жесткий диск). Если вы причастны к администрированию такого сервера, следует поискать возможную причину того, что статус in use задержался дольше положенного.
Опубликовано Март 20, 2010 | автор: levik | Комментарий (1) »
Для многих сайтов производительность напрямую зависит от скорости ответов на mysql-запросы. Конечно, если выполняется запрос на выборку по ключу, да ещё из одной таблицы (да и в таблице записей немного) - то, скорее всего, результат будет известен быстро.
Если же требуется выполнить тяжелый (медленный?) mysql-запрос на выборку несколько связанных таблиц с кучей условий… и такого рода различных запросов порядка сотни… Чувствуется, что база не справляется, сервер “трещит по швам”… однако, где конкретно самое узкое место - непонятно. “Где тонко, там и рвется”. Возможно, достаточно оптимизировать один-два запроса, и mysql будет “летать”.. А возможно и нет.
Итак, как найти, какие mysql запросы наиболее сильно грузят сервер. Какие запросы наиболее требовательны к памяти и процессорному времени?
mysql-сервер предоставляет возможность отслеживать запросы, которые выполнялись слишком долго (long query time)
Журнал медленных запросов MYSQL
Это log-файл, в который помещается информация о запросах, которые выполняются больше указанного времени. Указанного где? Конечно, в конфигурационном файле. Кстати, по умолчанию журнал отключен - без исправлений в conf-файле не обойтись. Файл настроек для mysql обычно называется my.conf и хранится в каталоге /etc
Для включения логгирования медленных (предположительно тяжелых) запросов к серверу mysql добавляем в секцию [mysld] следующие строки:
log-slow-queries=/var/log/mysql/slow-queries.log
long_query_time=3
log-queries-not-using-indexes
Здесь в первой строке (log-slow-queries)указан путь к журналу медленных запросов (следует “организовать” сам файл и доступ к нему пользователю, от имени которого запускается mysql)
long_query_time - время выполнения медленного запроса
log-queries-not-using-indexes - фиксируем запросы, не использующие индексы
http://www.mysqlperformanceblog.com/2006/09/06/slow-query-log-analyzes-tools/
Опубликовано Декабрь 19, 2008 | автор: levik | Нет комментариев »
При переносе сайта на хостинг появилась проблема при сортировке выборки - элементы попросту не сортировались. Попытки найти ошибки в коде, исключить проблемы кодировки при переносе, и другие “мучения” ни к чему не привели.
Как оказалось, проблема скрыта в самом mysql сервере.. точнее в его конкретной версии. В некоторых случаях сортировка попросту не работает:
http://bugs.mysql.com/bug.php?id=34310
http://bugs.mysql.com/bug.php?id=39287
Если у Вас по какой-то непонятной причине происходят ошибки при сортировке (в коде ничего не менялось, и раньше таких ошибок не было наверняка) - проверьте версию MYSQL на хостинге. Если что-то похожее на 5.0.51 (или 5.0.51a) - уточните у хостера, возможно, они не в курсе этого бага.
Если же версия отличается, можно перейти по ссылкам выше и посмотреть известные баги для этой версии. Однако, все же для начала рекомендуется проверить код (если есть возможность - и на локальном сервере или на другом хостинге). Как ни банально, но не ошибается тот, кто ничего не делает…
Опубликовано Сентябрь 30, 2008 | автор: levik | Нет комментариев »
При выполнении SQL запроса возникает ошибка с кодом 122.
Ошибка MySQL Error writing file ‘/tmp/MYxxxxxx’ с кодом 122 (Errcode:122) говорит о невозможности.. записать временный файл. Чтобы понять это, особого знания английского языка не требуется. Гораздо интереснее, почему же mysql не может записать этот временный (или постоянный) файл в каталог tmp (или каталог баз данных). Кстати, ошибка может появляться при выполнении различных SQL-запросов, как на выборку, так и на запись.
Error code 122: Disk quota exceeded (см. коды ошибок MySQL)
Причины ошибки Can’t create/write to file ‘/tmp/MYxxxxxx’ (Errcode: 122)
Одной из возможных (довольно частых) причин ошибки создания файла может быть … переполнение диска, временного каталога или каталога пользователя. СтОит проверить (по SSH - команда df). Если дело действительно в переполнении - ищем “лишние файлы”. Если есть ssh-доступ - довольно удобно воспользоваться командой du (du –max-depth=1) Если места хватает, смотрим квоту пользователя, от имени которого запущен MySQL.
Если хостинг предоставляется как услуга - смело обращайтесь в службу поддержки.
VPS и Ошибка MySQL “Can’t create/write to file” (Errcode: 122)
Если у вас выделенный сервер (или виртуальный выделенный сервер) и вы столкнулись с ошибкой MySQL при создании временных файлов, то, скорее всего… на VPS кончилось место. Смотрим, куда же делось свободное место и удивляемся… Рекомендую проверить каталог с log-файлами. Если дело в логах - настраиваем ротацию (или удаляем по cron-у). Если не помогло - ищем “мусорку” с помощью du.
Знаете другие способы решения ошибки MySQL 122 Can’t create/write to file? Пишите в комментарии!
ps. Интересно, что по запросу MySQL Error writing file (Errcode: 122) в Yandex на первой странице довольно весомые (%) сайты абсолютно не связанные с компьютерной тематикой. Никто не застрахован от ошибок! (Если появится желание проверить - следует учитывать, что ситуация со временем меняется…)
Опубликовано Сентябрь 5, 2008 | автор: levik | Нет комментариев »
Выбираем записи с максимальным значением определенного поля.
На всякий случай - требуется получить не сами максимальные значения, а записи, в которых определенное поле равно максимальному.
Если поля всего два - сработает простой запрос:
id|date
select id, max(date) from table1;
При добавлении еще одного поля задача выбора записей с максимальным значением усложняется:
id|date|count
чтобы получить все записи с максимальной датой:
читать дальше про поиск записей с максимальным значением
Опубликовано Август 2, 2008 | автор: levik | Нет комментариев »
в Mysql вопросы вместо текста? Знакомо?
Иногда при работе с MySql вместо ожидаемого текста, мы получаем в ответ что-то вроде “??? ?? ?????? ???…” Интуитивно можно предположить, что весь ВОПРОС (;) в кодировке MySQL. Что с этим делать, как бороться?
Для начала проверить, как хранятся данные в базе - зайти, к примеру, phpmyadmin-ом. Иногда из-за несоблюдения кодировки при импорте вопросики уже лежат в базе. В этом случае либо импортировать (если есть откуда) заново, либо… с нуля.
При импорте следует указать кодировку, соответствующую файлу импорта. Естественно, если данные хранятся в базе вопросами - ничего другого мы и не получим.
Если же в базе данные хранятся “как надо”, а проблема появляется при выводе, обычно помогает незамысловатый запрос “Set names cp1251″ - сразу после подключения к базе. (вместо cp1251, следует указать нужную кодировку - с учетом русского языка - возможно UTF8)
У меня после такой операции вместо знаков вопроса отобразился “нормальный” текст.
Опубликовано Июнь 20, 2008 | автор: levik | Нет комментариев »
Table host/tablename is marked as crashed and should be repaired
Сообщение о такой ошибке при запросе к базе данных mysql может сбить с толку начинающего (да и уже “опытного”) владельца или администратора сайта. Crash mysql!!! Однако, все не так уж плохо - возможно, таблица всего-навсего повреждена, и её следует восстановить.
Как восстановить таблицу mysql?
Первым делом следует проверить таблицу (запрос “CHECK TABLE table_name”) .
Для восстановления таблиц в mysql существует специальный запрос “Repair Table table_name”, который возвращает результат своей работы в виде таблицы:
| Table | Op (операция - repair) | Msg_type (тип сообщения) | Msg_text (текст сообщения) |
Если действительно, ничего страшного не случилось, то, скорее всего, этими нехитрыми действиями Вам удастся восстановить поврежденную таблицу. Если же описанные шаги не помогли - смотрим в сторону мануалов “How to Repair MyISAM Tables”
Если Вы заметили ошибку “marked as crashed and should be repaired” - сообщите, пожалуйста администратору, владельцу или представителю службы технической поддержки сайта. Как минимум, они будут Вам благодарны.
Да минует Вас Крэш… во всех его проявлениях…
Удачи!
Коды ошибок MySQL сервера
http://oscommerce.su/modules/newbb/viewtopic.php?post_id=963
http://wiki.iblink.ru/sources/db/errors
Опубликовано Май 3, 2008 | автор: levik | Нет комментариев »
Опубликовано Апрель 2, 2008 | автор: levik | Комментарий (1) »
Столкнулся с тем, что иногда гораздно удобнее и правильнее спрятать логику работы базы в хранимые процедуры.
1. Вызов процедуры, которая возвращает результат:
CREATE PROCEDURE returnresult(IN userid INT)
BEGIN
SELECT * from ... ;
END;
Тогда
<?php mysql_query('call returnresult(2)');'?>
выдаст ошибку “PROCEDURE base.returnresult can’t return a result set in the given context “.
Проблема в том, что библиотека mysql не поддерживает мульти-запросы. Для возврата результата из хранимой процедуры следует использовать улучшенную версию - библиотеку mysqli (improved).
Заменим в коде функции mysql на mysqli, (на локальном сервере для windows - добавим в файл php.ini строку: extension=php_mysqli.dll; аналогичной команды для *nix не знаю.). После этого все заработало.
2. Рекурсивные процедуры в mysql
При попытке использовать рекурсию mysql выдал:
Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routineset …
Лечится запросом “SET max_sp_recursion_depth= 4″ // глубину рекурсии - в зависимости от задачи. Мне много не надо было. 
Опубликовано Январь 12, 2008 | автор: levik | Нет комментариев »