1 /*****************************************************************************
2 
3 Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8 
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation.  The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License, version 2.0, for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24 
25 *****************************************************************************/
26 
27 /**************************************************//**
28 @file include/log0recv.h
29 Recovery
30 
31 Created 9/20/1997 Heikki Tuuri
32 *******************************************************/
33 
34 #ifndef log0recv_h
35 #define log0recv_h
36 
37 #include "univ.i"
38 #include "ut0byte.h"
39 #include "buf0types.h"
40 #include "hash0hash.h"
41 #include "log0log.h"
42 #include <list>
43 
44 /******************************************************//**
45 Checks the 4-byte checksum to the trailer checksum field of a log
46 block.  We also accept a log block in the old format before
47 InnoDB-3.23.52 where the checksum field contains the log block number.
48 @return TRUE if ok, or if the log block may be in the format of InnoDB
49 version predating 3.23.52 */
50 UNIV_INTERN
51 ibool
52 log_block_checksum_is_ok_or_old_format(
53 /*===================================*/
54 	const byte*	block);	/*!< in: pointer to a log block */
55 
56 /*******************************************************//**
57 Calculates the new value for lsn when more data is added to the log. */
58 UNIV_INTERN
59 ib_uint64_t
60 recv_calc_lsn_on_data_add(
61 /*======================*/
62 	lsn_t		lsn,	/*!< in: old lsn */
63 	ib_uint64_t	len);	/*!< in: this many bytes of data is
64 				added, log block headers not included */
65 
66 #ifdef UNIV_HOTBACKUP
67 extern ibool	recv_replay_file_ops;
68 
69 /*******************************************************************//**
70 Reads the checkpoint info needed in hot backup.
71 @return	TRUE if success */
72 UNIV_INTERN
73 ibool
74 recv_read_checkpoint_info_for_backup(
75 /*=================================*/
76 	const byte*	hdr,	/*!< in: buffer containing the log group
77 				header */
78 	lsn_t*		lsn,	/*!< out: checkpoint lsn */
79 	lsn_t*		offset,	/*!< out: checkpoint offset in the log group */
80 	lsn_t*		cp_no,	/*!< out: checkpoint number */
81 	lsn_t*		first_header_lsn)
82 				/*!< out: lsn of of the start of the
83 				first log file */
84 	MY_ATTRIBUTE((nonnull));
85 /*******************************************************************//**
86 Scans the log segment and n_bytes_scanned is set to the length of valid
87 log scanned. */
88 UNIV_INTERN
89 void
90 recv_scan_log_seg_for_backup(
91 /*=========================*/
92 	byte*		buf,		/*!< in: buffer containing log data */
93 	ulint		buf_len,	/*!< in: data length in that buffer */
94 	lsn_t*		scanned_lsn,	/*!< in/out: lsn of buffer start,
95 					we return scanned lsn */
96 	ulint*		scanned_checkpoint_no,
97 					/*!< in/out: 4 lowest bytes of the
98 					highest scanned checkpoint number so
99 					far */
100 	ulint*		n_bytes_scanned);/*!< out: how much we were able to
101 					scan, smaller than buf_len if log
102 					data ended here */
103 #endif /* UNIV_HOTBACKUP */
104 /*******************************************************************//**
105 Returns TRUE if recovery is currently running.
106 @return	recv_recovery_on */
107 UNIV_INLINE
108 ibool
109 recv_recovery_is_on(void);
110 /*=====================*/
111 /************************************************************************//**
112 Applies the hashed log records to the page, if the page lsn is less than the
113 lsn of a log record. This can be called when a buffer page has just been
114 read in, or also for a page already in the buffer pool. */
115 UNIV_INTERN
116 void
117 recv_recover_page_func(
118 /*===================*/
119 #ifndef UNIV_HOTBACKUP
120 	ibool		just_read_in,
121 				/*!< in: TRUE if the i/o handler calls
122 				this for a freshly read page */
123 #endif /* !UNIV_HOTBACKUP */
124 	buf_block_t*	block);	/*!< in/out: buffer block */
125 #ifndef UNIV_HOTBACKUP
126 /** Wrapper for recv_recover_page_func().
127 Applies the hashed log records to the page, if the page lsn is less than the
128 lsn of a log record. This can be called when a buffer page has just been
129 read in, or also for a page already in the buffer pool.
130 @param jri	in: TRUE if just read in (the i/o handler calls this for
131 a freshly read page)
132 @param block	in/out: the buffer block
133 */
134 # define recv_recover_page(jri, block)	recv_recover_page_func(jri, block)
135 #else /* !UNIV_HOTBACKUP */
136 /** Wrapper for recv_recover_page_func().
137 Applies the hashed log records to the page, if the page lsn is less than the
138 lsn of a log record. This can be called when a buffer page has just been
139 read in, or also for a page already in the buffer pool.
140 @param jri	in: TRUE if just read in (the i/o handler calls this for
141 a freshly read page)
142 @param block	in/out: the buffer block
143 */
144 # define recv_recover_page(jri, block)	recv_recover_page_func(block)
145 #endif /* !UNIV_HOTBACKUP */
146 /********************************************************//**
147 Recovers from a checkpoint. When this function returns, the database is able
148 to start processing of new user transactions, but the function
149 recv_recovery_from_checkpoint_finish should be called later to complete
150 the recovery and free the resources used in it.
151 @return	error code or DB_SUCCESS */
152 UNIV_INTERN
153 dberr_t
154 recv_recovery_from_checkpoint_start_func(
155 /*=====================================*/
156 #ifdef UNIV_LOG_ARCHIVE
157 	ulint		type,		/*!< in: LOG_CHECKPOINT or
158 					LOG_ARCHIVE */
159 	lsn_t		limit_lsn,	/*!< in: recover up to this lsn
160 					if possible */
161 #endif /* UNIV_LOG_ARCHIVE */
162 	lsn_t		min_flushed_lsn,/*!< in: min flushed lsn from
163 					data files */
164 	lsn_t		max_flushed_lsn);/*!< in: max flushed lsn from
165 					 data files */
166 #ifdef UNIV_LOG_ARCHIVE
167 /** Wrapper for recv_recovery_from_checkpoint_start_func().
168 Recovers from a checkpoint. When this function returns, the database is able
169 to start processing of new user transactions, but the function
170 recv_recovery_from_checkpoint_finish should be called later to complete
171 the recovery and free the resources used in it.
172 @param type	in: LOG_CHECKPOINT or LOG_ARCHIVE
173 @param lim	in: recover up to this log sequence number if possible
174 @param min	in: minimum flushed log sequence number from data files
175 @param max	in: maximum flushed log sequence number from data files
176 @return	error code or DB_SUCCESS */
177 # define recv_recovery_from_checkpoint_start(type,lim,min,max)		\
178 	recv_recovery_from_checkpoint_start_func(type,lim,min,max)
179 #else /* UNIV_LOG_ARCHIVE */
180 /** Wrapper for recv_recovery_from_checkpoint_start_func().
181 Recovers from a checkpoint. When this function returns, the database is able
182 to start processing of new user transactions, but the function
183 recv_recovery_from_checkpoint_finish should be called later to complete
184 the recovery and free the resources used in it.
185 @param type	ignored: LOG_CHECKPOINT or LOG_ARCHIVE
186 @param lim	ignored: recover up to this log sequence number if possible
187 @param min	in: minimum flushed log sequence number from data files
188 @param max	in: maximum flushed log sequence number from data files
189 @return	error code or DB_SUCCESS */
190 # define recv_recovery_from_checkpoint_start(type,lim,min,max)		\
191 	recv_recovery_from_checkpoint_start_func(min,max)
192 #endif /* UNIV_LOG_ARCHIVE */
193 /********************************************************//**
194 Completes recovery from a checkpoint. */
195 UNIV_INTERN
196 void
197 recv_recovery_from_checkpoint_finish(void);
198 /*======================================*/
199 /********************************************************//**
200 Initiates the rollback of active transactions. */
201 UNIV_INTERN
202 void
203 recv_recovery_rollback_active(void);
204 /*===============================*/
205 
206 /*******************************************************************//**
207 Tries to parse a single log record and returns its length.
208 @return	length of the record, or 0 if the record was not complete */
209 UNIV_INTERN
210 ulint
211 recv_parse_log_rec(
212 /*===============*/
213 	byte*	ptr,	/*!< in: pointer to a buffer */
214 	byte*	end_ptr,/*!< in: pointer to the buffer end */
215 	byte*	type,	/*!< out: type */
216 	ulint*	space,	/*!< out: space id */
217 	ulint*	page_no,/*!< out: page number */
218 	byte**	body);	/*!< out: log record body start */
219 
220 /*******************************************************//**
221 Scans log from a buffer and stores new log data to the parsing buffer.
222 Parses and hashes the log records if new data found.  Unless
223 UNIV_HOTBACKUP is defined, this function will apply log records
224 automatically when the hash table becomes full.
225 @return TRUE if limit_lsn has been reached, or not able to scan any
226 more in this log group */
227 UNIV_INTERN
228 ibool
229 recv_scan_log_recs(
230 /*===============*/
231 	ulint		available_memory,/*!< in: we let the hash table of recs
232 					to grow to this size, at the maximum */
233 	ibool		store_to_hash,	/*!< in: TRUE if the records should be
234 					stored to the hash table; this is set
235 					to FALSE if just debug checking is
236 					needed */
237 	const byte*	buf,		/*!< in: buffer containing a log
238 					segment or garbage */
239 	ulint		len,		/*!< in: buffer length */
240 	lsn_t		start_lsn,	/*!< in: buffer start lsn */
241 	lsn_t*		contiguous_lsn,	/*!< in/out: it is known that all log
242 					groups contain contiguous log data up
243 					to this lsn */
244 	lsn_t*		group_scanned_lsn);/*!< out: scanning succeeded up to
245 					this lsn */
246 /******************************************************//**
247 Resets the logs. The contents of log files will be lost! */
248 UNIV_INTERN
249 void
250 recv_reset_logs(
251 /*============*/
252 #ifdef UNIV_LOG_ARCHIVE
253 	ulint		arch_log_no,	/*!< in: next archived log file number */
254 	ibool		new_logs_created,/*!< in: TRUE if resetting logs
255 					is done at the log creation;
256 					FALSE if it is done after
257 					archive recovery */
258 #endif /* UNIV_LOG_ARCHIVE */
259 	lsn_t		lsn);		/*!< in: reset to this lsn
260 					rounded up to be divisible by
261 					OS_FILE_LOG_BLOCK_SIZE, after
262 					which we add
263 					LOG_BLOCK_HDR_SIZE */
264 #ifdef UNIV_HOTBACKUP
265 /******************************************************//**
266 Creates new log files after a backup has been restored. */
267 UNIV_INTERN
268 void
269 recv_reset_log_files_for_backup(
270 /*============================*/
271 	const char*	log_dir,	/*!< in: log file directory path */
272 	ulint		n_log_files,	/*!< in: number of log files */
273 	lsn_t		log_file_size,	/*!< in: log file size */
274 	lsn_t		lsn);		/*!< in: new start lsn, must be
275 					divisible by OS_FILE_LOG_BLOCK_SIZE */
276 #endif /* UNIV_HOTBACKUP */
277 /********************************************************//**
278 Creates the recovery system. */
279 UNIV_INTERN
280 void
281 recv_sys_create(void);
282 /*=================*/
283 /**********************************************************//**
284 Release recovery system mutexes. */
285 UNIV_INTERN
286 void
287 recv_sys_close(void);
288 /*================*/
289 /********************************************************//**
290 Frees the recovery system memory. */
291 UNIV_INTERN
292 void
293 recv_sys_mem_free(void);
294 /*===================*/
295 /********************************************************//**
296 Inits the recovery system for a recovery operation. */
297 UNIV_INTERN
298 void
299 recv_sys_init(
300 /*==========*/
301 	ulint	available_memory);	/*!< in: available memory in bytes */
302 #ifndef UNIV_HOTBACKUP
303 /********************************************************//**
304 Reset the state of the recovery system variables. */
305 UNIV_INTERN
306 void
307 recv_sys_var_init(void);
308 /*===================*/
309 #endif /* !UNIV_HOTBACKUP */
310 /*******************************************************************//**
311 Empties the hash table of stored log records, applying them to appropriate
312 pages. */
313 UNIV_INTERN
314 void
315 recv_apply_hashed_log_recs(
316 /*=======================*/
317 	ibool	allow_ibuf);	/*!< in: if TRUE, also ibuf operations are
318 				allowed during the application; if FALSE,
319 				no ibuf operations are allowed, and after
320 				the application all file pages are flushed to
321 				disk and invalidated in buffer pool: this
322 				alternative means that no new log records
323 				can be generated during the application */
324 #ifdef UNIV_HOTBACKUP
325 /*******************************************************************//**
326 Applies log records in the hash table to a backup. */
327 UNIV_INTERN
328 void
329 recv_apply_log_recs_for_backup(void);
330 /*================================*/
331 #endif
332 
333 /** Block of log record data */
334 struct recv_data_t{
335 	recv_data_t*	next;	/*!< pointer to the next block or NULL */
336 				/*!< the log record data is stored physically
337 				immediately after this struct, max amount
338 				RECV_DATA_BLOCK_SIZE bytes of it */
339 };
340 
341 /** Stored log record struct */
342 struct recv_t{
343 	byte		type;	/*!< log record type */
344 	ulint		len;	/*!< log record body length in bytes */
345 	recv_data_t*	data;	/*!< chain of blocks containing the log record
346 				body */
347 	lsn_t		start_lsn;/*!< start lsn of the log segment written by
348 				the mtr which generated this log record: NOTE
349 				that this is not necessarily the start lsn of
350 				this log record */
351 	lsn_t		end_lsn;/*!< end lsn of the log segment written by
352 				the mtr which generated this log record: NOTE
353 				that this is not necessarily the end lsn of
354 				this log record */
355 	UT_LIST_NODE_T(recv_t)
356 			rec_list;/*!< list of log records for this page */
357 };
358 
359 /** States of recv_addr_t */
360 enum recv_addr_state {
361 	/** not yet processed */
362 	RECV_NOT_PROCESSED,
363 	/** page is being read */
364 	RECV_BEING_READ,
365 	/** log records are being applied on the page */
366 	RECV_BEING_PROCESSED,
367 	/** log records have been applied on the page, or they have
368 	been discarded because the tablespace does not exist */
369 	RECV_PROCESSED
370 };
371 
372 /** Hashed page file address struct */
373 struct recv_addr_t{
374 	enum recv_addr_state state;
375 				/*!< recovery state of the page */
376 	unsigned	space:32;/*!< space id */
377 	unsigned	page_no:32;/*!< page number */
378 	UT_LIST_BASE_NODE_T(recv_t)
379 			rec_list;/*!< list of log records for this page */
380 	hash_node_t	addr_hash;/*!< hash node in the hash bucket chain */
381 };
382 
383 struct recv_dblwr_t {
384 	void add(byte* page);
385 
386 	byte* find_page(ulint space_id, ulint page_no);
387 
388 	std::list<byte *> pages; /* Pages from double write buffer */
389 
operatorrecv_dblwr_t390 	void operator() () {
391 		pages.clear();
392 	}
393 };
394 
395 /** Recovery system data structure */
396 struct recv_sys_t{
397 #ifndef UNIV_HOTBACKUP
398 	ib_mutex_t		mutex;	/*!< mutex protecting the fields apply_log_recs,
399 				n_addrs, and the state field in each recv_addr
400 				struct */
401 	ib_mutex_t		writer_mutex;/*!< mutex coordinating
402 				flushing between recv_writer_thread and
403 				the recovery thread. */
404 #endif /* !UNIV_HOTBACKUP */
405 	ibool		apply_log_recs;
406 				/*!< this is TRUE when log rec application to
407 				pages is allowed; this flag tells the
408 				i/o-handler if it should do log record
409 				application */
410 	ibool		apply_batch_on;
411 				/*!< this is TRUE when a log rec application
412 				batch is running */
413 	lsn_t		lsn;	/*!< log sequence number */
414 	ulint		last_log_buf_size;
415 				/*!< size of the log buffer when the database
416 				last time wrote to the log */
417 	byte*		last_block;
418 				/*!< possible incomplete last recovered log
419 				block */
420 	byte*		last_block_buf_start;
421 				/*!< the nonaligned start address of the
422 				preceding buffer */
423 	byte*		buf;	/*!< buffer for parsing log records */
424 	ulint		len;	/*!< amount of data in buf */
425 	lsn_t		parse_start_lsn;
426 				/*!< this is the lsn from which we were able to
427 				start parsing log records and adding them to
428 				the hash table; zero if a suitable
429 				start point not found yet */
430 	lsn_t		scanned_lsn;
431 				/*!< the log data has been scanned up to this
432 				lsn */
433 	ulint		scanned_checkpoint_no;
434 				/*!< the log data has been scanned up to this
435 				checkpoint number (lowest 4 bytes) */
436 	ulint		recovered_offset;
437 				/*!< start offset of non-parsed log records in
438 				buf */
439 	lsn_t		recovered_lsn;
440 				/*!< the log records have been parsed up to
441 				this lsn */
442 	lsn_t		limit_lsn;/*!< recovery should be made at most
443 				up to this lsn */
444 	ibool		found_corrupt_log;
445 				/*!< this is set to TRUE if we during log
446 				scan find a corrupt log block, or a corrupt
447 				log record, or there is a log parsing
448 				buffer overflow */
449 #ifdef UNIV_LOG_ARCHIVE
450 	log_group_t*	archive_group;
451 				/*!< in archive recovery: the log group whose
452 				archive is read */
453 #endif /* !UNIV_LOG_ARCHIVE */
454 	mem_heap_t*	heap;	/*!< memory heap of log records and file
455 				addresses*/
456 	hash_table_t*	addr_hash;/*!< hash table of file addresses of pages */
457 	ulint		n_addrs;/*!< number of not processed hashed file
458 				addresses in the hash table */
459 
460 	recv_dblwr_t	dblwr;
461 };
462 
463 /** The recovery system */
464 extern recv_sys_t*	recv_sys;
465 
466 /** TRUE when applying redo log records during crash recovery; FALSE
467 otherwise.  Note that this is FALSE while a background thread is
468 rolling back incomplete transactions. */
469 extern ibool		recv_recovery_on;
470 /** If the following is TRUE, the buffer pool file pages must be invalidated
471 after recovery and no ibuf operations are allowed; this becomes TRUE if
472 the log record hash table becomes too full, and log records must be merged
473 to file pages already before the recovery is finished: in this case no
474 ibuf operations are allowed, as they could modify the pages read in the
475 buffer pool before the pages have been recovered to the up-to-date state.
476 
477 TRUE means that recovery is running and no operations on the log files
478 are allowed yet: the variable name is misleading. */
479 extern ibool		recv_no_ibuf_operations;
480 /** TRUE when recv_init_crash_recovery() has been called. */
481 extern ibool		recv_needed_recovery;
482 #ifdef UNIV_DEBUG
483 /** TRUE if writing to the redo log (mtr_commit) is forbidden.
484 Protected by log_sys->mutex. */
485 extern ibool		recv_no_log_write;
486 #endif /* UNIV_DEBUG */
487 
488 /** TRUE if buf_page_is_corrupted() should check if the log sequence
489 number (FIL_PAGE_LSN) is in the future.  Initially FALSE, and set by
490 recv_recovery_from_checkpoint_start_func(). */
491 extern ibool		recv_lsn_checks_on;
492 #ifdef UNIV_HOTBACKUP
493 /** TRUE when the redo log is being backed up */
494 extern ibool		recv_is_making_a_backup;
495 #endif /* UNIV_HOTBACKUP */
496 /** Maximum page number encountered in the redo log */
497 extern ulint		recv_max_parsed_page_no;
498 
499 /** Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
500 times! */
501 #define RECV_PARSING_BUF_SIZE	(2 * 1024 * 1024)
502 
503 /** Size of block reads when the log groups are scanned forward to do a
504 roll-forward */
505 #define RECV_SCAN_SIZE		(4 * UNIV_PAGE_SIZE)
506 
507 /** This many frames must be left free in the buffer pool when we scan
508 the log and store the scanned log records in the buffer pool: we will
509 use these free frames to read in pages when we start applying the
510 log records to the database. */
511 extern ulint	recv_n_pool_free_frames;
512 
513 #ifndef UNIV_NONINL
514 #include "log0recv.ic"
515 #endif
516 
517 #endif
518