~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:26:39 UTC
  • mfrom: (2157.2.2 give-in-to-pkg-config)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172639-nhy7i72sfhoq13ms
Merged in pkg-config fixes.

Show diffs side-by-side

added added

removed removed

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