1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/storage/write_ahead_log.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/helper.hpp"
12#include "duckdb/common/types/data_chunk.hpp"
13#include "duckdb/common/enums/wal_type.hpp"
14#include "duckdb/common/serializer/buffered_file_writer.hpp"
15#include "duckdb/catalog/catalog_entry/scalar_macro_catalog_entry.hpp"
16#include "duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp"
17#include "duckdb/catalog/catalog_entry/table_macro_catalog_entry.hpp"
18#include "duckdb/catalog/catalog_entry/index_catalog_entry.hpp"
19#include "duckdb/main/attached_database.hpp"
20#include "duckdb/storage/storage_info.hpp"
21
22namespace duckdb {
23
24struct AlterInfo;
25
26class AttachedDatabase;
27class BufferedSerializer;
28class Catalog;
29class DatabaseInstance;
30class SchemaCatalogEntry;
31class SequenceCatalogEntry;
32class ScalarMacroCatalogEntry;
33class ViewCatalogEntry;
34class TypeCatalogEntry;
35class TableCatalogEntry;
36class Transaction;
37class TransactionManager;
38
39class ReplayState {
40public:
41 ReplayState(AttachedDatabase &db, ClientContext &context, Deserializer &source)
42 : db(db), context(context), catalog(db.GetCatalog()), source(source), deserialize_only(false),
43 checkpoint_id(INVALID_BLOCK) {
44 }
45
46 AttachedDatabase &db;
47 ClientContext &context;
48 Catalog &catalog;
49 Deserializer &source;
50 optional_ptr<TableCatalogEntry> current_table;
51 bool deserialize_only;
52 block_id_t checkpoint_id;
53
54public:
55 void ReplayEntry(WALType entry_type);
56
57protected:
58 virtual void ReplayCreateTable();
59 void ReplayDropTable();
60 void ReplayAlter();
61
62 void ReplayCreateView();
63 void ReplayDropView();
64
65 void ReplayCreateSchema();
66 void ReplayDropSchema();
67
68 void ReplayCreateType();
69 void ReplayDropType();
70
71 void ReplayCreateSequence();
72 void ReplayDropSequence();
73 void ReplaySequenceValue();
74
75 void ReplayCreateMacro();
76 void ReplayDropMacro();
77
78 void ReplayCreateTableMacro();
79 void ReplayDropTableMacro();
80
81 void ReplayCreateIndex();
82 void ReplayDropIndex();
83
84 void ReplayUseTable();
85 void ReplayInsert();
86 void ReplayDelete();
87 void ReplayUpdate();
88 void ReplayCheckpoint();
89};
90
91//! The WriteAheadLog (WAL) is a log that is used to provide durability. Prior
92//! to committing a transaction it writes the changes the transaction made to
93//! the database to the log, which can then be replayed upon startup in case the
94//! server crashes or is shut down.
95class WriteAheadLog {
96public:
97 //! Initialize the WAL in the specified directory
98 explicit WriteAheadLog(AttachedDatabase &database, const string &path);
99 virtual ~WriteAheadLog();
100
101 //! Skip writing to the WAL
102 bool skip_writing;
103
104public:
105 //! Replay the WAL
106 static bool Replay(AttachedDatabase &database, string &path);
107
108 //! Returns the current size of the WAL in bytes
109 int64_t GetWALSize();
110 //! Gets the total bytes written to the WAL since startup
111 idx_t GetTotalWritten();
112
113 virtual void WriteCreateTable(const TableCatalogEntry &entry);
114 void WriteDropTable(const TableCatalogEntry &entry);
115
116 void WriteCreateSchema(const SchemaCatalogEntry &entry);
117 void WriteDropSchema(const SchemaCatalogEntry &entry);
118
119 void WriteCreateView(const ViewCatalogEntry &entry);
120 void WriteDropView(const ViewCatalogEntry &entry);
121
122 void WriteCreateSequence(const SequenceCatalogEntry &entry);
123 void WriteDropSequence(const SequenceCatalogEntry &entry);
124 void WriteSequenceValue(const SequenceCatalogEntry &entry, SequenceValue val);
125
126 void WriteCreateMacro(const ScalarMacroCatalogEntry &entry);
127 void WriteDropMacro(const ScalarMacroCatalogEntry &entry);
128
129 void WriteCreateTableMacro(const TableMacroCatalogEntry &entry);
130 void WriteDropTableMacro(const TableMacroCatalogEntry &entry);
131
132 void WriteCreateIndex(const IndexCatalogEntry &entry);
133 void WriteDropIndex(const IndexCatalogEntry &entry);
134
135 void WriteCreateType(const TypeCatalogEntry &entry);
136 void WriteDropType(const TypeCatalogEntry &entry);
137 //! Sets the table used for subsequent insert/delete/update commands
138 void WriteSetTable(string &schema, string &table);
139
140 void WriteAlter(data_ptr_t ptr, idx_t data_size);
141
142 void WriteInsert(DataChunk &chunk);
143 void WriteDelete(DataChunk &chunk);
144 //! Write a single (sub-) column update to the WAL. Chunk must be a pair of (COL, ROW_ID).
145 //! The column_path vector is a *path* towards a column within the table
146 //! i.e. if we have a table with a single column S STRUCT(A INT, B INT)
147 //! and we update the validity mask of "S.B"
148 //! the column path is:
149 //! 0 (first column of table)
150 //! -> 1 (second subcolumn of struct)
151 //! -> 0 (first subcolumn of INT)
152 void WriteUpdate(DataChunk &chunk, const vector<column_t> &column_path);
153
154 //! Truncate the WAL to a previous size, and clear anything currently set in the writer
155 void Truncate(int64_t size);
156 //! Delete the WAL file on disk. The WAL should not be used after this point.
157 void Delete();
158 void Flush();
159
160 void WriteCheckpoint(block_id_t meta_block);
161
162protected:
163 AttachedDatabase &database;
164 unique_ptr<BufferedFileWriter> writer;
165 string wal_path;
166};
167
168} // namespace duckdb
169