1
/*****************************************************************************
3
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/trx0sys.h
23
Created 3/26/1996 Heikki Tuuri
24
*******************************************************/
31
#include "trx0types.h"
32
#include "fsp0types.h"
35
#ifndef UNIV_HOTBACKUP
39
#include "sync0sync.h"
41
#include "read0types.h"
42
#include "page0types.h"
44
/** In a MySQL replication slave, in crash recovery we store the master log
45
file name and position here. */
47
/** Master binlog file name */
48
extern char trx_sys_mysql_master_log_name[];
49
/** Master binlog file position. We have successfully got the updates
50
up to this position. -1 means that no crash recovery was needed, or
51
there was no master log position info inside InnoDB.*/
52
extern ib_int64_t trx_sys_mysql_master_log_pos;
55
/** If this MySQL server uses binary logging, after InnoDB has been inited
56
and if it has done a crash recovery, we store the binlog file name and position
59
/** Binlog file name */
60
extern char trx_sys_mysql_bin_log_name[];
61
/** Binlog file position, or -1 if unknown */
62
extern ib_int64_t trx_sys_mysql_bin_log_pos;
65
/** The transaction system */
66
extern trx_sys_t* trx_sys;
68
/** Doublewrite system */
69
extern trx_doublewrite_t* trx_doublewrite;
70
/** The following is set to TRUE when we are upgrading from pre-4.1
71
format data files to the multiple tablespaces format data files */
72
extern ibool trx_doublewrite_must_reset_space_ids;
73
/** Set to TRUE when the doublewrite buffer is being created */
74
extern ibool trx_doublewrite_buf_is_being_created;
75
/** The following is TRUE when we are using the database in the
76
post-4.1 format, i.e., we have successfully upgraded, or have created
77
a new database installation */
78
extern ibool trx_sys_multiple_tablespace_format;
80
/****************************************************************//**
81
Creates the doublewrite buffer to a new InnoDB installation. The header of the
82
doublewrite buffer is placed on the trx system header page. */
85
trx_sys_create_doublewrite_buf(void);
86
/*================================*/
87
/****************************************************************//**
88
At a database startup initializes the doublewrite buffer memory structure if
89
we already have a doublewrite buffer created in the data files. If we are
90
upgrading to an InnoDB version which supports multiple tablespaces, then this
91
function performs the necessary update operations. If we are in a crash
92
recovery, this function uses a possible doublewrite buffer to restore
93
half-written pages in the data files. */
96
trx_sys_doublewrite_init_or_restore_pages(
97
/*======================================*/
98
ibool restore_corrupt_pages); /*!< in: TRUE=restore pages */
99
/****************************************************************//**
100
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
101
multiple tablespace format. */
104
trx_sys_mark_upgraded_to_multiple_tablespaces(void);
105
/*===============================================*/
106
/****************************************************************//**
107
Determines if a page number is located inside the doublewrite buffer.
108
@return TRUE if the location is inside the two blocks of the
109
doublewrite buffer */
112
trx_doublewrite_page_inside(
113
/*========================*/
114
ulint page_no); /*!< in: page number */
115
/***************************************************************//**
116
Checks if a page address is the trx sys header page.
117
@return TRUE if trx sys header page */
122
ulint space, /*!< in: space */
123
ulint page_no);/*!< in: page number */
124
/*****************************************************************//**
125
Creates and initializes the central memory structures for the transaction
126
system. This is called when the database is started. */
129
trx_sys_init_at_db_start(void);
130
/*==========================*/
131
/*****************************************************************//**
132
Creates and initializes the transaction system at the database creation. */
135
trx_sys_create(void);
137
/****************************************************************//**
138
Looks for a free slot for a rollback segment in the trx system file copy.
139
@return slot index or ULINT_UNDEFINED if not found */
142
trx_sysf_rseg_find_free(
143
/*====================*/
144
mtr_t* mtr); /*!< in: mtr */
145
/***************************************************************//**
146
Gets the pointer in the nth slot of the rseg array.
147
@return pointer to rseg object, NULL if slot not in use */
150
trx_sys_get_nth_rseg(
151
/*=================*/
152
trx_sys_t* sys, /*!< in: trx system */
153
ulint n); /*!< in: index of slot */
154
/***************************************************************//**
155
Sets the pointer in the nth slot of the rseg array. */
158
trx_sys_set_nth_rseg(
159
/*=================*/
160
trx_sys_t* sys, /*!< in: trx system */
161
ulint n, /*!< in: index of slot */
162
trx_rseg_t* rseg); /*!< in: pointer to rseg object, NULL if slot
164
/**********************************************************************//**
165
Gets a pointer to the transaction system file copy and x-locks its page.
166
@return pointer to system file copy, page x-locked */
171
mtr_t* mtr); /*!< in: mtr */
172
/*****************************************************************//**
173
Gets the space of the nth rollback segment slot in the trx system
178
trx_sysf_rseg_get_space(
179
/*====================*/
180
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
181
ulint i, /*!< in: slot index == rseg id */
182
mtr_t* mtr); /*!< in: mtr */
183
/*****************************************************************//**
184
Gets the page number of the nth rollback segment slot in the trx system
186
@return page number, FIL_NULL if slot unused */
189
trx_sysf_rseg_get_page_no(
190
/*======================*/
191
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
192
ulint i, /*!< in: slot index == rseg id */
193
mtr_t* mtr); /*!< in: mtr */
194
/*****************************************************************//**
195
Sets the space id of the nth rollback segment slot in the trx system
199
trx_sysf_rseg_set_space(
200
/*====================*/
201
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
202
ulint i, /*!< in: slot index == rseg id */
203
ulint space, /*!< in: space id */
204
mtr_t* mtr); /*!< in: mtr */
205
/*****************************************************************//**
206
Sets the page number of the nth rollback segment slot in the trx system
210
trx_sysf_rseg_set_page_no(
211
/*======================*/
212
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
213
ulint i, /*!< in: slot index == rseg id */
214
ulint page_no, /*!< in: page number, FIL_NULL if
215
the slot is reset to unused */
216
mtr_t* mtr); /*!< in: mtr */
217
/*****************************************************************//**
218
Allocates a new transaction id.
219
@return new, allocated trx id */
222
trx_sys_get_new_trx_id(void);
223
/*========================*/
224
/*****************************************************************//**
225
Allocates a new transaction number.
226
@return new, allocated trx number */
229
trx_sys_get_new_trx_no(void);
230
/*========================*/
231
#endif /* !UNIV_HOTBACKUP */
232
/*****************************************************************//**
233
Writes a trx id to an index page. In case that the id size changes in
234
some future version, this function should be used instead of
240
byte* ptr, /*!< in: pointer to memory where written */
241
trx_id_t id); /*!< in: id */
242
#ifndef UNIV_HOTBACKUP
243
/*****************************************************************//**
244
Reads a trx id from an index page. In case that the id size changes in
245
some future version, this function should be used instead of
252
const byte* ptr); /*!< in: pointer to memory from where to read */
253
/****************************************************************//**
254
Looks for the trx handle with the given id in trx_list.
255
@return the trx handle or NULL if not found */
260
trx_id_t trx_id);/*!< in: trx id to search for */
261
/****************************************************************//**
262
Returns the minumum trx id in trx list. This is the smallest id for which
263
the trx can possibly be active. (But, you must look at the trx->conc_state to
264
find out if the minimum trx id transaction itself is active, or already
266
@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
269
trx_list_get_min_trx_id(void);
270
/*=========================*/
271
/****************************************************************//**
272
Checks if a transaction with the given id is active.
273
@return TRUE if active */
278
trx_id_t trx_id);/*!< in: trx id of the transaction */
279
/****************************************************************//**
280
Checks that trx is in the trx list.
281
@return TRUE if is in */
286
trx_t* in_trx);/*!< in: trx */
287
/*****************************************************************//**
288
Updates the offset information about the end of the MySQL binlog entry
289
which corresponds to the transaction just being committed. In a MySQL
290
replication slave updates the latest master binlog position up to which
291
replication has proceeded. */
294
trx_sys_update_mysql_binlog_offset(
295
/*===============================*/
296
const char* file_name,/*!< in: MySQL log file name */
297
ib_int64_t offset, /*!< in: position in that log file */
298
ulint field, /*!< in: offset of the MySQL log info field in
299
the trx sys header */
300
mtr_t* mtr); /*!< in: mtr */
301
/*****************************************************************//**
302
Prints to stderr the MySQL binlog offset info in the trx system header if
303
the magic number shows it valid. */
306
trx_sys_print_mysql_binlog_offset(void);
307
/*===================================*/
308
/*****************************************************************//**
309
Prints to stderr the MySQL master log offset info in the trx system header if
310
the magic number shows it valid. */
313
trx_sys_print_mysql_master_log_pos(void);
314
/*====================================*/
315
/*****************************************************************//**
316
Initializes the tablespace tag system. */
319
trx_sys_file_format_init(void);
320
/*==========================*/
321
/*****************************************************************//**
322
Closes the tablespace tag system. */
325
trx_sys_file_format_close(void);
326
/*===========================*/
327
/********************************************************************//**
328
Tags the system table space with minimum format id if it has not been
330
WARNING: This function is only called during the startup and AFTER the
331
redo log application during recovery has finished. */
334
trx_sys_file_format_tag_init(void);
335
/*==============================*/
336
#ifndef UNIV_HOTBACKUP
337
/*****************************************************************//**
338
Shutdown/Close the transaction system. */
343
#endif /* !UNIV_HOTBACKUP */
344
/*****************************************************************//**
345
Get the name representation of the file format from its id.
346
@return pointer to the name */
349
trx_sys_file_format_id_to_name(
350
/*===========================*/
351
const ulint id); /*!< in: id of the file format */
352
/*****************************************************************//**
353
Set the file format id unconditionally except if it's already the
355
@return TRUE if value updated */
358
trx_sys_file_format_max_set(
359
/*========================*/
360
ulint format_id, /*!< in: file format id */
361
const char** name); /*!< out: max file format name or
362
NULL if not needed. */
363
/*****************************************************************//**
364
Get the name representation of the file format from its id.
365
@return pointer to the max format name */
368
trx_sys_file_format_max_get(void);
369
/*=============================*/
370
/*****************************************************************//**
371
Check for the max file format tag stored on disk.
372
@return DB_SUCCESS or error code */
375
trx_sys_file_format_max_check(
376
/*==========================*/
377
ulint max_format_id); /*!< in: the max format id to check */
378
/********************************************************************//**
379
Update the file format tag in the system tablespace only if the given
380
format id is greater than the known max id.
381
@return TRUE if format_id was bigger than the known max id */
384
trx_sys_file_format_max_upgrade(
385
/*============================*/
386
const char** name, /*!< out: max file format name */
387
ulint format_id); /*!< in: file format identifier */
388
#else /* !UNIV_HOTBACKUP */
389
/*****************************************************************//**
390
Prints to stderr the MySQL binlog info in the system header if the
391
magic number shows it valid. */
394
trx_sys_print_mysql_binlog_offset_from_page(
395
/*========================================*/
396
const byte* page); /*!< in: buffer containing the trx
397
system header page, i.e., page number
398
TRX_SYS_PAGE_NO in the tablespace */
399
/*****************************************************************//**
400
Reads the file format id from the first system table space file.
401
Even if the call succeeds and returns TRUE, the returned format id
402
may be ULINT_UNDEFINED signalling that the format id was not present
404
@return TRUE if call succeeds */
407
trx_sys_read_file_format_id(
408
/*========================*/
409
const char *pathname, /*!< in: pathname of the first system
411
ulint *format_id); /*!< out: file format of the system table
413
/*****************************************************************//**
414
Reads the file format id from the given per-table data file.
415
@return TRUE if call succeeds */
418
trx_sys_read_pertable_file_format_id(
419
/*=================================*/
420
const char *pathname, /*!< in: pathname of a per-table
422
ulint *format_id); /*!< out: file format of the per-table
424
/*****************************************************************//**
425
Get the name representation of the file format from its id.
426
@return pointer to the name */
429
trx_sys_file_format_id_to_name(
430
/*===========================*/
431
const ulint id); /*!< in: id of the file format */
433
#endif /* !UNIV_HOTBACKUP */
434
/*********************************************************************
435
Creates the rollback segments */
438
trx_sys_create_rsegs(
439
/*=================*/
440
ulint n_rsegs); /*!< number of rollback segments to create */
442
/* The automatically created system rollback segment has this id */
443
#define TRX_SYS_SYSTEM_RSEG_ID 0
445
/* Space id and page no where the trx system file copy resides */
446
#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
448
#define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
450
/* The offset of the transaction system header on the page */
451
#define TRX_SYS FSEG_PAGE_DATA
453
/** Transaction system header */
454
/*------------------------------------------------------------- @{ */
455
#define TRX_SYS_TRX_ID_STORE 0 /*!< the maximum trx id or trx
457
TRX_SYS_TRX_ID_UPDATE_MARGIN
458
written to a file page by any
459
transaction; the assignment of
460
transaction ids continues from
461
this number rounded up by
462
TRX_SYS_TRX_ID_UPDATE_MARGIN
464
TRX_SYS_TRX_ID_UPDATE_MARGIN
467
#define TRX_SYS_FSEG_HEADER 8 /*!< segment header for the
468
tablespace segment the trx
469
system is created into */
470
#define TRX_SYS_RSEGS (8 + FSEG_HEADER_SIZE)
471
/*!< the start of the array of
472
rollback segment specification
474
/*------------------------------------------------------------- @} */
476
/* Max number of rollback segments: the number of segment specification slots
477
in the transaction system array; rollback segment id must fit in one (signed)
478
byte, therefore 128; each slot is currently 8 bytes in size. If you want
479
to raise the level to 256 then you will need to fix some assertions that
480
impose the 7 bit restriction. e.g., mach_write_to_3() */
481
#define TRX_SYS_N_RSEGS 128
482
/* Originally, InnoDB defined TRX_SYS_N_RSEGS as 256 but created only one
483
rollback segment. It initialized some arrays with this number of entries.
484
We must remember this limit in order to keep file compatibility. */
485
#define TRX_SYS_OLD_N_RSEGS 256
487
/** Maximum length of MySQL binlog file name, in bytes.
488
@see trx_sys_mysql_master_log_name
489
@see trx_sys_mysql_bin_log_name */
490
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512
491
/** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
492
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
494
#if UNIV_PAGE_SIZE < 4096
495
# error "UNIV_PAGE_SIZE < 4096"
497
/** The offset of the MySQL replication info in the trx system header;
498
this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
499
#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
501
/** The offset of the MySQL binlog offset info in the trx system header */
502
#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)
503
#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /*!< magic number which is
504
TRX_SYS_MYSQL_LOG_MAGIC_N
505
if we have valid data in the
507
#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH 4 /*!< high 4 bytes of the offset
509
#define TRX_SYS_MYSQL_LOG_OFFSET_LOW 8 /*!< low 4 bytes of the offset
511
#define TRX_SYS_MYSQL_LOG_NAME 12 /*!< MySQL log file name */
513
/** Doublewrite buffer */
515
/** The offset of the doublewrite buffer header on the trx system header page */
516
#define TRX_SYS_DOUBLEWRITE (UNIV_PAGE_SIZE - 200)
517
/*-------------------------------------------------------------*/
518
#define TRX_SYS_DOUBLEWRITE_FSEG 0 /*!< fseg header of the fseg
519
containing the doublewrite
521
#define TRX_SYS_DOUBLEWRITE_MAGIC FSEG_HEADER_SIZE
522
/*!< 4-byte magic number which
523
shows if we already have
524
created the doublewrite
526
#define TRX_SYS_DOUBLEWRITE_BLOCK1 (4 + FSEG_HEADER_SIZE)
527
/*!< page number of the
528
first page in the first
530
(= FSP_EXTENT_SIZE) consecutive
531
pages in the doublewrite
533
#define TRX_SYS_DOUBLEWRITE_BLOCK2 (8 + FSEG_HEADER_SIZE)
534
/*!< page number of the
535
first page in the second
536
sequence of 64 consecutive
537
pages in the doublewrite
539
#define TRX_SYS_DOUBLEWRITE_REPEAT 12 /*!< we repeat
540
TRX_SYS_DOUBLEWRITE_MAGIC,
541
TRX_SYS_DOUBLEWRITE_BLOCK1,
542
TRX_SYS_DOUBLEWRITE_BLOCK2
543
so that if the trx sys
544
header is half-written
545
to disk, we still may
546
be able to recover the
548
/** If this is not yet set to TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N,
549
we must reset the doublewrite buffer, because starting from 4.1.x the
550
space id of a data page is stored into
551
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO. */
552
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED (24 + FSEG_HEADER_SIZE)
554
/*-------------------------------------------------------------*/
555
/** Contents of TRX_SYS_DOUBLEWRITE_MAGIC */
556
#define TRX_SYS_DOUBLEWRITE_MAGIC_N 536853855
557
/** Contents of TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED */
558
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N 1783657386
560
/** Size of the doublewrite block in pages */
561
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
564
#ifndef UNIV_HOTBACKUP
565
/** File format tag */
567
/** The offset of the file format tag on the trx system header page
568
(TRX_SYS_PAGE_NO of TRX_SYS_SPACE) */
569
#define TRX_SYS_FILE_FORMAT_TAG (UNIV_PAGE_SIZE - 16)
571
/** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format
572
identifier is added to this constant. */
573
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW 3645922177UL
574
/** Contents of TRX_SYS_FILE_FORMAT_TAG+4 when valid */
575
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH 2745987765UL
576
/** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format
577
identifier is added to this 64-bit constant. */
578
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N \
579
((ib_uint64_t) TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH << 32 \
580
| TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW)
583
/** Doublewrite control struct */
584
struct trx_doublewrite_struct{
585
mutex_t mutex; /*!< mutex protecting the first_free field and
587
ulint block1; /*!< the page number of the first
588
doublewrite block (64 pages) */
589
ulint block2; /*!< page number of the second block */
590
ulint first_free; /*!< first free position in write_buf measured
591
in units of UNIV_PAGE_SIZE */
592
byte* write_buf; /*!< write buffer used in writing to the
593
doublewrite buffer, aligned to an
594
address divisible by UNIV_PAGE_SIZE
595
(which is required by Windows aio) */
596
byte* write_buf_unaligned;
597
/*!< pointer to write_buf, but unaligned */
599
buf_block_arr; /*!< array to store pointers to the buffer
600
blocks which have been cached to write_buf */
603
/** The transaction system central memory data structure; protected by the
605
struct trx_sys_struct{
606
trx_id_t max_trx_id; /*!< The smallest number not yet
607
assigned as a transaction id or
608
transaction number */
609
UT_LIST_BASE_NODE_T(trx_t) trx_list;
610
/*!< List of active and committed in
611
memory transactions, sorted on trx id,
613
UT_LIST_BASE_NODE_T(trx_t) mysql_trx_list;
614
/*!< List of transactions created
616
UT_LIST_BASE_NODE_T(trx_rseg_t) rseg_list;
617
/*!< List of rollback segment
619
trx_rseg_t* latest_rseg; /*!< Latest rollback segment in the
620
round-robin assignment of rollback
621
segments to transactions */
622
trx_rseg_t* rseg_array[TRX_SYS_N_RSEGS];
623
/*!< Pointer array to rollback
624
segments; NULL if slot not in use */
625
ulint rseg_history_len;/*!< Length of the TRX_RSEG_HISTORY
626
list (update undo logs for committed
627
transactions), protected by
629
UT_LIST_BASE_NODE_T(read_view_t) view_list;
630
/*!< List of read views sorted
631
on trx no, biggest first */
634
/** When a trx id which is zero modulo this number (which must be a power of
635
two) is assigned, the field TRX_SYS_TRX_ID_STORE on the transaction system
637
#define TRX_SYS_TRX_ID_WRITE_MARGIN 256
638
#endif /* !UNIV_HOTBACKUP */
641
#include "trx0sys.ic"