~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/trx/trx0sys.c

  • Committer: Monty Taylor
  • Date: 2008-09-15 17:24:04 UTC
  • Revision ID: monty@inaugust.com-20080915172404-ygh6hiyu0q7qpa9x
Removed strndup calls.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include "log0log.h"
23
23
#include "os0file.h"
24
24
 
25
 
/* The file format tag structure with id and name. */
26
 
struct file_format_struct {
27
 
        uint            id;             /* id of the file format */
28
 
        const char*     name;           /* text representation of the
29
 
                                        file format */
30
 
        mutex_t         mutex;          /* covers changes to the above
31
 
                                        fields */
32
 
};
33
 
 
34
 
typedef struct file_format_struct       file_format_t;
35
 
 
36
25
/* The transaction system */
37
 
UNIV_INTERN trx_sys_t*          trx_sys         = NULL;
38
 
UNIV_INTERN trx_doublewrite_t*  trx_doublewrite = NULL;
 
26
trx_sys_t*              trx_sys         = NULL;
 
27
trx_doublewrite_t*      trx_doublewrite = NULL;
39
28
 
40
29
/* The following is set to TRUE when we are upgrading from the old format data
41
30
files to the new >= 4.1.x format multiple tablespaces format data files */
42
31
 
43
 
UNIV_INTERN ibool       trx_doublewrite_must_reset_space_ids    = FALSE;
 
32
ibool                   trx_doublewrite_must_reset_space_ids    = FALSE;
44
33
 
45
34
/* The following is TRUE when we are using the database in the new format,
46
35
i.e., we have successfully upgraded, or have created a new database
47
36
installation */
48
37
 
49
 
UNIV_INTERN ibool       trx_sys_multiple_tablespace_format      = FALSE;
 
38
ibool                   trx_sys_multiple_tablespace_format      = FALSE;
50
39
 
51
40
/* In a MySQL replication slave, in crash recovery we store the master log
52
41
file name and position here. We have successfully got the updates to InnoDB
53
42
up to this position. If .._pos is -1, it means no crash recovery was needed,
54
43
or there was no master log position info inside InnoDB. */
55
44
 
56
 
UNIV_INTERN char        trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
57
 
UNIV_INTERN ib_int64_t  trx_sys_mysql_master_log_pos    = -1;
 
45
char            trx_sys_mysql_master_log_name[TRX_SYS_DRIZZLE_LOG_NAME_LEN];
 
46
ib_longlong     trx_sys_mysql_master_log_pos    = -1;
58
47
 
59
48
/* If this MySQL server uses binary logging, after InnoDB has been inited
60
49
and if it has done a crash recovery, we store the binlog file name and position
61
50
here. If .._pos is -1, it means there was no binlog position info inside
62
51
InnoDB. */
63
52
 
64
 
UNIV_INTERN char        trx_sys_mysql_bin_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
65
 
UNIV_INTERN ib_int64_t  trx_sys_mysql_bin_log_pos       = -1;
66
 
 
67
 
/* List of animal names representing file format. */
68
 
static const char*      file_format_name_map[] = {
69
 
        "Antelope",
70
 
        "Barracuda",
71
 
        "Cheetah",
72
 
        "Dragon",
73
 
        "Elk",
74
 
        "Fox",
75
 
        "Gazelle",
76
 
        "Hornet",
77
 
        "Impala",
78
 
        "Jaguar",
79
 
        "Kangaroo",
80
 
        "Leopard",
81
 
        "Moose",
82
 
        "Nautilus",
83
 
        "Ocelot",
84
 
        "Porpoise",
85
 
        "Quail",
86
 
        "Rabbit",
87
 
        "Shark",
88
 
        "Tiger",
89
 
        "Urchin",
90
 
        "Viper",
91
 
        "Whale",
92
 
        "Xenops",
93
 
        "Yak",
94
 
        "Zebra"
95
 
};
96
 
 
97
 
/* The number of elements in the file format name array. */
98
 
static const ulint      FILE_FORMAT_NAME_N = 
99
 
        sizeof(file_format_name_map) / sizeof(file_format_name_map[0]);
100
 
 
101
 
/* This is used to track the maximum file format id known to InnoDB. It's
102
 
updated via SET GLOBAL innodb_file_format_check = 'x' or when we open
103
 
or create a table. */
104
 
static  file_format_t   file_format_max;
 
53
char            trx_sys_mysql_bin_log_name[TRX_SYS_DRIZZLE_LOG_NAME_LEN];
 
54
ib_longlong     trx_sys_mysql_bin_log_pos       = -1;
 
55
 
105
56
 
106
57
/********************************************************************
107
58
Determines if a page number is located inside the doublewrite buffer. */
108
 
UNIV_INTERN
 
59
 
