summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2017-05-15 17:17:16 +0300
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2017-05-15 17:17:16 +0300
commit0af9818240a0745aca3fd94891664fe008de24fe (patch)
tree2074689c7de4be94ae94b13ab2d5b5831882d902 /storage/innobase
parent6ac84d9824ec384c4489b68b8087369aef147ff9 (diff)
downloadmariadb-git-0af9818240a0745aca3fd94891664fe008de24fe.tar.gz
5.6.36
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/btr/btr0sea.cc2
-rw-r--r--storage/innobase/buf/buf0buf.cc2
-rw-r--r--storage/innobase/buf/buf0dblwr.cc4
-rw-r--r--storage/innobase/buf/buf0dump.cc4
-rw-r--r--storage/innobase/buf/buf0flu.cc4
-rw-r--r--storage/innobase/dict/dict0boot.cc7
-rw-r--r--storage/innobase/dict/dict0stats.cc15
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc4
-rw-r--r--storage/innobase/fil/fil0fil.cc20
-rw-r--r--storage/innobase/handler/ha_innodb.cc7
-rw-r--r--storage/innobase/include/buf0dblwr.h4
-rw-r--r--storage/innobase/include/fil0fil.h14
-rw-r--r--storage/innobase/include/ha0ha.h6
-rw-r--r--storage/innobase/include/os0file.h134
-rw-r--r--storage/innobase/include/os0file.ic130
-rw-r--r--storage/innobase/include/row0mysql.h8
-rw-r--r--storage/innobase/include/srv0srv.h9
-rw-r--r--storage/innobase/include/srv0start.h4
-rw-r--r--storage/innobase/include/trx0xa.h15
-rw-r--r--storage/innobase/include/univ.i10
-rw-r--r--storage/innobase/log/log0log.cc9
-rw-r--r--storage/innobase/log/log0recv.cc4
-rw-r--r--storage/innobase/os/os0file.cc128
-rw-r--r--storage/innobase/row/row0log.cc17
-rw-r--r--storage/innobase/row/row0merge.cc35
-rw-r--r--storage/innobase/row/row0sel.cc235
-rw-r--r--storage/innobase/srv/srv0srv.cc26
-rw-r--r--storage/innobase/srv/srv0start.cc66
-rw-r--r--storage/innobase/trx/trx0purge.cc5
-rw-r--r--storage/innobase/trx/trx0roll.cc4
-rw-r--r--storage/innobase/trx/trx0sys.cc18
31 files changed, 658 insertions, 292 deletions
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index dd28f50f4f6..01f03b2eaf7 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -175,7 +175,7 @@ btr_search_sys_create(
btr_search_sys = (btr_search_sys_t*)
mem_alloc(sizeof(btr_search_sys_t));
- btr_search_sys->hash_index = ha_create(hash_size, 0,
+ btr_search_sys->hash_index = ib_create(hash_size, 0,
MEM_HEAP_FOR_BTR_SEARCH, 0);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
btr_search_sys->hash_index->adaptive = TRUE;
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 6f206918212..fa73e80b358 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -1366,7 +1366,7 @@ buf_pool_init_instance(
ut_a(srv_n_page_hash_locks != 0);
ut_a(srv_n_page_hash_locks <= MAX_PAGE_HASH_LOCKS);
- buf_pool->page_hash = ha_create(2 * buf_pool->curr_size,
+ buf_pool->page_hash = ib_create(2 * buf_pool->curr_size,
srv_n_page_hash_locks,
MEM_HEAP_FOR_PAGE_HASH,
SYNC_BUF_PAGE_HASH);
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index 62222993622..a752c3dfda5 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -355,7 +355,7 @@ recovery, this function loads the pages from double write buffer into memory. */
void
buf_dblwr_init_or_load_pages(
/*=========================*/
- os_file_t file,
+ pfs_os_file_t file,
char* path,
bool load_corrupt_pages)
{
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index ed27a70307d..6c830205e2b 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -597,6 +597,7 @@ DECLARE_THREAD(buf_dump_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */
{
+ my_thread_init();
ut_ad(!srv_read_only_mode);
srv_buf_dump_thread_active = TRUE;
@@ -632,6 +633,7 @@ DECLARE_THREAD(buf_dump_thread)(
srv_buf_dump_thread_active = FALSE;
+ my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 1cdd1610c4f..6550f916805 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -2388,6 +2388,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
/*!< in: a dummy parameter required by
os_thread_create */
{
+ my_thread_init();
ulint next_loop_time = ut_time_ms() + 1000;
ulint n_flushed = 0;
ulint last_activity = srv_get_activity_count();
@@ -2506,6 +2507,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
thread_exit:
buf_page_cleaner_is_active = FALSE;
+ my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
diff --git a/storage/innobase/dict/dict0boot.cc b/storage/innobase/dict/dict0boot.cc
index 1a1dd29a202..7873da30207 100644
--- a/storage/innobase/dict/dict0boot.cc
+++ b/storage/innobase/dict/dict0boot.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -454,7 +454,10 @@ dict_boot(void)
dberr_t err = DB_SUCCESS;
- if (srv_read_only_mode && !ibuf_is_empty()) {
+ /** If innodb_force_recovery is set to 6 then allow
+ the server to start even though ibuf is not empty. */
+ if (srv_force_recovery != SRV_FORCE_NO_LOG_REDO
+ && srv_read_only_mode && !ibuf_is_empty()) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Change buffer must be empty when --innodb-read-only "
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index b0ba98308be..55a26268579 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2009, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2009, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -690,6 +690,9 @@ dict_stats_copy(
&& (src_idx = dict_table_get_next_index(src_idx)))) {
if (dict_stats_should_ignore_index(dst_idx)) {
+ if (!(dst_idx->type & DICT_FTS)) {
+ dict_stats_empty_index(dst_idx);
+ }
continue;
}
@@ -1096,10 +1099,10 @@ dict_stats_analyze_index_level(
leaf-level delete marks because delete marks on
non-leaf level do not make sense. */
- if (level == 0 && srv_stats_include_delete_marked? 0:
+ if (level == 0 && (srv_stats_include_delete_marked ? 0:
rec_get_deleted_flag(
rec,
- page_is_comp(btr_pcur_get_page(&pcur)))) {
+ page_is_comp(btr_pcur_get_page(&pcur))))) {
if (rec_is_last_on_page
&& !prev_rec_is_copied
@@ -3229,12 +3232,6 @@ dict_stats_update(
dict_table_stats_lock(table, RW_X_LATCH);
- /* Initialize all stats to dummy values before
- copying because dict_stats_table_clone_create() does
- skip corrupted indexes so our dummy object 't' may
- have less indexes than the real object 'table'. */
- dict_stats_empty_table(table);
-
dict_stats_copy(table, t);
dict_stats_assert_initialized(table);
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index 6f01c379776..975c8a50803 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -334,6 +334,7 @@ DECLARE_THREAD(dict_stats_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */
{
+ my_thread_init();
ut_a(!srv_read_only_mode);
srv_dict_stats_thread_active = TRUE;
@@ -359,6 +360,7 @@ DECLARE_THREAD(dict_stats_thread)(
srv_dict_stats_thread_active = FALSE;
+ my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit instead of return(). */
os_thread_exit(NULL);
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 5e1a9d6c05e..20c6cc6201e 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -146,7 +146,7 @@ struct fil_node_t {
belongs */
char* name; /*!< path to the file */
ibool open; /*!< TRUE if file open */
- os_file_t handle; /*!< OS handle to the file, if file open */
+ pfs_os_file_t handle; /*!< OS handle to the file, if file open */
os_event_t sync_event;/*!< Condition event to group and
serialize calls to fsync */
ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw
@@ -316,7 +316,8 @@ initialized. */
static fil_system_t* fil_system = NULL;
/** Determine if (i) is a user tablespace id or not. */
-# define fil_is_user_tablespace_id(i) ((i) > srv_undo_tablespaces_open)
+# define fil_is_user_tablespace_id(i) (i != 0 \
+ && !srv_is_undo_tablespace(i))
/** Determine if user has explicitly disabled fsync(). */
#ifndef __WIN__
@@ -2025,7 +2026,7 @@ UNIV_INTERN
const char*
fil_read_first_page(
/*================*/
- os_file_t data_file, /*!< in: open data file */
+ pfs_os_file_t data_file, /*!< in: open data file */
ibool one_read_already, /*!< in: TRUE if min and max
parameters below already
contain sensible data */
@@ -3360,7 +3361,7 @@ fil_open_linked_file(
/*===============*/
const char* tablename, /*!< in: database/tablename */
char** remote_filepath,/*!< out: remote filepath */
- os_file_t* remote_file) /*!< out: remote file handle */
+ pfs_os_file_t* remote_file) /*!< out: remote file handle */
{
ibool success;
@@ -3420,7 +3421,8 @@ fil_create_new_single_table_tablespace(
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
{
- os_file_t file;
+ pfs_os_file_t file;
+
ibool ret;
dberr_t err;
byte* buf2;
@@ -5862,7 +5864,7 @@ fil_flush(
{
fil_space_t* space;
fil_node_t* node;
- os_file_t file;
+ pfs_os_file_t file;
mutex_enter(&fil_system->mutex);
@@ -6224,7 +6226,7 @@ fil_buf_block_init(
}
struct fil_iterator_t {
- os_file_t file; /*!< File handle */
+ pfs_os_file_t file; /*!< File handle */
const char* filepath; /*!< File path name */
os_offset_t start; /*!< From where to start */
os_offset_t end; /*!< Where to stop */
@@ -6359,7 +6361,7 @@ fil_tablespace_iterate(
PageCallback& callback)
{
dberr_t err;
- os_file_t file;
+ pfs_os_file_t file;
char* filepath;
ut_a(n_io_buffers > 0);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 41c767a4bfc..7843c328bc8 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
@@ -5052,6 +5052,8 @@ table_opened:
prebuilt->default_rec = table->s->default_values;
ut_ad(prebuilt->default_rec);
+ prebuilt->mysql_handler = this;
+
/* Looks like MySQL-3.23 sometimes has primary key number != 0 */
primary_key = table->s->primary_key;
key_used_on_scan = primary_key;
@@ -10168,7 +10170,8 @@ ha_innobase::delete_table(
extension, in contrast to ::create */
normalize_table_name(norm_name, name);
- if (srv_read_only_mode) {
+ if (srv_read_only_mode
+ || srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) {
DBUG_RETURN(HA_ERR_TABLE_READONLY);
} else if (row_is_magic_monitor_table(norm_name)
&& check_global_access(thd, PROCESS_ACL)) {
diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h
index a62a6400d97..18e124b7437 100644
--- a/storage/innobase/include/buf0dblwr.h
+++ b/storage/innobase/include/buf0dblwr.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -55,7 +55,7 @@ recovery, this function loads the pages from double write buffer into memory. */
void
buf_dblwr_init_or_load_pages(
/*=========================*/
- os_file_t file,
+ pfs_os_file_t file,
char* path,
bool load_corrupt_pages);
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 4d2913846b5..5806863f926 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -181,7 +181,7 @@ struct fsp_open_info {
ibool success; /*!< Has the tablespace been opened? */
const char* check_msg; /*!< fil_check_first_page() message */
ibool valid; /*!< Is the tablespace valid? */
- os_file_t file; /*!< File handle */
+ pfs_os_file_t file; /*!< File handle */
char* filepath; /*!< File path to open */
lsn_t lsn; /*!< Flushed LSN from header page */
ulint id; /*!< Space ID */
@@ -384,7 +384,7 @@ UNIV_INTERN
const char*
fil_read_first_page(
/*================*/
- os_file_t data_file, /*!< in: open data file */
+ pfs_os_file_t data_file, /*!< in: open data file */
ibool one_read_already, /*!< in: TRUE if min and max
parameters below already
contain sensible data */
@@ -902,12 +902,12 @@ struct PageCallback {
Called for every page in the tablespace. If the page was not
updated then its state must be set to BUF_PAGE_NOT_USED. For
compressed tables the page descriptor memory will be at offset:
- block->frame + UNIV_PAGE_SIZE;
+ block->frame + UNIV_PAGE_SIZE;
@param offset - physical offset within the file
@param block - block read from file, note it is not from the buffer pool
@retval DB_SUCCESS or error code. */
virtual dberr_t operator()(
- os_offset_t offset,
+ os_offset_t offset,
buf_block_t* block) UNIV_NOTHROW = 0;
/**
@@ -915,7 +915,7 @@ struct PageCallback {
to open it for the file that is being iterated over.
@param filename - then physical name of the tablespace file.
@param file - OS file handle */
- void set_file(const char* filename, os_file_t file) UNIV_NOTHROW
+ void set_file(const char* filename, pfs_os_file_t file) UNIV_NOTHROW
{
m_file = file;
m_filepath = filename;
@@ -951,7 +951,7 @@ struct PageCallback {
ulint m_page_size;
/** File handle to the tablespace */
- os_file_t m_file;
+ pfs_os_file_t m_file;
/** Physical file path. */
const char* m_filepath;
diff --git a/storage/innobase/include/ha0ha.h b/storage/innobase/include/ha0ha.h
index 7351b407e8c..58eb581e76a 100644
--- a/storage/innobase/include/ha0ha.h
+++ b/storage/innobase/include/ha0ha.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -107,7 +107,7 @@ chosen to be a slightly bigger prime number.
@param level in: level of the mutexes in the latching order
@param n_m in: number of mutexes to protect the hash table;
must be a power of 2, or 0 */
-# define ha_create(n_c,n_m,type,level) ha_create_func(n_c,level,n_m,type)
+# define ib_create(n_c,n_m,type,level) ha_create_func(n_c,level,n_m,type)
#else /* UNIV_SYNC_DEBUG */
/** Creates a hash table.
@return own: created table
@@ -116,7 +116,7 @@ chosen to be a slightly bigger prime number.
@param level in: level of the mutexes in the latching order
@param n_m in: number of mutexes to protect the hash table;
must be a power of 2, or 0 */
-# define ha_create(n_c,n_m,type,level) ha_create_func(n_c,n_m,type)
+# define ib_create(n_c,n_m,type,level) ha_create_func(n_c,n_m,type)
#endif /* UNIV_SYNC_DEBUG */
/*************************************************************//**
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index f047302c60c..76a389f9051 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -1,6 +1,6 @@
/***********************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Percona Inc.
Portions of this file contain modifications contributed and copyrighted
@@ -89,6 +89,16 @@ typedef int os_file_t;
# define OS_FILE_FROM_FD(fd) fd
#endif
+/*Common file descriptor for file IO instrumentation with PFS
+on windows and other platforms */
+struct pfs_os_file_t
+{
+ os_file_t m_file;
+#ifdef UNIV_PFS_IO
+ struct PSI_file *m_psi;
+#endif
+};
+
/** Umask for creating files */
extern ulint os_innodb_umask;
@@ -216,6 +226,8 @@ extern mysql_pfs_key_t innodb_file_temp_key;
various file I/O operations with performance schema.
1) register_pfs_file_open_begin() and register_pfs_file_open_end() are
used to register file creation, opening, closing and renaming.
+2) register_pfs_file_rename_begin() and register_pfs_file_rename_end()
+are used to register file renaming
2) register_pfs_file_io_begin() and register_pfs_file_io_end() are
used to register actual file read, write and flush
3) register_pfs_file_close_begin() and register_pfs_file_close_end()
@@ -225,17 +237,30 @@ are used to register file deletion operations*/
do { \
locker = PSI_FILE_CALL(get_thread_file_name_locker)( \
state, key, op, name, &locker); \
- if (UNIV_LIKELY(locker != NULL)) { \
+ if (locker != NULL) { \
PSI_FILE_CALL(start_file_open_wait)( \
locker, src_file, src_line); \
} \
} while (0)
-# define register_pfs_file_open_end(locker, file) \
+# define register_pfs_file_open_end(locker, file, result) \
do { \
- if (UNIV_LIKELY(locker != NULL)) { \
- PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(\
- locker, file); \
+ if (locker != NULL) { \
+ file.m_psi = PSI_FILE_CALL( \
+ end_file_open_wait)( \
+ locker, result); \
+ } \
+} while (0)
+
+# define register_pfs_file_rename_begin(state, locker, key, op, name, \
+ src_file, src_line) \
+ register_pfs_file_open_begin(state, locker, key, op, name, \
+ src_file, src_line) \
+
+# define register_pfs_file_rename_end(locker, result) \
+do { \
+ if (locker != NULL) { \
+ PSI_FILE_CALL(end_file_open_wait)(locker, result); \
} \
} while (0)
@@ -261,9 +286,9 @@ do { \
# define register_pfs_file_io_begin(state, locker, file, count, op, \
src_file, src_line) \
do { \
- locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)( \
- state, file, op); \
- if (UNIV_LIKELY(locker != NULL)) { \
+ locker = PSI_FILE_CALL(get_thread_file_stream_locker)( \
+ state, file.m_psi, op); \
+ if (locker != NULL) { \
PSI_FILE_CALL(start_file_wait)( \
locker, count, src_file, src_line); \
} \
@@ -271,7 +296,7 @@ do { \
# define register_pfs_file_io_end(locker, count) \
do { \
- if (UNIV_LIKELY(locker != NULL)) { \
+ if (locker != NULL) { \
PSI_FILE_CALL(end_file_wait)(locker, count); \
} \
} while (0)
@@ -289,7 +314,9 @@ os_file_rename
os_aio
os_file_read
os_file_read_no_error_handling
+os_file_read_no_error_handling_int_fd
os_file_write
+os_file_write_int_fd
The wrapper functions have the prefix of "innodb_". */
@@ -307,7 +334,7 @@ The wrapper functions have the prefix of "innodb_". */
pfs_os_file_create_simple_no_error_handling_func( \
key, name, create_mode, access, success, __FILE__, __LINE__)
-# define os_file_close(file) \
+# define os_file_close_pfs(file) \
pfs_os_file_close_func(file, __FILE__, __LINE__)
# define os_aio(type, mode, name, file, buf, offset, \
@@ -315,18 +342,27 @@ The wrapper functions have the prefix of "innodb_". */
pfs_os_aio_func(type, mode, name, file, buf, offset, \
n, message1, message2, __FILE__, __LINE__)
-# define os_file_read(file, buf, offset, n) \
+# define os_file_read_pfs(file, buf, offset, n) \
pfs_os_file_read_func(file, buf, offset, n, __FILE__, __LINE__)
# define os_file_read_no_error_handling(file, buf, offset, n) \
pfs_os_file_read_no_error_handling_func(file, buf, offset, n, \
__FILE__, __LINE__)
-# define os_file_write(name, file, buf, offset, n) \
+# define os_file_read_no_error_handling_int_fd( \
+ file, buf, offset, n) \
+ pfs_os_file_read_no_error_handling_int_fd_func( \
+ file, buf, offset, n, __FILE__, __LINE__)
+
+# define os_file_write_pfs(name, file, buf, offset, n) \
pfs_os_file_write_func(name, file, buf, offset, \
n, __FILE__, __LINE__)
-# define os_file_flush(file) \
+# define os_file_write_int_fd(name, file, buf, offset, n) \
+ pfs_os_file_write_int_fd_func(name, file, buf, offset, \
+ n, __FILE__, __LINE__)
+
+# define os_file_flush_pfs(file) \
pfs_os_file_flush_func(file, __FILE__, __LINE__)
# define os_file_rename(key, oldpath, newpath) \
@@ -352,22 +388,29 @@ to original un-instrumented file I/O APIs */
os_file_create_simple_no_error_handling_func( \
name, create_mode, access, success)
-# define os_file_close(file) os_file_close_func(file)
+# define os_file_close_pfs(file) \
+ os_file_close_func(file)
# define os_aio(type, mode, name, file, buf, offset, n, message1, message2) \
os_aio_func(type, mode, name, file, buf, offset, n, \
message1, message2)
-# define os_file_read(file, buf, offset, n) \
+# define os_file_read_pfs(file, buf, offset, n) \
os_file_read_func(file, buf, offset, n)
# define os_file_read_no_error_handling(file, buf, offset, n) \
os_file_read_no_error_handling_func(file, buf, offset, n)
+# define os_file_read_no_error_handling_int_fd( \
+ file, buf, offset, n) \
+ os_file_read_no_error_handling_func(file, buf, offset, n)
-# define os_file_write(name, file, buf, offset, n) \
+# define os_file_write_int_fd(name, file, buf, offset, n) \
+ os_file_write_func(name, file, buf, offset, n)
+# define os_file_write_pfs(name, file, buf, offset, n) \
os_file_write_func(name, file, buf, offset, n)
-# define os_file_flush(file) os_file_flush_func(file)
+
+# define os_file_flush_pfs(file) os_file_flush_func(file)
# define os_file_rename(key, oldpath, newpath) \
os_file_rename_func(oldpath, newpath)
@@ -379,6 +422,33 @@ to original un-instrumented file I/O APIs */
#endif /* UNIV_PFS_IO */
+#ifdef UNIV_PFS_IO
+ #define os_file_close(file) os_file_close_pfs(file)
+#else
+ #define os_file_close(file) os_file_close_pfs((file).m_file)
+#endif
+
+#ifdef UNIV_PFS_IO
+ #define os_file_read(file, buf, offset, n) \
+ os_file_read_pfs(file, buf, offset, n)
+#else
+ #define os_file_read(file, buf, offset, n) \
+ os_file_read_pfs(file.m_file, buf, offset, n)
+#endif
+
+#ifdef UNIV_PFS_IO
+ #define os_file_flush(file) os_file_flush_pfs(file)
+#else
+ #define os_file_flush(file) os_file_flush_pfs(file.m_file)
+#endif
+
+#ifdef UNIV_PFS_IO
+ #define os_file_write(name, file, buf, offset, n) \
+ os_file_write_pfs(name, file, buf, offset, n)
+#else
+ #define os_file_write(name, file, buf, offset, n) \
+ os_file_write_pfs(name, file.m_file, buf, offset, n)
+#endif
/* File types for directory entry data type */
enum os_file_type_t {
@@ -518,7 +588,7 @@ A simple function to open or create a file.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INTERN
-os_file_t
+pfs_os_file_t
os_file_create_simple_no_error_handling_func(
/*=========================================*/
const char* name, /*!< in: name of the file or path as a
@@ -548,7 +618,7 @@ Opens an existing file or creates a new.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INTERN
-os_file_t
+pfs_os_file_t
os_file_create_func(
/*================*/
const char* name, /*!< in: name of the file or path as a
@@ -617,7 +687,7 @@ os_file_create_simple() which opens or creates a file.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
-os_file_t
+pfs_os_file_t
pfs_os_file_create_simple_func(
/*===========================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@@ -640,7 +710,7 @@ monitor file creation/open.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
-os_file_t
+pfs_os_file_t
pfs_os_file_create_simple_no_error_handling_func(
/*=============================================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@@ -664,7 +734,7 @@ Add instrumentation to monitor file creation/open.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
-os_file_t
+pfs_os_file_t
pfs_os_file_create_func(
/*====================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@@ -693,7 +763,7 @@ UNIV_INLINE
ibool
pfs_os_file_close_func(
/*===================*/
- os_file_t file, /*!< in, own: handle to a file */
+ pfs_os_file_t file, /*!< in, own: handle to a file */
const char* src_file,/*!< in: file name where func invoked */
ulint src_line);/*!< in: line where the func invoked */
/*******************************************************************//**
@@ -706,7 +776,7 @@ UNIV_INLINE
ibool
pfs_os_file_read_func(
/*==================*/
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */
@@ -724,7 +794,7 @@ UNIV_INLINE
ibool
pfs_os_file_read_no_error_handling_func(
/*====================================*/
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */
@@ -745,7 +815,7 @@ pfs_os_aio_func(
ulint mode, /*!< in: OS_AIO_NORMAL etc. I/O mode */
const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read or from which
to write */
os_offset_t offset, /*!< in: file offset where to read or write */
@@ -772,7 +842,7 @@ pfs_os_file_write_func(
/*===================*/
const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
const void* buf, /*!< in: buffer from which to write */
os_offset_t offset, /*!< in: file offset where to write */
ulint n, /*!< in: number of bytes to write */
@@ -789,7 +859,7 @@ UNIV_INLINE
ibool
pfs_os_file_flush_func(
/*===================*/
- os_file_t file, /*!< in, own: handle to a file */
+ pfs_os_file_t file, /*!< in, own: handle to a file */
const char* src_file,/*!< in: file name where func invoked */
ulint src_line);/*!< in: line where the func invoked */
@@ -860,7 +930,7 @@ UNIV_INTERN
os_offset_t
os_file_get_size(
/*=============*/
- os_file_t file) /*!< in: handle to a file */
+ pfs_os_file_t file) /*!< in: handle to a file */
MY_ATTRIBUTE((warn_unused_result));
/***********************************************************************//**
Write the specified number of zeros to a newly created file.
@@ -871,7 +941,7 @@ os_file_set_size(
/*=============*/
const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
os_offset_t size) /*!< in: file size */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/***********************************************************************//**
@@ -1109,7 +1179,7 @@ os_aio_func(
caution! */
const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read or from which
to write */
os_offset_t offset, /*!< in: file offset where to read or write */
diff --git a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic
index defd8204ba3..31d5cc1d6a2 100644
--- a/storage/innobase/include/os0file.ic
+++ b/storage/innobase/include/os0file.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2010, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2010, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -34,7 +34,7 @@ os_file_create_simple() which opens or creates a file.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
-os_file_t
+pfs_os_file_t
pfs_os_file_create_simple_func(
/*===========================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@@ -47,7 +47,7 @@ pfs_os_file_create_simple_func(
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
- os_file_t file;
+ pfs_os_file_t file;
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
@@ -58,11 +58,13 @@ pfs_os_file_create_simple_func(
: PSI_FILE_OPEN),
name, src_file, src_line);
- file = os_file_create_simple_func(name, create_mode,
+ file.m_file = os_file_create_simple_func(name, create_mode,
access_type, success);
+ file.m_psi = NULL;
- /* Regsiter the returning "file" value with the system */
- register_pfs_file_open_end(locker, file);
+ /* Regsiter psi value for the file */
+ register_pfs_file_open_end(locker, file,
+ (*success == TRUE ? success : 0));
return(file);
}
@@ -76,7 +78,7 @@ monitor file creation/open.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
-os_file_t
+pfs_os_file_t
pfs_os_file_create_simple_no_error_handling_func(
/*=============================================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@@ -91,7 +93,7 @@ pfs_os_file_create_simple_no_error_handling_func(
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
- os_file_t file;
+ pfs_os_file_t file;
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
@@ -104,8 +106,10 @@ pfs_os_file_create_simple_no_error_handling_func(
file = os_file_create_simple_no_error_handling_func(
name, create_mode, access_type, success);
+ file.m_psi = NULL;
- register_pfs_file_open_end(locker, file);
+ register_pfs_file_open_end(locker, file,
+ (*success == TRUE ? success : 0));
return(file);
}
@@ -118,7 +122,7 @@ Add instrumentation to monitor file creation/open.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
-os_file_t
+pfs_os_file_t
pfs_os_file_create_func(
/*====================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@@ -137,7 +141,7 @@ pfs_os_file_create_func(
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
- os_file_t file;
+ pfs_os_file_t file;
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
@@ -149,8 +153,10 @@ pfs_os_file_create_func(
name, src_file, src_line);
file = os_file_create_func(name, create_mode, purpose, type, success);
+ file.m_psi = NULL;
- register_pfs_file_open_end(locker, file);
+ register_pfs_file_open_end(locker, file,
+ (*success == TRUE ? success : 0));
return(file);
}
@@ -164,7 +170,7 @@ UNIV_INLINE
ibool
pfs_os_file_close_func(
/*===================*/
- os_file_t file, /*!< in, own: handle to a file */
+ pfs_os_file_t file, /*!< in, own: handle to a file */
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
@@ -176,7 +182,7 @@ pfs_os_file_close_func(
register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_CLOSE,
src_file, src_line);
- result = os_file_close_func(file);
+ result = os_file_close_func(file.m_file);
register_pfs_file_io_end(locker, 0);
@@ -197,7 +203,7 @@ pfs_os_aio_func(
ulint mode, /*!< in: OS_AIO_NORMAL etc. I/O mode */
const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read or from which
to write */
os_offset_t offset, /*!< in: file offset where to read or write */
@@ -242,7 +248,7 @@ UNIV_INLINE
ibool
pfs_os_file_read_func(
/*==================*/
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */
@@ -256,7 +262,7 @@ pfs_os_file_read_func(
register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ,
src_file, src_line);
- result = os_file_read_func(file, buf, offset, n);
+ result = os_file_read_func(file.m_file, buf, offset, n);
register_pfs_file_io_end(locker, n);
@@ -275,7 +281,7 @@ UNIV_INLINE
ibool
pfs_os_file_read_no_error_handling_func(
/*====================================*/
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */
@@ -289,13 +295,50 @@ pfs_os_file_read_no_error_handling_func(
register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ,
src_file, src_line);
- result = os_file_read_no_error_handling_func(file, buf, offset, n);
+ result = os_file_read_no_error_handling_func(file.m_file, buf, offset, n);
register_pfs_file_io_end(locker, n);
return(result);
}
+/** NOTE! Please use the corresponding macro
+os_file_read_no_error_handling_int_fd(), not directly this function!
+This is the performance schema instrumented wrapper function for
+os_file_read_no_error_handling_int_fd_func() which requests a
+synchronous read operation.
+@return TRUE if request was successful, FALSE if fail */
+UNIV_INLINE
+ibool
+pfs_os_file_read_no_error_handling_int_fd_func(
+ int file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ os_offset_t offset, /*!< in: file offset where to read */
+ ulint n, /*!< in: number of bytes to read */
+ const char* src_file,/*!< in: file name where func invoked */
+ ulint src_line)/*!< in: line where the func invoked */
+{
+
+ PSI_file_locker_state state;
+ struct PSI_file_locker* locker = NULL;
+
+ locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
+ &state, file, PSI_FILE_READ);
+ if (locker != NULL) {
+ PSI_FILE_CALL(start_file_wait)(
+ locker, n,
+ __FILE__, __LINE__);
+ }
+ ibool result = os_file_read_no_error_handling_func(
+ OS_FILE_FROM_FD(file), buf, offset, n);
+
+ if (locker != NULL) {
+ PSI_FILE_CALL(end_file_wait)(locker, n);
+ }
+
+ return(result);
+}
+
/*******************************************************************//**
NOTE! Please use the corresponding macro os_file_write(), not directly
this function!
@@ -308,7 +351,7 @@ pfs_os_file_write_func(
/*===================*/
const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
const void* buf, /*!< in: buffer from which to write */
os_offset_t offset, /*!< in: file offset where to write */
ulint n, /*!< in: number of bytes to write */
@@ -322,13 +365,50 @@ pfs_os_file_write_func(
register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_WRITE,
src_file, src_line);
- result = os_file_write_func(name, file, buf, offset, n);
+ result = os_file_write_func(name, file.m_file, buf, offset, n);
register_pfs_file_io_end(locker, n);
return(result);
}
+/** NOTE! Please use the corresponding macro os_file_write(), not
+directly this function!
+This is the performance schema instrumented wrapper function for
+os_file_write() which requests a synchronous write operation.
+@return TRUE if request was successful, FALSE if fail */
+UNIV_INLINE
+ibool
+pfs_os_file_write_int_fd_func(
+ const char* name, /*!< in: name of the file or path as a
+ null-terminated string */
+ int file, /*!< in: handle to a file */
+ const void* buf, /*!< in: buffer from which to write */
+ os_offset_t offset, /*!< in: file offset where to write */
+ ulint n, /*!< in: number of bytes to write */
+ const char* src_file,/*!< in: file name where func invoked */
+ ulint src_line)/*!< in: line where the func invoked */
+{
+ PSI_file_locker_state state;
+ struct PSI_file_locker* locker = NULL;
+
+ locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
+ &state, file, PSI_FILE_WRITE);
+ if (locker != NULL) {
+ PSI_FILE_CALL(start_file_wait)(
+ locker, n,
+ __FILE__, __LINE__);
+ }
+ ibool result = os_file_write_func(
+ name, OS_FILE_FROM_FD(file), buf, offset, n);
+
+ if (locker != NULL) {
+ PSI_FILE_CALL(end_file_wait)(locker, n);
+ }
+
+ return(result);
+}
+
/***********************************************************************//**
NOTE! Please use the corresponding macro os_file_flush(), not directly
this function!
@@ -339,7 +419,7 @@ UNIV_INLINE
ibool
pfs_os_file_flush_func(
/*===================*/
- os_file_t file, /*!< in, own: handle to a file */
+ pfs_os_file_t file, /*!< in, own: handle to a file */
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
@@ -349,7 +429,7 @@ pfs_os_file_flush_func(
register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_SYNC,
src_file, src_line);
- result = os_file_flush_func(file);
+ result = os_file_flush_func(file.m_file);
register_pfs_file_io_end(locker, 0);
@@ -377,12 +457,12 @@ pfs_os_file_rename_func(
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
- register_pfs_file_open_begin(&state, locker, key, PSI_FILE_RENAME, newpath,
+ register_pfs_file_rename_begin(&state, locker, key, PSI_FILE_RENAME, newpath,
src_file, src_line);
result = os_file_rename_func(oldpath, newpath);
- register_pfs_file_open_end(locker, 0);
+ register_pfs_file_rename_end(locker, 0);
return(result);
}
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index fc1846b76f3..d0c1bdaa585 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -652,6 +652,8 @@ struct mysql_row_templ_t {
#define ROW_PREBUILT_ALLOCATED 78540783
#define ROW_PREBUILT_FREED 26423527
+class ha_innobase;
+
/** A struct for (sometimes lazily) prebuilt structures in an Innobase table
handle used within MySQL; these are used to save CPU time. */
@@ -879,6 +881,12 @@ struct row_prebuilt_t {
to InnoDB format.*/
uint srch_key_val_len; /*!< Size of search key */
+ /** MySQL handler object. */
+ ha_innobase* mysql_handler;
+
+ /** True if exceeded the end_range while filling the prefetch cache. */
+ bool end_range;
+
};
/** Callback for row_mysql_sys_index_iterate() */
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 042ced75d10..7d701536341 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, 2009, Google Inc.
Copyright (c) 2009, Percona Inc.
@@ -785,6 +785,13 @@ void
srv_purge_wakeup(void);
/*==================*/
+/** Check whether given space id is undo tablespace id
+@param[in] space_id space id to check
+@return true if it is undo tablespace else false. */
+bool
+srv_is_undo_tablespace(
+ ulint space_id);
+
/** Status variables to be passed to MySQL */
struct export_var_t{
ulint innodb_data_pending_reads; /*!< Pending reads */
diff --git a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h
index 963b767f0fb..a60776a4665 100644
--- a/storage/innobase/include/srv0start.h
+++ b/storage/innobase/include/srv0start.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -139,6 +139,8 @@ extern ibool srv_startup_is_before_trx_rollback_phase;
/** TRUE if a raw partition is in use */
extern ibool srv_start_raw_disk_in_use;
+/** Undo tablespaces starts with space_id. */
+extern ulint srv_undo_space_id_start;
/** Shutdown state */
enum srv_shutdown_state {
diff --git a/storage/innobase/include/trx0xa.h b/storage/innobase/include/trx0xa.h
index 7caddfb7ba4..255431293f5 100644
--- a/storage/innobase/include/trx0xa.h
+++ b/storage/innobase/include/trx0xa.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2009, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -24,6 +24,8 @@ this program; if not, write to the Free Software Foundation, Inc.,
#ifndef XA_H
#define XA_H
+#include "xa.h"
+
/*
* Transaction branch identification: XID and NULLXID:
*/
@@ -35,17 +37,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
#define MAXGTRIDSIZE 64 /*!< maximum size in bytes of gtrid */
#define MAXBQUALSIZE 64 /*!< maximum size in bytes of bqual */
-/** X/Open XA distributed transaction identifier */
-struct xid_t {
- long formatID; /*!< format identifier; -1
- means that the XID is null */
- long gtrid_length; /*!< value from 1 through 64 */
- long bqual_length; /*!< value from 1 through 64 */
- char data[XIDDATASIZE]; /*!< distributed transaction
- identifier */
-};
-/** X/Open XA distributed transaction identifier */
-typedef struct xid_t XID;
#endif
/** X/Open XA distributed transaction status codes */
/* @{ */
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index dfb59673f0b..5d3dcafb322 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -133,14 +133,8 @@ HAVE_PSI_INTERFACE is defined. */
#if defined HAVE_PSI_INTERFACE && !defined UNIV_HOTBACKUP
# define UNIV_PFS_MUTEX
# define UNIV_PFS_RWLOCK
-/* For I/O instrumentation, performance schema rely
-on a native descriptor to identify the file, this
-descriptor could conflict with our OS level descriptor.
-Disable IO instrumentation on Windows until this is
-resolved */
-# ifndef __WIN__
-# define UNIV_PFS_IO
-# endif
+
+# define UNIV_PFS_IO
# define UNIV_PFS_THREAD
/* There are mutexes/rwlocks that we want to exclude from
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 8ff8e39d352..51b057ec09a 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -3406,7 +3406,12 @@ loop:
lsn = log_sys->lsn;
- if (lsn != log_sys->last_checkpoint_lsn
+ const bool is_last = ((srv_force_recovery == SRV_FORCE_NO_LOG_REDO
+ && lsn == log_sys->last_checkpoint_lsn
+ + LOG_BLOCK_HDR_SIZE)
+ || lsn == log_sys->last_checkpoint_lsn);
+
+ if (!is_last
#ifdef UNIV_LOG_ARCHIVE
|| (srv_log_archive_on
&& lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE)
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 85f4f6ea671..69d74a99ab5 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@@ -332,6 +332,7 @@ DECLARE_THREAD(recv_writer_thread)(
/*!< in: a dummy parameter required by
os_thread_create */
{
+ my_thread_init();
ut_ad(!srv_read_only_mode);
#ifdef UNIV_PFS_THREAD
@@ -364,6 +365,7 @@ DECLARE_THREAD(recv_writer_thread)(
recv_writer_thread_active = false;
+ my_thread_end();
/* We count the number of threads in os_thread_exit().
A created thread should always use that to exit and not
use return() to exit. */
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 46a7b801521..dbd30c3d658 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -1,6 +1,6 @@
/***********************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Percona Inc.
Portions of this file contain modifications contributed and copyrighted
@@ -163,7 +163,7 @@ struct os_aio_slot_t{
byte* buf; /*!< buffer used in i/o */
ulint type; /*!< OS_FILE_READ or OS_FILE_WRITE */
os_offset_t offset; /*!< file offset in bytes */
- os_file_t file; /*!< file where to read or write */
+ pfs_os_file_t file; /*!< file where to read or write */
const char* name; /*!< file name or path */
ibool io_already_done;/*!< used only in simulated aio:
TRUE if the physical i/o already
@@ -1306,7 +1306,7 @@ A simple function to open or create a file.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INTERN
-os_file_t
+pfs_os_file_t
os_file_create_simple_no_error_handling_func(
/*=========================================*/
const char* name, /*!< in: name of the file or path as a
@@ -1318,7 +1318,7 @@ os_file_create_simple_no_error_handling_func(
used by a backup program reading the file */
ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
- os_file_t file;
+ pfs_os_file_t file;
*success = FALSE;
#ifdef __WIN__
@@ -1326,7 +1326,6 @@ os_file_create_simple_no_error_handling_func(
DWORD create_flag;
DWORD attributes = 0;
DWORD share_mode = FILE_SHARE_READ;
-
ut_a(name);
ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT));
@@ -1343,8 +1342,8 @@ os_file_create_simple_no_error_handling_func(
ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown file create mode (%lu) for file '%s'",
create_mode, name);
-
- return((os_file_t) -1);
+ file.m_file = (os_file_t)-1;
+ return(file);
}
if (access_type == OS_FILE_READ_ONLY) {
@@ -1367,11 +1366,11 @@ os_file_create_simple_no_error_handling_func(
ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown file access type (%lu) for file '%s'",
access_type, name);
-
- return((os_file_t) -1);
+ file.m_file = (os_file_t)-1;
+ return(file);
}
- file = CreateFile((LPCTSTR) name,
+ file.m_file = CreateFile((LPCTSTR) name,
access,
share_mode,
NULL, // Security attributes
@@ -1379,11 +1378,10 @@ os_file_create_simple_no_error_handling_func(
attributes,
NULL); // No template file
- *success = (file != INVALID_HANDLE_VALUE);
+ *success = (file.m_file != INVALID_HANDLE_VALUE);
#else /* __WIN__ */
int create_flag;
const char* mode_str = NULL;
-
ut_a(name);
ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT));
@@ -1425,13 +1423,13 @@ os_file_create_simple_no_error_handling_func(
ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown file create mode (%lu) for file '%s'",
create_mode, name);
-
- return((os_file_t) -1);
+ file.m_file = -1;
+ return(file);
}
- file = ::open(name, create_flag, os_innodb_umask);
+ file.m_file = ::open(name, create_flag, os_innodb_umask);
- *success = file == -1 ? FALSE : TRUE;
+ *success = file.m_file == -1 ? FALSE : TRUE;
/* This function is always called for data files, we should disable
OS caching (O_DIRECT) here as we do in os_file_create_func(), so
@@ -1441,18 +1439,18 @@ os_file_create_simple_no_error_handling_func(
&& (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT
|| srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)) {
- os_file_set_nocache(file, name, mode_str);
+ os_file_set_nocache(file.m_file, name, mode_str);
}
#ifdef USE_FILE_LOCK
if (!srv_read_only_mode
&& *success
&& access_type == OS_FILE_READ_WRITE
- && os_file_lock(file, name)) {
+ && os_file_lock(file.m_file, name)) {
*success = FALSE;
- close(file);
- file = -1;
+ close(file.m_file);
+ file.m_file = -1;
}
#endif /* USE_FILE_LOCK */
@@ -1527,7 +1525,7 @@ Opens an existing file or creates a new.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INTERN
-os_file_t
+pfs_os_file_t
os_file_create_func(
/*================*/
const char* name, /*!< in: name of the file or path as a
@@ -1543,24 +1541,25 @@ os_file_create_func(
ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */
ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
- os_file_t file;
+ pfs_os_file_t file;
ibool retry;
ibool on_error_no_exit;
ibool on_error_silent;
-
#ifdef __WIN__
DBUG_EXECUTE_IF(
"ib_create_table_fail_disk_full",
*success = FALSE;
SetLastError(ERROR_DISK_FULL);
- return((os_file_t) -1);
+ file.m_file = (os_file_t)-1;
+ return(file);
);
#else /* __WIN__ */
DBUG_EXECUTE_IF(
"ib_create_table_fail_disk_full",
*success = FALSE;
errno = ENOSPC;
- return((os_file_t) -1);
+ file.m_file = -1;
+ return(file);
);
#endif /* __WIN__ */
@@ -1611,7 +1610,8 @@ os_file_create_func(
"Unknown file create mode (%lu) for file '%s'",
create_mode, name);
- return((os_file_t) -1);
+ file.m_file = (os_file_t)-1;
+ return(file);
}
DWORD attributes = 0;
@@ -1636,8 +1636,8 @@ os_file_create_func(
ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown purpose flag (%lu) while opening file '%s'",
purpose, name);
-
- return((os_file_t)(-1));
+ file.m_file = (os_file_t)-1;
+ return(file);
}
#ifdef UNIV_NON_BUFFERED_IO
@@ -1664,11 +1664,11 @@ os_file_create_func(
do {
/* Use default security attributes and no template file. */
- file = CreateFile(
+ file.m_file = CreateFile(
(LPCTSTR) name, access, share_mode, NULL,
create_flag, attributes, NULL);
- if (file == INVALID_HANDLE_VALUE) {
+ if (file.m_file == INVALID_HANDLE_VALUE) {
const char* operation;
operation = (create_mode == OS_FILE_CREATE
@@ -1693,7 +1693,6 @@ os_file_create_func(
#else /* __WIN__ */
int create_flag;
const char* mode_str = NULL;
-
on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT
? TRUE : FALSE;
on_error_silent = create_mode & OS_FILE_ON_ERROR_SILENT
@@ -1731,7 +1730,8 @@ os_file_create_func(
"Unknown file create mode (%lu) for file '%s'",
create_mode, name);
- return((os_file_t) -1);
+ file.m_file = -1;
+ return(file);
}
ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE);
@@ -1751,9 +1751,9 @@ os_file_create_func(
#endif /* O_SYNC */
do {
- file = ::open(name, create_flag, os_innodb_umask);
+ file.m_file = ::open(name, create_flag, os_innodb_umask);
- if (file == -1) {
+ if (file.m_file == -1) {
const char* operation;
operation = (create_mode == OS_FILE_CREATE
@@ -1783,14 +1783,14 @@ os_file_create_func(
&& (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT
|| srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)) {
- os_file_set_nocache(file, name, mode_str);
+ os_file_set_nocache(file.m_file, name, mode_str);
}
#ifdef USE_FILE_LOCK
if (!srv_read_only_mode
&& *success
&& create_mode != OS_FILE_OPEN_RAW
- && os_file_lock(file, name)) {
+ && os_file_lock(file.m_file, name)) {
if (create_mode == OS_FILE_OPEN_RETRY) {
@@ -1802,7 +1802,7 @@ os_file_create_func(
for (int i = 0; i < 100; i++) {
os_thread_sleep(1000000);
- if (!os_file_lock(file, name)) {
+ if (!os_file_lock(file.m_file, name)) {
*success = TRUE;
return(file);
}
@@ -1813,8 +1813,8 @@ os_file_create_func(
}
*success = FALSE;
- close(file);
- file = -1;
+ close(file.m_file);
+ file.m_file = -1;
}
#endif /* USE_FILE_LOCK */
@@ -2086,14 +2086,14 @@ UNIV_INTERN
os_offset_t
os_file_get_size(
/*=============*/
- os_file_t file) /*!< in: handle to a file */
+ pfs_os_file_t file) /*!< in: handle to a file */
{
#ifdef __WIN__
os_offset_t offset;
DWORD high;
DWORD low;
- low = GetFileSize(file, &high);
+ low = GetFileSize(file.m_file, &high);
if ((low == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) {
return((os_offset_t) -1);
@@ -2103,7 +2103,8 @@ os_file_get_size(
return(offset);
#else
- return((os_offset_t) lseek(file, 0, SEEK_END));
+ return((os_offset_t) lseek(file.m_file, 0, SEEK_END));
+
#endif /* __WIN__ */
}
@@ -2116,7 +2117,7 @@ os_file_set_size(
/*=============*/
const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
os_offset_t size) /*!< in: file size */
{
os_offset_t current_size;
@@ -4187,7 +4188,7 @@ os_aio_array_reserve_slot(
the aio operation */
void* message2,/*!< in: message to be passed along with
the aio operation */
- os_file_t file, /*!< in: file handle */
+ pfs_os_file_t file, /*!< in: file handle */
const char* name, /*!< in: name of the file or path as a
null-terminated string */
void* buf, /*!< in: buffer where to read or from which
@@ -4307,10 +4308,10 @@ found:
iocb = &slot->control;
if (type == OS_FILE_READ) {
- io_prep_pread(iocb, file, buf, len, aio_offset);
+ io_prep_pread(iocb, file.m_file, buf, len, aio_offset);
} else {
ut_a(type == OS_FILE_WRITE);
- io_prep_pwrite(iocb, file, buf, len, aio_offset);
+ io_prep_pwrite(iocb, file.m_file, buf, len, aio_offset);
}
iocb->data = (void*) slot;
@@ -4548,7 +4549,7 @@ os_aio_func(
caution! */
const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /*!< in: handle to a file */
+ pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read or from which
to write */
os_offset_t offset, /*!< in: file offset where to read or write */
@@ -4573,8 +4574,7 @@ os_aio_func(
ulint dummy_type;
#endif /* WIN_ASYNC_IO */
ulint wake_later;
-
- ut_ad(file);
+ ut_ad(file.m_file);
ut_ad(buf);
ut_ad(n > 0);
ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0);
@@ -4606,13 +4606,11 @@ os_aio_func(
and os_file_write_func() */
if (type == OS_FILE_READ) {
- return(os_file_read_func(file, buf, offset, n));
+ return(os_file_read_func(file.m_file, buf, offset, n));
}
-
ut_ad(!srv_read_only_mode);
ut_a(type == OS_FILE_WRITE);
-
- return(os_file_write_func(name, file, buf, offset, n));
+ return(os_file_write_func(name, file.m_file, buf, offset, n));
}
try_again:
@@ -4664,9 +4662,8 @@ try_again:
os_n_file_reads++;
os_bytes_read_since_printout += n;
#ifdef WIN_ASYNC_IO
- ret = ReadFile(file, buf, (DWORD) n, &len,
+ ret = ReadFile(file.m_file, buf, (DWORD) n, &len,
&(slot->control));
-
#elif defined(LINUX_NATIVE_AIO)
if (!os_aio_linux_dispatch(array, slot)) {
goto err_exit;
@@ -4684,9 +4681,8 @@ try_again:
if (srv_use_native_aio) {
os_n_file_writes++;
#ifdef WIN_ASYNC_IO
- ret = WriteFile(file, buf, (DWORD) n, &len,
+ ret = WriteFile(file.m_file, buf, (DWORD) n, &len,
&(slot->control));
-
#elif defined(LINUX_NATIVE_AIO)
if (!os_aio_linux_dispatch(array, slot)) {
goto err_exit;
@@ -4840,8 +4836,7 @@ os_aio_windows_handle(
srv_set_io_thread_op_info(
orig_seg, "get windows aio return value");
}
-
- ret = GetOverlappedResult(slot->file, &(slot->control), &len, TRUE);
+ ret = GetOverlappedResult(slot->file.m_file, &(slot->control), &len, TRUE);
*message1 = slot->message1;
*message2 = slot->message2;
@@ -4870,7 +4865,8 @@ os_aio_windows_handle(
and os_file_write APIs, need to register with
performance schema explicitly here. */
struct PSI_file_locker* locker = NULL;
- register_pfs_file_io_begin(locker, slot->file, slot->len,
+ PSI_file_locker_state state;
+ register_pfs_file_io_begin(&state, locker, slot->file, slot->len,
(slot->type == OS_FILE_WRITE)
? PSI_FILE_WRITE
: PSI_FILE_READ,
@@ -4881,16 +4877,14 @@ os_aio_windows_handle(
switch (slot->type) {
case OS_FILE_WRITE:
- ret = WriteFile(slot->file, slot->buf,
+ ret = WriteFile(slot->file.m_file, slot->buf,
(DWORD) slot->len, &len,
&(slot->control));
-
break;
case OS_FILE_READ:
- ret = ReadFile(slot->file, slot->buf,
+ ret = ReadFile(slot->file.m_file, slot->buf,
(DWORD) slot->len, &len,
&(slot->control));
-
break;
default:
ut_error;
@@ -4906,8 +4900,7 @@ os_aio_windows_handle(
file where we also use async i/o: in Windows
we must use the same wait mechanism as for
async i/o */
-
- ret = GetOverlappedResult(slot->file,
+ ret = GetOverlappedResult(slot->file.m_file,
&(slot->control),
&len, TRUE);
}
@@ -5354,12 +5347,11 @@ consecutive_loop:
os_aio_slot_t* slot;
slot = os_aio_array_get_nth_slot(array, i + segment * n);
-
if (slot->reserved
&& slot != aio_slot
&& slot->offset == aio_slot->offset + aio_slot->len
&& slot->type == aio_slot->type
- && slot->file == aio_slot->file) {
+ && slot->file.m_file == aio_slot->file.m_file) {
/* Found a consecutive i/o request */
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 54183759e8d..4596e2fb951 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -363,9 +363,9 @@ row_log_online_op(
goto err_exit;
}
- ret = os_file_write(
+ ret = os_file_write_int_fd(
"(modification log)",
- OS_FILE_FROM_FD(log->fd),
+ log->fd,
log->tail.block, byte_offset, srv_sort_buf_size);
log->tail.blocks++;
if (!ret) {
@@ -479,9 +479,9 @@ row_log_table_close_func(
goto err_exit;
}
- ret = os_file_write(
+ ret = os_file_write_int_fd(
"(modification log)",
- OS_FILE_FROM_FD(log->fd),
+ log->fd,
log->tail.block, byte_offset, srv_sort_buf_size);
log->tail.blocks++;
if (!ret) {
@@ -2609,11 +2609,10 @@ all_done:
goto func_exit;
}
- success = os_file_read_no_error_handling(
- OS_FILE_FROM_FD(index->online_log->fd),
+ success = os_file_read_no_error_handling_int_fd(
+ index->online_log->fd,
index->online_log->head.block, ofs,
srv_sort_buf_size);
-
if (!success) {
fprintf(stderr, "InnoDB: unable to read temporary file"
" for table %s\n", index->table_name);
@@ -3436,8 +3435,8 @@ all_done:
goto func_exit;
}
- success = os_file_read_no_error_handling(
- OS_FILE_FROM_FD(index->online_log->fd),
+ success = os_file_read_no_error_handling_int_fd(
+ index->online_log->fd,
index->online_log->head.block, ofs,
srv_sort_buf_size);
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index f8bea67906c..2d63352feaf 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -869,8 +869,9 @@ row_merge_read(
}
#endif /* UNIV_DEBUG */
- success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf,
+ success = os_file_read_no_error_handling_int_fd(fd, buf,
ofs, srv_sort_buf_size);
+
#ifdef POSIX_FADV_DONTNEED
/* Each block is read exactly once. Free up the file cache. */
posix_fadvise(fd, ofs, srv_sort_buf_size, POSIX_FADV_DONTNEED);
@@ -904,7 +905,7 @@ row_merge_write(
DBUG_EXECUTE_IF("row_merge_write_failure", return(FALSE););
- ret = os_file_write("(merge)", OS_FILE_FROM_FD(fd), buf, ofs, buf_len);
+ ret = os_file_write_int_fd("(merge)", fd, buf, ofs, buf_len);
#ifdef UNIV_DEBUG
if (row_merge_print_block_write) {
@@ -3121,14 +3122,21 @@ row_merge_file_create_low(
performance schema */
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
- register_pfs_file_open_begin(&state, locker, innodb_file_temp_key,
- PSI_FILE_OPEN,
- "Innodb Merge Temp File",
- __FILE__, __LINE__);
+ locker = PSI_FILE_CALL(get_thread_file_name_locker)(
+ &state, innodb_file_temp_key, PSI_FILE_OPEN,
+ "Innodb Merge Temp File", &locker);
+ if (locker != NULL) {
+ PSI_FILE_CALL(start_file_open_wait)(locker,
+ __FILE__,
+ __LINE__);
+ }
#endif
fd = innobase_mysql_tmpfile(path);
#ifdef UNIV_PFS_IO
- register_pfs_file_open_end(locker, fd);
+ if (locker != NULL) {
+ PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(
+ locker, fd);
+ }
#endif
if (fd < 0) {
@@ -3175,15 +3183,20 @@ row_merge_file_destroy_low(
#ifdef UNIV_PFS_IO
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
- register_pfs_file_io_begin(&state, locker,
- fd, 0, PSI_FILE_CLOSE,
- __FILE__, __LINE__);
+ locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
+ &state, fd, PSI_FILE_CLOSE);
+ if (locker != NULL) {
+ PSI_FILE_CALL(start_file_wait)(
+ locker, 0, __FILE__, __LINE__);
+ }
#endif
if (fd >= 0) {
close(fd);
}
#ifdef UNIV_PFS_IO
- register_pfs_file_io_end(locker, 0);
+ if (locker != NULL) {
+ PSI_FILE_CALL(end_file_wait)(locker, 0);
+ }
#endif
}
/*********************************************************************//**
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 42b1ab57630..c53c1154f60 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -61,6 +61,9 @@ Created 12/19/1997 Heikki Tuuri
#include "my_sys.h" /* DEBUG_SYNC_C */
#include "my_compare.h" /* enum icp_result */
+#include "thr_lock.h"
+#include "handler.h"
+#include "ha_innodb.h"
/* Maximum number of rows to prefetch; MySQL interface has another parameter */
#define SEL_MAX_N_PREFETCH 16
@@ -2743,34 +2746,43 @@ row_sel_field_store_in_mysql_format_func(
#ifdef UNIV_DEBUG
/** Convert a field from Innobase format to MySQL format. */
-# define row_sel_store_mysql_field(m,p,r,i,o,f,t) \
- row_sel_store_mysql_field_func(m,p,r,i,o,f,t)
+# define row_sel_store_mysql_field(m,p,r,i,o,f,t,c) \
+ row_sel_store_mysql_field_func(m,p,r,i,o,f,t,c)
#else /* UNIV_DEBUG */
/** Convert a field from Innobase format to MySQL format. */
-# define row_sel_store_mysql_field(m,p,r,i,o,f,t) \
- row_sel_store_mysql_field_func(m,p,r,o,f,t)
+# define row_sel_store_mysql_field(m,p,r,i,o,f,t,c) \
+ row_sel_store_mysql_field_func(m,p,r,o,f,t,c)
#endif /* UNIV_DEBUG */
-/**************************************************************//**
-Convert a field in the Innobase format to a field in the MySQL format. */
+/** Convert a field in the Innobase format to a field in the MySQL format.
+@param[out] mysql_rec record in the MySQL format
+@param[in,out] prebuilt prebuilt struct
+@param[in] rec InnoDB record; must be protected
+ by a page latch
+@param[in] index index of rec
+@param[in] offsets array returned by rec_get_offsets()
+@param[in] field_no templ->rec_field_no or
+ templ->clust_rec_field_no
+ or templ->icp_rec_field_no
+ or sec field no if clust_templ_for_sec
+ is TRUE
+@param[in] templ row template
+@param[in] clust_templ_for_sec TRUE if rec belongs to secondary index
+ but prebuilt template is in clustered
+ index format and used only for end
+ range comparison. */
static MY_ATTRIBUTE((warn_unused_result))
ibool
row_sel_store_mysql_field_func(
-/*===========================*/
- byte* mysql_rec, /*!< out: record in the
- MySQL format */
- row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct */
- const rec_t* rec, /*!< in: InnoDB record;
- must be protected by
- a page latch */
+ byte* mysql_rec,
+ row_prebuilt_t* prebuilt,
+ const rec_t* rec,
#ifdef UNIV_DEBUG
- const dict_index_t* index, /*!< in: index of rec */
+ const dict_index_t* index,
#endif
- const ulint* offsets, /*!< in: array returned by
- rec_get_offsets() */
- ulint field_no, /*!< in: templ->rec_field_no or
- templ->clust_rec_field_no or
- templ->icp_rec_field_no */
- const mysql_row_templ_t*templ) /*!< in: row template */
+ const ulint* offsets,
+ ulint field_no,
+ const mysql_row_templ_t*templ,
+ bool clust_templ_for_sec)
{
const byte* data;
ulint len;
@@ -2779,10 +2791,12 @@ row_sel_store_mysql_field_func(
ut_ad(templ);
ut_ad(templ >= prebuilt->mysql_template);
ut_ad(templ < &prebuilt->mysql_template[prebuilt->n_template]);
- ut_ad(field_no == templ->clust_rec_field_no
+ ut_ad(clust_templ_for_sec
+ || field_no == templ->clust_rec_field_no
|| field_no == templ->rec_field_no
|| field_no == templ->icp_rec_field_no);
- ut_ad(rec_offs_validate(rec, index, offsets));
+ ut_ad(rec_offs_validate(rec,
+ clust_templ_for_sec == true ? prebuilt->index : index, offsets));
if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
@@ -2896,30 +2910,37 @@ row_sel_store_mysql_field_func(
return(TRUE);
}
-/**************************************************************//**
-Convert a row in the Innobase format to a row in the MySQL format.
+/** Convert a row in the Innobase format to a row in the MySQL format.
Note that the template in prebuilt may advise us to copy only a few
columns to mysql_rec, other columns are left blank. All columns may not
be needed in the query.
+@param[out] mysql_rec row in the MySQL format
+@param[in] prebuilt prebuilt structure
+@param[in] rec Innobase record in the index
+ which was described in prebuilt's
+ template, or in the clustered index;
+ must be protected by a page latch
+@param[in] rec_clust TRUE if the rec in the clustered index
+@param[in] index index of rec
+@param[in] offsets array returned by rec_get_offsets(rec)
+@param[in] clust_templ_for_sec TRUE if rec belongs to secondary index
+ but the prebuilt->template is in
+ clustered index format and it is
+ used only for end range comparison
@return TRUE on success, FALSE if not all columns could be retrieved */
static MY_ATTRIBUTE((warn_unused_result))
ibool
row_sel_store_mysql_rec(
-/*====================*/
- byte* mysql_rec, /*!< out: row in the MySQL format */
- row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
- const rec_t* rec, /*!< in: Innobase record in the index
- which was described in prebuilt's
- template, or in the clustered index;
- must be protected by a page latch */
- ibool rec_clust, /*!< in: TRUE if rec is in the
- clustered index instead of
- prebuilt->index */
- const dict_index_t* index, /*!< in: index of rec */
- const ulint* offsets) /*!< in: array returned by
- rec_get_offsets(rec) */
+ byte* mysql_rec,
+ row_prebuilt_t* prebuilt,
+ const rec_t* rec,
+ ibool rec_clust,
+ const dict_index_t* index,
+ const ulint* offsets,
+ bool clust_templ_for_sec)
{
- ulint i;
+ ulint i;
+ std::vector<ulint> template_col;
ut_ad(rec_clust || index == prebuilt->index);
ut_ad(!rec_clust || dict_index_is_clust(index));
@@ -2929,9 +2950,20 @@ row_sel_store_mysql_rec(
prebuilt->blob_heap = NULL;
}
+ if (clust_templ_for_sec) {
+ /* Store all clustered index field of
+ secondary index record. */
+ for (i = 0; i < dict_index_get_n_fields(
+ prebuilt->index); i++) {
+ ulint sec_field = dict_index_get_nth_field_pos(
+ index, prebuilt->index, i);
+ template_col.push_back(sec_field);
+ }
+ }
+
for (i = 0; i < prebuilt->n_template; i++) {
const mysql_row_templ_t*templ = &prebuilt->mysql_template[i];
- const ulint field_no
+ ulint field_no
= rec_clust
? templ->clust_rec_field_no
: templ->rec_field_no;
@@ -2940,9 +2972,24 @@ row_sel_store_mysql_rec(
ut_ad(dict_index_get_nth_field(index, field_no)->prefix_len
== 0);
+ if (clust_templ_for_sec) {
+ std::vector<ulint>::iterator it;
+ it = std::find(template_col.begin(),
+ template_col.end(), field_no);
+
+ if (it == template_col.end()) {
+ continue;
+ }
+
+ ut_ad(templ->rec_field_no == templ->clust_rec_field_no);
+
+ field_no = it - template_col.begin();
+ }
+
if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
rec, index, offsets,
- field_no, templ)) {
+ field_no, templ,
+ clust_templ_for_sec)) {
return(FALSE);
}
}
@@ -3582,7 +3629,7 @@ row_search_idx_cond_check(
if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
rec, prebuilt->index, offsets,
templ->icp_rec_field_no,
- templ)) {
+ templ, false)) {
return(ICP_NO_MATCH);
}
}
@@ -3603,7 +3650,7 @@ row_search_idx_cond_check(
|| dict_index_is_clust(prebuilt->index)) {
if (!row_sel_store_mysql_rec(
mysql_rec, prebuilt, rec, FALSE,
- prebuilt->index, offsets)) {
+ prebuilt->index, offsets, false)) {
ut_ad(dict_index_is_clust(prebuilt->index));
return(ICP_NO_MATCH);
}
@@ -3622,6 +3669,27 @@ row_search_idx_cond_check(
return(result);
}
+/** Check the pushed down end range condition to avoid extra traversal
+if records are not within view and also to avoid prefetching in the
+cache buffer.
+@param[in] mysql_rec record in MySQL format
+@param[in,out] handler the MySQL handler performing the scan
+@retval true if the row in mysql_rec is out of range
+@retval false if the row in mysql_rec is in range */
+static
+bool
+row_search_end_range_check(
+ const byte* mysql_rec,
+ ha_innobase* handler)
+{
+ if (handler->end_range &&
+ handler->compare_key_in_buffer(mysql_rec) > 0) {
+ return(true);
+ }
+
+ return(false);
+}
+
/********************************************************************//**
Searches for rows in the database. This is used in the interface to
MySQL. This function opens a cursor, and also implements fetch next
@@ -3659,7 +3727,9 @@ row_search_for_mysql(
trx_t* trx = prebuilt->trx;
dict_index_t* clust_index;
que_thr_t* thr;
- const rec_t* rec;
+ const rec_t* prev_rec = NULL;
+ const rec_t* rec = NULL;
+ byte* end_range_cache = NULL;
const rec_t* result_rec = NULL;
const rec_t* clust_rec;
dberr_t err = DB_SUCCESS;
@@ -3684,6 +3754,7 @@ row_search_for_mysql(
ulint* offsets = offsets_;
ibool table_lock_waited = FALSE;
byte* next_buf = 0;
+ ulint end_loop = 0;
rec_offs_init(offsets_);
@@ -3823,6 +3894,10 @@ row_search_for_mysql(
err = DB_SUCCESS;
goto func_exit;
+ } else if (prebuilt->end_range == true) {
+ prebuilt->end_range = false;
+ err = DB_RECORD_NOT_FOUND;
+ goto func_exit;
}
if (prebuilt->fetch_cache_first > 0
@@ -3956,7 +4031,8 @@ row_search_for_mysql(
if (!row_sel_store_mysql_rec(
buf, prebuilt,
- rec, FALSE, index, offsets)) {
+ rec, FALSE, index,
+ offsets, false)) {
/* Only fresh inserts may contain
incomplete externally stored
columns. Pretend that such
@@ -4205,11 +4281,62 @@ rec_loop:
and neither can a record lock be placed on it: we skip such
a record. */
+ prev_rec = NULL;
goto next_rec;
}
if (page_rec_is_supremum(rec)) {
+ /** Compare the last record of the page with end range
+ passed to InnoDB when there is no ICP and number of loops
+ in row_search_for_mysql for rows found but not
+ reporting due to search views etc. */
+ if (prev_rec != NULL
+ && prebuilt->mysql_handler->end_range != NULL
+ && prebuilt->idx_cond == NULL
+ && end_loop >= 100) {
+
+ dict_index_t* key_index = prebuilt->index;
+ bool clust_templ_for_sec = false;
+
+ if (end_range_cache == NULL) {
+ end_range_cache = static_cast<byte*>(
+ ut_malloc(prebuilt->mysql_row_len));
+ }
+
+ if (index != clust_index
+ && prebuilt->need_to_access_clustered) {
+ /** Secondary index record but the template
+ based on PK. */
+ key_index = clust_index;
+ clust_templ_for_sec = true;
+ }
+
+ /** Create offsets based on prebuilt index. */
+ offsets = rec_get_offsets(prev_rec, prebuilt->index,
+ offsets, ULINT_UNDEFINED, &heap);
+
+ if (row_sel_store_mysql_rec(
+ end_range_cache, prebuilt, prev_rec,
+ clust_templ_for_sec, key_index, offsets,
+ clust_templ_for_sec)) {
+
+ if (row_search_end_range_check(
+ end_range_cache,
+ prebuilt->mysql_handler)) {
+
+ /** In case of prebuilt->fetch,
+ set the error in prebuilt->end_range. */
+ if (prebuilt->n_fetch_cached > 0) {
+ prebuilt->end_range = true;
+ }
+
+ err = DB_RECORD_NOT_FOUND;
+ goto normal_return;
+ }
+ }
+ }
+
if (set_also_gap_locks
&& !(srv_locks_unsafe_for_binlog
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED)
@@ -4241,6 +4368,7 @@ rec_loop:
/* A page supremum record cannot be in the result set: skip
it now that we have placed a possible lock on it */
+ prev_rec = NULL;
goto next_rec;
}
@@ -4308,6 +4436,7 @@ wrong_offs:
btr_pcur_move_to_last_on_page(pcur, &mtr);
+ prev_rec = NULL;
goto next_rec;
}
}
@@ -4334,10 +4463,13 @@ wrong_offs:
fputs(". We try to skip the record.\n",
stderr);
+ prev_rec = NULL;
goto next_rec;
}
}
+ prev_rec = rec;
+
/* Note that we cannot trust the up_match value in the cursor at this
place because we can arrive here after moving the cursor! Thus
we have to recompare rec and search_tuple to determine if they
@@ -4562,6 +4694,7 @@ no_gap_lock:
did_semi_consistent_read = TRUE;
rec = old_vers;
+ prev_rec = rec;
break;
default:
@@ -4608,6 +4741,7 @@ no_gap_lock:
}
rec = old_vers;
+ prev_rec = rec;
}
} else {
/* We are looking into a non-clustered index,
@@ -4785,7 +4919,7 @@ requires_clust_rec:
appropriate version of the clustered index record. */
if (!row_sel_store_mysql_rec(
buf, prebuilt, result_rec,
- TRUE, clust_index, offsets)) {
+ TRUE, clust_index, offsets, false)) {
goto next_rec;
}
}
@@ -4853,7 +4987,7 @@ requires_clust_rec:
next_buf, prebuilt, result_rec,
result_rec != rec,
result_rec != rec ? clust_index : index,
- offsets)) {
+ offsets, false)) {
if (next_buf == buf) {
ut_a(prebuilt->n_fetch_cached == 0);
@@ -4908,7 +5042,7 @@ requires_clust_rec:
buf, prebuilt, result_rec,
result_rec != rec,
result_rec != rec ? clust_index : index,
- offsets)) {
+ offsets, false)) {
/* Only fresh inserts may contain
incomplete externally stored
columns. Pretend that such records do
@@ -4960,6 +5094,8 @@ idx_cond_failed:
goto normal_return;
next_rec:
+ end_loop++;
+
/* Reset the old and new "did semi-consistent read" flags. */
if (UNIV_UNLIKELY(prebuilt->row_read_type
== ROW_READ_DID_SEMI_CONSISTENT)) {
@@ -5146,6 +5282,11 @@ normal_return:
func_exit:
trx->op_info = "";
+
+ if (end_range_cache != NULL) {
+ ut_free(end_range_cache);
+ }
+
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index a67f3a776c5..173577740f8 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
@@ -2315,6 +2315,8 @@ DECLARE_THREAD(srv_master_thread)(
/*!< in: a dummy parameter required by
os_thread_create */
{
+ my_thread_init();
+
srv_slot_t* slot;
ulint old_activity_count = srv_get_activity_count();
ib_time_t last_print_time;
@@ -2376,6 +2378,7 @@ suspend_thread:
os_event_wait(slot->event);
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ my_thread_end();
os_thread_exit(NULL);
}
@@ -2458,6 +2461,8 @@ DECLARE_THREAD(srv_worker_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */
{
+ my_thread_init();
+
srv_slot_t* slot;
ut_ad(!srv_read_only_mode);
@@ -2516,6 +2521,7 @@ DECLARE_THREAD(srv_worker_thread)(
os_thread_pf(os_thread_get_curr_id()));
#endif /* UNIV_DEBUG_THREAD_CREATION */
+ my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
@@ -2716,6 +2722,8 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */
{
+ my_thread_init();
+
srv_slot_t* slot;
ulint n_total_purged = ULINT_UNDEFINED;
@@ -2821,6 +2829,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
srv_release_threads(SRV_WORKER, srv_n_purge_threads - 1);
}
+ my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
@@ -2889,3 +2898,18 @@ srv_purge_wakeup(void)
}
}
+/** Check whether given space id is undo tablespace id
+@param[in] space_id space id to check
+@return true if it is undo tablespace else false. */
+bool
+srv_is_undo_tablespace(
+ ulint space_id)
+{
+ if (srv_undo_space_id_start == 0) {
+ return (false);
+ }
+
+ return(space_id >= srv_undo_space_id_start
+ && space_id < (srv_undo_space_id_start
+ + srv_undo_tablespaces_open));
+}
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 697107a1e0d..f6b68a73b74 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
@@ -109,6 +109,9 @@ UNIV_INTERN ibool srv_have_fullfsync = FALSE;
/** TRUE if a raw partition is in use */
UNIV_INTERN ibool srv_start_raw_disk_in_use = FALSE;
+/** UNDO tablespaces starts with space id. */
+ulint srv_undo_space_id_start;
+
/** TRUE if the server is being started, before rolling back any
incomplete transactions */
UNIV_INTERN ibool srv_startup_is_before_trx_rollback_phase = FALSE;
@@ -124,7 +127,7 @@ SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE;
/** Files comprising the system tablespace */
-static os_file_t files[1000];
+static pfs_os_file_t files[1000];
/** io_handler_thread parameters for thread identification */
static ulint n[SRV_MAX_N_IO_THREADS + 6];
@@ -530,7 +533,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
create_log_file(
/*============*/
- os_file_t* file, /*!< out: file handle */
+ pfs_os_file_t* file, /*!< out: file handle */
const char* name) /*!< in: log file name */
{
ibool ret;
@@ -737,7 +740,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
open_log_file(
/*==========*/
- os_file_t* file, /*!< out: file handle */
+ pfs_os_file_t* file, /*!< out: file handle */
const char* name, /*!< in: log file name */
os_offset_t* size) /*!< out: file size */
{
@@ -853,7 +856,7 @@ open_or_create_data_files(
&& os_file_get_last_error(false)
!= OS_FILE_ALREADY_EXISTS
#ifdef UNIV_AIX
- /* AIX 5.1 after security patch ML7 may have
+ /* AIX 5.1 after security patch ML7 may have
errno set to 0 here, which causes our
function to return 100; work around that
AIX problem */
@@ -1156,7 +1159,7 @@ srv_undo_tablespace_create(
const char* name, /*!< in: tablespace name */
ulint size) /*!< in: tablespace size in pages */
{
- os_file_t fh;
+ pfs_os_file_t fh;
ibool ret;
dberr_t err = DB_SUCCESS;
@@ -1233,7 +1236,7 @@ srv_undo_tablespace_open(
const char* name, /*!< in: tablespace name */
ulint space) /*!< in: tablespace id */
{
- os_file_t fh;
+ pfs_os_file_t fh;
dberr_t err = DB_ERROR;
ibool ret;
ulint flags;
@@ -1332,13 +1335,23 @@ srv_undo_tablespaces_init(
for (i = 0; create_new_db && i < n_conf_tablespaces; ++i) {
char name[OS_FILE_MAX_PATH];
+ ulint space_id = i + 1;
+
+ DBUG_EXECUTE_IF("innodb_undo_upgrade",
+ space_id = i + 3;);
ut_snprintf(
name, sizeof(name),
"%s%cundo%03lu",
- srv_undo_dir, SRV_PATH_SEPARATOR, i + 1);
+ srv_undo_dir, SRV_PATH_SEPARATOR, space_id);
+
+ if (i == 0) {
+ srv_undo_space_id_start = space_id;
+ prev_space_id = srv_undo_space_id_start - 1;
+ }
+
+ undo_tablespace_ids[i] = space_id;
- /* Undo space ids start from 1. */
err = srv_undo_tablespace_create(
name, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES);
@@ -1360,14 +1373,16 @@ srv_undo_tablespaces_init(
if (!create_new_db) {
n_undo_tablespaces = trx_rseg_get_n_undo_tablespaces(
undo_tablespace_ids);
- } else {
- n_undo_tablespaces = n_conf_tablespaces;
- for (i = 1; i <= n_undo_tablespaces; ++i) {
- undo_tablespace_ids[i - 1] = i;
+ if (n_undo_tablespaces != 0) {
+ srv_undo_space_id_start = undo_tablespace_ids[0];
+ prev_space_id = srv_undo_space_id_start - 1;
}
- undo_tablespace_ids[i] = ULINT_UNDEFINED;
+ } else {
+ n_undo_tablespaces = n_conf_tablespaces;
+
+ undo_tablespace_ids[n_conf_tablespaces] = ULINT_UNDEFINED;
}
/* Open all the undo tablespaces that are currently in use. If we
@@ -1391,8 +1406,6 @@ srv_undo_tablespaces_init(
ut_a(undo_tablespace_ids[i] != 0);
ut_a(undo_tablespace_ids[i] != ULINT_UNDEFINED);
- /* Undo space ids start from 1. */
-
err = srv_undo_tablespace_open(name, undo_tablespace_ids[i]);
if (err != DB_SUCCESS) {
@@ -1427,11 +1440,23 @@ srv_undo_tablespaces_init(
break;
}
+ /** Note the first undo tablespace id in case of
+ no active undo tablespace. */
+ if (n_undo_tablespaces == 0) {
+ srv_undo_space_id_start = i;
+ }
+
++n_undo_tablespaces;
++*n_opened;
}
+ /** Explictly specify the srv_undo_space_id_start
+ as zero when there are no undo tablespaces. */
+ if (n_undo_tablespaces == 0) {
+ srv_undo_space_id_start = 0;
+ }
+
/* If the user says that there are fewer than what we find we
tolerate that discrepancy but not the inverse. Because there could
be unused undo tablespaces for future use. */
@@ -1476,10 +1501,11 @@ srv_undo_tablespaces_init(
mtr_start(&mtr);
/* The undo log tablespace */
- for (i = 1; i <= n_undo_tablespaces; ++i) {
+ for (i = 0; i < n_undo_tablespaces; ++i) {
fsp_header_init(
- i, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
+ undo_tablespace_ids[i],
+ SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
}
mtr_commit(&mtr);
@@ -1554,6 +1580,10 @@ innobase_start_or_create_for_mysql(void)
char* logfile0 = NULL;
size_t dirnamelen;
+ if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) {
+ srv_read_only_mode = 1;
+ }
+
high_level_read_only = srv_read_only_mode
|| srv_force_recovery > SRV_FORCE_NO_TRX_UNDO;
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index efc600d16b1..55af54991c6 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -692,7 +692,8 @@ trx_purge_get_rseg_with_min_trx_id(
/* We assume in purge of externally stored fields that space id is
in the range of UNDO tablespace space ids */
- ut_a(purge_sys->rseg->space <= srv_undo_tablespaces_open);
+ ut_a(purge_sys->rseg->space == 0
+ || srv_is_undo_tablespace(purge_sys->rseg->space));
zip_size = purge_sys->rseg->zip_size;
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index e1e253cbb76..09e8e018c4f 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -800,6 +800,7 @@ DECLARE_THREAD(trx_rollback_or_clean_all_recovered)(
/*!< in: a dummy parameter required by
os_thread_create */
{
+ my_thread_init();
ut_ad(!srv_read_only_mode);
#ifdef UNIV_PFS_THREAD
@@ -810,6 +811,7 @@ DECLARE_THREAD(trx_rollback_or_clean_all_recovered)(
trx_rollback_or_clean_is_active = false;
+ my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index e5f03f4b96a..00d79e7ff51 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -909,18 +909,12 @@ trx_sys_create_rsegs(
ulint new_rsegs = n_rsegs - n_used;
for (i = 0; i < new_rsegs; ++i) {
- ulint space;
+ ulint space_id;
+ space_id = (n_spaces == 0) ? 0
+ : (srv_undo_space_id_start + i % n_spaces);
- /* Tablespace 0 is the system tablespace. All UNDO
- log tablespaces start from 1. */
-
- if (n_spaces > 0) {
- space = (i % n_spaces) + 1;
- } else {
- space = 0; /* System tablespace */
- }
-
- if (trx_rseg_create(space) != NULL) {
+ /* Tablespace 0 is the system tablespace. */
+ if (trx_rseg_create(space_id) != NULL) {
++n_used;
} else {
break;