Variables on MySQL-replication
Рубрика: MySQL | 17 September 2006, 15:39 |
Vadim Voituk
Часто в проектах приходится строить рейтинг чего-либо.
Например рейтинг пользоватлей за день по критерию (количество баллов, сообщений и тд и тп).
При работе с MySQL 4.0 и выше это будет выглядеть приблизительно так:
mysql> SELECT @a:=0; (или SET @a:=0;)
mysql> UPDATE table SET rating=(@a:=@a+1) ORDER BY scores;
Т.е. первым запросом инициализируется переменая, а следующбим
перебираются все записи из таблицы в нужном порядке и проставляются
последовательные значения.
В стабильности подобного решения я был уверен 2 года, пока Дима не
выявил, что имея MySQL-репликацию, при выполнении этих запросов на
master-сервере, до slave-сервера доходит только второй запрос.
Следовательно на slave-сервере обновление просходит некорректно.
Причина столь неоднозначного поведения проста – на slave-сервер не передаются SELECT- и SET- запросы
Потому, имея master-slave репликацию описанные выше действия необходимо реализовывать уже 3-мя запросами:
mysql> CREATE TEMPORARY TABLE IF NOT EXISTS dummy (id int);
mysql> insert into dummy set id=(@a:=0);
mysql> UPDATE table SET rating=(@a:=@a+1) ORDER BY scores;
Возможно есть более элегантное решение этой проблемы, но у меня небыло времени его искать.
В принципе описанная проблемма должна касаться всех запросов, в каких подобным образом используются переменные.

Preved! Nice resourse! Kagdila? I’m medved
Вопрос: а что делает данный блок
SET rating=(@a:=@a+1)
?
Увеличивает значение переменной @a на единицу, и записывает новое значение в поле rating таблицы table.
Ага, хитро. Спасибо за объяснение!