From 8a6707c6af1a358cd9641299b4484ba298c65be3 Mon Sep 17 00:00:00 2001 From: Jurriaan Mous Date: Sat, 4 Jan 2025 11:50:27 +0100 Subject: [PATCH] Add more options to C api for backups and getting info from them --- db/c.cc | 65 +++++++++++++++++++++++++++++++++++++++++++++ db/c_test.c | 22 ++++++++++++++- include/rocksdb/c.h | 23 ++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/db/c.cc b/db/c.cc index 77b0a6af326..263011576f4 100644 --- a/db/c.cc +++ b/db/c.cc @@ -59,6 +59,7 @@ using ROCKSDB_NAMESPACE::BottommostLevelCompaction; using ROCKSDB_NAMESPACE::BytewiseComparator; using ROCKSDB_NAMESPACE::Cache; using ROCKSDB_NAMESPACE::Checkpoint; +using ROCKSDB_NAMESPACE::CreateBackupOptions; using ROCKSDB_NAMESPACE::ColumnFamilyDescriptor; using ROCKSDB_NAMESPACE::ColumnFamilyHandle; using ROCKSDB_NAMESPACE::ColumnFamilyMetaData; @@ -145,6 +146,9 @@ struct rocksdb_backup_engine_t { struct rocksdb_backup_engine_info_t { std::vector rep; }; +struct rocksdb_create_backup_options_t { + CreateBackupOptions rep; +}; struct rocksdb_restore_options_t { RestoreOptions rep; }; @@ -680,12 +684,68 @@ void rocksdb_backup_engine_create_new_backup_flush( SaveError(errptr, be->rep->CreateNewBackup(db->rep, flush_before_backup)); } +void rocksdb_backup_engine_create_new_backup_with_options_with_metadata( + rocksdb_backup_engine_t* be, rocksdb_t* db, + rocksdb_create_backup_options_t* bo, const char* app_metadata, + uint32_t* new_backup_id, char** errptr) { + + std::string metadata_str; + if (app_metadata != NULL) { + metadata_str = std::string(app_metadata); + } + + SaveError(errptr, be->rep->CreateNewBackupWithMetadata(bo->rep, db->rep, metadata_str, new_backup_id)); +} + +rocksdb_create_backup_options_t* rocksdb_create_backup_options_create() { + return new rocksdb_create_backup_options_t; +} + +void rocksdb_create_backup_options_destroy(rocksdb_create_backup_options_t* opt) { + delete opt; +} + +void rocksdb_create_backup_options_set_flush_before_backup(rocksdb_create_backup_options_t* opt, bool flush) { + opt->rep.flush_before_backup = flush; +} + void rocksdb_backup_engine_purge_old_backups(rocksdb_backup_engine_t* be, uint32_t num_backups_to_keep, char** errptr) { SaveError(errptr, be->rep->PurgeOldBackups(num_backups_to_keep)); } +void rocksdb_backup_engine_delete_backup(rocksdb_backup_engine_t* be, + uint32_t backup_id, + char** errptr) { + SaveError(errptr, be->rep->DeleteBackup(backup_id)); +} + +int* rocksdb_backup_engine_get_corrupted_backups( + const rocksdb_backup_engine_t* be, + size_t* num_corrupted_backups) { + std::vector corrupt_backup_ids; + + be->rep->GetCorruptedBackups(&corrupt_backup_ids); + + if (corrupt_backup_ids.empty()) { + return nullptr; + } + + *num_corrupted_backups = corrupt_backup_ids.size(); + int* corrupted_backups = static_cast(malloc(sizeof(int) * corrupt_backup_ids.size())); + + for (size_t i = 0; i < corrupt_backup_ids.size(); ++i) { + corrupted_backups[i] = static_cast(corrupt_backup_ids[i]); + } + + return corrupted_backups; +} + +void rocksdb_backup_engine_garbage_collect(rocksdb_backup_engine_t* be, char** errptr) { + SaveError(errptr, be->rep->GarbageCollect()); +} + rocksdb_restore_options_t* rocksdb_restore_options_create() { return new rocksdb_restore_options_t; } @@ -752,6 +812,11 @@ uint32_t rocksdb_backup_engine_info_number_files( return info->rep[index].number_files; } +char* rocksdb_backup_engine_info_app_metadata( + const rocksdb_backup_engine_info_t* info, int index) { + return strdup(info->rep[index].app_metadata.c_str()); +} + void rocksdb_backup_engine_info_destroy( const rocksdb_backup_engine_info_t* info) { delete info; diff --git a/db/c_test.c b/db/c_test.c index eb9886ba467..8f7255c3865 100644 --- a/db/c_test.c +++ b/db/c_test.c @@ -855,9 +855,18 @@ int main(int argc, char** argv) { rocksdb_delete(db, woptions, "does-not-exist", 14, &err); CheckNoError(err); - rocksdb_backup_engine_create_new_backup(be, db, &err); + rocksdb_create_backup_options_t* beo = rocksdb_create_backup_options_create(); + rocksdb_create_backup_options_set_flush_before_backup(beo, false); + + uint32_t backup_id = 0; + + rocksdb_backup_engine_create_new_backup_with_options_with_metadata(be, db, beo, "a", &backup_id, &err); CheckNoError(err); + CheckCondition(backup_id > 0); + + rocksdb_create_backup_options_destroy(beo); + const rocksdb_backup_engine_info_t* bei = rocksdb_backup_engine_get_backup_info(be); CheckCondition(rocksdb_backup_engine_info_count(bei) > 1); @@ -870,9 +879,20 @@ int main(int argc, char** argv) { CheckCondition(rocksdb_backup_engine_info_count(bei) == 1); rocksdb_backup_engine_info_destroy(bei); + size_t num_corrupted_backups = 0; + int* corrupted_backups = + rocksdb_backup_engine_get_corrupted_backups(be, &num_corrupted_backups); + CheckCondition(num_corrupted_backups == 0); + if (corrupted_backups) { + free(corrupted_backups); + } + rocksdb_delete(db, woptions, "foo", 3, &err); CheckNoError(err); + rocksdb_backup_engine_garbage_collect(be, &err); + CheckNoError(err); + // get the identity before the backup size_t before_db_id_len = 0; char* before_db_id = rocksdb_get_db_identity(db, &before_db_id_len); diff --git a/include/rocksdb/c.h b/include/rocksdb/c.h index ff452a3546e..e2ac012871a 100644 --- a/include/rocksdb/c.h +++ b/include/rocksdb/c.h @@ -72,6 +72,7 @@ typedef struct rocksdb_t rocksdb_t; typedef struct rocksdb_backup_engine_t rocksdb_backup_engine_t; typedef struct rocksdb_backup_engine_info_t rocksdb_backup_engine_info_t; typedef struct rocksdb_backup_engine_options_t rocksdb_backup_engine_options_t; +typedef struct rocksdb_create_backup_options_t rocksdb_create_backup_options_t; typedef struct rocksdb_restore_options_t rocksdb_restore_options_t; typedef struct rocksdb_memory_allocator_t rocksdb_memory_allocator_t; typedef struct rocksdb_lru_cache_options_t rocksdb_lru_cache_options_t; @@ -172,9 +173,22 @@ extern ROCKSDB_LIBRARY_API void rocksdb_backup_engine_create_new_backup_flush( rocksdb_backup_engine_t* be, rocksdb_t* db, unsigned char flush_before_backup, char** errptr); +extern ROCKSDB_LIBRARY_API void rocksdb_backup_engine_create_new_backup_with_options_with_metadata( + rocksdb_backup_engine_t* be, rocksdb_t* db, + rocksdb_create_backup_options_t* bo, const char* app_metadata, uint32_t* new_backup_id, char** errptr); + +extern ROCKSDB_LIBRARY_API rocksdb_create_backup_options_t* rocksdb_create_backup_options_create(void); + +extern ROCKSDB_LIBRARY_API void rocksdb_create_backup_options_destroy(rocksdb_create_backup_options_t* opt); + +extern ROCKSDB_LIBRARY_API void rocksdb_create_backup_options_set_flush_before_backup(rocksdb_create_backup_options_t* opt, bool flush); + extern ROCKSDB_LIBRARY_API void rocksdb_backup_engine_purge_old_backups( rocksdb_backup_engine_t* be, uint32_t num_backups_to_keep, char** errptr); +extern ROCKSDB_LIBRARY_API void rocksdb_backup_engine_delete_backup( + rocksdb_backup_engine_t* be, uint32_t backup_id, char** errptr); + extern ROCKSDB_LIBRARY_API rocksdb_restore_options_t* rocksdb_restore_options_create(void); extern ROCKSDB_LIBRARY_API void rocksdb_restore_options_destroy( @@ -195,6 +209,12 @@ extern ROCKSDB_LIBRARY_API void rocksdb_backup_engine_restore_db_from_backup( const rocksdb_restore_options_t* restore_options, const uint32_t backup_id, char** errptr); +extern ROCKSDB_LIBRARY_API int* rocksdb_backup_engine_get_corrupted_backups( + const rocksdb_backup_engine_t* be, size_t* num_corrupted_backups); + +extern ROCKSDB_LIBRARY_API void rocksdb_backup_engine_garbage_collect( + rocksdb_backup_engine_t* be, char** errptr); + extern ROCKSDB_LIBRARY_API const rocksdb_backup_engine_info_t* rocksdb_backup_engine_get_backup_info(rocksdb_backup_engine_t* be); @@ -213,6 +233,9 @@ extern ROCKSDB_LIBRARY_API uint64_t rocksdb_backup_engine_info_size( extern ROCKSDB_LIBRARY_API uint32_t rocksdb_backup_engine_info_number_files( const rocksdb_backup_engine_info_t* info, int index); +extern ROCKSDB_LIBRARY_API char* rocksdb_backup_engine_info_app_metadata( + const rocksdb_backup_engine_info_t* info, int index); + extern ROCKSDB_LIBRARY_API void rocksdb_backup_engine_info_destroy( const rocksdb_backup_engine_info_t* info);