109
60
ibool
110
61
trx_doublewrite_page_inside(
111
62
/*========================*/
170
121
/********************************************************************
171
122
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
172
123
multiple tablespace format. */
173
 
UNIV_INTERN
 
124
 
174
125
void
175
126
trx_sys_mark_upgraded_to_multiple_tablespaces(void)
176
127
/*===============================================*/
177
128
{
178
 
        buf_block_t*    block;
179
 
        byte*           doublewrite;
180
 
        mtr_t           mtr;
 
129
        page_t* page;
 
130
        byte*   doublewrite;
 
131
        mtr_t   mtr;
181
132
 
182
133
        /* We upgraded to 4.1.x and reset the space id fields in the
183
134
        doublewrite buffer. Let us mark to the trx_sys header that the upgrade
185
136
 
186
137
        mtr_start(&mtr);
187
138
 
188
 
        block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
189
 
                             RW_X_LATCH, &mtr);
 
139
        page = buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO, RW_X_LATCH, &mtr);
190
140
#ifdef UNIV_SYNC_DEBUG
191
 
        buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
 
141
        buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK);
192
142
#endif /* UNIV_SYNC_DEBUG */
193
143
 
194
 
        doublewrite = buf_block_get_frame(block) + TRX_SYS_DOUBLEWRITE;
 
144
        doublewrite = page + TRX_SYS_DOUBLEWRITE;
195
145
 
196
146
        mlog_write_ulint(doublewrite + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED,
197
147
                         TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N,
199
149
        mtr_commit(&mtr);
200
150
 
201
151
        /* Flush the modified pages to disk and make a checkpoint */
202
 
        log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
 
152
        log_make_checkpoint_at(ut_dulint_max, TRUE);
203
153
 
204
154
        trx_sys_multiple_tablespace_format = TRUE;
205
155
}
207
157
/********************************************************************
208
158
Creates the doublewrite buffer to a new InnoDB installation. The header of the
209
159
doublewrite buffer is placed on the trx system header page. */
210
 
UNIV_INTERN
 
160
 
211
161
void
212
162
trx_sys_create_doublewrite_buf(void)
213
163
/*================================*/
214
164
{
215
 
        buf_block_t*    block;
216
 
        buf_block_t*    block2;
217
 
        buf_block_t*    new_block;
 
165
        page_t* page;
 
166
        page_t* page2;
 
167
        page_t* new_page;
218
168
        byte*   doublewrite;
219
169
        byte*   fseg_header;
220
170
        ulint   page_no;
231
181
start_again:
232
182
        mtr_start(&mtr);
233
183
 
234
 
        block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
235
 
                             RW_X_LATCH, &mtr);
 
184
        page = buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO, RW_X_LATCH, &mtr);
236
185
#ifdef UNIV_SYNC_DEBUG
237
 
        buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
 
186
        buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK);
238
187
#endif /* UNIV_SYNC_DEBUG */
239
188
 
240
 
        doublewrite = buf_block_get_frame(block) + TRX_SYS_DOUBLEWRITE;
 
189
        doublewrite = page + TRX_SYS_DOUBLEWRITE;
241
190
 
242
191
        if (mach_read_from_4(doublewrite + TRX_SYS_DOUBLEWRITE_MAGIC)
243
192
            == TRX_SYS_DOUBLEWRITE_MAGIC_N) {
265
214
                        exit(1);
266
215
                }
267
216
 
268
 
                block2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
269
 
                                     TRX_SYS_DOUBLEWRITE
270
 
                                     + TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
 
217
                page2 = fseg_create(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
 
218
                                    TRX_SYS_DOUBLEWRITE
 
219
                                    + TRX_SYS_DOUBLEWRITE_FSEG, &mtr);
271
220
 
272
221
                /* fseg_create acquires a second latch on the page,
273
222
                therefore we must declare it: */
274
223
 
275
224
#ifdef UNIV_SYNC_DEBUG
276
 
                buf_block_dbg_add_level(block2, SYNC_NO_ORDER_CHECK);
 
225
                buf_page_dbg_add_level(page2, SYNC_NO_ORDER_CHECK);
277
226
#endif /* UNIV_SYNC_DEBUG */
278
227
 
