ADR: migrate from map_callrw to bucket version
В ходе обсуждения с @kostja было решено, что текущий DML на базе map_callrw не оптимален и его хотелось бы заменить в будущем. Главная проблема в том, что каждый вызов map_callrw требует 2-3 RPC:
- заблокировать бакеты на экземпляре на таймаут
- выполнить пользовательскую функцию
- (опционально, если шаг 2 занял слишком много времени) отменить пользовательскую функцию по таймауту
Все это нужно только для того, чтобы избежать аномалий при исполнении SQL из-за фонового перемещения бакетов (копирование на приемник, удаление на источнике). Нам бы хотелось иметь 1 RPC и так же защищаться от аномалий. Если бы перемещением бакетов управлял рафт лидер, который бы инкрементировал версию топологии бакетов на каждое перемещение, то у нас были бы варианты сделать все за 1 RPC.
- Fencing: сравнивать версию топологии бакетов с роутера на стороджах (или отбивать запрос, или ждать, пока схема станет нужной нам).
- MVCC: добавить в шардированные таблицы служебные поля с версией перемещения бакетов (не отбивать запрос, а читать нужную версию). Тут будет много хлопот с видимостью и сборкой мусора (не факт, что мы это хотим).
При локальном исполнении SQL запроса следует продумать, чтобы от отбивался за переданный с роутера таймаут (мы не хотим тратить на медленные запросы еще один RPC).
Следует иметь ввиду, что эта логика требуется только для DML (который работает с версией топологии бакетов). Для DDL можно оставить map_callrw (он работает в версией схемы метаданных в рафте).
Нужно расписать эту логику в отдельном ADR, чтобы синхронизировать доработки по vshard и sql.