This commit is contained in:
Vicențiu Ciorbaru 2017-05-15 17:17:16 +03:00
parent 6ac84d9824
commit 0af9818240
31 changed files with 658 additions and 292 deletions

View File

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

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 <= MAX_PAGE_HASH_LOCKS);
buf_pool->page_hash = ha_create(2 * buf_pool->curr_size,
buf_pool->page_hash = ib_create(2 * buf_pool->curr_size,
srv_n_page_hash_locks,
MEM_HEAP_FOR_PAGE_HASH,
SYNC_BUF_PAGE_HASH);

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
the terms of the GNU General Public License as published by the Free Software
@ -355,7 +355,7 @@ recovery, this function loads the pages from double write buffer into memory. */
void
buf_dblwr_init_or_load_pages(
/*=========================*/
os_file_t file,
pfs_os_file_t file,
char* path,
bool load_corrupt_pages)
{

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.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -597,6 +597,7 @@ DECLARE_THREAD(buf_dump_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */
{
my_thread_init();
ut_ad(!srv_read_only_mode);
srv_buf_dump_thread_active = TRUE;
@ -632,6 +633,7 @@ DECLARE_THREAD(buf_dump_thread)(
srv_buf_dump_thread_active = FALSE;
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);

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
the terms of the GNU General Public License as published by the Free Software
@ -2388,6 +2388,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
/*!< in: a dummy parameter required by
os_thread_create */
{
my_thread_init();
ulint next_loop_time = ut_time_ms() + 1000;
ulint n_flushed = 0;
ulint last_activity = srv_get_activity_count();
@ -2506,6 +2507,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
thread_exit:
buf_page_cleaner_is_active = FALSE;
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);

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
the terms of the GNU General Public License as published by the Free Software
@ -454,7 +454,10 @@ dict_boot(void)
dberr_t err = DB_SUCCESS;
if (srv_read_only_mode && !ibuf_is_empty()) {
/** If innodb_force_recovery is set to 6 then allow
the server to start even though ibuf is not empty. */
if (srv_force_recovery != SRV_FORCE_NO_LOG_REDO
&& srv_read_only_mode && !ibuf_is_empty()) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Change buffer must be empty when --innodb-read-only "

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
the terms of the GNU General Public License as published by the Free Software
@ -690,6 +690,9 @@ dict_stats_copy(
&& (src_idx = dict_table_get_next_index(src_idx)))) {
if (dict_stats_should_ignore_index(dst_idx)) {
if (!(dst_idx->type & DICT_FTS)) {
dict_stats_empty_index(dst_idx);
}
continue;
}
@ -1096,10 +1099,10 @@ dict_stats_analyze_index_level(
leaf-level delete marks because delete marks on
non-leaf level do not make sense. */
if (level == 0 && srv_stats_include_delete_marked? 0:
if (level == 0 && (srv_stats_include_delete_marked ? 0:
rec_get_deleted_flag(
rec,
page_is_comp(btr_pcur_get_page(&pcur)))) {
page_is_comp(btr_pcur_get_page(&pcur))))) {
if (rec_is_last_on_page
&& !prev_rec_is_copied
@ -3229,12 +3232,6 @@ dict_stats_update(
dict_table_stats_lock(table, RW_X_LATCH);
/* Initialize all stats to dummy values before
copying because dict_stats_table_clone_create() does
skip corrupted indexes so our dummy object 't' may
have less indexes than the real object 'table'. */
dict_stats_empty_table(table);
dict_stats_copy(table, t);
dict_stats_assert_initialized(table);

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.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -334,6 +334,7 @@ DECLARE_THREAD(dict_stats_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */
{
my_thread_init();
ut_a(!srv_read_only_mode);
srv_dict_stats_thread_active = TRUE;
@ -359,6 +360,7 @@ DECLARE_THREAD(dict_stats_thread)(
srv_dict_stats_thread_active = FALSE;
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit instead of return(). */
os_thread_exit(NULL);

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
the terms of the GNU General Public License as published by the Free Software
@ -146,7 +146,7 @@ struct fil_node_t {
belongs */
char* name; /*!< path to the file */
ibool open; /*!< TRUE if file open */
os_file_t handle; /*!< OS handle to the file, if file open */
pfs_os_file_t handle; /*!< OS handle to the file, if file open */
os_event_t sync_event;/*!< Condition event to group and
serialize calls to fsync */
ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw
@ -316,7 +316,8 @@ initialized. */
static fil_system_t* fil_system = NULL;
/** Determine if (i) is a user tablespace id or not. */
# define fil_is_user_tablespace_id(i) ((i) > srv_undo_tablespaces_open)
# define fil_is_user_tablespace_id(i) (i != 0 \
&& !srv_is_undo_tablespace(i))
/** Determine if user has explicitly disabled fsync(). */
#ifndef __WIN__
@ -2025,7 +2026,7 @@ UNIV_INTERN
const char*
fil_read_first_page(
/*================*/
os_file_t data_file, /*!< in: open data file */
pfs_os_file_t data_file, /*!< in: open data file */
ibool one_read_already, /*!< in: TRUE if min and max
parameters below already
contain sensible data */
@ -3360,7 +3361,7 @@ fil_open_linked_file(
/*===============*/
const char* tablename, /*!< in: database/tablename */
char** remote_filepath,/*!< out: remote filepath */
os_file_t* remote_file) /*!< out: remote file handle */
pfs_os_file_t* remote_file) /*!< out: remote file handle */
{
ibool success;
@ -3420,7 +3421,8 @@ fil_create_new_single_table_tablespace(
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
{
os_file_t file;
pfs_os_file_t file;
ibool ret;
dberr_t err;
byte* buf2;
@ -5862,7 +5864,7 @@ fil_flush(
{
fil_space_t* space;
fil_node_t* node;
os_file_t file;
pfs_os_file_t file;
mutex_enter(&fil_system->mutex);
@ -6224,7 +6226,7 @@ fil_buf_block_init(
}
struct fil_iterator_t {
os_file_t file; /*!< File handle */
pfs_os_file_t file; /*!< File handle */
const char* filepath; /*!< File path name */
os_offset_t start; /*!< From where to start */
os_offset_t end; /*!< Where to stop */
@ -6359,7 +6361,7 @@ fil_tablespace_iterate(
PageCallback& callback)
{
dberr_t err;
os_file_t file;
pfs_os_file_t file;
char* filepath;
ut_a(n_io_buffers > 0);

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) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
@ -5052,6 +5052,8 @@ table_opened:
prebuilt->default_rec = table->s->default_values;
ut_ad(prebuilt->default_rec);
prebuilt->mysql_handler = this;
/* Looks like MySQL-3.23 sometimes has primary key number != 0 */
primary_key = table->s->primary_key;
key_used_on_scan = primary_key;
@ -10168,7 +10170,8 @@ ha_innobase::delete_table(
extension, in contrast to ::create */
normalize_table_name(norm_name, name);
if (srv_read_only_mode) {
if (srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) {
DBUG_RETURN(HA_ERR_TABLE_READONLY);
} else if (row_is_magic_monitor_table(norm_name)
&& check_global_access(thd, PROCESS_ACL)) {

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
the terms of the GNU General Public License as published by the Free Software
@ -55,7 +55,7 @@ recovery, this function loads the pages from double write buffer into memory. */
void
buf_dblwr_init_or_load_pages(
/*=========================*/
os_file_t file,
pfs_os_file_t file,
char* path,
bool load_corrupt_pages);

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
the terms of the GNU General Public License as published by the Free Software
@ -181,7 +181,7 @@ struct fsp_open_info {
ibool success; /*!< Has the tablespace been opened? */
const char* check_msg; /*!< fil_check_first_page() message */
ibool valid; /*!< Is the tablespace valid? */
os_file_t file; /*!< File handle */
pfs_os_file_t file; /*!< File handle */
char* filepath; /*!< File path to open */
lsn_t lsn; /*!< Flushed LSN from header page */
ulint id; /*!< Space ID */
@ -384,7 +384,7 @@ UNIV_INTERN
const char*
fil_read_first_page(
/*================*/
os_file_t data_file, /*!< in: open data file */
pfs_os_file_t data_file, /*!< in: open data file */
ibool one_read_already, /*!< in: TRUE if min and max
parameters below already
contain sensible data */
@ -902,12 +902,12 @@ struct PageCallback {
Called for every page in the tablespace. If the page was not
updated then its state must be set to BUF_PAGE_NOT_USED. For
compressed tables the page descriptor memory will be at offset:
block->frame + UNIV_PAGE_SIZE;
block->frame + UNIV_PAGE_SIZE;
@param offset - physical offset within the file
@param block - block read from file, note it is not from the buffer pool
@retval DB_SUCCESS or error code. */
virtual dberr_t operator()(
os_offset_t offset,
os_offset_t offset,
buf_block_t* block) UNIV_NOTHROW = 0;
/**
@ -915,7 +915,7 @@ struct PageCallback {
to open it for the file that is being iterated over.
@param filename - then physical name of the tablespace file.
@param file - OS file handle */
void set_file(const char* filename, os_file_t file) UNIV_NOTHROW
void set_file(const char* filename, pfs_os_file_t file) UNIV_NOTHROW
{
m_file = file;
m_filepath = filename;
@ -951,7 +951,7 @@ struct PageCallback {
ulint m_page_size;
/** File handle to the tablespace */
os_file_t m_file;
pfs_os_file_t m_file;
/** Physical file path. */
const char* m_filepath;

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
the terms of the GNU General Public License as published by the Free Software
@ -107,7 +107,7 @@ chosen to be a slightly bigger prime number.
@param level in: level of the mutexes in the latching order
@param n_m in: number of mutexes to protect the hash table;
must be a power of 2, or 0 */
# define ha_create(n_c,n_m,type,level) ha_create_func(n_c,level,n_m,type)
# define ib_create(n_c,n_m,type,level) ha_create_func(n_c,level,n_m,type)
#else /* UNIV_SYNC_DEBUG */
/** Creates a hash table.
@return own: created table
@ -116,7 +116,7 @@ chosen to be a slightly bigger prime number.
@param level in: level of the mutexes in the latching order
@param n_m in: number of mutexes to protect the hash table;
must be a power of 2, or 0 */
# define ha_create(n_c,n_m,type,level) ha_create_func(n_c,n_m,type)
# define ib_create(n_c,n_m,type,level) ha_create_func(n_c,n_m,type)
#endif /* UNIV_SYNC_DEBUG */
/*************************************************************//**

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.
Portions of this file contain modifications contributed and copyrighted
@ -89,6 +89,16 @@ typedef int os_file_t;
# define OS_FILE_FROM_FD(fd) fd
#endif
/*Common file descriptor for file IO instrumentation with PFS
on windows and other platforms */
struct pfs_os_file_t
{
os_file_t m_file;
#ifdef UNIV_PFS_IO
struct PSI_file *m_psi;
#endif
};
/** Umask for creating files */
extern ulint os_innodb_umask;
@ -216,6 +226,8 @@ extern mysql_pfs_key_t innodb_file_temp_key;
various file I/O operations with performance schema.
1) register_pfs_file_open_begin() and register_pfs_file_open_end() are
used to register file creation, opening, closing and renaming.
2) register_pfs_file_rename_begin() and register_pfs_file_rename_end()
are used to register file renaming
2) register_pfs_file_io_begin() and register_pfs_file_io_end() are
used to register actual file read, write and flush
3) register_pfs_file_close_begin() and register_pfs_file_close_end()
@ -225,17 +237,30 @@ are used to register file deletion operations*/
do { \
locker = PSI_FILE_CALL(get_thread_file_name_locker)( \
state, key, op, name, &locker); \
if (UNIV_LIKELY(locker != NULL)) { \
if (locker != NULL) { \
PSI_FILE_CALL(start_file_open_wait)( \
locker, src_file, src_line); \
} \
} while (0)
# define register_pfs_file_open_end(locker, file) \
# define register_pfs_file_open_end(locker, file, result) \
do { \
if (UNIV_LIKELY(locker != NULL)) { \
PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(\
locker, file); \
if (locker != NULL) { \
file.m_psi = PSI_FILE_CALL( \
end_file_open_wait)( \
locker, result); \
} \
} while (0)
# define register_pfs_file_rename_begin(state, locker, key, op, name, \
src_file, src_line) \
register_pfs_file_open_begin(state, locker, key, op, name, \
src_file, src_line) \
# define register_pfs_file_rename_end(locker, result) \
do { \
if (locker != NULL) { \
PSI_FILE_CALL(end_file_open_wait)(locker, result); \
} \
} while (0)
@ -261,9 +286,9 @@ do { \
# define register_pfs_file_io_begin(state, locker, file, count, op, \
src_file, src_line) \
do { \
locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)( \
state, file, op); \
if (UNIV_LIKELY(locker != NULL)) { \
locker = PSI_FILE_CALL(get_thread_file_stream_locker)( \
state, file.m_psi, op); \
if (locker != NULL) { \
PSI_FILE_CALL(start_file_wait)( \
locker, count, src_file, src_line); \
} \
@ -271,7 +296,7 @@ do { \
# define register_pfs_file_io_end(locker, count) \
do { \
if (UNIV_LIKELY(locker != NULL)) { \
if (locker != NULL) { \
PSI_FILE_CALL(end_file_wait)(locker, count); \
} \
} while (0)
@ -289,7 +314,9 @@ os_file_rename
os_aio
os_file_read
os_file_read_no_error_handling
os_file_read_no_error_handling_int_fd
os_file_write
os_file_write_int_fd
The wrapper functions have the prefix of "innodb_". */
@ -307,7 +334,7 @@ The wrapper functions have the prefix of "innodb_". */
pfs_os_file_create_simple_no_error_handling_func( \
key, name, create_mode, access, success, __FILE__, __LINE__)
# define os_file_close(file) \
# define os_file_close_pfs(file) \
pfs_os_file_close_func(file, __FILE__, __LINE__)
# define os_aio(type, mode, name, file, buf, offset, \
@ -315,18 +342,27 @@ The wrapper functions have the prefix of "innodb_". */
pfs_os_aio_func(type, mode, name, file, buf, offset, \
n, message1, message2, __FILE__, __LINE__)
# define os_file_read(file, buf, offset, n) \
# define os_file_read_pfs(file, buf, offset, n) \
pfs_os_file_read_func(file, buf, offset, n, __FILE__, __LINE__)
# define os_file_read_no_error_handling(file, buf, offset, n) \
pfs_os_file_read_no_error_handling_func(file, buf, offset, n, \
__FILE__, __LINE__)
# define os_file_write(name, file, buf, offset, n) \
# define os_file_read_no_error_handling_int_fd( \
file, buf, offset, n) \
pfs_os_file_read_no_error_handling_int_fd_func( \
file, buf, offset, n, __FILE__, __LINE__)
# define os_file_write_pfs(name, file, buf, offset, n) \
pfs_os_file_write_func(name, file, buf, offset, \
n, __FILE__, __LINE__)
# define os_file_flush(file) \
# define os_file_write_int_fd(name, file, buf, offset, n) \
pfs_os_file_write_int_fd_func(name, file, buf, offset, \
n, __FILE__, __LINE__)
# define os_file_flush_pfs(file) \
pfs_os_file_flush_func(file, __FILE__, __LINE__)
# define os_file_rename(key, oldpath, newpath) \
@ -352,22 +388,29 @@ to original un-instrumented file I/O APIs */
os_file_create_simple_no_error_handling_func( \
name, create_mode, access, success)
# define os_file_close(file) os_file_close_func(file)
# define os_file_close_pfs(file) \
os_file_close_func(file)
# define os_aio(type, mode, name, file, buf, offset, n, message1, message2) \
os_aio_func(type, mode, name, file, buf, offset, n, \
message1, message2)
# define os_file_read(file, buf, offset, n) \
# define os_file_read_pfs(file, buf, offset, n) \
os_file_read_func(file, buf, offset, n)
# define os_file_read_no_error_handling(file, buf, offset, n) \
os_file_read_no_error_handling_func(file, buf, offset, n)
# define os_file_read_no_error_handling_int_fd( \
file, buf, offset, n) \
os_file_read_no_error_handling_func(file, buf, offset, n)
# define os_file_write(name, file, buf, offset, n) \
# define os_file_write_int_fd(name, file, buf, offset, n) \
os_file_write_func(name, file, buf, offset, n)
# define os_file_write_pfs(name, file, buf, offset, n) \
os_file_write_func(name, file, buf, offset, n)
# define os_file_flush(file) os_file_flush_func(file)
# define os_file_flush_pfs(file) os_file_flush_func(file)
# define os_file_rename(key, oldpath, newpath) \
os_file_rename_func(oldpath, newpath)
@ -379,6 +422,33 @@ to original un-instrumented file I/O APIs */
#endif /* UNIV_PFS_IO */
#ifdef UNIV_PFS_IO
#define os_file_close(file) os_file_close_pfs(file)
#else
#define os_file_close(file) os_file_close_pfs((file).m_file)
#endif
#ifdef UNIV_PFS_IO
#define os_file_read(file, buf, offset, n) \
os_file_read_pfs(file, buf, offset, n)
#else
#define os_file_read(file, buf, offset, n) \
os_file_read_pfs(file.m_file, buf, offset, n)
#endif
#ifdef UNIV_PFS_IO
#define os_file_flush(file) os_file_flush_pfs(file)
#else
#define os_file_flush(file) os_file_flush_pfs(file.m_file)
#endif
#ifdef UNIV_PFS_IO
#define os_file_write(name, file, buf, offset, n) \
os_file_write_pfs(name, file, buf, offset, n)
#else
#define os_file_write(name, file, buf, offset, n) \
os_file_write_pfs(name, file.m_file, buf, offset, n)
#endif
/* File types for directory entry data type */
enum os_file_type_t {
@ -518,7 +588,7 @@ A simple function to open or create a file.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
pfs_os_file_t
os_file_create_simple_no_error_handling_func(
/*=========================================*/
const char* name, /*!< in: name of the file or path as a
@ -548,7 +618,7 @@ Opens an existing file or creates a new.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
pfs_os_file_t
os_file_create_func(
/*================*/
const char* name, /*!< in: name of the file or path as a
@ -617,7 +687,7 @@ os_file_create_simple() which opens or creates a file.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
os_file_t
pfs_os_file_t
pfs_os_file_create_simple_func(
/*===========================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@ -640,7 +710,7 @@ monitor file creation/open.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
os_file_t
pfs_os_file_t
pfs_os_file_create_simple_no_error_handling_func(
/*=============================================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@ -664,7 +734,7 @@ Add instrumentation to monitor file creation/open.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
os_file_t
pfs_os_file_t
pfs_os_file_create_func(
/*====================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@ -693,7 +763,7 @@ UNIV_INLINE
ibool
pfs_os_file_close_func(
/*===================*/
os_file_t file, /*!< in, own: handle to a file */
pfs_os_file_t file, /*!< in, own: handle to a file */
const char* src_file,/*!< in: file name where func invoked */
ulint src_line);/*!< in: line where the func invoked */
/*******************************************************************//**
@ -706,7 +776,7 @@ UNIV_INLINE
ibool
pfs_os_file_read_func(
/*==================*/
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */
@ -724,7 +794,7 @@ UNIV_INLINE
ibool
pfs_os_file_read_no_error_handling_func(
/*====================================*/
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */
@ -745,7 +815,7 @@ pfs_os_aio_func(
ulint mode, /*!< in: OS_AIO_NORMAL etc. I/O mode */
const char* name, /*!< in: name of the file or path as a
null-terminated string */
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read or from which
to write */
os_offset_t offset, /*!< in: file offset where to read or write */
@ -772,7 +842,7 @@ pfs_os_file_write_func(
/*===================*/
const char* name, /*!< in: name of the file or path as a
null-terminated string */
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
const void* buf, /*!< in: buffer from which to write */
os_offset_t offset, /*!< in: file offset where to write */
ulint n, /*!< in: number of bytes to write */
@ -789,7 +859,7 @@ UNIV_INLINE
ibool
pfs_os_file_flush_func(
/*===================*/
os_file_t file, /*!< in, own: handle to a file */
pfs_os_file_t file, /*!< in, own: handle to a file */
const char* src_file,/*!< in: file name where func invoked */
ulint src_line);/*!< in: line where the func invoked */
@ -860,7 +930,7 @@ UNIV_INTERN
os_offset_t
os_file_get_size(
/*=============*/
os_file_t file) /*!< in: handle to a file */
pfs_os_file_t file) /*!< in: handle to a file */
MY_ATTRIBUTE((warn_unused_result));
/***********************************************************************//**
Write the specified number of zeros to a newly created file.
@ -871,7 +941,7 @@ os_file_set_size(
/*=============*/
const char* name, /*!< in: name of the file or path as a
null-terminated string */
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
os_offset_t size) /*!< in: file size */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/***********************************************************************//**
@ -1109,7 +1179,7 @@ os_aio_func(
caution! */
const char* name, /*!< in: name of the file or path as a
null-terminated string */
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read or from which
to write */
os_offset_t offset, /*!< in: file offset where to read or write */

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
the terms of the GNU General Public License as published by the Free Software
@ -34,7 +34,7 @@ os_file_create_simple() which opens or creates a file.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
os_file_t
pfs_os_file_t
pfs_os_file_create_simple_func(
/*===========================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@ -47,7 +47,7 @@ pfs_os_file_create_simple_func(
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
os_file_t file;
pfs_os_file_t file;
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
@ -58,11 +58,13 @@ pfs_os_file_create_simple_func(
: PSI_FILE_OPEN),
name, src_file, src_line);
file = os_file_create_simple_func(name, create_mode,
file.m_file = os_file_create_simple_func(name, create_mode,
access_type, success);
file.m_psi = NULL;
/* Regsiter the returning "file" value with the system */
register_pfs_file_open_end(locker, file);
/* Regsiter psi value for the file */
register_pfs_file_open_end(locker, file,
(*success == TRUE ? success : 0));
return(file);
}
@ -76,7 +78,7 @@ monitor file creation/open.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
os_file_t
pfs_os_file_t
pfs_os_file_create_simple_no_error_handling_func(
/*=============================================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@ -91,7 +93,7 @@ pfs_os_file_create_simple_no_error_handling_func(
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
os_file_t file;
pfs_os_file_t file;
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
@ -104,8 +106,10 @@ pfs_os_file_create_simple_no_error_handling_func(
file = os_file_create_simple_no_error_handling_func(
name, create_mode, access_type, success);
file.m_psi = NULL;
register_pfs_file_open_end(locker, file);
register_pfs_file_open_end(locker, file,
(*success == TRUE ? success : 0));
return(file);
}
@ -118,7 +122,7 @@ Add instrumentation to monitor file creation/open.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INLINE
os_file_t
pfs_os_file_t
pfs_os_file_create_func(
/*====================*/
mysql_pfs_key_t key, /*!< in: Performance Schema Key */
@ -137,7 +141,7 @@ pfs_os_file_create_func(
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
os_file_t file;
pfs_os_file_t file;
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
@ -149,8 +153,10 @@ pfs_os_file_create_func(
name, src_file, src_line);
file = os_file_create_func(name, create_mode, purpose, type, success);
file.m_psi = NULL;
register_pfs_file_open_end(locker, file);
register_pfs_file_open_end(locker, file,
(*success == TRUE ? success : 0));
return(file);
}
@ -164,7 +170,7 @@ UNIV_INLINE
ibool
pfs_os_file_close_func(
/*===================*/
os_file_t file, /*!< in, own: handle to a file */
pfs_os_file_t file, /*!< in, own: handle to a file */
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
@ -176,7 +182,7 @@ pfs_os_file_close_func(
register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_CLOSE,
src_file, src_line);
result = os_file_close_func(file);
result = os_file_close_func(file.m_file);
register_pfs_file_io_end(locker, 0);
@ -197,7 +203,7 @@ pfs_os_aio_func(
ulint mode, /*!< in: OS_AIO_NORMAL etc. I/O mode */
const char* name, /*!< in: name of the file or path as a
null-terminated string */
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read or from which
to write */
os_offset_t offset, /*!< in: file offset where to read or write */
@ -242,7 +248,7 @@ UNIV_INLINE
ibool
pfs_os_file_read_func(
/*==================*/
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */
@ -256,7 +262,7 @@ pfs_os_file_read_func(
register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ,
src_file, src_line);
result = os_file_read_func(file, buf, offset, n);
result = os_file_read_func(file.m_file, buf, offset, n);
register_pfs_file_io_end(locker, n);
@ -275,7 +281,7 @@ UNIV_INLINE
ibool
pfs_os_file_read_no_error_handling_func(
/*====================================*/
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */
@ -289,13 +295,50 @@ pfs_os_file_read_no_error_handling_func(
register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ,
src_file, src_line);
result = os_file_read_no_error_handling_func(file, buf, offset, n);
result = os_file_read_no_error_handling_func(file.m_file, buf, offset, n);
register_pfs_file_io_end(locker, n);
return(result);
}
/** NOTE! Please use the corresponding macro
os_file_read_no_error_handling_int_fd(), not directly this function!
This is the performance schema instrumented wrapper function for
os_file_read_no_error_handling_int_fd_func() which requests a
synchronous read operation.
@return TRUE if request was successful, FALSE if fail */
UNIV_INLINE
ibool
pfs_os_file_read_no_error_handling_int_fd_func(
int file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read */
os_offset_t offset, /*!< in: file offset where to read */
ulint n, /*!< in: number of bytes to read */
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
PSI_file_locker_state state;
struct PSI_file_locker* locker = NULL;
locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
&state, file, PSI_FILE_READ);
if (locker != NULL) {
PSI_FILE_CALL(start_file_wait)(
locker, n,
__FILE__, __LINE__);
}
ibool result = os_file_read_no_error_handling_func(
OS_FILE_FROM_FD(file), buf, offset, n);
if (locker != NULL) {
PSI_FILE_CALL(end_file_wait)(locker, n);
}
return(result);
}
/*******************************************************************//**
NOTE! Please use the corresponding macro os_file_write(), not directly
this function!
@ -308,7 +351,7 @@ pfs_os_file_write_func(
/*===================*/
const char* name, /*!< in: name of the file or path as a
null-terminated string */
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
const void* buf, /*!< in: buffer from which to write */
os_offset_t offset, /*!< in: file offset where to write */
ulint n, /*!< in: number of bytes to write */
@ -322,13 +365,50 @@ pfs_os_file_write_func(
register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_WRITE,
src_file, src_line);
result = os_file_write_func(name, file, buf, offset, n);
result = os_file_write_func(name, file.m_file, buf, offset, n);
register_pfs_file_io_end(locker, n);
return(result);
}
/** NOTE! Please use the corresponding macro os_file_write(), not
directly this function!
This is the performance schema instrumented wrapper function for
os_file_write() which requests a synchronous write operation.
@return TRUE if request was successful, FALSE if fail */
UNIV_INLINE
ibool
pfs_os_file_write_int_fd_func(
const char* name, /*!< in: name of the file or path as a
null-terminated string */
int file, /*!< in: handle to a file */
const void* buf, /*!< in: buffer from which to write */
os_offset_t offset, /*!< in: file offset where to write */
ulint n, /*!< in: number of bytes to write */
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
PSI_file_locker_state state;
struct PSI_file_locker* locker = NULL;
locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
&state, file, PSI_FILE_WRITE);
if (locker != NULL) {
PSI_FILE_CALL(start_file_wait)(
locker, n,
__FILE__, __LINE__);
}
ibool result = os_file_write_func(
name, OS_FILE_FROM_FD(file), buf, offset, n);
if (locker != NULL) {
PSI_FILE_CALL(end_file_wait)(locker, n);
}
return(result);
}
/***********************************************************************//**
NOTE! Please use the corresponding macro os_file_flush(), not directly
this function!
@ -339,7 +419,7 @@ UNIV_INLINE
ibool
pfs_os_file_flush_func(
/*===================*/
os_file_t file, /*!< in, own: handle to a file */
pfs_os_file_t file, /*!< in, own: handle to a file */
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
@ -349,7 +429,7 @@ pfs_os_file_flush_func(
register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_SYNC,
src_file, src_line);
result = os_file_flush_func(file);
result = os_file_flush_func(file.m_file);
register_pfs_file_io_end(locker, 0);
@ -377,12 +457,12 @@ pfs_os_file_rename_func(
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
register_pfs_file_open_begin(&state, locker, key, PSI_FILE_RENAME, newpath,
register_pfs_file_rename_begin(&state, locker, key, PSI_FILE_RENAME, newpath,
src_file, src_line);
result = os_file_rename_func(oldpath, newpath);
register_pfs_file_open_end(locker, 0);
register_pfs_file_rename_end(locker, 0);
return(result);
}

View File

@ -652,6 +652,8 @@ struct mysql_row_templ_t {
#define ROW_PREBUILT_ALLOCATED 78540783
#define ROW_PREBUILT_FREED 26423527
class ha_innobase;
/** A struct for (sometimes lazily) prebuilt structures in an Innobase table
handle used within MySQL; these are used to save CPU time. */
@ -879,6 +881,12 @@ struct row_prebuilt_t {
to InnoDB format.*/
uint srch_key_val_len; /*!< Size of search key */
/** MySQL handler object. */
ha_innobase* mysql_handler;
/** True if exceeded the end_range while filling the prefetch cache. */
bool end_range;
};
/** Callback for row_mysql_sys_index_iterate() */

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) 2009, Percona Inc.
@ -785,6 +785,13 @@ void
srv_purge_wakeup(void);
/*==================*/
/** Check whether given space id is undo tablespace id
@param[in] space_id space id to check
@return true if it is undo tablespace else false. */
bool
srv_is_undo_tablespace(
ulint space_id);
/** Status variables to be passed to MySQL */
struct export_var_t{
ulint innodb_data_pending_reads; /*!< Pending reads */

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
the terms of the GNU General Public License as published by the Free Software
@ -139,6 +139,8 @@ extern ibool srv_startup_is_before_trx_rollback_phase;
/** TRUE if a raw partition is in use */
extern ibool srv_start_raw_disk_in_use;
/** Undo tablespaces starts with space_id. */
extern ulint srv_undo_space_id_start;
/** Shutdown state */
enum srv_shutdown_state {

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
the terms of the GNU General Public License as published by the Free Software
@ -24,6 +24,8 @@ this program; if not, write to the Free Software Foundation, Inc.,
#ifndef XA_H
#define XA_H
#include "xa.h"
/*
* Transaction branch identification: XID and NULLXID:
*/
@ -35,17 +37,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
#define MAXGTRIDSIZE 64 /*!< maximum size in bytes of gtrid */
#define MAXBQUALSIZE 64 /*!< maximum size in bytes of bqual */
/** X/Open XA distributed transaction identifier */
struct xid_t {
long formatID; /*!< format identifier; -1
means that the XID is null */
long gtrid_length; /*!< value from 1 through 64 */
long bqual_length; /*!< value from 1 through 64 */
char data[XIDDATASIZE]; /*!< distributed transaction
identifier */
};
/** X/Open XA distributed transaction identifier */
typedef struct xid_t XID;
#endif
/** X/Open XA distributed transaction status codes */
/* @{ */

View File

@ -133,14 +133,8 @@ HAVE_PSI_INTERFACE is defined. */
#if defined HAVE_PSI_INTERFACE && !defined UNIV_HOTBACKUP
# define UNIV_PFS_MUTEX
# define UNIV_PFS_RWLOCK
/* For I/O instrumentation, performance schema rely
on a native descriptor to identify the file, this
descriptor could conflict with our OS level descriptor.
Disable IO instrumentation on Windows until this is
resolved */
# ifndef __WIN__
# define UNIV_PFS_IO
# endif
# define UNIV_PFS_IO
# define UNIV_PFS_THREAD
/* There are mutexes/rwlocks that we want to exclude from

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.
Portions of this file contain modifications contributed and copyrighted by
@ -3406,7 +3406,12 @@ loop:
lsn = log_sys->lsn;
if (lsn != log_sys->last_checkpoint_lsn
const bool is_last = ((srv_force_recovery == SRV_FORCE_NO_LOG_REDO
&& lsn == log_sys->last_checkpoint_lsn
+ LOG_BLOCK_HDR_SIZE)
|| lsn == log_sys->last_checkpoint_lsn);
if (!is_last
#ifdef UNIV_LOG_ARCHIVE
|| (srv_log_archive_on
&& lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE)

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

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.
Portions of this file contain modifications contributed and copyrighted
@ -163,7 +163,7 @@ struct os_aio_slot_t{
byte* buf; /*!< buffer used in i/o */
ulint type; /*!< OS_FILE_READ or OS_FILE_WRITE */
os_offset_t offset; /*!< file offset in bytes */
os_file_t file; /*!< file where to read or write */
pfs_os_file_t file; /*!< file where to read or write */
const char* name; /*!< file name or path */
ibool io_already_done;/*!< used only in simulated aio:
TRUE if the physical i/o already
@ -1306,7 +1306,7 @@ A simple function to open or create a file.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
pfs_os_file_t
os_file_create_simple_no_error_handling_func(
/*=========================================*/
const char* name, /*!< in: name of the file or path as a
@ -1318,7 +1318,7 @@ os_file_create_simple_no_error_handling_func(
used by a backup program reading the file */
ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
os_file_t file;
pfs_os_file_t file;
*success = FALSE;
#ifdef __WIN__
@ -1326,7 +1326,6 @@ os_file_create_simple_no_error_handling_func(
DWORD create_flag;
DWORD attributes = 0;
DWORD share_mode = FILE_SHARE_READ;
ut_a(name);
ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT));
@ -1343,8 +1342,8 @@ os_file_create_simple_no_error_handling_func(
ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown file create mode (%lu) for file '%s'",
create_mode, name);
return((os_file_t) -1);
file.m_file = (os_file_t)-1;
return(file);
}
if (access_type == OS_FILE_READ_ONLY) {
@ -1367,11 +1366,11 @@ os_file_create_simple_no_error_handling_func(
ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown file access type (%lu) for file '%s'",
access_type, name);
return((os_file_t) -1);
file.m_file = (os_file_t)-1;
return(file);
}
file = CreateFile((LPCTSTR) name,
file.m_file = CreateFile((LPCTSTR) name,
access,
share_mode,
NULL, // Security attributes
@ -1379,11 +1378,10 @@ os_file_create_simple_no_error_handling_func(
attributes,
NULL); // No template file
*success = (file != INVALID_HANDLE_VALUE);
*success = (file.m_file != INVALID_HANDLE_VALUE);
#else /* __WIN__ */
int create_flag;
const char* mode_str = NULL;
ut_a(name);
ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT));
@ -1425,13 +1423,13 @@ os_file_create_simple_no_error_handling_func(
ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown file create mode (%lu) for file '%s'",
create_mode, name);
return((os_file_t) -1);
file.m_file = -1;
return(file);
}
file = ::open(name, create_flag, os_innodb_umask);
file.m_file = ::open(name, create_flag, os_innodb_umask);
*success = file == -1 ? FALSE : TRUE;
*success = file.m_file == -1 ? FALSE : TRUE;
/* This function is always called for data files, we should disable
OS caching (O_DIRECT) here as we do in os_file_create_func(), so
@ -1441,18 +1439,18 @@ os_file_create_simple_no_error_handling_func(
&& (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT
|| srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)) {
os_file_set_nocache(file, name, mode_str);
os_file_set_nocache(file.m_file, name, mode_str);
}
#ifdef USE_FILE_LOCK
if (!srv_read_only_mode
&& *success
&& access_type == OS_FILE_READ_WRITE
&& os_file_lock(file, name)) {
&& os_file_lock(file.m_file, name)) {
*success = FALSE;
close(file);
file = -1;
close(file.m_file);
file.m_file = -1;
}
#endif /* USE_FILE_LOCK */
@ -1527,7 +1525,7 @@ Opens an existing file or creates a new.
@return own: handle to the file, not defined if error, error number
can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
pfs_os_file_t
os_file_create_func(
/*================*/
const char* name, /*!< in: name of the file or path as a
@ -1543,24 +1541,25 @@ os_file_create_func(
ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */
ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
os_file_t file;
pfs_os_file_t file;
ibool retry;
ibool on_error_no_exit;
ibool on_error_silent;
#ifdef __WIN__
DBUG_EXECUTE_IF(
"ib_create_table_fail_disk_full",
*success = FALSE;
SetLastError(ERROR_DISK_FULL);
return((os_file_t) -1);
file.m_file = (os_file_t)-1;
return(file);
);
#else /* __WIN__ */
DBUG_EXECUTE_IF(
"ib_create_table_fail_disk_full",
*success = FALSE;
errno = ENOSPC;
return((os_file_t) -1);
file.m_file = -1;
return(file);
);
#endif /* __WIN__ */
@ -1611,7 +1610,8 @@ os_file_create_func(
"Unknown file create mode (%lu) for file '%s'",
create_mode, name);
return((os_file_t) -1);
file.m_file = (os_file_t)-1;
return(file);
}
DWORD attributes = 0;
@ -1636,8 +1636,8 @@ os_file_create_func(
ib_logf(IB_LOG_LEVEL_ERROR,
"Unknown purpose flag (%lu) while opening file '%s'",
purpose, name);
return((os_file_t)(-1));
file.m_file = (os_file_t)-1;
return(file);
}
#ifdef UNIV_NON_BUFFERED_IO
@ -1664,11 +1664,11 @@ os_file_create_func(
do {
/* Use default security attributes and no template file. */
file = CreateFile(
file.m_file = CreateFile(
(LPCTSTR) name, access, share_mode, NULL,
create_flag, attributes, NULL);
if (file == INVALID_HANDLE_VALUE) {
if (file.m_file == INVALID_HANDLE_VALUE) {
const char* operation;
operation = (create_mode == OS_FILE_CREATE
@ -1693,7 +1693,6 @@ os_file_create_func(
#else /* __WIN__ */
int create_flag;
const char* mode_str = NULL;
on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT
? TRUE : FALSE;
on_error_silent = create_mode & OS_FILE_ON_ERROR_SILENT
@ -1731,7 +1730,8 @@ os_file_create_func(
"Unknown file create mode (%lu) for file '%s'",
create_mode, name);
return((os_file_t) -1);
file.m_file = -1;
return(file);
}
ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE);
@ -1751,9 +1751,9 @@ os_file_create_func(
#endif /* O_SYNC */
do {
file = ::open(name, create_flag, os_innodb_umask);
file.m_file = ::open(name, create_flag, os_innodb_umask);
if (file == -1) {
if (file.m_file == -1) {
const char* operation;
operation = (create_mode == OS_FILE_CREATE
@ -1783,14 +1783,14 @@ os_file_create_func(
&& (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT
|| srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)) {
os_file_set_nocache(file, name, mode_str);
os_file_set_nocache(file.m_file, name, mode_str);
}
#ifdef USE_FILE_LOCK
if (!srv_read_only_mode
&& *success
&& create_mode != OS_FILE_OPEN_RAW
&& os_file_lock(file, name)) {
&& os_file_lock(file.m_file, name)) {
if (create_mode == OS_FILE_OPEN_RETRY) {
@ -1802,7 +1802,7 @@ os_file_create_func(
for (int i = 0; i < 100; i++) {
os_thread_sleep(1000000);
if (!os_file_lock(file, name)) {
if (!os_file_lock(file.m_file, name)) {
*success = TRUE;
return(file);
}
@ -1813,8 +1813,8 @@ os_file_create_func(
}
*success = FALSE;
close(file);
file = -1;
close(file.m_file);
file.m_file = -1;
}
#endif /* USE_FILE_LOCK */
@ -2086,14 +2086,14 @@ UNIV_INTERN
os_offset_t
os_file_get_size(
/*=============*/
os_file_t file) /*!< in: handle to a file */
pfs_os_file_t file) /*!< in: handle to a file */
{
#ifdef __WIN__
os_offset_t offset;
DWORD high;
DWORD low;
low = GetFileSize(file, &high);
low = GetFileSize(file.m_file, &high);
if ((low == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) {
return((os_offset_t) -1);
@ -2103,7 +2103,8 @@ os_file_get_size(
return(offset);
#else
return((os_offset_t) lseek(file, 0, SEEK_END));
return((os_offset_t) lseek(file.m_file, 0, SEEK_END));
#endif /* __WIN__ */
}
@ -2116,7 +2117,7 @@ os_file_set_size(
/*=============*/
const char* name, /*!< in: name of the file or path as a
null-terminated string */
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
os_offset_t size) /*!< in: file size */
{
os_offset_t current_size;
@ -4187,7 +4188,7 @@ os_aio_array_reserve_slot(
the aio operation */
void* message2,/*!< in: message to be passed along with
the aio operation */
os_file_t file, /*!< in: file handle */
pfs_os_file_t file, /*!< in: file handle */
const char* name, /*!< in: name of the file or path as a
null-terminated string */
void* buf, /*!< in: buffer where to read or from which
@ -4307,10 +4308,10 @@ found:
iocb = &slot->control;
if (type == OS_FILE_READ) {
io_prep_pread(iocb, file, buf, len, aio_offset);
io_prep_pread(iocb, file.m_file, buf, len, aio_offset);
} else {
ut_a(type == OS_FILE_WRITE);
io_prep_pwrite(iocb, file, buf, len, aio_offset);
io_prep_pwrite(iocb, file.m_file, buf, len, aio_offset);
}
iocb->data = (void*) slot;
@ -4548,7 +4549,7 @@ os_aio_func(
caution! */
const char* name, /*!< in: name of the file or path as a
null-terminated string */
os_file_t file, /*!< in: handle to a file */
pfs_os_file_t file, /*!< in: handle to a file */
void* buf, /*!< in: buffer where to read or from which
to write */
os_offset_t offset, /*!< in: file offset where to read or write */
@ -4573,8 +4574,7 @@ os_aio_func(
ulint dummy_type;
#endif /* WIN_ASYNC_IO */
ulint wake_later;
ut_ad(file);
ut_ad(file.m_file);
ut_ad(buf);
ut_ad(n > 0);
ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0);
@ -4606,13 +4606,11 @@ os_aio_func(
and os_file_write_func() */
if (type == OS_FILE_READ) {
return(os_file_read_func(file, buf, offset, n));
return(os_file_read_func(file.m_file, buf, offset, n));
}
ut_ad(!srv_read_only_mode);
ut_a(type == OS_FILE_WRITE);
return(os_file_write_func(name, file, buf, offset, n));
return(os_file_write_func(name, file.m_file, buf, offset, n));
}
try_again:
@ -4664,9 +4662,8 @@ try_again:
os_n_file_reads++;
os_bytes_read_since_printout += n;
#ifdef WIN_ASYNC_IO
ret = ReadFile(file, buf, (DWORD) n, &len,
ret = ReadFile(file.m_file, buf, (DWORD) n, &len,
&(slot->control));
#elif defined(LINUX_NATIVE_AIO)
if (!os_aio_linux_dispatch(array, slot)) {
goto err_exit;
@ -4684,9 +4681,8 @@ try_again:
if (srv_use_native_aio) {
os_n_file_writes++;
#ifdef WIN_ASYNC_IO
ret = WriteFile(file, buf, (DWORD) n, &len,
ret = WriteFile(file.m_file, buf, (DWORD) n, &len,
&(slot->control));
#elif defined(LINUX_NATIVE_AIO)
if (!os_aio_linux_dispatch(array, slot)) {
goto err_exit;
@ -4840,8 +4836,7 @@ os_aio_windows_handle(
srv_set_io_thread_op_info(
orig_seg, "get windows aio return value");
}
ret = GetOverlappedResult(slot->file, &(slot->control), &len, TRUE);
ret = GetOverlappedResult(slot->file.m_file, &(slot->control), &len, TRUE);
*message1 = slot->message1;
*message2 = slot->message2;
@ -4870,7 +4865,8 @@ os_aio_windows_handle(
and os_file_write APIs, need to register with
performance schema explicitly here. */
struct PSI_file_locker* locker = NULL;
register_pfs_file_io_begin(locker, slot->file, slot->len,
PSI_file_locker_state state;
register_pfs_file_io_begin(&state, locker, slot->file, slot->len,
(slot->type == OS_FILE_WRITE)
? PSI_FILE_WRITE
: PSI_FILE_READ,
@ -4881,16 +4877,14 @@ os_aio_windows_handle(
switch (slot->type) {
case OS_FILE_WRITE:
ret = WriteFile(slot->file, slot->buf,
ret = WriteFile(slot->file.m_file, slot->buf,
(DWORD) slot->len, &len,
&(slot->control));
break;
case OS_FILE_READ:
ret = ReadFile(slot->file, slot->buf,
ret = ReadFile(slot->file.m_file, slot->buf,
(DWORD) slot->len, &len,
&(slot->control));
break;
default:
ut_error;
@ -4906,8 +4900,7 @@ os_aio_windows_handle(
file where we also use async i/o: in Windows
we must use the same wait mechanism as for
async i/o */
ret = GetOverlappedResult(slot->file,
ret = GetOverlappedResult(slot->file.m_file,
&(slot->control),
&len, TRUE);
}
@ -5354,12 +5347,11 @@ consecutive_loop:
os_aio_slot_t* slot;
slot = os_aio_array_get_nth_slot(array, i + segment * n);
if (slot->reserved
&& slot != aio_slot
&& slot->offset == aio_slot->offset + aio_slot->len
&& slot->type == aio_slot->type
&& slot->file == aio_slot->file) {
&& slot->file.m_file == aio_slot->file.m_file) {
/* Found a consecutive i/o request */

View File

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

View File

@ -869,8 +869,9 @@ row_merge_read(
}
#endif /* UNIV_DEBUG */
success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf,
success = os_file_read_no_error_handling_int_fd(fd, buf,
ofs, srv_sort_buf_size);
#ifdef POSIX_FADV_DONTNEED
/* Each block is read exactly once. Free up the file cache. */
posix_fadvise(fd, ofs, srv_sort_buf_size, POSIX_FADV_DONTNEED);
@ -904,7 +905,7 @@ row_merge_write(
DBUG_EXECUTE_IF("row_merge_write_failure", return(FALSE););
ret = os_file_write("(merge)", OS_FILE_FROM_FD(fd), buf, ofs, buf_len);
ret = os_file_write_int_fd("(merge)", fd, buf, ofs, buf_len);
#ifdef UNIV_DEBUG
if (row_merge_print_block_write) {
@ -3121,14 +3122,21 @@ row_merge_file_create_low(
performance schema */
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
register_pfs_file_open_begin(&state, locker, innodb_file_temp_key,
PSI_FILE_OPEN,
"Innodb Merge Temp File",
__FILE__, __LINE__);
locker = PSI_FILE_CALL(get_thread_file_name_locker)(
&state, innodb_file_temp_key, PSI_FILE_OPEN,
"Innodb Merge Temp File", &locker);
if (locker != NULL) {
PSI_FILE_CALL(start_file_open_wait)(locker,
__FILE__,
__LINE__);
}
#endif
fd = innobase_mysql_tmpfile(path);
#ifdef UNIV_PFS_IO
register_pfs_file_open_end(locker, fd);
if (locker != NULL) {
PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(
locker, fd);
}
#endif
if (fd < 0) {
@ -3175,15 +3183,20 @@ row_merge_file_destroy_low(
#ifdef UNIV_PFS_IO
struct PSI_file_locker* locker = NULL;
PSI_file_locker_state state;
register_pfs_file_io_begin(&state, locker,
fd, 0, PSI_FILE_CLOSE,
__FILE__, __LINE__);
locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
&state, fd, PSI_FILE_CLOSE);
if (locker != NULL) {
PSI_FILE_CALL(start_file_wait)(
locker, 0, __FILE__, __LINE__);
}
#endif
if (fd >= 0) {
close(fd);
}
#ifdef UNIV_PFS_IO
register_pfs_file_io_end(locker, 0);
if (locker != NULL) {
PSI_FILE_CALL(end_file_wait)(locker, 0);
}
#endif
}
/*********************************************************************//**

View File

@ -61,6 +61,9 @@ Created 12/19/1997 Heikki Tuuri
#include "my_sys.h" /* DEBUG_SYNC_C */
#include "my_compare.h" /* enum icp_result */
#include "thr_lock.h"
#include "handler.h"
#include "ha_innodb.h"
/* Maximum number of rows to prefetch; MySQL interface has another parameter */
#define SEL_MAX_N_PREFETCH 16
@ -2743,34 +2746,43 @@ row_sel_field_store_in_mysql_format_func(
#ifdef UNIV_DEBUG
/** Convert a field from Innobase format to MySQL format. */
# define row_sel_store_mysql_field(m,p,r,i,o,f,t) \
row_sel_store_mysql_field_func(m,p,r,i,o,f,t)
# define row_sel_store_mysql_field(m,p,r,i,o,f,t,c) \
row_sel_store_mysql_field_func(m,p,r,i,o,f,t,c)
#else /* UNIV_DEBUG */
/** Convert a field from Innobase format to MySQL format. */
# define row_sel_store_mysql_field(m,p,r,i,o,f,t) \
row_sel_store_mysql_field_func(m,p,r,o,f,t)
# define row_sel_store_mysql_field(m,p,r,i,o,f,t,c) \
row_sel_store_mysql_field_func(m,p,r,o,f,t,c)
#endif /* UNIV_DEBUG */
/**************************************************************//**
Convert a field in the Innobase format to a field in the MySQL format. */
/** Convert a field in the Innobase format to a field in the MySQL format.
@param[out] mysql_rec record in the MySQL format
@param[in,out] prebuilt prebuilt struct
@param[in] rec InnoDB record; must be protected
by a page latch
@param[in] index index of rec
@param[in] offsets array returned by rec_get_offsets()
@param[in] field_no templ->rec_field_no or
templ->clust_rec_field_no
or templ->icp_rec_field_no
or sec field no if clust_templ_for_sec
is TRUE
@param[in] templ row template
@param[in] clust_templ_for_sec TRUE if rec belongs to secondary index
but prebuilt template is in clustered
index format and used only for end
range comparison. */
static MY_ATTRIBUTE((warn_unused_result))
ibool
row_sel_store_mysql_field_func(
/*===========================*/
byte* mysql_rec, /*!< out: record in the
MySQL format */
row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct */
const rec_t* rec, /*!< in: InnoDB record;
must be protected by
a page latch */
byte* mysql_rec,
row_prebuilt_t* prebuilt,
const rec_t* rec,
#ifdef UNIV_DEBUG
const dict_index_t* index, /*!< in: index of rec */
const dict_index_t* index,
#endif
const ulint* offsets, /*!< in: array returned by
rec_get_offsets() */
ulint field_no, /*!< in: templ->rec_field_no or
templ->clust_rec_field_no or
templ->icp_rec_field_no */
const mysql_row_templ_t*templ) /*!< in: row template */
const ulint* offsets,
ulint field_no,
const mysql_row_templ_t*templ,
bool clust_templ_for_sec)
{
const byte* data;
ulint len;
@ -2779,10 +2791,12 @@ row_sel_store_mysql_field_func(
ut_ad(templ);
ut_ad(templ >= prebuilt->mysql_template);
ut_ad(templ < &prebuilt->mysql_template[prebuilt->n_template]);
ut_ad(field_no == templ->clust_rec_field_no
ut_ad(clust_templ_for_sec
|| field_no == templ->clust_rec_field_no
|| field_no == templ->rec_field_no
|| field_no == templ->icp_rec_field_no);
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(rec_offs_validate(rec,
clust_templ_for_sec == true ? prebuilt->index : index, offsets));
if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
@ -2896,30 +2910,37 @@ row_sel_store_mysql_field_func(
return(TRUE);
}
/**************************************************************//**
Convert a row in the Innobase format to a row in the MySQL format.
/** Convert a row in the Innobase format to a row in the MySQL format.
Note that the template in prebuilt may advise us to copy only a few
columns to mysql_rec, other columns are left blank. All columns may not
be needed in the query.
@param[out] mysql_rec row in the MySQL format
@param[in] prebuilt prebuilt structure
@param[in] rec Innobase record in the index
which was described in prebuilt's
template, or in the clustered index;
must be protected by a page latch
@param[in] rec_clust TRUE if the rec in the clustered index
@param[in] index index of rec
@param[in] offsets array returned by rec_get_offsets(rec)
@param[in] clust_templ_for_sec TRUE if rec belongs to secondary index
but the prebuilt->template is in
clustered index format and it is
used only for end range comparison
@return TRUE on success, FALSE if not all columns could be retrieved */
static MY_ATTRIBUTE((warn_unused_result))
ibool
row_sel_store_mysql_rec(
/*====================*/
byte* mysql_rec, /*!< out: row in the MySQL format */
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
const rec_t* rec, /*!< in: Innobase record in the index
which was described in prebuilt's
template, or in the clustered index;
must be protected by a page latch */
ibool rec_clust, /*!< in: TRUE if rec is in the
clustered index instead of
prebuilt->index */
const dict_index_t* index, /*!< in: index of rec */
const ulint* offsets) /*!< in: array returned by
rec_get_offsets(rec) */
byte* mysql_rec,
row_prebuilt_t* prebuilt,
const rec_t* rec,
ibool rec_clust,
const dict_index_t* index,
const ulint* offsets,
bool clust_templ_for_sec)
{
ulint i;
ulint i;
std::vector<ulint> template_col;
ut_ad(rec_clust || index == prebuilt->index);
ut_ad(!rec_clust || dict_index_is_clust(index));
@ -2929,9 +2950,20 @@ row_sel_store_mysql_rec(
prebuilt->blob_heap = NULL;
}
if (clust_templ_for_sec) {
/* Store all clustered index field of
secondary index record. */
for (i = 0; i < dict_index_get_n_fields(
prebuilt->index); i++) {
ulint sec_field = dict_index_get_nth_field_pos(
index, prebuilt->index, i);
template_col.push_back(sec_field);
}
}
for (i = 0; i < prebuilt->n_template; i++) {
const mysql_row_templ_t*templ = &prebuilt->mysql_template[i];
const ulint field_no
ulint field_no
= rec_clust
? templ->clust_rec_field_no
: templ->rec_field_no;
@ -2940,9 +2972,24 @@ row_sel_store_mysql_rec(
ut_ad(dict_index_get_nth_field(index, field_no)->prefix_len
== 0);
if (clust_templ_for_sec) {
std::vector<ulint>::iterator it;
it = std::find(template_col.begin(),
template_col.end(), field_no);
if (it == template_col.end()) {
continue;
}
ut_ad(templ->rec_field_no == templ->clust_rec_field_no);
field_no = it - template_col.begin();
}
if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
rec, index, offsets,
field_no, templ)) {
field_no, templ,
clust_templ_for_sec)) {
return(FALSE);
}
}
@ -3582,7 +3629,7 @@ row_search_idx_cond_check(
if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
rec, prebuilt->index, offsets,
templ->icp_rec_field_no,
templ)) {
templ, false)) {
return(ICP_NO_MATCH);
}
}
@ -3603,7 +3650,7 @@ row_search_idx_cond_check(
|| dict_index_is_clust(prebuilt->index)) {
if (!row_sel_store_mysql_rec(
mysql_rec, prebuilt, rec, FALSE,
prebuilt->index, offsets)) {
prebuilt->index, offsets, false)) {
ut_ad(dict_index_is_clust(prebuilt->index));
return(ICP_NO_MATCH);
}
@ -3622,6 +3669,27 @@ row_search_idx_cond_check(
return(result);
}
/** Check the pushed down end range condition to avoid extra traversal
if records are not within view and also to avoid prefetching in the
cache buffer.
@param[in] mysql_rec record in MySQL format
@param[in,out] handler the MySQL handler performing the scan
@retval true if the row in mysql_rec is out of range
@retval false if the row in mysql_rec is in range */
static
bool
row_search_end_range_check(
const byte* mysql_rec,
ha_innobase* handler)
{
if (handler->end_range &&
handler->compare_key_in_buffer(mysql_rec) > 0) {
return(true);
}
return(false);
}
/********************************************************************//**
Searches for rows in the database. This is used in the interface to
MySQL. This function opens a cursor, and also implements fetch next
@ -3659,7 +3727,9 @@ row_search_for_mysql(
trx_t* trx = prebuilt->trx;
dict_index_t* clust_index;
que_thr_t* thr;
const rec_t* rec;
const rec_t* prev_rec = NULL;
const rec_t* rec = NULL;
byte* end_range_cache = NULL;
const rec_t* result_rec = NULL;
const rec_t* clust_rec;
dberr_t err = DB_SUCCESS;
@ -3684,6 +3754,7 @@ row_search_for_mysql(
ulint* offsets = offsets_;
ibool table_lock_waited = FALSE;
byte* next_buf = 0;
ulint end_loop = 0;
rec_offs_init(offsets_);
@ -3823,6 +3894,10 @@ row_search_for_mysql(
err = DB_SUCCESS;
goto func_exit;
} else if (prebuilt->end_range == true) {
prebuilt->end_range = false;
err = DB_RECORD_NOT_FOUND;
goto func_exit;
}
if (prebuilt->fetch_cache_first > 0
@ -3956,7 +4031,8 @@ row_search_for_mysql(
if (!row_sel_store_mysql_rec(
buf, prebuilt,
rec, FALSE, index, offsets)) {
rec, FALSE, index,
offsets, false)) {
/* Only fresh inserts may contain
incomplete externally stored
columns. Pretend that such
@ -4205,11 +4281,62 @@ rec_loop:
and neither can a record lock be placed on it: we skip such
a record. */
prev_rec = NULL;
goto next_rec;
}
if (page_rec_is_supremum(rec)) {
/** Compare the last record of the page with end range
passed to InnoDB when there is no ICP and number of loops
in row_search_for_mysql for rows found but not
reporting due to search views etc. */
if (prev_rec != NULL
&& prebuilt->mysql_handler->end_range != NULL
&& prebuilt->idx_cond == NULL
&& end_loop >= 100) {
dict_index_t* key_index = prebuilt->index;
bool clust_templ_for_sec = false;
if (end_range_cache == NULL) {
end_range_cache = static_cast<byte*>(
ut_malloc(prebuilt->mysql_row_len));
}
if (index != clust_index
&& prebuilt->need_to_access_clustered) {
/** Secondary index record but the template
based on PK. */
key_index = clust_index;
clust_templ_for_sec = true;
}
/** Create offsets based on prebuilt index. */
offsets = rec_get_offsets(prev_rec, prebuilt->index,
offsets, ULINT_UNDEFINED, &heap);
if (row_sel_store_mysql_rec(
end_range_cache, prebuilt, prev_rec,
clust_templ_for_sec, key_index, offsets,
clust_templ_for_sec)) {
if (row_search_end_range_check(
end_range_cache,
prebuilt->mysql_handler)) {
/** In case of prebuilt->fetch,
set the error in prebuilt->end_range. */
if (prebuilt->n_fetch_cached > 0) {
prebuilt->end_range = true;
}
err = DB_RECORD_NOT_FOUND;
goto normal_return;
}
}
}
if (set_also_gap_locks
&& !(srv_locks_unsafe_for_binlog
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED)
@ -4241,6 +4368,7 @@ rec_loop:
/* A page supremum record cannot be in the result set: skip
it now that we have placed a possible lock on it */
prev_rec = NULL;
goto next_rec;
}
@ -4308,6 +4436,7 @@ wrong_offs:
btr_pcur_move_to_last_on_page(pcur, &mtr);
prev_rec = NULL;
goto next_rec;
}
}
@ -4334,10 +4463,13 @@ wrong_offs:
fputs(". We try to skip the record.\n",
stderr);
prev_rec = NULL;
goto next_rec;
}
}
prev_rec = rec;
/* Note that we cannot trust the up_match value in the cursor at this
place because we can arrive here after moving the cursor! Thus
we have to recompare rec and search_tuple to determine if they
@ -4562,6 +4694,7 @@ no_gap_lock:
did_semi_consistent_read = TRUE;
rec = old_vers;
prev_rec = rec;
break;
default:
@ -4608,6 +4741,7 @@ no_gap_lock:
}
rec = old_vers;
prev_rec = rec;
}
} else {
/* We are looking into a non-clustered index,
@ -4785,7 +4919,7 @@ requires_clust_rec:
appropriate version of the clustered index record. */
if (!row_sel_store_mysql_rec(
buf, prebuilt, result_rec,
TRUE, clust_index, offsets)) {
TRUE, clust_index, offsets, false)) {
goto next_rec;
}
}
@ -4853,7 +4987,7 @@ requires_clust_rec:
next_buf, prebuilt, result_rec,
result_rec != rec,
result_rec != rec ? clust_index : index,
offsets)) {
offsets, false)) {
if (next_buf == buf) {
ut_a(prebuilt->n_fetch_cached == 0);
@ -4908,7 +5042,7 @@ requires_clust_rec:
buf, prebuilt, result_rec,
result_rec != rec,
result_rec != rec ? clust_index : index,
offsets)) {
offsets, false)) {
/* Only fresh inserts may contain
incomplete externally stored
columns. Pretend that such records do
@ -4960,6 +5094,8 @@ idx_cond_failed:
goto normal_return;
next_rec:
end_loop++;
/* Reset the old and new "did semi-consistent read" flags. */
if (UNIV_UNLIKELY(prebuilt->row_read_type
== ROW_READ_DID_SEMI_CONSISTENT)) {
@ -5146,6 +5282,11 @@ normal_return:
func_exit:
trx->op_info = "";
if (end_range_cache != NULL) {
ut_free(end_range_cache);
}
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}

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) 2009, Percona Inc.
@ -2315,6 +2315,8 @@ DECLARE_THREAD(srv_master_thread)(
/*!< in: a dummy parameter required by
os_thread_create */
{
my_thread_init();
srv_slot_t* slot;
ulint old_activity_count = srv_get_activity_count();
ib_time_t last_print_time;
@ -2376,6 +2378,7 @@ suspend_thread:
os_event_wait(slot->event);
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
my_thread_end();
os_thread_exit(NULL);
}
@ -2458,6 +2461,8 @@ DECLARE_THREAD(srv_worker_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */
{
my_thread_init();
srv_slot_t* slot;
ut_ad(!srv_read_only_mode);
@ -2516,6 +2521,7 @@ DECLARE_THREAD(srv_worker_thread)(
os_thread_pf(os_thread_get_curr_id()));
#endif /* UNIV_DEBUG_THREAD_CREATION */
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
@ -2716,6 +2722,8 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter
required by os_thread_create */
{
my_thread_init();
srv_slot_t* slot;
ulint n_total_purged = ULINT_UNDEFINED;
@ -2821,6 +2829,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
srv_release_threads(SRV_WORKER, srv_n_purge_threads - 1);
}
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
@ -2889,3 +2898,18 @@ srv_purge_wakeup(void)
}
}
/** Check whether given space id is undo tablespace id
@param[in] space_id space id to check
@return true if it is undo tablespace else false. */
bool
srv_is_undo_tablespace(
ulint space_id)
{
if (srv_undo_space_id_start == 0) {
return (false);
}
return(space_id >= srv_undo_space_id_start
&& space_id < (srv_undo_space_id_start
+ srv_undo_tablespaces_open));
}

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) 2009, Percona Inc.
@ -109,6 +109,9 @@ UNIV_INTERN ibool srv_have_fullfsync = FALSE;
/** TRUE if a raw partition is in use */
UNIV_INTERN ibool srv_start_raw_disk_in_use = FALSE;
/** UNDO tablespaces starts with space id. */
ulint srv_undo_space_id_start;
/** TRUE if the server is being started, before rolling back any
incomplete transactions */
UNIV_INTERN ibool srv_startup_is_before_trx_rollback_phase = FALSE;
@ -124,7 +127,7 @@ SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE;
/** Files comprising the system tablespace */
static os_file_t files[1000];
static pfs_os_file_t files[1000];
/** io_handler_thread parameters for thread identification */
static ulint n[SRV_MAX_N_IO_THREADS + 6];
@ -530,7 +533,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
create_log_file(
/*============*/
os_file_t* file, /*!< out: file handle */
pfs_os_file_t* file, /*!< out: file handle */
const char* name) /*!< in: log file name */
{
ibool ret;
@ -737,7 +740,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
open_log_file(
/*==========*/
os_file_t* file, /*!< out: file handle */
pfs_os_file_t* file, /*!< out: file handle */
const char* name, /*!< in: log file name */
os_offset_t* size) /*!< out: file size */
{
@ -853,7 +856,7 @@ open_or_create_data_files(
&& os_file_get_last_error(false)
!= OS_FILE_ALREADY_EXISTS
#ifdef UNIV_AIX
/* AIX 5.1 after security patch ML7 may have
/* AIX 5.1 after security patch ML7 may have
errno set to 0 here, which causes our
function to return 100; work around that
AIX problem */
@ -1156,7 +1159,7 @@ srv_undo_tablespace_create(
const char* name, /*!< in: tablespace name */
ulint size) /*!< in: tablespace size in pages */
{
os_file_t fh;
pfs_os_file_t fh;
ibool ret;
dberr_t err = DB_SUCCESS;
@ -1233,7 +1236,7 @@ srv_undo_tablespace_open(
const char* name, /*!< in: tablespace name */
ulint space) /*!< in: tablespace id */
{
os_file_t fh;
pfs_os_file_t fh;
dberr_t err = DB_ERROR;
ibool ret;
ulint flags;
@ -1332,13 +1335,23 @@ srv_undo_tablespaces_init(
for (i = 0; create_new_db && i < n_conf_tablespaces; ++i) {
char name[OS_FILE_MAX_PATH];
ulint space_id = i + 1;
DBUG_EXECUTE_IF("innodb_undo_upgrade",
space_id = i + 3;);
ut_snprintf(
name, sizeof(name),
"%s%cundo%03lu",
srv_undo_dir, SRV_PATH_SEPARATOR, i + 1);
srv_undo_dir, SRV_PATH_SEPARATOR, space_id);
if (i == 0) {
srv_undo_space_id_start = space_id;
prev_space_id = srv_undo_space_id_start - 1;
}
undo_tablespace_ids[i] = space_id;
/* Undo space ids start from 1. */
err = srv_undo_tablespace_create(
name, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES);
@ -1360,14 +1373,16 @@ srv_undo_tablespaces_init(
if (!create_new_db) {
n_undo_tablespaces = trx_rseg_get_n_undo_tablespaces(
undo_tablespace_ids);
if (n_undo_tablespaces != 0) {
srv_undo_space_id_start = undo_tablespace_ids[0];
prev_space_id = srv_undo_space_id_start - 1;
}
} else {
n_undo_tablespaces = n_conf_tablespaces;
for (i = 1; i <= n_undo_tablespaces; ++i) {
undo_tablespace_ids[i - 1] = i;
}
undo_tablespace_ids[i] = ULINT_UNDEFINED;
undo_tablespace_ids[n_conf_tablespaces] = ULINT_UNDEFINED;
}
/* Open all the undo tablespaces that are currently in use. If we
@ -1391,8 +1406,6 @@ srv_undo_tablespaces_init(
ut_a(undo_tablespace_ids[i] != 0);
ut_a(undo_tablespace_ids[i] != ULINT_UNDEFINED);
/* Undo space ids start from 1. */
err = srv_undo_tablespace_open(name, undo_tablespace_ids[i]);
if (err != DB_SUCCESS) {
@ -1427,11 +1440,23 @@ srv_undo_tablespaces_init(
break;
}
/** Note the first undo tablespace id in case of
no active undo tablespace. */
if (n_undo_tablespaces == 0) {
srv_undo_space_id_start = i;
}
++n_undo_tablespaces;
++*n_opened;
}
/** Explictly specify the srv_undo_space_id_start
as zero when there are no undo tablespaces. */
if (n_undo_tablespaces == 0) {
srv_undo_space_id_start = 0;
}
/* If the user says that there are fewer than what we find we
tolerate that discrepancy but not the inverse. Because there could
be unused undo tablespaces for future use. */
@ -1476,10 +1501,11 @@ srv_undo_tablespaces_init(
mtr_start(&mtr);
/* The undo log tablespace */
for (i = 1; i <= n_undo_tablespaces; ++i) {
for (i = 0; i < n_undo_tablespaces; ++i) {
fsp_header_init(
i, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
undo_tablespace_ids[i],
SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr);
}
mtr_commit(&mtr);
@ -1554,6 +1580,10 @@ innobase_start_or_create_for_mysql(void)
char* logfile0 = NULL;
size_t dirnamelen;
if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) {
srv_read_only_mode = 1;
}
high_level_read_only = srv_read_only_mode
|| srv_force_recovery > SRV_FORCE_NO_TRX_UNDO;

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.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -692,7 +692,8 @@ trx_purge_get_rseg_with_min_trx_id(
/* We assume in purge of externally stored fields that space id is
in the range of UNDO tablespace space ids */
ut_a(purge_sys->rseg->space <= srv_undo_tablespaces_open);
ut_a(purge_sys->rseg->space == 0
|| srv_is_undo_tablespace(purge_sys->rseg->space));
zip_size = purge_sys->rseg->zip_size;

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.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -800,6 +800,7 @@ DECLARE_THREAD(trx_rollback_or_clean_all_recovered)(
/*!< in: a dummy parameter required by
os_thread_create */
{
my_thread_init();
ut_ad(!srv_read_only_mode);
#ifdef UNIV_PFS_THREAD
@ -810,6 +811,7 @@ DECLARE_THREAD(trx_rollback_or_clean_all_recovered)(
trx_rollback_or_clean_is_active = false;
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */

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
the terms of the GNU General Public License as published by the Free Software
@ -909,18 +909,12 @@ trx_sys_create_rsegs(
ulint new_rsegs = n_rsegs - n_used;
for (i = 0; i < new_rsegs; ++i) {
ulint space;
ulint space_id;
space_id = (n_spaces == 0) ? 0
: (srv_undo_space_id_start + i % n_spaces);
/* Tablespace 0 is the system tablespace. All UNDO
log tablespaces start from 1. */
if (n_spaces > 0) {
space = (i % n_spaces) + 1;
} else {
space = 0; /* System tablespace */
}
if (trx_rseg_create(space) != NULL) {
/* Tablespace 0 is the system tablespace. */
if (trx_rseg_create(space_id) != NULL) {
++n_used;
} else {
break;