Тэг ‘mysql’

Подключение к Mysql через Named Pipe (Windows)

Подключение через именованный pipe функцией mysql_connect в Windows висит давним багом в трекере PHP При этом есть отзывы, что периодически (в частности, в версиях PHP 5.3…) данная функциональность отваливается. Немного информации о подключении через Named Pipe (ИМХО, перевод “именованный пайп” менее лаконичен, а “именованный канал” может ввести в заблуждение) под катом.
Читать целиком »

Опубликовано Март 1, 2013 | автор: levik  |  Нет комментариев »

Восстановление таблиц InnoDB базы mysql из файлов

После аварии в датацентре сервер mysql (а с ним и сайт) стал выдавать ошибки - посыпались сообщения вроде

Can't open and lock privilege tables: Table `*.host` doesn't exist

Часть таблиц (а именно - все таблицы InnoDB и некоторые MyISAM) были повреждены.

По умолчанию все базы хранятся в каталоге /var/lib/mysql. При этом для таблиц MyISAM создаются файлы в подкаталоге, имя которого совпадает с названием базы данных, а InnoDB, в отличии от MyISAM, сохраняет таблицы в виде нескольких файлов: ib_logfile0, ib_logfile1, ibdata1. А в каталоге с названием базы, сохраняются файлы с расширением *.FRM в которых находится информация о структуре таблицы. Читать целиком »

Опубликовано Сентябрь 28, 2012 | автор: levik  |  Нет комментариев »

MySQL where .. IN (`field`) или избавляемся от хранения массива в базе

Да, я в курсе, что такое “Многие ко многим”..

Иногда приходится сталкиваться с ситуациями, когда данные хранятся в таблице в “неудобной” для работы форме - ID-шники лежат в одном поле через запятую.. Как и почему - в подробности вдаваться не буду.. думаю, у тех, кто столкнулся с подобной ситуацией вопросов не будет. Как бы получше “развернуть” эту конструкцию в привычную таблицу многие-ко-многим, чтобы работать со связанными таблицами было удобнее (и быстрее - ведь поиск по подстроке намного медленнее, чем по индексу).

В любом случае, разбирать колонку со значениями через запятую нам придётся.. однако, лучше и правильнее сделать это один раз, чем при каждом запросе. Рассмотрим на примере работу с where field_1 IN (`field`) Читать целиком »

Опубликовано Август 17, 2012 | автор: levik  |  Нет комментариев »

MySQL как скопировать таблицу

Скопировать таблицу в БД MySQL можно при помощи PhpMyAdmin в меню операции - копировать.. в окошке вводим имя новой таблицы (при необходимости можно выбрать другую базу - текущий пользователь должен иметь доступ к этой базе с привилегией создания таблиц)

Скопировать таблицу в MySQL без PhpMyAdmin, можно простым запросом:
К примеру, чтобы скопировать таблицу posts из базы данных mydb (если обе таблицы находятся в одной базе, то использовать mydb. не обязательно) в таблицу posts_bak (структуру и все записи)
Читать целиком »

Опубликовано Август 13, 2012 | автор: levik  |  Нет комментариев »

Неразрывный пробел, mysql и Like

Есть таблица A и таблица B, в каждой из них есть колонка name (обе utf8_general_ci). Потребовалось найти соответствие name из A в B при том, что A.name содержит B.name (полностью). Казалось бы, что проще -

SELECT A.name, B.name FROM A,B
WHERE A.name LIKE CONCAT ('%',B.name,'%')

* вариант с условием WHERE POSITION (B.name in A.name) давал меньше соответствий

Интересная ситуация - визуально записи отображаются одинаково.. однако при попытке сравнить их, как при помощи оператора = или LIKE результат получается “различным”. При этом проверка “ручками” в браузере (поиск по CTRL+F) словосочетания считает абсолютно одинаковыми.. Читать целиком »

Опубликовано Июль 5, 2012 | автор: levik  |  Нет комментариев »

Репликация в MySQL

Некоторые неупорядоченные заметки-ссылки по репликации mysql-сервера.

http://onlamp.com/pub/a/onlamp/2006/04/20/advanced-mysql-replication.html?page=3