279
 
                if (block2 == NULL) {
 
228
                if (page2 == NULL) {
280
229
                        fprintf(stderr,
281
230
                                "InnoDB: Cannot create doublewrite buffer:"
282
231
                                " you must\n"
289
238
                        exit(1);
290
239
                }
291
240
 
292
 
                fseg_header = buf_block_get_frame(block)
293
 
                        + TRX_SYS_DOUBLEWRITE + TRX_SYS_DOUBLEWRITE_FSEG;
 
241
                fseg_header = page + TRX_SYS_DOUBLEWRITE
 
242
                        + TRX_SYS_DOUBLEWRITE_FSEG;
294
243
                prev_page_no = 0;
295
244
 
296
245
                for (i = 0; i < 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
319
268
                        the page position in the tablespace, then the page
320
269
                        has not been written to in doublewrite. */
321
270
 
322
 
                        new_block = buf_page_get(TRX_SYS_SPACE, 0, page_no,
323
 
                                                 RW_X_LATCH, &mtr);
 
271
                        new_page = buf_page_get(TRX_SYS_SPACE, page_no,
 
272
                                                RW_X_LATCH, &mtr);
324
273
#ifdef UNIV_SYNC_DEBUG
325
 
                        buf_block_dbg_add_level(new_block,
326
 
                                                SYNC_NO_ORDER_CHECK);
 
274
                        buf_page_dbg_add_level(new_page, SYNC_NO_ORDER_CHECK);
327
275
#endif /* UNIV_SYNC_DEBUG */
328
276
 
329
277
                        /* Make a dummy change to the page to ensure it will
330
278
                        be written to disk in a flush */
331
279
 
332
 
                        mlog_write_ulint(buf_block_get_frame(new_block)
333
 
                                         + FIL_PAGE_DATA,
 
280
                        mlog_write_ulint(new_page + FIL_PAGE_DATA,
334
281
                                         TRX_SYS_DOUBLEWRITE_MAGIC_N,
335
282
                                         MLOG_4BYTES, &mtr);
336
283
 
373
320
                mtr_commit(&mtr);
374
321
 
375
322
                /* Flush the modified pages to disk and make a checkpoint */
376
 
                log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
 
323
                log_make_checkpoint_at(ut_dulint_max, TRUE);
377
324
 
378
325
                fprintf(stderr, "InnoDB: Doublewrite buffer created\n");
379
326
 
390
337
function performs the necessary update operations. If we are in a crash
391
338
recovery, this function uses a possible doublewrite buffer to restore
392
339
half-written pages in the data files. */
393
 
UNIV_INTERN
 
340
 
394
341
void
395
342
trx_sys_doublewrite_init_or_restore_pages(
396
343
/*======================================*/
416
363
        /* Read the trx sys header to check if we are using the doublewrite
417
364
        buffer */
418
365
 
419
 
        fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO, 0,
 
366
        fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, TRX_SYS_PAGE_NO, 0,
420
367
               UNIV_PAGE_SIZE, read_buf, NULL);
421
368
        doublewrite = read_buf + TRX_SYS_DOUBLEWRITE;
422
369
 
454
401
 
455
402
        /* Read the pages from the doublewrite buffer to memory */
456
403
 
457
 
        fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, 0, block1, 0,
 
404
        fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, block1, 0,
458
405
               TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
459
406
               buf, NULL);
460
 
        fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, 0, block2, 0,
 
407
        fil_io(OS_FILE_READ, TRUE, TRX_SYS_SPACE, block2, 0,
461
408
               TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
462
409
               buf + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE,
463
410
               NULL);
486
433
                                        + i - TRX_SYS_DOUBLEWRITE_BLOCK_SIZE;
487
434
                        }
488
435
 
489
 
                        fil_io(OS_FILE_WRITE, TRUE, 0, 0, source_page_no, 0,
 
436
                        fil_io(OS_FILE_WRITE, TRUE, 0, source_page_no, 0,
490
437
                               UNIV_PAGE_SIZE, page, NULL);
491
438
                        /* printf("Resetting space id in page %lu\n",
492
439
                        source_page_no); */
525
472
                        /* It is an unwritten doublewrite buffer page:
526
473
                        do nothing */
527
474
                } else {
528
 
                        ulint   zip_size = fil_space_get_zip_size(space_id);
529
 
 
530
 
                        /* Read in the actual page from the file */
531
 
                        fil_io(OS_FILE_READ, TRUE, space_id, zip_size,
532
 
                               page_no, 0,
533
 
                               zip_size ? zip_size : UNIV_PAGE_SIZE,
534
 
                               read_buf, NULL);
535
 
 
 
475
                        /* Read in the actual page from the data files */
 
476
 
 
477
                        fil_io(OS_FILE_READ, TRUE, space_id, page_no, 0,
 
478
                               UNIV_PAGE_SIZE, read_buf, NULL);
536
479
                        /* Check if the page is corrupt */
537
480
 
538
 
                        if (UNIV_UNLIKELY
539
 
                            (buf_page_is_corrupted(read_buf, zip_size))) {
 
481
                        if (buf_page_is_corrupted(read_buf)) {
540
482
 
541
483
                                fprintf(stderr,
542
484
                                        "InnoDB: Warning: database page"
543
485
                                        " corruption or a failed\n"
544
 
                                        "InnoDB: file read of"
545
 
                                        " space %lu page %lu.\n"
 
486
                                        "InnoDB: file read of page %lu.\n",
 
487
                                        (ulong) page_no);
 
488
                                fprintf(stderr,
546
489
                                        "InnoDB: Trying to recover it from"
547
 
                                        " the doublewrite buffer.\n",
548
 
                                        (ulong) space_id, (ulong) page_no);
 
490
                                        " the doublewrite buffer.\n");
549
491
 
550
 
                                if (buf_page_is_corrupted(page, zip_size)) {
 
492
                                if (buf_page_is_corrupted(page)) {
551
493
                                        fprintf(stderr,
552
494
                                                "InnoDB: Dump of the page:\n");
553
 
                                        buf_page_print(read_buf, zip_size);
 
495
                                        buf_page_print(read_buf);
554
496
                                        fprintf(stderr,
555
497
                                                "InnoDB: Dump of"
556
498
                                                " corresponding page"
557
499
                                                " in doublewrite buffer:\n");
558
 
                                        buf_page_print(page, zip_size);
 
500
                                        buf_page_print(page);
559
501
 
560
502
                                        fprintf(stderr,
561
503
                                                "InnoDB: Also the page in the"
577
519
                                position */
578
520
 
579
521
                                fil_io(OS_FILE_WRITE, TRUE, space_id,
580
 
                                       zip_size, page_no, 0,
581
 
                                       zip_size ? zip_size : UNIV_PAGE_SIZE,
582
 
                                       page, NULL);
 
522
                                       page_no, 0,
 
523
                                       UNIV_PAGE_SIZE, page, NULL);
583
524
                                fprintf(stderr,
584
525
                                        "InnoDB: Recovered the page from"
585
526
                                        " the doublewrite buffer.\n");
597
538
 
598
539
/********************************************************************
599
540
Checks that trx is in the trx list. */
600
 
UNIV_INTERN
 
541
 
601
542
ibool
602
543
trx_in_trx_list(
603
544
/*============*/
625
566
 
626
567
/*********************************************************************
627
568
Writes the value of max_trx_id to the file based trx system header. */
628
 
UNIV_INTERN
 
569
 
629
570
void
630
571
trx_sys_flush_max_trx_id(void)
631
572
/*==========================*/
649
590
which corresponds to the transaction just being committed. In a MySQL
650
591
replication slave updates the latest master binlog position up to which
651
592
replication has proceeded. */
652
 
UNIV_INTERN
 
593
 
653
594
void
654
595
trx_sys_update_mysql_binlog_offset(
655
596
/*===============================*/
656
597
        const char*     file_name,/* in: MySQL log file name */
657
 
        ib_int64_t      offset, /* in: position in that log file */
 
598
        ib_longlong     offset, /* in: position in that log file */
658
599
        ulint           field,  /* in: offset of the MySQL log info field in
659
600
                                the trx sys header */
660
601
        mtr_t*          mtr)    /* in: mtr */
661
602
{
662
603
        trx_sysf_t*     sys_header;
663
604
 
664
 
        if (ut_strlen(file_name) >= TRX_SYS_MYSQL_LOG_NAME_LEN) {
 
605
        if (ut_strlen(file_name) >= TRX_SYS_DRIZZLE_LOG_NAME_LEN) {
665
606
 
666
607
                /* We cannot fit the name to the 512 bytes we have reserved */
667
608
 
671
612
        sys_header = trx_sysf_get(mtr);
672
613
 
673
614
        if (mach_read_from_4(sys_header + field
674
 
                             + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
675
 
            != TRX_SYS_MYSQL_LOG_MAGIC_N) {
 
615
                             + TRX_SYS_DRIZZLE_LOG_MAGIC_N_FLD)
 
616
            != TRX_SYS_DRIZZLE_LOG_MAGIC_N) {
676
617
 
677
618
                mlog_write_ulint(sys_header + field
678
 
                                 + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD,
679
 
                                 TRX_SYS_MYSQL_LOG_MAGIC_N,
 
619
                                 + TRX_SYS_DRIZZLE_LOG_MAGIC_N_FLD,
 
620
                                 TRX_SYS_DRIZZLE_LOG_MAGIC_N,
680
621
                                 MLOG_4BYTES, mtr);
681
622
        }
682
623
 
683
 
        if (0 != strcmp((char*) (sys_header + field + TRX_SYS_MYSQL_LOG_NAME),
 
624
        if (0 != strcmp((char*) (sys_header + field + TRX_SYS_DRIZZLE_LOG_NAME),
684
625
                        file_name)) {
685
626
 
686
627
                mlog_write_string(sys_header + field
687
 
                                  + TRX_SYS_MYSQL_LOG_NAME,
 
628
                                  + TRX_SYS_DRIZZLE_LOG_NAME,
688
629
                                  (byte*) file_name, 1 + ut_strlen(file_name),
689
630
                                  mtr);
690
631
        }
691
632
 
692
633
        if (mach_read_from_4(sys_header + field
693
 
                             + TRX_SYS_MYSQL_LOG_OFFSET_HIGH) > 0
 
634
                             + TRX_SYS_DRIZZLE_LOG_OFFSET_HIGH) > 0
694
635
            || (offset >> 32) > 0) {
695
636
 
696
637
                mlog_write_ulint(sys_header + field
697
 
                                 + TRX_SYS_MYSQL_LOG_OFFSET_HIGH,
 
638
                                 + TRX_SYS_DRIZZLE_LOG_OFFSET_HIGH,
698
639
                                 (ulint)(offset >> 32),
699
640
                                 MLOG_4BYTES, mtr);
700
641
        }
701
642
 
702
643
        mlog_write_ulint(sys_header + field
703
 
                         + TRX_SYS_MYSQL_LOG_OFFSET_LOW,
 
644
                         + TRX_SYS_DRIZZLE_LOG_OFFSET_LOW,
704
645
                         (ulint)(offset & 0xFFFFFFFFUL),
705
646
                         MLOG_4BYTES, mtr);
706
647
}
709
650
/*********************************************************************
710
651
Prints to stderr the MySQL binlog info in the system header if the
711
652
magic number shows it valid. */
712
 
UNIV_INTERN
 
653
 
713
654
void
714
655
trx_sys_print_mysql_binlog_offset_from_page(
715
656
/*========================================*/
716
 
        const byte*     page)   /* in: buffer containing the trx
717
 
                                system header page, i.e., page number
718
 
                                TRX_SYS_PAGE_NO in the tablespace */
 
657
        byte*   page)   /* in: buffer containing the trx system header page,
 
658
                        i.e., page number TRX_SYS_PAGE_NO in the tablespace */
719
659
{
720
 
        const trx_sysf_t*       sys_header;
 
660
        trx_sysf_t*     sys_header;
721
661
 
722
662
        sys_header = page + TRX_SYS;
723
663
 
724
 
        if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO
725
 
                             + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
726
 
            == TRX_SYS_MYSQL_LOG_MAGIC_N) {
 
664
        if (mach_read_from_4(sys_header + TRX_SYS_DRIZZLE_LOG_INFO
 
665
                             + TRX_SYS_DRIZZLE_LOG_MAGIC_N_FLD)
 
666
            == TRX_SYS_DRIZZLE_LOG_MAGIC_N) {
727
667
 
728
668
                fprintf(stderr,
729
669
                        "ibbackup: Last MySQL binlog file position %lu %lu,"
730
670
                        " file name %s\n",
731
671
                        (ulong) mach_read_from_4(
732
 
                                sys_header + TRX_SYS_MYSQL_LOG_INFO
733
 
                                + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
 
672
                                sys_header + TRX_SYS_DRIZZLE_LOG_INFO
 
673
                                + TRX_SYS_DRIZZLE_LOG_OFFSET_HIGH),
734
674
                        (ulong) mach_read_from_4(
735
 
                                sys_header + TRX_SYS_MYSQL_LOG_INFO
736
 
                                + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
737
 
                        sys_header + TRX_SYS_MYSQL_LOG_INFO
738
 
                        + TRX_SYS_MYSQL_LOG_NAME);
 
675
                                sys_header + TRX_SYS_DRIZZLE_LOG_INFO
 
676
                                + TRX_SYS_DRIZZLE_LOG_OFFSET_LOW),
 
677
                        sys_header + TRX_SYS_DRIZZLE_LOG_INFO
 
678
                        + TRX_SYS_DRIZZLE_LOG_NAME);
739
679
        }
740
680
}
741
681
#endif /* UNIV_HOTBACKUP */
743
683
/*********************************************************************
744
684
Stores the MySQL binlog offset info in the trx system header if
745
685
the magic number shows it valid, and print the info to stderr */
746
 
UNIV_INTERN
 
686
 
747
687
void
748
688
trx_sys_print_mysql_binlog_offset(void)
749
689
/*===================================*/
757
697
 
758
698
        sys_header = trx_sysf_get(&mtr);
759
699
 
760
 
        if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO
761
 
                             + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
762
 
            != TRX_SYS_MYSQL_LOG_MAGIC_N) {
 
700
        if (mach_read_from_4(sys_header + TRX_SYS_DRIZZLE_LOG_INFO
 
701
                             + TRX_SYS_DRIZZLE_LOG_MAGIC_N_FLD)
 
702
            != TRX_SYS_DRIZZLE_LOG_MAGIC_N) {
763
703
 
764
704
                mtr_commit(&mtr);
765
705
 
767
707
        }
768
708
 
769
709
        trx_sys_mysql_bin_log_pos_high = mach_read_from_4(
770
 
                sys_header + TRX_SYS_MYSQL_LOG_INFO
771
 
                + TRX_SYS_MYSQL_LOG_OFFSET_HIGH);
 
710
                sys_header + TRX_SYS_DRIZZLE_LOG_INFO
 
711
                + TRX_SYS_DRIZZLE_LOG_OFFSET_HIGH);
772
712
        trx_sys_mysql_bin_log_pos_low = mach_read_from_4(
773
 
                sys_header + TRX_SYS_MYSQL_LOG_INFO
774
 
                + TRX_SYS_MYSQL_LOG_OFFSET_LOW);
 
713
                sys_header + TRX_SYS_DRIZZLE_LOG_INFO
 
714
                + TRX_SYS_DRIZZLE_LOG_OFFSET_LOW);
775
715
 
776
716
        trx_sys_mysql_bin_log_pos
777
 
                = (((ib_int64_t)trx_sys_mysql_bin_log_pos_high) << 32)
778
 
                + (ib_int64_t)trx_sys_mysql_bin_log_pos_low;
 
717
                = (((ib_longlong)trx_sys_mysql_bin_log_pos_high) << 32)
 
718
                + (ib_longlong)trx_sys_mysql_bin_log_pos_low;
779
719
 
780
720
        ut_memcpy(trx_sys_mysql_bin_log_name,
781
 
                  sys_header + TRX_SYS_MYSQL_LOG_INFO
782
 
                  + TRX_SYS_MYSQL_LOG_NAME, TRX_SYS_MYSQL_LOG_NAME_LEN);
 
721
                  sys_header + TRX_SYS_DRIZZLE_LOG_INFO
 
722
                  + TRX_SYS_DRIZZLE_LOG_NAME, TRX_SYS_DRIZZLE_LOG_NAME_LEN);
783
723
 
784
724
        fprintf(stderr,
785
725
                "InnoDB: Last MySQL binlog file position %lu %lu,"
793
733
/*********************************************************************
794
734
Prints to stderr the MySQL master log offset info in the trx system header if
795
735
the magic number shows it valid. */
796
 
UNIV_INTERN
 
736
 
797
737
void
798
738
trx_sys_print_mysql_master_log_pos(void)
799
739
/*====================================*/
805
745
 
806
746
        sys_header = trx_sysf_get(&mtr);
807
747
 
808
 
        if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
809
 
                             + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
810
 
            != TRX_SYS_MYSQL_LOG_MAGIC_N) {
 
748
        if (mach_read_from_4(sys_header + TRX_SYS_DRIZZLE_MASTER_LOG_INFO
 
749
                             + TRX_SYS_DRIZZLE_LOG_MAGIC_N_FLD)
 
750
            != TRX_SYS_DRIZZLE_LOG_MAGIC_N) {
811
751
 
812
752
                mtr_commit(&mtr);
813
753
 
819
759
                " master binlog file\n"
820
760
                "InnoDB: position %lu %lu, file name %s\n",
821
761
                (ulong) mach_read_from_4(sys_header
822
 
                                         + TRX_SYS_MYSQL_MASTER_LOG_INFO
823
 
                                         + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
 
762
                                         + TRX_SYS_DRIZZLE_MASTER_LOG_INFO
 
763
                                         + TRX_SYS_DRIZZLE_LOG_OFFSET_HIGH),
824
764
                (ulong) mach_read_from_4(sys_header
825
 
                                         + TRX_SYS_MYSQL_MASTER_LOG_INFO
826
 
                                         + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
827
 
                sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
828
 
                + TRX_SYS_MYSQL_LOG_NAME);
 
765
                                         + TRX_SYS_DRIZZLE_MASTER_LOG_INFO
 
766
                                         + TRX_SYS_DRIZZLE_LOG_OFFSET_LOW),
 
767
                sys_header + TRX_SYS_DRIZZLE_MASTER_LOG_INFO
 
768
                + TRX_SYS_DRIZZLE_LOG_NAME);
829
769
        /* Copy the master log position info to global variables we can
830
770
        use in ha_innobase.cc to initialize glob_mi to right values */
831
771
 
832
772
        ut_memcpy(trx_sys_mysql_master_log_name,
833
 
                  sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
834
 
                  + TRX_SYS_MYSQL_LOG_NAME,
835
 
                  TRX_SYS_MYSQL_LOG_NAME_LEN);
 
773
                  sys_header + TRX_SYS_DRIZZLE_MASTER_LOG_INFO
 
774
                  + TRX_SYS_DRIZZLE_LOG_NAME,
 
775
                  TRX_SYS_DRIZZLE_LOG_NAME_LEN);
836
776
 
837
777
        trx_sys_mysql_master_log_pos
838
 
                = (((ib_int64_t) mach_read_from_4(
839
 
                            sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
840
 
                            + TRX_SYS_MYSQL_LOG_OFFSET_HIGH)) << 32)
841
 
                + ((ib_int64_t) mach_read_from_4(
842
 
                           sys_header + TRX_SYS_MYSQL_MASTER_LOG_INFO
843
 
                           + TRX_SYS_MYSQL_LOG_OFFSET_LOW));
 
778
                = (((ib_longlong) mach_read_from_4(
 
779
                            sys_header + TRX_SYS_DRIZZLE_MASTER_LOG_INFO
 
780
                            + TRX_SYS_DRIZZLE_LOG_OFFSET_HIGH)) << 32)
 
781
                + ((ib_longlong) mach_read_from_4(
 
782
                           sys_header + TRX_SYS_DRIZZLE_MASTER_LOG_INFO
 
783
                           + TRX_SYS_DRIZZLE_LOG_OFFSET_LOW));
844
784
        mtr_commit(&mtr);
845
785
}
846
786
 
847
787
/********************************************************************
848
788
Looks for a free slot for a rollback segment in the trx system file copy. */
849
 
UNIV_INTERN
 
789
 
850
790
ulint
851
791
trx_sysf_rseg_find_free(
852
792
/*====================*/
885
825
{
886
826
        trx_sysf_t*     sys_header;
887
827
        ulint           slot_no;
888
 
        buf_block_t*    block;
889
828
        page_t*         page;
890
829
        ulint           page_no;
891
830
        ulint           i;
896
835
        then enter the kernel: we must do it in this order to conform
897
836
        to the latching order rules. */
898
837
 
899
 
        mtr_x_lock(fil_space_get_latch(TRX_SYS_SPACE, NULL), mtr);
 
838
        mtr_x_lock(fil_space_get_latch(TRX_SYS_SPACE), mtr);
900
839
        mutex_enter(&kernel_mutex);
901
840
 
902
841
        /* Create the trx sys file block in a new allocated file segment */
903
 
        block = fseg_create(TRX_SYS_SPACE, 0, TRX_SYS + TRX_SYS_FSEG_HEADER,
904
 
                            mtr);
 
842
        page = fseg_create(TRX_SYS_SPACE, 0, TRX_SYS + TRX_SYS_FSEG_HEADER,
 
843
                           mtr);
 
844
        ut_a(buf_frame_get_page_no(page) == TRX_SYS_PAGE_NO);
 
845
 
905
846
#ifdef UNIV_SYNC_DEBUG
906
 
        buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
 
847
        buf_page_dbg_add_level(page, SYNC_TRX_SYS_HEADER);
907
848
#endif /* UNIV_SYNC_DEBUG */
908
 
        ut_a(buf_block_get_page_no(block) == TRX_SYS_PAGE_NO);
909
 
 
910
 
        page = buf_block_get_frame(block);
911
849
 
912
850
        mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_TYPE_TRX_SYS,
913
851
                         MLOG_2BYTES, mtr);
944
882
                       + page - sys_header);
945
883
 
946
884
        /* Create the first rollback segment in the SYSTEM tablespace */
947
 
        page_no = trx_rseg_header_create(TRX_SYS_SPACE, 0, ULINT_MAX, &slot_no,
 
885
        page_no = trx_rseg_header_create(TRX_SYS_SPACE, ULINT_MAX, &slot_no,
948
886
                                         mtr);
949
887
        ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
950
888
        ut_a(page_no != FIL_NULL);
955
893
/*********************************************************************
956
894
Creates and initializes the central memory structures for the transaction
957
895
system. This is called when the database is started. */
958
 
UNIV_INTERN
 
896
 
959
897
void
960
898
trx_sys_init_at_db_start(void)
961
899
/*==========================*/
962
900
{
963
901
        trx_sysf_t*     sys_header;
964
 
        ib_int64_t      rows_to_undo    = 0;
 
902
        ib_longlong     rows_to_undo    = 0;
965
903
        const char*     unit            = "";
966
904
        trx_t*          trx;
967
905
        mtr_t           mtr;
995
933
                2 * TRX_SYS_TRX_ID_WRITE_MARGIN);
996
934
 
997
935
        UT_LIST_INIT(trx_sys->mysql_trx_list);
998
 
        trx_dummy_sess = sess_open();
999
936
        trx_lists_init_at_db_start();
1000
937
 
1001
938
        if (UT_LIST_GET_LEN(trx_sys->trx_list) > 0) {
1027
964
                        (ulong) UT_LIST_GET_LEN(trx_sys->trx_list),
1028
965
                        (ulong) rows_to_undo, unit);
1029
966
 
1030
 
                fprintf(stderr, "InnoDB: Trx id counter is " TRX_ID_FMT "\n",
1031
 
                        TRX_ID_PREP_PRINTF(trx_sys->max_trx_id));
 
967
                fprintf(stderr, "InnoDB: Trx id counter is %lu %lu\n",
 
968
                        (ulong) ut_dulint_get_high(trx_sys->max_trx_id),
 
969
                        (ulong) ut_dulint_get_low(trx_sys->max_trx_id));
1032
970
        }
1033
971
 
1034
972
        UT_LIST_INIT(trx_sys->view_list);
1042
980
 
1043
981
/*********************************************************************
1044
982
Creates and initializes the transaction system at the database creation. */
1045
 
UNIV_INTERN
 
983
 
1046
984
void
1047
985
trx_sys_create(void)
1048
986
/*================*/
1057
995
 
1058
996
        trx_sys_init_at_db_start();
1059
997
}
1060
 
 
1061
 
/*********************************************************************
1062
 
Update the file format tag. */
1063
 
static
1064
 
ibool
1065
 
trx_sys_file_format_max_write(
1066
 
/*==========================*/
1067
 
                                        /* out: always TRUE */
1068
 
        ulint           format_id,      /* in: file format id */
1069
 
        char**          name)           /* out: max file format name, can
1070
 
                                        be NULL */
1071
 
{
1072
 
        mtr_t           mtr;
1073
 
        byte*           ptr;
1074
 
        buf_block_t*    block;
1075
 
        ulint           tag_value_low;
1076
 
 
1077
 
        mtr_start(&mtr);
1078
 
 
1079
 
        block = buf_page_get(
1080
 
                TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO, RW_X_LATCH, &mtr);
1081
 
 
1082
 
        file_format_max.id = format_id;
1083
 
        file_format_max.name = trx_sys_file_format_id_to_name(format_id);
1084
 
 
1085
 
        ptr = buf_block_get_frame(block) + TRX_SYS_FILE_FORMAT_TAG;
1086
 
        tag_value_low = format_id + TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
1087
 
 
1088
 
        if (name) {
1089
 
                *name = (char*) file_format_max.name;
1090
 
        }
1091
 
 
1092
 
        mlog_write_dulint(
1093
 
                ptr,
1094
 
                ut_dulint_create(TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH,
1095
 
                                 tag_value_low),
1096
 
                &mtr);
1097
 
 
1098
 
        mtr_commit(&mtr);
1099
 
 
1100
 
        return(TRUE);
1101
 
}
1102
 
 
1103
 
/*********************************************************************
1104
 
Read the file format tag. */
1105
 
static
1106
 
ulint
1107
 
trx_sys_file_format_max_read(void)
1108
 
/*==============================*/
1109
 
                                /* out: the file format */
1110
 
{
1111
 
        mtr_t                   mtr;
1112
 
        const byte*             ptr;
1113
 
        const buf_block_t*      block;
1114
 
        ulint                   format_id;
1115
 
        dulint                  file_format_id;
1116
 
 
1117
 
        /* Since this is called during the startup phase it's safe to
1118
 
        read the value without a covering mutex. */
1119
 
        mtr_start(&mtr);
1120
 
 
1121
 
        block = buf_page_get(
1122
 
                TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO, RW_X_LATCH, &mtr);
1123
 
 
1124
 
        ptr = buf_block_get_frame(block) + TRX_SYS_FILE_FORMAT_TAG;
1125
 
        file_format_id = mach_read_from_8(ptr);
1126
 
 
1127
 
        mtr_commit(&mtr);
1128
 
 
1129
 
        format_id = file_format_id.low - TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
1130
 
 
1131
 
        if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH
1132
 
            || format_id >= FILE_FORMAT_NAME_N) {
1133
 
 
1134
 
                /* Either it has never been tagged, or garbage in it.
1135
 
                Reset the tag in either case. */
1136
 
                format_id = DICT_TF_FORMAT_51;
1137
 
                trx_sys_file_format_max_write(format_id, NULL);
1138
 
        }
1139
 
 
1140
 
        return(format_id);
1141
 
}
1142
 
 
1143
 
/*********************************************************************
1144
 
Get the name representation of the file format from its id. */
1145
 
UNIV_INTERN
1146
 
const char*
1147
 
trx_sys_file_format_id_to_name(
1148
 
/*===========================*/
1149
 
                                /* out: pointer to the name */
1150
 
        const uint      id)     /* in: id of the file format */
1151
 
{
1152
 
        ut_a(id < FILE_FORMAT_NAME_N);
1153
 
 
1154
 
        return(file_format_name_map[id]);
1155
 
}
1156
 
 
1157
 
/*********************************************************************
1158
 
Check for the max file format tag stored on disk. Note: If max_format_id
1159
 
is == DICT_TF_FORMAT_MAX + 1 then we only print a warning. */
1160
 
UNIV_INTERN
1161
 
ulint
1162
 
trx_sys_file_format_max_check(
1163
 
/*==========================*/
1164
 
                                /* out: DB_SUCCESS or error code */
1165
 
        ulint   max_format_id)  /* in: max format id to check */
1166
 
{
1167
 
        ulint   format_id;
1168
 
 
1169
 
        /* Check the file format in the tablespace. Do not try to
1170
 
        recover if the file format is not supported by the engine
1171
 
        unless forced by the user. */
1172
 
        format_id = trx_sys_file_format_max_read();
1173
 
 
1174
 
        ut_print_timestamp(stderr);
1175
 
        fprintf(stderr,
1176
 
                "  InnoDB: highest supported file format is %s.\n",
1177
 
                trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
1178
 
 
1179
 
        if (format_id > DICT_TF_FORMAT_MAX) {
1180
 
 
1181
 
                ut_a(format_id < FILE_FORMAT_NAME_N);
1182
 
 
1183
 
                ut_print_timestamp(stderr);
1184
 
                fprintf(stderr,
1185
 
                        "  InnoDB: %s: the system tablespace is in a file "
1186
 
                        "format that this version doesn't support - %s\n",
1187
 
                        ((max_format_id <= DICT_TF_FORMAT_MAX)
1188
 
                                ? "Error" : "Warning"),
1189
 
                        trx_sys_file_format_id_to_name(format_id));
1190
 
 
1191
 
                if (max_format_id <= DICT_TF_FORMAT_MAX) {
1192
 
                        return(DB_ERROR);
1193
 
                }
1194
 
        }
1195
 
 
1196
 
        format_id = (format_id > max_format_id) ? format_id : max_format_id;
1197
 
 
1198
 
        /* We don't need a mutex here, as this function should only
1199
 
        be called once at start up. */
1200
 
        file_format_max.id = format_id;
1201
 
        file_format_max.name = trx_sys_file_format_id_to_name(format_id);
1202
 
 
1203
 
        return(DB_SUCCESS);
1204
 
}
1205
 
 
1206
 
/*********************************************************************
1207
 
Set the file format id unconditionally except if it's already the
1208
 
same value. */
1209
 
UNIV_INTERN
1210
 
ibool
1211
 
trx_sys_file_format_max_set(
1212
 
/*========================*/
1213
 
                                        /* out: TRUE if value updated */
1214
 
        ulint           format_id,      /* in: file format id */
1215
 
        char**          name)           /* out: max file format name */
1216
 
{
1217
 
        ibool           ret = FALSE;
1218
 
 
1219
 
        ut_a(name);
1220
 
        ut_a(format_id <= DICT_TF_FORMAT_MAX);
1221
 
 
1222
 
        mutex_enter(&file_format_max.mutex);
1223
 
 
1224
 
        /* Only update if not already same value. */
1225
 
        if (format_id != file_format_max.id) {
1226
 
 
1227
 
                ret = trx_sys_file_format_max_write(format_id, name);
1228
 
        }
1229
 
 
1230
 
        mutex_exit(&file_format_max.mutex);
1231
 
 
1232
 
        return(ret);
1233
 
}
1234
 
 
1235
 
/************************************************************************
1236
 
Update the file format tag in the tablespace only if the given format id
1237
 
is greater than the known max id. */
1238
 
UNIV_INTERN
1239
 
ibool
1240
 
trx_sys_file_format_max_update(
1241
 
/*===========================*/
1242
 
        uint            flags,          /* in: flags of the table.*/
1243
 
        char**          name)           /* out: max file format name */
1244
 
{
1245
 
        ulint           format_id;
1246
 
        ibool           ret = FALSE;
1247
 
 
1248
 
        format_id = (flags & DICT_TF_FORMAT_MASK) >> DICT_TF_FORMAT_SHIFT;
1249
 
 
1250
 
        ut_a(name);
1251
 
        ut_a(file_format_max.name != NULL);
1252
 
        ut_a(format_id <= DICT_TF_FORMAT_MAX);
1253
 
 
1254
 
        mutex_enter(&file_format_max.mutex);
1255
 
 
1256
 
        if (format_id > file_format_max.id) {
1257
 
 
1258
 
                ret = trx_sys_file_format_max_write(format_id, name);
1259
 
        }
1260
 
 
1261
 
        mutex_exit(&file_format_max.mutex);
1262
 
 
1263
 
        return(ret);
1264
 
}
1265
 
 
1266
 
/*********************************************************************
1267
 
Get the name representation of the file format from its id. */
1268
 
UNIV_INTERN
1269
 
const char*
1270
 
trx_sys_file_format_max_get(void)
1271
 
/*=============================*/
1272
 
                                /* out: pointer to the max format name */
1273
 
{
1274
 
        return(file_format_max.name);
1275
 
}
1276
 
 
1277
 
/*********************************************************************
1278
 
Initializes the tablespace tag system. */
1279
 
UNIV_INTERN
1280
 
void
1281
 
trx_sys_file_format_init(void)
1282
 
/*==========================*/
1283
 
{
1284
 
        mutex_create(&file_format_max.mutex, SYNC_FILE_FORMAT_TAG);
1285
 
 
1286
 
        /* We don't need a mutex here, as this function should only
1287
 
        be called once at start up. */
1288
 
        file_format_max.id = DICT_TF_FORMAT_51;
1289
 
 
1290
 
        file_format_max.name = trx_sys_file_format_id_to_name(
1291
 
                file_format_max.id);
1292
 
}
1293
 
 
1294
 
/*********************************************************************
1295
 
Closes the tablespace tag system. */
1296
 
UNIV_INTERN
1297
 
void
1298
 
trx_sys_file_format_close(void)
1299
 
/*===========================*/
1300
 
{
1301
 
        /* Does nothing at the moment */
1302
 
}