Merge branch 'merge-innodb-5.6' into bb-10.0-vicentiu

This merge reverts commit 6ca4f693c1ce472e2b1bf7392607c2d1124b4293
from current 5.6.36 innodb.

Bug #23481444	OPTIMISER CALL ROW_SEARCH_MVCC() AND READ THE
                       INDEX APPLIED BY UNCOMMITTED ROW
Problem:
========
row_search_for_mysql() does whole table traversal for range query
even though the end range is passed. Whole table traversal happens
when the record is not with in transaction read view.

Solution:
=========

Convert the innodb last record of page to mysql format and compare
with end range if the traversal of row_search_mvcc() exceeds 100,
no ICP involved. If it is out of range then InnoDB can avoid the
whole table traversal. Need to refactor the code little bit to
make it compile.

Reviewed-by: Jimmy Yang <jimmy.yang@oracle.com>
Reviewed-by: Knut Hatlen <knut.hatlen@oracle.com>
Reviewed-by: Dmitry Shulga <dmitry.shulga@oracle.com>
RB: 14660
This commit is contained in:
Vicențiu Ciorbaru 2017-05-17 14:53:28 +03:00
commit b87873b221
30 changed files with 505 additions and 272 deletions

View File

@ -175,7 +175,7 @@ btr_search_sys_create(
btr_search_sys = (btr_search_sys_t*) btr_search_sys = (btr_search_sys_t*)
mem_alloc(sizeof(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); MEM_HEAP_FOR_BTR_SEARCH, 0);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
btr_search_sys->hash_index->adaptive = TRUE; btr_search_sys->hash_index->adaptive = TRUE;

View File

@ -1366,7 +1366,7 @@ buf_pool_init_instance(
ut_a(srv_n_page_hash_locks != 0); ut_a(srv_n_page_hash_locks != 0);
ut_a(srv_n_page_hash_locks <= MAX_PAGE_HASH_LOCKS); 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, srv_n_page_hash_locks,
MEM_HEAP_FOR_PAGE_HASH, MEM_HEAP_FOR_PAGE_HASH,
SYNC_BUF_PAGE_HASH); SYNC_BUF_PAGE_HASH);

View File

