1/*
2 * storage.h
3 *
4 * Copyright (C) 2009-2018 Aerospike, Inc.
5 *
6 * Portions may be licensed to Aerospike, Inc. under one or more contributor
7 * license agreements.
8 *
9 * This program is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU Affero General Public License as published by the Free
11 * Software Foundation, either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see http://www.gnu.org/licenses/
21 */
22
23#pragma once
24
25//==========================================================
26// Includes.
27//
28
29#include <stdbool.h>
30#include <stddef.h>
31#include <stdint.h>
32
33#include "citrusleaf/cf_digest.h"
34#include "citrusleaf/cf_queue.h"
35
36
37//==========================================================
38// Forward declarations.
39//
40
41struct as_bin_s;
42struct as_flat_record_s;
43struct as_index_s;
44struct as_namespace_s;
45struct as_partition_s;
46struct drv_ssd_s;
47
48
49//==========================================================
50// Typedefs & constants.
51//
52
53typedef enum {
54 AS_STORAGE_ENGINE_MEMORY = 0,
55 AS_STORAGE_ENGINE_SSD = 1,
56
57 AS_NUM_STORAGE_ENGINES
58} as_storage_type;
59
60#define AS_STORAGE_MAX_DEVICES 128 // maximum devices or files per namespace
61#define AS_STORAGE_MAX_DEVICE_SIZE (2L * 1024 * 1024 * 1024 * 1024) // 2Tb
62
63// Artificial limit on write-block-size, in case we ever move to an
64// SSD_HEADER_SIZE that's too big to be a write-block size limit.
65// MAX_WRITE_BLOCK_SIZE must be power of 2 and <= SSD_HEADER_SIZE.
66#define MAX_WRITE_BLOCK_SIZE (8 * 1024 * 1024)
67
68// Artificial limit on write-block-size, must be power of 2 and >= RBLOCK_SIZE.
69#define MIN_WRITE_BLOCK_SIZE (1024 * 1)
70
71typedef enum {
72 AS_ENCRYPTION_AES_128,
73 AS_ENCRYPTION_AES_256,
74
75 AS_ENCRYPTION_LAST_PLUS_1
76} as_encryption_method;
77
78typedef struct as_storage_rd_s {
79 struct as_index_s *r;
80 struct as_namespace_s *ns;
81
82 struct as_bin_s *bins;
83 uint16_t n_bins;
84
85 bool record_on_device;
86 bool ignore_record_on_device;
87
88 // Shortcuts for handling set name storage:
89 uint32_t set_name_len;
90 const char *set_name;
91
92 // Parameters used when handling key storage:
93 uint32_t key_size;
94 const uint8_t *key;
95
96 bool read_page_cache;
97 bool is_durable_delete; // enterprise only
98
99 // Only used by storage type AS_STORAGE_ENGINE_SSD:
100 struct as_flat_record_s *flat;
101 const uint8_t *flat_end;
102 const uint8_t *flat_bins;
103 uint16_t flat_n_bins;
104 uint8_t *read_buf;
105 struct drv_ssd_s *ssd;
106
107 // Flat storage format also used for pickled records sent via fabric:
108 bool keep_pickle;
109 uint32_t pickle_sz;
110 uint32_t orig_pickle_sz;
111 uint8_t *pickle;
112} as_storage_rd;
113
114typedef struct storage_device_stats_s {
115 uint64_t used_sz;
116 uint32_t n_free_wblocks;
117
118 uint32_t write_q_sz;
119 uint64_t n_writes;
120
121 uint32_t defrag_q_sz;
122 uint64_t n_defrag_reads;
123 uint64_t n_defrag_writes;
124
125 uint32_t shadow_write_q_sz;
126} storage_device_stats;
127
128
129//==========================================================
130// Public API.
131//
132
133//------------------------------------------------
134// Generic "base class" functions that call
135// through storage-engine "v-tables".
136//
137
138void as_storage_cfg_init(struct as_namespace_s *ns);
139void as_storage_init();
140void as_storage_load();
141void as_storage_start_tomb_raider();
142int as_storage_namespace_destroy(struct as_namespace_s *ns);
143
144int as_storage_record_destroy(struct as_namespace_s *ns, struct as_index_s *r); // not the counterpart of as_storage_record_create()
145
146// Start and finish an as_storage_rd usage cycle.
147int as_storage_record_create(struct as_namespace_s *ns, struct as_index_s *r, as_storage_rd *rd);
148int as_storage_record_open(struct as_namespace_s *ns, struct as_index_s *r, as_storage_rd *rd);
149int as_storage_record_close(as_storage_rd *rd);
150
151// Called within as_storage_rd usage cycle.
152int as_storage_record_load_n_bins(as_storage_rd *rd);
153int as_storage_record_load_bins(as_storage_rd *rd);
154bool as_storage_record_size_and_check(as_storage_rd *rd);
155int as_storage_record_write(as_storage_rd *rd);
156
157// Storage capacity monitoring.
158void as_storage_wait_for_defrag();
159bool as_storage_overloaded(struct as_namespace_s *ns); // returns true if write queue is too backed up
160bool as_storage_has_space(struct as_namespace_s *ns);
161void as_storage_defrag_sweep(struct as_namespace_s *ns);
162
163// Storage of generic data into device headers.
164void as_storage_load_regime(struct as_namespace_s *ns);
165void as_storage_load_roster_generation(struct as_namespace_s *ns);
166void as_storage_save_regime(struct as_namespace_s *ns);
167void as_storage_save_roster_generation(struct as_namespace_s *ns);
168void as_storage_load_pmeta(struct as_namespace_s *ns, struct as_partition_s *p);
169void as_storage_save_pmeta(struct as_namespace_s *ns, const struct as_partition_s *p);
170void as_storage_cache_pmeta(struct as_namespace_s *ns, const struct as_partition_s *p);
171void as_storage_flush_pmeta(struct as_namespace_s *ns, uint32_t start_pid, uint32_t n_partitions);
172
173// Statistics.
174int as_storage_stats(struct as_namespace_s *ns, int *available_pct, uint64_t *inuse_disk_bytes); // available percent is that of worst device
175void as_storage_device_stats(struct as_namespace_s *ns, uint32_t device_ix, storage_device_stats *stats);
176int as_storage_ticker_stats(struct as_namespace_s *ns); // prints SSD histograms to the info ticker
177int as_storage_histogram_clear_all(struct as_namespace_s *ns); // clears all SSD histograms
178
179// Get record storage metadata.
180uint32_t as_storage_record_size(const struct as_namespace_s *ns, const struct as_index_s *r);
181
182//------------------------------------------------
183// Generic functions that don't use "v-tables".
184//
185
186// Called within as_storage_rd usage cycle.
187uint64_t as_storage_record_get_n_bytes_memory(as_storage_rd *rd);
188void as_storage_record_adjust_mem_stats(as_storage_rd *rd, uint64_t start_bytes);
189void as_storage_record_drop_from_mem_stats(as_storage_rd *rd);
190void as_storage_record_get_set_name(as_storage_rd *rd);
191bool as_storage_record_get_key(as_storage_rd *rd);
192bool as_storage_record_get_pickle(as_storage_rd *rd);
193
194// Called only at shutdown to flush all device write-queues.
195void as_storage_shutdown(uint32_t instance);
196
197//------------------------------------------------
198// AS_STORAGE_ENGINE_MEMORY functions.
199//
200
201void as_storage_namespace_init_memory(struct as_namespace_s *ns);
202void as_storage_start_tomb_raider_memory(struct as_namespace_s *ns);
203int as_storage_namespace_destroy_memory(struct as_namespace_s *ns);
204
205int as_storage_record_write_memory(as_storage_rd *rd);
206
207void as_storage_load_pmeta_memory(struct as_namespace_s *ns, struct as_partition_s *p);
208
209int as_storage_stats_memory(struct as_namespace_s *ns, int *available_pct, uint64_t *used_disk_bytes);
210
211//------------------------------------------------
212// AS_STORAGE_ENGINE_SSD functions.
213//
214
215void as_storage_cfg_init_ssd(struct as_namespace_s *ns);
216void as_storage_namespace_init_ssd(struct as_namespace_s *ns);
217void as_storage_namespace_load_ssd(struct as_namespace_s *ns, cf_queue *complete_q);
218void as_storage_start_tomb_raider_ssd(struct as_namespace_s *ns);
219void as_storage_loading_records_ticker_ssd(); // called directly by as_storage_init()
220int as_storage_namespace_destroy_ssd(struct as_namespace_s *ns);
221
222int as_storage_record_destroy_ssd(struct as_namespace_s *ns, struct as_index_s *r);
223
224int as_storage_record_create_ssd(as_storage_rd *rd);
225int as_storage_record_open_ssd(as_storage_rd *rd);
226int as_storage_record_close_ssd(as_storage_rd *rd);
227
228int as_storage_record_load_n_bins_ssd(as_storage_rd *rd);
229int as_storage_record_load_bins_ssd(as_storage_rd *rd);
230bool as_storage_record_size_and_check_ssd(as_storage_rd *rd);
231int as_storage_record_write_ssd(as_storage_rd *rd);
232
233void as_storage_wait_for_defrag_ssd(struct as_namespace_s *ns);
234bool as_storage_overloaded_ssd(struct as_namespace_s *ns);
235bool as_storage_has_space_ssd(struct as_namespace_s *ns);
236void as_storage_defrag_sweep_ssd(struct as_namespace_s *ns);
237
238void as_storage_load_regime_ssd(struct as_namespace_s *ns);
239void as_storage_load_roster_generation_ssd(struct as_namespace_s *ns);
240void as_storage_save_regime_ssd(struct as_namespace_s *ns);
241void as_storage_save_roster_generation_ssd(struct as_namespace_s *ns);
242void as_storage_load_pmeta_ssd(struct as_namespace_s *ns, struct as_partition_s *p);
243void as_storage_save_pmeta_ssd(struct as_namespace_s *ns, const struct as_partition_s *p);
244void as_storage_cache_pmeta_ssd(struct as_namespace_s *ns, const struct as_partition_s *p);
245void as_storage_flush_pmeta_ssd(struct as_namespace_s *ns, uint32_t start_pid, uint32_t n_partitions);
246
247int as_storage_stats_ssd(struct as_namespace_s *ns, int *available_pct, uint64_t *used_disk_bytes);
248void as_storage_device_stats_ssd(struct as_namespace_s *ns, uint32_t device_ix, storage_device_stats *stats);
249int as_storage_ticker_stats_ssd(struct as_namespace_s *ns);
250int as_storage_histogram_clear_ssd(struct as_namespace_s *ns);
251
252uint32_t as_storage_record_size_ssd(const struct as_index_s *r);
253
254// Called by "base class" functions but not via table.
255bool as_storage_record_get_key_ssd(as_storage_rd *rd);
256bool as_storage_record_get_pickle_ssd(as_storage_rd *rd);
257void as_storage_shutdown_ssd(struct as_namespace_s *ns);
258