Настройка репликации в MySQL очень подробно описана в мануале. Чтобы разобраться в репликации (возможно, не до мелочей), рекомендую просмотреть официальный мануал Mysql.

Краткая шпаргалка по репликации

http://www.opennet.ru/tips/info/1205.shtml
http://www.webnext.ru/blog/2007/08/21/replication-mysql-master-slave.html
http://debian.telenet.ru/adjustmentsoft/mysql_master_master_replication
http://informst.ucoz.ru/publ/subd/mysql/osnovy_replikacii_v_mysql/49-1-0-128
http://www.ossg.ru/wiki/Admin/%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0%20Master-Master%20%D1%80%D0%B5%D0%BF%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8%20%D0%B2%20MySQL
http://ru.ispdoc.com/index.php/%D0%A0%D0%B5%D0%BF%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_master-master_%D0%B2_MySQL

Репликация Master-Slave

Вариант репликации Master-Slave позволяет “добавить” к основному серверу MySQL запасной.. Все изменения, внесенные на Master-е, практически мгновенно (периодичность задается в настройках) синхронизируются со Slave-ом.

Для создания дампа с мастера можно использовать:

mysqldump –all-databases –master-data > all_databases.dump

****

Репликация Мастер-Мастер

Для репликации мастер-мастер (двусторонняя репликация) проводится настройка аналогичная “Master-Slave” с точностью до наоборот (основной Master настраивается как Slave, а второй (бывший Slave) - как Мастер). Если на втором мастере не будет производиться запись (”пассивный” мастер), то изменение Autoincrement-increment не потребуется.

При репликации двух активных master-master следует обратить внимание на Autoincrement. Действительно, если на двух серверах одновременно будет создана запись с одинаковым первичным ключом, то при попытке репликации получим ошибку Dublicate entry.

Проблема с auto_increment решается выставлением двух переменных
## в оба конфига добавляем двоечку -
--auto-increment-increment=2
## добавляем в Server-1 ; на первом - нечетные
--auto-increment-offset = 1
## добавляем в Server-2 ; на втором - четные
--auto-increment-offset = 2

Однако, при этом следует иметь ввиду, что на первом сервере ВСЕ автоинкрементные поля будут нечетными, а на втором - все будут четными.

Подборка ссылок по уникальным ключам (в PostgreSQL)
http://www.sql.ru/forum/actualthread.aspx?tid=422194

Подборка ссылок по Master-Slave репликации
http://habrahabr.ru/blogs/mysql/56702/ - подробно, с описанием “рокировки”;

Подборка ссылок по двусторонней репликации в MySQL
http://www.howtoforge.com/mysql_master_master_replication
http://www.itnotes.org.ua/administration/mysql/master_master_replication_db.html
http://www.initialize.ru/mysql-master-master-replikaciya
http://www.gra2.com/article.php/setting-up-database-replication-on-mysql

MySQL Multi Master Manager
http://mysql-mmm.org/
http://onlamp.com/onlamp/2006/04/20/advanced-mysql-replication.html

MySQL Load Balanced Cluster
http://www.howtoforge.com/loadbalanced_mysql_cluster_debian
http://www.dancryer.com/2010/01/mysql-circular-replication

Синхронизация сайтов:

http://habrahabr.ru/blogs/ubuntu/104342/
http://habrahabr.ru/blogs/sysadm/86496/
http://en.wikipedia.org/wiki/High-availability_cluster
http://habrahabr.ru/blogs/studiobusiness/90349/
http://kuroikaze85.wordpress.com/2009/11/24/%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-drupal-%d1%81%d0%b0%d0%b9%d1%82%d0%be%d0%b2-%d1%81-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-migraine/
http://barkingiguana.com/2008/07/20/load-balanced-highly-available-mysql-on-ubuntu-804/

Основы масштабирования + ссылки
http://habrahabr.ru/blogs/webdev/15362/

Опубликовано Март 27, 2011 | автор: levik  |  Нет комментариев »

mysql update where select from update-target

MySQL не позволяет апдейтить таблицу, которая участвует в выборке условия select. То есть при попытке выполнить запрос типа

update categories set discount =  (select discount from categories where id=1)

Получим следующее сообщение об ошибке:
ERROR 1093 (HY000): You can't specify target table 'goods' for update in FROM clause

В документации по UPDATE находим простое объяснение - “Currently, you cannot update a table and select from the same table in a subquery.”

Как быть, если всё же требуется изменить записи в таблице, которая участвует в условии?
Конечно, вариант с ручным созданием временной таблицы будет работать, однако…

Статья на английском с примерами, а также интересные решения в комментариях по ссылке:
http://www.xaprb.com/blog/2006/06/23/how-to-select-from-an-update-target-in-mysql/

update webartCategories as cat     inner join
( [тут наш запрос на выборку] ) as x on cat.id = x.id
set level = level + 1

UPD - Ещё один запрос с подзапросом - UPDATE SELECT MIN MAX
upate user u inner join
(SELECT id_user, max(id_post) as maxid_post from post2user GROUP BY id_user) u2p
set u.lastpost = u2p.maxid_post

Опубликовано Сентябрь 10, 2010 | автор: levik  |  Комментарий (1) »

utf-8, mysql и буквы ш, И - некорректно отображаются буквы

На некоторых конфигурациях хостинга 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/ |
+--------------------------+----------------------------+

php и utf8 - http://www.phpwact.org/php/i18n/utf-8

После переноса или смены кодировки некоторые буквы “ш” и “И” в UTF-8 могут отображаться неверно
буква “ш” = chr(209).chr(63) / правильно chr(209).chr(136)
буква “И” = chr(208).chr(63) / правильно chr(208).chr(152)
Для решения проблемы выполняем запросы (в phpmyadmin)

UPDATE `table` SET `field` = REPLACE(
`field`,
CONCAT( CHAR(209), CHAR(63) ),
CONCAT( CHAR(209), CHAR(136) )
);

UPDATE `table` SET `field` = REPLACE(
`field`,
CONCAT( CHAR(208), CHAR(63) ),
CONCAT( CHAR(208), CHAR(152) )
);

Опубликовано Июль 23, 2010 | автор: levik  |  Комментарии (6) »

Таблица MySQL используется (статус “in use”)

Иногда, таблицы 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  |  Комментарии (5) »

mysql на vps - отлавливаем тяжелые запросы к базе

Для многих сайтов производительность напрямую зависит от скорости ответов на mysql-запросы. Конечно, если выполняется запрос на выборку по ключу, да ещё из одной таблицы (да и в таблице записей немного) - то, скорее всего, результат будет известен быстро.

Если же требуется выполнить тяжелый (медленный?) mysql-запрос на выборку несколько связанных таблиц с кучей условий… и такого рода различных запросов порядка сотни… Чувствуется, что база не справляется, сервер “трещит по швам”… однако, где конкретно самое узкое место - непонятно. “Где тонко, там и рвется”. Возможно, достаточно оптимизировать один-два запроса, и mysql будет “летать”.. А возможно и нет.

Итак, как найти, какие mysql запросы наиболее сильно грузят сервер. Какие запросы наиболее требовательны к памяти и процессорному времени?

mysql-сервер предоставляет возможность отслеживать запросы, которые выполнялись слишком долго (long query time)

Журнал медленных запросов MYSQL

Это log-файл, в который помещается информация о запросах, которые выполняются больше указанного времени. Указанного где? Конечно, в конфигурационном файле. Кстати, по умолчанию журнал отключен - без исправлений в conf-файле не обойтись. Файл настроек для mysql обычно называется my.conf и хранится в каталоге /etc

Для включения логгирования медленных (предположительно тяжелых) запросов к серверу mysql добавляем в секцию [mysqld] следующие строки:

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/
http://www.day32.com/MySQL/
http://www.job-blog.bullgare.ru/wp-content/uploads/2009/08/tuning-primer.sh
http://habrahabr.ru/blogs/mysql/66684/
http://xpoint.ru/forums/computers/dbms/mysql/thread/40479.xhtml

http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/
заменяем ORDER BY RAND()

http://ruseller.com/lessons.php?rub=28&id=692
Советы по оптимальному использованию MySQL

Опубликовано Декабрь 19, 2008 | автор: levik  |  Комментарий (1) »