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*)
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.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
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
required by os_thread_create */
{
my_thread_init();
ut_ad(!srv_read_only_mode);
srv_buf_dump_thread_active = TRUE;
@ -718,6 +719,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.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
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
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();
@ -2518,6 +2519,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
@ -1110,10 +1110,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

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.
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
required by os_thread_create */
{
my_thread_init();
ut_a(!srv_read_only_mode);
srv_dict_stats_thread_active = TRUE;
@ -371,6 +372,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.
Copyright (c) 2014, 2017, MariaDB Corporation. All Rights Reserved.
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;
/** 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__
@ -1879,7 +1880,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 */
@ -3214,7 +3215,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;
@ -3274,7 +3275,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;
@ -5025,7 +5027,7 @@ retry:
int err;
do {
err = posix_fallocate(node->handle, start_offset, len);
err = posix_fallocate(node->handle.m_file, start_offset, len);
} while (err == EINTR
&& srv_shutdown_state == SRV_SHUTDOWN_NONE);
@ -5775,7 +5777,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);
@ -6137,7 +6139,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 */
@ -6272,7 +6274,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.
@ -10718,7 +10718,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.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
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
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.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
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? */
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 */
@ -205,7 +205,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;
os_event_set() and os_event_reset()
@ -569,7 +569,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 */
@ -1087,12 +1087,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;
/**
@ -1100,7 +1100,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;
@ -1136,7 +1136,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.
Copyright (c) 2013, 2017, MariaDB Corporation.
@ -80,6 +80,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;
@ -208,6 +218,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()
@ -217,17 +229,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)
@ -253,9 +278,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); \
} \
@ -263,7 +288,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)
@ -281,7 +306,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_". */
@ -299,7 +326,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, \
@ -307,18 +334,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) \
@ -344,22 +380,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)
@ -371,6 +414,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 {
@ -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
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
@ -540,7 +610,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
@ -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
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 */
@ -632,7 +702,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 */
@ -656,7 +726,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 */
@ -685,7 +755,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 */
/*******************************************************************//**
@ -698,7 +768,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 */
@ -716,7 +786,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 */
@ -737,7 +807,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 */
@ -764,7 +834,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 */
@ -781,7 +851,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 */
@ -852,7 +922,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.
@ -863,7 +933,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));
/***********************************************************************//**
@ -1101,7 +1171,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

@ -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.
Copyright (c) 2013, 2017, MariaDB Corporation.
@ -802,6 +802,13 @@ UNIV_INTERN
void
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 */
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 "handler.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

@ -134,14 +134,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.
Copyright (c) 2017, MariaDB Corporation.
@ -3400,7 +3400,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.
Copyright (c) 2017, MariaDB Corporation.
@ -328,6 +328,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
@ -358,6 +359,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.
Copyright (c) 2013, 2017, MariaDB Corporation.
@ -164,7 +164,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
@ -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
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
@ -1307,7 +1307,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__
@ -1315,7 +1315,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));
@ -1332,8 +1331,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) {
@ -1356,11 +1355,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
@ -1368,11 +1367,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));
@ -1414,13 +1412,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
@ -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_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 */
@ -1516,7 +1514,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
@ -1532,24 +1530,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__ */
@ -1600,7 +1599,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;
@ -1625,8 +1625,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
@ -1653,11 +1653,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
@ -1682,7 +1682,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
@ -1720,7 +1719,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);
@ -1740,9 +1740,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
@ -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_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) {
@ -1791,7 +1791,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);
}
@ -1802,8 +1802,8 @@ os_file_create_func(
}
*success = FALSE;
close(file);
file = -1;
close(file.m_file);
file.m_file = -1;
}
#endif /* USE_FILE_LOCK */
@ -2071,14 +2071,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);
@ -2088,7 +2088,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__ */
}
@ -2101,7 +2102,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 */
{
ibool ret;
@ -2113,7 +2114,7 @@ os_file_set_size(
if (srv_use_posix_fallocate) {
int err;
do {
err = posix_fallocate(file, 0, size);
err = posix_fallocate(file.m_file, 0, size);
} while (err == EINTR
&& srv_shutdown_state == SRV_SHUTDOWN_NONE);
@ -4100,7 +4101,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
@ -4220,10 +4221,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;
@ -4461,7 +4462,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 */
@ -4486,7 +4487,6 @@ os_aio_func(
ulint dummy_type;
#endif /* WIN_ASYNC_IO */
ulint wake_later;
ut_ad(buf);
ut_ad(n > 0);
ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0);
@ -4523,13 +4523,13 @@ os_aio_func(
and os_file_write_func() */
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 {
ut_ad(!srv_read_only_mode);
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",
os_has_said_disk_full = FALSE; ret = 0; errno = 28;);
@ -4591,9 +4591,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;
@ -4611,9 +4610,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;
@ -4767,8 +4765,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;
@ -4797,7 +4794,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,
@ -4808,16 +4806,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;
@ -4833,8 +4829,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);
}
@ -5281,12 +5276,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) {
@ -2612,11 +2612,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);
@ -3442,8 +3441,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

@ -864,8 +864,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);
@ -899,7 +900,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) {
@ -3140,14 +3141,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) {
@ -3194,15 +3202,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

@ -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) \
row_sel_store_mysql_field_func(m,p,r,o,f,t)
#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))
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)
{
const byte* data;
ulint len;
@ -2892,30 +2897,35 @@ 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)
{
ulint i;
ulint i;
ut_ad(rec_clust || index == prebuilt->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
== 0);
if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
rec, index, offsets,
field_no, templ)) {
@ -3658,7 +3669,7 @@ 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* rec = NULL;
const rec_t* result_rec = NULL;
const rec_t* clust_rec;
dberr_t err = DB_SUCCESS;
@ -3957,7 +3968,8 @@ row_search_for_mysql(
if (!row_sel_store_mysql_rec(
buf, prebuilt,
rec, FALSE, index, offsets)) {
rec, FALSE, index,
offsets)) {
/* Only fresh inserts may contain
incomplete externally stored
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) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation.
@ -2398,6 +2398,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;
@ -2459,6 +2461,7 @@ suspend_thread:
srv_resume_thread(slot);
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
my_thread_end();
os_thread_exit(NULL);
}
@ -2541,6 +2544,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);
@ -2598,6 +2603,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);
@ -2764,6 +2770,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;
@ -2870,6 +2878,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);
@ -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) 2009, Percona Inc.
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 */
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;
@ -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;
/** 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];
@ -540,7 +543,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;
@ -746,7 +749,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 */
{
@ -862,7 +865,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 */
@ -1165,7 +1168,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;
@ -1242,7 +1245,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;
@ -1341,13 +1344,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);
@ -1369,14 +1382,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
@ -1400,8 +1415,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) {
@ -1436,11 +1449,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. */
@ -1485,10 +1510,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);
@ -1575,6 +1601,10 @@ innobase_start_or_create_for_mysql(void)
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
|| 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.
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
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.
Copyright (c) 2016, 2017, MariaDB Corporation.
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
os_thread_create */
{
my_thread_init();
ut_ad(!srv_read_only_mode);
#ifdef UNIV_PFS_THREAD
@ -815,6 +816,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;