1
/******************************************************
6
Created 3/26/1996 Heikki Tuuri
7
*******************************************************/
14
#include "trx0types.h"
19
#include "sync0sync.h"
25
#include "read0types.h"
27
/* In a MySQL replication slave, in crash recovery we store the master log
28
file name and position here. We have successfully got the updates to InnoDB
29
up to this position. If .._pos is -1, it means no crash recovery was needed,
30
or there was no master log position info inside InnoDB. */
32
extern char trx_sys_mysql_master_log_name[];
33
extern ib_longlong trx_sys_mysql_master_log_pos;
35
/* If this MySQL server uses binary logging, after InnoDB has been inited
36
and if it has done a crash recovery, we store the binlog file name and position
37
here. If .._pos is -1, it means there was no binlog position info inside
40
extern char trx_sys_mysql_bin_log_name[];
41
extern ib_longlong trx_sys_mysql_bin_log_pos;
43
/* The transaction system */
44
extern trx_sys_t* trx_sys;
46
/* Doublewrite system */
47
extern trx_doublewrite_t* trx_doublewrite;
48
extern ibool trx_doublewrite_must_reset_space_ids;
49
extern ibool trx_sys_multiple_tablespace_format;
51
/********************************************************************
52
Creates the doublewrite buffer to a new InnoDB installation. The header of the
53
doublewrite buffer is placed on the trx system header page. */
56
trx_sys_create_doublewrite_buf(void);
57
/*================================*/
58
/********************************************************************
59
At a database startup initializes the doublewrite buffer memory structure if
60
we already have a doublewrite buffer created in the data files. If we are
61
upgrading to an InnoDB version which supports multiple tablespaces, then this
62
function performs the necessary update operations. If we are in a crash
63
recovery, this function uses a possible doublewrite buffer to restore
64
half-written pages in the data files. */
67
trx_sys_doublewrite_init_or_restore_pages(
68
/*======================================*/
69
ibool restore_corrupt_pages);
70
/********************************************************************
71
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
72
multiple tablespace format. */
75
trx_sys_mark_upgraded_to_multiple_tablespaces(void);
76
/*===============================================*/
77
/********************************************************************
78
Determines if a page number is located inside the doublewrite buffer. */
81
trx_doublewrite_page_inside(
82
/*========================*/
83
/* out: TRUE if the location is inside
84
the two blocks of the doublewrite buffer */
85
ulint page_no); /* in: page number */
86
/*******************************************************************
87
Checks if a page address is the trx sys header page. */
92
/* out: TRUE if trx sys header page */
93
ulint space, /* in: space */
94
ulint page_no);/* in: page number */
95
/*********************************************************************
96
Creates and initializes the central memory structures for the transaction
97
system. This is called when the database is started. */
100
trx_sys_init_at_db_start(void);
101
/*==========================*/
102
/*********************************************************************
103
Creates and initializes the transaction system at the database creation. */
106
trx_sys_create(void);
108
/********************************************************************
109
Looks for a free slot for a rollback segment in the trx system file copy. */
112
trx_sysf_rseg_find_free(
113
/*====================*/
114
/* out: slot index or ULINT_UNDEFINED
116
mtr_t* mtr); /* in: mtr */
117
/*******************************************************************
118
Gets the pointer in the nth slot of the rseg array. */
121
trx_sys_get_nth_rseg(
122
/*=================*/
123
/* out: pointer to rseg object, NULL if slot
125
trx_sys_t* sys, /* in: trx system */
126
ulint n); /* in: index of slot */
127
/*******************************************************************
128
Sets the pointer in the nth slot of the rseg array. */
131
trx_sys_set_nth_rseg(
132
/*=================*/
133
trx_sys_t* sys, /* in: trx system */
134
ulint n, /* in: index of slot */
135
trx_rseg_t* rseg); /* in: pointer to rseg object, NULL if slot
137
/**************************************************************************
138
Gets a pointer to the transaction system file copy and x-locks its page. */
143
/* out: pointer to system file copy, page x-locked */
144
mtr_t* mtr); /* in: mtr */
145
/*********************************************************************
146
Gets the space of the nth rollback segment slot in the trx system
150
trx_sysf_rseg_get_space(
151
/*====================*/
153
trx_sysf_t* sys_header, /* in: trx sys file copy */
154
ulint i, /* in: slot index == rseg id */
155
mtr_t* mtr); /* in: mtr */
156
/*********************************************************************
157
Gets the page number of the nth rollback segment slot in the trx system
161
trx_sysf_rseg_get_page_no(
162
/*======================*/
163
/* out: page number, FIL_NULL
165
trx_sysf_t* sys_header, /* in: trx sys file copy */
166
ulint i, /* in: slot index == rseg id */
167
mtr_t* mtr); /* in: mtr */
168
/*********************************************************************
169
Sets the space id of the nth rollback segment slot in the trx system
173
trx_sysf_rseg_set_space(
174
/*====================*/
175
trx_sysf_t* sys_header, /* in: trx sys file copy */
176
ulint i, /* in: slot index == rseg id */
177
ulint space, /* in: space id */
178
mtr_t* mtr); /* in: mtr */
179
/*********************************************************************
180
Sets the page number of the nth rollback segment slot in the trx system
184
trx_sysf_rseg_set_page_no(
185
/*======================*/
186
trx_sysf_t* sys_header, /* in: trx sys file copy */
187
ulint i, /* in: slot index == rseg id */
188
ulint page_no, /* in: page number, FIL_NULL if
189
the slot is reset to unused */
190
mtr_t* mtr); /* in: mtr */
191
/*********************************************************************
192
Allocates a new transaction id. */
195
trx_sys_get_new_trx_id(void);
196
/*========================*/
197
/* out: new, allocated trx id */
198
/*********************************************************************
199
Allocates a new transaction number. */
202
trx_sys_get_new_trx_no(void);
203
/*========================*/
204
/* out: new, allocated trx number */
205
/*********************************************************************
206
Writes a trx id to an index page. In case that the id size changes in
207
some future version, this function should be used instead of
213
byte* ptr, /* in: pointer to memory where written */
214
dulint id); /* in: id */
215
/*********************************************************************
216
Reads a trx id from an index page. In case that the id size changes in
217
some future version, this function should be used instead of
224
byte* ptr); /* in: pointer to memory from where to read */
225
/********************************************************************
226
Looks for the trx handle with the given id in trx_list. */
231
/* out: the trx handle or NULL if not found */
232
dulint trx_id); /* in: trx id to search for */
233
/********************************************************************
234
Returns the minumum trx id in trx list. This is the smallest id for which
235
the trx can possibly be active. (But, you must look at the trx->conc_state to
236
find out if the minimum trx id transaction itself is active, or already
240
trx_list_get_min_trx_id(void);
241
/*=========================*/
242
/* out: the minimum trx id, or trx_sys->max_trx_id
243
if the trx list is empty */
244
/********************************************************************
245
Checks if a transaction with the given id is active. */
250
/* out: TRUE if active */
251
dulint trx_id);/* in: trx id of the transaction */
252
/********************************************************************
253
Checks that trx is in the trx list. */
258
/* out: TRUE if is in */
259
trx_t* in_trx);/* in: trx */
260
/*********************************************************************
261
Updates the offset information about the end of the MySQL binlog entry
262
which corresponds to the transaction just being committed. In a MySQL
263
replication slave updates the latest master binlog position up to which
264
replication has proceeded. */
267
trx_sys_update_mysql_binlog_offset(
268
/*===============================*/
269
const char* file_name,/* in: MySQL log file name */
270
ib_longlong offset, /* in: position in that log file */
271
ulint field, /* in: offset of the MySQL log info field in
272
the trx sys header */
273
mtr_t* mtr); /* in: mtr */
274
/*********************************************************************
275
Prints to stderr the MySQL binlog offset info in the trx system header if
276
the magic number shows it valid. */
279
trx_sys_print_mysql_binlog_offset(void);
280
/*===================================*/
281
#ifdef UNIV_HOTBACKUP
282
/*********************************************************************
283
Prints to stderr the MySQL binlog info in the system header if the
284
magic number shows it valid. */
287
trx_sys_print_mysql_binlog_offset_from_page(
288
/*========================================*/
289
byte* page); /* in: buffer containing the trx system header page,
290
i.e., page number TRX_SYS_PAGE_NO in the tablespace */
291
#endif /* UNIV_HOTBACKUP */
292
/*********************************************************************
293
Prints to stderr the MySQL master log offset info in the trx system header if
294
the magic number shows it valid. */
297
trx_sys_print_mysql_master_log_pos(void);
298
/*====================================*/
300
/* The automatically created system rollback segment has this id */
301
#define TRX_SYS_SYSTEM_RSEG_ID 0
303
/* Space id and page no where the trx system file copy resides */
304
#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
305
#define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
307
/* The offset of the transaction system header on the page */
308
#define TRX_SYS FSEG_PAGE_DATA
310
/* Transaction system header */
311
/*-------------------------------------------------------------*/
312
#define TRX_SYS_TRX_ID_STORE 0 /* the maximum trx id or trx number
313
modulo TRX_SYS_TRX_ID_UPDATE_MARGIN
314
written to a file page by any
315
transaction; the assignment of
316
transaction ids continues from this
317
number rounded up by .._MARGIN plus
318
.._MARGIN when the database is
320
#define TRX_SYS_FSEG_HEADER 8 /* segment header for the tablespace
321
segment the trx system is created
323
#define TRX_SYS_RSEGS (8 + FSEG_HEADER_SIZE)
324
/* the start of the array of rollback
325
segment specification slots */
326
/*-------------------------------------------------------------*/
328
/* Max number of rollback segments: the number of segment specification slots
329
in the transaction system array; rollback segment id must fit in one byte,
330
therefore 256; each slot is currently 8 bytes in size */
331
#define TRX_SYS_N_RSEGS 256
333
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512
334
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
336
/* The offset of the MySQL replication info in the trx system header;
337
this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
338
#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
340
/* The offset of the MySQL binlog offset info in the trx system header */
341
#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)
342
#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /* magic number which shows
343
if we have valid data in the
344
MySQL binlog info; the value
345
is ..._MAGIC_N if yes */
346
#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH 4 /* high 4 bytes of the offset
348
#define TRX_SYS_MYSQL_LOG_OFFSET_LOW 8 /* low 4 bytes of the offset
350
#define TRX_SYS_MYSQL_LOG_NAME 12 /* MySQL log file name */
352
/* The offset of the doublewrite buffer header on the trx system header page */
353
#define TRX_SYS_DOUBLEWRITE (UNIV_PAGE_SIZE - 200)
354
/*-------------------------------------------------------------*/
355
#define TRX_SYS_DOUBLEWRITE_FSEG 0 /* fseg header of the fseg
356
containing the doublewrite
358
#define TRX_SYS_DOUBLEWRITE_MAGIC FSEG_HEADER_SIZE
359
/* 4-byte magic number which
360
shows if we already have
361
created the doublewrite
363
#define TRX_SYS_DOUBLEWRITE_BLOCK1 (4 + FSEG_HEADER_SIZE)
364
/* page number of the
365
first page in the first
367
(= FSP_EXTENT_SIZE) consecutive
368
pages in the doublewrite
370
#define TRX_SYS_DOUBLEWRITE_BLOCK2 (8 + FSEG_HEADER_SIZE)
371
/* page number of the
372
first page in the second
373
sequence of 64 consecutive
374
pages in the doublewrite
376
#define TRX_SYS_DOUBLEWRITE_REPEAT 12 /* we repeat the above 3
377
numbers so that if the trx
378
sys header is half-written
379
to disk, we still may be able
380
to recover the information */
381
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED (24 + FSEG_HEADER_SIZE)
382
/* If this is not yet set to
383
.._N, we must reset the
384
doublewrite buffer, because
385
starting from 4.1.x the space
386
id of a data page is stored to
387
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO */
388
/*-------------------------------------------------------------*/
389
#define TRX_SYS_DOUBLEWRITE_MAGIC_N 536853855
390
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N 1783657386
393
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
395
/* Doublewrite control struct */
396
struct trx_doublewrite_struct{
397
mutex_t mutex; /* mutex protecting the first_free field and
399
ulint block1; /* the page number of the first
400
doublewrite block (64 pages) */
401
ulint block2; /* page number of the second block */
402
ulint first_free; /* first free position in write_buf measured
403
in units of UNIV_PAGE_SIZE */
404
byte* write_buf; /* write buffer used in writing to the
405
doublewrite buffer, aligned to an
406
address divisible by UNIV_PAGE_SIZE
407
(which is required by Windows aio) */
408
byte* write_buf_unaligned; /* pointer to write_buf, but unaligned */
410
buf_block_arr; /* array to store pointers to the buffer
411
blocks which have been cached to write_buf */
414
/* The transaction system central memory data structure; protected by the
416
struct trx_sys_struct{
417
dulint max_trx_id; /* The smallest number not yet
418
assigned as a transaction id or
419
transaction number */
420
UT_LIST_BASE_NODE_T(trx_t) trx_list;
421
/* List of active and committed in
422
memory transactions, sorted on trx id,
424
UT_LIST_BASE_NODE_T(trx_t) mysql_trx_list;
425
/* List of transactions created
427
UT_LIST_BASE_NODE_T(trx_rseg_t) rseg_list;
428
/* List of rollback segment objects */
429
trx_rseg_t* latest_rseg; /* Latest rollback segment in the
430
round-robin assignment of rollback
431
segments to transactions */
432
trx_rseg_t* rseg_array[TRX_SYS_N_RSEGS];
433
/* Pointer array to rollback segments;
434
NULL if slot not in use */
435
ulint rseg_history_len;/* Length of the TRX_RSEG_HISTORY
436
list (update undo logs for committed
437
transactions), protected by
439
UT_LIST_BASE_NODE_T(read_view_t) view_list;
440
/* List of read views sorted on trx no,
444
/* When a trx id which is zero modulo this number (which must be a power of
445
two) is assigned, the field TRX_SYS_TRX_ID_STORE on the transaction system
447
#define TRX_SYS_TRX_ID_WRITE_MARGIN 256
450
#include "trx0sys.ic"