1 | /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
2 | // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: |
3 | #ident "$Id$" |
4 | /*====== |
5 | This file is part of PerconaFT. |
6 | |
7 | |
8 | Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. |
9 | |
10 | PerconaFT is free software: you can redistribute it and/or modify |
11 | it under the terms of the GNU General Public License, version 2, |
12 | as published by the Free Software Foundation. |
13 | |
14 | PerconaFT is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | GNU General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU General Public License |
20 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
21 | |
22 | ---------------------------------------- |
23 | |
24 | PerconaFT is free software: you can redistribute it and/or modify |
25 | it under the terms of the GNU Affero General Public License, version 3, |
26 | as published by the Free Software Foundation. |
27 | |
28 | PerconaFT is distributed in the hope that it will be useful, |
29 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
31 | GNU Affero General Public License for more details. |
32 | |
33 | You should have received a copy of the GNU Affero General Public License |
34 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
35 | ======= */ |
36 | |
37 | #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." |
38 | |
39 | #pragma once |
40 | |
41 | #include "ft/serialize/block_table.h" |
42 | #include "ft/serialize/ft_layout_version.h" |
43 | #include "ft/txn/txn.h" |
44 | |
45 | typedef struct tokulogger *TOKULOGGER; |
46 | |
47 | enum { |
48 | TOKU_LOG_VERSION_1 = 1, |
49 | TOKU_LOG_VERSION_2 = 2, |
50 | //After 2 we linked the log version to the FT_LAYOUT VERSION. |
51 | //So it went from 2 to 13 (3-12 do not exist) |
52 | TOKU_LOG_VERSION_24 = 24, |
53 | TOKU_LOG_VERSION_25 = 25, // change rollinclude rollback log entry |
54 | TOKU_LOG_VERSION_26 = 26, // no change from 25 |
55 | TOKU_LOG_VERSION_27 = 27, // no change from 26 |
56 | TOKU_LOG_VERSION_28 = 28, // no change from 27 |
57 | TOKU_LOG_VERSION_29 = 29, // no change from 28 |
58 | TOKU_LOG_VERSION = FT_LAYOUT_VERSION, |
59 | TOKU_LOG_MIN_SUPPORTED_VERSION = FT_LAYOUT_MIN_SUPPORTED_VERSION, |
60 | }; |
61 | |
62 | int toku_logger_create (TOKULOGGER *resultp); |
63 | int toku_logger_open (const char *directory, TOKULOGGER logger); |
64 | int toku_logger_open_with_last_xid(const char *directory, TOKULOGGER logger, TXNID last_xid); |
65 | void toku_logger_shutdown(TOKULOGGER logger); |
66 | int toku_logger_close(TOKULOGGER *loggerp); |
67 | void toku_logger_initialize_rollback_cache(TOKULOGGER logger, struct ft *ft); |
68 | int toku_logger_open_rollback(TOKULOGGER logger, struct cachetable *ct, bool create); |
69 | void toku_logger_close_rollback(TOKULOGGER logger); |
70 | void toku_logger_close_rollback_check_empty(TOKULOGGER logger, bool clean_shutdown); |
71 | bool toku_logger_rollback_is_open (TOKULOGGER); // return true iff the rollback is open. |
72 | |
73 | void toku_logger_fsync (TOKULOGGER logger); |
74 | void toku_logger_fsync_if_lsn_not_fsynced(TOKULOGGER logger, LSN lsn); |
75 | int toku_logger_is_open(TOKULOGGER logger); |
76 | void toku_logger_set_cachetable (TOKULOGGER logger, struct cachetable *ct); |
77 | int toku_logger_set_lg_max(TOKULOGGER logger, uint32_t lg_max); |
78 | int toku_logger_get_lg_max(TOKULOGGER logger, uint32_t *lg_maxp); |
79 | int toku_logger_set_lg_bsize(TOKULOGGER logger, uint32_t bsize); |
80 | |
81 | void toku_logger_write_log_files (TOKULOGGER logger, bool write_log_files); |
82 | void toku_logger_trim_log_files(TOKULOGGER logger, bool trim_log_files); |
83 | bool toku_logger_txns_exist(TOKULOGGER logger); |
84 | |
85 | // Restart the logger. This function is used by recovery to really start |
86 | // logging. |
87 | // Effects: Flush the current log buffer, reset the logger's lastlsn, and |
88 | // open a new log file. |
89 | // Returns: 0 if success |
90 | int toku_logger_restart(TOKULOGGER logger, LSN lastlsn); |
91 | |
92 | // Maybe trim the log entries from the log that are older than the given LSN |
93 | // Effect: find all of the log files whose largest LSN is smaller than the |
94 | // given LSN and delete them. |
95 | void toku_logger_maybe_trim_log(TOKULOGGER logger, LSN oldest_open_lsn); |
96 | |
97 | // At the ft layer, a FILENUM uniquely identifies an open file. |
98 | struct FILENUM { |
99 | uint32_t fileid; |
100 | }; |
101 | static const FILENUM FILENUM_NONE = { .fileid = UINT32_MAX }; |
102 | |
103 | struct FILENUMS { |
104 | uint32_t num; |
105 | FILENUM *filenums; |
106 | }; |
107 | |
108 | void toku_logger_log_fcreate(TOKUTXN txn, const char *fname, FILENUM filenum, uint32_t mode, uint32_t flags, uint32_t nodesize, uint32_t basementnodesize, enum toku_compression_method compression_method); |
109 | void toku_logger_log_fdelete(TOKUTXN txn, FILENUM filenum); |
110 | void toku_logger_log_fopen(TOKUTXN txn, const char * fname, FILENUM filenum, uint32_t treeflags); |
111 | |
112 | // the log generation code requires a typedef if we want to pass by pointer |
113 | typedef TOKU_XA_XID *XIDP; |
114 | |
115 | int toku_fread_uint8_t (FILE *f, uint8_t *v, struct x1764 *mm, uint32_t *len); |
116 | int toku_fread_uint32_t_nocrclen (FILE *f, uint32_t *v); |
117 | int toku_fread_uint32_t (FILE *f, uint32_t *v, struct x1764 *checksum, uint32_t *len); |
118 | int toku_fread_uint64_t (FILE *f, uint64_t *v, struct x1764 *checksum, uint32_t *len); |
119 | int toku_fread_bool (FILE *f, bool *v, struct x1764 *checksum, uint32_t *len); |
120 | int toku_fread_LSN (FILE *f, LSN *lsn, struct x1764 *checksum, uint32_t *len); |
121 | int toku_fread_BLOCKNUM (FILE *f, BLOCKNUM *lsn, struct x1764 *checksum, uint32_t *len); |
122 | int toku_fread_FILENUM (FILE *f, FILENUM *filenum, struct x1764 *checksum, uint32_t *len); |
123 | int toku_fread_TXNID (FILE *f, TXNID *txnid, struct x1764 *checksum, uint32_t *len); |
124 | int toku_fread_TXNID_PAIR (FILE *f, TXNID_PAIR *txnid, struct x1764 *checksum, uint32_t *len); |
125 | int toku_fread_XIDP (FILE *f, XIDP *xidp, struct x1764 *checksum, uint32_t *len); |
126 | int toku_fread_BYTESTRING (FILE *f, BYTESTRING *bs, struct x1764 *checksum, uint32_t *len); |
127 | int toku_fread_FILENUMS (FILE *f, FILENUMS *fs, struct x1764 *checksum, uint32_t *len); |
128 | |
129 | int toku_logprint_LSN (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format __attribute__((__unused__))); |
130 | int toku_logprint_TXNID (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format __attribute__((__unused__))); |
131 | int toku_logprint_TXNID_PAIR (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format __attribute__((__unused__))); |
132 | int toku_logprint_XIDP (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format __attribute__((__unused__))); |
133 | int toku_logprint_uint8_t (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format); |
134 | int toku_logprint_uint32_t (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format); |
135 | int toku_logprint_BLOCKNUM (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format); |
136 | int toku_logprint_uint64_t (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format); |
137 | int toku_logprint_bool (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format __attribute__((__unused__))); |
138 | void toku_print_BYTESTRING (FILE *outf, uint32_t len, char *data); |
139 | int toku_logprint_BYTESTRING (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format __attribute__((__unused__))); |
140 | int toku_logprint_FILENUM (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format); |
141 | int toku_logprint_FILENUMS (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, uint32_t *len, const char *format); |
142 | int toku_read_and_print_logmagic (FILE *f, uint32_t *versionp); |
143 | int toku_read_logmagic (FILE *f, uint32_t *versionp); |
144 | |
145 | TXNID_PAIR toku_txn_get_txnid (TOKUTXN txn); |
146 | LSN toku_logger_last_lsn(TOKULOGGER logger); |
147 | TOKULOGGER toku_txn_logger (TOKUTXN txn); |
148 | |
149 | void toku_txnid2txn (TOKULOGGER logger, TXNID_PAIR txnid, TOKUTXN *result); |
150 | |
151 | int toku_logger_log_archive (TOKULOGGER logger, char ***logs_p, int flags); |
152 | |
153 | TOKUTXN toku_logger_txn_parent (TOKUTXN txn); |
154 | void toku_logger_note_checkpoint(TOKULOGGER logger, LSN lsn); |
155 | |
156 | void toku_logger_make_space_in_inbuf (TOKULOGGER logger, int n_bytes_needed); |
157 | |
158 | int toku_logger_write_inbuf (TOKULOGGER logger); |
159 | // Effect: Write the buffered data (from the inbuf) to a file. No fsync, however. |
160 | // As a side effect, the inbuf will be made empty. |
161 | // Return 0 on success, otherwise return an error number. |
162 | // Requires: The inbuf lock is currently held, and the outbuf lock is not held. |
163 | // Upon return, the inbuf lock will be held, and the outbuf lock is not held. |
164 | // However, no side effects should have been made to the logger. The lock was acquired simply to determine that the buffer will overflow if we try to put something into it. |
165 | // The inbuf lock will be released, so the operations before and after this function call will not be atomic. |
166 | // Rationale: When the buffer becomes nearly full, call this function so that more can be put in. |
167 | // Implementation note: Since the output lock is acquired first, we must release the input lock, and then grab both in the right order. |
168 | |
169 | void toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync, bool holds_input_lock); |
170 | // Effect: If fsync is nonzero, then make sure that the log is flushed and synced at least up to lsn. |
171 | // Entry: Holds input lock iff 'holds_input_lock'. |
172 | // Exit: Holds no locks. |
173 | |
174 | // Discussion: How does the logger work: |
175 | // The logger has two buffers: an inbuf and an outbuf. |
176 | // There are two locks, called the inlock, and the outlock. To write, both locks must be held, and the outlock is acquired first. |
177 | // Roughly speaking, the inbuf is used to accumulate logged data, and the outbuf is used to write to disk. |
178 | // When something is to be logged we do the following: |
179 | // acquire the inlock. |
180 | // Make sure there is space in the inbuf for the logentry. (We know the size of the logentry in advance): |
181 | // if the inbuf doesn't have enough space then |
182 | // release the inlock |
183 | // acquire the outlock |
184 | // acquire the inlock |
185 | // it's possible that some other thread made space. |
186 | // if there still isn't space |
187 | // swap the inbuf and the outbuf |
188 | // release the inlock |
189 | // write the outbuf |
190 | // acquire the inlock |
191 | // release the outlock |
192 | // if the inbuf is still too small, then increase the size of the inbuf |
193 | // Increment the LSN and fill the inbuf. |
194 | // If fsync is required then |
195 | // release the inlock |
196 | // acquire the outlock |
197 | // acquire the inlock |
198 | // if the LSN has been flushed and fsynced (if so we are done. Some other thread did the flush.) |
199 | // release the locks |
200 | // if the LSN has been flushed but not fsynced up to the LSN: |
201 | // release the inlock |
202 | // fsync |
203 | // release the outlock |
204 | // otherwise: |
205 | // swap the outbuf and the inbuf |
206 | // release the inlock |
207 | // write the outbuf |
208 | // fsync |
209 | // release the outlock |
210 | |
211 | void toku_logger_get_status(TOKULOGGER logger, LOGGER_STATUS s); |
212 | |
213 | int toku_get_version_of_logs_on_disk(const char *log_dir, bool *found_any_logs, uint32_t *version_found); |
214 | |
215 | struct txn_manager *toku_logger_get_txn_manager(TOKULOGGER logger); |
216 | |
217 | // For serialize / deserialize |
218 | |
219 | #include "ft/serialize/wbuf.h" |
220 | |
221 | static inline void wbuf_nocrc_FILENUM(struct wbuf *wb, FILENUM fileid) { |
222 | wbuf_nocrc_uint(wb, fileid.fileid); |
223 | } |
224 | |
225 | static inline void wbuf_FILENUM(struct wbuf *wb, FILENUM fileid) { |
226 | wbuf_uint(wb, fileid.fileid); |
227 | } |
228 | |
229 | static inline void wbuf_nocrc_FILENUMS(struct wbuf *wb, FILENUMS v) { |
230 | wbuf_nocrc_uint(wb, v.num); |
231 | for (uint32_t i = 0; i < v.num; i++) { |
232 | wbuf_nocrc_FILENUM(wb, v.filenums[i]); |
233 | } |
234 | } |
235 | |
236 | static inline void wbuf_FILENUMS(struct wbuf *wb, FILENUMS v) { |
237 | wbuf_uint(wb, v.num); |
238 | for (uint32_t i = 0; i < v.num; i++) { |
239 | wbuf_FILENUM(wb, v.filenums[i]); |
240 | } |
241 | } |
242 | |
243 | static inline void wbuf_nocrc_XIDP (struct wbuf *w, TOKU_XA_XID *xid) { |
244 | wbuf_nocrc_uint32_t(w, xid->formatID); |
245 | wbuf_nocrc_uint8_t(w, xid->gtrid_length); |
246 | wbuf_nocrc_uint8_t(w, xid->bqual_length); |
247 | wbuf_nocrc_literal_bytes(w, xid->data, xid->gtrid_length+xid->bqual_length); |
248 | } |
249 | |
250 | #include "ft/serialize/rbuf.h" |
251 | |
252 | static inline void rbuf_FILENUM(struct rbuf *rb, FILENUM *filenum) { |
253 | filenum->fileid = rbuf_int(rb); |
254 | } |
255 | static inline void rbuf_ma_FILENUM(struct rbuf *rb, memarena *UU(ma), FILENUM *filenum) { |
256 | rbuf_FILENUM(rb, filenum); |
257 | } |
258 | |
259 | static inline void rbuf_FILENUMS(struct rbuf *rb, FILENUMS *filenums) { |
260 | filenums->num = rbuf_int(rb); |
261 | XMALLOC_N(filenums->num, filenums->filenums); |
262 | for (uint32_t i = 0; i < filenums->num; i++) { |
263 | rbuf_FILENUM(rb, &(filenums->filenums[i])); |
264 | } |
265 | } |
266 | |
267 | static inline void rbuf_ma_FILENUMS(struct rbuf *rb, memarena *ma, FILENUMS *filenums) { |
268 | rbuf_ma_uint32_t(rb, ma, &(filenums->num)); |
269 | filenums->filenums = (FILENUM *) ma->malloc_from_arena(filenums->num * sizeof(FILENUM)); |
270 | assert(filenums->filenums != NULL); |
271 | for (uint32_t i = 0; i < filenums->num; i++) { |
272 | rbuf_ma_FILENUM(rb, ma, &(filenums->filenums[i])); |
273 | } |
274 | } |
275 | |