Skip to content
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

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

gy2411
Copy link
Collaborator

@gy2411 gy2411 commented Dec 13, 2024

#1950

Сейчас есть баг при создании снапшотов из disk registy based дисков. Чекпоинты для таких дисков делаются через теневой диск (shadow disk). Сейчас, если вот тут мы от чекпоинта с теневым диском получаем статус Error, то мы удаляем чекпоинт и ретраим таск. При ретрае таск падает при попытке создать чекпоинт с тем же id, что был у удалённого чекпоинта.

Теперь вместо этого мы при ретрае создаём чекпоинт с новым checkpoint id.

Также для воспроизведения падений теневого диска в интеграционных тестах нам нужно ходить в disk registry. Добавляю в nbs client нужный для этого код.

См. больше деталей в комментариях в #1950

Надо понимать, что эта правка ещё не полностью решает проблему с падением теневого диска. Подробнее написал в issue #1950.

@gy2411 gy2411 added the large-tests Launch large tests for PR label Dec 13, 2024
Copy link
Contributor

Note

This is an automated comment that will be appended during run.

🟢 linux-x86_64-relwithdebinfo: all tests PASSED for commit 35da72c.

TESTS PASSED ERRORS FAILED SKIPPED MUTED?
6618 6618 0 0 0 0

if err != nil {
return err
}
if t.state.FinalCheckpointID == "" {
Copy link
Collaborator Author

@gy2411 gy2411 Dec 13, 2024

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)
Copy link
Collaborator Author

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) {
Copy link
Collaborator Author

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\"}",
Copy link
Collaborator Author

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(
Copy link
Collaborator Author

@gy2411 gy2411 Dec 13, 2024

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.

Copy link
Contributor

Note

This is an automated comment that will be appended during run.

🟢 linux-x86_64-relwithdebinfo: all tests PASSED for commit 3b88f28.

TESTS PASSED ERRORS FAILED SKIPPED MUTED?
6619 6619 0 0 0 0

Copy link
Contributor

Note

This is an automated comment that will be appended during run.

🟢 linux-x86_64-relwithdebinfo: all tests PASSED for commit e5ab782.

TESTS PASSED ERRORS FAILED SKIPPED MUTED?
6624 6624 0 0 0 0


// Needed for shadow disk based checkpoints.
int32 FailedCheckpointsCount = 7;
string FinalCheckpointID = 8;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

отступ, так как коммент относится только в переменной FailedCheckpointsCount

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Казалось бы, к FinalCheckpointID этот комментарий тоже относится. Без теневых дисков было бы незачем созранять id чекпоинта персистентно.

return t.makeCheckpointID(int(t.state.FailedCheckpointsCount))
}

func (t *createSnapshotFromDiskTask) makeCheckpointID(index int) string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

вообще этот подход ломает семантику snapshotID = checkpointID - это точно ничего не сломает?

Copy link
Collaborator Author

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

предлагаю упростить и если уж тащить внутренности dr в дм, то только в тестового клиента (и я бы даже делал это без тестов)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А что ты понимаешь под "упростить"?

Хм, а в чём принципиальная разница между тестовым клиентом и отдельным файликом disk_registry_state.go? Они ведь всё равно в одном модуле находятся.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если не писать тесты на методы работы с disk registry, то появляется опасение, что выключение девайса не сработает. И тогда интеграционный тест будет работать вхолостую -- он будет завершаться успехом, но при этом по факту никогда не будет выключать девайс. Хочется обезопаситься от этого.

Было бы здорово в самом интеграционном тесте как-то проверить, что девайс действительно был выключен и что действительно был налит новый чекпоинт. Но ведь так происходит не всегда -- из-за рандома с таймингами могут быть сценарии, когда девайс не ломался.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

то, что написаны тесты - никогда не плохо

но такой большой кусок кода, особенно не используемый ДМом в проде тащить в nbs клиента неправильно - мы вообще в DA не ходим

в клиенте иметь этот код также будет причиной вопросов что это, зачем это, давайте сделаем по аналогии и тп

мы в целом уже давно хотели это исправить и мне кажется этот момент настал, тк этот код нетривиальный (тк это внутренности DA) #892

@gy2411 gy2411 force-pushed the users/gayurgin/retry_with_new_checkpoint_id_when_create_snapshot branch 2 times, most recently from 7cd05e6 to ff6d6f1 Compare January 16, 2025 10:34
@gy2411 gy2411 force-pushed the users/gayurgin/retry_with_new_checkpoint_id_when_create_snapshot branch from ff6d6f1 to 560c54f Compare January 16, 2025 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
large-tests Launch large tests for PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants