~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/log/log0recv.c

  • Committer: lbieber
  • Date: 2010-10-05 22:23:12 UTC
  • mfrom: (1813.1.4 build)
  • Revision ID: lbieber@orisndriz08-20101005222312-weuq0ardk3gcryau
Merge Travis - 621861 - convert structs to classes
Merge Billy - 621331 - Replace use of stringstream with boost::lexical_cast
Merge Travis - 621861 = To change C structs to C++ classes in Drizzle
Merge Andrew - fix bug 653300 - Syntax error on inport of a SQL file produced by drizzledump

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 1997, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
69
69
/** TRUE when applying redo log records during crash recovery; FALSE
70
70
otherwise.  Note that this is FALSE while a background thread is
71
71
rolling back incomplete transactions. */
72
 
UNIV_INTERN ibool       recv_recovery_on;
 
72
UNIV_INTERN ibool       recv_recovery_on = FALSE;
73
73
#ifdef UNIV_LOG_ARCHIVE
74
74
/** TRUE when applying redo log records from an archived log file */
75
 
UNIV_INTERN ibool       recv_recovery_from_backup_on;
 
75
UNIV_INTERN ibool       recv_recovery_from_backup_on = FALSE;
76
76
#endif /* UNIV_LOG_ARCHIVE */
77
77
 
78
78
#ifndef UNIV_HOTBACKUP
79
79
/** TRUE when recv_init_crash_recovery() has been called. */
80
 
UNIV_INTERN ibool       recv_needed_recovery;
81
 
# ifdef UNIV_DEBUG
82
 
/** TRUE if writing to the redo log (mtr_commit) is forbidden.
83
 
Protected by log_sys->mutex. */
84
 
UNIV_INTERN ibool       recv_no_log_write = FALSE;
85
 
# endif /* UNIV_DEBUG */
 
80
UNIV_INTERN ibool       recv_needed_recovery = FALSE;
86
81
 
87
82
/** TRUE if buf_page_is_corrupted() should check if the log sequence
88
83
number (FIL_PAGE_LSN) is in the future.  Initially FALSE, and set by
89
84
recv_recovery_from_checkpoint_start_func(). */
90
 
UNIV_INTERN ibool       recv_lsn_checks_on;
 
85
UNIV_INTERN ibool       recv_lsn_checks_on = FALSE;
91
86
 
92
87
/** There are two conditions under which we scan the logs, the first
93
88
is normal startup and the second is when we do a recovery from an
97
92
we know that the server was not cleanly shutdown. We must then initialize
98
93
the crash recovery environment before attempting to store these entries in
99
94
the log hash table. */
100
 
static ibool            recv_log_scan_is_startup_type;
 
95
static ibool            recv_log_scan_is_startup_type = FALSE;
101
96
 
102
97
/** If the following is TRUE, the buffer pool file pages must be invalidated
103
98
after recovery and no ibuf operations are allowed; this becomes TRUE if
108
103
 
109
104
TRUE means that recovery is running and no operations on the log files
110
105
are allowed yet: the variable name is misleading. */
111
 
UNIV_INTERN ibool       recv_no_ibuf_operations;
 
106
UNIV_INTERN ibool       recv_no_ibuf_operations = FALSE;
112
107
/** TRUE when the redo log is being backed up */
113
108
# define recv_is_making_a_backup                FALSE
114
109
/** TRUE when recovering from a backed up redo log file */
116
111
#else /* !UNIV_HOTBACKUP */
117
112
# define recv_needed_recovery                   FALSE
118
113
/** TRUE when the redo log is being backed up */
119
 
UNIV_INTERN ibool       recv_is_making_a_backup = FALSE;
 
114
UNIV_INTERN ibool       recv_is_making_a_backup = FALSE;
120
115
/** TRUE when recovering from a backed up redo log file */
121
116
UNIV_INTERN ibool       recv_is_from_backup     = FALSE;
122
117
# define buf_pool_get_curr_size() (5 * 1024 * 1024)
123
118
#endif /* !UNIV_HOTBACKUP */
124
119
/** The following counter is used to decide when to print info on
125
120
log scan */
126
 
static ulint    recv_scan_print_counter;
 
121
static ulint    recv_scan_print_counter = 0;
127
122
 
128
123
/** The type of the previous parsed redo log record */
129
 
static ulint    recv_previous_parsed_rec_type;
 
124
static ulint    recv_previous_parsed_rec_type   = 999999;
130
125
/** The offset of the previous parsed redo log record */
131
 
static ulint    recv_previous_parsed_rec_offset;
 
126
static ulint    recv_previous_parsed_rec_offset = 0;
132
127
/** The 'multi' flag of the previous parsed redo log record */
133
 
static ulint    recv_previous_parsed_rec_is_multi;
 
128
static ulint    recv_previous_parsed_rec_is_multi = 0;
134
129
 
135
130
/** Maximum page number encountered in the redo log */
136
 
UNIV_INTERN ulint       recv_max_parsed_page_no;
 
131
UNIV_INTERN ulint       recv_max_parsed_page_no         = 0;
137
132
 
138
133
/** This many frames must be left free in the buffer pool when we scan
139
134
the log and store the scanned log records in the buffer pool: we will
140
135
use these free frames to read in pages when we start applying the
141
 
log records to the database.
142
 
This is the default value. If the actual size of the buffer pool is
143
 
larger than 10 MB we'll set this value to 512. */
144
 
