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
#include <drizzled/atomics.h>
46
/** the highest commit identifier assigned in the system */
47
extern drizzled::atomic<uint64_t> trx_sys_commit_id;
49
/** The transaction system */
50
extern trx_sys_t* trx_sys;
52
/** Doublewrite system */
53
extern trx_doublewrite_t* trx_doublewrite;
54
/** The following is set to TRUE when we are upgrading from pre-4.1
55
format data files to the multiple tablespaces format data files */
56
extern ibool trx_doublewrite_must_reset_space_ids;
57
/** Set to TRUE when the doublewrite buffer is being created */
58
extern ibool trx_doublewrite_buf_is_being_created;
59
/** The following is TRUE when we are using the database in the
60
post-4.1 format, i.e., we have successfully upgraded, or have created
61
a new database installation */
62
extern ibool trx_sys_multiple_tablespace_format;
64
/****************************************************************//**
65
Creates the doublewrite buffer to a new InnoDB installation. The header of the
66
doublewrite buffer is placed on the trx system header page. */
69
trx_sys_create_doublewrite_buf(void);
70
/*================================*/
71
/****************************************************************//**
72
At a database startup initializes the doublewrite buffer memory structure if
73
we already have a doublewrite buffer created in the data files. If we are
74
upgrading to an InnoDB version which supports multiple tablespaces, then this
75
function performs the necessary update operations. If we are in a crash
76
recovery, this function uses a possible doublewrite buffer to restore
77
half-written pages in the data files. */
80
trx_sys_doublewrite_init_or_restore_pages(
81
/*======================================*/
82
ibool restore_corrupt_pages); /*!< in: TRUE=restore pages */
83
/****************************************************************//**
84
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
85
multiple tablespace format. */
88
trx_sys_mark_upgraded_to_multiple_tablespaces(void);
89
/*===============================================*/
90
/****************************************************************//**
91
Determines if a page number is located inside the doublewrite buffer.
92
@return TRUE if the location is inside the two blocks of the
96
trx_doublewrite_page_inside(
97
/*========================*/
98
ulint page_no); /*!< in: page number */
99
/***************************************************************//**
100
Checks if a page address is the trx sys header page.
101
@return TRUE if trx sys header page */
106
ulint space, /*!< in: space */
107
ulint page_no);/*!< in: page number */
108
/*****************************************************************//**
109
Creates and initializes the central memory structures for the transaction
110
system. This is called when the database is started. */
113
trx_sys_init_at_db_start(void);
114
/*==========================*/
115
/*****************************************************************//**
116
Creates and initializes the transaction system at the database creation. */
119
trx_sys_create(void);
121
/****************************************************************//**
122
Looks for a free slot for a rollback segment in the trx system file copy.
123
@return slot index or ULINT_UNDEFINED if not found */
126
trx_sysf_rseg_find_free(
127
/*====================*/
128
mtr_t* mtr); /*!< in: mtr */
129
/***************************************************************//**
130
Gets the pointer in the nth slot of the rseg array.
131
@return pointer to rseg object, NULL if slot not in use */
134
trx_sys_get_nth_rseg(
135
/*=================*/
136
trx_sys_t* sys, /*!< in: trx system */
137
ulint n); /*!< in: index of slot */
138
/***************************************************************//**
139
Sets the pointer in the nth slot of the rseg array. */
142
trx_sys_set_nth_rseg(
143
/*=================*/
144
trx_sys_t* sys, /*!< in: trx system */
145
ulint n, /*!< in: index of slot */
146
trx_rseg_t* rseg); /*!< in: pointer to rseg object, NULL if slot
148
/**********************************************************************//**
149
Gets a pointer to the transaction system file copy and x-locks its page.
150
@return pointer to system file copy, page x-locked */
155
mtr_t* mtr); /*!< in: mtr */
156
/*****************************************************************//**
157
Gets the space of the nth rollback segment slot in the trx system
162
trx_sysf_rseg_get_space(
163
/*====================*/
164
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
165
ulint i, /*!< in: slot index == rseg id */
166
mtr_t* mtr); /*!< in: mtr */
167
/*****************************************************************//**
168
Gets the page number of the nth rollback segment slot in the trx system
170
@return page number, FIL_NULL if slot unused */
173
trx_sysf_rseg_get_page_no(
174
/*======================*/
175
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
176
ulint i, /*!< in: slot index == rseg id */
177
mtr_t* mtr); /*!< in: mtr */
178
/*****************************************************************//**
179
Sets the space id of the nth rollback segment slot in the trx system
183
trx_sysf_rseg_set_space(
184
/*====================*/
185
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
186
ulint i, /*!< in: slot index == rseg id */
187
ulint space, /*!< in: space id */
188
mtr_t* mtr); /*!< in: mtr */
189
/*****************************************************************//**
190
Sets the page number of the nth rollback segment slot in the trx system
194
trx_sysf_rseg_set_page_no(
195
/*======================*/
196
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
197
ulint i, /*!< in: slot index == rseg id */
198
ulint page_no, /*!< in: page number, FIL_NULL if
199
the slot is reset to unused */
200
mtr_t* mtr); /*!< in: mtr */
201
/*****************************************************************//**
202
Allocates a new transaction id.
203
@return new, allocated trx id */
206
trx_sys_get_new_trx_id(void);
207
/*========================*/
208
/*****************************************************************//**
209
Allocates a new transaction number.
210
@return new, allocated trx number */
213
trx_sys_get_new_trx_no(void);
214
/*========================*/
215
#endif /* !UNIV_HOTBACKUP */
216
/*****************************************************************//**
217
Writes a trx id to an index page. In case that the id size changes in
218
some future version, this function should be used instead of
224
byte* ptr, /*!< in: pointer to memory where written */
225
trx_id_t id); /*!< in: id */
226
#ifndef UNIV_HOTBACKUP
227
/*****************************************************************//**
228
Reads a trx id from an index page. In case that the id size changes in
229
some future version, this function should be used instead of
236
const byte* ptr); /*!< in: pointer to memory from where to read */
237
/****************************************************************//**
238
Looks for the trx handle with the given id in trx_list.
239
@return the trx handle or NULL if not found */
244
trx_id_t trx_id);/*!< in: trx id to search for */
245
/****************************************************************//**
246
Returns the minumum trx id in trx list. This is the smallest id for which
247
the trx can possibly be active. (But, you must look at the trx->conc_state to
248
find out if the minimum trx id transaction itself is active, or already
250
@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
253
trx_list_get_min_trx_id(void);
254
/*=========================*/
255
/****************************************************************//**
256
Checks if a transaction with the given id is active.
257
@return TRUE if active */
262
trx_id_t trx_id);/*!< in: trx id of the transaction */
263
/****************************************************************//**
264
Checks that trx is in the trx list.
265
@return TRUE if is in */
270
trx_t* in_trx);/*!< in: trx */
271
/*****************************************************************//**
272
Writes to the sys header file the latest commit_id in the system */
275
trx_sys_flush_commit_id(uint64_t commit_id, ulint field, mtr_t* mtr);
276
/*****************************************************************//**
277
Reads the latest commit_id into trx_sys_commit_id */
280
trx_sys_read_commit_id(void);
281
/*****************************************************************//**
282
Prints to stderr the MySQL master log offset info in the trx system header if
283
the magic number shows it valid. */
286
trx_sys_print_mysql_master_log_pos(void);
287
/*====================================*/
288
/*****************************************************************//**
289
Initializes the tablespace tag system. */
292
trx_sys_file_format_init(void);
293
/*==========================*/
294
/*****************************************************************//**
295
Closes the tablespace tag system. */
298
trx_sys_file_format_close(void);
299
/*===========================*/
300
/********************************************************************//**
301
Tags the system table space with minimum format id if it has not been
303
WARNING: This function is only called during the startup and AFTER the
304
redo log application during recovery has finished. */
307
trx_sys_file_format_tag_init(void);
308
/*==============================*/
309
#ifndef UNIV_HOTBACKUP
310
/*****************************************************************//**
311
Shutdown/Close the transaction system. */
316
#endif /* !UNIV_HOTBACKUP */
317
/*****************************************************************//**
318
Get the name representation of the file format from its id.
319
@return pointer to the name */
322
trx_sys_file_format_id_to_name(
323
/*===========================*/
324
const ulint id); /*!< in: id of the file format */
325
/*****************************************************************//**
326
Set the file format id unconditionally except if it's already the
328
@return TRUE if value updated */
331
trx_sys_file_format_max_set(
332
/*========================*/
333
ulint format_id, /*!< in: file format id */
334
const char** name); /*!< out: max file format name or
335
NULL if not needed. */
336
/*****************************************************************//**
337
Get the name representation of the file format from its id.
338
@return pointer to the max format name */
341
trx_sys_file_format_max_get(void);
342
/*=============================*/
343
/*****************************************************************//**
344
Check for the max file format tag stored on disk.
345
@return DB_SUCCESS or error code */
348
trx_sys_file_format_max_check(
349
/*==========================*/
350
ulint max_format_id); /*!< in: the max format id to check */
351
/********************************************************************//**
352
Update the file format tag in the system tablespace only if the given
353
format id is greater than the known max id.
354
@return TRUE if format_id was bigger than the known max id */
357
trx_sys_file_format_max_upgrade(
358
/*============================*/
359
const char** name, /*!< out: max file format name */
360
ulint format_id); /*!< in: file format identifier */
361
#else /* !UNIV_HOTBACKUP */
362
/*****************************************************************//**
363
Reads the file format id from the first system table space file.
364
Even if the call succeeds and returns TRUE, the returned format id
365
may be ULINT_UNDEFINED signalling that the format id was not present
367
@return TRUE if call succeeds */
370
trx_sys_read_file_format_id(
371
/*========================*/
372
const char *pathname, /*!< in: pathname of the first system
374
ulint *format_id); /*!< out: file format of the system table
376
/*****************************************************************//**
377
Reads the file format id from the given per-table data file.
378
@return TRUE if call succeeds */
381
trx_sys_read_pertable_file_format_id(
382
/*=================================*/
383
const char *pathname, /*!< in: pathname of a per-table
385
ulint *format_id); /*!< out: file format of the per-table
387
/*****************************************************************//**
388
Get the name representation of the file format from its id.
389
@return pointer to the name */
392
trx_sys_file_format_id_to_name(
393
/*===========================*/
394
const ulint id); /*!< in: id of the file format */
396
#endif /* !UNIV_HOTBACKUP */
397
/*********************************************************************
398
Creates the rollback segments */
401
trx_sys_create_rsegs(
402
/*=================*/
403
ulint n_rsegs); /*!< number of rollback segments to create */
405
/* The automatically created system rollback segment has this id */
406
#define TRX_SYS_SYSTEM_RSEG_ID 0
408
/* Space id and page no where the trx system file copy resides */
409
#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
411
#define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
413
/* The offset of the transaction system header on the page */
414
#define TRX_SYS FSEG_PAGE_DATA
416
/** Transaction system header */
417
/*------------------------------------------------------------- @{ */
418
#define TRX_SYS_TRX_ID_STORE 0 /*!< the maximum trx id or trx
420
TRX_SYS_TRX_ID_UPDATE_MARGIN
421
written to a file page by any
422
transaction; the assignment of
423
transaction ids continues from
424
this number rounded up by
425
TRX_SYS_TRX_ID_UPDATE_MARGIN
427
TRX_SYS_TRX_ID_UPDATE_MARGIN
430
#define TRX_SYS_FSEG_HEADER 8 /*!< segment header for the
431
tablespace segment the trx
432
system is created into */
433
#define TRX_SYS_RSEGS (8 + FSEG_HEADER_SIZE)
434
/*!< the start of the array of
435
rollback segment specification
437
/*------------------------------------------------------------- @} */
439
/* Max number of rollback segments: the number of segment specification slots
440
in the transaction system array; rollback segment id must fit in one (signed)
441
byte, therefore 128; each slot is currently 8 bytes in size. If you want
442
to raise the level to 256 then you will need to fix some assertions that
443
impose the 7 bit restriction. e.g., mach_write_to_3() */
444
#define TRX_SYS_N_RSEGS 128
445
/* Originally, InnoDB defined TRX_SYS_N_RSEGS as 256 but created only one
446
rollback segment. It initialized some arrays with this number of entries.
447
We must remember this limit in order to keep file compatibility. */
448
#define TRX_SYS_OLD_N_RSEGS 256
450
/** Maximum length of MySQL binlog file name, in bytes.
451
@see trx_sys_mysql_master_log_name
452
@see trx_sys_mysql_bin_log_name */
453
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512
454
/** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
455
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
457
#if UNIV_PAGE_SIZE < 4096
458
# error "UNIV_PAGE_SIZE < 4096"
460
/** The offset of the MySQL replication info in the trx system header;
461
this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
462
#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
464
/** The offset of the MySQL binlog offset info in the trx system header */
465
#define TRX_SYS_DRIZZLE_LOG_INFO (UNIV_PAGE_SIZE - 1000)
466
#define TRX_SYS_DRIZZLE_MAX_COMMIT_ID 8 /*!< the maximum commit id
467
assigned in the system */
468
#define TRX_SYS_DRIZZLE_LOG_NAME 12 /*!< Unused */
470
/** Doublewrite buffer */
472
/** The offset of the doublewrite buffer header on the trx system header page */
473
#define TRX_SYS_DOUBLEWRITE (UNIV_PAGE_SIZE - 200)
474
/*-------------------------------------------------------------*/
475
#define TRX_SYS_DOUBLEWRITE_FSEG 0 /*!< fseg header of the fseg
476
containing the doublewrite
478
#define TRX_SYS_DOUBLEWRITE_MAGIC FSEG_HEADER_SIZE
479
/*!< 4-byte magic number which
480
shows if we already have
481
created the doublewrite
483
#define TRX_SYS_DOUBLEWRITE_BLOCK1 (4 + FSEG_HEADER_SIZE)
484
/*!< page number of the
485
first page in the first
487
(= FSP_EXTENT_SIZE) consecutive
488
pages in the doublewrite
490
#define TRX_SYS_DOUBLEWRITE_BLOCK2 (8 + FSEG_HEADER_SIZE)
491
/*!< page number of the
492
first page in the second
493
sequence of 64 consecutive
494
pages in the doublewrite
496
#define TRX_SYS_DOUBLEWRITE_REPEAT 12 /*!< we repeat
497
TRX_SYS_DOUBLEWRITE_MAGIC,
498
TRX_SYS_DOUBLEWRITE_BLOCK1,
499
TRX_SYS_DOUBLEWRITE_BLOCK2
500
so that if the trx sys
501
header is half-written
502
to disk, we still may
503
be able to recover the
505
/** If this is not yet set to TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N,
506
we must reset the doublewrite buffer, because starting from 4.1.x the
507
space id of a data page is stored into
508
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO. */
509
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED (24 + FSEG_HEADER_SIZE)
511
/*-------------------------------------------------------------*/
512
/** Contents of TRX_SYS_DOUBLEWRITE_MAGIC */
513
#define TRX_SYS_DOUBLEWRITE_MAGIC_N 536853855
514
/** Contents of TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED */
515
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N 1783657386
517
/** Size of the doublewrite block in pages */
518
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
521
#ifndef UNIV_HOTBACKUP
522
/** File format tag */
524
/** The offset of the file format tag on the trx system header page
525
(TRX_SYS_PAGE_NO of TRX_SYS_SPACE) */
526
#define TRX_SYS_FILE_FORMAT_TAG (UNIV_PAGE_SIZE - 16)
528
/** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format
529
identifier is added to this constant. */
530
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW 3645922177UL
531
/** Contents of TRX_SYS_FILE_FORMAT_TAG+4 when valid */
532
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH 2745987765UL
533
/** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format
534
identifier is added to this 64-bit constant. */
535
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N \
536
((ib_uint64_t) TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH << 32 \
537
| TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW)
540
/** Doublewrite control struct */
541
struct trx_doublewrite_struct{
542
mutex_t mutex; /*!< mutex protecting the first_free field and
544
ulint block1; /*!< the page number of the first
545
doublewrite block (64 pages) */
546
ulint block2; /*!< page number of the second block */
547
ulint first_free; /*!< first free position in write_buf measured
548
in units of UNIV_PAGE_SIZE */
549
byte* write_buf; /*!< write buffer used in writing to the
550
doublewrite buffer, aligned to an
551
address divisible by UNIV_PAGE_SIZE
552
(which is required by Windows aio) */
553
byte* write_buf_unaligned;
554
/*!< pointer to write_buf, but unaligned */
556
buf_block_arr; /*!< array to store pointers to the buffer
557
blocks which have been cached to write_buf */
560
/** The transaction system central memory data structure; protected by the
562
struct trx_sys_struct{
563
trx_id_t max_trx_id; /*!< The smallest number not yet
564
assigned as a transaction id or
565
transaction number */
567
UT_LIST_BASE_NODE_T(trx_t) trx_list;
568
/*!< List of active and committed in
569
memory transactions, sorted on trx id,
571
UT_LIST_BASE_NODE_T(trx_t) mysql_trx_list;
572
/*!< List of transactions created
574
UT_LIST_BASE_NODE_T(trx_rseg_t) rseg_list;
575
/*!< List of rollback segment
577
trx_rseg_t* latest_rseg; /*!< Latest rollback segment in the
578
round-robin assignment of rollback
579
segments to transactions */
580
trx_rseg_t* rseg_array[TRX_SYS_N_RSEGS];
581
/*!< Pointer array to rollback
582
segments; NULL if slot not in use */
583
ulint rseg_history_len;/*!< Length of the TRX_RSEG_HISTORY
584
list (update undo logs for committed
585
transactions), protected by
587
UT_LIST_BASE_NODE_T(read_view_t) view_list;
588
/*!< List of read views sorted
589
on trx no, biggest first */
592
/** When a trx id which is zero modulo this number (which must be a power of
593
two) is assigned, the field TRX_SYS_TRX_ID_STORE on the transaction system
595
#define TRX_SYS_TRX_ID_WRITE_MARGIN 256
596
#endif /* !UNIV_HOTBACKUP */
599
#include "trx0sys.ic"