# Заметки по апгрейду Tarantool 1.6 -> 1.10 Несколько неожиданных моментов при апгрейде по стандартной процедуре. Обновлялись с 1.6.9 до 1.10.11-2 ## Стандартная процедура 1. Проверяем кластер и его мастер (живы ли) 2. У всех проверяем replication_source в `box.cfg` и репликацию в `box.info` 3. Обновляем реплику 4. Проверяем репликацию в `box.info` 5. Повторяем шаги 4-5 для всех реплик 6. Переключаем мастер на обновленную реплику и проверяем репликацию в `box.info` 7. Обновляем старый мастер и проверяем репликацию в `box.info` 8. Выполняем `box.schema.upgrade()` на новом мастере 9. `box.snapshot()` на всех нодах кластера ## Что пошло не по плану **Шаг 4** 1.6 ещё никак не проверял работу несколькими нодами в одной wal_dir / memtx_dir. Поэтому обязательно проверяем, что реплика 1.6 точно остановлена, прежде, чем стартуем 1.10. Иначе можно потратить много времени, выясняя, каким образом 1.10 после апгрейда ловит duplicate_key с мастера. (Спойлер: 1.6 применяет реквесты с мастера и пишет в вал, а 1.10 восстанавливается из вала, прямо как хот стендбай, а затем ещё и с мастера те же данные просит) **Update:** Ох уж этот 1.6, всё в нём не как у людей. В продолжение истории, 1.6 даже не нужно работать параллельно с 1.10, чтобы ломать ему восстановление из журнала. Оказывается, до версии [1.7.0-765-g650df2440](https://github.com/tarantool/tarantool/commit/650df2440d359a1d258c98461d269bea38032081) тарантул не ротировал икслог в момент снапшота, поэтому вполне могло получиться, что 00000000000**552**...xlog содержит часть данных, записанных до 00000000000**553**...snap, и часть данных, записанных после. Если это игнорировать, тарантул 1.10 восстановится с vclock из снапшота, поскольку будет считать снапшот самым свежим, однако всё равно прочитает данные из икслога. Из-за этого при репликации Тарантул повторно применит все данные, находящиеся в конце икслога, и оборвёт соединение на первой не переживающей дублирования операции (например, INSERT). **Шаг 6** После обновления реплик до 1.10, ноды 1.6 не могут реплицироваться с них. В box.info.replication ошибка: `"instance bootstrap hasn't finished yet"`. Проблема в том, что 1.10 кидает ошибку ER_LOADING, если subscribe пришёл до завершения рекавери. 1.6 пытается переподключиться только после SocketError, поэтому после ER_LOADING репликация с 1.10 на 1.6 встаёт. Чтобы это исправить, достаточно ресетнуть репликацию на 1.6 **Шаг 8** `box.schema.upgrade()` обновляет форматы спейсов: заменяет поля типа `'num'` на `'unsigned'`. Однако `num` в 1.6, похоже, был аналогом `'number'`, поэтому в таплах в этих полях могут быть `float`, `double`, `lua number`, you name it. Сам апгрейд проходит успешно (кстати, почему? обновление формата ведь должно валиться, когда обнаружило неправильный формат), но тарантул после рестарта не может подняться из своего же снапшота (формат неправильный). Лечится так: нужно найти все пользовательские спейсы, у которых есть поля `num` и таплы, содержащие не-unsigned в этих полях. То есть `double`, `int`, etc. Для всех таких спейсов (уже находясь на 1.10) после `box.schema.upgrade()` нужно сказать: ```lua= a = box.space.problematic_space:format() a[problematic_field_no].type='number' box.space.problematic_space:format(a) ``` И уже после этого звать `box.snapshot()` на всех. **Note:** похоже, то что `upgrade` меняет `num` на `unsigned` - правильно (судя по тикету [#1534](https://github.com/tarantool/tarantool/issues/1534)). **Шаг 9** Снапшоты 1.10 занимают **намного** меньше места, чем 1.6 (разница ~330Mb vs. 6Gb). Что пугает. Бояться не нужно: в 1.6 ещё не было сжатия снапшотов. Оно появилось в ~1.7.2: [d9f82b176e](https://github.com/tarantool/tarantool/commit/d9f82b176e245f2ae19845a6177a8b271256642e)