UNIV_INTERN ulint       recv_n_pool_free_frames;
 
136
log records to the database. */
 
137
UNIV_INTERN ulint       recv_n_pool_free_frames         = 256;
145
138
 
146
139
/** The maximum lsn we see for a page during the recovery process. If this
147
140
is bigger than the lsn we are able to scan up to, that is an indication that
148
141
the recovery failed and the database may be corrupt. */
149
142
UNIV_INTERN ib_uint64_t recv_max_page_lsn;
150
143
 
151
 
#ifdef UNIV_PFS_THREAD
152
 
UNIV_INTERN mysql_pfs_key_t     trx_rollback_clean_thread_key;
153
 
#endif /* UNIV_PFS_THREAD */
154
 
 
155
 
#ifdef UNIV_PFS_MUTEX
156
 
UNIV_INTERN mysql_pfs_key_t     recv_sys_mutex_key;
157
 
#endif /* UNIV_PFS_MUTEX */
158
 
 
159
144
/* prototypes */
160
145
 
161
146
#ifndef UNIV_HOTBACKUP
180
165
                return;
181
166
        }
182
167
 
183
 
        recv_sys = static_cast<recv_sys_t *>(mem_alloc(sizeof(*recv_sys)));
184
 
        memset(recv_sys, 0x0, sizeof(*recv_sys));
 
168
        recv_sys = mem_alloc(sizeof(recv_sys_t));
185
169
 
186
 
        mutex_create(recv_sys_mutex_key, &recv_sys->mutex, SYNC_RECV);
 
170
        mutex_create(&recv_sys->mutex, SYNC_RECV);
187
171
 
188
172
        recv_sys->heap = NULL;
189
173
        recv_sys->addr_hash = NULL;
190
174
}
191
175
 
192
176
/********************************************************//**
193
 
Release recovery system mutexes. */
194
 
UNIV_INTERN
195
 
void
196
 
recv_sys_close(void)
197
 
/*================*/
198
 
{
199
 
        if (recv_sys != NULL) {
200
 
                if (recv_sys->addr_hash != NULL) {
201
 
                        hash_table_free(recv_sys->addr_hash);
202
 
                }
203
 
 
204
 
                if (recv_sys->heap != NULL) {
205
 
                        mem_heap_free(recv_sys->heap);
206
 
                }
207
 
 
208
 
                if (recv_sys->buf != NULL) {
209
 
                        ut_free(recv_sys->buf);
210
 
                }
211
 
 
212
 
                if (recv_sys->last_block_buf_start != NULL) {
213
 
                        mem_free(recv_sys->last_block_buf_start);
214
 
                }
215
 
 
216
 
                mutex_free(&recv_sys->mutex);
217
 
 
218
 
                mem_free(recv_sys);
219
 
                recv_sys = NULL;
220
 
        }
221
 
}
222
 
 
223
 
/********************************************************//**
224
 
Frees the recovery system memory. */
225
 
UNIV_INTERN
226
 
void
227
 
recv_sys_mem_free(void)
228
 
/*===================*/
229
 
{
230
 
        if (recv_sys != NULL) {
231
 
                if (recv_sys->addr_hash != NULL) {
232
 
                        hash_table_free(recv_sys->addr_hash);
233
 
                }
234
 
 
235
 
                if (recv_sys->heap != NULL) {
236
 
                        mem_heap_free(recv_sys->heap);
237
 
                }
238
 
 
239
 
                if (recv_sys->buf != NULL) {
240
 
                        ut_free(recv_sys->buf);
241
 
                }
242
 
 
243
 
                if (recv_sys->last_block_buf_start != NULL) {
244
 
                        mem_free(recv_sys->last_block_buf_start);
245
 
                }
246
 
 
247
 
                mem_free(recv_sys);
248
 
                recv_sys = NULL;
249
 
        }
250
 
}
251
 
 
252
 
#ifndef UNIV_HOTBACKUP
253
 
/************************************************************
254
 
Reset the state of the recovery system variables. */
255
 
UNIV_INTERN
256
 
void
257
 
recv_sys_var_init(void)
258
 
/*===================*/
259
 
{
260
 
        recv_lsn_checks_on = FALSE;
261
 
 
262
 
        recv_n_pool_free_frames = 256;
263
 
 
264
 
        recv_recovery_on = FALSE;
265
 
 
266
 
#ifdef UNIV_LOG_ARCHIVE
267
 
        recv_recovery_from_backup_on = FALSE;
268
 
#endif /* UNIV_LOG_ARCHIVE */
269
 
 
270
 
        recv_needed_recovery = FALSE;
271
 
 
272
 
        recv_lsn_checks_on = FALSE;
273
 
 
274
 
        recv_log_scan_is_startup_type = FALSE;
275
 
 
276
 
        recv_no_ibuf_operations = FALSE;
277
 
 
278
 
        recv_scan_print_counter = 0;
279
 
 
280
 
        recv_previous_parsed_rec_type   = 999999;
281
 
 
282
 
        recv_previous_parsed_rec_offset = 0;
283
 
 
284
 
        recv_previous_parsed_rec_is_multi = 0;
285
 
 
286
 
        recv_max_parsed_page_no = 0;
287
 
 
288
 
        recv_n_pool_free_frames = 256;
289
 
 
290
 
        recv_max_page_lsn = 0;
291
 
}
292
 