@ -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 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 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 void
buf_dblwr_init_or_load_pages( buf_dblwr_init_or_load_pages(
/*=========================*/ /*=========================*/
os_file_t file, pfs_os_file_t file,
char* path, char* path,
bool load_corrupt_pages) bool load_corrupt_pages)
{ {

View File

@ -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.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
@ -680,6 +680,7 @@ DECLARE_THREAD(buf_dump_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */ required by os_thread_create */
{ {
my_thread_init();
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
srv_buf_dump_thread_active = TRUE; srv_buf_dump_thread_active = TRUE;
@ -718,6 +719,7 @@ DECLARE_THREAD(buf_dump_thread)(
srv_buf_dump_thread_active = FALSE; srv_buf_dump_thread_active = FALSE;
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created /* 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. */ thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL); os_thread_exit(NULL);

View File

@ -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) 2017, MariaDB Corporation. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
@ -2406,6 +2406,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
/*!< in: a dummy parameter required by /*!< in: a dummy parameter required by
os_thread_create */ os_thread_create */
{ {
my_thread_init();
ulint next_loop_time = ut_time_ms() + 1000; ulint next_loop_time = ut_time_ms() + 1000;
ulint n_flushed = 0; ulint n_flushed = 0;
ulint last_activity = srv_get_activity_count(); ulint last_activity = srv_get_activity_count();
@ -2518,6 +2519,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
thread_exit: thread_exit:
buf_page_cleaner_is_active = FALSE; buf_page_cleaner_is_active = FALSE;
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created /* 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. */ thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL); os_thread_exit(NULL);

View File

@ -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 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 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; 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, ib_logf(IB_LOG_LEVEL_ERROR,
"Change buffer must be empty when --innodb-read-only " "Change buffer must be empty when --innodb-read-only "

View File

@ -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 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 the terms of the GNU General Public License as published by the Free Software
@ -1110,10 +1110,10 @@ dict_stats_analyze_index_level(
leaf-level delete marks because delete marks on leaf-level delete marks because delete marks on
non-leaf level do not make sense. */ 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_get_deleted_flag(
rec, rec,
page_is_comp(btr_pcur_get_page(&pcur)))) { page_is_comp(btr_pcur_get_page(&pcur))))) {
if (rec_is_last_on_page if (rec_is_last_on_page
&& !prev_rec_is_copied && !prev_rec_is_copied

View File

@ -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.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
@ -346,6 +346,7 @@ DECLARE_THREAD(dict_stats_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */ required by os_thread_create */
{ {
my_thread_init();
ut_a(!srv_read_only_mode); ut_a(!srv_read_only_mode);
srv_dict_stats_thread_active = TRUE; srv_dict_stats_thread_active = TRUE;
@ -371,6 +372,7 @@ DECLARE_THREAD(dict_stats_thread)(
srv_dict_stats_thread_active = FALSE; srv_dict_stats_thread_active = FALSE;
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created /* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit instead of return(). */ thread should always use that to exit instead of return(). */
os_thread_exit(NULL); os_thread_exit(NULL);

View File

@ -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) 2014, 2017, MariaDB Corporation. All Rights Reserved. Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
@ -148,7 +148,8 @@ initialized. */
fil_system_t* fil_system = NULL; fil_system_t* fil_system = NULL;
/** Determine if (i) is a user tablespace id or not. */ /** 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(). */ /** Determine if user has explicitly disabled fsync(). */
#ifndef __WIN__ #ifndef __WIN__
@ -1879,7 +1880,7 @@ UNIV_INTERN
const char* const char*
fil_read_first_page( 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 ibool one_read_already, /*!< in: TRUE if min and max
parameters below already parameters below already
contain sensible data */ contain sensible data */
@ -3214,7 +3215,7 @@ fil_open_linked_file(
/*===============*/ /*===============*/
const char* tablename, /*!< in: database/tablename */ const char* tablename, /*!< in: database/tablename */
char** remote_filepath,/*!< out: remote filepath */ 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; ibool success;
@ -3274,7 +3275,8 @@ fil_create_new_single_table_tablespace(
tablespace file in pages, tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */ must be >= FIL_IBD_FILE_INITIAL_SIZE */
{ {
os_file_t file; pfs_os_file_t file;
ibool ret; ibool ret;
dberr_t err; dberr_t err;
byte* buf2; byte* buf2;
@ -5025,7 +5027,7 @@ retry:
int err; int err;
do { do {
err = posix_fallocate(node->handle, start_offset, len); err = posix_fallocate(node->handle.m_file, start_offset, len);
} while (err == EINTR } while (err == EINTR
&& srv_shutdown_state == SRV_SHUTDOWN_NONE); && srv_shutdown_state == SRV_SHUTDOWN_NONE);
@ -5775,7 +5777,7 @@ fil_flush(
{ {
fil_space_t* space; fil_space_t* space;
fil_node_t* node; fil_node_t* node;
os_file_t file; pfs_os_file_t file;
mutex_enter(&fil_system->mutex); mutex_enter(&fil_system->mutex);
@ -6137,7 +6139,7 @@ fil_buf_block_init(
} }
struct fil_iterator_t { struct fil_iterator_t {
os_file_t file; /*!< File handle */ pfs_os_file_t file; /*!< File handle */
const char* filepath; /*!< File path name */ const char* filepath; /*!< File path name */
os_offset_t start; /*!< From where to start */ os_offset_t start; /*!< From where to start */
os_offset_t end; /*!< Where to stop */ os_offset_t end; /*!< Where to stop */
@ -6272,7 +6274,7 @@ fil_tablespace_iterate(
PageCallback& callback) PageCallback& callback)
{ {
dberr_t err; dberr_t err;
os_file_t file; pfs_os_file_t file;
char* filepath; char* filepath;
ut_a(n_io_buffers > 0); ut_a(n_io_buffers > 0);

View File

@ -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) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc. Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
@ -10718,7 +10718,8 @@ ha_innobase::delete_table(
extension, in contrast to ::create */ extension, in contrast to ::create */
normalize_table_name(norm_name, name); 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); DBUG_RETURN(HA_ERR_TABLE_READONLY);
} else if (row_is_magic_monitor_table(norm_name) } else if (row_is_magic_monitor_table(norm_name)
&& check_global_access(thd, PROCESS_ACL)) { && check_global_access(thd, PROCESS_ACL)) {

View File

@ -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.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
@ -56,7 +56,7 @@ recovery, this function loads the pages from double write buffer into memory. */
void void
buf_dblwr_init_or_load_pages( buf_dblwr_init_or_load_pages(
/*=========================*/ /*=========================*/
os_file_t file, pfs_os_file_t file,
char* path, char* path,
bool load_corrupt_pages); bool load_corrupt_pages);

View File

@ -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) 2017, MariaDB Corporation. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
@ -187,7 +187,7 @@ struct fsp_open_info {
ibool success; /*!< Has the tablespace been opened? */ ibool success; /*!< Has the tablespace been opened? */
const char* check_msg; /*!< fil_check_first_page() message */ const char* check_msg; /*!< fil_check_first_page() message */
ibool valid; /*!< Is the tablespace valid? */ 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 */ char* filepath; /*!< File path to open */
lsn_t lsn; /*!< Flushed LSN from header page */ lsn_t lsn; /*!< Flushed LSN from header page */
ulint id; /*!< Space ID */ ulint id; /*!< Space ID */
@ -205,7 +205,7 @@ struct fil_node_t {
belongs */ belongs */
char* name; /*!< path to the file */ char* name; /*!< path to the file */
ibool open; /*!< TRUE if file open */ 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 os_event_t sync_event;/*!< Condition event to group and
serialize calls to fsync; serialize calls to fsync;
os_event_set() and os_event_reset() os_event_set() and os_event_reset()
@ -569,7 +569,7 @@ UNIV_INTERN
const char* const char*
fil_read_first_page( 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 ibool one_read_already, /*!< in: TRUE if min and max
parameters below already parameters below already
contain sensible data */ contain sensible data */
@ -1087,12 +1087,12 @@ struct PageCallback {
Called for every page in the tablespace. If the page was not 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 updated then its state must be set to BUF_PAGE_NOT_USED. For
compressed tables the page descriptor memory will be at offset: 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 offset - physical offset within the file
@param block - block read from file, note it is not from the buffer pool @param block - block read from file, note it is not from the buffer pool
@retval DB_SUCCESS or error code. */ @retval DB_SUCCESS or error code. */
virtual dberr_t operator()( virtual dberr_t operator()(
os_offset_t offset, os_offset_t offset,
buf_block_t* block) UNIV_NOTHROW = 0; buf_block_t* block) UNIV_NOTHROW = 0;
/** /**
@ -1100,7 +1100,7 @@ struct PageCallback {
to open it for the file that is being iterated over. to open it for the file that is being iterated over.
@param filename - then physical name of the tablespace file. @param filename - then physical name of the tablespace file.
@param file - OS file handle */ @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_file = file;
m_filepath = filename; m_filepath = filename;
@ -1136,7 +1136,7 @@ struct PageCallback {
ulint m_page_size; ulint m_page_size;
/** File handle to the tablespace */ /** File handle to the tablespace */
os_file_t m_file; pfs_os_file_t m_file;
/** Physical file path. */ /** Physical file path. */
const char* m_filepath; const char* m_filepath;

View File

@ -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 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 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 level in: level of the mutexes in the latching order
@param n_m in: number of mutexes to protect the hash table; @param n_m in: number of mutexes to protect the hash table;
must be a power of 2, or 0 */ 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 */ #else /* UNIV_SYNC_DEBUG */
/** Creates a hash table. /** Creates a hash table.
@return own: created 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 level in: level of the mutexes in the latching order
@param n_m in: number of mutexes to protect the hash table; @param n_m in: number of mutexes to protect the hash table;
must be a power of 2, or 0 */ 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 */ #endif /* UNIV_SYNC_DEBUG */
/*************************************************************//** /*************************************************************//**

View File

@ -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. Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation. Copyright (c) 2013, 2017, MariaDB Corporation.
@ -80,6 +80,16 @@ typedef int os_file_t;
# define OS_FILE_FROM_FD(fd) fd # define OS_FILE_FROM_FD(fd) fd
#endif #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 */ /** Umask for creating files */
extern ulint os_innodb_umask; extern ulint os_innodb_umask;
@ -208,6 +218,8 @@ extern mysql_pfs_key_t innodb_file_temp_key;
various file I/O operations with performance schema. various file I/O operations with performance schema.
1) register_pfs_file_open_begin() and register_pfs_file_open_end() are 1) register_pfs_file_open_begin() and register_pfs_file_open_end() are
used to register file creation, opening, closing and renaming. 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 2) register_pfs_file_io_begin() and register_pfs_file_io_end() are
used to register actual file read, write and flush used to register actual file read, write and flush
3) register_pfs_file_close_begin() and register_pfs_file_close_end() 3) register_pfs_file_close_begin() and register_pfs_file_close_end()
@ -217,17 +229,30 @@ are used to register file deletion operations*/
do { \ do { \
locker = PSI_FILE_CALL(get_thread_file_name_locker)( \ locker = PSI_FILE_CALL(get_thread_file_name_locker)( \
state, key, op, name, &locker); \ state, key, op, name, &locker); \
if (UNIV_LIKELY(locker != NULL)) { \ if (locker != NULL) { \
PSI_FILE_CALL(start_file_open_wait)( \ PSI_FILE_CALL(start_file_open_wait)( \
locker, src_file, src_line); \ locker, src_file, src_line); \
} \ } \
} while (0) } while (0)
# define register_pfs_file_open_end(locker, file) \ # define register_pfs_file_open_end(locker, file, result) \
do { \ do { \
if (UNIV_LIKELY(locker != NULL)) { \ if (locker != NULL) { \
PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(\ file.m_psi = PSI_FILE_CALL( \
locker, file); \ 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) } while (0)
@ -253,9 +278,9 @@ do { \
# define register_pfs_file_io_begin(state, locker, file, count, op, \ # define register_pfs_file_io_begin(state, locker, file, count, op, \
src_file, src_line) \ src_file, src_line) \
do { \ do { \
locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)( \ locker = PSI_FILE_CALL(get_thread_file_stream_locker)( \
state, file, op); \ state, file.m_psi, op); \
if (UNIV_LIKELY(locker != NULL)) { \ if (locker != NULL) { \
PSI_FILE_CALL(start_file_wait)( \ PSI_FILE_CALL(start_file_wait)( \
locker, count, src_file, src_line); \ locker, count, src_file, src_line); \
} \ } \
@ -263,7 +288,7 @@ do { \
# define register_pfs_file_io_end(locker, count) \ # define register_pfs_file_io_end(locker, count) \
do { \ do { \
if (UNIV_LIKELY(locker != NULL)) { \ if (locker != NULL) { \
PSI_FILE_CALL(end_file_wait)(locker, count); \ PSI_FILE_CALL(end_file_wait)(locker, count); \
} \ } \
} while (0) } while (0)
@ -281,7 +306,9 @@ os_file_rename
os_aio os_aio
os_file_read os_file_read
os_file_read_no_error_handling os_file_read_no_error_handling
os_file_read_no_error_handling_int_fd
os_file_write os_file_write
os_file_write_int_fd
The wrapper functions have the prefix of "innodb_". */ The wrapper functions have the prefix of "innodb_". */
@ -299,7 +326,7 @@ The wrapper functions have the prefix of "innodb_". */
pfs_os_file_create_simple_no_error_handling_func( \ pfs_os_file_create_simple_no_error_handling_func( \
key, name, create_mode, access, success, __FILE__, __LINE__) 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__) pfs_os_file_close_func(file, __FILE__, __LINE__)
# define os_aio(type, mode, name, file, buf, offset, \ # define os_aio(type, mode, name, file, buf, offset, \
@ -307,18 +334,27 @@ The wrapper functions have the prefix of "innodb_". */
pfs_os_aio_func(type, mode, name, file, buf, offset, \ pfs_os_aio_func(type, mode, name, file, buf, offset, \
n, message1, message2, __FILE__, __LINE__) 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__) pfs_os_file_read_func(file, buf, offset, n, __FILE__, __LINE__)
# define os_file_read_no_error_handling(file, buf, offset, n) \ # define os_file_read_no_error_handling(file, buf, offset, n) \
pfs_os_file_read_no_error_handling_func(file, buf, offset, n, \ pfs_os_file_read_no_error_handling_func(file, buf, offset, n, \
__FILE__, __LINE__) __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, \ pfs_os_file_write_func(name, file, buf, offset, \
n, __FILE__, __LINE__) 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__) pfs_os_file_flush_func(file, __FILE__, __LINE__)
# define os_file_rename(key, oldpath, newpath) \ # define os_file_rename(key, oldpath, newpath) \
@ -344,22 +380,29 @@ to original un-instrumented file I/O APIs */
os_file_create_simple_no_error_handling_func( \ os_file_create_simple_no_error_handling_func( \
name, create_mode, access, success) 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) \ # define os_aio(type, mode, name, file, buf, offset, n, message1, message2) \
os_aio_func(type, mode, name, file, buf, offset, n, \ os_aio_func(type, mode, name, file, buf, offset, n, \
message1, message2) 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) os_file_read_func(file, buf, offset, n)
# define os_file_read_no_error_handling(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) 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) 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) \ # define os_file_rename(key, oldpath, newpath) \
os_file_rename_func(oldpath, newpath) os_file_rename_func(oldpath, newpath)
@ -371,6 +414,33 @@ to original un-instrumented file I/O APIs */
#endif /* UNIV_PFS_IO */ #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 */ /* File types for directory entry data type */
enum os_file_type_t { enum os_file_type_t {
@ -510,7 +580,7 @@ A simple function to open or create a file.
@return own: handle to the file, not defined if error, error number @return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */ can be retrieved with os_file_get_last_error */
UNIV_INTERN UNIV_INTERN
os_file_t pfs_os_file_t
os_file_create_simple_no_error_handling_func( os_file_create_simple_no_error_handling_func(
/*=========================================*/ /*=========================================*/
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
@ -540,7 +610,7 @@ Opens an existing file or creates a new.
@return own: handle to the file, not defined if error, error number @return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */ can be retrieved with os_file_get_last_error */
UNIV_INTERN UNIV_INTERN
os_file_t pfs_os_file_t
os_file_create_func( os_file_create_func(
/*================*/ /*================*/
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
@ -609,7 +679,7 @@ os_file_create_simple() which opens or creates a file.
@return own: handle to the file, not defined if error, error number @return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */ can be retrieved with os_file_get_last_error */
UNIV_INLINE UNIV_INLINE
os_file_t pfs_os_file_t
pfs_os_file_create_simple_func( pfs_os_file_create_simple_func(
/*===========================*/ /*===========================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */ mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@ -632,7 +702,7 @@ monitor file creation/open.
@return own: handle to the file, not defined if error, error number @return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */ can be retrieved with os_file_get_last_error */
UNIV_INLINE UNIV_INLINE
os_file_t pfs_os_file_t
pfs_os_file_create_simple_no_error_handling_func( pfs_os_file_create_simple_no_error_handling_func(
/*=============================================*/ /*=============================================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */ mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@ -656,7 +726,7 @@ Add instrumentation to monitor file creation/open.
@return own: handle to the file, not defined if error, error number @return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */ can be retrieved with os_file_get_last_error */
UNIV_INLINE UNIV_INLINE
os_file_t pfs_os_file_t
pfs_os_file_create_func( pfs_os_file_create_func(
/*====================*/ /*====================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */ mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@ -685,7 +755,7 @@ UNIV_INLINE
ibool ibool
pfs_os_file_close_func( 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 */ const char* src_file,/*!< in: file name where func invoked */
ulint src_line);/*!< in: line where the func invoked */ ulint src_line);/*!< in: line where the func invoked */
/*******************************************************************//** /*******************************************************************//**
@ -698,7 +768,7 @@ UNIV_INLINE
ibool ibool
pfs_os_file_read_func( 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 */ void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */ os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */ ulint n, /*!< in: number of bytes to read */
@ -716,7 +786,7 @@ UNIV_INLINE
ibool ibool
pfs_os_file_read_no_error_handling_func( 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 */ void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */ os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */ ulint n, /*!< in: number of bytes to read */
@ -737,7 +807,7 @@ pfs_os_aio_func(
ulint mode, /*!< in: OS_AIO_NORMAL etc. I/O mode */ ulint mode, /*!< in: OS_AIO_NORMAL etc. I/O mode */
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
null-terminated string */ 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 void* buf, /*!< in: buffer where to read or from which
to write */ to write */
os_offset_t offset, /*!< in: file offset where to read or write */ os_offset_t offset, /*!< in: file offset where to read or write */
@ -764,7 +834,7 @@ pfs_os_file_write_func(
/*===================*/ /*===================*/
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
null-terminated string */ 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 */ const void* buf, /*!< in: buffer from which to write */
os_offset_t offset, /*!< in: file offset where to write */ os_offset_t offset, /*!< in: file offset where to write */
ulint n, /*!< in: number of bytes to write */ ulint n, /*!< in: number of bytes to write */
@ -781,7 +851,7 @@ UNIV_INLINE
ibool ibool
pfs_os_file_flush_func( 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 */ const char* src_file,/*!< in: file name where func invoked */
ulint src_line);/*!< in: line where the func invoked */ ulint src_line);/*!< in: line where the func invoked */
@ -852,7 +922,7 @@ UNIV_INTERN
os_offset_t os_offset_t
os_file_get_size( 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)); MY_ATTRIBUTE((warn_unused_result));
/***********************************************************************//** /***********************************************************************//**
Write the specified number of zeros to a newly created file. Write the specified number of zeros to a newly created file.
@ -863,7 +933,7 @@ os_file_set_size(
/*=============*/ /*=============*/
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
null-terminated string */ 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 size) /*!< in: file size */
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/***********************************************************************//** /***********************************************************************//**
@ -1101,7 +1171,7 @@ os_aio_func(
caution! */ caution! */
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
null-terminated string */ 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 void* buf, /*!< in: buffer where to read or from which
to write */ to write */
os_offset_t offset, /*!< in: file offset where to read or write */ os_offset_t offset, /*!< in: file offset where to read or write */

View File

@ -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 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 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 @return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */ can be retrieved with os_file_get_last_error */
UNIV_INLINE UNIV_INLINE
os_file_t pfs_os_file_t
pfs_os_file_create_simple_func( pfs_os_file_create_simple_func(
/*===========================*/ /*===========================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */ 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 */ const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the 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; struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state; PSI_file_locker_state state;
@ -58,11 +58,13 @@ pfs_os_file_create_simple_func(
: PSI_FILE_OPEN), : PSI_FILE_OPEN),
name, src_file, src_line); 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); access_type, success);
file.m_psi = NULL;
/* Regsiter the returning "file" value with the system */ /* Regsiter psi value for the file */
register_pfs_file_open_end(locker, file); register_pfs_file_open_end(locker, file,
(*success == TRUE ? success : 0));
return(file); return(file);
} }
@ -76,7 +78,7 @@ monitor file creation/open.
@return own: handle to the file, not defined if error, error number @return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */ can be retrieved with os_file_get_last_error */
UNIV_INLINE UNIV_INLINE
os_file_t pfs_os_file_t
pfs_os_file_create_simple_no_error_handling_func( pfs_os_file_create_simple_no_error_handling_func(
/*=============================================*/ /*=============================================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */ 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 */ const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the 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; struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state; 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( file = os_file_create_simple_no_error_handling_func(
name, create_mode, access_type, success); 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); 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 @return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */ can be retrieved with os_file_get_last_error */
UNIV_INLINE UNIV_INLINE
os_file_t pfs_os_file_t
pfs_os_file_create_func( pfs_os_file_create_func(
/*====================*/ /*====================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */ 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 */ const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the 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; struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state; PSI_file_locker_state state;
@ -149,8 +153,10 @@ pfs_os_file_create_func(
name, src_file, src_line); name, src_file, src_line);
file = os_file_create_func(name, create_mode, purpose, type, success); 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); return(file);
} }
@ -164,7 +170,7 @@ UNIV_INLINE
ibool ibool
pfs_os_file_close_func( 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 */ const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the 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, register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_CLOSE,
src_file, src_line); 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); 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 */ ulint mode, /*!< in: OS_AIO_NORMAL etc. I/O mode */
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
null-terminated string */ 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 void* buf, /*!< in: buffer where to read or from which
to write */ to write */
os_offset_t offset, /*!< in: file offset where to read or write */ os_offset_t offset, /*!< in: file offset where to read or write */
@ -242,7 +248,7 @@ UNIV_INLINE
ibool ibool
pfs_os_file_read_func( 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 */ void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */ os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes 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, register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ,
src_file, src_line); 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); register_pfs_file_io_end(locker, n);
@ -275,7 +281,7 @@ UNIV_INLINE
ibool ibool
pfs_os_file_read_no_error_handling_func( 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 */ void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */ os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes 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, register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ,
src_file, src_line); 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); register_pfs_file_io_end(locker, n);
return(result); 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 NOTE! Please use the corresponding macro os_file_write(), not directly
this function! this function!
@ -308,7 +351,7 @@ pfs_os_file_write_func(
/*===================*/ /*===================*/
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
null-terminated string */ 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 */ const void* buf, /*!< in: buffer from which to write */
os_offset_t offset, /*!< in: file offset where to write */ os_offset_t offset, /*!< in: file offset where to write */
ulint n, /*!< in: number of bytes 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, register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_WRITE,
src_file, src_line); 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); register_pfs_file_io_end(locker, n);
return(result); 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 NOTE! Please use the corresponding macro os_file_flush(), not directly
this function! this function!
@ -339,7 +419,7 @@ UNIV_INLINE
ibool ibool
pfs_os_file_flush_func( 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 */ const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the 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, register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_SYNC,
src_file, src_line); 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); register_pfs_file_io_end(locker, 0);
@ -377,12 +457,12 @@ pfs_os_file_rename_func(
struct PSI_file_locker* locker = NULL; struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state; 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); src_file, src_line);
result = os_file_rename_func(oldpath, newpath); result = os_file_rename_func(oldpath, newpath);
register_pfs_file_open_end(locker, 0); register_pfs_file_rename_end(locker, 0);
return(result); return(result);
} }

View File

@ -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) 2008, 2009, Google Inc.
Copyright (c) 2009, Percona Inc. Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation. Copyright (c) 2013, 2017, MariaDB Corporation.
@ -802,6 +802,13 @@ UNIV_INTERN
void void
srv_purge_wakeup(); srv_purge_wakeup();
/** 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 */ /** Status variables to be passed to MySQL */
struct export_var_t{ struct export_var_t{
ulint innodb_data_pending_reads; /*!< Pending reads */ ulint innodb_data_pending_reads; /*!< Pending reads */

View File

@ -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 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 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 */ /** TRUE if a raw partition is in use */
extern ibool srv_start_raw_disk_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 */ /** Shutdown state */
enum srv_shutdown_state { enum srv_shutdown_state {

View File

@ -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 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 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 #ifndef XA_H
#define XA_H #define XA_H
#include "handler.h"
/* /*
* Transaction branch identification: XID and NULLXID: * 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 MAXGTRIDSIZE 64 /*!< maximum size in bytes of gtrid */
#define MAXBQUALSIZE 64 /*!< maximum size in bytes of bqual */ #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 #endif
/** X/Open XA distributed transaction status codes */ /** X/Open XA distributed transaction status codes */
/* @{ */ /* @{ */

View File

@ -134,14 +134,8 @@ HAVE_PSI_INTERFACE is defined. */
#if defined HAVE_PSI_INTERFACE && !defined UNIV_HOTBACKUP #if defined HAVE_PSI_INTERFACE && !defined UNIV_HOTBACKUP
# define UNIV_PFS_MUTEX # define UNIV_PFS_MUTEX
# define UNIV_PFS_RWLOCK # define UNIV_PFS_RWLOCK
/* For I/O instrumentation, performance schema rely
on a native descriptor to identify the file, this # define UNIV_PFS_IO
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_THREAD # define UNIV_PFS_THREAD
/* There are mutexes/rwlocks that we want to exclude from /* There are mutexes/rwlocks that we want to exclude from

View File

@ -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. Copyright (c) 2009, Google Inc.
Copyright (c) 2017, MariaDB Corporation. Copyright (c) 2017, MariaDB Corporation.
@ -3400,7 +3400,12 @@ loop:
lsn = log_sys->lsn; 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 #ifdef UNIV_LOG_ARCHIVE
|| (srv_log_archive_on || (srv_log_archive_on
&& lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE) && lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE)

View File

@ -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. Copyright (c) 2012, Facebook Inc.
Copyright (c) 2017, MariaDB Corporation. Copyright (c) 2017, MariaDB Corporation.
@ -328,6 +328,7 @@ DECLARE_THREAD(recv_writer_thread)(
/*!< in: a dummy parameter required by /*!< in: a dummy parameter required by
os_thread_create */ os_thread_create */
{ {
my_thread_init();
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
#ifdef UNIV_PFS_THREAD #ifdef UNIV_PFS_THREAD
@ -358,6 +359,7 @@ DECLARE_THREAD(recv_writer_thread)(
recv_writer_thread_active = false; recv_writer_thread_active = false;
my_thread_end();
/* We count the number of threads in os_thread_exit(). /* We count the number of threads in os_thread_exit().
A created thread should always use that to exit and not A created thread should always use that to exit and not
use return() to exit. */ use return() to exit. */

View File

@ -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. Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation. Copyright (c) 2013, 2017, MariaDB Corporation.
@ -164,7 +164,7 @@ struct os_aio_slot_t{
byte* buf; /*!< buffer used in i/o */ byte* buf; /*!< buffer used in i/o */
ulint type; /*!< OS_FILE_READ or OS_FILE_WRITE */ ulint type; /*!< OS_FILE_READ or OS_FILE_WRITE */
os_offset_t offset; /*!< file offset in bytes */ 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 */ const char* name; /*!< file name or path */
ibool io_already_done;/*!< used only in simulated aio: ibool io_already_done;/*!< used only in simulated aio:
TRUE if the physical i/o already TRUE if the physical i/o already
@ -1295,7 +1295,7 @@ A simple function to open or create a file.
@return own: handle to the file, not defined if error, error number @return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */ can be retrieved with os_file_get_last_error */
UNIV_INTERN UNIV_INTERN
os_file_t pfs_os_file_t
os_file_create_simple_no_error_handling_func( os_file_create_simple_no_error_handling_func(
/*=========================================*/ /*=========================================*/
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
@ -1307,7 +1307,7 @@ os_file_create_simple_no_error_handling_func(
used by a backup program reading the file */ used by a backup program reading the file */
ibool* success)/*!< out: TRUE if succeed, FALSE if error */ ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{ {
os_file_t file; pfs_os_file_t file;
*success = FALSE; *success = FALSE;
#ifdef __WIN__ #ifdef __WIN__
@ -1315,7 +1315,6 @@ os_file_create_simple_no_error_handling_func(
DWORD create_flag; DWORD create_flag;
DWORD attributes = 0; DWORD attributes = 0;
DWORD share_mode = FILE_SHARE_READ; DWORD share_mode = FILE_SHARE_READ;
ut_a(name); ut_a(name);
ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT)); ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT));
@ -1332,8 +1331,8 @@ os_file_create_simple_no_error_handling_func(
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown file create mode (%lu) for file '%s'", "Unknown file create mode (%lu) for file '%s'",
create_mode, name); create_mode, name);
file.m_file = (os_file_t)-1;
return((os_file_t) -1); return(file);
} }
if (access_type == OS_FILE_READ_ONLY) { if (access_type == OS_FILE_READ_ONLY) {
@ -1356,11 +1355,11 @@ os_file_create_simple_no_error_handling_func(
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown file access type (%lu) for file '%s'", "Unknown file access type (%lu) for file '%s'",
access_type, name); access_type, name);
file.m_file = (os_file_t)-1;
return((os_file_t) -1); return(file);
} }
file = CreateFile((LPCTSTR) name, file.m_file = CreateFile((LPCTSTR) name,
access, access,
share_mode, share_mode,
NULL, // Security attributes NULL, // Security attributes
@ -1368,11 +1367,10 @@ os_file_create_simple_no_error_handling_func(
attributes, attributes,
NULL); // No template file NULL); // No template file
*success = (file != INVALID_HANDLE_VALUE); *success = (file.m_file != INVALID_HANDLE_VALUE);
#else /* __WIN__ */ #else /* __WIN__ */
int create_flag; int create_flag;
const char* mode_str = NULL; const char* mode_str = NULL;
ut_a(name); ut_a(name);
ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT)); ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT));
@ -1414,13 +1412,13 @@ os_file_create_simple_no_error_handling_func(
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown file create mode (%lu) for file '%s'", "Unknown file create mode (%lu) for file '%s'",
create_mode, name); create_mode, name);
file.m_file = -1;
return((os_file_t) -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 /* 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 OS caching (O_DIRECT) here as we do in os_file_create_func(), so
@ -1430,18 +1428,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
|| srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)) { || 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 #ifdef USE_FILE_LOCK
if (!srv_read_only_mode if (!srv_read_only_mode
&& *success && *success
&& access_type == OS_FILE_READ_WRITE && access_type == OS_FILE_READ_WRITE
&& os_file_lock(file, name)) { && os_file_lock(file.m_file, name)) {
*success = FALSE; *success = FALSE;
close(file); close(file.m_file);
file = -1; file.m_file = -1;
} }
#endif /* USE_FILE_LOCK */ #endif /* USE_FILE_LOCK */
@ -1516,7 +1514,7 @@ Opens an existing file or creates a new.
@return own: handle to the file, not defined if error, error number @return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */ can be retrieved with os_file_get_last_error */
UNIV_INTERN UNIV_INTERN
os_file_t pfs_os_file_t
os_file_create_func( os_file_create_func(
/*================*/ /*================*/
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
@ -1532,24 +1530,25 @@ os_file_create_func(
ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */ ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */
ibool* success)/*!< out: TRUE if succeed, FALSE if error */ ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{ {
os_file_t file; pfs_os_file_t file;
ibool retry; ibool retry;
ibool on_error_no_exit; ibool on_error_no_exit;
ibool on_error_silent; ibool on_error_silent;
#ifdef __WIN__ #ifdef __WIN__
DBUG_EXECUTE_IF( DBUG_EXECUTE_IF(
"ib_create_table_fail_disk_full", "ib_create_table_fail_disk_full",
*success = FALSE; *success = FALSE;
SetLastError(ERROR_DISK_FULL); SetLastError(ERROR_DISK_FULL);
return((os_file_t) -1); file.m_file = (os_file_t)-1;
return(file);
); );
#else /* __WIN__ */ #else /* __WIN__ */
DBUG_EXECUTE_IF( DBUG_EXECUTE_IF(
"ib_create_table_fail_disk_full", "ib_create_table_fail_disk_full",
*success = FALSE; *success = FALSE;
errno = ENOSPC; errno = ENOSPC;
return((os_file_t) -1); file.m_file = -1;
return(file);
); );
#endif /* __WIN__ */ #endif /* __WIN__ */
@ -1600,7 +1599,8 @@ os_file_create_func(
"Unknown file create mode (%lu) for file '%s'", "Unknown file create mode (%lu) for file '%s'",
create_mode, name); create_mode, name);
return((os_file_t) -1); file.m_file = (os_file_t)-1;
return(file);
} }
DWORD attributes = 0; DWORD attributes = 0;
@ -1625,8 +1625,8 @@ os_file_create_func(
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown purpose flag (%lu) while opening file '%s'", "Unknown purpose flag (%lu) while opening file '%s'",
purpose, name); purpose, name);
file.m_file = (os_file_t)-1;
return((os_file_t)(-1)); return(file);
} }
#ifdef UNIV_NON_BUFFERED_IO #ifdef UNIV_NON_BUFFERED_IO
@ -1653,11 +1653,11 @@ os_file_create_func(
do { do {
/* Use default security attributes and no template file. */ /* Use default security attributes and no template file. */
file = CreateFile( file.m_file = CreateFile(
(LPCTSTR) name, access, share_mode, NULL, (LPCTSTR) name, access, share_mode, NULL,
create_flag, attributes, NULL); create_flag, attributes, NULL);
if (file == INVALID_HANDLE_VALUE) { if (file.m_file == INVALID_HANDLE_VALUE) {
const char* operation; const char* operation;
operation = (create_mode == OS_FILE_CREATE operation = (create_mode == OS_FILE_CREATE
@ -1682,7 +1682,6 @@ os_file_create_func(
#else /* __WIN__ */ #else /* __WIN__ */
int create_flag; int create_flag;
const char* mode_str = NULL; const char* mode_str = NULL;
on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT
? TRUE : FALSE; ? TRUE : FALSE;
on_error_silent = create_mode & OS_FILE_ON_ERROR_SILENT on_error_silent = create_mode & OS_FILE_ON_ERROR_SILENT
@ -1720,7 +1719,8 @@ os_file_create_func(
"Unknown file create mode (%lu) for file '%s'", "Unknown file create mode (%lu) for file '%s'",
create_mode, name); create_mode, name);
return((os_file_t) -1); file.m_file = -1;
return(file);
} }
ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE); ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE);
@ -1740,9 +1740,9 @@ os_file_create_func(
#endif /* O_SYNC */ #endif /* O_SYNC */
do { 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; const char* operation;
operation = (create_mode == OS_FILE_CREATE operation = (create_mode == OS_FILE_CREATE
@ -1772,14 +1772,14 @@ os_file_create_func(
&& (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT && (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT
|| srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)) { || 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 #ifdef USE_FILE_LOCK
if (!srv_read_only_mode if (!srv_read_only_mode
&& *success && *success
&& create_mode != OS_FILE_OPEN_RAW && 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) { if (create_mode == OS_FILE_OPEN_RETRY) {
@ -1791,7 +1791,7 @@ os_file_create_func(
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
os_thread_sleep(1000000); os_thread_sleep(1000000);
if (!os_file_lock(file, name)) { if (!os_file_lock(file.m_file, name)) {
*success = TRUE; *success = TRUE;
return(file); return(file);
} }
@ -1802,8 +1802,8 @@ os_file_create_func(
} }
*success = FALSE; *success = FALSE;
close(file); close(file.m_file);
file = -1; file.m_file = -1;
} }
#endif /* USE_FILE_LOCK */ #endif /* USE_FILE_LOCK */
@ -2071,14 +2071,14 @@ UNIV_INTERN
os_offset_t os_offset_t
os_file_get_size( 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__ #ifdef __WIN__
os_offset_t offset; os_offset_t offset;
DWORD high; DWORD high;
DWORD low; DWORD low;
low = GetFileSize(file, &high); low = GetFileSize(file.m_file, &high);
if ((low == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) { if ((low == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) {
return((os_offset_t) -1); return((os_offset_t) -1);
@ -2088,7 +2088,8 @@ os_file_get_size(
return(offset); return(offset);
#else #else
return((os_offset_t) lseek(file, 0, SEEK_END)); return((os_offset_t) lseek(file.m_file, 0, SEEK_END));
#endif /* __WIN__ */ #endif /* __WIN__ */
} }
@ -2101,7 +2102,7 @@ os_file_set_size(
/*=============*/ /*=============*/
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
null-terminated string */ 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 size) /*!< in: file size */
{ {
ibool ret; ibool ret;
@ -2113,7 +2114,7 @@ os_file_set_size(
if (srv_use_posix_fallocate) { if (srv_use_posix_fallocate) {
int err; int err;
do { do {
err = posix_fallocate(file, 0, size); err = posix_fallocate(file.m_file, 0, size);
} while (err == EINTR } while (err == EINTR
&& srv_shutdown_state == SRV_SHUTDOWN_NONE); && srv_shutdown_state == SRV_SHUTDOWN_NONE);
@ -4100,7 +4101,7 @@ os_aio_array_reserve_slot(
the aio operation */ the aio operation */
void* message2,/*!< in: message to be passed along with void* message2,/*!< in: message to be passed along with
the aio operation */ 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 const char* name, /*!< in: name of the file or path as a
null-terminated string */ null-terminated string */
void* buf, /*!< in: buffer where to read or from which void* buf, /*!< in: buffer where to read or from which
@ -4220,10 +4221,10 @@ found:
iocb = &slot->control; iocb = &slot->control;
if (type == OS_FILE_READ) { 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 { } else {
ut_a(type == OS_FILE_WRITE); 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; iocb->data = (void*) slot;
@ -4461,7 +4462,7 @@ os_aio_func(
caution! */ caution! */
const char* name, /*!< in: name of the file or path as a const char* name, /*!< in: name of the file or path as a
null-terminated string */ 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 void* buf, /*!< in: buffer where to read or from which
to write */ to write */
os_offset_t offset, /*!< in: file offset where to read or write */ os_offset_t offset, /*!< in: file offset where to read or write */
@ -4486,7 +4487,6 @@ os_aio_func(
ulint dummy_type; ulint dummy_type;
#endif /* WIN_ASYNC_IO */ #endif /* WIN_ASYNC_IO */
ulint wake_later; ulint wake_later;
ut_ad(buf); ut_ad(buf);
ut_ad(n > 0); ut_ad(n > 0);
ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0);
@ -4523,13 +4523,13 @@ os_aio_func(
and os_file_write_func() */ and os_file_write_func() */
if (type == OS_FILE_READ) { if (type == OS_FILE_READ) {
ret = os_file_read_func(file, buf, offset, n); ret = os_file_read_func(file.m_file, buf, offset, n);
} else { } else {
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
ut_a(type == OS_FILE_WRITE); ut_a(type == OS_FILE_WRITE);
ret = os_file_write_func(name, file, buf, offset, n); ret = os_file_write_func(name, file.m_file, buf, offset, n);
DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28", DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
os_has_said_disk_full = FALSE; ret = 0; errno = 28;); os_has_said_disk_full = FALSE; ret = 0; errno = 28;);
@ -4591,9 +4591,8 @@ try_again:
os_n_file_reads++; os_n_file_reads++;
os_bytes_read_since_printout += n; os_bytes_read_since_printout += n;
#ifdef WIN_ASYNC_IO #ifdef WIN_ASYNC_IO
ret = ReadFile(file, buf, (DWORD) n, &len, ret = ReadFile(file.m_file, buf, (DWORD) n, &len,
&(slot->control)); &(slot->control));
#elif defined(LINUX_NATIVE_AIO) #elif defined(LINUX_NATIVE_AIO)
if (!os_aio_linux_dispatch(array, slot)) { if (!os_aio_linux_dispatch(array, slot)) {
goto err_exit; goto err_exit;
@ -4611,9 +4610,8 @@ try_again:
if (srv_use_native_aio) { if (srv_use_native_aio) {
os_n_file_writes++; os_n_file_writes++;
#ifdef WIN_ASYNC_IO #ifdef WIN_ASYNC_IO
ret = WriteFile(file, buf, (DWORD) n, &len, ret = WriteFile(file.m_file, buf, (DWORD) n, &len,
&(slot->control)); &(slot->control));
#elif defined(LINUX_NATIVE_AIO) #elif defined(LINUX_NATIVE_AIO)
if (!os_aio_linux_dispatch(array, slot)) { if (!os_aio_linux_dispatch(array, slot)) {
goto err_exit; goto err_exit;
@ -4767,8 +4765,7 @@ os_aio_windows_handle(
srv_set_io_thread_op_info( srv_set_io_thread_op_info(
orig_seg, "get windows aio return value"); orig_seg, "get windows aio return value");
} }
ret = GetOverlappedResult(slot->file.m_file, &(slot->control), &len, TRUE);
ret = GetOverlappedResult(slot->file, &(slot->control), &len, TRUE);
*message1 = slot->message1; *message1 = slot->message1;
*message2 = slot->message2; *message2 = slot->message2;
@ -4797,7 +4794,8 @@ os_aio_windows_handle(
and os_file_write APIs, need to register with and os_file_write APIs, need to register with
performance schema explicitly here. */ performance schema explicitly here. */
struct PSI_file_locker* locker = NULL; 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) (slot->type == OS_FILE_WRITE)
? PSI_FILE_WRITE ? PSI_FILE_WRITE
: PSI_FILE_READ, : PSI_FILE_READ,
@ -4808,16 +4806,14 @@ os_aio_windows_handle(
switch (slot->type) { switch (slot->type) {
case OS_FILE_WRITE: case OS_FILE_WRITE:
ret = WriteFile(slot->file, slot->buf, ret = WriteFile(slot->file.m_file, slot->buf,
(DWORD) slot->len, &len, (DWORD) slot->len, &len,
&(slot->control)); &(slot->control));
break; break;
case OS_FILE_READ: case OS_FILE_READ:
ret = ReadFile(slot->file, slot->buf, ret = ReadFile(slot->file.m_file, slot->buf,
(DWORD) slot->len, &len, (DWORD) slot->len, &len,
&(slot->control)); &(slot->control));
break; break;
default: default:
ut_error; ut_error;
@ -4833,8 +4829,7 @@ os_aio_windows_handle(
file where we also use async i/o: in Windows file where we also use async i/o: in Windows
we must use the same wait mechanism as for we must use the same wait mechanism as for
async i/o */ async i/o */
ret = GetOverlappedResult(slot->file.m_file,
ret = GetOverlappedResult(slot->file,
&(slot->control), &(slot->control),
&len, TRUE); &len, TRUE);
} }
@ -5281,12 +5276,11 @@ consecutive_loop:
os_aio_slot_t* slot; os_aio_slot_t* slot;
slot = os_aio_array_get_nth_slot(array, i + segment * n); slot = os_aio_array_get_nth_slot(array, i + segment * n);
if (slot->reserved if (slot->reserved
&& slot != aio_slot && slot != aio_slot
&& slot->offset == aio_slot->offset + aio_slot->len && slot->offset == aio_slot->offset + aio_slot->len
&& slot->type == aio_slot->type && 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 */ /* Found a consecutive i/o request */

View File

@ -363,9 +363,9 @@ row_log_online_op(
goto err_exit; goto err_exit;
} }
ret = os_file_write( ret = os_file_write_int_fd(
"(modification log)", "(modification log)",
OS_FILE_FROM_FD(log->fd), log->fd,
log->tail.block, byte_offset, srv_sort_buf_size); log->tail.block, byte_offset, srv_sort_buf_size);
log->tail.blocks++; log->tail.blocks++;
if (!ret) { if (!ret) {
@ -479,9 +479,9 @@ row_log_table_close_func(
goto err_exit; goto err_exit;
} }
ret = os_file_write( ret = os_file_write_int_fd(
"(modification log)", "(modification log)",
OS_FILE_FROM_FD(log->fd), log->fd,
log->tail.block, byte_offset, srv_sort_buf_size); log->tail.block, byte_offset, srv_sort_buf_size);
log->tail.blocks++; log->tail.blocks++;
if (!ret) { if (!ret) {
@ -2612,11 +2612,10 @@ all_done:
goto func_exit; goto func_exit;
} }
success = os_file_read_no_error_handling( success = os_file_read_no_error_handling_int_fd(
OS_FILE_FROM_FD(index->online_log->fd), index->online_log->fd,
index->online_log->head.block, ofs, index->online_log->head.block, ofs,
srv_sort_buf_size); srv_sort_buf_size);
if (!success) { if (!success) {
fprintf(stderr, "InnoDB: unable to read temporary file" fprintf(stderr, "InnoDB: unable to read temporary file"
" for table %s\n", index->table_name); " for table %s\n", index->table_name);
@ -3442,8 +3441,8 @@ all_done:
goto func_exit; goto func_exit;
} }
success = os_file_read_no_error_handling( success = os_file_read_no_error_handling_int_fd(
OS_FILE_FROM_FD(index->online_log->fd), index->online_log->fd,
index->online_log->head.block, ofs, index->online_log->head.block, ofs,
srv_sort_buf_size); srv_sort_buf_size);

View File

@ -864,8 +864,9 @@ row_merge_read(
} }
#endif /* UNIV_DEBUG */ #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); ofs, srv_sort_buf_size);
#ifdef POSIX_FADV_DONTNEED #ifdef POSIX_FADV_DONTNEED
/* Each block is read exactly once. Free up the file cache. */ /* Each block is read exactly once. Free up the file cache. */
posix_fadvise(fd, ofs, srv_sort_buf_size, POSIX_FADV_DONTNEED); posix_fadvise(fd, ofs, srv_sort_buf_size, POSIX_FADV_DONTNEED);
@ -899,7 +900,7 @@ row_merge_write(
DBUG_EXECUTE_IF("row_merge_write_failure", return(FALSE);); 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 #ifdef UNIV_DEBUG
if (row_merge_print_block_write) { if (row_merge_print_block_write) {
@ -3140,14 +3141,21 @@ row_merge_file_create_low(
performance schema */ performance schema */
struct PSI_file_locker* locker = NULL; struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state; PSI_file_locker_state state;
register_pfs_file_open_begin(&state, locker, innodb_file_temp_key, locker = PSI_FILE_CALL(get_thread_file_name_locker)(
PSI_FILE_OPEN, &state, innodb_file_temp_key, PSI_FILE_OPEN,
"Innodb Merge Temp File", "Innodb Merge Temp File", &locker);
__FILE__, __LINE__); if (locker != NULL) {
PSI_FILE_CALL(start_file_open_wait)(locker,
__FILE__,
__LINE__);
}
#endif #endif
fd = innobase_mysql_tmpfile(path); fd = innobase_mysql_tmpfile(path);
#ifdef UNIV_PFS_IO #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 #endif
if (fd < 0) { if (fd < 0) {
@ -3194,15 +3202,20 @@ row_merge_file_destroy_low(
#ifdef UNIV_PFS_IO #ifdef UNIV_PFS_IO
struct PSI_file_locker* locker = NULL; struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state; PSI_file_locker_state state;
register_pfs_file_io_begin(&state, locker, locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
fd, 0, PSI_FILE_CLOSE, &state, fd, PSI_FILE_CLOSE);
__FILE__, __LINE__); if (locker != NULL) {
PSI_FILE_CALL(start_file_wait)(
locker, 0, __FILE__, __LINE__);
}
#endif #endif
if (fd >= 0) { if (fd >= 0) {
close(fd); close(fd);
} }
#ifdef UNIV_PFS_IO #ifdef UNIV_PFS_IO
register_pfs_file_io_end(locker, 0); if (locker != NULL) {
PSI_FILE_CALL(end_file_wait)(locker, 0);
}
#endif #endif
} }
/*********************************************************************//** /*********************************************************************//**

View File

@ -2746,27 +2746,32 @@ row_sel_field_store_in_mysql_format_func(
# define row_sel_store_mysql_field(m,p,r,i,o,f,t) \ # 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) row_sel_store_mysql_field_func(m,p,r,o,f,t)
#endif /* UNIV_DEBUG */ #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
*/
static MY_ATTRIBUTE((warn_unused_result)) static MY_ATTRIBUTE((warn_unused_result))
ibool ibool
row_sel_store_mysql_field_func( row_sel_store_mysql_field_func(
/*===========================*/ byte* mysql_rec,
byte* mysql_rec, /*!< out: record in the row_prebuilt_t* prebuilt,
MySQL format */ const rec_t* rec,
row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct */
const rec_t* rec, /*!< in: InnoDB record;
must be protected by
a page latch */
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
const dict_index_t* index, /*!< in: index of rec */ const dict_index_t* index,
#endif #endif
const ulint* offsets, /*!< in: array returned by const ulint* offsets,
rec_get_offsets() */ ulint field_no,
ulint field_no, /*!< in: templ->rec_field_no or const mysql_row_templ_t*templ)
templ->clust_rec_field_no or
templ->icp_rec_field_no */
const mysql_row_templ_t*templ) /*!< in: row template */
{ {
const byte* data; const byte* data;
ulint len; ulint len;
@ -2892,30 +2897,35 @@ row_sel_store_mysql_field_func(
return(TRUE); 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 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 columns to mysql_rec, other columns are left blank. All columns may not
be needed in the query. 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 */ @return TRUE on success, FALSE if not all columns could be retrieved */
static MY_ATTRIBUTE((warn_unused_result)) static MY_ATTRIBUTE((warn_unused_result))
ibool ibool
row_sel_store_mysql_rec( row_sel_store_mysql_rec(
/*====================*/ byte* mysql_rec,
byte* mysql_rec, /*!< out: row in the MySQL format */ row_prebuilt_t* prebuilt,
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */ const rec_t* rec,
const rec_t* rec, /*!< in: Innobase record in the index ibool rec_clust,
which was described in prebuilt's const dict_index_t* index,
template, or in the clustered index; const ulint* offsets)
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) */
{ {
ulint i; ulint i;
ut_ad(rec_clust || index == prebuilt->index); ut_ad(rec_clust || index == prebuilt->index);
ut_ad(!rec_clust || dict_index_is_clust(index)); ut_ad(!rec_clust || dict_index_is_clust(index));
@ -2936,6 +2946,7 @@ row_sel_store_mysql_rec(
ut_ad(dict_index_get_nth_field(index, field_no)->prefix_len ut_ad(dict_index_get_nth_field(index, field_no)->prefix_len
== 0); == 0);
if (!row_sel_store_mysql_field(mysql_rec, prebuilt, if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
rec, index, offsets, rec, index, offsets,
field_no, templ)) { field_no, templ)) {
@ -3658,7 +3669,7 @@ row_search_for_mysql(
trx_t* trx = prebuilt->trx; trx_t* trx = prebuilt->trx;
dict_index_t* clust_index; dict_index_t* clust_index;
que_thr_t* thr; que_thr_t* thr;
const rec_t* rec; const rec_t* rec = NULL;
const rec_t* result_rec = NULL; const rec_t* result_rec = NULL;
const rec_t* clust_rec; const rec_t* clust_rec;
dberr_t err = DB_SUCCESS; dberr_t err = DB_SUCCESS;
@ -3957,7 +3968,8 @@ row_search_for_mysql(
if (!row_sel_store_mysql_rec( if (!row_sel_store_mysql_rec(
buf, prebuilt, buf, prebuilt,
rec, FALSE, index, offsets)) { rec, FALSE, index,
offsets)) {
/* Only fresh inserts may contain /* Only fresh inserts may contain
incomplete externally stored incomplete externally stored
columns. Pretend that such columns. Pretend that such

View File

@ -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) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc. Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation. Copyright (c) 2013, 2017, MariaDB Corporation.
@ -2398,6 +2398,8 @@ DECLARE_THREAD(srv_master_thread)(
/*!< in: a dummy parameter required by /*!< in: a dummy parameter required by
os_thread_create */ os_thread_create */
{ {
my_thread_init();
srv_slot_t* slot; srv_slot_t* slot;
ulint old_activity_count = srv_get_activity_count(); ulint old_activity_count = srv_get_activity_count();
ib_time_t last_print_time; ib_time_t last_print_time;
@ -2459,6 +2461,7 @@ suspend_thread:
srv_resume_thread(slot); srv_resume_thread(slot);
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
my_thread_end();
os_thread_exit(NULL); os_thread_exit(NULL);
} }
@ -2541,6 +2544,8 @@ DECLARE_THREAD(srv_worker_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */ required by os_thread_create */
{ {
my_thread_init();
srv_slot_t* slot; srv_slot_t* slot;
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
@ -2598,6 +2603,7 @@ DECLARE_THREAD(srv_worker_thread)(
os_thread_pf(os_thread_get_curr_id())); os_thread_pf(os_thread_get_curr_id()));
#endif /* UNIV_DEBUG_THREAD_CREATION */ #endif /* UNIV_DEBUG_THREAD_CREATION */
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created /* 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. */ thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL); os_thread_exit(NULL);
@ -2764,6 +2770,8 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */ required by os_thread_create */
{ {
my_thread_init();
srv_slot_t* slot; srv_slot_t* slot;
ulint n_total_purged = ULINT_UNDEFINED; ulint n_total_purged = ULINT_UNDEFINED;
@ -2870,6 +2878,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
srv_release_threads(SRV_WORKER, srv_n_purge_threads - 1); 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 /* 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. */ thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL); os_thread_exit(NULL);
@ -2935,3 +2944,19 @@ srv_purge_wakeup()
} }
} }
} }
/** 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));
}

View File

@ -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) 2008, Google Inc.
Copyright (c) 2009, Percona Inc. Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation. Copyright (c) 2013, 2017, MariaDB Corporation.
@ -110,6 +110,9 @@ UNIV_INTERN ibool srv_have_fullfsync = FALSE;
/** TRUE if a raw partition is in use */ /** TRUE if a raw partition is in use */
UNIV_INTERN ibool srv_start_raw_disk_in_use = FALSE; 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 /** TRUE if the server is being started, before rolling back any
incomplete transactions */ incomplete transactions */
UNIV_INTERN ibool srv_startup_is_before_trx_rollback_phase = FALSE; UNIV_INTERN ibool srv_startup_is_before_trx_rollback_phase = FALSE;
@ -125,7 +128,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; UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE;
/** Files comprising the system tablespace */ /** 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 */ /** io_handler_thread parameters for thread identification */
static ulint n[SRV_MAX_N_IO_THREADS + 6]; static ulint n[SRV_MAX_N_IO_THREADS + 6];
@ -540,7 +543,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t dberr_t
create_log_file( 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 */ const char* name) /*!< in: log file name */
{ {
ibool ret; ibool ret;
@ -746,7 +749,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t dberr_t
open_log_file( 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 */ const char* name, /*!< in: log file name */
os_offset_t* size) /*!< out: file size */ os_offset_t* size) /*!< out: file size */
{ {
@ -862,7 +865,7 @@ open_or_create_data_files(
&& os_file_get_last_error(false) && os_file_get_last_error(false)
!= OS_FILE_ALREADY_EXISTS != OS_FILE_ALREADY_EXISTS
#ifdef UNIV_AIX #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 errno set to 0 here, which causes our
function to return 100; work around that function to return 100; work around that
AIX problem */ AIX problem */
@ -1165,7 +1168,7 @@ srv_undo_tablespace_create(
const char* name, /*!< in: tablespace name */ const char* name, /*!< in: tablespace name */
ulint size) /*!< in: tablespace size in pages */ ulint size) /*!< in: tablespace size in pages */
{ {
os_file_t fh; pfs_os_file_t fh;
ibool ret; ibool ret;
dberr_t err = DB_SUCCESS; dberr_t err = DB_SUCCESS;
@ -1242,7 +1245,7 @@ srv_undo_tablespace_open(
const char* name, /*!< in: tablespace name */ const char* name, /*!< in: tablespace name */
ulint space) /*!< in: tablespace id */ ulint space) /*!< in: tablespace id */
{ {
os_file_t fh; pfs_os_file_t fh;
dberr_t err = DB_ERROR; dberr_t err = DB_ERROR;
ibool ret; ibool ret;
ulint flags; ulint flags;
@ -1341,13 +1344,23 @@ srv_undo_tablespaces_init(
for (i = 0; create_new_db && i < n_conf_tablespaces; ++i) { for (i = 0; create_new_db && i < n_conf_tablespaces; ++i) {
char name[OS_FILE_MAX_PATH]; char name[OS_FILE_MAX_PATH];
ulint space_id = i + 1;
DBUG_EXECUTE_IF("innodb_undo_upgrade",
space_id = i + 3;);
ut_snprintf( ut_snprintf(
name, sizeof(name), name, sizeof(name),
"%s%cundo%03lu", "%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( err = srv_undo_tablespace_create(
name, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES); name, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES);
@ -1369,14 +1382,16 @@ srv_undo_tablespaces_init(
if (!create_new_db) { if (!create_new_db) {
n_undo_tablespaces = trx_rseg_get_n_undo_tablespaces( n_undo_tablespaces = trx_rseg_get_n_undo_tablespaces(
undo_tablespace_ids); undo_tablespace_ids);
if (n_undo_tablespaces != 0) {
srv_undo_space_id_start = undo_tablespace_ids[0];
prev_space_id = srv_undo_space_id_start - 1;
}
} else { } else {
n_undo_tablespaces = n_conf_tablespaces; n_undo_tablespaces = n_conf_tablespaces;
for (i = 1; i <= n_undo_tablespaces; ++i) { undo_tablespace_ids[n_conf_tablespaces] = ULINT_UNDEFINED;
undo_tablespace_ids[i - 1] = i;
}
undo_tablespace_ids[i] = ULINT_UNDEFINED;
} }
/* Open all the undo tablespaces that are currently in use. If we /* Open all the undo tablespaces that are currently in use. If we
@ -1400,8 +1415,6 @@ srv_undo_tablespaces_init(
ut_a(undo_tablespace_ids[i] != 0); ut_a(undo_tablespace_ids[i] != 0);
ut_a(undo_tablespace_ids[i] != ULINT_UNDEFINED); ut_a(undo_tablespace_ids[i] != ULINT_UNDEFINED);
/* Undo space ids start from 1. */
err = srv_undo_tablespace_open(name, undo_tablespace_ids[i]); err = srv_undo_tablespace_open(name, undo_tablespace_ids[i]);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
@ -1436,11 +1449,23 @@ srv_undo_tablespaces_init(
break; 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_undo_tablespaces;
++*n_opened; ++*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 /* If the user says that there are fewer than what we find we
tolerate that discrepancy but not the inverse. Because there could tolerate that discrepancy but not the inverse. Because there could
be unused undo tablespaces for future use. */ be unused undo tablespaces for future use. */
@ -1485,10 +1510,11 @@ srv_undo_tablespaces_init(
mtr_start(&mtr); mtr_start(&mtr);
/* The undo log tablespace */ /* The undo log tablespace */
for (i = 1; i <= n_undo_tablespaces; ++i) { for (i = 0; i < n_undo_tablespaces; ++i) {
fsp_header_init( 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); mtr_commit(&mtr);
@ -1575,6 +1601,10 @@ innobase_start_or_create_for_mysql(void)
os_fast_mutex_free(&srv_os_test_mutex); os_fast_mutex_free(&srv_os_test_mutex);
if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) {
srv_read_only_mode = 1;
}
high_level_read_only = srv_read_only_mode high_level_read_only = srv_read_only_mode
|| srv_force_recovery > SRV_FORCE_NO_TRX_UNDO; || srv_force_recovery > SRV_FORCE_NO_TRX_UNDO;

View File

@ -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) 2017, MariaDB Corporation. All Rights Reserved. Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
@ -686,7 +686,8 @@ trx_purge_get_rseg_with_min_trx_id(
/* We assume in purge of externally stored fields that space id is /* We assume in purge of externally stored fields that space id is
in the range of UNDO tablespace space ids */ 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; zip_size = purge_sys->rseg->zip_size;

View File

@ -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) 2016, 2017, MariaDB Corporation. Copyright (c) 2016, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
@ -805,6 +805,7 @@ DECLARE_THREAD(trx_rollback_or_clean_all_recovered)(
/*!< in: a dummy parameter required by /*!< in: a dummy parameter required by
os_thread_create */ os_thread_create */
{ {
my_thread_init();
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
#ifdef UNIV_PFS_THREAD #ifdef UNIV_PFS_THREAD
@ -815,6 +816,7 @@ DECLARE_THREAD(trx_rollback_or_clean_all_recovered)(
trx_rollback_or_clean_is_active = false; trx_rollback_or_clean_is_active = false;
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created /* 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. */ thread should always use that to exit and not use return() to exit. */

View File

@ -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 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 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; ulint new_rsegs = n_rsegs - n_used;
for (i = 0; i < new_rsegs; ++i) { 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 /* Tablespace 0 is the system tablespace. */
log tablespaces start from 1. */ if (trx_rseg_create(space_id) != NULL) {
if (n_spaces > 0) {
space = (i % n_spaces) + 1;
} else {
space = 0; /* System tablespace */
}
if (trx_rseg_create(space) != NULL) {
++n_used; ++n_used;
} else { } else {
break; break;