@@ -31,7 +31,7 @@ picodata run --instance-id iN --listen iN --peer i1,i2
### fn start_discover()
Дочерний процесс начинает своё существование с вызова `box.cfg()` и вызова функции `start_discover`.
Если вдруг из спейсов обнаруживается, что нода уже была забутстрапленна, то никакой алгоритм дискавери делаь и не надо, и инстанс сразу переходит на этап `postjoin()`. В противном случае, если это первый запуск, из алгоритма дискавери мы получаем флаг `its_me` и адрес лидера. Сам лидер выполняет `start_boot`, после чего выполняет `postjoin()`. Остальные инстансы (не только проигравшие пиры, но и все будущие) ребутстрапятся и идут делать `start_join`.
Если вдруг из спейсов обнаруживается, что нода уже была забутстрапленна, то никакой алгоритм дискавери делаь и не надо, и инстанс сразу переходит на этап `postjoin()`. В противном случае, если это первый запуск, из алгоритма дискавери мы получаем флаг `its_me` и адрес лидера. Сам лидер (единственный `its_me == true`) выполняет `start_boot`, после чего выполняет `postjoin()`. Остальные инстансы (не только проигравшие пиры, но и все будущие) ребутстрапятся и идут делать `start_join`.
### fn start_boot()
...
...
@@ -44,7 +44,9 @@ picodata run --instance-id iN --listen iN --peer i1,i2
Вызову `start_join` всегда предшествует ребутстрап (удаление БД и рестарт процесса), поэтому ни бокса, ни спейсов на этом этапе снова нет. Сама функция достаточно примитивная.
Инстанс отправляет запрос `join` на лидера (лидер известен после дискавери). Лидер шушукается с группой, и если всё хорошо, в ответ присылает необходимую для `box.cfg()` информацию - `raft_id`, `raft_group`, `insance_uuid`, `replicaset__uuid`, `replication`, `read_only`.
Инстанс отправляет запрос `join` на лидера (лидер известен после дискавери). Лидер шушукается с группой, и если всё хорошо, в ответ присылает необходимую информацию:
-`raft_id` и `raft_group` - для инициализации рафт ноды;
-`insance_uuid`, `replicaset_uuid`, `replication`, `read_only` - для `box.cfg`.
Получив все настройки, инстанс засовывает их в `box.cfg()`, и после этого персистит `raft_group` с актуальными адресами других инстансов. Без этого инстанс не сможет отвечать на рафт сообщения. А чтобы записи в `raft_group` не были потёрты менее актуальными из рафт лога, каждая маркируется значением `commit_index`.
...
...
@@ -52,7 +54,7 @@ picodata run --instance-id iN --listen iN --peer i1,i2
### fn postjoin()
Логика `postjoin()` для всех инстансов одинакова. К этому моменту на инстансе уже инициализированы правильные спейсы и возможно даже существует предыстория рафт журнала. Инстанс инициализирует рафт ноду и получает read barrier. Если всё хорошо, то в актуальности рафт лога сомневаться не прихоится. Из рафт лога становятся известны параметры репликации, и инстанс синхронизируемся с репликами.
Логика `postjoin()` для всех инстансов одинакова. К этому моменту на инстансе уже инициализированы правильные спейсы и возможно даже существует предыстория рафт журнала. Инстанс инициализирует рафт ноду и получает read barrier (это позволяет убедиться, что рафт лог актуален). Из рафт лога становятся известны параметры репликации, и инстанс синхронизируется с репликами.
Остаётся один маленький штришок - проверить свой статус voter / learner, при необходимости кинуть запрос на промоут до воутера (всё тот же `join`, лидер известен после получения read barrier), и дождаться его применения.