#endif /* !UNIV_HOTBACKUP */
293
 
 
294
 
/************************************************************
295
177
Inits the recovery system for a recovery operation. */
296
178
UNIV_INTERN
297
179
void
304
186
                return;
305
187
        }
306
188
 
307
 
#ifndef UNIV_HOTBACKUP
308
 
        /* Initialize red-black tree for fast insertions into the
309
 
        flush_list during recovery process.
310
 
        As this initialization is done while holding the buffer pool
311
 
        mutex we perform it before acquiring recv_sys->mutex. */
312
 
#ifndef UNIV_HOTBACKUP
313
 
        buf_flush_init_flush_rbt();
314
 
#endif /* !UNIV_HOTBACKUP */
315
 
 
316
189
        mutex_enter(&(recv_sys->mutex));
317
190
 
 
191
#ifndef UNIV_HOTBACKUP
318
192
        recv_sys->heap = mem_heap_create_in_buffer(256);
319
193
#else /* !UNIV_HOTBACKUP */
320
194
        recv_sys->heap = mem_heap_create(256);
321
195
        recv_is_from_backup = TRUE;
322
196
#endif /* !UNIV_HOTBACKUP */
323
197
 
324
 
        /* Set appropriate value of recv_n_pool_free_frames. */
325
 
        if (buf_pool_get_curr_size() >= (10 * 1024 * 1024)) {
326
 
                /* Buffer pool of size greater than 10 MB. */
327
 
                recv_n_pool_free_frames = 512;
328
 
        }
329
 
 
330
 
        recv_sys->buf = static_cast<byte *>(ut_malloc(RECV_PARSING_BUF_SIZE));
 
198
        recv_sys->buf = ut_malloc(RECV_PARSING_BUF_SIZE);
331
199
        recv_sys->len = 0;
332
200
        recv_sys->recovered_offset = 0;
333
201
 
334
 
        recv_sys->addr_hash = hash_create(available_memory / 512);
 
202
        recv_sys->addr_hash = hash_create(available_memory / 64);
335
203
        recv_sys->n_addrs = 0;
336
204
 
337
205
        recv_sys->apply_log_recs = FALSE;
338
206
        recv_sys->apply_batch_on = FALSE;
339
207
 
340
 
        recv_sys->last_block_buf_start = static_cast<byte *>(mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE));
 
208
        recv_sys->last_block_buf_start = mem_alloc(2 * OS_FILE_LOG_BLOCK_SIZE);
341
209
 
342
 
        recv_sys->last_block = static_cast<byte *>(ut_align(recv_sys->last_block_buf_start,
343
 
                                        OS_FILE_LOG_BLOCK_SIZE));
 
210
        recv_sys->last_block = ut_align(recv_sys->last_block_buf_start,
 
211
                                        OS_FILE_LOG_BLOCK_SIZE);
344
212
        recv_sys->found_corrupt_log = FALSE;
345
213
 
346
214
        recv_max_page_lsn = 0;
371
239
        hash_table_free(recv_sys->addr_hash);
372
240
        mem_heap_empty(recv_sys->heap);
373
241
 
374
 
        recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 512);
 
242
        recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 256);
375
243
}
376
244
 
377
245
#ifndef UNIV_HOTBACKUP
380
248
Frees the recovery system. */
381
249
static
382
250
void
383
 
recv_sys_debug_free(void)
384
 
/*=====================*/
 
251
recv_sys_free(void)
 
252
/*===============*/
385
253
{
386
254
        mutex_enter(&(recv_sys->mutex));
387
255
 
390
258
        ut_free(recv_sys->buf);
391
259
        mem_free(recv_sys->last_block_buf_start);
392
260
 
393
 
        recv_sys->buf = NULL;
 
261
        recv_sys->addr_hash = NULL;
394
262
        recv_sys->heap = NULL;
395
 
        recv_sys->addr_hash = NULL;
396
 
        recv_sys->last_block_buf_start = NULL;
397
263
 
398
264
        mutex_exit(&(recv_sys->mutex));
399
 
 
400
 
        /* Free up the flush_rbt. */
401
 
        buf_flush_free_flush_rbt();
402
265
}
403
266
# endif /* UNIV_LOG_DEBUG */
404
267
 
569
432
        ib_uint64_t     start_lsn;
570
433
        ib_uint64_t     end_lsn;
571
434
        ib_uint64_t     recovered_lsn;
 
435
        ib_uint64_t     limit_lsn;
572
436
 
573
437
        recovered_lsn = recv_sys->recovered_lsn;
 
438
        limit_lsn = recv_sys->limit_lsn;
574
439
 
575
440
        /* Read the last recovered log block to the recovery system buffer:
576
441
        the block is always incomplete */
702
567
 
703
568
                        group->state = LOG_GROUP_OK;
704
569
 
