1
by brian
clean slate |
1 |
/******************************************************
|
2 |
Recovery
|
|
3 |
||
4 |
(c) 1997 Innobase Oy
|
|
5 |
||
6 |
Created 9/20/1997 Heikki Tuuri
|
|
7 |
*******************************************************/
|
|
8 |
||
9 |
#ifndef log0recv_h
|
|
10 |
#define log0recv_h
|
|
11 |
||
12 |
#include "univ.i" |
|
13 |
#include "ut0byte.h" |
|
14 |
#include "page0types.h" |
|
15 |
#include "hash0hash.h" |
|
16 |
#include "log0log.h" |
|
17 |
||
18 |
#ifdef UNIV_HOTBACKUP
|
|
19 |
extern ibool recv_replay_file_ops; |
|
20 |
#endif /* UNIV_HOTBACKUP */ |
|
21 |
||
22 |
/***********************************************************************
|
|
23 |
Reads the checkpoint info needed in hot backup. */
|
|
24 |
||
25 |
ibool
|
|
26 |
recv_read_cp_info_for_backup( |
|
27 |
/*=========================*/
|
|
28 |
/* out: TRUE if success */
|
|
29 |
byte* hdr, /* in: buffer containing the log group header */ |
|
30 |
dulint* lsn, /* out: checkpoint lsn */ |
|
31 |
ulint* offset, /* out: checkpoint offset in the log group */ |
|
32 |
ulint* fsp_limit,/* out: fsp limit of space 0, 1000000000 if the |
|
33 |
database is running with < version 3.23.50 of InnoDB */
|
|
34 |
dulint* cp_no, /* out: checkpoint number */ |
|
35 |
dulint* first_header_lsn); |
|
36 |
/* out: lsn of of the start of the first log file */
|
|
37 |
/***********************************************************************
|
|
38 |
Scans the log segment and n_bytes_scanned is set to the length of valid
|
|
39 |
log scanned. */
|
|
40 |
||
41 |
void
|
|
42 |
recv_scan_log_seg_for_backup( |
|
43 |
/*=========================*/
|
|
44 |
byte* buf, /* in: buffer containing log data */ |
|
45 |
ulint buf_len, /* in: data length in that buffer */ |
|
46 |
dulint* scanned_lsn, /* in/out: lsn of buffer start, |
|
47 |
we return scanned lsn */
|
|
48 |
ulint* scanned_checkpoint_no, |
|
49 |
/* in/out: 4 lowest bytes of the
|
|
50 |
highest scanned checkpoint number so
|
|
51 |
far */
|
|
52 |
ulint* n_bytes_scanned);/* out: how much we were able to |
|
53 |
scan, smaller than buf_len if log
|
|
54 |
data ended here */
|
|
55 |
/***********************************************************************
|
|
56 |
Returns TRUE if recovery is currently running. */
|
|
57 |
UNIV_INLINE
|
|
58 |
ibool
|
|
59 |
recv_recovery_is_on(void); |
|
60 |
/*=====================*/
|
|
61 |
/***********************************************************************
|
|
62 |
Returns TRUE if recovery from backup is currently running. */
|
|
63 |
UNIV_INLINE
|
|
64 |
ibool
|
|
65 |
recv_recovery_from_backup_is_on(void); |
|
66 |
/*=================================*/
|
|
67 |
/****************************************************************************
|
|
68 |
Applies the hashed log records to the page, if the page lsn is less than the
|
|
69 |
lsn of a log record. This can be called when a buffer page has just been
|
|
70 |
read in, or also for a page already in the buffer pool. */
|
|
71 |
||
72 |
void
|
|
73 |
recv_recover_page( |
|
74 |
/*==============*/
|
|
75 |
ibool recover_backup, /* in: TRUE if we are recovering a backup |
|
76 |
page: then we do not acquire any latches
|
|
77 |
since the page was read in outside the
|
|
78 |
buffer pool */
|
|
79 |
ibool just_read_in, /* in: TRUE if the i/o-handler calls this for |
|
80 |
a freshly read page */
|
|
81 |
page_t* page, /* in: buffer page */ |
|
82 |
ulint space, /* in: space id */ |
|
83 |
ulint page_no); /* in: page number */ |
|
84 |
/************************************************************
|
|
85 |
Recovers from a checkpoint. When this function returns, the database is able
|
|
86 |
to start processing of new user transactions, but the function
|
|
87 |
recv_recovery_from_checkpoint_finish should be called later to complete
|
|
88 |
the recovery and free the resources used in it. */
|
|
89 |
||
90 |
ulint
|
|
91 |
recv_recovery_from_checkpoint_start( |
|
92 |
/*================================*/
|
|
93 |
/* out: error code or DB_SUCCESS */
|
|
94 |
ulint type, /* in: LOG_CHECKPOINT or LOG_ARCHIVE */ |
|
95 |
dulint limit_lsn, /* in: recover up to this lsn if possible */ |
|
96 |
dulint min_flushed_lsn,/* in: min flushed lsn from data files */ |
|
97 |
dulint max_flushed_lsn);/* in: max flushed lsn from data files */ |
|
98 |
/************************************************************
|
|
99 |
Completes recovery from a checkpoint. */
|
|
100 |
||
101 |
void
|
|
102 |
recv_recovery_from_checkpoint_finish(void); |
|
103 |
/*======================================*/
|
|
104 |
/***********************************************************
|
|
105 |
Scans log from a buffer and stores new log data to the parsing buffer. Parses
|
|
106 |
and hashes the log records if new data found. */
|
|
107 |
||
108 |
ibool
|
|
109 |
recv_scan_log_recs( |
|
110 |
/*===============*/
|
|
111 |
/* out: TRUE if limit_lsn has been reached, or
|
|
112 |
not able to scan any more in this log group */
|
|
113 |
ibool apply_automatically,/* in: TRUE if we want this function to |
|
114 |
apply log records automatically when the
|
|
115 |
hash table becomes full; in the hot backup tool
|
|
116 |
the tool does the applying, not this
|
|
117 |
function */
|
|
118 |
ulint available_memory,/* in: we let the hash table of recs to grow |
|
119 |
to this size, at the maximum */
|
|
120 |
ibool store_to_hash, /* in: TRUE if the records should be stored |
|
121 |
to the hash table; this is set to FALSE if just
|
|
122 |
debug checking is needed */
|
|
123 |
byte* buf, /* in: buffer containing a log segment or |
|
124 |
garbage */
|
|
125 |
ulint len, /* in: buffer length */ |
|
126 |
dulint start_lsn, /* in: buffer start lsn */ |
|
127 |
dulint* contiguous_lsn, /* in/out: it is known that all log groups |
|
128 |
contain contiguous log data up to this lsn */
|
|
129 |
dulint* group_scanned_lsn);/* out: scanning succeeded up to this lsn */ |
|
130 |
/**********************************************************
|
|
131 |
Resets the logs. The contents of log files will be lost! */
|
|
132 |
||
133 |
void
|
|
134 |
recv_reset_logs( |
|
135 |
/*============*/
|
|
136 |
dulint lsn, /* in: reset to this lsn rounded up to |
|
137 |
be divisible by OS_FILE_LOG_BLOCK_SIZE,
|
|
138 |
after which we add LOG_BLOCK_HDR_SIZE */
|
|
139 |
#ifdef UNIV_LOG_ARCHIVE
|
|
140 |
ulint arch_log_no, /* in: next archived log file number */ |
|
141 |
#endif /* UNIV_LOG_ARCHIVE */ |
|
142 |
ibool new_logs_created);/* in: TRUE if resetting logs is done |
|
143 |
at the log creation; FALSE if it is done
|
|
144 |
after archive recovery */
|
|
145 |
#ifdef UNIV_HOTBACKUP
|
|
146 |
/**********************************************************
|
|
147 |
Creates new log files after a backup has been restored. */
|
|
148 |
||
149 |
void
|
|
150 |
recv_reset_log_files_for_backup( |
|
151 |
/*============================*/
|
|
152 |
const char* log_dir, /* in: log file directory path */ |
|
153 |
ulint n_log_files, /* in: number of log files */ |
|
154 |
ulint log_file_size, /* in: log file size */ |
|
155 |
dulint lsn); /* in: new start lsn, must be |
|
156 |
divisible by OS_FILE_LOG_BLOCK_SIZE */
|
|
157 |
#endif /* UNIV_HOTBACKUP */ |
|
158 |
/************************************************************
|
|
159 |
Creates the recovery system. */
|
|
160 |
||
161 |
void
|
|
162 |
recv_sys_create(void); |
|
163 |
/*=================*/
|
|
164 |
/************************************************************
|
|
165 |
Inits the recovery system for a recovery operation. */
|
|
166 |
||
167 |
void
|
|
168 |
recv_sys_init( |
|
169 |
/*==========*/
|
|
170 |
ibool recover_from_backup, /* in: TRUE if this is called |
|
171 |
to recover from a hot backup */
|
|
172 |
ulint available_memory); /* in: available memory in bytes */ |
|
173 |
/***********************************************************************
|
|
174 |
Empties the hash table of stored log records, applying them to appropriate
|
|
175 |
pages. */
|
|
176 |
||
177 |
void
|
|
178 |
recv_apply_hashed_log_recs( |
|
179 |
/*=======================*/
|
|
180 |
ibool allow_ibuf); /* in: if TRUE, also ibuf operations are |
|
181 |
allowed during the application; if FALSE,
|
|
182 |
no ibuf operations are allowed, and after
|
|
183 |
the application all file pages are flushed to
|
|
184 |
disk and invalidated in buffer pool: this
|
|
185 |
alternative means that no new log records
|
|
186 |
can be generated during the application */
|
|
187 |
#ifdef UNIV_HOTBACKUP
|
|
188 |
/***********************************************************************
|
|
189 |
Applies log records in the hash table to a backup. */
|
|
190 |
||
191 |
void
|
|
192 |
recv_apply_log_recs_for_backup(void); |
|
193 |
/*================================*/
|
|
194 |
#endif
|
|
195 |
#ifdef UNIV_LOG_ARCHIVE
|
|
196 |
/************************************************************
|
|
197 |
Recovers from archived log files, and also from log files, if they exist. */
|
|
198 |
||
199 |
ulint
|
|
200 |
recv_recovery_from_archive_start( |
|
201 |
/*=============================*/
|
|
202 |
/* out: error code or DB_SUCCESS */
|
|
203 |
dulint min_flushed_lsn,/* in: min flushed lsn field from the |
|
204 |
data files */
|
|
205 |
dulint limit_lsn, /* in: recover up to this lsn if possible */ |
|
206 |
ulint first_log_no); /* in: number of the first archived log file |
|
207 |
to use in the recovery; the file will be
|
|
208 |
searched from INNOBASE_LOG_ARCH_DIR specified
|
|
209 |
in server config file */
|
|
210 |
/************************************************************
|
|
211 |
Completes recovery from archive. */
|
|
212 |
||
213 |
void
|
|
214 |
recv_recovery_from_archive_finish(void); |
|
215 |
/*===================================*/
|
|
216 |
#endif /* UNIV_LOG_ARCHIVE */ |
|
217 |
||
218 |
/* Block of log record data */
|
|
219 |
typedef struct recv_data_struct recv_data_t; |
|
220 |
struct recv_data_struct{ |
|
221 |
recv_data_t* next; /* pointer to the next block or NULL */ |
|
222 |
/* the log record data is stored physically
|
|
223 |
immediately after this struct, max amount
|
|
224 |
RECV_DATA_BLOCK_SIZE bytes of it */
|
|
225 |
};
|
|
226 |
||
227 |
/* Stored log record struct */
|
|
228 |
typedef struct recv_struct recv_t; |
|
229 |
struct recv_struct{ |
|
230 |
byte type; /* log record type */ |
|
231 |
ulint len; /* log record body length in bytes */ |
|
232 |
recv_data_t* data; /* chain of blocks containing the log record |
|
233 |
body */
|
|
234 |
dulint start_lsn;/* start lsn of the log segment written by |
|
235 |
the mtr which generated this log record: NOTE
|
|
236 |
that this is not necessarily the start lsn of
|
|
237 |
this log record */
|
|
238 |
dulint end_lsn;/* end lsn of the log segment written by |
|
239 |
the mtr which generated this log record: NOTE
|
|
240 |
that this is not necessarily the end lsn of
|
|
241 |
this log record */
|
|
242 |
UT_LIST_NODE_T(recv_t) |
|
243 |
rec_list;/* list of log records for this page */ |
|
244 |
};
|
|
245 |
||
246 |
/* Hashed page file address struct */
|
|
247 |
typedef struct recv_addr_struct recv_addr_t; |
|
248 |
struct recv_addr_struct{ |
|
249 |
ulint state; /* RECV_NOT_PROCESSED, RECV_BEING_PROCESSED, |
|
250 |
or RECV_PROCESSED */
|
|
251 |
ulint space; /* space id */ |
|
252 |
ulint page_no;/* page number */ |
|
253 |
UT_LIST_BASE_NODE_T(recv_t) |
|
254 |
rec_list;/* list of log records for this page */ |
|
255 |
hash_node_t addr_hash; |
|
256 |
};
|
|
257 |
||
258 |
/* Recovery system data structure */
|
|
259 |
typedef struct recv_sys_struct recv_sys_t; |
|
260 |
struct recv_sys_struct{ |
|
261 |
mutex_t mutex; /* mutex protecting the fields apply_log_recs, |
|
262 |
n_addrs, and the state field in each recv_addr
|
|
263 |
struct */
|
|
264 |
ibool apply_log_recs; |
|
265 |
/* this is TRUE when log rec application to
|
|
266 |
pages is allowed; this flag tells the
|
|
267 |
i/o-handler if it should do log record
|
|
268 |
application */
|
|
269 |
ibool apply_batch_on; |
|
270 |
/* this is TRUE when a log rec application
|
|
271 |
batch is running */
|
|
272 |
dulint lsn; /* log sequence number */ |
|
273 |
ulint last_log_buf_size; |
|
274 |
/* size of the log buffer when the database
|
|
275 |
last time wrote to the log */
|
|
276 |
byte* last_block; |
|
277 |
/* possible incomplete last recovered log
|
|
278 |
block */
|
|
279 |
byte* last_block_buf_start; |
|
280 |
/* the nonaligned start address of the
|
|
281 |
preceding buffer */
|
|
282 |
byte* buf; /* buffer for parsing log records */ |
|
283 |
ulint len; /* amount of data in buf */ |
|
284 |
dulint parse_start_lsn; |
|
285 |
/* this is the lsn from which we were able to
|
|
286 |
start parsing log records and adding them to
|
|
287 |
the hash table; ut_dulint_zero if a suitable
|
|
288 |
start point not found yet */
|
|
289 |
dulint scanned_lsn; |
|
290 |
/* the log data has been scanned up to this
|
|
291 |
lsn */
|
|
292 |
ulint scanned_checkpoint_no; |
|
293 |
/* the log data has been scanned up to this
|
|
294 |
checkpoint number (lowest 4 bytes) */
|
|
295 |
ulint recovered_offset; |
|
296 |
/* start offset of non-parsed log records in
|
|
297 |
buf */
|
|
298 |
dulint recovered_lsn; |
|
299 |
/* the log records have been parsed up to
|
|
300 |
this lsn */
|
|
301 |
dulint limit_lsn;/* recovery should be made at most up to this |
|
302 |
lsn */
|
|
303 |
ibool found_corrupt_log; |
|
304 |
/* this is set to TRUE if we during log
|
|
305 |
scan find a corrupt log block, or a corrupt
|
|
306 |
log record, or there is a log parsing
|
|
307 |
buffer overflow */
|
|
308 |
log_group_t* archive_group; |
|
309 |
/* in archive recovery: the log group whose
|
|
310 |
archive is read */
|
|
311 |
mem_heap_t* heap; /* memory heap of log records and file |
|
312 |
addresses*/
|
|
313 |
hash_table_t* addr_hash;/* hash table of file addresses of pages */ |
|
314 |
ulint n_addrs;/* number of not processed hashed file |
|
315 |
addresses in the hash table */
|
|
316 |
};
|
|
317 |
||
318 |
extern recv_sys_t* recv_sys; |
|
319 |
extern ibool recv_recovery_on; |
|
320 |
extern ibool recv_no_ibuf_operations; |
|
321 |
extern ibool recv_needed_recovery; |
|
322 |
||
323 |
extern ibool recv_lsn_checks_on; |
|
324 |
#ifdef UNIV_HOTBACKUP
|
|
325 |
extern ibool recv_is_making_a_backup; |
|
326 |
#endif /* UNIV_HOTBACKUP */ |
|
327 |
extern ulint recv_max_parsed_page_no; |
|
328 |
||
329 |
/* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
|
|
330 |
times! */
|
|
331 |
#define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024)
|
|
332 |
||
333 |
/* Size of block reads when the log groups are scanned forward to do a
|
|
334 |
roll-forward */
|
|
335 |
#define RECV_SCAN_SIZE (4 * UNIV_PAGE_SIZE)
|
|
336 |
||
337 |
/* States of recv_addr_struct */
|
|
338 |
#define RECV_NOT_PROCESSED 71
|
|
339 |
#define RECV_BEING_READ 72
|
|
340 |
#define RECV_BEING_PROCESSED 73
|
|
341 |
#define RECV_PROCESSED 74
|
|
342 |
||
343 |
extern ulint recv_n_pool_free_frames; |
|
344 |
||
345 |
#ifndef UNIV_NONINL
|
|
346 |
#include "log0recv.ic" |
|
347 |
#endif
|
|
348 |
||
349 |
#endif
|