Я хотел бы выполнить резервное копирование запущенного экземпляра rockdb в папку на том же диске безопасным способом, не прерывая обработку во время резервного копирования.
Я прочитал:
Мой вопрос, является ли звонок CreateNewBackupWithMetadata
помечен как НЕ потокобезопасный, чтобы выразить, что два одновременных вызова этот функция будет иметь небезопасное поведение или указывать, что ЛЮБОЙ одновременный вызов в базе данных будет небезопасным. Я проверил реализацию, которая, по-видимому, создает контрольную точку — которая, как утверждается во второй статье, используется для онлайн-резервного копирования MyRocks — но я все еще не уверен, какая часть вызова не является поточно-ориентированной.
Я в настоящее время интерпретирую это как, это небезопасно, потому что CreateBackup...
звонки DisableFileDeletions
и позже EnableFileDeletions
что, конечно, если два перекрывающихся вызова сделаны, может вызвать проблемы. Поскольку SST-файлы являются неизменяемыми, я не беспокоюсь о них, но не уверен, может ли изменение WAL через вставки повредить резервную копию. Я хотел бы предположить, что запуск сброса при резервном копировании должен предотвратить это, но я хотел бы быть уверен.
Любые указатели или помощь приветствуются.
В итоге я заглянул в путь реализации глубже, и вот что я нашел:
Напомним, база данных RockSDB состоит из Memtables, SST и одной WAL, которая защищает данные в Memtables от сбоев.
Когда вы звоните rocksdb::BackupEngine::CreateBackupWithMetadata
, внутренняя блокировка не выполняется, так что этот вызов является слишком высоким, если одновременно активны два вызова. В частности, этот звонок Disable/EnableFileDeletions
, который, если вызван одним вызовом, в то время как другой все еще активен, обречен на смерть для другого вызова.
Процесс копирования файлов из базы данных в резервную копию защищен от изменений, происходящих в базе данных во время активного вызова, путем создания rocksdb::Checkpoint
, который, если flush_before_backup
был установлен в true, будет сначала очищать Memtables, таким образом очищая активный WAL.
Внутренне вызов CreateCustomCheckpoint
звонки DB::GetLiveFiles
в db_filecheckpoint.cc
, GetLiveFiles
берет глобальную блокировку базы данных (_mutex
), при необходимости сбрасывает Memtables и получает список SST. Если флеш в GetLiveFiles
происходит при удержании глобальной блокировки базы данных, в это время WAL должен быть пустым, что означает, что список всегда должен содержать SST-файлы, представляющие полное и непротиворечивое состояние базы данных со времени контрольной точки. Поскольку SST являются неизменяемыми, и поскольку удаление файла посредством сжатия отключается вызовом резервного копирования, вы всегда должны получать полную резервную копию, не сохраняя записи в базу данных. Однако это, конечно, означает, что невозможно определить точную последнюю запись / порядковый номер в резервной копии, когда происходят параллельные обновления.
Для не-сбрасывающей версии могут быть WAL-файлы, которые извлекаются в другом вызове, чем GetLiveFiles
между ними нет блокировки, т. е. они не обязательно согласованы, но я не стал проводить дальнейшее расследование, так как случай отсутствия промывки не был применим к моему использованию.
Других решений пока нет …