суббота

 

Интересный баг mysql

Официальный логотип Mysql

По долгу службы пришлось мне отправиться в длительную поездку. Компьютер с собой не возьмешь, и поэтому приспичило меня залить дамп базы Mysql на ноутбук с OpenSuSe 11.0. Dump отказался заливаться, ругнулся вот так:

ERROR 1221 (HY000) at line 3: Incorrect usage of UNION and INTO

Код хранимой функции был чистый, давным-давно вылизанный и ошибок в нем не было. Выяснилось, что на старых версиях mysql может не работать вот такая конструкция:

select 1 into @`avar` from (select 1 union select 1) `a`;

хотя сам запрос:

select 1 from (select 1 union select 1) `a`;

синтаксически правильный и имеет право на жизнь. Баг в конце концов поправили (подробности здесь), но в стандартных репозиториях OpenSuSe 11.0 (OSS, Non-OSS, Debug и Updates) версия mysql осталась старая, с багом.

Проблема лечится подключением репозитория MySQL и обновлением до последней версии сервера mysql.

Ярлыки: , ,


четверг

 

MySQL и защита от удаления записей в таблицах

Однажды мне понадобилась защита от удаления записей в таблице. Естественно, на триггере BEFORE DELETE, чтобы уж наверняка все работало. В привычном мне Oracle такая задача решается очень просто, с вызовом raise_application_error внутри триггера. Но как оказалось, в MySQL такая задача решается через жоп использование несуществующего поля в какой-нибудь таблице. Вот пример:

delimiter |

CREATE TRIGGER my_table_bd
BEFORE DELETE ON my_table
FOR EACH ROW
begin
declare v int;
if ifnull(old.status,0) > 0 then
select antarktida
into v
from logs u
where africa = 'asia';
end if;
end|

delimiter ;

Полей antarktida, africa в таблице logs нет, поэтому при срабатывании триггера происходит ошибка. Причем ошибка выскочит, если ifnull(old.status,0) > 0. Такая конструкция выглядит ужасно (костыль он и есть костыль), но работает 100%. И похоже, это единственный способ запретить удаление из таблицы.

Ярлыки:


понедельник

 

Экспорт баз MySQL

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

mysqldump -u username -p db_name --routines --extended-insert >dump.sql

Ярлыки: ,


воскресенье

 

Как получить список дат в mysql

Однажды мне потребовалось получить список дат на каждый день 2009 года. Как оказалось, в mysql такой список получить очень просто.

Для этого нужна всего лишь любая таблица, в которой есть не меньше 365 строк. У меня такая таблица была, и называется она games. Скрипт выглядит так:


SET @rownum:=0;
select adddate('2008-12-31',interval @rownum:=@rownum+1 DAY) next_date from games limit 0,365;

Ярлыки: ,


четверг

 

Как сбросить пароль в mysql

Иногда бывают ситуации, когда рутовый пароль на базу MySQL проебали где-то потерялся, и его надо срочно перезадать. Если есть доступ к shell на сервере, то сделать это достаточно просто:

1. Останавливаем mysqld:

/etc/init.d/mysqld stop

2. Запускаем mysqld без проверки прав доступа:

mysqld_safe --skip-grant-tables &

3. Заходим под рутом и перебиваем пароль:

mysql -u root -D mysql
mysql> update user set password=password('new_password') where user='root';


4. Обновляем права доступа:

flush privileges;

5. Выходим, убиваем mysqld и запускаем его снова:

mysql> exit;
/etc/init.d/mysqld stop
/etc/init.d/mysqld start

Ярлыки: , ,