127
126
static const ulint FILE_FORMAT_NAME_N
128
127
= sizeof(file_format_name_map) / sizeof(file_format_name_map[0]);
130
#ifdef UNIV_PFS_MUTEX
131
/* Key to register the mutex with performance schema */
132
UNIV_INTERN mysql_pfs_key_t trx_doublewrite_mutex_key;
133
UNIV_INTERN mysql_pfs_key_t file_format_max_mutex_key;
134
#endif /* UNIV_PFS_MUTEX */
136
129
#ifndef UNIV_HOTBACKUP
137
130
/** This is used to track the maximum file format id known to InnoDB. It's
138
updated via SET GLOBAL innodb_file_format_max = 'x' or when we open
131
updated via SET GLOBAL innodb_file_format_check = 'x' or when we open
139
132
or create a table. */
140
133
static file_format_t file_format_max;
186
179
os_do_not_call_flush_at_each_write = TRUE;
187
180
#endif /* UNIV_DO_FLUSH */
189
mutex_create(trx_doublewrite_mutex_key,
190
&trx_doublewrite->mutex, SYNC_DOUBLEWRITE);
182
mutex_create(&trx_doublewrite->mutex, SYNC_DOUBLEWRITE);
192
184
trx_doublewrite->first_free = 0;
354
344
the page position in the tablespace, then the page
355
345
has not been written to in doublewrite. */
357
#ifdef UNIV_SYNC_DEBUG
359
#endif /* UNIV_SYNC_DEBUG */
360
buf_page_get(TRX_SYS_SPACE, 0, page_no,
347
new_block = buf_page_get(TRX_SYS_SPACE, 0, page_no,
362
349
buf_block_dbg_add_level(new_block,
363
350
SYNC_NO_ORDER_CHECK);
670
657
sys_header = trx_sysf_get(&mtr);
672
mlog_write_ull(sys_header + TRX_SYS_TRX_ID_STORE,
673
trx_sys->max_trx_id, &mtr);
659
mlog_write_dulint(sys_header + TRX_SYS_TRX_ID_STORE,
660
trx_sys->max_trx_id, &mtr);
674
661
mtr_commit(&mtr);
917
903
sys_header = trx_sysf_get(mtr);
919
905
/* Start counting transaction ids from number 1 up */
920
mach_write_to_8(sys_header + TRX_SYS_TRX_ID_STORE, 1);
922
/* Reset the rollback segment slots. Old versions of InnoDB
923
define TRX_SYS_N_RSEGS as 256 (TRX_SYS_OLD_N_RSEGS) and expect
924
that the whole array is initialized. */
925
ptr = TRX_SYS_RSEGS + sys_header;
926
len = ut_max(TRX_SYS_OLD_N_RSEGS, TRX_SYS_N_RSEGS)
927
* TRX_SYS_RSEG_SLOT_SIZE;
928
memset(ptr, 0xff, len);
930
ut_a(ptr <= page + (UNIV_PAGE_SIZE - FIL_PAGE_DATA_END));
932
/* Initialize all of the page. This part used to be uninitialized. */
933
memset(ptr, 0, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page - ptr);
935
mlog_log_string(sys_header, UNIV_PAGE_SIZE - FIL_PAGE_DATA_END
936
+ page - sys_header, mtr);
906
mlog_write_dulint(sys_header + TRX_SYS_TRX_ID_STORE,
907
ut_dulint_create(0, 1), mtr);
909
/* Reset the rollback segment slots */
910
for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
912
trx_sysf_rseg_set_space(sys_header, i, ULINT_UNDEFINED, mtr);
913
trx_sysf_rseg_set_page_no(sys_header, i, FIL_NULL, mtr);
916
/* The remaining area (up to the page trailer) is uninitialized.
917
Silence Valgrind warnings about it. */
918
UNIV_MEM_VALID(sys_header + (TRX_SYS_RSEGS
919
+ TRX_SYS_N_RSEGS * TRX_SYS_RSEG_SLOT_SIZE
920
+ TRX_SYS_RSEG_SPACE),
921
(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END
923
+ TRX_SYS_N_RSEGS * TRX_SYS_RSEG_SLOT_SIZE
924
+ TRX_SYS_RSEG_SPACE))
925
+ page - sys_header);
938
927
/* Create the first rollback segment in the SYSTEM tablespace */
939
slot_no = trx_sysf_rseg_find_free(mtr);
940
page_no = trx_rseg_header_create(TRX_SYS_SPACE, 0, ULINT_MAX, slot_no,
928
page_no = trx_rseg_header_create(TRX_SYS_SPACE, 0, ULINT_MAX, &slot_no,
942
930
ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
943
ut_a(page_no == FSP_FIRST_RSEG_PAGE_NO);
931
ut_a(page_no != FIL_NULL);
945
933
mutex_exit(&kernel_mutex);
980
968
to the disk-based header! Thus trx id values will not overlap when
981
969
the database is repeatedly started! */
983
trx_sys->max_trx_id = 2 * TRX_SYS_TRX_ID_WRITE_MARGIN
984
+ ut_uint64_align_up(mach_read_from_8(sys_header
985
+ TRX_SYS_TRX_ID_STORE),
986
TRX_SYS_TRX_ID_WRITE_MARGIN);
971
trx_sys->max_trx_id = ut_dulint_add(
972
ut_dulint_align_up(mtr_read_dulint(
974
+ TRX_SYS_TRX_ID_STORE, &mtr),
975
TRX_SYS_TRX_ID_WRITE_MARGIN),
976
2 * TRX_SYS_TRX_ID_WRITE_MARGIN);
988
978
UT_LIST_INIT(trx_sys->mysql_trx_list);
989
979
trx_dummy_sess = sess_open();
1073
1064
file_format_max.name = trx_sys_file_format_id_to_name(format_id);
1075
1066
ptr = buf_block_get_frame(block) + TRX_SYS_FILE_FORMAT_TAG;
1076
tag_value = format_id + TRX_SYS_FILE_FORMAT_TAG_MAGIC_N;
1067
tag_value_low = format_id + TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
1079
1070
*name = file_format_max.name;
1082
mlog_write_ull(ptr, tag_value, &mtr);
1075
ut_dulint_create(TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH,
1084
1079
mtr_commit(&mtr);
1112
1108
mtr_commit(&mtr);
1114
file_format_id -= TRX_SYS_FILE_FORMAT_TAG_MAGIC_N;
1110
format_id = file_format_id.low - TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
1116
if (file_format_id >= FILE_FORMAT_NAME_N) {
1112
if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH
1113
|| format_id >= FILE_FORMAT_NAME_N) {
1118
1115
/* Either it has never been tagged, or garbage in it. */
1119
1116
return(ULINT_UNDEFINED);
1122
return((ulint) file_format_id);
1125
1122
/*****************************************************************//**
1286
1283
trx_sys_file_format_init(void)
1287
1284
/*==========================*/
1289
mutex_create(file_format_max_mutex_key,
1290
&file_format_max.mutex, SYNC_FILE_FORMAT_TAG);
1286
mutex_create(&file_format_max.mutex, SYNC_FILE_FORMAT_TAG);
1292
1288
/* We don't need a mutex here, as this function should only
1293
1289
be called once at start up. */
1294
file_format_max.id = DICT_TF_FORMAT_MIN;
1290
file_format_max.id = DICT_TF_FORMAT_51;
1296
1292
file_format_max.name = trx_sys_file_format_id_to_name(
1297
1293
file_format_max.id);
1307
1303
/* Does nothing at the moment */
1310
/*********************************************************************
1311
Creates the rollback segments */
1314
trx_sys_create_rsegs(
1315
/*=================*/
1316
ulint n_rsegs) /*!< number of rollback segments to create */
1318
ulint new_rsegs = 0;
1320
/* Do not create additional rollback segments if
1321
innodb_force_recovery has been set and the database
1322
was not shutdown cleanly. */
1323
if (!srv_force_recovery && !recv_needed_recovery) {
1326
for (i = 0; i < n_rsegs; ++i) {
1328
if (trx_rseg_create() != NULL) {
1336
if (new_rsegs > 0) {
1338
"InnoDB: %lu rollback segment(s) active.\n",
1343
1305
#else /* !UNIV_HOTBACKUP */
1344
1306
/*****************************************************************//**
1345
1307
Prints to stderr the MySQL binlog info in the system header if the
1425
1386
if (!success) {
1426
1387
/* The following call prints an error message */
1427
1388
os_file_get_last_error(TRUE);
1429
1390
ut_print_timestamp(stderr);
1431
1392
fprintf(stderr,
1432
1393
" ibbackup: Error: trying to read system tablespace file format,\n"
1433
1394
" ibbackup: but could not open the tablespace file %s!\n",
1444
1405
if (!success) {
1445
1406
/* The following call prints an error message */
1446
1407
os_file_get_last_error(TRUE);
1448
1409
ut_print_timestamp(stderr);
1450
1411
fprintf(stderr,
1451
1412
" ibbackup: Error: trying to read system table space file format,\n"
1452
1413
" ibbackup: but failed to read the tablespace file %s!\n",
1460
1421
/* get the file format from the page */
1461
1422
ptr = page + TRX_SYS_FILE_FORMAT_TAG;
1462
1423
file_format_id = mach_read_from_8(ptr);
1463
file_format_id -= TRX_SYS_FILE_FORMAT_TAG_MAGIC_N;
1465
if (file_format_id >= FILE_FORMAT_NAME_N) {
1425
*format_id = file_format_id.low - TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
1427
if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH
1428
|| *format_id >= FILE_FORMAT_NAME_N) {
1467
1430
/* Either it has never been tagged, or garbage in it. */
1431
*format_id = ULINT_UNDEFINED;
1471
*format_id = (ulint) file_format_id;