-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Disk Manager] retry with new checkpoint id when create snapshot if shadow disk failed during filling #2691
base: main
Are you sure you want to change the base?
[Disk Manager] retry with new checkpoint id when create snapshot if shadow disk failed during filling #2691
Conversation
if err != nil { | ||
return err | ||
} | ||
if t.state.FinalCheckpointID == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Мотивировка этого if (и вообще мотивировка поля FinalCheckpointID) -- мы не должны обновлять чекпоинт, если мы уже зашедуллили dataplane таск с предыдущим чекпоинтом.
|
||
// NBS-1873: should always delete checkpoint. | ||
err = nbsClient.DeleteCheckpoint(ctx, disk.DiskId, checkpointID) | ||
err = t.deletePreviousCheckpoint(ctx, nbsClient) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Предыдущий чекпоинт тоже надо удалить -- таск мог пойти на отмену после инкремента FailedCheckpointsCount, но до удаления старого чекпоинта.
) | ||
} | ||
|
||
func TestCreateSnapshotFromDiskWithFailedShadowDiskLong(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Сделал два варианта теста с разными границами на интервал случайной зажержки, чтобы меньше зависеть от конкретных таймингов работы таска.
} | ||
|
||
input := fmt.Sprintf( | ||
"{\"DisableAgent\":{\"AgentId\":\"%v\",\"DeviceUUIDs\":%v},\"Message\":\"%v\"}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Хотя ручка и называется "DisableAgent", она не будет ломать весь агент, если ей передать непустой спасок девайсов. Она сломает только девайсы из этого списка.
Сломает -- значит, девайсы начнут отдавать ошибку в ответ на все запросы чтения и записи.
@@ -278,6 +293,7 @@ func (t *createSnapshotFromDiskTask) GetResponse() proto.Message { | |||
|
|||
func (t *createSnapshotFromDiskTask) ensureCheckpointReady( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут есть конфликт с #2612 (там эта функция уносится в метод nbs-клиента). Придётся его порезолвить.
Кстати, в том pr делается удаление чекпоинта в методе EnsureCheckpointReady, а в этом pr предлагается вынести его за пределы EnsureCheckpointReady. Это важно: иначе будет возможен плохой сценарий, при котором таск пойдёт на ретрай уже после удаления чекпоинта, но еще не успев увеличить FailedCheckpointsCount.
cloud/disk_manager/internal/pkg/services/snapshots/protos/create_snapshot_from_disk_task.proto
Outdated
Show resolved
Hide resolved
cloud/disk_manager/internal/pkg/services/snapshots/protos/create_snapshot_from_disk_task.proto
Outdated
Show resolved
Hide resolved
|
||
// Needed for shadow disk based checkpoints. | ||
int32 FailedCheckpointsCount = 7; | ||
string FinalCheckpointID = 8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
отступ, так как коммент относится только в переменной FailedCheckpointsCount
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Казалось бы, к FinalCheckpointID этот комментарий тоже относится. Без теневых дисков было бы незачем созранять id чекпоинта персистентно.
cloud/disk_manager/internal/pkg/services/snapshots/create_snapshot_from_disk_task.go
Outdated
Show resolved
Hide resolved
cloud/disk_manager/internal/pkg/services/snapshots/create_snapshot_from_disk_task.go
Outdated
Show resolved
Hide resolved
cloud/disk_manager/internal/pkg/services/snapshots/create_snapshot_from_disk_task.go
Show resolved
Hide resolved
return t.makeCheckpointID(int(t.state.FailedCheckpointsCount)) | ||
} | ||
|
||
func (t *createSnapshotFromDiskTask) makeCheckpointID(index int) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
вообще этот подход ломает семантику snapshotID = checkpointID - это точно ничего не сломает?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Насколько я вижу по коду, ничего сломаться не должно. У нас везде разграничены checkpoint id и snapshot id. Мы на это полагаемся разве что в некоторых тестах, в которых не должны происходить поломки чекпоинтов.
Но конечно хотелось бы как-то более нажёжно убедиться, что ничего не сломается... Есть радикальная идея -- делать первый же чекпоинт с другим id (скажем, не snapshot_id, а snapshot_id_0). Чтобы ситуация с различными id снапшота и чекпоинта воспроизволась не только в случаях поломки теневого диска и наблюдалась во всех имеющихся ныне тестах.
@@ -0,0 +1,62 @@ | |||
package nbs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
предлагаю упростить и если уж тащить внутренности dr в дм, то только в тестового клиента (и я бы даже делал это без тестов)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А что ты понимаешь под "упростить"?
Хм, а в чём принципиальная разница между тестовым клиентом и отдельным файликом disk_registry_state.go? Они ведь всё равно в одном модуле находятся.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Если не писать тесты на методы работы с disk registry, то появляется опасение, что выключение девайса не сработает. И тогда интеграционный тест будет работать вхолостую -- он будет завершаться успехом, но при этом по факту никогда не будет выключать девайс. Хочется обезопаситься от этого.
Было бы здорово в самом интеграционном тесте как-то проверить, что девайс действительно был выключен и что действительно был налит новый чекпоинт. Но ведь так происходит не всегда -- из-за рандома с таймингами могут быть сценарии, когда девайс не ломался.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
то, что написаны тесты - никогда не плохо
но такой большой кусок кода, особенно не используемый ДМом в проде тащить в nbs клиента неправильно - мы вообще в DA не ходим
в клиенте иметь этот код также будет причиной вопросов что это, зачем это, давайте сделаем по аналогии и тп
мы в целом уже давно хотели это исправить и мне кажется этот момент настал, тк этот код нетривиальный (тк это внутренности DA) #892
7cd05e6
to
ff6d6f1
Compare
…f shadow disk failed during its filling
…s update when retry shadow disk fail
ff6d6f1
to
560c54f
Compare
#1950
Сейчас есть баг при создании снапшотов из disk registy based дисков. Чекпоинты для таких дисков делаются через теневой диск (shadow disk). Сейчас, если вот тут мы от чекпоинта с теневым диском получаем статус Error, то мы удаляем чекпоинт и ретраим таск. При ретрае таск падает при попытке создать чекпоинт с тем же id, что был у удалённого чекпоинта.
Теперь вместо этого мы при ретрае создаём чекпоинт с новым checkpoint id.
Также для воспроизведения падений теневого диска в интеграционных тестах нам нужно ходить в disk registry. Добавляю в nbs client нужный для этого код.
См. больше деталей в комментариях в #1950
Надо понимать, что эта правка ещё не полностью решает проблему с падением теневого диска. Подробнее написал в issue #1950.