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;

Возможно есть более элегантное решение этой проблемы, но у меня небыло времени его искать.

В принципе описанная проблемма должна касаться всех запросов, в каких подобным образом используются переменные.

Комментариев: 4

4 Responses to “Variables on MySQL-replication”

Комментарии:

  1. Artioma

    Preved! Nice resourse! Kagdila? I’m medved

  2. Скакунов Александр

    Вопрос: а что делает данный блок

    SET rating=(@a:=@a+1)

    ?

  3. vadim

    Увеличивает значение переменной @a на единицу, и записывает новое значение в поле rating таблицы table.

  4. Скакунов Александр

    Ага, хитро. Спасибо за объяснение!

Leave a Reply