1 /*****************************************************************************
2 
3 Copyright (c) 1996, 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/trx0sys.h
29 Transaction system
30 
31 Created 3/26/1996 Heikki Tuuri
32 *******************************************************/
33 
34 #ifndef trx0sys_h
35 #define trx0sys_h
36 
37 #include "univ.i"
38 
39 #include "trx0types.h"
40 #include "fsp0types.h"
41 #include "fil0fil.h"
42 #include "buf0buf.h"
43 #ifndef UNIV_HOTBACKUP
44 #include "mtr0mtr.h"
45 #include "ut0byte.h"
46 #include "mem0mem.h"
47 #include "sync0sync.h"
48 #include "ut0lst.h"
49 #include "ut0bh.h"
50 #include "read0types.h"
51 #include "page0types.h"
52 #ifdef WITH_WSREP
53 #include "trx0xa.h"
54 #endif /* WITH_WSREP */
55 #include "ut0bh.h"
56 
57 typedef UT_LIST_BASE_NODE_T(trx_t) trx_list_t;
58 
59 /** In a MySQL replication slave, in crash recovery we store the master log
60 file name and position here. */
61 /* @{ */
62 /** Master binlog file name */
63 extern char		trx_sys_mysql_master_log_name[];
64 /** Master binlog file position.  We have successfully got the updates
65 up to this position.  -1 means that no crash recovery was needed, or
66 there was no master log position info inside InnoDB.*/
67 extern ib_int64_t	trx_sys_mysql_master_log_pos;
68 /* @} */
69 
70 /** If this MySQL server uses binary logging, after InnoDB has been inited
71 and if it has done a crash recovery, we store the binlog file name and position
72 here. */
73 /* @{ */
74 /** Binlog file name */
75 extern char		trx_sys_mysql_bin_log_name[];
76 /** Binlog file position, or -1 if unknown */
77 extern ib_int64_t	trx_sys_mysql_bin_log_pos;
78 /* @} */
79 
80 /** The transaction system */
81 extern trx_sys_t*	trx_sys;
82 
83 /***************************************************************//**
84 Checks if a page address is the trx sys header page.
85 @return	TRUE if trx sys header page */
86 UNIV_INLINE
87 ibool
88 trx_sys_hdr_page(
89 /*=============*/
90 	ulint	space,	/*!< in: space */
91 	ulint	page_no);/*!< in: page number */
92 /*****************************************************************//**
93 Creates and initializes the central memory structures for the transaction
94 system. This is called when the database is started.
95 @return min binary heap of rsegs to purge */
96 UNIV_INTERN
97 ib_bh_t*
98 trx_sys_init_at_db_start(void);
99 /*==========================*/
100 /*****************************************************************//**
101 Creates the trx_sys instance and initializes ib_bh and mutex. */
102 UNIV_INTERN
103 void
104 trx_sys_create(void);
105 /*================*/
106 /*****************************************************************//**
107 Creates and initializes the transaction system at the database creation. */
108 UNIV_INTERN
109 void
110 trx_sys_create_sys_pages(void);
111 /*==========================*/
112 /****************************************************************//**
113 Looks for a free slot for a rollback segment in the trx system file copy.
114 @return	slot index or ULINT_UNDEFINED if not found */
115 UNIV_INTERN
116 ulint
117 trx_sysf_rseg_find_free(
118 /*====================*/
119 	mtr_t*		mtr);		/*!< in: mtr */
120 /***************************************************************//**
121 Gets the pointer in the nth slot of the rseg array.
122 @return	pointer to rseg object, NULL if slot not in use */
123 UNIV_INLINE
124 trx_rseg_t*
125 trx_sys_get_nth_rseg(
126 /*=================*/
127 	trx_sys_t*	sys,	/*!< in: trx system */
128 	ulint		n);	/*!< in: index of slot */
129 /**********************************************************************//**
130 Gets a pointer to the transaction system file copy and x-locks its page.
131 @return	pointer to system file copy, page x-locked */
132 UNIV_INLINE
133 trx_sysf_t*
134 trx_sysf_get(
135 /*=========*/
136 	mtr_t*	mtr);	/*!< in: mtr */
137 /*****************************************************************//**
138 Gets the space of the nth rollback segment slot in the trx system
139 file copy.
140 @return	space id */
141 UNIV_INLINE
142 ulint
143 trx_sysf_rseg_get_space(
144 /*====================*/
145 	trx_sysf_t*	sys_header,	/*!< in: trx sys file copy */
146 	ulint		i,		/*!< in: slot index == rseg id */
147 	mtr_t*		mtr);		/*!< in: mtr */
148 /*****************************************************************//**
149 Gets the page number of the nth rollback segment slot in the trx system
150 file copy.
151 @return	page number, FIL_NULL if slot unused */
152 UNIV_INLINE
153 ulint
154 trx_sysf_rseg_get_page_no(
155 /*======================*/
156 	trx_sysf_t*	sys_header,	/*!< in: trx sys file copy */
157 	ulint		i,		/*!< in: slot index == rseg id */
158 	mtr_t*		mtr);		/*!< in: mtr */
159 /*****************************************************************//**
160 Sets the space id of the nth rollback segment slot in the trx system
161 file copy. */
162 UNIV_INLINE
163 void
164 trx_sysf_rseg_set_space(
165 /*====================*/
166 	trx_sysf_t*	sys_header,	/*!< in: trx sys file copy */
167 	ulint		i,		/*!< in: slot index == rseg id */
168 	ulint		space,		/*!< in: space id */
169 	mtr_t*		mtr);		/*!< in: mtr */
170 /*****************************************************************//**
171 Sets the page number of the nth rollback segment slot in the trx system
172 file copy. */
173 UNIV_INLINE
174 void
175 trx_sysf_rseg_set_page_no(
176 /*======================*/
177 	trx_sysf_t*	sys_header,	/*!< in: trx sys file copy */
178 	ulint		i,		/*!< in: slot index == rseg id */
179 	ulint		page_no,	/*!< in: page number, FIL_NULL if
180 					the slot is reset to unused */
181 	mtr_t*		mtr);		/*!< in: mtr */
182 /*****************************************************************//**
183 Allocates a new transaction id.
184 @return	new, allocated trx id */
185 UNIV_INLINE
186 trx_id_t
187 trx_sys_get_new_trx_id(void);
188 /*========================*/
189 /*****************************************************************//**
190 Determines the maximum transaction id.
191 @return maximum currently allocated trx id; will be stale after the
192 next call to trx_sys_get_new_trx_id() */
193 UNIV_INLINE
194 trx_id_t
195 trx_sys_get_max_trx_id(void);
196 /*========================*/
197 
198 #ifdef UNIV_DEBUG
199 /* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
200 extern uint			trx_rseg_n_slots_debug;
201 #endif
202 
203 /*****************************************************************//**
204 Writes a trx id to an index page. In case that the id size changes in
205 some future version, this function should be used instead of
206 mach_write_... */
207 UNIV_INLINE
208 void
209 trx_write_trx_id(
210 /*=============*/
211 	byte*		ptr,	/*!< in: pointer to memory where written */
212 	trx_id_t	id);	/*!< in: id */
213 /*****************************************************************//**
214 Reads a trx id from an index page. In case that the id size changes in
215 some future version, this function should be used instead of
216 mach_read_...
217 @return	id */
218 UNIV_INLINE
219 trx_id_t
220 trx_read_trx_id(
221 /*============*/
222 	const byte*	ptr);	/*!< in: pointer to memory from where to read */
223 /****************************************************************//**
224 Looks for the trx instance with the given id in the rw trx_list.
225 The caller must be holding trx_sys->mutex.
226 @return	the trx handle or NULL if not found;
227 the pointer must not be dereferenced unless lock_sys->mutex was
228 acquired before calling this function and is still being held */
229 UNIV_INLINE
230 trx_t*
231 trx_get_rw_trx_by_id(
232 /*=================*/
233 	trx_id_t	trx_id);/*!< in: trx id to search for */
234 /****************************************************************//**
235 Returns the minimum trx id in rw trx list. This is the smallest id for which
236 the trx can possibly be active. (But, you must look at the trx->state to
237 find out if the minimum trx id transaction itself is active, or already
238 committed.)
239 @return	the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
240 UNIV_INLINE
241 trx_id_t
242 trx_rw_min_trx_id(void);
243 /*===================*/
244 /****************************************************************//**
245 Checks if a rw transaction with the given id is active. Caller must hold
246 trx_sys->mutex in shared mode. If the caller is not holding
247 lock_sys->mutex, the transaction may already have been committed.
248 @return	transaction instance if active, or NULL;
249 the pointer must not be dereferenced unless lock_sys->mutex was
250 acquired before calling this function and is still being held */
251 UNIV_INLINE
252 trx_t*
253 trx_rw_is_active_low(
254 /*=================*/
255 	trx_id_t	trx_id,		/*!< in: trx id of the transaction */
256 	ibool*		corrupt);	/*!< in: NULL or pointer to a flag
257 					that will be set if corrupt */
258 /****************************************************************//**
259 Checks if a rw transaction with the given id is active. If the caller is
260 not holding lock_sys->mutex, the transaction may already have been
261 committed.
262 @return	transaction instance if active, or NULL;
263 the pointer must not be dereferenced unless lock_sys->mutex was
264 acquired before calling this function and is still being held */
265 UNIV_INLINE
266 trx_t*
267 trx_rw_is_active(
268 /*=============*/
269 	trx_id_t	trx_id,		/*!< in: trx id of the transaction */
270 	ibool*		corrupt);	/*!< in: NULL or pointer to a flag
271 					that will be set if corrupt */
272 #ifdef UNIV_DEBUG
273 /****************************************************************//**
274 Checks whether a trx is in one of rw_trx_list or ro_trx_list.
275 @return	TRUE if is in */
276 UNIV_INTERN
277 ibool
278 trx_in_trx_list(
279 /*============*/
280 	const trx_t*	in_trx)		/*!< in: transaction */
281 	MY_ATTRIBUTE((nonnull, warn_unused_result));
282 #endif /* UNIV_DEBUG */
283 #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
284 /***********************************************************//**
285 Assert that a transaction has been recovered.
286 @return TRUE */
287 UNIV_INLINE
288 ibool
289 trx_assert_recovered(
290 /*=================*/
291 	trx_id_t	trx_id)		/*!< in: transaction identifier */
292 	MY_ATTRIBUTE((warn_unused_result));
293 #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
294 /*****************************************************************//**
295 Updates the offset information about the end of the MySQL binlog entry
296 which corresponds to the transaction just being committed. In a MySQL
297 replication slave updates the latest master binlog position up to which
298 replication has proceeded. */
299 UNIV_INTERN
300 void
301 trx_sys_update_mysql_binlog_offset(
302 /*===============================*/
303 	const char*	file_name,/*!< in: MySQL log file name */
304 	ib_int64_t	offset,	/*!< in: position in that log file */
305 	ulint		field,	/*!< in: offset of the MySQL log info field in
306 				the trx sys header */
307 #ifdef WITH_WSREP
308         trx_sysf_t*     sys_header, /*!< in: trx sys header */
309 #endif /* WITH_WSREP */
310 	mtr_t*		mtr);	/*!< in: mtr */
311 /*****************************************************************//**
312 Prints to stderr the MySQL binlog offset info in the trx system header if
313 the magic number shows it valid. */
314 UNIV_INTERN
315 void
316 trx_sys_print_mysql_binlog_offset(void);
317 /*===================================*/
318 #ifdef WITH_WSREP
319 /** Update WSREP checkpoint XID in sys header. */
320 void
321 trx_sys_update_wsrep_checkpoint(
322         const XID*      xid,         /*!< in: WSREP XID */
323         trx_sysf_t*     sys_header,  /*!< in: sys_header */
324         mtr_t*          mtr);        /*!< in: mtr       */
325 
326 void
327 /** Read WSREP checkpoint XID from sys header. */
328 trx_sys_read_wsrep_checkpoint(
329         XID* xid); /*!< out: WSREP XID */
330 #endif /* WITH_WSREP */
331 /*****************************************************************//**
332 Prints to stderr the MySQL master log offset info in the trx system header if
333 the magic number shows it valid. */
334 UNIV_INTERN
335 void
336 trx_sys_print_mysql_master_log_pos(void);
337 /*====================================*/
338 /*****************************************************************//**
339 Initializes the tablespace tag system. */
340 UNIV_INTERN
341 void
342 trx_sys_file_format_init(void);
343 /*==========================*/
344 /*****************************************************************//**
345 Closes the tablespace tag system. */
346 UNIV_INTERN
347 void
348 trx_sys_file_format_close(void);
349 /*===========================*/
350 /********************************************************************//**
351 Tags the system table space with minimum format id if it has not been
352 tagged yet.
353 WARNING: This function is only called during the startup and AFTER the
354 redo log application during recovery has finished. */
355 UNIV_INTERN
356 void
357 trx_sys_file_format_tag_init(void);
358 /*==============================*/
359 /*****************************************************************//**
360 Shutdown/Close the transaction system. */
361 UNIV_INTERN
362 void
363 trx_sys_close(void);
364 /*===============*/
365 /*****************************************************************//**
366 Get the name representation of the file format from its id.
367 @return	pointer to the name */
368 UNIV_INTERN
369 const char*
370 trx_sys_file_format_id_to_name(
371 /*===========================*/
372 	const ulint	id);		/*!< in: id of the file format */
373 /*****************************************************************//**
374 Set the file format id unconditionally except if it's already the
375 same value.
376 @return	TRUE if value updated */
377 UNIV_INTERN
378 ibool
379 trx_sys_file_format_max_set(
380 /*========================*/
381 	ulint		format_id,	/*!< in: file format id */
382 	const char**	name);		/*!< out: max file format name or
383 					NULL if not needed. */
384 /*********************************************************************
385 Creates the rollback segments
386 @return number of rollback segments that are active. */
387 UNIV_INTERN
388 ulint
389 trx_sys_create_rsegs(
390 /*=================*/
391 	ulint	n_spaces,	/*!< number of tablespaces for UNDO logs */
392 	ulint	n_rsegs);	/*!< number of rollback segments to create */
393 /*****************************************************************//**
394 Get the number of transaction in the system, independent of their state.
395 @return count of transactions in trx_sys_t::trx_list */
396 UNIV_INLINE
397 ulint
398 trx_sys_get_n_rw_trx(void);
399 /*======================*/
400 
401 /*********************************************************************
402 Check if there are any active (non-prepared) transactions.
403 @return total number of active transactions or 0 if none */
404 UNIV_INTERN
405 ulint
406 trx_sys_any_active_transactions(void);
407 /*=================================*/
408 #else /* !UNIV_HOTBACKUP */
409 /*****************************************************************//**
410 Prints to stderr the MySQL binlog info in the system header if the
411 magic number shows it valid. */
412 UNIV_INTERN
413 void
414 trx_sys_print_mysql_binlog_offset_from_page(
415 /*========================================*/
416 	const byte*	page);	/*!< in: buffer containing the trx
417 				system header page, i.e., page number
418 				TRX_SYS_PAGE_NO in the tablespace */
419 /*****************************************************************//**
420 Reads the file format id from the first system table space file.
421 Even if the call succeeds and returns TRUE, the returned format id
422 may be ULINT_UNDEFINED signalling that the format id was not present
423 in the data file.
424 @return TRUE if call succeeds */
425 UNIV_INTERN
426 ibool
427 trx_sys_read_file_format_id(
428 /*========================*/
429 	const char *pathname,	/*!< in: pathname of the first system
430 				table space file */
431 	ulint *format_id);	/*!< out: file format of the system table
432 				space */
433 /*****************************************************************//**
434 Reads the file format id from the given per-table data file.
435 @return TRUE if call succeeds */
436 UNIV_INTERN
437 ibool
438 trx_sys_read_pertable_file_format_id(
439 /*=================================*/
440 	const char *pathname,	/*!< in: pathname of a per-table
441 				datafile */
442 	ulint *format_id);	/*!< out: file format of the per-table
443 				data file */
444 #endif /* !UNIV_HOTBACKUP */
445 /*****************************************************************//**
446 Get the name representation of the file format from its id.
447 @return	pointer to the max format name */
448 UNIV_INTERN
449 const char*
450 trx_sys_file_format_max_get(void);
451 /*=============================*/
452 /*****************************************************************//**
453 Check for the max file format tag stored on disk.
454 @return	DB_SUCCESS or error code */
455 UNIV_INTERN
456 dberr_t
457 trx_sys_file_format_max_check(
458 /*==========================*/
459 	ulint		max_format_id);	/*!< in: the max format id to check */
460 /********************************************************************//**
461 Update the file format tag in the system tablespace only if the given
462 format id is greater than the known max id.
463 @return	TRUE if format_id was bigger than the known max id */
464 UNIV_INTERN
465 ibool
466 trx_sys_file_format_max_upgrade(
467 /*============================*/
468 	const char**	name,		/*!< out: max file format name */
469 	ulint		format_id);	/*!< in: file format identifier */
470 /*****************************************************************//**
471 Get the name representation of the file format from its id.
472 @return	pointer to the name */
473 UNIV_INTERN
474 const char*
475 trx_sys_file_format_id_to_name(
476 /*===========================*/
477 	const ulint	id);	/*!< in: id of the file format */
478 
479 #ifdef UNIV_DEBUG
480 /*************************************************************//**
481 Validate the trx_sys_t::trx_list. */
482 UNIV_INTERN
483 ibool
484 trx_sys_validate_trx_list(void);
485 /*===========================*/
486 #endif /* UNIV_DEBUG */
487 
488 /* The automatically created system rollback segment has this id */
489 #define TRX_SYS_SYSTEM_RSEG_ID	0
490 
491 /* Space id and page no where the trx system file copy resides */
492 #define	TRX_SYS_SPACE	0	/* the SYSTEM tablespace */
493 #include "fsp0fsp.h"
494 #define	TRX_SYS_PAGE_NO	FSP_TRX_SYS_PAGE_NO
495 
496 /* The offset of the transaction system header on the page */
497 #define	TRX_SYS		FSEG_PAGE_DATA
498 
499 /** Transaction system header */
500 /*------------------------------------------------------------- @{ */
501 #define	TRX_SYS_TRX_ID_STORE	0	/*!< the maximum trx id or trx
502 					number modulo
503 					TRX_SYS_TRX_ID_UPDATE_MARGIN
504 					written to a file page by any
505 					transaction; the assignment of
506 					transaction ids continues from
507 					this number rounded up by
508 					TRX_SYS_TRX_ID_UPDATE_MARGIN
509 					plus
510 					TRX_SYS_TRX_ID_UPDATE_MARGIN
511 					when the database is
512 					started */
513 #define TRX_SYS_FSEG_HEADER	8	/*!< segment header for the
514 					tablespace segment the trx
515 					system is created into */
516 #define	TRX_SYS_RSEGS		(8 + FSEG_HEADER_SIZE)
517 					/*!< the start of the array of
518 					rollback segment specification
519 					slots */
520 /*------------------------------------------------------------- @} */
521 
522 /* Max number of rollback segments: the number of segment specification slots
523 in the transaction system array; rollback segment id must fit in one (signed)
524 byte, therefore 128; each slot is currently 8 bytes in size. If you want
525 to raise the level to 256 then you will need to fix some assertions that
526 impose the 7 bit restriction. e.g., mach_write_to_3() */
527 #define	TRX_SYS_N_RSEGS			128
528 /* Originally, InnoDB defined TRX_SYS_N_RSEGS as 256 but created only one
529 rollback segment.  It initialized some arrays with this number of entries.
530 We must remember this limit in order to keep file compatibility. */
531 #define TRX_SYS_OLD_N_RSEGS		256
532 
533 /** Maximum length of MySQL binlog file name, in bytes.
534 @see trx_sys_mysql_master_log_name
535 @see trx_sys_mysql_bin_log_name */
536 #define TRX_SYS_MYSQL_LOG_NAME_LEN	512
537 /** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
538 #define TRX_SYS_MYSQL_LOG_MAGIC_N	873422344
539 
540 #if UNIV_PAGE_SIZE_MIN < 4096
541 # error "UNIV_PAGE_SIZE_MIN < 4096"
542 #endif
543 /** The offset of the MySQL replication info in the trx system header;
544 this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
545 #define TRX_SYS_MYSQL_MASTER_LOG_INFO	(UNIV_PAGE_SIZE - 2000)
546 
547 /** The offset of the MySQL binlog offset info in the trx system header */
548 #define TRX_SYS_MYSQL_LOG_INFO		(UNIV_PAGE_SIZE - 1000)
549 #define	TRX_SYS_MYSQL_LOG_MAGIC_N_FLD	0	/*!< magic number which is
550 						TRX_SYS_MYSQL_LOG_MAGIC_N
551 						if we have valid data in the
552 						MySQL binlog info */
553 #define TRX_SYS_MYSQL_LOG_OFFSET_HIGH	4	/*!< high 4 bytes of the offset
554 						within that file */
555 #define TRX_SYS_MYSQL_LOG_OFFSET_LOW	8	/*!< low 4 bytes of the offset
556 						within that file */
557 #define TRX_SYS_MYSQL_LOG_NAME		12	/*!< MySQL log file name */
558 
559 #ifdef WITH_WSREP
560 /* The offset to WSREP XID headers */
561 #define TRX_SYS_WSREP_XID_INFO (UNIV_PAGE_SIZE - 3500)
562 #define TRX_SYS_WSREP_XID_MAGIC_N_FLD 0
563 #define TRX_SYS_WSREP_XID_MAGIC_N 0x77737265
564 
565 /* XID field: formatID, gtrid_len, bqual_len, xid_data */
566 #define TRX_SYS_WSREP_XID_LEN        (4 + 4 + 4 + XIDDATASIZE)
567 #define TRX_SYS_WSREP_XID_FORMAT     4
568 #define TRX_SYS_WSREP_XID_GTRID_LEN  8
569 #define TRX_SYS_WSREP_XID_BQUAL_LEN 12
570 #define TRX_SYS_WSREP_XID_DATA      16
571 #endif /* WITH_WSREP*/
572 
573 /** Doublewrite buffer */
574 /* @{ */
575 /** The offset of the doublewrite buffer header on the trx system header page */
576 #define TRX_SYS_DOUBLEWRITE		(UNIV_PAGE_SIZE - 200)
577 /*-------------------------------------------------------------*/
578 #define TRX_SYS_DOUBLEWRITE_FSEG	0	/*!< fseg header of the fseg
579 						containing the doublewrite
580 						buffer */
581 #define TRX_SYS_DOUBLEWRITE_MAGIC	FSEG_HEADER_SIZE
582 						/*!< 4-byte magic number which
583 						shows if we already have
584 						created the doublewrite
585 						buffer */
586 #define TRX_SYS_DOUBLEWRITE_BLOCK1	(4 + FSEG_HEADER_SIZE)
587 						/*!< page number of the
588 						first page in the first
589 						sequence of 64
590 						(= FSP_EXTENT_SIZE) consecutive
591 						pages in the doublewrite
592 						buffer */
593 #define TRX_SYS_DOUBLEWRITE_BLOCK2	(8 + FSEG_HEADER_SIZE)
594 						/*!< page number of the
595 						first page in the second
596 						sequence of 64 consecutive
597 						pages in the doublewrite
598 						buffer */
599 #define TRX_SYS_DOUBLEWRITE_REPEAT	12	/*!< we repeat
600 						TRX_SYS_DOUBLEWRITE_MAGIC,
601 						TRX_SYS_DOUBLEWRITE_BLOCK1,
602 						TRX_SYS_DOUBLEWRITE_BLOCK2
603 						so that if the trx sys
604 						header is half-written
605 						to disk, we still may
606 						be able to recover the
607 						information */
608 /** If this is not yet set to TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N,
609 we must reset the doublewrite buffer, because starting from 4.1.x the
610 space id of a data page is stored into
611 FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID. */
612 #define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED (24 + FSEG_HEADER_SIZE)
613 
614 /*-------------------------------------------------------------*/
615 /** Contents of TRX_SYS_DOUBLEWRITE_MAGIC */
616 #define TRX_SYS_DOUBLEWRITE_MAGIC_N	536853855
617 /** Contents of TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED */
618 #define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N 1783657386
619 
620 /** Size of the doublewrite block in pages */
621 #define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE	FSP_EXTENT_SIZE
622 /* @} */
623 
624 /** File format tag */
625 /* @{ */
626 /** The offset of the file format tag on the trx system header page
627 (TRX_SYS_PAGE_NO of TRX_SYS_SPACE) */
628 #define TRX_SYS_FILE_FORMAT_TAG		(UNIV_PAGE_SIZE - 16)
629 
630 /** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format
631 identifier is added to this constant. */
632 #define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW	3645922177UL
633 /** Contents of TRX_SYS_FILE_FORMAT_TAG+4 when valid */
634 #define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH	2745987765UL
635 /** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format
636 identifier is added to this 64-bit constant. */
637 #define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N					\
638 	((ib_uint64_t) TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH << 32	\
639 	 | TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW)
640 /* @} */
641 
642 #ifndef UNIV_HOTBACKUP
643 /** The transaction system central memory data structure. */
644 struct trx_sys_t{
645 
646 	ib_mutex_t		mutex;		/*!< mutex protecting most fields in
647 					this structure except when noted
648 					otherwise */
649 	ulint		n_prepared_trx;	/*!< Number of transactions currently
650 					in the XA PREPARED state */
651 	ulint		n_prepared_recovered_trx; /*!< Number of transactions
652 					currently in XA PREPARED state that are
653 					also recovered. Such transactions cannot
654 					be added during runtime. They can only
655 					occur after recovery if mysqld crashed
656 					while there were XA PREPARED
657 					transactions. We disable query cache
658 					if such transactions exist. */
659 	trx_id_t	max_trx_id;	/*!< The smallest number not yet
660 					assigned as a transaction id or
661 					transaction number */
662 #ifdef UNIV_DEBUG
663 	trx_id_t	rw_max_trx_id;	/*!< Max trx id of read-write transactions
664 					which exist or existed */
665 #endif
666 	trx_list_t	rw_trx_list;	/*!< List of active and committed in
667 					memory read-write transactions, sorted
668 					on trx id, biggest first. Recovered
669 					transactions are always on this list. */
670 	trx_list_t	ro_trx_list;	/*!< List of active and committed in
671 					memory read-only transactions, sorted
672 					on trx id, biggest first. NOTE:
673 					The order for read-only transactions
674 					is not necessary. We should exploit
675 					this and increase concurrency during
676 					add/remove. */
677 	trx_list_t	mysql_trx_list;	/*!< List of transactions created
678 					for MySQL. All transactions on
679 					ro_trx_list are on mysql_trx_list. The
680 					rw_trx_list can contain system
681 					transactions and recovered transactions
682 					that will not be in the mysql_trx_list.
683 					There can be active non-locking
684 					auto-commit read only transactions that
685 					are on this list but not on ro_trx_list.
686 					mysql_trx_list may additionally contain
687 					transactions that have not yet been
688 					started in InnoDB. */
689 	trx_rseg_t*	const rseg_array[TRX_SYS_N_RSEGS];
690 					/*!< Pointer array to rollback
691 					segments; NULL if slot not in use;
692 					created and destroyed in
693 					single-threaded mode; not protected
694 					by any mutex, because it is read-only
695 					during multi-threaded operation */
696 	ulint		rseg_history_len;/*!< Length of the TRX_RSEG_HISTORY
697 					list (update undo logs for committed
698 					transactions), protected by
699 					rseg->mutex */
700 	UT_LIST_BASE_NODE_T(read_view_t) view_list;
701 					/*!< List of read views sorted
702 					on trx no, biggest first */
703 };
704 
705 /** When a trx id which is zero modulo this number (which must be a power of
706 two) is assigned, the field TRX_SYS_TRX_ID_STORE on the transaction system
707 page is updated */
708 #define TRX_SYS_TRX_ID_WRITE_MARGIN	256
709 #endif /* !UNIV_HOTBACKUP */
710 
711 #ifndef UNIV_NONINL
712 #include "trx0sys.ic"
713 #endif
714 
715 #endif
716