RocksDB备份恢复 #
一、备份概述 #
1.1 为什么需要备份 #
text
备份的重要性:
├── 数据安全 - 防止数据丢失
├── 灾难恢复 - 系统故障时恢复
├── 数据迁移 - 跨环境迁移数据
└── 历史版本 - 保留历史数据状态
1.2 RocksDB备份方式 #
| 方式 | 说明 | 适用场景 |
|---|---|---|
| BackupEngine | 增量备份,支持多版本 | 定期备份 |
| Checkpoint | 快速创建一致性快照 | 即时备份 |
| 文件复制 | 直接复制数据文件 | 简单备份 |
二、BackupEngine #
2.1 创建备份 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/utilities/backup_engine.h>
#include <iostream>
int main() {
rocksdb::DB* db;
rocksdb::Options options;
options.create_if_missing = true;
rocksdb::Status status = rocksdb::DB::Open(options, "/tmp/testdb", &db);
if (!status.ok()) {
std::cerr << "Open failed: " << status.ToString() << std::endl;
return 1;
}
// 创建BackupEngine
rocksdb::BackupEngine* backup_engine;
rocksdb::BackupEngineOptions backup_options("/tmp/backup");
status = rocksdb::BackupEngine::Open(rocksdb::Env::Default(),
backup_options,
&backup_engine);
if (!status.ok()) {
std::cerr << "BackupEngine open failed: " << status.ToString() << std::endl;
delete db;
return 1;
}
// 创建备份
status = backup_engine->CreateNewBackup(db);
if (status.ok()) {
std::cout << "Backup created successfully!" << std::endl;
} else {
std::cerr << "Backup failed: " << status.ToString() << std::endl;
}
delete backup_engine;
delete db;
return 0;
}
2.2 BackupEngineOptions #
cpp
#include <rocksdb/utilities/backup_engine.h>
rocksdb::BackupEngineOptions GetBackupOptions(const std::string& backup_dir) {
rocksdb::BackupEngineOptions options(backup_dir);
// 备份目录
options.backup_dir = backup_dir;
// 备份线程数
options.backup_rate_limit = 0; // 无限制
options.restore_rate_limit = 0; // 无限制
// 最大备份数量
options.max_valid_backups_to_open = 10;
// 是否共享表文件
options.share_table_files = true;
// 是否共享带ID的表文件
options.share_files_with_checksum = true;
// 同步备份
options.sync = true;
// 备份日志
options.backup_log_files = true;
return options;
}
2.3 列出备份 #
cpp
#include <rocksdb/utilities/backup_engine.h>
#include <iostream>
#include <vector>
void ListBackups(rocksdb::BackupEngine* backup_engine) {
std::vector<rocksdb::BackupInfo> backup_info;
backup_engine->GetBackupInfo(&backup_info);
std::cout << "Available backups:" << std::endl;
for (const auto& info : backup_info) {
std::cout << " Backup ID: " << info.backup_id << std::endl;
std::cout << " Timestamp: " << info.timestamp << std::endl;
std::cout << " Size: " << info.size << " bytes" << std::endl;
std::cout << " Number of files: " << info.number_files << std::endl;
std::cout << std::endl;
}
}
2.4 恢复备份 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/utilities/backup_engine.h>
#include <iostream>
void RestoreBackup(const std::string& backup_dir,
const std::string& db_dir) {
rocksdb::BackupEngine* backup_engine;
rocksdb::BackupEngineOptions backup_options(backup_dir);
rocksdb::Status status = rocksdb::BackupEngine::Open(
rocksdb::Env::Default(), backup_options, &backup_engine);
if (!status.ok()) {
std::cerr << "Open backup engine failed: " << status.ToString() << std::endl;
return;
}
// 恢复最新备份
status = backup_engine->RestoreDBFromLatestBackup(db_dir, db_dir);
if (status.ok()) {
std::cout << "Database restored successfully!" << std::endl;
} else {
std::cerr << "Restore failed: " << status.ToString() << std::endl;
}
delete backup_engine;
}
// 恢复指定备份
void RestoreSpecificBackup(const std::string& backup_dir,
const std::string& db_dir,
uint32_t backup_id) {
rocksdb::BackupEngine* backup_engine;
rocksdb::BackupEngineOptions backup_options(backup_dir);
rocksdb::BackupEngine::Open(rocksdb::Env::Default(), backup_options, &backup_engine);
// 恢复指定ID的备份
rocksdb::Status status = backup_engine->RestoreDBFromBackup(
backup_id, db_dir, db_dir);
if (status.ok()) {
std::cout << "Database restored from backup " << backup_id << std::endl;
}
delete backup_engine;
}
2.5 删除备份 #
cpp
#include <rocksdb/utilities/backup_engine.h>
void DeleteOldBackups(rocksdb::BackupEngine* backup_engine, int keep_count) {
// 只保留最近N个备份
rocksdb::Status status = backup_engine->PurgeOldBackups(keep_count);
if (status.ok()) {
std::cout << "Old backups purged, keeping " << keep_count << " latest" << std::endl;
}
}
void DeleteSpecificBackup(rocksdb::BackupEngine* backup_engine, uint32_t backup_id) {
rocksdb::Status status = backup_engine->DeleteBackup(backup_id);
if (status.ok()) {
std::cout << "Backup " << backup_id << " deleted" << std::endl;
}
}
三、Checkpoint #
3.1 创建检查点 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/utilities/checkpoint.h>
#include <iostream>
void CreateCheckpoint(rocksdb::DB* db, const std::string& checkpoint_dir) {
rocksdb::Checkpoint* checkpoint;
rocksdb::Status status = rocksdb::Checkpoint::Create(db, &checkpoint);
if (!status.ok()) {
std::cerr << "Create checkpoint object failed: " << status.ToString() << std::endl;
return;
}
// 创建检查点
status = checkpoint->CreateCheckpoint(checkpoint_dir);
if (status.ok()) {
std::cout << "Checkpoint created at " << checkpoint_dir << std::endl;
} else {
std::cerr << "Create checkpoint failed: " << status.ToString() << std::endl;
}
delete checkpoint;
}
int main() {
rocksdb::DB* db;
rocksdb::Options options;
options.create_if_missing = true;
rocksdb::DB::Open(options, "/tmp/testdb", &db);
// 写入一些数据
for (int i = 0; i < 100; i++) {
db->Put(rocksdb::WriteOptions(),
"key" + std::to_string(i),
"value" + std::to_string(i));
}
// 创建检查点
CreateCheckpoint(db, "/tmp/checkpoint");
delete db;
return 0;
}
3.2 检查点与备份的区别 #
| 特性 | Checkpoint | BackupEngine |
|---|---|---|
| 创建速度 | 快(硬链接) | 较慢(复制) |
| 空间占用 | 共享文件 | 独立文件 |
| 增量支持 | 否 | 是 |
| 版本管理 | 否 | 是 |
| 适用场景 | 即时快照 | 定期备份 |
四、增量备份 #
4.1 增量备份原理 #
text
增量备份流程:
第一次备份:
├── 复制所有SST文件
├── 复制WAL文件
└── 记录文件清单
第二次备份(增量):
├── 检查文件变化
├── 只复制新文件
├── 硬链接共享文件
└── 更新文件清单
4.2 实现增量备份 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/utilities/backup_engine.h>
#include <iostream>
class BackupManager {
public:
BackupManager(rocksdb::DB* db, const std::string& backup_dir)
: db_(db), backup_dir_(backup_dir) {
rocksdb::BackupEngineOptions options(backup_dir);
options.share_table_files = true;
options.share_files_with_checksum = true;
rocksdb::BackupEngine::Open(rocksdb::Env::Default(), options, &backup_engine_);
}
~BackupManager() {
if (backup_engine_) {
delete backup_engine_;
}
}
bool CreateBackup() {
rocksdb::Status status = backup_engine_->CreateNewBackup(db_);
if (status.ok()) {
std::cout << "Backup created at " << backup_dir_ << std::endl;
return true;
}
std::cerr << "Backup failed: " << status.ToString() << std::endl;
return false;
}
void ListBackups() {
std::vector<rocksdb::BackupInfo> info;
backup_engine_->GetBackupInfo(&info);
for (const auto& i : info) {
std::cout << "Backup " << i.backup_id
<< ": " << i.size << " bytes" << std::endl;
}
}
bool RestoreLatest(const std::string& restore_dir) {
rocksdb::Status status = backup_engine_->RestoreDBFromLatestBackup(
restore_dir, restore_dir);
return status.ok();
}
void PurgeOldBackups(int keep_count) {
backup_engine_->PurgeOldBackups(keep_count);
}
private:
rocksdb::DB* db_;
std::string backup_dir_;
rocksdb::BackupEngine* backup_engine_ = nullptr;
};
五、备份策略 #
5.1 定期备份 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/utilities/backup_engine.h>
#include <chrono>
#include <thread>
void ScheduledBackup(rocksdb::DB* db,
const std::string& backup_dir,
int interval_seconds,
int max_backups) {
rocksdb::BackupEngine* backup_engine;
rocksdb::BackupEngineOptions options(backup_dir);
rocksdb::BackupEngine::Open(rocksdb::Env::Default(), options, &backup_engine);
while (true) {
// 创建备份
rocksdb::Status status = backup_engine->CreateNewBackup(db);
if (status.ok()) {
std::cout << "Backup created at "
<< std::chrono::system_clock::now().time_since_epoch().count()
<< std::endl;
// 清理旧备份
backup_engine->PurgeOldBackups(max_backups);
}
// 等待下一次备份
std::this_thread::sleep_for(std::chrono::seconds(interval_seconds));
}
delete backup_engine;
}
5.2 备份验证 #
cpp
#include <rocksdb/utilities/backup_engine.h>
#include <iostream>
bool VerifyBackup(rocksdb::BackupEngine* backup_engine, uint32_t backup_id) {
rocksdb::Status status = backup_engine->VerifyBackup(backup_id);
if (status.ok()) {
std::cout << "Backup " << backup_id << " is valid" << std::endl;
return true;
} else {
std::cerr << "Backup " << backup_id << " is corrupted: "
<< status.ToString() << std::endl;
return false;
}
}
void VerifyAllBackups(rocksdb::BackupEngine* backup_engine) {
std::vector<rocksdb::BackupInfo> backup_info;
backup_engine->GetBackupInfo(&backup_info);
for (const auto& info : backup_info) {
VerifyBackup(backup_engine, info.backup_id);
}
}
六、灾难恢复 #
6.1 恢复流程 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/utilities/backup_engine.h>
#include <iostream>
class DisasterRecovery {
public:
DisasterRecovery(const std::string& backup_dir, const std::string& db_dir)
: backup_dir_(backup_dir), db_dir_(db_dir) {}
bool Recover() {
std::cout << "Starting disaster recovery..." << std::endl;
// 1. 打开备份引擎
rocksdb::BackupEngine* backup_engine;
rocksdb::BackupEngineOptions options(backup_dir_);
rocksdb::Status status = rocksdb::BackupEngine::Open(
rocksdb::Env::Default(), options, &backup_engine);
if (!status.ok()) {
std::cerr << "Cannot open backup engine: " << status.ToString() << std::endl;
return false;
}
// 2. 列出可用备份
std::vector<rocksdb::BackupInfo> backup_info;
backup_engine->GetBackupInfo(&backup_info);
if (backup_info.empty()) {
std::cerr << "No backups available" << std::endl;
delete backup_engine;
return false;
}
// 3. 选择最新备份
uint32_t latest_backup_id = backup_info.back().backup_id;
std::cout << "Restoring from backup " << latest_backup_id << std::endl;
// 4. 验证备份
status = backup_engine->VerifyBackup(latest_backup_id);
if (!status.ok()) {
std::cerr << "Backup verification failed" << std::endl;
delete backup_engine;
return false;
}
// 5. 恢复数据库
status = backup_engine->RestoreDBFromBackup(
latest_backup_id, db_dir_, db_dir_);
if (!status.ok()) {
std::cerr << "Restore failed: " << status.ToString() << std::endl;
delete backup_engine;
return false;
}
// 6. 验证恢复的数据库
rocksdb::DB* db;
status = rocksdb::DB::Open(rocksdb::Options(), db_dir_, &db);
if (!status.ok()) {
std::cerr << "Cannot open restored database" << std::endl;
delete backup_engine;
return false;
}
std::cout << "Recovery completed successfully!" << std::endl;
delete db;
delete backup_engine;
return true;
}
private:
std::string backup_dir_;
std::string db_dir_;
};
七、最佳实践 #
7.1 备份建议 #
| 建议 | 说明 |
|---|---|
| 定期备份 | 设置自动备份计划 |
| 多份备份 | 保留多个历史版本 |
| 异地备份 | 备份存储到远程位置 |
| 验证备份 | 定期验证备份有效性 |
| 测试恢复 | 定期测试恢复流程 |
7.2 备份配置示例 #
cpp
#include <rocksdb/utilities/backup_engine.h>
rocksdb::BackupEngineOptions GetProductionBackupOptions() {
rocksdb::BackupEngineOptions options("/backup/rocksdb");
// 启用文件共享(增量备份)
options.share_table_files = true;
options.share_files_with_checksum = true;
// 同步写入
options.sync = true;
// 备份日志文件
options.backup_log_files = true;
// 限速(可选)
// options.backup_rate_limit = 100 * 1024 * 1024; // 100MB/s
return options;
}
八、总结 #
8.1 备份API速查 #
| 操作 | 方法 | 说明 |
|---|---|---|
| 创建备份 | CreateNewBackup(db) |
创建新备份 |
| 列出备份 | GetBackupInfo(&info) |
获取备份列表 |
| 恢复最新 | RestoreDBFromLatestBackup(db_dir, wal_dir) |
恢复最新备份 |
| 恢复指定 | RestoreDBFromBackup(id, db_dir, wal_dir) |
恢复指定备份 |
| 删除备份 | DeleteBackup(id) |
删除指定备份 |
| 清理旧备份 | PurgeOldBackups(count) |
保留最近N个 |
| 验证备份 | VerifyBackup(id) |
验证备份有效性 |
| 创建检查点 | checkpoint->CreateCheckpoint(dir) |
创建检查点 |
8.2 关键要点 #
- 定期备份:设置自动备份计划
- 增量备份:使用BackupEngine节省空间
- 验证备份:定期验证备份有效性
- 测试恢复:确保恢复流程可用
- 异地备份:备份存储到远程位置
下一步,让我们学习存储引擎原理!
最后更新:2026-03-27