1
--- a/storage/innobase/btr/btr0btr.cc
2
+++ b/storage/innobase/btr/btr0btr.cc
4
/**************************************************************//**
5
Gets the root node of a tree and x- or s-latches it.
6
@return root page, x- or s-latched */
13
/************************************************************//**
14
Returns the child page of a node pointer and x-latches it.
15
@return child page, x-latched */
19
btr_node_ptr_get_child(
20
/*===================*/
21
--- a/storage/innobase/buf/buf0buf.cc
22
+++ b/storage/innobase/buf/buf0buf.cc
24
if (checksum_field1 == 0 && checksum_field2 == 0
25
&& mach_read_from_4(read_buf + FIL_PAGE_LSN) == 0) {
26
/* make sure that the page is really empty */
28
+ /* Do not make sure that the page is really empty as this check
29
+ is incompatible with 1st newly-created tablespace pages, which
30
+ have FIL_PAGE_FIL_FLUSH_LSN != 0, FIL_PAGE_OR_CHKSUM == 0,
31
+ FIL_PAGE_END_LSN_OLD_CHKSUM == 0 */
32
ut_d(for (ulint i = 0; i < UNIV_PAGE_SIZE; i++) {
33
ut_a(read_buf[i] == 0); });
39
--- a/storage/innobase/fil/fil0fil.cc
40
+++ b/storage/innobase/fil/fil0fil.cc
42
#include "dict0dict.h"
43
#include "page0page.h"
45
+#include "pars0pars.h"
48
#include "row0mysql.h"
49
#ifndef UNIV_HOTBACKUP
52
/** The tablespace memory cache. This variable is NULL before the module is
54
-static fil_system_t* fil_system = NULL;
55
+fil_system_t* fil_system = NULL;
57
/** Determine if (i) is a user tablespace id or not. */
58
# define fil_is_user_tablespace_id(i) ((i) > srv_undo_tablespaces_open)
60
off the LRU list if it is in the LRU list. The caller must hold the fil_sys
65
fil_node_prepare_for_io(
66
/*====================*/
67
fil_node_t* node, /*!< in: file node */
69
Opens a file of a node of a tablespace. The caller must own the fil_system
76
fil_node_t* node, /*!< in: file node */
78
OS_FILE_READ_ONLY, &success);
80
/* The following call prints an error message */
81
+ if (os_file_get_last_error(TRUE) == OS_FILE_NOT_FOUND)
83
+ ut_print_timestamp(stderr);
85
+ " InnoDB: Warning: cannot open %s\n"
86
+ "InnoDB: this can happen if the table "
87
+ "was removed or renamed during an \n"
88
+ "InnoDB: xtrabackup run and is not dangerous.\n",
90
+ return(OS_FILE_NOT_FOUND);
93
os_file_get_last_error(true);
95
ut_print_timestamp(stderr);
98
if (UNIV_UNLIKELY(space_id != space->id)) {
100
- "InnoDB: Error: tablespace id is %lu"
101
+ "InnoDB: Warning: tablespace id is %lu"
102
" in the data dictionary\n"
103
- "InnoDB: but in file %s it is %lu!\n",
104
+ "InnoDB: but in file %s it is %lu!\n"
105
+ "InnoDB: this can happen if the table "
106
+ "metadata was modified during an xtrabackup "
108
+ "InnoDB: and is not dangerous.\n",
110
space->id, node->name, space_id);
113
+ return(OS_FILE_NOT_FOUND);
116
if (UNIV_UNLIKELY(space_id == ULINT_UNDEFINED
120
if (size_bytes >= 1024 * 1024) {
121
- /* Truncate the size to whole megabytes. */
122
- size_bytes = ut_2pow_round(size_bytes, 1024 * 1024);
123
+ /* The size should be exact for after applying
125
+ //size_bytes = ut_2pow_round(size_bytes, 1024 * 1024);
128
if (!fsp_flags_is_compressed(flags)) {
130
/* Put the node to the LRU list */
131
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
137
/**********************************************************************//**
138
@@ -1491,7 +1513,12 @@
139
the file yet; the following calls will open it and update the
142
- fil_node_prepare_for_io(node, fil_system, space);
143
+ if (fil_node_prepare_for_io(node, fil_system, space))
145
+ mutex_exit(&fil_system->mutex);
149
fil_node_complete_io(node, fil_system, OS_FILE_READ);
152
@@ -2095,7 +2122,7 @@
156
-#ifndef UNIV_HOTBACKUP
158
/********************************************************//**
159
Writes a log record about an .ibd file create/rename/delete. */
161
@@ -2329,7 +2356,7 @@
162
space_id, name, path, flags,
163
DICT_TF2_USE_TABLESPACE,
164
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
170
@@ -2687,7 +2714,7 @@
173
if (err == DB_SUCCESS) {
174
-#ifndef UNIV_HOTBACKUP
176
/* Write a log record about the deletion of the .ibd
177
file, so that ibbackup can replay it in the
178
--apply-log phase. We use a dummy mtr and the familiar
179
@@ -3042,7 +3069,7 @@
181
mutex_exit(&fil_system->mutex);
183
-#ifndef UNIV_HOTBACKUP
185
if (success && !recv_recovery_on) {
188
@@ -3426,7 +3453,7 @@
192
-#ifndef UNIV_HOTBACKUP
196
ulint mlog_file_flag = 0;
197
@@ -3504,6 +3531,97 @@
198
#endif /* UNIV_LOG_ARCHIVE */
203
+fil_remove_invalid_table_from_data_dict(const char *name)
206
+ pars_info_t* info = NULL;
208
+ trx = trx_allocate_for_mysql();
209
+ trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
211
+ ut_ad(mutex_own(&dict_sys->mutex));
213
+ trx->op_info = "removing invalid table from data dictionary";
215
+ info = pars_info_create();
217
+ pars_info_add_str_literal(info, "table_name", name);
220
+ "PROCEDURE DROP_TABLE_PROC () IS\n"
221
+ "sys_foreign_id CHAR;\n"
224
+ "foreign_id CHAR;\n"
227
+ "SELECT ID INTO table_id\n"
228
+ "FROM SYS_TABLES\n"
229
+ "WHERE NAME = :table_name\n"
230
+ "LOCK IN SHARE MODE;\n"
231
+ "IF (SQL % NOTFOUND) THEN\n"
235
+ "SELECT ID INTO sys_foreign_id\n"
236
+ "FROM SYS_TABLES\n"
237
+ "WHERE NAME = 'SYS_FOREIGN'\n"
238
+ "LOCK IN SHARE MODE;\n"
239
+ "IF (SQL % NOTFOUND) THEN\n"
242
+ "IF (:table_name = 'SYS_FOREIGN') THEN\n"
245
+ "IF (:table_name = 'SYS_FOREIGN_COLS') THEN\n"
248
+ "WHILE found = 1 LOOP\n"
249
+ " SELECT ID INTO foreign_id\n"
250
+ " FROM SYS_FOREIGN\n"
251
+ " WHERE FOR_NAME = :table_name\n"
252
+ " AND TO_BINARY(FOR_NAME)\n"
253
+ " = TO_BINARY(:table_name)\n"
254
+ " LOCK IN SHARE MODE;\n"
255
+ " IF (SQL % NOTFOUND) THEN\n"
258
+ " DELETE FROM SYS_FOREIGN_COLS\n"
259
+ " WHERE ID = foreign_id;\n"
260
+ " DELETE FROM SYS_FOREIGN\n"
261
+ " WHERE ID = foreign_id;\n"
265
+ "WHILE found = 1 LOOP\n"
266
+ " SELECT ID INTO index_id\n"
267
+ " FROM SYS_INDEXES\n"
268
+ " WHERE TABLE_ID = table_id\n"
269
+ " LOCK IN SHARE MODE;\n"
270
+ " IF (SQL % NOTFOUND) THEN\n"
273
+ " DELETE FROM SYS_FIELDS\n"
274
+ " WHERE INDEX_ID = index_id;\n"
275
+ " DELETE FROM SYS_INDEXES\n"
276
+ " WHERE ID = index_id\n"
277
+ " AND TABLE_ID = table_id;\n"
280
+ "DELETE FROM SYS_COLUMNS\n"
281
+ "WHERE TABLE_ID = table_id;\n"
282
+ "DELETE FROM SYS_TABLES\n"
283
+ "WHERE ID = table_id;\n"
287
+ trx_commit_for_mysql(trx);
289
+ trx_free_for_mysql(trx);
292
/********************************************************************//**
293
Tries to open a single-table tablespace and optionally checks that the
294
space id in it is correct. If this does not succeed, print an error message
295
@@ -3712,11 +3830,15 @@
296
/* The following call prints an error message */
297
os_file_get_last_error(true);
299
- ib_logf(IB_LOG_LEVEL_ERROR,
300
+ ib_logf(IB_LOG_LEVEL_WARN,
301
"Could not find a valid tablespace file for '%s'. "
302
"See " REFMAN "innodb-troubleshooting-datadict.html "
303
"for how to resolve the issue.",
305
+ ib_logf(IB_LOG_LEVEL_WARN,
306
+ "It will be removed from the data dictionary.");
308
+ fil_remove_invalid_table_from_data_dict(tablename);
312
@@ -4135,7 +4257,7 @@
314
ulong minimum_size = FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE;
315
if (size < minimum_size) {
316
-#ifndef UNIV_HOTBACKUP
318
ib_logf(IB_LOG_LEVEL_ERROR,
319
"The size of single-table tablespace file %s "
320
"is only " UINT64PF ", should be at least %lu!",
321
@@ -4263,7 +4385,7 @@
322
idea is to read as much good data as we can and jump over bad data.
323
@return 0 if ok, -1 if error even after the retries, 1 if at the end
328
fil_file_readdir_next_file(
329
/*=======================*/
330
@@ -4359,7 +4481,9 @@
331
"%s/%s", fil_path_to_mysql_datadir, dbinfo.name);
332
srv_normalize_path_for_win(dbpath);
334
- dbdir = os_file_opendir(dbpath, FALSE);
335
+ /* We want wrong directory permissions to be a fatal error for
337
+ dbdir = os_file_opendir(dbpath, TRUE);
341
@@ -4538,6 +4662,7 @@
343
fil_space_t* fnamespace;
345
+ ibool remove_from_data_dict = FALSE;
349
@@ -4615,6 +4740,10 @@
350
if (fnamespace == NULL) {
351
if (print_error_if_does_not_exist) {
352
fil_report_missing_tablespace(name, id);
353
+ ib_logf(IB_LOG_LEVEL_WARN,
354
+ "It will be removed from "
355
+ "the data dictionary.");
356
+ remove_from_data_dict = TRUE;
359
ut_print_timestamp(stderr);
360
@@ -4638,6 +4767,10 @@
362
mutex_exit(&fil_system->mutex);
364
+ if (remove_from_data_dict) {
365
+ fil_remove_invalid_table_from_data_dict(name);
371
@@ -4728,6 +4861,7 @@
377
ut_ad(!srv_read_only_mode);
379
@@ -4772,13 +4906,17 @@
383
- fil_node_prepare_for_io(node, fil_system, space);
384
+ err = fil_node_prepare_for_io(node, fil_system, space);
386
/* At this point it is safe to release fil_system mutex. No
387
other thread can rename, delete or close the file because
388
we have set the node->being_extended flag. */
389
mutex_exit(&fil_system->mutex);
395
start_page_no = space->size;
396
file_start_page_no = space->size - node->size;
398
@@ -5024,7 +5162,7 @@
399
off the LRU list if it is in the LRU list. The caller must hold the fil_sys
404
fil_node_prepare_for_io(
405
/*====================*/
406
fil_node_t* node, /*!< in: file node */
407
@@ -5044,9 +5182,12 @@
410
if (node->open == FALSE) {
412
/* File is closed: open it */
413
ut_a(node->n_pending == 0);
414
- fil_node_open_file(node, system, space);
415
+ err = fil_node_open_file(node, system, space);
420
if (node->n_pending == 0 && fil_space_belongs_in_lru(space)) {
421
@@ -5058,6 +5199,8 @@
429
/********************************************************************//**
430
@@ -5259,6 +5402,16 @@
432
ut_ad(mode != OS_AIO_IBUF || space->purpose == FIL_TABLESPACE);
434
+ if (space->size > 0 && space->size <= block_offset) {
437
+ mutex_exit(&fil_system->mutex);
438
+ fil_extend_space_to_desired_size(&actual_size, space->id,
440
+ mutex_enter(&fil_system->mutex);
441
+ /* should retry? but it may safe for xtrabackup for now. */
444
node = UT_LIST_GET_FIRST(space->chain);
447
@@ -5290,7 +5443,11 @@
450
/* Open file if closed */
451
- fil_node_prepare_for_io(node, fil_system, space);
452
+ if (fil_node_prepare_for_io(node, fil_system, space)) {
454
+ mutex_exit(&fil_system->mutex);
455
+ return(DB_TABLESPACE_DELETED);
458
/* Check that at least the start offset is within the bounds of a
459
single-table tablespace, including rollback tablespaces. */
460
@@ -6164,6 +6321,7 @@
465
/****************************************************************//**
466
Generate redo logs for swapping two .ibd files */
468
@@ -6187,4 +6345,4 @@
469
0, 0, new_name, old_name, &mtr);
474
--- a/storage/innobase/handler/ha_innodb.cc
475
+++ b/storage/innobase/handler/ha_innodb.cc
476
@@ -1548,7 +1548,7 @@
477
ut_ad(*mbminlen < DATA_MBMAX);
478
ut_ad(*mbmaxlen < DATA_MBMAX);
480
- THD* thd = current_thd;
483
if (thd && thd_sql_command(thd) == SQLCOM_DROP_TABLE) {
485
--- a/storage/innobase/include/srv0srv.h
486
+++ b/storage/innobase/include/srv0srv.h
488
extern ulong srv_max_purge_lag_delay;
490
extern ulong srv_replication_delay;
492
+extern ibool srv_apply_log_only;
494
/*-------------------------------------------*/
496
extern ibool srv_print_innodb_monitor;
497
--- a/storage/innobase/log/log0recv.cc
498
+++ b/storage/innobase/log/log0recv.cc
500
#include "trx0undo.h"
503
-#ifndef UNIV_HOTBACKUP
504
+//#ifndef UNIV_HOTBACKUP
505
# include "buf0rea.h"
506
# include "srv0srv.h"
507
# include "srv0start.h"
508
# include "trx0roll.h"
509
# include "row0merge.h"
510
# include "sync0sync.h"
511
-#else /* !UNIV_HOTBACKUP */
512
+//#else /* !UNIV_HOTBACKUP */
514
/** This is set to FALSE if the backup was originally taken with the
515
ibbackup --include regexp option: then we do not want to create tables in
516
directories which were not included */
517
UNIV_INTERN ibool recv_replay_file_ops = TRUE;
518
-#endif /* !UNIV_HOTBACKUP */
519
+//#endif /* !UNIV_HOTBACKUP */
521
/** Log records are stored in the hash table in chunks at most of this size;
522
this must be less than UNIV_PAGE_SIZE as it is stored in the buffer pool */
524
/* Set appropriate value of recv_n_pool_free_frames. */
525
if (buf_pool_get_curr_size() >= (10 * 1024 * 1024)) {
526
/* Buffer pool of size greater than 10 MB. */
527
- recv_n_pool_free_frames = 512;
528
+ recv_n_pool_free_frames = 1024;
531
recv_sys->buf = static_cast<byte*>(ut_malloc(RECV_PARSING_BUF_SIZE));
533
/***********************************************************************//**
534
Checks the consistency of the checkpoint info
535
@return TRUE if ok */
539
recv_check_cp_is_consistent(
540
/*========================*/
542
/********************************************************//**
543
Looks for the maximum consistent checkpoint from the log groups.
544
@return error code or DB_SUCCESS */
545
-static __attribute__((nonnull, warn_unused_result))
546
+UNIV_INTERN __attribute__((nonnull, warn_unused_result))
548
recv_find_max_checkpoint(
549
/*=====================*/
551
InnoDB-3.23.52 where the checksum field contains the log block number.
552
@return TRUE if ok, or if the log block may be in the format of InnoDB
553
version predating 3.23.52 */
557
log_block_checksum_is_ok_or_old_format(
558
/*===================================*/
559
@@ -1588,6 +1588,8 @@
560
buf_block_get_page_no(block));
562
if ((recv_addr == NULL)
563
+ /* Fix for http://bugs.mysql.com/bug.php?id=44140 */
564
+ || (recv_addr->state == RECV_BEING_READ && !just_read_in)
565
|| (recv_addr->state == RECV_BEING_PROCESSED)
566
|| (recv_addr->state == RECV_PROCESSED)) {
568
@@ -2413,7 +2415,7 @@
569
|| type == MLOG_FILE_RENAME
570
|| type == MLOG_FILE_DELETE) {
572
-#ifdef UNIV_HOTBACKUP
573
+//#ifdef UNIV_HOTBACKUP
574
if (recv_replay_file_ops) {
576
/* In ibbackup --apply-log, replay an .ibd file
577
@@ -2436,7 +2438,7 @@
583
/* In normal mysqld crash recovery we do not try to
584
replay file operations */
585
#ifdef UNIV_LOG_LSN_DEBUG
586
@@ -2863,8 +2865,14 @@
589
"InnoDB: Doing recovery: scanned up to"
590
- " log sequence number " LSN_PF "\n",
591
- *group_scanned_lsn);
592
+ " log sequence number " LSN_PF " (%lu%%)\n",
593
+ *group_scanned_lsn,
594
+ (ulong) ((*group_scanned_lsn
595
+ - recv_sys->parse_start_lsn)
596
+ / (8 * log_group_get_capacity(
598
+ log_sys->log_groups))
603
@@ -3456,7 +3464,8 @@
604
that the data dictionary tables will be free of any locks.
605
The data dictionary latch should guarantee that there is at
606
most one data dictionary transaction active at a time. */
607
- if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) {
608
+ if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO
609
+ && !srv_apply_log_only) {
610
trx_rollback_or_clean_recovered(FALSE);
613
--- a/storage/innobase/os/os0file.cc
614
+++ b/storage/innobase/os/os0file.cc
619
-#define USE_FILE_LOCK
620
+//#define USE_FILE_LOCK
621
#if defined(UNIV_HOTBACKUP) || defined(__WIN__)
622
/* InnoDB Hot Backup does not lock the data files.
623
* On Windows, mandatory locking is used.
624
--- a/storage/innobase/row/row0merge.cc
625
+++ b/storage/innobase/row/row0merge.cc
626
@@ -3227,9 +3227,11 @@
631
/* Generate the redo logs for file operations */
632
fil_mtr_rename_log(old_table->space, old_name,
633
new_table->space, new_table->name, tmp_name);
636
/* What if the redo logs are flushed to disk here? This is
637
tested with following crash point */
638
--- a/storage/innobase/srv/srv0srv.cc
639
+++ b/storage/innobase/srv/srv0srv.cc
642
UNIV_INTERN ulong srv_replication_delay = 0;
644
+UNIV_INTERN ibool srv_apply_log_only = FALSE;
646
/*-------------------------------------------*/
647
UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
648
UNIV_INTERN ulong srv_spin_wait_delay = 6;
649
@@ -1808,7 +1810,8 @@
651
&& srv_shutdown_state != SRV_SHUTDOWN_NONE
652
&& trx_purge_state() != PURGE_STATE_DISABLED
653
- && trx_purge_state() != PURGE_STATE_EXIT) {
654
+ && trx_purge_state() != PURGE_STATE_EXIT
655
+ && trx_purge_state() != PURGE_STATE_INIT) {
659
--- a/storage/innobase/srv/srv0start.cc
660
+++ b/storage/innobase/srv/srv0start.cc
662
UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE;
664
/** Files comprising the system tablespace */
665
-static os_file_t files[1000];
666
+os_file_t files[1000];
668
/** io_handler_thread parameters for thread identification */
669
static ulint n[SRV_MAX_N_IO_THREADS + 6];
671
/*********************************************************************//**
672
Creates or opens database data files and closes them.
673
@return DB_SUCCESS or error code */
674
-static __attribute__((nonnull, warn_unused_result))
675
+UNIV_INTERN __attribute__((nonnull, warn_unused_result))
677
open_or_create_data_files(
678
/*======================*/
679
@@ -2065,11 +2065,13 @@
680
max_flushed_lsn = min_flushed_lsn
685
/* must have at least 2 log files */
686
ib_logf(IB_LOG_LEVEL_ERROR,
687
"Only one log file found.");
692
/* opened all files */
693
@@ -2326,6 +2328,10 @@
695
recv_recovery_from_checkpoint_finish();
697
+ if (srv_apply_log_only) {
698
+ goto skip_processes;
701
if (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE) {
702
/* The following call is necessary for the insert
703
buffer to work with multiple tablespaces. We must
704
@@ -2647,6 +2653,7 @@
705
&& srv_auto_extend_last_data_file
706
&& sum_of_data_file_sizes < tablespace_size_in_header) {
709
ut_print_timestamp(stderr);
711
" InnoDB: Error: tablespace size stored in header"
712
@@ -2683,6 +2690,7 @@
719
/* Check that os_fast_mutexes work as expected */
720
@@ -2739,6 +2747,7 @@
725
srv_was_started = TRUE;
728
@@ -2794,7 +2803,7 @@
732
- if (!srv_read_only_mode) {
733
+ if (!srv_read_only_mode && !srv_apply_log_only) {
734
/* Shutdown the FTS optimize sub system. */
735
fts_optimize_start_shutdown();
737
--- a/storage/innobase/trx/trx0rseg.cc
738
+++ b/storage/innobase/trx/trx0rseg.cc
741
mutex_free(&rseg->mutex);
743
+ if (!srv_apply_log_only) {
744
/* There can't be any active transactions. */
745
ut_a(UT_LIST_GET_LEN(rseg->update_undo_list) == 0);
746
ut_a(UT_LIST_GET_LEN(rseg->insert_undo_list) == 0);
749
for (undo = UT_LIST_GET_FIRST(rseg->update_undo_cached);
751
--- a/storage/innobase/trx/trx0sys.cc
752
+++ b/storage/innobase/trx/trx0sys.cc
753
@@ -1191,12 +1191,14 @@
755
ut_a(UT_LIST_GET_LEN(trx_sys->ro_trx_list) == 0);
757
+ if (!srv_apply_log_only) {
758
/* Only prepared transactions may be left in the system. Free them. */
759
ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == trx_sys->n_prepared_trx);
761
while ((trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list)) != NULL) {
762
trx_free_prepared(trx);
766
/* There can't be any active transactions. */
767
for (i = 0; i < TRX_SYS_N_RSEGS; ++i) {
768
@@ -1223,10 +1225,12 @@
769
UT_LIST_REMOVE(view_list, trx_sys->view_list, prev_view);
772
+ if (!srv_apply_log_only) {
773
ut_a(UT_LIST_GET_LEN(trx_sys->view_list) == 0);
774
ut_a(UT_LIST_GET_LEN(trx_sys->ro_trx_list) == 0);
775
ut_a(UT_LIST_GET_LEN(trx_sys->rw_trx_list) == 0);
776
ut_a(UT_LIST_GET_LEN(trx_sys->mysql_trx_list) == 0);
779
mutex_exit(&trx_sys->mutex);
781
@@ -1247,6 +1251,10 @@
785
+ if (srv_apply_log_only) {
789
mutex_enter(&trx_sys->mutex);
791
total_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list)
792
--- a/storage/innobase/trx/trx0trx.cc
793
+++ b/storage/innobase/trx/trx0trx.cc
794
@@ -2053,7 +2053,8 @@
795
scenario where some undo generated by a transaction,
796
has XA stuff, and other undo, generated by the same
797
transaction, doesn't. */
798
- trx->support_xa = thd_supports_xa(trx->mysql_thd);
799
+ trx->support_xa = trx->mysql_thd
800
+ ? thd_supports_xa(trx->mysql_thd) : FALSE;