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