1#![allow(clippy::derive_partial_eq_without_eq)]
16#![feature(trait_alias)]
17#![feature(type_alias_impl_trait)]
18#![feature(custom_test_frameworks)]
19#![feature(map_try_insert)]
20#![feature(error_generic_member_access)]
21#![feature(coverage_attribute)]
22
23pub mod error;
24pub mod meta_snapshot;
25pub mod meta_snapshot_v1;
26pub mod meta_snapshot_v2;
27pub mod storage;
28
29use std::collections::{HashMap, HashSet};
30
31use itertools::Itertools;
32use risingwave_common::RW_VERSION;
33use risingwave_hummock_sdk::state_table_info::StateTableInfo;
34use risingwave_hummock_sdk::version::HummockVersion;
35use risingwave_hummock_sdk::{HummockRawObjectId, HummockVersionId};
36use risingwave_pb::backup_service::{PbMetaSnapshotManifest, PbMetaSnapshotMetadata};
37use serde::{Deserialize, Serialize};
38
39use crate::error::{BackupError, BackupResult};
40
41pub type MetaSnapshotId = u64;
42pub type MetaBackupJobId = u64;
43
44#[derive(Serialize, Deserialize, Clone)]
46pub struct MetaSnapshotMetadata {
47 pub id: MetaSnapshotId,
48 pub hummock_version_id: HummockVersionId,
49 #[serde(rename = "ssts")]
51 pub objects: HashSet<HummockRawObjectId>,
52 #[serde(default)]
53 pub format_version: u32,
54 pub remarks: Option<String>,
55 #[serde(default)]
56 pub state_table_info: HashMap<u32, StateTableInfo>,
57 pub rw_version: Option<String>,
58}
59
60impl MetaSnapshotMetadata {
61 pub fn new(
62 id: MetaSnapshotId,
63 v: &HummockVersion,
64 format_version: u32,
65 remarks: Option<String>,
66 ) -> Self {
67 Self {
68 id,
69 hummock_version_id: v.id,
70 objects: v
71 .get_object_ids(false)
72 .map(|object_id| object_id.as_raw())
73 .collect(),
74 format_version,
75 remarks,
76 state_table_info: v
77 .state_table_info
78 .info()
79 .iter()
80 .map(|(id, info)| (id.table_id, info.into()))
81 .collect(),
82 rw_version: Some(RW_VERSION.to_owned()),
83 }
84 }
85}
86
87#[derive(Serialize, Deserialize, Default, Clone)]
89pub struct MetaSnapshotManifest {
90 pub manifest_id: u64,
91 pub snapshot_metadata: Vec<MetaSnapshotMetadata>,
92}
93
94pub fn xxhash64_checksum(data: &[u8]) -> u64 {
95 twox_hash::XxHash64::oneshot(0, data)
96}
97
98pub fn xxhash64_verify(data: &[u8], checksum: u64) -> BackupResult<()> {
99 let data_checksum = xxhash64_checksum(data);
100 if data_checksum != checksum {
101 return Err(BackupError::ChecksumMismatch {
102 expected: checksum,
103 found: data_checksum,
104 });
105 }
106 Ok(())
107}
108
109impl From<&MetaSnapshotMetadata> for PbMetaSnapshotMetadata {
110 fn from(m: &MetaSnapshotMetadata) -> Self {
111 Self {
112 id: m.id,
113 hummock_version_id: m.hummock_version_id.to_u64(),
114 format_version: Some(m.format_version),
115 remarks: m.remarks.clone(),
116 state_table_info: m
117 .state_table_info
118 .iter()
119 .map(|(t, i)| (*t, i.into()))
120 .collect(),
121 rw_version: m.rw_version.clone(),
122 }
123 }
124}
125
126impl From<&MetaSnapshotManifest> for PbMetaSnapshotManifest {
127 fn from(m: &MetaSnapshotManifest) -> Self {
128 Self {
129 manifest_id: m.manifest_id,
130 snapshot_metadata: m.snapshot_metadata.iter().map_into().collect_vec(),
131 }
132 }
133}