1
/******************************************************
6
Created 3/26/1996 Heikki Tuuri
7
*******************************************************/
14
#include "trx0types.h"
19
#include "sync0sync.h"
25
#include "read0types.h"
26
#include "page0types.h"
28
/* In a MySQL replication slave, in crash recovery we store the master log
29
file name and position here. We have successfully got the updates to InnoDB
30
up to this position. If .._pos is -1, it means no crash recovery was needed,
31
or there was no master log position info inside InnoDB. */
33
extern char trx_sys_mysql_master_log_name[];
34
extern ib_int64_t trx_sys_mysql_master_log_pos;
36
/* If this MySQL server uses binary logging, after InnoDB has been inited
37
and if it has done a crash recovery, we store the binlog file name and position
38
here. If .._pos is -1, it means there was no binlog position info inside
41
extern char trx_sys_mysql_bin_log_name[];
42
extern ib_int64_t trx_sys_mysql_bin_log_pos;
44
/* The transaction system */
45
extern trx_sys_t* trx_sys;
47
/* Doublewrite system */
48
extern trx_doublewrite_t* trx_doublewrite;
49
extern ibool trx_doublewrite_must_reset_space_ids;
50
extern ibool trx_sys_multiple_tablespace_format;
52
/********************************************************************
53
Creates the doublewrite buffer to a new InnoDB installation. The header of the
54
doublewrite buffer is placed on the trx system header page. */
57
trx_sys_create_doublewrite_buf(void);
58
/*================================*/
59
/********************************************************************
60
At a database startup initializes the doublewrite buffer memory structure if
61
we already have a doublewrite buffer created in the data files. If we are
62
upgrading to an InnoDB version which supports multiple tablespaces, then this
63
function performs the necessary update operations. If we are in a crash
64
recovery, this function uses a possible doublewrite buffer to restore
65
half-written pages in the data files. */
68
trx_sys_doublewrite_init_or_restore_pages(
69
/*======================================*/
70
ibool restore_corrupt_pages);
71
/********************************************************************
72
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
73
multiple tablespace format. */
76
trx_sys_mark_upgraded_to_multiple_tablespaces(void);
77
/*===============================================*/
78
/********************************************************************
79
Determines if a page number is located inside the doublewrite buffer. */
82
trx_doublewrite_page_inside(
83
/*========================*/
84
/* out: TRUE if the location is inside
85
the two blocks of the doublewrite buffer */
86
ulint page_no); /* in: page number */
87
/*******************************************************************
88
Checks if a page address is the trx sys header page. */
93
/* out: TRUE if trx sys header page */
94
ulint space, /* in: space */
95
ulint page_no);/* in: page number */
96
/*********************************************************************
97
Creates and initializes the central memory structures for the transaction
98
system. This is called when the database is started. */
101
trx_sys_init_at_db_start(void);
102
/*==========================*/
103
/*********************************************************************
104
Creates and initializes the transaction system at the database creation. */
107
trx_sys_create(void);
109
/********************************************************************
110
Looks for a free slot for a rollback segment in the trx system file copy. */
113
trx_sysf_rseg_find_free(
114
/*====================*/
115
/* out: slot index or ULINT_UNDEFINED
117
mtr_t* mtr); /* in: mtr */
118
/*******************************************************************
119
Gets the pointer in the nth slot of the rseg array. */
122
trx_sys_get_nth_rseg(
123
/*=================*/
124
/* out: pointer to rseg object, NULL if slot
126
trx_sys_t* sys, /* in: trx system */
127
ulint n); /* in: index of slot */
128
/*******************************************************************
129
Sets the pointer in the nth slot of the rseg array. */
132
trx_sys_set_nth_rseg(
133
/*=================*/
134
trx_sys_t* sys, /* in: trx system */
135
ulint n, /* in: index of slot */
136
trx_rseg_t* rseg); /* in: pointer to rseg object, NULL if slot
138
/**************************************************************************
139
Gets a pointer to the transaction system file copy and x-locks its page. */
144
/* out: pointer to system file copy, page x-locked */
145
mtr_t* mtr); /* in: mtr */
146
/*********************************************************************
147
Gets the space of the nth rollback segment slot in the trx system
151
trx_sysf_rseg_get_space(
152
/*====================*/
154
trx_sysf_t* sys_header, /* in: trx sys file copy */
155
ulint i, /* in: slot index == rseg id */
156
mtr_t* mtr); /* in: mtr */
157
/*********************************************************************
158
Gets the page number of the nth rollback segment slot in the trx system
162
trx_sysf_rseg_get_page_no(
163
/*======================*/
164
/* out: page number, FIL_NULL
166
trx_sysf_t* sys_header, /* in: trx sys file copy */
167
ulint i, /* in: slot index == rseg id */
168
mtr_t* mtr); /* in: mtr */
169
/*********************************************************************
170
Sets the space id of the nth rollback segment slot in the trx system
174
trx_sysf_rseg_set_space(
175
/*====================*/
176
trx_sysf_t* sys_header, /* in: trx sys file copy */
177
ulint i, /* in: slot index == rseg id */
178
ulint space, /* in: space id */
179
mtr_t* mtr); /* in: mtr */
180
/*********************************************************************
181
Sets the page number of the nth rollback segment slot in the trx system
185
trx_sysf_rseg_set_page_no(
186
/*======================*/
187
trx_sysf_t* sys_header, /* in: trx sys file copy */
188
ulint i, /* in: slot index == rseg id */
189
ulint page_no, /* in: page number, FIL_NULL if
190
the slot is reset to unused */
191
mtr_t* mtr); /* in: mtr */
192
/*********************************************************************
193
Allocates a new transaction id. */
196
trx_sys_get_new_trx_id(void);
197
/*========================*/
198
/* out: new, allocated trx id */
199
/*********************************************************************
200
Allocates a new transaction number. */
203
trx_sys_get_new_trx_no(void);
204
/*========================*/
205
/* out: new, allocated trx number */
206
/*********************************************************************
207
Writes a trx id to an index page. In case that the id size changes in
208
some future version, this function should be used instead of
214
byte* ptr, /* in: pointer to memory where written */
215
dulint id); /* in: id */
216
/*********************************************************************
217
Reads a trx id from an index page. In case that the id size changes in
218
some future version, this function should be used instead of
225
const byte* ptr); /* in: pointer to memory from where to read */
226
/********************************************************************
227
Looks for the trx handle with the given id in trx_list. */
232
/* out: the trx handle or NULL if not found */
233
dulint trx_id); /* in: trx id to search for */
234
/********************************************************************
235
Returns the minumum trx id in trx list. This is the smallest id for which
236
the trx can possibly be active. (But, you must look at the trx->conc_state to
237
find out if the minimum trx id transaction itself is active, or already
241
trx_list_get_min_trx_id(void);
242
/*=========================*/
243
/* out: the minimum trx id, or trx_sys->max_trx_id
244
if the trx list is empty */
245
/********************************************************************
246
Checks if a transaction with the given id is active. */
251
/* out: TRUE if active */
252
dulint trx_id);/* in: trx id of the transaction */
253
/********************************************************************
254
Checks that trx is in the trx list. */
259
/* out: TRUE if is in */
260
trx_t* in_trx);/* in: trx */
261
/*********************************************************************
262
Updates the offset information about the end of the MySQL binlog entry
263
which corresponds to the transaction just being committed. In a MySQL
264
replication slave updates the latest master binlog position up to which
265
replication has proceeded. */
268
trx_sys_update_mysql_binlog_offset(
269
/*===============================*/
270
const char* file_name,/* in: MySQL log file name */
271
ib_int64_t offset, /* in: position in that log file */
272
ulint field, /* in: offset of the MySQL log info field in
273
the trx sys header */
274
mtr_t* mtr); /* in: mtr */
275
/*********************************************************************
276
Prints to stderr the MySQL binlog offset info in the trx system header if
277
the magic number shows it valid. */
280
trx_sys_print_mysql_binlog_offset(void);
281
/*===================================*/
282
#ifdef UNIV_HOTBACKUP
283
/*********************************************************************
284
Prints to stderr the MySQL binlog info in the system header if the
285
magic number shows it valid. */
288
trx_sys_print_mysql_binlog_offset_from_page(
289
/*========================================*/
290
const byte* page); /* in: buffer containing the trx
291
system header page, i.e., page number
292
TRX_SYS_PAGE_NO in the tablespace */
293
#endif /* UNIV_HOTBACKUP */
294
/*********************************************************************
295
Prints to stderr the MySQL master log offset info in the trx system header if
296
the magic number shows it valid. */
299
trx_sys_print_mysql_master_log_pos(void);
300
/*====================================*/
301
/*********************************************************************
302
Initializes the tablespace tag system. */
305
trx_sys_file_format_init(void);
306
/*==========================*/
307
/*********************************************************************
308
Closes the tablespace tag system. */
311
trx_sys_file_format_close(void);
312
/*===========================*/
313
/*********************************************************************
314
Get the name representation of the file format from its id. */
317
trx_sys_file_format_id_to_name(
318
/*===========================*/
319
/* out: pointer to the name */
320
const uint id); /* in: id of the file format */
321
/*********************************************************************
322
Set the file format tag unconditonally. */
325
trx_sys_file_format_max_set(
326
/*===========================*/
327
/* out: TRUE if value updated */
328
ulint file_format, /* in: file format id */
329
char** name); /* out: max format name */
330
/*********************************************************************
331
Get the name representation of the file format from its id. */
334
trx_sys_file_format_max_get(void);
335
/*=============================*/
336
/* out: pointer to the max format name */
337
/*********************************************************************
338
Check for the max file format tag stored on disk. */
341
trx_sys_file_format_max_check(
342
/*==========================*/
343
/* out: DB_SUCCESS or error code */
344
ulint max_format_id); /* in: the max format id to check */
345
/************************************************************************
346
Update the file format tag in the tablespace to the max value. */
349
trx_sys_file_format_max_update(
350
/*===========================*/
351
/* out: TRUE if value updated */
352
uint flags, /* in: flags of the table */
353
char** name); /* out: max format name */
354
/* The automatically created system rollback segment has this id */
355
#define TRX_SYS_SYSTEM_RSEG_ID 0
357
/* Space id and page no where the trx system file copy resides */
358
#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
359
#define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
361
/* The offset of the transaction system header on the page */
362
#define TRX_SYS FSEG_PAGE_DATA
364
/* Transaction system header */
365
/*-------------------------------------------------------------*/
366
#define TRX_SYS_TRX_ID_STORE 0 /* the maximum trx id or trx number
367
modulo TRX_SYS_TRX_ID_UPDATE_MARGIN
368
written to a file page by any
369
transaction; the assignment of
370
transaction ids continues from this
371
number rounded up by .._MARGIN plus
372
.._MARGIN when the database is
374
#define TRX_SYS_FSEG_HEADER 8 /* segment header for the tablespace
375
segment the trx system is created
377
#define TRX_SYS_RSEGS (8 + FSEG_HEADER_SIZE)
378
/* the start of the array of rollback
379
segment specification slots */
380
/*-------------------------------------------------------------*/
382
/* Max number of rollback segments: the number of segment specification slots
383
in the transaction system array; rollback segment id must fit in one byte,
384
therefore 256; each slot is currently 8 bytes in size */
385
#define TRX_SYS_N_RSEGS 256
387
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512
388
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
390
#if UNIV_PAGE_SIZE < 4096
391
# error "UNIV_PAGE_SIZE < 4096"
393
/* The offset of the MySQL replication info in the trx system header;
394
this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
395
#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
397
/* The offset of the MySQL binlog offset info in the trx system header */
398
#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)
399
#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /* magic number which shows
400
if we have valid data in the
401
MySQL binlog info; the value
402
is ..._MAGIC_N if yes */
403
#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH 4 /* high 4 bytes of the offset
405
#define TRX_SYS_MYSQL_LOG_OFFSET_LOW 8 /* low 4 bytes of the offset
407
#define TRX_SYS_MYSQL_LOG_NAME 12 /* MySQL log file name */
409
/* The offset of the doublewrite buffer header on the trx system header page */
410
#define TRX_SYS_DOUBLEWRITE (UNIV_PAGE_SIZE - 200)
411
/*-------------------------------------------------------------*/
412
#define TRX_SYS_DOUBLEWRITE_FSEG 0 /* fseg header of the fseg
413
containing the doublewrite
415
#define TRX_SYS_DOUBLEWRITE_MAGIC FSEG_HEADER_SIZE
416
/* 4-byte magic number which
417
shows if we already have
418
created the doublewrite
420
#define TRX_SYS_DOUBLEWRITE_BLOCK1 (4 + FSEG_HEADER_SIZE)
421
/* page number of the
422
first page in the first
424
(= FSP_EXTENT_SIZE) consecutive
425
pages in the doublewrite
427
#define TRX_SYS_DOUBLEWRITE_BLOCK2 (8 + FSEG_HEADER_SIZE)
428
/* page number of the
429
first page in the second
430
sequence of 64 consecutive
431
pages in the doublewrite
433
#define TRX_SYS_DOUBLEWRITE_REPEAT 12 /* we repeat the above 3
434
numbers so that if the trx
435
sys header is half-written
436
to disk, we still may be able
437
to recover the information */
438
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED (24 + FSEG_HEADER_SIZE)
439
/* If this is not yet set to
440
.._N, we must reset the
441
doublewrite buffer, because
442
starting from 4.1.x the space
443
id of a data page is stored to
444
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO */
445
/*-------------------------------------------------------------*/
446
#define TRX_SYS_DOUBLEWRITE_MAGIC_N 536853855
447
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N 1783657386
450
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
452
/* The offset of the file format tag on the trx system header page */
453
#define TRX_SYS_FILE_FORMAT_TAG (UNIV_PAGE_SIZE - 16)
455
/* We use these random constants to reduce the probability of reading
456
garbage (from previous versions) that maps to an actual format id. We
457
use these as bit masks at the time of reading and writing from/to disk. */
458
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW 3645922177UL
459
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH 2745987765UL
461
/* Doublewrite control struct */
462
struct trx_doublewrite_struct{
463
mutex_t mutex; /* mutex protecting the first_free field and
465
ulint block1; /* the page number of the first
466
doublewrite block (64 pages) */
467
ulint block2; /* page number of the second block */
468
ulint first_free; /* first free position in write_buf measured
469
in units of UNIV_PAGE_SIZE */
470
byte* write_buf; /* write buffer used in writing to the
471
doublewrite buffer, aligned to an
472
address divisible by UNIV_PAGE_SIZE
473
(which is required by Windows aio) */
474
byte* write_buf_unaligned; /* pointer to write_buf, but unaligned */
476
buf_block_arr; /* array to store pointers to the buffer
477
blocks which have been cached to write_buf */
480
/* The transaction system central memory data structure; protected by the
482
struct trx_sys_struct{
483
dulint max_trx_id; /* The smallest number not yet
484
assigned as a transaction id or
485
transaction number */
486
UT_LIST_BASE_NODE_T(trx_t) trx_list;
487
/* List of active and committed in
488
memory transactions, sorted on trx id,
490
UT_LIST_BASE_NODE_T(trx_t) mysql_trx_list;
491
/* List of transactions created
493
UT_LIST_BASE_NODE_T(trx_rseg_t) rseg_list;
494
/* List of rollback segment objects */
495
trx_rseg_t* latest_rseg; /* Latest rollback segment in the
496
round-robin assignment of rollback
497
segments to transactions */
498
trx_rseg_t* rseg_array[TRX_SYS_N_RSEGS];
499
/* Pointer array to rollback segments;
500
NULL if slot not in use */
501
ulint rseg_history_len;/* Length of the TRX_RSEG_HISTORY
502
list (update undo logs for committed
503
transactions), protected by
505
UT_LIST_BASE_NODE_T(read_view_t) view_list;
506
/* List of read views sorted on trx no,
510
/* When a trx id which is zero modulo this number (which must be a power of
511
two) is assigned, the field TRX_SYS_TRX_ID_STORE on the transaction system
513
#define TRX_SYS_TRX_ID_WRITE_MARGIN 256
516
#include "trx0sys.ic"