reddb_server/storage/wal/
mod.rs1pub mod append_coordinator;
10pub mod archiver;
11pub mod checkpoint;
12pub mod checkpointer_task;
13pub mod group_commit;
14pub mod reader;
15pub mod record;
16pub mod recovery;
17pub mod rmgr;
18pub mod transaction;
19pub mod writer;
20
21pub use append_coordinator::WalAppendCoordinator;
22pub use archiver::{
23 archive_change_records, archive_snapshot, load_archived_change_records, load_backup_head,
24 load_snapshot_manifest, load_unified_manifest, load_wal_segment_manifest, publish_backup_head,
25 publish_snapshot_manifest, publish_unified_manifest, publish_unified_manifest_for_prefix,
26 publish_wal_segment_manifest, WalArchiver,
27};
28pub use checkpoint::{CheckpointError, CheckpointMode, CheckpointResult, Checkpointer};
29pub use group_commit::GroupCommit;
30pub use reader::WalReader;
31pub use record::{RecordType, WalRecord};
32pub use recovery::{PointInTimeRecovery, RecoveryResult, RestorePoint};
33pub use transaction::{Transaction, TransactionManager, TxError, TxState};
34pub use writer::WalWriter;
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39 use std::fs;
40 use std::time::{SystemTime, UNIX_EPOCH};
41
42 #[test]
43 fn test_wal_write_read() {
44 let timestamp = SystemTime::now()
45 .duration_since(UNIX_EPOCH)
46 .unwrap()
47 .as_nanos();
48 let dir = std::env::temp_dir().join(format!("reddb_wal_test_{}", timestamp));
49 let _ = fs::create_dir_all(&dir);
50 let path = reddb_file::layout::wal_component_temp_path(
51 &dir,
52 "mod",
53 "write-read",
54 std::process::id(),
55 );
56 if path.exists() {
57 fs::remove_file(&path).unwrap();
58 }
59
60 {
62 let mut writer = WalWriter::open(&path).unwrap();
63
64 let rec1 = WalRecord::Begin { tx_id: 100 };
65 writer.append(&rec1).unwrap();
66
67 let rec2 = WalRecord::PageWrite {
68 tx_id: 100,
69 page_id: 5,
70 data: vec![1, 2, 3, 4],
71 };
72 writer.append(&rec2).unwrap();
73
74 let rec3 = WalRecord::Commit { tx_id: 100 };
75 writer.append(&rec3).unwrap();
76 }
77
78 {
80 let reader = WalReader::open(&path).unwrap();
81 let records: Vec<_> = reader.iter().map(|r| r.unwrap().1).collect();
82
83 assert_eq!(records.len(), 3);
84
85 match &records[0] {
86 WalRecord::Begin { tx_id } => assert_eq!(*tx_id, 100),
87 _ => panic!("Wrong type"),
88 }
89
90 match &records[1] {
91 WalRecord::PageWrite {
92 tx_id,
93 page_id,
94 data,
95 } => {
96 assert_eq!(*tx_id, 100);
97 assert_eq!(*page_id, 5);
98 assert_eq!(*data, vec![1, 2, 3, 4]);
99 }
100 _ => panic!("Wrong type"),
101 }
102
103 match &records[2] {
104 WalRecord::Commit { tx_id } => assert_eq!(*tx_id, 100),
105 _ => panic!("Wrong type"),
106 }
107 }
108
109 if path.exists() {
111 fs::remove_file(path).unwrap();
112 }
113 if dir.exists() {
114 fs::remove_dir(dir).unwrap();
115 }
116 }
117}