705
 
                        group->lsn = mach_read_from_8(
 
570
                        group->lsn = mach_read_ull(
706
571
                                buf + LOG_CHECKPOINT_LSN);
707
572
                        group->lsn_offset = mach_read_from_4(
708
573
                                buf + LOG_CHECKPOINT_OFFSET);
709
 
                        checkpoint_no = mach_read_from_8(
 
574
                        checkpoint_no = mach_read_ull(
710
575
                                buf + LOG_CHECKPOINT_NO);
711
576
 
712
577
#ifdef UNIV_DEBUG
776
641
        cp_buf = hdr + LOG_CHECKPOINT_1;
777
642
 
778
643
        if (recv_check_cp_is_consistent(cp_buf)) {
779
 
                max_cp_no = mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO);
 
644
                max_cp_no = mach_read_ull(cp_buf + LOG_CHECKPOINT_NO);
780
645
                max_cp = LOG_CHECKPOINT_1;
781
646
        }
782
647
 
783
648
        cp_buf = hdr + LOG_CHECKPOINT_2;
784
649
 
785
650
        if (recv_check_cp_is_consistent(cp_buf)) {
786
 
                if (mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO) > max_cp_no) {
 
651
                if (mach_read_ull(cp_buf + LOG_CHECKPOINT_NO) > max_cp_no) {
787
652
                        max_cp = LOG_CHECKPOINT_2;
788
653
                }
789
654
        }
794
659
 
795
660
        cp_buf = hdr + max_cp;
796
661
 
797
 
        *lsn = mach_read_from_8(cp_buf + LOG_CHECKPOINT_LSN);
 
662
        *lsn = mach_read_ull(cp_buf + LOG_CHECKPOINT_LSN);
798
663
        *offset = mach_read_from_4(cp_buf + LOG_CHECKPOINT_OFFSET);
799
664
 
800
665
        /* If the user is running a pre-3.23.50 version of InnoDB, its
814
679
 
815
680
        /*      fprintf(stderr, "fsp limit %lu MB\n", *fsp_limit); */
816
681
 
817
 
        *cp_no = mach_read_from_8(cp_buf + LOG_CHECKPOINT_NO);
 
682
        *cp_no = mach_read_ull(cp_buf + LOG_CHECKPOINT_NO);
818
683
 
819
 
        *first_header_lsn = mach_read_from_8(hdr + LOG_FILE_START_LSN);
 
684
        *first_header_lsn = mach_read_ull(hdr + LOG_FILE_START_LSN);
820
685
 
821
686
        return(TRUE);
822
687
}
988
853
        }
989
854
 
