summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-04-25 09:05:52 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-04-25 09:05:52 +0300
commitacf6f92aa936fbfe7524617ae57d011ab8f1f96d (patch)
treee7fc2258c06a0fdab1cce115de4d71a091d82d28 /storage
parent765ae6e82165d1bc4cf6cc9f0d556d66a5e172d1 (diff)
parentbc145193c164b895a52b943e73fff53952d48a60 (diff)
downloadmariadb-git-acf6f92aa936fbfe7524617ae57d011ab8f1f96d.tar.gz
Merge 10.2 into 10.3
Diffstat (limited to 'storage')
-rw-r--r--storage/archive/ha_archive.cc50
-rw-r--r--storage/archive/ha_archive.h3
-rw-r--r--storage/innobase/buf/buf0buf.cc52
-rw-r--r--storage/innobase/buf/buf0flu.cc7
-rw-r--r--storage/innobase/buf/buf0lru.cc6
-rw-r--r--storage/innobase/dict/dict0dict.cc18
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc113
-rw-r--r--storage/innobase/include/ibuf0ibuf.h9
-rw-r--r--storage/innobase/include/trx0sys.h4
-rw-r--r--storage/innobase/include/trx0trx.h3
-rw-r--r--storage/innobase/include/trx0trx.ic4
-rw-r--r--storage/innobase/include/trx0types.h9
-rw-r--r--storage/innobase/include/univ.i5
-rw-r--r--storage/innobase/lock/lock0lock.cc1
-rw-r--r--storage/innobase/row/row0undo.cc3
-rw-r--r--storage/innobase/srv/srv0start.cc4
-rw-r--r--storage/innobase/trx/trx0roll.cc5
-rw-r--r--storage/innobase/trx/trx0trx.cc61
-rw-r--r--storage/maria/ma_test3.c2
-rw-r--r--storage/maria/maria_chk.c4
-rw-r--r--storage/myisam/mi_test3.c2
-rw-r--r--storage/myisam/myisamchk.c4
-rw-r--r--storage/perfschema/pfs_events.h12
-rw-r--r--storage/perfschema/pfs_events_waits.h34
24 files changed, 154 insertions, 261 deletions
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 487c0038239..9d7f7e66b28 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -1671,7 +1671,6 @@ void ha_archive::update_create_info(HA_CREATE_INFO *create_info)
DBUG_VOID_RETURN;
}
-
/*
Hints for optimizer, see ha_tina for more information
*/
@@ -1679,22 +1678,7 @@ int ha_archive::info(uint flag)
{
DBUG_ENTER("ha_archive::info");
- mysql_mutex_lock(&share->mutex);
- if (share->dirty)
- {
- DBUG_PRINT("ha_archive", ("archive flushing out rows for scan"));
- DBUG_ASSERT(share->archive_write_open);
- azflush(&(share->archive_write), Z_SYNC_FLUSH);
- share->dirty= FALSE;
- }
-
- /*
- This should be an accurate number now, though bulk and delayed inserts can
- cause the number to be inaccurate.
- */
- stats.records= share->rows_recorded;
- mysql_mutex_unlock(&share->mutex);
-
+ flush_and_clear_pending_writes();
stats.deleted= 0;
DBUG_PRINT("ha_archive", ("Stats rows is %d\n", (int)stats.records));
@@ -1737,6 +1721,38 @@ int ha_archive::info(uint flag)
}
+int ha_archive::external_lock(THD *thd, int lock_type)
+{
+ if (lock_type == F_RDLCK)
+ {
+ // We are going to read from the table. Flush any pending writes that we
+ // may have
+ flush_and_clear_pending_writes();
+ }
+ return 0;
+}
+
+
+void ha_archive::flush_and_clear_pending_writes()
+{
+ mysql_mutex_lock(&share->mutex);
+ if (share->dirty)
+ {
+ DBUG_PRINT("ha_archive", ("archive flushing out rows for scan"));
+ DBUG_ASSERT(share->archive_write_open);
+ azflush(&(share->archive_write), Z_SYNC_FLUSH);
+ share->dirty= FALSE;
+ }
+
+ /*
+ This should be an accurate number now, though bulk and delayed inserts can
+ cause the number to be inaccurate.
+ */
+ stats.records= share->rows_recorded;
+ mysql_mutex_unlock(&share->mutex);
+}
+
+
/*
This method tells us that a bulk insert operation is about to occur. We set
a flag which will keep write_row from saying that its data is dirty. This in
diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h
index 56ff566db8c..a74374a340f 100644
--- a/storage/archive/ha_archive.h
+++ b/storage/archive/ha_archive.h
@@ -169,5 +169,8 @@ public:
int unpack_row(azio_stream *file_to_read, uchar *record);
unsigned int pack_row(uchar *record, azio_stream *writer);
bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
+ int external_lock(THD *thd, int lock_type);
+private:
+ void flush_and_clear_pending_writes();
};
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index d5d1dcea152..579eb62d82c 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -3897,10 +3897,6 @@ got_block:
}
}
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(ibuf_count_get(page_id) == 0);
-#endif /* UNIV_IBUF_COUNT_DEBUG */
-
return(bpage);
}
@@ -4682,15 +4678,9 @@ evict_from_pool:
}
}
- if (!recv_no_ibuf_operations) {
- if (access_time) {
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(ibuf_count_get(page_id) == 0);
-#endif /* UNIV_IBUF_COUNT_DEBUG */
- } else {
- ibuf_merge_or_delete_for_page(
- block, page_id, &page_size, TRUE);
- }
+ if (!access_time && !recv_no_ibuf_operations) {
+ ibuf_merge_or_delete_for_page(
+ block, page_id, &page_size, TRUE);
}
buf_pool_mutex_enter(buf_pool);
@@ -4892,10 +4882,6 @@ evict_from_pool:
buf_read_ahead_linear(page_id, page_size, ibuf_inside(mtr));
}
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(ibuf_count_get(fix_block->page.id) == 0);
-#endif
-
ut_ad(!rw_lock_own_flagged(hash_lock,
RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
@@ -5003,10 +4989,6 @@ buf_page_optimistic_get(
ibuf_inside(mtr));
}
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(ibuf_count_get(block->page.id) == 0);
-#endif /* UNIV_IBUF_COUNT_DEBUG */
-
buf_pool = buf_pool_from_block(block);
buf_pool->stat.n_page_gets++;
@@ -5110,9 +5092,6 @@ buf_page_get_known_nowait(
}
#endif /* UNIV_DEBUG */
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a((mode == BUF_KEEP_OLD) || ibuf_count_get(block->page.id) == 0);
-#endif
buf_pool->stat.n_page_gets++;
return(TRUE);
@@ -5197,10 +5176,6 @@ buf_page_try_get_func(
buf_pool->stat.n_page_gets++;
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(ibuf_count_get(block->page.id) == 0);
-#endif /* UNIV_IBUF_COUNT_DEBUG */
-
return(block);
}
@@ -5599,11 +5574,6 @@ buf_page_create(
if (block
&& buf_page_in_file(&block->page)
&& !buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
-
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(ibuf_count_get(page_id) == 0);
-#endif /* UNIV_IBUF_COUNT_DEBUG */
-
ut_d(block->page.file_page_was_freed = FALSE);
/* Page can be found in buf_pool */
@@ -5708,9 +5678,6 @@ buf_page_create(
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(++buf_dbg_counter % 5771 || buf_validate());
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(ibuf_count_get(block->page.id) == 0);
-#endif
return(block);
}
@@ -6158,14 +6125,6 @@ database_corrupted:
buf_pool_mutex_enter(buf_pool);
mutex_enter(block_mutex);
-#ifdef UNIV_IBUF_COUNT_DEBUG
- if (io_type == BUF_IO_WRITE || uncompressed) {
- /* For BUF_IO_READ of compressed-only blocks, the
- buffered operations will be merged by buf_page_get_gen()
- after the block has been uncompressed. */
- ut_a(ibuf_count_get(bpage->id) == 0);
- }
-#endif
/* Because this thread which does the unlocking is not the same that
did the locking, we use a pass value != 0 in unlock, which simply
removes the newest lock debug record, without checking the thread
@@ -6394,11 +6353,6 @@ buf_pool_validate_instance(
buf_pool, block->page.id)
== &block->page);
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(buf_page_get_io_fix(&block->page)
- == BUF_IO_READ
- || !ibuf_count_get(block->page.id));
-#endif
switch (buf_page_get_io_fix(&block->page)) {
case BUF_IO_NONE:
break;
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index b1c84e1d74a..fd9d4713a9c 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation.
+Copyright (c) 2013, 2019, MariaDB Corporation.
Copyright (c) 2013, 2014, Fusion-io
This program is free software; you can redistribute it and/or modify it under
@@ -1043,11 +1043,6 @@ buf_flush_write_block_low(
ut_ad(!buf_page_get_mutex(bpage)->is_owned());
ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE);
ut_ad(bpage->oldest_modification != 0);
-
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(ibuf_count_get(bpage->id) == 0);
-#endif /* UNIV_IBUF_COUNT_DEBUG */
-
ut_ad(bpage->newest_modification != 0);
/* Force the log to the disk before writing the modified block */
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 859d5ece06a..9b4a0809f25 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1595,10 +1595,6 @@ buf_LRU_free_page(
goto func_exit;
}
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(ibuf_count_get(bpage->id) == 0);
-#endif /* UNIV_IBUF_COUNT_DEBUG */
-
if (zip || !bpage->zip.data) {
/* This would completely free the block. */
/* Do not completely free dirty blocks. */
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 2bf22778f70..e67f860f3e2 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -4355,11 +4355,19 @@ dict_create_foreign_constraints_low(
}
orig = ptr;
- ptr = dict_accept(cs, ptr, "TABLE", &success);
-
- if (!success) {
-
- goto loop;
+ for (;;) {
+ ptr = dict_accept(cs, ptr, "TABLE", &success);
+ if (success) {
+ break;
+ }
+ ptr = dict_accept(cs, ptr, "ONLINE", &success);
+ if (success) {
+ continue;
+ }
+ ptr = dict_accept(cs, ptr, "IGNORE", &success);
+ if (!success) {
+ goto loop;
+ }
}
/* We are doing an ALTER TABLE: scan the table name we are altering */
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index e8d089ee41b..86deae0c015 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -192,35 +192,6 @@ uint ibuf_debug;
/** The insert buffer control structure */
ibuf_t* ibuf = NULL;
-#ifdef UNIV_IBUF_COUNT_DEBUG
-/** Number of tablespaces in the ibuf_counts array */
-#define IBUF_COUNT_N_SPACES 4
-/** Number of pages within each tablespace in the ibuf_counts array */
-#define IBUF_COUNT_N_PAGES 130000
-
-/** Buffered entry counts for file pages, used in debugging */
-static ulint ibuf_counts[IBUF_COUNT_N_SPACES][IBUF_COUNT_N_PAGES];
-
-/** Checks that the indexes to ibuf_counts[][] are within limits.
-@param[in] page_id page id */
-UNIV_INLINE
-void
-ibuf_count_check(
- const page_id_t page_id)
-{
- if (page_id.space() < IBUF_COUNT_N_SPACES
- && page_id.page_no() < IBUF_COUNT_N_PAGES) {
- return;
- }
-
- ib::fatal() << "UNIV_IBUF_COUNT_DEBUG limits space_id and page_no"
- " and breaks crash recovery. space_id=" << page_id.space()
- << ", should be 0<=space_id<" << IBUF_COUNT_N_SPACES
- << ". page_no=" << page_id.page_no()
- << ", should be 0<=page_no<" << IBUF_COUNT_N_PAGES;
-}
-#endif
-
/** @name Offsets to the per-page bits in the insert buffer bitmap */
/* @{ */
#define IBUF_BITMAP_FREE 0 /*!< Bits indicating the
@@ -408,35 +379,6 @@ ibuf_tree_root_get(
return(root);
}
-#ifdef UNIV_IBUF_COUNT_DEBUG
-
-/** Gets the ibuf count for a given page.
-@param[in] page_id page id
-@return number of entries in the insert buffer currently buffered for
-this page */
-ulint ibuf_count_get(const page_id_t page_id)
-{
- ibuf_count_check(page_id);
-
- return(ibuf_counts[page_id.space()][page_id.page_no()]);
-}
-
-/** Sets the ibuf count for a given page.
-@param[in] page_id page id
-@param[in] val value to set */
-static
-void
-ibuf_count_set(
- const page_id_t page_id,
- ulint val)
-{
- ibuf_count_check(page_id);
- ut_a(val < srv_page_size);
-
- ibuf_counts[page_id.space()][page_id.page_no()] = val;
-}
-#endif
-
/******************************************************************//**
Closes insert buffer and frees the data structures. */
void
@@ -733,10 +675,6 @@ ibuf_bitmap_page_set_bits(
compile_time_assert(!(IBUF_BITS_PER_PAGE % 2));
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
ut_ad(mtr->is_named_space(page_id.space()));
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a((bit != IBUF_BITMAP_BUFFERED) || (val != FALSE)
- || (0 == ibuf_count_get(page_id)));
-#endif
bit_offset = (page_id.page_no() % page_size.physical())
* IBUF_BITS_PER_PAGE + bit;
@@ -3492,9 +3430,6 @@ fail_exit:
which it cannot do until we have buffered the IBUF_OP_DELETE
and done mtr_commit(&mtr) to release the latch. */
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a((buffered == 0) || ibuf_count_get(page_id));
-#endif
ibuf_mtr_start(&bitmap_mtr);
index->set_modified(bitmap_mtr);
@@ -3637,17 +3572,6 @@ fail_exit:
}
func_exit:
-#ifdef UNIV_IBUF_COUNT_DEBUG
- if (err == DB_SUCCESS) {
-
- ib::info() << "Incrementing ibuf count of page " << page_id
- << " from " << ibuf_count_get(space, page_no)
- << " by 1";
-
- ibuf_count_set(page_id, ibuf_count_get(page_id) + 1);
- }
-#endif
-
ibuf_mtr_commit(&mtr);
btr_pcur_close(&pcur);
@@ -4339,14 +4263,6 @@ ibuf_delete_rec(
ibuf->empty = true;
}
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ib::info() << "Decrementing ibuf count of space " << space
- << " page " << page_no << " from "
- << ibuf_count_get(page_id) << " by 1";
-
- ibuf_count_set(page_id, ibuf_count_get(page_id) - 1);
-#endif /* UNIV_IBUF_COUNT_DEBUG */
-
return(FALSE);
}
@@ -4382,10 +4298,6 @@ ibuf_delete_rec(
false, mtr);
ut_a(err == DB_SUCCESS);
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ibuf_count_set(page_id, ibuf_count_get(page_id) - 1);
-#endif /* UNIV_IBUF_COUNT_DEBUG */
-
ibuf_size_update(root);
mutex_exit(&ibuf_mutex);
@@ -4768,10 +4680,6 @@ reset_bit:
my_atomic_addlint(&ibuf->n_merges, 1);
ibuf_add_ops(ibuf->n_merged_ops, mops);
ibuf_add_ops(ibuf->n_discarded_ops, dops);
-
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ut_a(ibuf_count_get(page_id) == 0);
-#endif
}
/*********************************************************************//**
@@ -4889,11 +4797,6 @@ ibuf_print(
/*=======*/
FILE* file) /*!< in: file where to print */
{
-#ifdef UNIV_IBUF_COUNT_DEBUG
- ulint i;
- ulint j;
-#endif
-
mutex_enter(&ibuf_mutex);
fprintf(file,
@@ -4910,22 +4813,6 @@ ibuf_print(
fputs("discarded operations:\n ", file);
ibuf_print_ops(ibuf->n_discarded_ops, file);
-#ifdef UNIV_IBUF_COUNT_DEBUG
- for (i = 0; i < IBUF_COUNT_N_SPACES; i++) {
- for (j = 0; j < IBUF_COUNT_N_PAGES; j++) {
- ulint count = ibuf_count_get(page_id_t(i, j, 0));
-
- if (count > 0) {
- fprintf(stderr,
- "Ibuf count for page "
- ULINTPF ":" ULINTPF ""
- " is " ULINTPF "\n",
- i, j, count);
- }
- }
- }
-#endif /* UNIV_IBUF_COUNT_DEBUG */
-
mutex_exit(&ibuf_mutex);
}
diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h
index 72b9e291fca..1f5e8bfe4b2 100644
--- a/storage/innobase/include/ibuf0ibuf.h
+++ b/storage/innobase/include/ibuf0ibuf.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2018, MariaDB Corporation.
+Copyright (c) 2016, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -381,13 +381,6 @@ ibuf_parse_bitmap_init(
buf_block_t* block, /*!< in: block or NULL */
mtr_t* mtr); /*!< in: mtr or NULL */
-#ifdef UNIV_IBUF_COUNT_DEBUG
-/** Gets the ibuf count for a given page.
-@param[in] page_id page id
-@return number of entries in the insert buffer currently buffered for
-this page */
-ulint ibuf_count_get(const page_id_t page_id);
-#endif
/******************************************************************//**
Looks if the insert buffer is empty.
@return true if empty */
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index 8c5be47fb85..043429b7f56 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -431,6 +431,7 @@ class rw_trx_hash_t
if (trx_t *trx= element->trx)
{
ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED) ||
+ trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED) ||
(trx_state_eq(trx, TRX_STATE_ACTIVE) &&
(!srv_was_started ||
srv_read_only_mode ||
@@ -515,6 +516,7 @@ class rw_trx_hash_t
ut_ad(!trx_is_autocommit_non_locking(trx));
mutex_enter(&trx->mutex);
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) ||
+ trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED) ||
trx_state_eq(trx, TRX_STATE_PREPARED));
mutex_exit(&trx->mutex);
}
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 653f9ad0d8f..b2594b46895 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -447,7 +447,7 @@ Check transaction state */
ut_ad(!trx_is_autocommit_non_locking((t))); \
switch ((t)->state) { \
case TRX_STATE_PREPARED: \
- /* fall through */ \
+ case TRX_STATE_PREPARED_RECOVERED: \
case TRX_STATE_ACTIVE: \
case TRX_STATE_COMMITTED_IN_MEMORY: \
continue; \
@@ -785,6 +785,7 @@ public:
TRX_STATE_NOT_STARTED
TRX_STATE_ACTIVE
TRX_STATE_PREPARED
+ TRX_STATE_PREPARED_RECOVERED (special case of TRX_STATE_PREPARED)
TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED)
Valid state transitions are:
diff --git a/storage/innobase/include/trx0trx.ic b/storage/innobase/include/trx0trx.ic
index 6589aca4e77..6cf4e51fa20 100644
--- a/storage/innobase/include/trx0trx.ic
+++ b/storage/innobase/include/trx0trx.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2018, MariaDB Corporation.
+Copyright (c) 2016, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -47,7 +47,7 @@ trx_state_eq(
#ifdef UNIV_DEBUG
switch (trx->state) {
case TRX_STATE_PREPARED:
-
+ case TRX_STATE_PREPARED_RECOVERED:
ut_ad(!trx_is_autocommit_non_locking(trx));
return(trx->state == state);
diff --git a/storage/innobase/include/trx0types.h b/storage/innobase/include/trx0types.h
index 252d93796ee..e6b1851f330 100644
--- a/storage/innobase/include/trx0types.h
+++ b/storage/innobase/include/trx0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -62,10 +62,11 @@ enum trx_state_t {
TRX_STATE_NOT_STARTED,
TRX_STATE_ACTIVE,
-
- /** Support for 2PC/XA */
+ /** XA PREPARE has been executed; only XA COMMIT or XA ROLLBACK
+ are possible */
TRX_STATE_PREPARED,
-
+ /** XA PREPARE transaction that was returned to ha_recover() */
+ TRX_STATE_PREPARED_RECOVERED,
TRX_STATE_COMMITTED_IN_MEMORY
};
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 549394c80de..b66c4a96c9b 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation.
+Copyright (c) 2013, 2019, MariaDB Corporation.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -205,9 +205,6 @@ using the call command. */
this will break redo log file compatibility, but it may be useful when
debugging redo log application problems. */
#define UNIV_IBUF_DEBUG /* debug the insert buffer */
-#define UNIV_IBUF_COUNT_DEBUG /* debug the insert buffer;
-this limits the database to IBUF_COUNT_N_SPACES and IBUF_COUNT_N_PAGES,
-and the insert buffer must be empty when the database is started */
#define UNIV_PERF_DEBUG /* debug flag that enables
light weight performance
related stuff. */
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 8414ed82e34..7ef468fae39 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -6307,6 +6307,7 @@ lock_trx_release_locks(
{
check_trx_state(trx);
ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED)
+ || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)
|| trx_state_eq(trx, TRX_STATE_ACTIVE));
bool release_lock = UT_LIST_GET_LEN(trx->lock.trx_locks) > 0;
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index 9b88f950917..7fe59807521 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -130,6 +130,7 @@ row_undo_node_create(
undo_node_t* undo;
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)
+ || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)
|| trx_state_eq(trx, TRX_STATE_PREPARED));
ut_ad(parent);
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index a60170de48e..830255e89f0 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1400,10 +1400,6 @@ dberr_t srv_start(bool create_new_db)
#ifdef UNIV_IBUF_DEBUG
ib::info() << "!!!!!!!! UNIV_IBUF_DEBUG switched on !!!!!!!!!";
-# ifdef UNIV_IBUF_COUNT_DEBUG
- ib::info() << "!!!!!!!! UNIV_IBUF_COUNT_DEBUG switched on !!!!!!!!!";
- ib::error() << "Crash recovery will fail with UNIV_IBUF_COUNT_DEBUG";
-# endif
#endif
#ifdef UNIV_LOG_LSN_DEBUG
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index 9e992d2f145..2bff7495c1b 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2018, MariaDB Corporation.
+Copyright (c) 2016, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -236,6 +236,7 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
return(trx_rollback_for_mysql_low(trx));
case TRX_STATE_PREPARED:
+ case TRX_STATE_PREPARED_RECOVERED:
ut_ad(!trx_is_autocommit_non_locking(trx));
if (trx->rsegs.m_redo.undo || trx->rsegs.m_redo.old_insert) {
/* Change the undo log state back from
@@ -335,6 +336,7 @@ trx_rollback_last_sql_stat_for_mysql(
return(err);
case TRX_STATE_PREPARED:
+ case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY:
/* The statement rollback is only allowed on an ACTIVE
transaction, not a PREPARED or COMMITTED one. */
@@ -508,6 +510,7 @@ trx_rollback_to_savepoint_for_mysql(
trx, savep, mysql_binlog_cache_pos));
case TRX_STATE_PREPARED:
+ case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY:
/* The savepoint rollback is only allowed on an ACTIVE
transaction, not a PREPARED or COMMITTED one. */
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index cdb5d4a1ee3..0d75b72a149 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -466,6 +466,7 @@ trx_free_at_shutdown(trx_t *trx)
{
ut_ad(trx->is_recovered);
ut_a(trx_state_eq(trx, TRX_STATE_PREPARED)
+ || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)
|| (trx_state_eq(trx, TRX_STATE_ACTIVE)
&& (!srv_was_started
|| srv_operation == SRV_OPERATION_RESTORE
@@ -1551,7 +1552,7 @@ trx_commit_or_rollback_prepare(
case TRX_STATE_ACTIVE:
case TRX_STATE_PREPARED:
-
+ case TRX_STATE_PREPARED_RECOVERED:
/* If the trx is in a lock wait state, moves the waiting
query thread to the suspended state */
@@ -1662,7 +1663,7 @@ trx_commit_for_mysql(
/* fall through */
case TRX_STATE_ACTIVE:
case TRX_STATE_PREPARED:
-
+ case TRX_STATE_PREPARED_RECOVERED:
trx->op_info = "committing";
trx_commit(trx);
@@ -1708,6 +1709,7 @@ trx_mark_sql_stat_end(
switch (trx->state) {
case TRX_STATE_PREPARED:
+ case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY:
break;
case TRX_STATE_NOT_STARTED:
@@ -1762,6 +1764,7 @@ trx_print_low(
(ulong) difftime(time(NULL), trx->start_time));
goto state_ok;
case TRX_STATE_PREPARED:
+ case TRX_STATE_PREPARED_RECOVERED:
fprintf(f, ", ACTIVE (PREPARED) %lu sec",
(ulong) difftime(time(NULL), trx->start_time));
goto state_ok;
@@ -2041,6 +2044,7 @@ struct trx_recover_for_mysql_callback_arg
static my_bool trx_recover_for_mysql_callback(rw_trx_hash_element_t *element,
trx_recover_for_mysql_callback_arg *arg)
{
+ DBUG_ASSERT(arg->len > 0);
mutex_enter(&element->mutex);
if (trx_t *trx= element->trx)
{
@@ -2052,17 +2056,38 @@ static my_bool trx_recover_for_mysql_callback(rw_trx_hash_element_t *element,
if (trx_state_eq(trx, TRX_STATE_PREPARED))
{
ut_ad(trx->is_recovered);
+ ut_ad(trx->id);
if (arg->count == 0)
ib::info() << "Starting recovery for XA transactions...";
- ib::info() << "Transaction " << trx_get_id_for_print(trx)
- << " in prepared state after recovery";
- ib::info() << "Transaction contains changes to " << trx->undo_no
- << " rows";
- arg->xid_list[arg->count++]= *trx->xid;
+ XID& xid= arg->xid_list[arg->count];
+ if (arg->count++ < arg->len)
+ {
+ trx->state= TRX_STATE_PREPARED_RECOVERED;
+ ib::info() << "Transaction " << trx->id
+ << " in prepared state after recovery";
+ ib::info() << "Transaction contains changes to " << trx->undo_no
+ << " rows";
+ xid= *trx->xid;
+ }
}
}
mutex_exit(&element->mutex);
- return arg->count == arg->len;
+ /* Do not terminate upon reaching arg->len; count all transactions */
+ return false;
+}
+
+
+static my_bool trx_recover_reset_callback(rw_trx_hash_element_t *element,
+ void*)
+{
+ mutex_enter(&element->mutex);
+ if (trx_t *trx= element->trx)
+ {
+ if (trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED))
+ trx->state= TRX_STATE_PREPARED;
+ }
+ mutex_exit(&element->mutex);
+ return false;
}
@@ -2086,9 +2111,18 @@ int trx_recover_for_mysql(XID *xid_list, uint len)
trx_sys.rw_trx_hash.iterate_no_dups(reinterpret_cast<my_hash_walk_action>
(trx_recover_for_mysql_callback), &arg);
if (arg.count)
+ {
ib::info() << arg.count
- << " transactions in prepared state after recovery";
- return int(arg.count);
+ << " transactions in prepared state after recovery";
+ /* After returning the full list, reset the state, because
+ init_server_components() wants to recover the collection of
+ transactions twice, by first calling tc_log->open() and then
+ ha_recover() directly. */
+ if (arg.count <= len)
+ trx_sys.rw_trx_hash.iterate(reinterpret_cast<my_hash_walk_action>
+ (trx_recover_reset_callback), NULL);
+ }
+ return int(std::min(arg.count, len));
}
@@ -2106,7 +2140,9 @@ static my_bool trx_get_trx_by_xid_callback(rw_trx_hash_element_t *element,
mutex_enter(&element->mutex);
if (trx_t *trx= element->trx)
{
- if (trx->is_recovered && trx_state_eq(trx, TRX_STATE_PREPARED) &&
+ if (trx->is_recovered &&
+ (trx_state_eq(trx, TRX_STATE_PREPARED) ||
+ trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) &&
arg->xid->eq(reinterpret_cast<XID*>(trx->xid)))
{
#ifdef WITH_WSREP
@@ -2172,6 +2208,7 @@ trx_start_if_not_started_xa_low(
}
return;
case TRX_STATE_PREPARED:
+ case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY:
break;
}
@@ -2199,6 +2236,7 @@ trx_start_if_not_started_low(
return;
case TRX_STATE_PREPARED:
+ case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY:
break;
}
@@ -2265,6 +2303,7 @@ trx_start_for_ddl_low(
case TRX_STATE_ACTIVE:
case TRX_STATE_PREPARED:
+ case TRX_STATE_PREPARED_RECOVERED:
case TRX_STATE_COMMITTED_IN_MEMORY:
break;
}
diff --git a/storage/maria/ma_test3.c b/storage/maria/ma_test3.c
index f81d5363c6b..604c2b676a4 100644
--- a/storage/maria/ma_test3.c
+++ b/storage/maria/ma_test3.c
@@ -362,7 +362,7 @@ int test_write(MARIA_HA *file,int id,int lock_type)
maria_extra(file,HA_EXTRA_WRITE_CACHE,0);
}
- sprintf((char*) record.id,"%7ld", (long) getpid());
+ my_snprintf((char*) record.id, sizeof(record.id), "%7ld", (long) getpid());
strnmov((char*) record.text,"Testing...", sizeof(record.text));
tries=(uint) rnd(100)+10;
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index ae3b95db6ec..43798fe8c07 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -1731,8 +1731,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
null_bit[0]=null_pos[0]=0;
if (keyseg->null_bit)
{
- sprintf(null_bit,"%d",keyseg->null_bit);
- sprintf(null_pos,"%ld",(long) keyseg->null_pos+1);
+ my_snprintf(null_bit, sizeof(null_bit), "%d", keyseg->null_bit);
+ my_snprintf(null_pos, sizeof(null_pos), "%ld", (long) keyseg->null_pos+1);
}
printf("%-7ld%-5d%-9s%-10s%-30s\n",
(long) keyseg->start+1,keyseg->length,
diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c
index 6922655450b..52df065eae5 100644
--- a/storage/myisam/mi_test3.c
+++ b/storage/myisam/mi_test3.c
@@ -365,7 +365,7 @@ int test_write(MI_INFO *file,int id,int lock_type)
mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
}
- sprintf((char*) record.id,"%7ld",(long) getpid());
+ my_snprintf((char*) record.id, sizeof(record.id), "%7ld", (long) getpid());
strnmov((char*) record.text,"Testing...", sizeof(record.text));
tries=(uint) rnd(100)+10;
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index ad8de98280c..abb5a99d423 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -1405,8 +1405,8 @@ static void descript(HA_CHECK *param, register MI_INFO *info, char * name)
null_bit[0]=null_pos[0]=0;
if (keyseg->null_bit)
{
- sprintf(null_bit,"%d",keyseg->null_bit);
- sprintf(null_pos,"%ld",(long) keyseg->null_pos+1);
+ my_snprintf(null_bit, sizeof(null_bit), "%d", keyseg->null_bit);
+ my_snprintf(null_pos, sizeof(null_pos), "%ld", (long) keyseg->null_pos+1);
}
printf("%-7ld%-5d%-9s%-10s%-30s\n",
(long) keyseg->start+1,keyseg->length,
diff --git a/storage/perfschema/pfs_events.h b/storage/perfschema/pfs_events.h
index 97fb7e08d63..905d6f8590f 100644
--- a/storage/perfschema/pfs_events.h
+++ b/storage/perfschema/pfs_events.h
@@ -34,14 +34,8 @@ struct PFS_events
ulonglong m_event_id;
/** END_EVENT_ID. */
ulonglong m_end_event_id;
- /** (EVENT_TYPE) */
- enum_event_type m_event_type;
/** NESTING_EVENT_ID. */
ulonglong m_nesting_event_id;
- /** NESTING_EVENT_TYPE */
- enum_event_type m_nesting_event_type;
- /** Instrument metadata. */
- PFS_instr_class *m_class;
/**
Timer start.
This member is populated only if m_class->m_timed is true.
@@ -52,8 +46,14 @@ struct PFS_events
This member is populated only if m_class->m_timed is true.
*/
ulonglong m_timer_end;
+ /** Instrument metadata. */
+ PFS_instr_class *m_class;
/** Location of the instrumentation in the source code (file name). */
const char *m_source_file;
+ /** (EVENT_TYPE) */
+ enum_event_type m_event_type;
+ /** NESTING_EVENT_TYPE */
+ enum_event_type m_nesting_event_type;
/** Location of the instrumentation in the source code (line number). */
uint m_source_line;
};
diff --git a/storage/perfschema/pfs_events_waits.h b/storage/perfschema/pfs_events_waits.h
index 6a50134ad44..0d4e4c37cae 100644
--- a/storage/perfschema/pfs_events_waits.h
+++ b/storage/perfschema/pfs_events_waits.h
@@ -55,6 +55,23 @@ enum events_waits_class
/** A wait event record. */
struct PFS_events_waits : public PFS_events
{
+ /** Executing thread. */
+ PFS_thread *m_thread;
+ /** Table share, for table operations only. */
+ PFS_table_share *m_weak_table_share;
+ /** File, for file operations only. */
+ PFS_file *m_weak_file;
+ /** Address in memory of the object instance waited on. */
+ const void *m_object_instance_addr;
+ /** Socket, for socket operations only. */
+ PFS_socket *m_weak_socket;
+ /**
+ Number of bytes read/written.
+ This member is populated for file READ/WRITE operations only.
+ */
+ size_t m_number_of_bytes;
+ /** Flags */
+ ulong m_flags;
/**
The type of wait.
Readers:
@@ -67,34 +84,17 @@ struct PFS_events_waits : public PFS_events
- TRUNCATE EVENTS_WAITS_HISTORY_LONG
*/
events_waits_class m_wait_class;
- /** Executing thread. */
- PFS_thread *m_thread;
/** Object type */
enum_object_type m_object_type;
- /** Table share, for table operations only. */
- PFS_table_share *m_weak_table_share;
- /** File, for file operations only. */
- PFS_file *m_weak_file;
- /** Socket, for socket operations only. */
- PFS_socket *m_weak_socket;
/** For weak pointers, target object version. */
uint32 m_weak_version;
- /** Address in memory of the object instance waited on. */
- const void *m_object_instance_addr;
/** Operation performed. */
enum_operation_type m_operation;
/**
- Number of bytes read/written.
- This member is populated for file READ/WRITE operations only.
- */
- size_t m_number_of_bytes;
- /**
Index used.
This member is populated for TABLE IO operations only.
*/
uint m_index;
- /** Flags */
- ulong m_flags;
};
/** TIMED bit in the state flags bitfield. */