Parece que está intentando ejecutar este código de procedimiento como un bloque anónimo. Si bien esto funciona en algunas bases de datos (como Oracle), no se puede hacer en MySQL.
Si desea ejecutar esto, colóquelo en un procedimiento almacenado y luego llame al procedimiento. Por lo tanto:
Crear procedimiento
DELIMITER $$
CREATE PROCEDURE `foo_update_routine`()
BEGIN
WHILE ((SELECT COUNT(*) FROM
(SELECT id, COUNT(*) AS cnt
FROM foo
GROUP BY id
ORDER BY COUNT(*) DESC
) cnts
WHERE cnt > 1) != 0)
DO
SET @curr_id = (SELECT id FROM
(SELECT id, COUNT(*) AS cnt
FROM foo
GROUP BY id
ORDER BY COUNT(*) DESC
) cnts
WHERE cnt > 1
LIMIT 1);
SET @new_id = (SELECT MAX(id) + 1 FROM foo);
UPDATE foo SET id = @new_id
WHERE id = @curr_id
LIMIT 1;
END WHILE;
END $$
Procedimiento de llamada
CALL `foo_update_routine`;
PD Es posible que desee investigar la cláusula HAVING para sus declaraciones selectas...