990
855
        switch (type) {
991
 
#ifdef UNIV_LOG_LSN_DEBUG
992
 
        case MLOG_LSN:
993
 
                /* The LSN is checked in recv_parse_log_rec(). */
994
 
                break;
995
 
#endif /* UNIV_LOG_LSN_DEBUG */
996
856
        case MLOG_1BYTE: case MLOG_2BYTES: case MLOG_4BYTES: case MLOG_8BYTES:
997
857
#ifdef UNIV_DEBUG
998
858
                if (page && page_type == FIL_PAGE_TYPE_ALLOCATED
1319
1179
{
1320
1180
        recv_addr_t*    recv_addr;
1321
1181
 
1322
 
        recv_addr = static_cast<recv_addr_t *>(HASH_GET_FIRST(recv_sys->addr_hash,
1323
 
                                   recv_hash(space, page_no)));
 
1182
        recv_addr = HASH_GET_FIRST(recv_sys->addr_hash,
 
1183
                                   recv_hash(space, page_no));
1324
1184
        while (recv_addr) {
1325
1185
                if ((recv_addr->space == space)
1326
1186
                    && (recv_addr->page_no == page_no)) {
1328
1188
                        break;
1329
1189
                }
1330
1190
 
1331
 
                recv_addr = static_cast<recv_addr_t *>(HASH_GET_NEXT(addr_hash, recv_addr));
 
1191
                recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
1332
1192
        }
1333
1193
 
1334
1194
        return(recv_addr);
1363
1223
 
1364
1224
        len = rec_end - body;
1365
1225
 
1366
 
        recv = static_cast<recv_t *>(mem_heap_alloc(recv_sys->heap, sizeof(recv_t)));
 
1226
        recv = mem_heap_alloc(recv_sys->heap, sizeof(recv_t));
1367
1227
        recv->type = type;
1368
1228
        recv->len = rec_end - body;
1369
1229
        recv->start_lsn = start_lsn;
1372
1232
        recv_addr = recv_get_fil_addr_struct(space, page_no);
1373
1233
 
1374
1234
        if (recv_addr == NULL) {
1375
 
                recv_addr = static_cast<recv_addr_t *>(mem_heap_alloc(recv_sys->heap,
1376
 
                                           sizeof(recv_addr_t)));
 
1235
                recv_addr = mem_heap_alloc(recv_sys->heap,
 
1236
                                           sizeof(recv_addr_t));
1377
1237
                recv_addr->space = space;
1378
1238
                recv_addr->page_no = page_no;
1379
1239
                recv_addr->state = RECV_NOT_PROCESSED;
1405
1265
                        len = RECV_DATA_BLOCK_SIZE;
1406
1266
                }
1407
1267
 
1408
 
                recv_data = static_cast<recv_data_t *>(mem_heap_alloc(recv_sys->heap,
1409
 
                                           sizeof(recv_data_t) + len));
 
1268
                recv_data = mem_heap_alloc(recv_sys->heap,
 
1269
                                           sizeof(recv_data_t) + len);
1410
1270
                *prev_field = recv_data;
1411
1271
 
1412
 
                memcpy(recv_data + 1, body, len);
 
1272
                ut_memcpy(((byte*)recv_data) + sizeof(recv_data_t), body, len);
1413
1273
 
1414
1274
                prev_field = &(recv_data->next);
1415
1275
 
1467
1327
        buf_block_t*    block)  /*!< in/out: buffer block */
1468
1328
{
1469
1329
        page_t*         page;
1470
 
        page_zip_des_t* page_zip;
1471
1330
        recv_addr_t*    recv_addr;
1472
1331
        recv_t*         recv;
1473
1332
        byte*           buf;
1517
1376
        mtr_set_log_mode(&mtr, MTR_LOG_NONE);
1518
1377
 
1519
1378
        page = block->frame;
1520
 
        page_zip = buf_block_get_page_zip(block);
1521
1379
 
1522
1380
#ifndef UNIV_HOTBACKUP
1523
1381
        if (just_read_in) {
1539
1397
#endif /* !UNIV_HOTBACKUP */
1540
1398
 
1541
1399
        /* Read the newest modification lsn from the page */
1542
 
        page_lsn = mach_read_from_8(page + FIL_PAGE_LSN);
 
1400
        page_lsn = mach_read_ull(page + FIL_PAGE_LSN);
1543
1401
 
1544
1402
#ifndef UNIV_HOTBACKUP
1545
1403
        /* It may be that the page has been modified in the buffer
1568
1426
                        /* We have to copy the record body to a separate
1569
1427
                        buffer */
1570
1428
 
1571
 
                        buf = static_cast<byte *>(mem_alloc(recv->len));
 
1429
                        buf = mem_alloc(recv->len);
1572
1430
 
1573
1431
                        recv_data_copy_to_buf(buf, recv);
1574
1432
                } else {
1578
1436
                if (recv->type == MLOG_INIT_FILE_PAGE) {
1579
1437
                        page_lsn = page_newest_lsn;
1580
1438
 
1581
 
                        memset(FIL_PAGE_LSN + page, 0, 8);
1582
 
                        memset(UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM
1583
 
                               + page, 0, 8);
1584
 
 
1585
 
                        if (page_zip) {
1586
 
                                memset(FIL_PAGE_LSN + page_zip->data, 0, 8);
1587
 
                        }
 
1439
                        mach_write_ull(page + UNIV_PAGE_SIZE
 
1440
                                       - FIL_PAGE_END_LSN_OLD_CHKSUM, 0);
 
1441
                        mach_write_ull(page + FIL_PAGE_LSN, 0);
1588
1442
                }
1589
1443
 
1590
1444
                if (recv->start_lsn >= page_lsn) {
1591
1445
 
1592
 
                        ib_uint64_t     page_end_lsn;
1593
 
 
1594
1446
                        if (!modification_to_page) {
1595
1447
 
1596
1448
                                modification_to_page = TRUE;
1612
1464
                        recv_parse_or_apply_log_rec_body(recv->type, buf,
1613
1465
                                                         buf + recv->len,
1614
1466
                                                         block, &mtr);
1615
 
 
1616
 
                        page_end_lsn = recv->start_lsn + recv->len;
1617
 
                        mach_write_to_8(FIL_PAGE_LSN + page, page_end_lsn);
1618
 
                        mach_write_to_8(UNIV_PAGE_SIZE
1619
 
                                        - FIL_PAGE_END_LSN_OLD_CHKSUM
1620
 
                                        + page, page_end_lsn);
1621
 
 
1622
 
                        if (page_zip) {
1623
 
                                mach_write_to_8(FIL_PAGE_LSN
1624
 
                                                + page_zip->data, page_end_lsn);
1625
 
                        }
 
1467
                        mach_write_ull(page + UNIV_PAGE_SIZE
 
1468
                                       - FIL_PAGE_END_LSN_OLD_CHKSUM,
 
1469
                                       recv->start_lsn + recv->len);
 
1470
                        mach_write_ull(page + FIL_PAGE_LSN,
 
1471
                                       recv->start_lsn + recv->len);
1626
1472
                }
1627
1473
 
1628
1474
                if (recv->len > RECV_DATA_BLOCK_SIZE) {
1659
1505
        if (modification_to_page) {
1660
1506
                ut_a(block);
1661
1507
 
1662
 
                log_flush_order_mutex_enter();
1663
1508
                buf_flush_recv_note_modification(block, start_lsn, end_lsn);
1664
 
                log_flush_order_mutex_exit();
1665
1509
        }
1666
1510
#endif /* !UNIV_HOTBACKUP */
1667
1511
 
1767
1611
 
1768
1612
        for (i = 0; i < hash_get_n_cells(recv_sys->addr_hash); i++) {
1769
1613
 
1770
 
                recv_addr = static_cast<recv_addr_t *>(HASH_GET_FIRST(recv_sys->addr_hash, i));
 
1614
                recv_addr = HASH_GET_FIRST(recv_sys->addr_hash, i);
1771
1615
 
1772
1616
                while (recv_addr) {
1773
1617
                        ulint   space = recv_addr->space;
1808
1652
                                mutex_enter(&(recv_sys->mutex));
1809
1653
                        }
1810
1654
 
1811
 
                        recv_addr = static_cast<recv_addr_t *>(HASH_GET_NEXT(addr_hash, recv_addr));
 
1655
                        recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
1812
1656
                }
1813
1657
 
1814
1658
                if (has_printed
1842
1686
                /* Flush all the file pages to disk and invalidate them in
1843
1687
                the buffer pool */
1844
1688
 
1845
 
                ut_d(recv_no_log_write = TRUE);
1846
1689
                mutex_exit(&(recv_sys->mutex));
1847
1690
                mutex_exit(&(log_sys->mutex));
1848
1691
 
1849
 
                n_pages = buf_flush_list(ULINT_MAX, IB_ULONGLONG_MAX);
1850
 
                ut_a(n_pages != ULINT_UNDEFINED);
1851
 
  
1852
 
                buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
 
1692
                n_pages = buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX,
 
1693
                                          IB_ULONGLONG_MAX);
 
1694
                ut_a(n_pages != ULINT_UNDEFINED);
 
1695
 
 
1696
                buf_flush_wait_batch_end(BUF_FLUSH_LIST);
1853
1697
 
1854
1698
                buf_pool_invalidate();
1855
1699
 
1856
1700
                mutex_enter(&(log_sys->mutex));
1857
1701
                mutex_enter(&(recv_sys->mutex));
1858
 
                ut_d(recv_no_log_write = FALSE);
1859
1702
 
1860
1703
                recv_no_ibuf_operations = FALSE;
1861
1704
        }
1989
1832
 
1990
1833
                        buf_flush_init_for_writing(
1991
1834
                                block->frame, buf_block_get_page_zip(block),
1992
 
                                mach_read_from_8(block->frame + FIL_PAGE_LSN));
 
1835
                                mach_read_ull(block->frame + FIL_PAGE_LSN));
1993
1836
 
1994
1837
                        if (zip_size) {
1995
1838
                                error = fil_io(OS_FILE_WRITE, TRUE,
2067
1910
                return(0);
2068
1911
        }
2069
1912
 
2070
 
#ifdef UNIV_LOG_LSN_DEBUG
2071
 
        if (*type == MLOG_LSN) {
2072
 
                ib_uint64_t     lsn = (ib_uint64_t) *space << 32 | *page_no;
2073
 
# ifdef UNIV_LOG_DEBUG
2074
 
                ut_a(lsn == log_sys->old_lsn);
2075
 
# else /* UNIV_LOG_DEBUG */
2076
 
                ut_a(lsn == recv_sys->recovered_lsn);
2077
 
# endif /* UNIV_LOG_DEBUG */
 
1913
        /* Check that page_no is sensible */
 
1914
 
 
1915
        if (UNIV_UNLIKELY(*page_no > 0x8FFFFFFFUL)) {
 
1916
 
 
1917
                recv_sys->found_corrupt_log = TRUE;
 
1918
 
 
1919
                return(0);
2078
1920
        }
2079
 
#endif /* UNIV_LOG_LSN_DEBUG */
2080
1921
 
2081
1922
        new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr,
2082
1923
                                                   NULL, NULL);
2186
2027
                putc('\n', stderr);
2187
2028
        }
2188
2029
 
2189
 
#ifndef UNIV_HOTBACKUP
2190
 
        if (!srv_force_recovery) {
2191
 
                fputs("InnoDB: Set innodb_force_recovery"
2192
 
                      " to ignore this error.\n", stderr);
2193
 
                ut_error;
2194
 
        }
2195
 
#endif /* !UNIV_HOTBACKUP */
2196
 
 
2197
2030
        fputs("InnoDB: WARNING: the log file may have been corrupt and it\n"
2198
2031
              "InnoDB: is possible that the log scan did not proceed\n"
2199
2032
              "InnoDB: far enough in recovery! Please run CHECK TABLE\n"
2334
2167
#endif
2335
2168
                        /* In normal mysqld crash recovery we do not try to
2336
2169
                        replay file operations */
2337
 
#ifdef UNIV_LOG_LSN_DEBUG
2338
 
                } else if (type == MLOG_LSN) {
2339
 
                        /* Do not add these records to the hash table.
2340
 
                        The page number and space id fields are misused
2341
 
                        for something else. */
2342
 
#endif /* UNIV_LOG_LSN_DEBUG */
2343
2170
                } else {
2344
2171
                        recv_add_to_hash_table(type, space, page_no, body,
2345
2172
                                               ptr + len, old_lsn,
2371
2198
                                = recv_sys->recovered_offset + total_len;
2372
2199
                        recv_previous_parsed_rec_is_multi = 1;
2373
2200
 
2374
 
#ifdef UNIV_LOG_DEBUG
2375
2201
                        if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
 
2202
#ifdef UNIV_LOG_DEBUG
2376
2203
                                recv_check_incomplete_log_recs(ptr, len);
 
2204
#endif /* UNIV_LOG_DEBUG */
2377
2205
                        }
2378
 
#endif /* UNIV_LOG_DEBUG */
2379
2206
 
2380
2207
#ifdef UNIV_DEBUG
2381
2208
                        if (log_debug_writes) {
2439
2266
                                break;
2440
2267
                        }
2441
2268
 
2442
 
                        if (store_to_hash
2443
 
#ifdef UNIV_LOG_LSN_DEBUG
2444
 
                            && type != MLOG_LSN
2445
 
#endif /* UNIV_LOG_LSN_DEBUG */
2446
 
                            ) {
 
2269
                        if (store_to_hash) {
2447
2270
                                recv_add_to_hash_table(type, space, page_no,
2448
2271
                                                       body, ptr + len,
2449
2272
                                                       old_lsn,
2583
2406
 
2584
2407
        ut_ad(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0);
2585
2408
        ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);
2586
 
        ut_ad(len >= OS_FILE_LOG_BLOCK_SIZE);
 
2409
        ut_ad(len > 0);
2587
2410
        ut_a(store_to_hash <= TRUE);
2588
2411
 
2589
2412
        finished = FALSE;
2592
2415
        scanned_lsn = start_lsn;
2593
2416
        more_data = FALSE;
2594
2417
 
2595
 
        do {
 
2418
        while (log_block < buf + len && !finished) {
 
2419
 
2596
2420
                no = log_block_get_hdr_no(log_block);
2597
2421
                /*
2598
2422
                fprintf(stderr, "Log block header no %lu\n", no);
2708
2532
 
2709
2533
                                recv_sys->found_corrupt_log = TRUE;
2710
2534
 
2711
 
#ifndef UNIV_HOTBACKUP
2712
 
                                if (!srv_force_recovery) {
2713
 
                                        fputs("InnoDB: Set"
2714
 
                                              " innodb_force_recovery"
2715
 
                                              " to ignore this error.\n",
2716
 
                                              stderr);
2717
 
                                        ut_error;
2718
 
                                }
2719
 
#endif /* !UNIV_HOTBACKUP */
2720
 
 
2721
2535
                        } else if (!recv_sys->found_corrupt_log) {
2722
2536
                                more_data = recv_sys_add_to_parsing_buf(
2723
2537
                                        log_block, scanned_lsn);
2732
2546
                        /* Log data for this group ends here */
2733
2547
 
2734
2548
                        finished = TRUE;
2735
 
                        break;
2736
2549
                } else {
2737
2550
                        log_block += OS_FILE_LOG_BLOCK_SIZE;
2738
2551
                }
2739
 
        } while (log_block < buf + len && !finished);
 
2552
        }
2740
2553
 
2741
2554
        *group_scanned_lsn = scanned_lsn;
2742
2555
 
2759
2572
                recv_parse_log_recs(store_to_hash);
2760
2573
 
2761
2574
#ifndef UNIV_HOTBACKUP
2762
 
                if (store_to_hash
2763
 
                    && mem_heap_get_size(recv_sys->heap) > available_memory) {
 
2575
                if (store_to_hash && mem_heap_get_size(recv_sys->heap)
 
2576
                    > available_memory) {
2764
2577
 
2765
2578
                        /* Hash table of log records has grown too big:
2766
2579
                        empty it; FALSE means no ibuf operations
2812
2625
                                       group, start_lsn, end_lsn);
2813
2626
 
2814
2627
                finished = recv_scan_log_recs(
2815
 
                        (buf_pool_get_n_pages()
2816
 
                        - (recv_n_pool_free_frames * srv_buf_pool_instances))
2817
 
                        * UNIV_PAGE_SIZE,
2818
 
                        TRUE, log_sys->buf, RECV_SCAN_SIZE,
 
2628
                        (buf_pool->curr_size - recv_n_pool_free_frames)
 
2629
                        * UNIV_PAGE_SIZE, TRUE, log_sys->buf, RECV_SCAN_SIZE,
2819
2630
                        start_lsn, contiguous_lsn, group_scanned_lsn);
2820
2631
                start_lsn = end_lsn;
2821
2632
        }
2902
2713
        ib_uint64_t     old_scanned_lsn;
2903
2714
        ib_uint64_t     group_scanned_lsn= 0;
2904
2715
        ib_uint64_t     contiguous_lsn;
2905
 
#ifdef UNIV_LOG_ARCHIVE
2906
2716
        ib_uint64_t     archived_lsn;
2907
 
#endif /* UNIV_LOG_ARCHIVE */
2908
2717
        byte*           buf;
2909
2718
        byte            log_hdr_buf[LOG_FILE_HDR_SIZE];
2910
2719
        ulint           err;
2957
2766
 
2958
2767
        buf = log_sys->checkpoint_buf;
2959
2768
 
2960
 
        checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
2961
 
        checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
2962
 
#ifdef UNIV_LOG_ARCHIVE
2963
 
        archived_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN);
2964
 
#endif /* UNIV_LOG_ARCHIVE */
 
2769
        checkpoint_lsn = mach_read_ull(buf + LOG_CHECKPOINT_LSN);
 
2770
        checkpoint_no = mach_read_ull(buf + LOG_CHECKPOINT_NO);
 
2771
        archived_lsn = mach_read_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN);
2965
2772
 
2966
2773
        /* Read the first log file header to print a note if this is
2967
2774
        a recovery from a restored InnoDB Hot Backup */
3253
3060
recv_recovery_from_checkpoint_finish(void)
3254
3061
/*======================================*/
3255
3062
{
 
3063
        int             i;
 
3064
 
3256
3065
        /* Apply the hashed log records to the respective file pages */
3257
3066
 
3258
3067
        if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
3267
3076
        }
3268
3077
#endif /* UNIV_DEBUG */
3269
3078
 
 
3079
        if (recv_needed_recovery) {
 
3080
                trx_sys_print_mysql_master_log_pos();
 
3081
                trx_sys_print_mysql_binlog_offset();
 
3082
        }
 
3083
 
3270
3084
        if (recv_sys->found_corrupt_log) {
3271
3085
 
3272
3086
                fprintf(stderr,
3288
3102
        recv_recovery_on = FALSE;
3289
3103
 
3290
3104
#ifndef UNIV_LOG_DEBUG
3291
 
        recv_sys_debug_free();
 
3105
        recv_sys_free();
3292
3106
#endif
3293
 
        /* Roll back any recovered data dictionary transactions, so
3294
 
        that the data dictionary tables will be free of any locks.
3295
 
        The data dictionary latch should guarantee that there is at
3296
 
        most one data dictionary transaction active at a time. */
3297
 
        trx_rollback_or_clean_recovered(FALSE);
3298
 
}
3299
3107
 
3300
 
/********************************************************//**
3301
 
Initiates the rollback of active transactions. */
3302
 
UNIV_INTERN
3303
 
void
3304
 
recv_recovery_rollback_active(void)
3305
 
/*===============================*/
3306
 
{
3307
 
        int             i;
 
3108
        /* Drop partially created indexes. */
 
3109
        row_merge_drop_temp_indexes();
3308
3110
 
3309
3111
#ifdef UNIV_SYNC_DEBUG
3310
3112
        /* Wait for a while so that created threads have time to suspend
3314
3116
        /* Switch latching order checks on in sync0sync.c */
3315
3117
        sync_order_checks_on = TRUE;
3316
3118
#endif
3317
 
        /* Drop partially created indexes. */
3318
 
        row_merge_drop_temp_indexes();
3319
 
        /* Drop temporary tables. */
3320
 
        row_mysql_drop_temp_tables();
3321
 
 
3322
3119
        if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) {
3323
3120
                /* Rollback the uncommitted transactions which have no user
3324
3121
                session */
3434
3231
                sprintf(name, "%s%s%lu", log_dir,
3435
3232
                        ib_logfile_basename, (ulong)i);
3436
3233
 
3437
 
                log_file = os_file_create_simple(innodb_file_log_key,
3438
 
                                                 name, OS_FILE_CREATE,
3439
 
                                                 OS_FILE_READ_WRITE,
3440
 
                                                 &success);
 
3234
                log_file = os_file_create_simple(name, OS_FILE_CREATE,
 
3235
                                                 OS_FILE_READ_WRITE, &success);
3441
3236
                if (!success) {
3442
3237
                        fprintf(stderr,
3443
3238
                                "InnoDB: Cannot create %s. Check that"
3476
3271
                                      LOG_BLOCK_HDR_SIZE);
3477
3272
        sprintf(name, "%s%s%lu", log_dir, ib_logfile_basename, (ulong)0);
3478
3273
 
3479
 
        log_file = os_file_create_simple(innodb_file_log_key,
3480
 
                                         name, OS_FILE_OPEN,
 
3274
        log_file = os_file_create_simple(name, OS_FILE_OPEN,
3481
3275
                                         OS_FILE_READ_WRITE, &success);
3482
3276
        if (!success) {
3483
3277
                fprintf(stderr, "InnoDB: Cannot open %s.\n", name);
3495
3289
#endif /* UNIV_HOTBACKUP */
3496
3290
 
3497
3291
#ifdef UNIV_LOG_ARCHIVE
3498
 
/* Dead code */
3499
3292
/******************************************************//**
3500
3293
Reads from the archive of a log group and performs recovery.
3501
3294
@return TRUE if no more complete consistent archive files */
3528
3321
 
3529
3322
        log_archived_file_name_gen(name, group->id, group->archived_file_no);
3530
3323
 
3531
 
        file_handle = os_file_create(innodb_file_log_key,
3532
 
                                     name, OS_FILE_OPEN,
 
3324
        file_handle = os_file_create(name, OS_FILE_OPEN,
3533
3325
                                     OS_FILE_LOG, OS_FILE_AIO, &ret);
3534
3326
 
3535
3327
        if (ret == FALSE) {
3606
3398
                return(TRUE);
3607
3399
        }
3608
3400
 
3609
 
        start_lsn = mach_read_from_8(buf + LOG_FILE_START_LSN);
3610
 
        file_end_lsn = mach_read_from_8(buf + LOG_FILE_END_LSN);
 
3401
        start_lsn = mach_read_ull(buf + LOG_FILE_START_LSN);
 
3402
        file_end_lsn = mach_read_ull(buf + LOG_FILE_END_LSN);
3611
3403
 
3612
3404
        if (!recv_sys->scanned_lsn) {
3613
3405
 
3661
3453
                       read_offset % UNIV_PAGE_SIZE, len, buf, NULL);
3662
3454
 
3663
3455
                ret = recv_scan_log_recs(
3664
 
                        (buf_pool_get_n_pages()
3665
 
                        - (recv_n_pool_free_frames * srv_buf_pool_instances))
 
3456
                        (buf_pool->n_frames - recv_n_pool_free_frames)
3666
3457
                        * UNIV_PAGE_SIZE, TRUE, buf, len, start_lsn,
3667
3458
                        &dummy_lsn, &scanned_lsn);
3668
3459