Merge branch 'merge-xtradb-5.6' into 10.0
This commit is contained in:
commit
d8b45b0c00
@ -199,7 +199,7 @@ btr_search_sys_create(
|
||||
&btr_search_latch_arr[i], SYNC_SEARCH_SYS);
|
||||
|
||||
btr_search_sys->hash_tables[i]
|
||||
= ha_create(hash_size, 0, MEM_HEAP_FOR_BTR_SEARCH, 0);
|
||||
= ib_create(hash_size, 0, MEM_HEAP_FOR_BTR_SEARCH, 0);
|
||||
|
||||
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
|
||||
btr_search_sys->hash_tables[i]->adaptive = TRUE;
|
||||
|
@ -1455,7 +1455,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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
@ -357,6 +357,7 @@ buf_flush_insert_into_flush_list(
|
||||
buf_block_t* block, /*!< in/out: block which is modified */
|
||||
lsn_t lsn) /*!< in: oldest modification */
|
||||
{
|
||||
ut_ad(srv_shutdown_state != SRV_SHUTDOWN_FLUSH_PHASE);
|
||||
ut_ad(log_flush_order_mutex_own());
|
||||
ut_ad(mutex_own(&block->mutex));
|
||||
|
||||
@ -415,6 +416,7 @@ buf_flush_insert_sorted_into_flush_list(
|
||||
buf_page_t* prev_b;
|
||||
buf_page_t* b;
|
||||
|
||||
ut_ad(srv_shutdown_state != SRV_SHUTDOWN_FLUSH_PHASE);
|
||||
ut_ad(log_flush_order_mutex_own());
|
||||
ut_ad(mutex_own(&block->mutex));
|
||||
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
||||
@ -720,6 +722,7 @@ buf_flush_write_complete(
|
||||
buf_page_set_io_fix(bpage, BUF_IO_NONE);
|
||||
|
||||
buf_pool->n_flush[flush_type]--;
|
||||
ut_ad(buf_pool->n_flush[flush_type] != ULINT_MAX);
|
||||
|
||||
if (buf_pool->n_flush[flush_type] == 0
|
||||
&& buf_pool->init_flush[flush_type] == FALSE) {
|
||||
@ -1054,6 +1057,7 @@ buf_flush_page(
|
||||
}
|
||||
|
||||
++buf_pool->n_flush[flush_type];
|
||||
ut_ad(buf_pool->n_flush[flush_type] != 0);
|
||||
|
||||
mutex_exit(&buf_pool->flush_state_mutex);
|
||||
|
||||
@ -2196,13 +2200,14 @@ Clears up tail of the LRU lists:
|
||||
* Flush dirty pages at the tail of LRU to the disk
|
||||
The depth to which we scan each buffer pool is controlled by dynamic
|
||||
config parameter innodb_LRU_scan_depth.
|
||||
@return number of pages flushed */
|
||||
@return number of flushed and evicted pages */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
buf_flush_LRU_tail(void)
|
||||
/*====================*/
|
||||
{
|
||||
ulint total_flushed = 0;
|
||||
ulint total_evicted = 0;
|
||||
ulint start_time = ut_time_ms();
|
||||
ulint scan_depth[MAX_BUFFER_POOLS];
|
||||
ulint requested_pages[MAX_BUFFER_POOLS];
|
||||
@ -2268,6 +2273,7 @@ buf_flush_LRU_tail(void)
|
||||
limited_scan[i]
|
||||
= (previous_evicted[i] > n.evicted);
|
||||
previous_evicted[i] = n.evicted;
|
||||
total_evicted += n.evicted;
|
||||
|
||||
requested_pages[i] += lru_chunk_size;
|
||||
|
||||
@ -2300,7 +2306,7 @@ buf_flush_LRU_tail(void)
|
||||
MONITOR_LRU_BATCH_PAGES,
|
||||
total_flushed);
|
||||
}
|
||||
return(total_flushed);
|
||||
return(total_flushed + total_evicted);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
@ -2601,6 +2607,23 @@ buf_get_total_free_list_length(void)
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Returns the aggregate LRU list length over all buffer pool instances.
|
||||
@return total LRU list length. */
|
||||
MY_ATTRIBUTE((warn_unused_result))
|
||||
static
|
||||
ulint
|
||||
buf_get_total_LRU_list_length(void)
|
||||
{
|
||||
ulint result = 0;
|
||||
|
||||
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
|
||||
|
||||
result += UT_LIST_GET_LEN(buf_pool_from_array(i)->LRU);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Adjust the desired page cleaner thread sleep time for LRU flushes. */
|
||||
MY_ATTRIBUTE((nonnull))
|
||||
@ -2613,8 +2636,9 @@ page_cleaner_adapt_lru_sleep_time(
|
||||
ulint lru_n_flushed) /*!< in: number of flushed in previous batch */
|
||||
|
||||
{
|
||||
ulint free_len = buf_get_total_free_list_length();
|
||||
ulint max_free_len = srv_LRU_scan_depth * srv_buf_pool_instances;
|
||||
ulint free_len = buf_get_total_free_list_length();
|
||||
ulint max_free_len = ut_min(buf_get_total_LRU_list_length(),
|
||||
srv_LRU_scan_depth * srv_buf_pool_instances);
|
||||
|
||||
if (free_len < max_free_len / 100 && lru_n_flushed) {
|
||||
|
||||
@ -2626,7 +2650,7 @@ page_cleaner_adapt_lru_sleep_time(
|
||||
|
||||
/* Free lists filled more than 20%
|
||||
or no pages flushed in previous batch, sleep a bit more */
|
||||
*lru_sleep_time += 50;
|
||||
*lru_sleep_time += 1;
|
||||
if (*lru_sleep_time > srv_cleaner_max_lru_time)
|
||||
*lru_sleep_time = srv_cleaner_max_lru_time;
|
||||
} else if (free_len < max_free_len / 20 && *lru_sleep_time >= 50) {
|
||||
@ -2673,6 +2697,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();
|
||||
@ -2806,6 +2831,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);
|
||||
|
@ -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.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
@ -461,7 +461,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 "
|
||||
|
@ -876,16 +876,24 @@ dict_index_get_nth_col_or_prefix_pos(
|
||||
/*=================================*/
|
||||
const dict_index_t* index, /*!< in: index */
|
||||
ulint n, /*!< in: column number */
|
||||
ibool inc_prefix) /*!< in: TRUE=consider
|
||||
ibool inc_prefix, /*!< in: TRUE=consider
|
||||
column prefixes too */
|
||||
ulint* prefix_col_pos) /*!< out: col num if prefix */
|
||||
{
|
||||
const dict_field_t* field;
|
||||
const dict_col_t* col;
|
||||
ulint pos;
|
||||
ulint n_fields;
|
||||
ulint prefixed_pos_dummy;
|
||||
|
||||
ut_ad(index);
|
||||
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
|
||||
ut_ad((inc_prefix && !prefix_col_pos) || (!inc_prefix));
|
||||
|
||||
if (!prefix_col_pos) {
|
||||
prefix_col_pos = &prefixed_pos_dummy;
|
||||
}
|
||||
*prefix_col_pos = ULINT_UNDEFINED;
|
||||
|
||||
col = dict_table_get_nth_col(index->table, n);
|
||||
|
||||
@ -899,10 +907,11 @@ dict_index_get_nth_col_or_prefix_pos(
|
||||
for (pos = 0; pos < n_fields; pos++) {
|
||||
field = dict_index_get_nth_field(index, pos);
|
||||
|
||||
if (col == field->col
|
||||
&& (inc_prefix || field->prefix_len == 0)) {
|
||||
|
||||
return(pos);
|
||||
if (col == field->col) {
|
||||
*prefix_col_pos = pos;
|
||||
if (inc_prefix || field->prefix_len == 0) {
|
||||
return(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1046,7 +1055,7 @@ dict_table_get_nth_col_pos(
|
||||
ulint n) /*!< in: column number */
|
||||
{
|
||||
return(dict_index_get_nth_col_pos(dict_table_get_first_index(table),
|
||||
n));
|
||||
n, NULL));
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -336,6 +336,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;
|
||||
@ -361,6 +362,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);
|
||||
|
@ -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
|
||||
@ -154,7 +154,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__
|
||||
@ -1943,7 +1944,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 */
|
||||
@ -3266,7 +3267,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;
|
||||
@ -3326,7 +3327,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;
|
||||
@ -5065,19 +5067,10 @@ 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);
|
||||
|
||||
success = !err;
|
||||
if (!success) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR, "extending file %s"
|
||||
" from " INT64PF " to " INT64PF " bytes"
|
||||
" failed with error %d",
|
||||
node->name, start_offset, len + start_offset,
|
||||
err);
|
||||
}
|
||||
|
||||
DBUG_EXECUTE_IF("ib_os_aio_func_io_failure_28",
|
||||
success = FALSE; os_has_said_disk_full = TRUE;);
|
||||
|
||||
@ -5843,7 +5836,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);
|
||||
@ -6202,7 +6195,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 */
|
||||
@ -6337,7 +6330,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);
|
||||
|
@ -953,6 +953,18 @@ fts_query_free_doc_ids(
|
||||
query->total_size -= SIZEOF_RBT_CREATE;
|
||||
}
|
||||
|
||||
/**
|
||||
Free the query intersection
|
||||
@param[in] query query instance */
|
||||
static
|
||||
void
|
||||
fts_query_free_intersection(
|
||||
fts_query_t* query)
|
||||
{
|
||||
fts_query_free_doc_ids(query, query->intersection);
|
||||
query->intersection = NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Add the word to the documents "list" of matching words from
|
||||
the query. We make a copy of the word from the query heap. */
|
||||
@ -1311,6 +1323,7 @@ fts_query_intersect(
|
||||
/* error is passed by 'query->error' */
|
||||
if (query->error != DB_SUCCESS) {
|
||||
ut_ad(query->error == DB_FTS_EXCEED_RESULT_CACHE_LIMIT);
|
||||
fts_query_free_intersection(query);
|
||||
return(query->error);
|
||||
}
|
||||
|
||||
@ -1339,6 +1352,8 @@ fts_query_intersect(
|
||||
|
||||
ut_a(!query->multi_exist || (query->multi_exist
|
||||
&& rbt_size(query->doc_ids) <= n_doc_ids));
|
||||
} else if (query->intersection != NULL) {
|
||||
fts_query_free_intersection(query);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1557,6 +1572,11 @@ fts_merge_doc_ids(
|
||||
query, ranking->doc_id, ranking->rank);
|
||||
|
||||
if (query->error != DB_SUCCESS) {
|
||||
if (query->intersection != NULL)
|
||||
{
|
||||
ut_a(query->oper == FTS_EXIST);
|
||||
fts_query_free_intersection(query);
|
||||
}
|
||||
DBUG_RETURN(query->error);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
@ -780,6 +780,32 @@ innobase_is_fake_change(
|
||||
THD* thd) __attribute__((unused)); /*!< in: MySQL thread handle of the user for
|
||||
whom the transaction is being committed */
|
||||
|
||||
/** Empty free list algorithm.
|
||||
Checks if buffer pool is big enough to enable backoff algorithm.
|
||||
InnoDB empty free list algorithm backoff requires free pages
|
||||
from LRU for the best performance.
|
||||
buf_LRU_buf_pool_running_out cancels query if 1/4 of
|
||||
buffer pool belongs to LRU or freelist.
|
||||
At the same time buf_flush_LRU_list_batch
|
||||
keeps up to BUF_LRU_MIN_LEN in LRU.
|
||||
In order to avoid deadlock baclkoff requires buffer pool
|
||||
to be at least 4*BUF_LRU_MIN_LEN,
|
||||
but flush peformance is bad because of trashing
|
||||
and additional BUF_LRU_MIN_LEN pages are requested.
|
||||
@param[in] algorithm desired algorithm from srv_empty_free_list_t
|
||||
@return true if it's possible to enable backoff. */
|
||||
static inline
|
||||
bool
|
||||
innodb_empty_free_list_algorithm_allowed(
|
||||
srv_empty_free_list_t algorithm)
|
||||
{
|
||||
long long buf_pool_pages = srv_buf_pool_size / srv_page_size
|
||||
/ srv_buf_pool_instances;
|
||||
|
||||
return(buf_pool_pages >= BUF_LRU_MIN_LEN * (4 + 1)
|
||||
|| algorithm != SRV_EMPTY_FREE_LIST_BACKOFF);
|
||||
}
|
||||
|
||||
/** Get the list of foreign keys referencing a specified table
|
||||
table.
|
||||
@param thd The thread handle
|
||||
@ -1070,6 +1096,10 @@ static SHOW_VAR innodb_status_variables[]= {
|
||||
(char*) &export_vars.innodb_x_lock_spin_rounds, SHOW_LONGLONG},
|
||||
{"x_lock_spin_waits",
|
||||
(char*) &export_vars.innodb_x_lock_spin_waits, SHOW_LONGLONG},
|
||||
{"secondary_index_triggered_cluster_reads",
|
||||
(char*) &export_vars.innodb_sec_rec_cluster_reads, SHOW_LONG},
|
||||
{"secondary_index_triggered_cluster_reads_avoided",
|
||||
(char*) &export_vars.innodb_sec_rec_cluster_reads_avoided, SHOW_LONG},
|
||||
{NullS, NullS, SHOW_LONG}
|
||||
};
|
||||
|
||||
@ -1468,28 +1498,6 @@ normalize_table_name_low(
|
||||
ibool set_lower_case); /* in: TRUE if we want to set
|
||||
name to lower case */
|
||||
|
||||
/*************************************************************//**
|
||||
Checks if buffer pool is big enough to enable backoff algorithm.
|
||||
InnoDB empty free list algorithm backoff requires free pages
|
||||
from LRU for the best performance.
|
||||
buf_LRU_buf_pool_running_out cancels query if 1/4 of
|
||||
buffer pool belongs to LRU or freelist.
|
||||
At the same time buf_flush_LRU_list_batch
|
||||
keeps up to BUF_LRU_MIN_LEN in LRU.
|
||||
In order to avoid deadlock baclkoff requires buffer pool
|
||||
to be at least 4*BUF_LRU_MIN_LEN,
|
||||
but flush peformance is bad because of trashing
|
||||
and additional BUF_LRU_MIN_LEN pages are requested.
|
||||
@return true if it's possible to enable backoff. */
|
||||
static
|
||||
bool
|
||||
innodb_empty_free_list_algorithm_backoff_allowed(
|
||||
srv_empty_free_list_t
|
||||
algorithm, /*!< in: desired algorithm
|
||||
from srv_empty_free_list_t */
|
||||
long long buf_pool_pages); /*!< in: total number
|
||||
of pages inside buffer pool */
|
||||
|
||||
#ifdef NOT_USED
|
||||
/*************************************************************//**
|
||||
Removes old archived transaction log files.
|
||||
@ -4011,10 +4019,9 @@ innobase_change_buffering_inited_ok:
|
||||
srv_use_posix_fallocate = (ibool) innobase_use_fallocate;
|
||||
#endif
|
||||
/* Do not enable backoff algorithm for small buffer pool. */
|
||||
if (!innodb_empty_free_list_algorithm_backoff_allowed(
|
||||
if (!innodb_empty_free_list_algorithm_allowed(
|
||||
static_cast<srv_empty_free_list_t>(
|
||||
srv_empty_free_list_algorithm),
|
||||
innobase_buffer_pool_size / srv_page_size)) {
|
||||
srv_empty_free_list_algorithm))) {
|
||||
sql_print_information(
|
||||
"InnoDB: innodb_empty_free_list_algorithm "
|
||||
"has been changed to legacy "
|
||||
@ -7365,9 +7372,31 @@ build_template_field(
|
||||
}
|
||||
|
||||
if (dict_index_is_clust(index)) {
|
||||
templ->rec_field_is_prefix = false;
|
||||
templ->rec_field_no = templ->clust_rec_field_no;
|
||||
templ->rec_prefix_field_no = ULINT_UNDEFINED;
|
||||
} else {
|
||||
templ->rec_field_no = dict_index_get_nth_col_pos(index, i);
|
||||
/* If we're in a secondary index, keep track of the original
|
||||
index position even if this is just a prefix index; we will use
|
||||
this later to avoid a cluster index lookup in some cases.*/
|
||||
|
||||
templ->rec_field_no = dict_index_get_nth_col_pos(index, i,
|
||||
&templ->rec_prefix_field_no);
|
||||
templ->rec_field_is_prefix
|
||||
= (templ->rec_field_no == ULINT_UNDEFINED)
|
||||
&& (templ->rec_prefix_field_no != ULINT_UNDEFINED);
|
||||
#ifdef UNIV_DEBUG
|
||||
if (templ->rec_prefix_field_no != ULINT_UNDEFINED)
|
||||
{
|
||||
const dict_field_t* field = dict_index_get_nth_field(
|
||||
index,
|
||||
templ->rec_prefix_field_no);
|
||||
ut_ad(templ->rec_field_is_prefix
|
||||
== (field->prefix_len != 0));
|
||||
} else {
|
||||
ut_ad(!templ->rec_field_is_prefix);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (field->real_maybe_null()) {
|
||||
@ -7559,7 +7588,8 @@ ha_innobase::build_template(
|
||||
} else {
|
||||
templ->icp_rec_field_no
|
||||
= dict_index_get_nth_col_pos(
|
||||
prebuilt->index, i);
|
||||
prebuilt->index, i,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (dict_index_is_clust(prebuilt->index)) {
|
||||
@ -7589,7 +7619,7 @@ ha_innobase::build_template(
|
||||
|
||||
templ->icp_rec_field_no
|
||||
= dict_index_get_nth_col_or_prefix_pos(
|
||||
prebuilt->index, i, TRUE);
|
||||
prebuilt->index, i, TRUE, NULL);
|
||||
ut_ad(templ->icp_rec_field_no
|
||||
!= ULINT_UNDEFINED);
|
||||
|
||||
@ -11497,7 +11527,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)) {
|
||||
@ -16858,15 +16889,17 @@ innodb_buffer_pool_evict_uncompressed(void)
|
||||
ut_ad(block->page.in_LRU_list);
|
||||
|
||||
mutex_enter(&block->mutex);
|
||||
if (!buf_LRU_free_page(&block->page, false)) {
|
||||
mutex_exit(&block->mutex);
|
||||
all_evicted = false;
|
||||
} else {
|
||||
mutex_exit(&block->mutex);
|
||||
mutex_enter(&buf_pool->LRU_list_mutex);
|
||||
}
|
||||
all_evicted = buf_LRU_free_page(&block->page, false);
|
||||
mutex_exit(&block->mutex);
|
||||
|
||||
block = prev_block;
|
||||
if (all_evicted) {
|
||||
|
||||
mutex_enter(&buf_pool->LRU_list_mutex);
|
||||
block = UT_LIST_GET_LAST(buf_pool->unzip_LRU);
|
||||
} else {
|
||||
|
||||
block = prev_block;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_exit(&buf_pool->LRU_list_mutex);
|
||||
@ -17680,32 +17713,6 @@ innodb_status_output_update(
|
||||
os_event_set(srv_monitor_event);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Empty free list algorithm.
|
||||
Checks if buffer pool is big enough to enable backoff algorithm.
|
||||
InnoDB empty free list algorithm backoff requires free pages
|
||||
from LRU for the best performance.
|
||||
buf_LRU_buf_pool_running_out cancels query if 1/4 of
|
||||
buffer pool belongs to LRU or freelist.
|
||||
At the same time buf_flush_LRU_list_batch
|
||||
keeps up to BUF_LRU_MIN_LEN in LRU.
|
||||
In order to avoid deadlock baclkoff requires buffer pool
|
||||
to be at least 4*BUF_LRU_MIN_LEN,
|
||||
but flush peformance is bad because of trashing
|
||||
and additional BUF_LRU_MIN_LEN pages are requested.
|
||||
@return true if it's possible to enable backoff. */
|
||||
static
|
||||
bool
|
||||
innodb_empty_free_list_algorithm_backoff_allowed(
|
||||
srv_empty_free_list_t algorithm, /*!< in: desired algorithm
|
||||
from srv_empty_free_list_t */
|
||||
long long buf_pool_pages) /*!< in: total number
|
||||
of pages inside buffer pool */
|
||||
{
|
||||
return(buf_pool_pages >= BUF_LRU_MIN_LEN * (4 + 1)
|
||||
|| algorithm != SRV_EMPTY_FREE_LIST_BACKOFF);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Empty free list algorithm. This function is registered as
|
||||
a callback with MySQL.
|
||||
@ -17747,13 +17754,11 @@ innodb_srv_empty_free_list_algorithm_validate(
|
||||
return(1);
|
||||
|
||||
algorithm = static_cast<srv_empty_free_list_t>(algo);
|
||||
if (!innodb_empty_free_list_algorithm_backoff_allowed(
|
||||
algorithm,
|
||||
innobase_buffer_pool_size / srv_page_size)) {
|
||||
if (!innodb_empty_free_list_algorithm_allowed(algorithm)) {
|
||||
sql_print_warning(
|
||||
"InnoDB: innodb_empty_free_list_algorithm "
|
||||
"= 'backoff' requires at least"
|
||||
" 20MB buffer pool.\n");
|
||||
" 20MB buffer pool instances.\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -1260,7 +1260,8 @@ innobase_rec_to_mysql(
|
||||
|
||||
field->reset();
|
||||
|
||||
ipos = dict_index_get_nth_col_or_prefix_pos(index, i, TRUE);
|
||||
ipos = dict_index_get_nth_col_or_prefix_pos(index, i, TRUE,
|
||||
NULL);
|
||||
|
||||
if (ipos == ULINT_UNDEFINED
|
||||
|| rec_offs_nth_extern(offsets, ipos)) {
|
||||
@ -1312,7 +1313,8 @@ innobase_fields_to_mysql(
|
||||
|
||||
field->reset();
|
||||
|
||||
ipos = dict_index_get_nth_col_or_prefix_pos(index, i, TRUE);
|
||||
ipos = dict_index_get_nth_col_or_prefix_pos(index, i, TRUE,
|
||||
NULL);
|
||||
|
||||
if (ipos == ULINT_UNDEFINED
|
||||
|| dfield_is_ext(&fields[ipos])
|
||||
|
@ -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);
|
||||
|
||||
|
@ -1168,8 +1168,9 @@ ulint
|
||||
dict_index_get_nth_col_pos(
|
||||
/*=======================*/
|
||||
const dict_index_t* index, /*!< in: index */
|
||||
ulint n) /*!< in: column number */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
ulint n, /*!< in: column number */
|
||||
ulint* prefix_col_pos) /*!< out: col num if prefix */
|
||||
MY_ATTRIBUTE((nonnull(1), warn_unused_result));
|
||||
/********************************************************************//**
|
||||
Looks for column n in an index.
|
||||
@return position in internal representation of the index;
|
||||
@ -1180,9 +1181,11 @@ dict_index_get_nth_col_or_prefix_pos(
|
||||
/*=================================*/
|
||||
const dict_index_t* index, /*!< in: index */
|
||||
ulint n, /*!< in: column number */
|
||||
ibool inc_prefix) /*!< in: TRUE=consider
|
||||
ibool inc_prefix, /*!< in: TRUE=consider
|
||||
column prefixes too */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
ulint* prefix_col_pos) /*!< out: col num if prefix */
|
||||
|
||||
MY_ATTRIBUTE((nonnull(1), warn_unused_result));
|
||||
/********************************************************************//**
|
||||
Returns TRUE if the index contains a column or a prefix of that column.
|
||||
@return TRUE if contains the column or its prefix */
|
||||
|
@ -1043,7 +1043,8 @@ dict_index_get_sys_col_pos(
|
||||
}
|
||||
|
||||
return(dict_index_get_nth_col_pos(
|
||||
index, dict_table_get_sys_col_no(index->table, type)));
|
||||
index, dict_table_get_sys_col_no(index->table, type),
|
||||
NULL));
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
@ -1095,9 +1096,11 @@ ulint
|
||||
dict_index_get_nth_col_pos(
|
||||
/*=======================*/
|
||||
const dict_index_t* index, /*!< in: index */
|
||||
ulint n) /*!< in: column number */
|
||||
ulint n, /*!< in: column number */
|
||||
ulint* prefix_col_pos) /*!< out: col num if prefix */
|
||||
{
|
||||
return(dict_index_get_nth_col_or_prefix_pos(index, n, FALSE));
|
||||
return(dict_index_get_nth_col_or_prefix_pos(index, n, FALSE,
|
||||
prefix_col_pos));
|
||||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
|
@ -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
|
||||
@ -183,7 +183,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 */
|
||||
@ -198,7 +198,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()
|
||||
@ -571,7 +571,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;
|
||||
|
@ -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 */
|
||||
|
||||
/*************************************************************//**
|
||||
|
@ -130,7 +130,7 @@ log_online_bitmap_iterator_next(
|
||||
/** Struct for single bitmap file information */
|
||||
struct log_online_bitmap_file_struct {
|
||||
char name[FN_REFLEN]; /*!< Name with full path */
|
||||
os_file_t file; /*!< Handle to opened file */
|
||||
pfs_os_file_t file; /*!< Handle to opened file */
|
||||
ib_uint64_t size; /*!< Size of the file */
|
||||
os_offset_t offset; /*!< Offset of the next read,
|
||||
or count of already-read bytes
|
||||
|
@ -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.
|
||||
|
||||
@ -69,7 +69,6 @@ typedef ib_uint64_t os_offset_t;
|
||||
#define SRV_PATH_SEPARATOR '\\'
|
||||
/** File handle */
|
||||
# define os_file_t HANDLE
|
||||
# define os_file_invalid INVALID_HANDLE_VALUE
|
||||
/** Convert a C file descriptor to a native file handle
|
||||
@param fd file descriptor
|
||||
@return native file handle */
|
||||
@ -78,13 +77,22 @@ typedef ib_uint64_t os_offset_t;
|
||||
#define SRV_PATH_SEPARATOR '/'
|
||||
/** File handle */
|
||||
typedef int os_file_t;
|
||||
# define os_file_invalid (-1)
|
||||
/** Convert a C file descriptor to a native file handle
|
||||
@param fd file descriptor
|
||||
@return native file handle */
|
||||
# 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;
|
||||
|
||||
@ -120,6 +128,21 @@ enum os_file_create_t {
|
||||
ON_ERROR_NO_EXIT is set */
|
||||
};
|
||||
|
||||
/** Options for os_file_advise_func @{ */
|
||||
enum os_file_advise_t {
|
||||
OS_FILE_ADVISE_NORMAL = 1, /*!< no advice on access pattern
|
||||
(default) */
|
||||
OS_FILE_ADVISE_RANDOM = 2, /*!< access in random order */
|
||||
OS_FILE_ADVISE_SEQUENTIAL = 4, /*!< access the specified data
|
||||
sequentially (with lower offsets read
|
||||
before higher ones) */
|
||||
OS_FILE_ADVISE_WILLNEED = 8, /*!< specified data will be accessed
|
||||
in the near future */
|
||||
OS_FILE_ADVISE_DONTNEED = 16, /*!< specified data will not be
|
||||
accessed in the near future */
|
||||
OS_FILE_ADVISE_NOREUSE = 32 /*!< access only once */
|
||||
};
|
||||
|
||||
#define OS_FILE_READ_ONLY 333
|
||||
#define OS_FILE_READ_WRITE 444
|
||||
#define OS_FILE_READ_ALLOW_DELETE 555 /* for mysqlbackup */
|
||||
@ -222,6 +245,8 @@ extern mysql_pfs_key_t innodb_file_bmp_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()
|
||||
@ -231,17 +256,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)
|
||||
|
||||
@ -267,9 +305,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); \
|
||||
} \
|
||||
@ -277,7 +315,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)
|
||||
@ -291,11 +329,16 @@ os_file_create
|
||||
os_file_create_simple
|
||||
os_file_create_simple_no_error_handling
|
||||
os_file_close
|
||||
os_file_close_no_error_handling
|
||||
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
|
||||
os_file_set_eof_at
|
||||
os_file_allocate
|
||||
|
||||
The wrapper functions have the prefix of "innodb_". */
|
||||
|
||||
@ -313,20 +356,23 @@ 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_file_close_no_error_handling_pfs(file) \
|
||||
pfs_os_file_close_no_error_handling_func(file, __FILE__, __LINE__)
|
||||
|
||||
# define os_aio(type, mode, name, file, buf, offset, \
|
||||
n, message1, message2, space_id, trx) \
|
||||
pfs_os_aio_func(type, mode, name, file, buf, offset, \
|
||||
n, message1, message2, space_id, trx, \
|
||||
__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, NULL, \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
# define os_file_read_trx(file, buf, offset, n, trx) \
|
||||
# define os_file_read_trx_pfs(file, buf, offset, n, trx) \
|
||||
pfs_os_file_read_func(file, buf, offset, n, trx, \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
@ -334,11 +380,20 @@ The wrapper functions have the prefix of "innodb_". */
|
||||
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) \
|
||||
@ -349,6 +404,15 @@ The wrapper functions have the prefix of "innodb_". */
|
||||
|
||||
# define os_file_delete_if_exists(key, name) \
|
||||
pfs_os_file_delete_if_exists_func(key, name, __FILE__, __LINE__)
|
||||
|
||||
# define os_file_set_eof_at_pfs(file, new_len) \
|
||||
pfs_os_file_set_eof_at_func(file, new_len, __FILE__, __LINE__)
|
||||
|
||||
# ifdef HAVE_POSIX_FALLOCATE
|
||||
# define os_file_allocate_pfs(file, offset, len) \
|
||||
pfs_os_file_allocate_func(file, offset, len, __FILE__, __LINE__)
|
||||
# endif
|
||||
|
||||
#else /* UNIV_PFS_IO */
|
||||
|
||||
/* If UNIV_PFS_IO is not defined, these I/O APIs point
|
||||
@ -364,26 +428,36 @@ 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_file_close_no_error_handling_pfs(file) \
|
||||
os_file_close_no_error_handling_func(file)
|
||||
|
||||
# define os_aio(type, mode, name, file, buf, offset, n, message1, \
|
||||
message2, space_id, trx) \
|
||||
os_aio_func(type, mode, name, file, buf, offset, n, \
|
||||
message1, message2, space_id, trx)
|
||||
|
||||
# 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, NULL)
|
||||
|
||||
# define os_file_read_trx(file, buf, offset, n, trx) \
|
||||
# define os_file_read_trx_pfs(file, buf, offset, n, trx) \
|
||||
os_file_read_func(file, buf, offset, n, trx)
|
||||
|
||||
# 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)
|
||||
@ -393,8 +467,78 @@ to original un-instrumented file I/O APIs */
|
||||
# define os_file_delete_if_exists(key, name) \
|
||||
os_file_delete_if_exists_func(name)
|
||||
|
||||
# define os_file_set_eof_at_pfs(file, new_len) \
|
||||
os_file_set_eof_at_func(file, new_len)
|
||||
|
||||
# ifdef HAVE_POSIX_FALLOCATE
|
||||
# define os_file_allocate_pfs(file, offset, len) \
|
||||
os_file_allocate_func(file, offset, len)
|
||||
# endif
|
||||
|
||||
#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_close_no_error_handling(file) \
|
||||
os_file_close_no_error_handling_pfs(file)
|
||||
#else
|
||||
#define os_file_close_no_error_handling(file) \
|
||||
os_file_close_no_error_handling_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_read_trx(file, buf, offset, n, trx) \
|
||||
os_file_read_trx_pfs(file, buf, offset, n, trx)
|
||||
#else
|
||||
# define os_file_read_trx(file, buf, offset, n, trx) \
|
||||
os_file_read_trx_pfs(file.m_file, buf, offset, n, trx)
|
||||
#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
|
||||
|
||||
#ifdef UNIV_PFS_IO
|
||||
#define os_file_set_eof_at(file, new_len) \
|
||||
os_file_set_eof_at_pfs(file, new_len)
|
||||
#else
|
||||
#define os_file_set_eof_at(file, new_len) \
|
||||
os_file_set_eof_at_pfs(file.m_file, new_len)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POSIX_FALLOCATE
|
||||
#ifdef UNIV_PFS_IO
|
||||
#define os_file_allocate(file, offset, len) \
|
||||
os_file_allocate_pfs(file, offset, len)
|
||||
#else
|
||||
#define os_file_allocate(file, offset, len) \
|
||||
os_file_allocate_pfs(file.m_file, offset, len)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* File types for directory entry data type */
|
||||
|
||||
enum os_file_type_t {
|
||||
@ -528,7 +672,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
|
||||
@ -561,7 +705,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
|
||||
@ -620,6 +764,42 @@ ibool
|
||||
os_file_close_func(
|
||||
/*===============*/
|
||||
os_file_t file); /*!< in, own: handle to a file */
|
||||
/***********************************************************************//**
|
||||
NOTE! Use the corresponding macro os_file_close(), not directly this
|
||||
function!
|
||||
Closes a file handle. In case of error, error number can be retrieved with
|
||||
os_file_get_last_error.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
os_file_close_no_error_handling_func(
|
||||
/*===============*/
|
||||
os_file_t file); /*!< in, own: handle to a file */
|
||||
|
||||
/***********************************************************************//**
|
||||
NOTE! Please use the corresponding macro os_file_set_eof_at(), not
|
||||
directly this function!
|
||||
Truncates a file at the specified position.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
os_file_set_eof_at_func(
|
||||
os_file_t file, /*!< in: handle to a file */
|
||||
ib_uint64_t new_len);/*!< in: new file length */
|
||||
|
||||
#ifdef HAVE_POSIX_FALLOCATE
|
||||
/***********************************************************************//**
|
||||
NOTE! Please use the corresponding macro os_file_allocate(), not
|
||||
directly this function!
|
||||
Ensures that disk space is allocated for the file.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
os_file_allocate_func(
|
||||
os_file_t file, /*!< in, own: handle to a file */
|
||||
os_offset_t offset, /*!< in: file region offset */
|
||||
os_offset_t len); /*!< in: file region length */
|
||||
#endif
|
||||
|
||||
#ifdef UNIV_PFS_IO
|
||||
/****************************************************************//**
|
||||
@ -630,7 +810,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 */
|
||||
@ -653,7 +833,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 */
|
||||
@ -677,7 +857,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 */
|
||||
@ -706,7 +886,20 @@ 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 */
|
||||
/***********************************************************************//**
|
||||
NOTE! Please use the corresponding macro os_file_close_no_error_handling(),
|
||||
not directly this function!
|
||||
A performance schema instrumented wrapper function for
|
||||
os_file_close_no_error_handling().
|
||||
@return TRUE if success */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
pfs_os_file_close_no_error_handling_func(
|
||||
/*===================*/
|
||||
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 */
|
||||
/*******************************************************************//**
|
||||
@ -719,7 +912,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 */
|
||||
@ -738,7 +931,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 */
|
||||
@ -759,7 +952,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 */
|
||||
@ -788,7 +981,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 */
|
||||
@ -805,7 +998,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 */
|
||||
|
||||
@ -857,16 +1050,66 @@ pfs_os_file_delete_if_exists_func(
|
||||
string */
|
||||
const char* src_file,/*!< in: file name where func invoked */
|
||||
ulint src_line);/*!< in: line where the func invoked */
|
||||
|
||||
/***********************************************************************//**
|
||||
NOTE! Please use the corresponding macro os_file_set_eof_at(), not
|
||||
directly this function!
|
||||
This is the performance schema instrumented wrapper function for
|
||||
os_file_set_eof_at()
|
||||
@return TRUE if success */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
pfs_os_file_set_eof_at_func(
|
||||
pfs_os_file_t file, /*!< in: handle to a file */
|
||||
ib_uint64_t new_len,/*!< in: new file length */
|
||||
const char* src_file,/*!< in: file name where func invoked */
|
||||
ulint src_line);/*!< in: line where the func invoked */
|
||||
|
||||
#ifdef HAVE_POSIX_FALLOCATE
|
||||
/***********************************************************************//**
|
||||
NOTE! Please use the corresponding macro os_file_allocate(), not
|
||||
directly this function!
|
||||
Ensures that disk space is allocated for the file.
|
||||
@return TRUE if success */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
pfs_os_file_allocate_func(
|
||||
pfs_os_file_t file, /*!< in, own: handle to a file */
|
||||
os_offset_t offset, /*!< in: file region offset */
|
||||
os_offset_t len, /*!< in: file region length */
|
||||
const char* src_file,/*!< in: file name where func invoked */
|
||||
ulint src_line);/*!< in: line where the func invoked */
|
||||
#endif
|
||||
|
||||
#endif /* UNIV_PFS_IO */
|
||||
|
||||
/***********************************************************************//**
|
||||
Closes a file handle.
|
||||
@return TRUE if success */
|
||||
Checks if the file is marked as invalid.
|
||||
@return TRUE if invalid */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
os_file_close_no_error_handling(
|
||||
/*============================*/
|
||||
os_file_t file); /*!< in, own: handle to a file */
|
||||
bool
|
||||
os_file_is_invalid(
|
||||
pfs_os_file_t file); /*!< in, own: handle to a file */
|
||||
|
||||
/***********************************************************************//**
|
||||
Marks the file as invalid. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
os_file_mark_invalid(
|
||||
pfs_os_file_t* file); /*!< out: pointer to a handle to a file */
|
||||
|
||||
/***********************************************************************//**
|
||||
Announces an intention to access file data in a specific pattern in the
|
||||
future.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
os_file_advise(
|
||||
pfs_os_file_t file, /*!< in, own: handle to a file */
|
||||
os_offset_t offset, /*!< in: file region offset */
|
||||
os_offset_t len, /*!< in: file region length */
|
||||
ulint advice);/*!< in: advice for access pattern */
|
||||
|
||||
/***********************************************************************//**
|
||||
Gets a file size.
|
||||
@return file size, or (os_offset_t) -1 on failure */
|
||||
@ -874,7 +1117,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.
|
||||
@ -885,7 +1128,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));
|
||||
/***********************************************************************//**
|
||||
@ -897,14 +1140,6 @@ os_file_set_eof(
|
||||
/*============*/
|
||||
FILE* file); /*!< in: file to be truncated */
|
||||
/***********************************************************************//**
|
||||
Truncates a file at the specified position.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
os_file_set_eof_at(
|
||||
os_file_t file, /*!< in: handle to a file */
|
||||
ib_uint64_t new_len);/*!< in: new file length */
|
||||
/***********************************************************************//**
|
||||
NOTE! Use the corresponding macro os_file_flush(), not directly this function!
|
||||
Flushes the write buffers of a given file to the disk.
|
||||
@return TRUE if success */
|
||||
@ -1132,7 +1367,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 */
|
||||
|
@ -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,35 @@ 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);
|
||||
|
||||
return(result);
|
||||
}
|
||||
/***********************************************************************//**
|
||||
NOTE! Please use the corresponding macro os_file_close_no_error_handling(),
|
||||
not directly this function!
|
||||
A performance schema instrumented wrapper function for
|
||||
os_file_close_no_error_handling().
|
||||
@return TRUE if success */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
pfs_os_file_close_no_error_handling_func(
|
||||
/*===================*/
|
||||
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 */
|
||||
{
|
||||
bool result;
|
||||
struct PSI_file_locker* locker = NULL;
|
||||
PSI_file_locker_state state;
|
||||
|
||||
/* register the file close */
|
||||
register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_CLOSE,
|
||||
src_file, src_line);
|
||||
|
||||
result = os_file_close_no_error_handling_func(file.m_file);
|
||||
|
||||
register_pfs_file_io_end(locker, 0);
|
||||
|
||||
@ -197,7 +231,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 */
|
||||
@ -244,7 +278,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 */
|
||||
@ -259,7 +293,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, trx);
|
||||
result = os_file_read_func(file.m_file, buf, offset, n, trx);
|
||||
|
||||
register_pfs_file_io_end(locker, n);
|
||||
|
||||
@ -278,7 +312,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 */
|
||||
@ -292,13 +326,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!
|
||||
@ -311,7 +382,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 */
|
||||
@ -325,13 +396,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!
|
||||
@ -342,7 +450,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 */
|
||||
{
|
||||
@ -352,7 +460,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);
|
||||
|
||||
@ -380,12 +488,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);
|
||||
}
|
||||
@ -449,4 +557,61 @@ pfs_os_file_delete_if_exists_func(
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/***********************************************************************//**
|
||||
NOTE! Please use the corresponding macro os_file_set_eof_at(), not
|
||||
directly this function!
|
||||
This is the performance schema instrumented wrapper function for
|
||||
os_file_set_eof_at()
|
||||
@return TRUE if success */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
pfs_os_file_set_eof_at_func(
|
||||
pfs_os_file_t file, /*!< in: handle to a file */
|
||||
ib_uint64_t new_len,/*!< in: new file length */
|
||||
const char* src_file,/*!< in: file name where func invoked */
|
||||
ulint src_line)/*!< in: line where the func invoked */
|
||||
{
|
||||
bool result;
|
||||
struct PSI_file_locker* locker = NULL;
|
||||
PSI_file_locker_state state;
|
||||
|
||||
register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_CHSIZE,
|
||||
src_file, src_line);
|
||||
result = os_file_set_eof_at_func(file.m_file, new_len);
|
||||
|
||||
register_pfs_file_io_end(locker, 0);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
#ifdef HAVE_POSIX_FALLOCATE
|
||||
/***********************************************************************//**
|
||||
NOTE! Please use the corresponding macro os_file_allocate(), not
|
||||
directly this function!
|
||||
Ensures that disk space is allocated for the file.
|
||||
@return TRUE if success */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
pfs_os_file_allocate_func(
|
||||
pfs_os_file_t file, /*!< in, own: handle to a file */
|
||||
os_offset_t offset, /*!< in: file region offset */
|
||||
os_offset_t len, /*!< in: file region length */
|
||||
const char* src_file,/*!< in: file name where func invoked */
|
||||
ulint src_line)/*!< in: line where the func invoked */
|
||||
{
|
||||
bool result;
|
||||
struct PSI_file_locker* locker = NULL;
|
||||
PSI_file_locker_state state;
|
||||
|
||||
register_pfs_file_io_begin(&state, locker, file, 0, PSI_FILE_CHSIZE,
|
||||
src_file, src_line);
|
||||
result = os_file_allocate_func(file.m_file, offset, len);
|
||||
|
||||
register_pfs_file_io_end(locker, 0);
|
||||
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UNIV_PFS_IO */
|
||||
|
@ -611,6 +611,12 @@ struct mysql_row_templ_t {
|
||||
Innobase record in the current index;
|
||||
not defined if template_type is
|
||||
ROW_MYSQL_WHOLE_ROW */
|
||||
bool rec_field_is_prefix; /* is this field in a prefix index? */
|
||||
ulint rec_prefix_field_no; /* record field, even if just a
|
||||
prefix; same as rec_field_no when not a
|
||||
prefix, otherwise rec_field_no is
|
||||
ULINT_UNDEFINED but this is the true
|
||||
field number*/
|
||||
ulint clust_rec_field_no; /*!< field number of the column in an
|
||||
Innobase record in the clustered index;
|
||||
not defined if template_type is
|
||||
@ -713,7 +719,9 @@ struct row_prebuilt_t {
|
||||
columns through a secondary index
|
||||
and at least one column is not in
|
||||
the secondary index, then this is
|
||||
set to TRUE */
|
||||
set to TRUE; note that sometimes this
|
||||
is set but we later optimize out the
|
||||
clustered index lookup */
|
||||
unsigned templ_contains_blob:1;/*!< TRUE if the template contains
|
||||
a column with DATA_BLOB ==
|
||||
get_innobase_type_from_mysql_type();
|
||||
|
@ -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.
|
||||
@ -610,6 +610,11 @@ extern my_bool srv_print_all_deadlocks;
|
||||
|
||||
extern my_bool srv_cmp_per_index_enabled;
|
||||
|
||||
/** Number of times secondary index lookup triggered cluster lookup */
|
||||
extern ulint srv_sec_rec_cluster_reads;
|
||||
/** Number of times prefix optimization avoided triggering cluster lookup */
|
||||
extern ulint srv_sec_rec_cluster_reads_avoided;
|
||||
|
||||
/** Status variables to be passed to MySQL */
|
||||
extern struct export_var_t export_vars;
|
||||
|
||||
@ -990,6 +995,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_adaptive_hash_hash_searches;
|
||||
@ -1106,6 +1118,9 @@ struct export_var_t{
|
||||
#endif /* UNIV_DEBUG */
|
||||
ulint innodb_column_compressed; /*!< srv_column_compressed */
|
||||
ulint innodb_column_decompressed; /*!< srv_column_decompressed */
|
||||
|
||||
ulint innodb_sec_rec_cluster_reads; /*!< srv_sec_rec_cluster_reads */
|
||||
ulint innodb_sec_rec_cluster_reads_avoided; /*!< srv_sec_rec_cluster_reads_avoided */
|
||||
};
|
||||
|
||||
/** Thread slot in the thread table. */
|
||||
|
@ -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 {
|
||||
|
@ -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 */
|
||||
/* @{ */
|
||||
|
@ -48,7 +48,7 @@ Created 1/20/1994 Heikki Tuuri
|
||||
#define INNODB_VERSION_BUGFIX 35
|
||||
|
||||
#ifndef PERCONA_INNODB_VERSION
|
||||
#define PERCONA_INNODB_VERSION 80.0
|
||||
#define PERCONA_INNODB_VERSION 82.0
|
||||
#endif
|
||||
|
||||
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
|
||||
@ -146,14 +146,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
|
||||
|
@ -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.
|
||||
|
||||
@ -2741,7 +2741,7 @@ log_group_archive(
|
||||
/*==============*/
|
||||
log_group_t* group) /*!< in: log group */
|
||||
{
|
||||
os_file_t file_handle;
|
||||
pfs_os_file_t file_handle;
|
||||
lsn_t start_lsn;
|
||||
lsn_t end_lsn;
|
||||
char name[OS_FILE_MAX_PATH];
|
||||
@ -3716,9 +3716,15 @@ loop:
|
||||
|
||||
lsn = log_sys->lsn;
|
||||
|
||||
if (lsn != log_sys->last_checkpoint_lsn
|
||||
|| (srv_track_changed_pages
|
||||
&& (tracked_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)
|
||||
&& (!srv_track_changed_pages
|
||||
|| tracked_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)
|
||||
@ -3784,7 +3790,8 @@ loop:
|
||||
ut_a(freed);
|
||||
|
||||
ut_a(lsn == log_sys->lsn);
|
||||
ut_ad(lsn == log_sys->last_checkpoint_lsn);
|
||||
ut_ad(srv_force_recovery >= SRV_FORCE_NO_LOG_REDO
|
||||
|| lsn == log_sys->last_checkpoint_lsn);
|
||||
|
||||
if (lsn < srv_start_lsn) {
|
||||
ib_logf(IB_LOG_LEVEL_ERROR,
|
||||
|
@ -328,7 +328,7 @@ log_online_read_last_tracked_lsn(void)
|
||||
lsn_t result;
|
||||
os_offset_t read_offset = log_bmp_sys->out.offset;
|
||||
|
||||
while (!checksum_ok && read_offset > 0 && !is_last_page)
|
||||
while ((!checksum_ok || !is_last_page) && read_offset > 0)
|
||||
{
|
||||
read_offset -= MODIFIED_PAGE_BLOCK_SIZE;
|
||||
log_bmp_sys->out.offset = read_offset;
|
||||
@ -556,9 +556,9 @@ log_online_rotate_bitmap_file(
|
||||
lsn_t next_file_start_lsn) /*!<in: the start LSN name
|
||||
part */
|
||||
{
|
||||
if (log_bmp_sys->out.file != os_file_invalid) {
|
||||
if (!os_file_is_invalid(log_bmp_sys->out.file)) {
|
||||
os_file_close(log_bmp_sys->out.file);
|
||||
log_bmp_sys->out.file = os_file_invalid;
|
||||
os_file_mark_invalid(&log_bmp_sys->out.file);
|
||||
}
|
||||
log_bmp_sys->out_seq_num++;
|
||||
log_online_make_bitmap_name(next_file_start_lsn);
|
||||
@ -728,7 +728,11 @@ log_online_read_init(void)
|
||||
}
|
||||
|
||||
last_tracked_lsn = log_online_read_last_tracked_lsn();
|
||||
/* Do not rotate if we truncated the file to zero length - we
|
||||
can just start writing there */
|
||||
const bool need_rotate = (last_tracked_lsn != 0);
|
||||
if (!last_tracked_lsn) {
|
||||
|
||||
last_tracked_lsn = last_file_start_lsn;
|
||||
}
|
||||
|
||||
@ -740,7 +744,10 @@ log_online_read_init(void)
|
||||
} else {
|
||||
file_start_lsn = tracking_start_lsn;
|
||||
}
|
||||
if (!log_online_rotate_bitmap_file(file_start_lsn)) {
|
||||
|
||||
if (need_rotate
|
||||
&& !log_online_rotate_bitmap_file(file_start_lsn)) {
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -780,9 +787,9 @@ log_online_read_shutdown(void)
|
||||
|
||||
ib_rbt_node_t *free_list_node = log_bmp_sys->page_free_list;
|
||||
|
||||
if (log_bmp_sys->out.file != os_file_invalid) {
|
||||
if (!os_file_is_invalid(log_bmp_sys->out.file)) {
|
||||
os_file_close(log_bmp_sys->out.file);
|
||||
log_bmp_sys->out.file = os_file_invalid;
|
||||
os_file_mark_invalid(&log_bmp_sys->out.file);
|
||||
}
|
||||
|
||||
rbt_free(log_bmp_sys->modified_pages);
|
||||
@ -1121,6 +1128,18 @@ log_online_write_bitmap_page(
|
||||
}
|
||||
});
|
||||
|
||||
/* A crash injection site that ensures last checkpoint LSN > last
|
||||
tracked LSN, so that LSN tracking for this interval is tested. */
|
||||
DBUG_EXECUTE_IF("crash_before_bitmap_write",
|
||||
{
|
||||
ulint space_id
|
||||
= mach_read_from_4(block
|
||||
+ MODIFIED_PAGE_SPACE_ID);
|
||||
if (space_id > 0)
|
||||
DBUG_SUICIDE();
|
||||
});
|
||||
|
||||
|
||||
ibool success = os_file_write(log_bmp_sys->out.name,
|
||||
log_bmp_sys->out.file, block,
|
||||
log_bmp_sys->out.offset,
|
||||
@ -1144,10 +1163,8 @@ log_online_write_bitmap_page(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef UNIV_LINUX
|
||||
posix_fadvise(log_bmp_sys->out.file, log_bmp_sys->out.offset,
|
||||
MODIFIED_PAGE_BLOCK_SIZE, POSIX_FADV_DONTNEED);
|
||||
#endif
|
||||
os_file_advise(log_bmp_sys->out.file, log_bmp_sys->out.offset,
|
||||
MODIFIED_PAGE_BLOCK_SIZE, OS_FILE_ADVISE_DONTNEED);
|
||||
|
||||
log_bmp_sys->out.offset += MODIFIED_PAGE_BLOCK_SIZE;
|
||||
return TRUE;
|
||||
@ -1269,10 +1286,6 @@ log_online_follow_redo_log(void)
|
||||
group = UT_LIST_GET_NEXT(log_groups, group);
|
||||
}
|
||||
|
||||
/* A crash injection site that ensures last checkpoint LSN > last
|
||||
tracked LSN, so that LSN tracking for this interval is tested. */
|
||||
DBUG_EXECUTE_IF("crash_before_bitmap_write", DBUG_SUICIDE(););
|
||||
|
||||
result = log_online_write_bitmap();
|
||||
log_bmp_sys->start_lsn = log_bmp_sys->end_lsn;
|
||||
log_set_tracked_lsn(log_bmp_sys->start_lsn);
|
||||
@ -1542,10 +1555,8 @@ log_online_open_bitmap_file_read_only(
|
||||
bitmap_file->size = os_file_get_size(bitmap_file->file);
|
||||
bitmap_file->offset = 0;
|
||||
|
||||
#ifdef UNIV_LINUX
|
||||
posix_fadvise(bitmap_file->file, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
posix_fadvise(bitmap_file->file, 0, 0, POSIX_FADV_NOREUSE);
|
||||
#endif
|
||||
os_file_advise(bitmap_file->file, 0, 0, OS_FILE_ADVISE_SEQUENTIAL);
|
||||
os_file_advise(bitmap_file->file, 0, 0, OS_FILE_ADVISE_NOREUSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1631,7 +1642,7 @@ log_online_bitmap_iterator_init(
|
||||
/* Empty range */
|
||||
i->in_files.count = 0;
|
||||
i->in_files.files = NULL;
|
||||
i->in.file = os_file_invalid;
|
||||
os_file_mark_invalid(&i->in.file);
|
||||
i->page = NULL;
|
||||
i->failed = FALSE;
|
||||
return TRUE;
|
||||
@ -1649,7 +1660,7 @@ log_online_bitmap_iterator_init(
|
||||
if (i->in_files.count == 0) {
|
||||
|
||||
/* Empty range */
|
||||
i->in.file = os_file_invalid;
|
||||
os_file_mark_invalid(&i->in.file);
|
||||
i->page = NULL;
|
||||
i->failed = FALSE;
|
||||
return TRUE;
|
||||
@ -1688,10 +1699,10 @@ log_online_bitmap_iterator_release(
|
||||
{
|
||||
ut_a(i);
|
||||
|
||||
if (i->in.file != os_file_invalid) {
|
||||
if (!os_file_is_invalid(i->in.file)) {
|
||||
|
||||
os_file_close(i->in.file);
|
||||
i->in.file = os_file_invalid;
|
||||
os_file_mark_invalid(&i->in.file);
|
||||
}
|
||||
if (i->in_files.files) {
|
||||
|
||||
@ -1745,8 +1756,9 @@ log_online_bitmap_iterator_next(
|
||||
|
||||
/* Advance file */
|
||||
i->in_i++;
|
||||
success = os_file_close_no_error_handling(i->in.file);
|
||||
i->in.file = os_file_invalid;
|
||||
success = os_file_close_no_error_handling(
|
||||
i->in.file);
|
||||
os_file_mark_invalid(&i->in.file);
|
||||
if (UNIV_UNLIKELY(!success)) {
|
||||
|
||||
os_file_get_last_error(TRUE);
|
||||
@ -1855,7 +1867,7 @@ log_online_purge_changed_page_bitmaps(
|
||||
/* If we have to delete the current output file, close it
|
||||
first. */
|
||||
os_file_close(log_bmp_sys->out.file);
|
||||
log_bmp_sys->out.file = os_file_invalid;
|
||||
os_file_mark_invalid(&log_bmp_sys->out.file);
|
||||
}
|
||||
|
||||
for (i = 0; i < bitmap_files.count; i++) {
|
||||
|
@ -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.
|
||||
|
||||
@ -327,6 +327,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
|
||||
@ -357,6 +358,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. */
|
||||
|
@ -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.
|
||||
|
||||
@ -87,9 +87,11 @@ my_umask */
|
||||
#ifndef __WIN__
|
||||
/** Umask for creating files */
|
||||
UNIV_INTERN ulint os_innodb_umask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
|
||||
# define os_file_invalid (-1)
|
||||
#else
|
||||
/** Umask for creating files */
|
||||
UNIV_INTERN ulint os_innodb_umask = 0;
|
||||
# define os_file_invalid INVALID_HANDLE_VALUE
|
||||
#endif /* __WIN__ */
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
@ -184,7 +186,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
|
||||
@ -1427,7 +1429,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
|
||||
@ -1441,7 +1443,7 @@ os_file_create_simple_no_error_handling_func(
|
||||
if it would be enabled otherwise) */
|
||||
ibool* success)/*!< out: TRUE if succeed, FALSE if error */
|
||||
{
|
||||
os_file_t file;
|
||||
pfs_os_file_t file;
|
||||
|
||||
*success = FALSE;
|
||||
#ifdef __WIN__
|
||||
@ -1449,7 +1451,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));
|
||||
@ -1466,8 +1467,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) {
|
||||
@ -1491,11 +1492,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
|
||||
@ -1503,11 +1504,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));
|
||||
@ -1550,19 +1550,19 @@ 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
|
||||
we open the same file in the same mode, see man page of open(2). */
|
||||
if (*success) {
|
||||
os_file_set_nocache_if_needed(file, name, mode_str,
|
||||
os_file_set_nocache_if_needed(file.m_file, name, mode_str,
|
||||
OS_DATA_FILE, access_type);
|
||||
}
|
||||
|
||||
@ -1571,11 +1571,11 @@ os_file_create_simple_no_error_handling_func(
|
||||
&& *success
|
||||
&& (access_type == OS_FILE_READ_WRITE
|
||||
|| access_type == OS_FILE_READ_WRITE_CACHED)
|
||||
&& 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 */
|
||||
@ -1687,7 +1687,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
|
||||
@ -1703,24 +1703,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__ */
|
||||
|
||||
@ -1771,7 +1772,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;
|
||||
@ -1796,8 +1798,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
|
||||
@ -1834,11 +1836,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
|
||||
@ -1873,7 +1875,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
|
||||
@ -1911,7 +1912,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);
|
||||
@ -1931,9 +1933,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
|
||||
@ -1957,14 +1959,15 @@ os_file_create_func(
|
||||
|
||||
if (*success) {
|
||||
|
||||
os_file_set_nocache_if_needed(file, name, mode_str, type, 0);
|
||||
os_file_set_nocache_if_needed(file.m_file, name, mode_str,
|
||||
type, 0);
|
||||
}
|
||||
|
||||
#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) {
|
||||
|
||||
@ -1976,7 +1979,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);
|
||||
}
|
||||
@ -1987,17 +1990,18 @@ os_file_create_func(
|
||||
}
|
||||
|
||||
*success = FALSE;
|
||||
close(file);
|
||||
file = -1;
|
||||
close(file.m_file);
|
||||
file.m_file = -1;
|
||||
}
|
||||
#endif /* USE_FILE_LOCK */
|
||||
|
||||
if (srv_use_atomic_writes && type == OS_DATA_FILE
|
||||
&& file != -1 && !os_file_set_atomic_writes(name, file)) {
|
||||
&& file.m_file != -1
|
||||
&& !os_file_set_atomic_writes(name, file.m_file)) {
|
||||
|
||||
*success = FALSE;
|
||||
close(file);
|
||||
file = -1;
|
||||
close(file.m_file);
|
||||
file.m_file = -1;
|
||||
}
|
||||
|
||||
#endif /* __WIN__ */
|
||||
@ -2226,8 +2230,8 @@ os_file_close_func(
|
||||
Closes a file handle.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
os_file_close_no_error_handling(
|
||||
bool
|
||||
os_file_close_no_error_handling_func(
|
||||
/*============================*/
|
||||
os_file_t file) /*!< in, own: handle to a file */
|
||||
{
|
||||
@ -2237,10 +2241,10 @@ os_file_close_no_error_handling(
|
||||
ret = CloseHandle(file);
|
||||
|
||||
if (ret) {
|
||||
return(TRUE);
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
return(false);
|
||||
#else
|
||||
int ret;
|
||||
|
||||
@ -2248,10 +2252,83 @@ os_file_close_no_error_handling(
|
||||
|
||||
if (ret == -1) {
|
||||
|
||||
return(FALSE);
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
return(true);
|
||||
#endif /* __WIN__ */
|
||||
}
|
||||
|
||||
#ifdef HAVE_POSIX_FALLOCATE
|
||||
/***********************************************************************//**
|
||||
Ensures that disk space is allocated for the file.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
os_file_allocate_func(
|
||||
os_file_t file, /*!< in, own: handle to a file */
|
||||
os_offset_t offset, /*!< in: file region offset */
|
||||
os_offset_t len) /*!< in: file region length */
|
||||
{
|
||||
return(posix_fallocate(file, offset, len) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************//**
|
||||
Checks if the file is marked as invalid.
|
||||
@return TRUE if invalid */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
os_file_is_invalid(
|
||||
pfs_os_file_t file) /*!< in, own: handle to a file */
|
||||
{
|
||||
return(file.m_file == os_file_invalid);
|
||||
}
|
||||
|
||||
/***********************************************************************//**
|
||||
Marks the file as invalid. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
os_file_mark_invalid(
|
||||
pfs_os_file_t* file) /*!< out: pointer to a handle to a file */
|
||||
{
|
||||
file->m_file = os_file_invalid;
|
||||
}
|
||||
|
||||
/***********************************************************************//**
|
||||
Announces an intention to access file data in a specific pattern in the
|
||||
future.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
os_file_advise(
|
||||
pfs_os_file_t file, /*!< in, own: handle to a file */
|
||||
os_offset_t offset, /*!< in: file region offset */
|
||||
os_offset_t len, /*!< in: file region length */
|
||||
ulint advice)/*!< in: advice for access pattern */
|
||||
{
|
||||
#ifdef __WIN__
|
||||
return(true);
|
||||
#else
|
||||
#ifdef UNIV_LINUX
|
||||
int native_advice = 0;
|
||||
if ((advice & OS_FILE_ADVISE_NORMAL) != 0)
|
||||
native_advice |= POSIX_FADV_NORMAL;
|
||||
if ((advice & OS_FILE_ADVISE_RANDOM) != 0)
|
||||
native_advice |= POSIX_FADV_RANDOM;
|
||||
if ((advice & OS_FILE_ADVISE_SEQUENTIAL) != 0)
|
||||
native_advice |= POSIX_FADV_SEQUENTIAL;
|
||||
if ((advice & OS_FILE_ADVISE_WILLNEED) != 0)
|
||||
native_advice |= POSIX_FADV_WILLNEED;
|
||||
if ((advice & OS_FILE_ADVISE_DONTNEED) != 0)
|
||||
native_advice |= POSIX_FADV_DONTNEED;
|
||||
if ((advice & OS_FILE_ADVISE_NOREUSE) != 0)
|
||||
native_advice |= POSIX_FADV_NOREUSE;
|
||||
|
||||
return(posix_fadvise(file.m_file, offset, len, native_advice) == 0);
|
||||
#else
|
||||
return(true);
|
||||
#endif
|
||||
#endif /* __WIN__ */
|
||||
}
|
||||
|
||||
@ -2262,14 +2339,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);
|
||||
@ -2279,7 +2356,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__ */
|
||||
}
|
||||
|
||||
@ -2292,7 +2370,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;
|
||||
@ -2304,7 +2382,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);
|
||||
|
||||
@ -2383,8 +2461,8 @@ os_file_set_eof(
|
||||
Truncates a file at the specified position.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
os_file_set_eof_at(
|
||||
bool
|
||||
os_file_set_eof_at_func(
|
||||
os_file_t file, /*!< in: handle to a file */
|
||||
ib_uint64_t new_len)/*!< in: new file length */
|
||||
{
|
||||
@ -4314,7 +4392,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
|
||||
@ -4437,10 +4515,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;
|
||||
@ -4674,7 +4752,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 */
|
||||
@ -4697,7 +4775,6 @@ os_aio_func(
|
||||
BOOL ret;
|
||||
#endif
|
||||
ulint wake_later;
|
||||
|
||||
ut_ad(buf);
|
||||
ut_ad(n > 0);
|
||||
ut_ad(n % OS_MIN_LOG_BLOCK_SIZE == 0);
|
||||
@ -4719,7 +4796,7 @@ os_aio_func(
|
||||
no need to use an i/o-handler thread */
|
||||
|
||||
if (type == OS_FILE_READ) {
|
||||
ret = os_file_read_func(file, buf, offset, n, trx);
|
||||
ret = os_file_read_func(file.m_file, buf, offset, n, trx);
|
||||
} else {
|
||||
ut_ad(!srv_read_only_mode);
|
||||
ut_a(type == OS_FILE_WRITE);
|
||||
@ -4795,7 +4872,7 @@ 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));
|
||||
if(!ret && GetLastError() != ERROR_IO_PENDING)
|
||||
goto err_exit;
|
||||
@ -4817,7 +4894,7 @@ 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));
|
||||
|
||||
if(!ret && GetLastError() != ERROR_IO_PENDING)
|
||||
@ -4937,7 +5014,6 @@ os_aio_windows_handle(
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*message1 = slot->message1;
|
||||
*message2 = slot->message2;
|
||||
|
||||
@ -4964,11 +5040,11 @@ os_aio_windows_handle(
|
||||
|
||||
switch (slot->type) {
|
||||
case OS_FILE_WRITE:
|
||||
ret_val = os_file_write(slot->name, slot->file, slot->buf,
|
||||
ret_val = os_file_write(slot->name, slot->file.m_file, slot->buf,
|
||||
li.QuadPart, slot->len);
|
||||
break;
|
||||
case OS_FILE_READ:
|
||||
ret_val = os_file_read(slot->file, slot->buf,
|
||||
ret_val = os_file_read(slot->file, slot->buf,
|
||||
li.QuadPart, slot->len);
|
||||
break;
|
||||
default:
|
||||
@ -5223,12 +5299,14 @@ found:
|
||||
iocb = &(slot->control);
|
||||
|
||||
if (slot->type == OS_FILE_READ) {
|
||||
io_prep_pread(&slot->control, slot->file, slot->buf,
|
||||
slot->len, (off_t) slot->offset);
|
||||
io_prep_pread(&slot->control, slot->file.m_file,
|
||||
slot->buf, slot->len,
|
||||
(off_t) slot->offset);
|
||||
} else {
|
||||
ut_a(slot->type == OS_FILE_WRITE);
|
||||
io_prep_pwrite(&slot->control, slot->file, slot->buf,
|
||||
slot->len, (off_t) slot->offset);
|
||||
io_prep_pwrite(&slot->control, slot->file.m_file,
|
||||
slot->buf, slot->len,
|
||||
(off_t) slot->offset);
|
||||
}
|
||||
/* Resubmit an I/O request */
|
||||
submit_ret = io_submit(array->aio_ctx[segment], 1, &iocb);
|
||||
@ -5455,12 +5533,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 */
|
||||
|
||||
|
@ -948,12 +948,14 @@ opt_find_all_cols(
|
||||
/* Fill in the field_no fields in sym_node */
|
||||
|
||||
sym_node->field_nos[SYM_CLUST_FIELD_NO] = dict_index_get_nth_col_pos(
|
||||
dict_table_get_first_index(index->table), sym_node->col_no);
|
||||
dict_table_get_first_index(index->table), sym_node->col_no,
|
||||
NULL);
|
||||
if (!dict_index_is_clust(index)) {
|
||||
|
||||
ut_a(plan);
|
||||
|
||||
col_pos = dict_index_get_nth_col_pos(index, sym_node->col_no);
|
||||
col_pos = dict_index_get_nth_col_pos(index, sym_node->col_no,
|
||||
NULL);
|
||||
|
||||
if (col_pos == ULINT_UNDEFINED) {
|
||||
|
||||
|
@ -1232,7 +1232,8 @@ pars_process_assign_list(
|
||||
col_sym = assign_node->col;
|
||||
|
||||
upd_field_set_field_no(upd_field, dict_index_get_nth_col_pos(
|
||||
clust_index, col_sym->col_no),
|
||||
clust_index, col_sym->col_no,
|
||||
NULL),
|
||||
clust_index, NULL);
|
||||
upd_field->exp = assign_node->val;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -871,8 +871,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);
|
||||
@ -906,7 +907,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) {
|
||||
@ -3144,14 +3145,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) {
|
||||
@ -3198,15 +3206,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
|
||||
}
|
||||
/*********************************************************************//**
|
||||
|
@ -64,6 +64,8 @@ Created 12/19/1997 Heikki Tuuri
|
||||
|
||||
#include "my_compare.h" /* enum icp_result */
|
||||
|
||||
#include <vector>
|
||||
|
||||
/* Maximum number of rows to prefetch; MySQL interface has another parameter */
|
||||
#define SEL_MAX_N_PREFETCH 16
|
||||
|
||||
@ -2713,7 +2715,8 @@ row_sel_field_store_in_mysql_format_func(
|
||||
|| !(templ->mysql_col_len % templ->mbmaxlen));
|
||||
ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len
|
||||
|| (field_no == templ->icp_rec_field_no
|
||||
&& field->prefix_len > 0));
|
||||
&& field->prefix_len > 0)
|
||||
|| templ->rec_field_is_prefix);
|
||||
ut_ad(!(field->prefix_len % templ->mbmaxlen));
|
||||
|
||||
if (templ->mbminlen == 1 && templ->mbmaxlen != 1) {
|
||||
@ -2755,27 +2758,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;
|
||||
@ -2904,31 +2912,31 @@ 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)
|
||||
@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;
|
||||
|
||||
ut_ad(rec_clust || index == prebuilt->index);
|
||||
ut_ad(!rec_clust || dict_index_is_clust(index));
|
||||
|
||||
@ -2944,9 +2952,12 @@ row_sel_store_mysql_rec(
|
||||
? templ->clust_rec_field_no
|
||||
: templ->rec_field_no;
|
||||
/* We should never deliver column prefixes to MySQL,
|
||||
except for evaluating innobase_index_cond(). */
|
||||
except for evaluating innobase_index_cond() and if the prefix
|
||||
index is longer than the actual row data. */
|
||||
|
||||
ut_ad(dict_index_get_nth_field(index, field_no)->prefix_len
|
||||
== 0);
|
||||
== 0 || templ->rec_field_is_prefix);
|
||||
|
||||
|
||||
if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
|
||||
rec, index, offsets,
|
||||
@ -3040,6 +3051,8 @@ row_sel_get_clust_rec_for_mysql(
|
||||
dberr_t err;
|
||||
trx_t* trx;
|
||||
|
||||
os_atomic_increment_ulint(&srv_sec_rec_cluster_reads, 1);
|
||||
|
||||
*out_rec = NULL;
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
@ -3633,6 +3646,30 @@ row_search_idx_cond_check(
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** Return the record field length in characters.
|
||||
@param[in] col table column of the field
|
||||
@param[in] field_no field number
|
||||
@param[in] rec physical record
|
||||
@param[in] offsets field offsets in the physical record
|
||||
|
||||
@return field length in characters */
|
||||
static
|
||||
size_t
|
||||
rec_field_len_in_chars(const dict_col_t &col,
|
||||
const ulint field_no,
|
||||
const rec_t *rec,
|
||||
const ulint *offsets)
|
||||
{
|
||||
const ulint cset = dtype_get_charset_coll(col.prtype);
|
||||
const CHARSET_INFO* cs = all_charsets[cset];
|
||||
ulint rec_field_len;
|
||||
const char* rec_field = reinterpret_cast<const char *>(
|
||||
rec_get_nth_field(
|
||||
rec, offsets, field_no, &rec_field_len));
|
||||
return(cs->cset->numchars(cs, rec_field, rec_field + rec_field_len));
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Searches for rows in the database. This is used in the interface to
|
||||
MySQL. This function opens a cursor, and also implements fetch next
|
||||
@ -3671,7 +3708,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;
|
||||
@ -3696,6 +3733,7 @@ row_search_for_mysql(
|
||||
ulint* offsets = offsets_;
|
||||
ibool table_lock_waited = FALSE;
|
||||
byte* next_buf = 0;
|
||||
bool use_clustered_index = false;
|
||||
|
||||
rec_offs_init(offsets_);
|
||||
|
||||
@ -3953,7 +3991,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
|
||||
@ -4211,7 +4250,6 @@ rec_loop:
|
||||
}
|
||||
|
||||
if (page_rec_is_supremum(rec)) {
|
||||
|
||||
if (set_also_gap_locks
|
||||
&& !(srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED)
|
||||
@ -4724,10 +4762,85 @@ locks_ok:
|
||||
}
|
||||
|
||||
/* Get the clustered index record if needed, if we did not do the
|
||||
search using the clustered index. */
|
||||
search using the clustered index... */
|
||||
|
||||
if (index != clust_index && prebuilt->need_to_access_clustered) {
|
||||
|
||||
use_clustered_index =
|
||||
(index != clust_index && prebuilt->need_to_access_clustered);
|
||||
|
||||
if (use_clustered_index && prebuilt->n_template <= index->n_fields) {
|
||||
/* ...but, perhaps avoid the clustered index lookup if
|
||||
all of the following are true:
|
||||
1) all columns are in the secondary index
|
||||
2) all values for columns that are prefix-only
|
||||
indexes are shorter than the prefix size
|
||||
This optimization can avoid many IOs for certain schemas.
|
||||
*/
|
||||
bool row_contains_all_values = true;
|
||||
unsigned int i;
|
||||
for (i = 0; i < prebuilt->n_template; i++) {
|
||||
/* Condition (1) from above: is the field in the
|
||||
index (prefix or not)? */
|
||||
const mysql_row_templ_t* templ =
|
||||
prebuilt->mysql_template + i;
|
||||
ulint secondary_index_field_no =
|
||||
templ->rec_prefix_field_no;
|
||||
if (secondary_index_field_no == ULINT_UNDEFINED) {
|
||||
row_contains_all_values = false;
|
||||
break;
|
||||
}
|
||||
/* Condition (2) from above: if this is a
|
||||
prefix, is this row's value size shorter
|
||||
than the prefix? */
|
||||
if (templ->rec_field_is_prefix) {
|
||||
ulint record_size = rec_offs_nth_size(
|
||||
offsets,
|
||||
secondary_index_field_no);
|
||||
const dict_field_t *field =
|
||||
dict_index_get_nth_field(
|
||||
index,
|
||||
secondary_index_field_no);
|
||||
ut_a(field->prefix_len > 0);
|
||||
if (record_size
|
||||
< field->prefix_len / templ->mbmaxlen) {
|
||||
|
||||
/* Record in bytes shorter than the
|
||||
index prefix length in characters */
|
||||
continue;
|
||||
|
||||
} else if (record_size * templ->mbminlen
|
||||
>= field->prefix_len) {
|
||||
|
||||
/* The shortest represantable string by
|
||||
the byte length of the record is longer
|
||||
than the maximum possible index
|
||||
prefix. */
|
||||
row_contains_all_values = false;
|
||||
break;
|
||||
} else {
|
||||
|
||||
row_contains_all_values = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If (1) and (2) were true for all columns above, use
|
||||
rec_prefix_field_no instead of rec_field_no, and skip
|
||||
the clustered lookup below. */
|
||||
if (row_contains_all_values) {
|
||||
for (i = 0; i < prebuilt->n_template; i++) {
|
||||
mysql_row_templ_t* templ =
|
||||
prebuilt->mysql_template + i;
|
||||
templ->rec_field_no =
|
||||
templ->rec_prefix_field_no;
|
||||
ut_a(templ->rec_field_no != ULINT_UNDEFINED);
|
||||
}
|
||||
use_clustered_index = false;
|
||||
os_atomic_increment_ulint(
|
||||
&srv_sec_rec_cluster_reads_avoided, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (use_clustered_index) {
|
||||
requires_clust_rec:
|
||||
ut_ad(index != clust_index);
|
||||
/* We use a 'goto' to the preceding label if a consistent
|
||||
|
@ -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.
|
||||
@ -156,7 +156,8 @@ UNIV_INTERN unsigned long long srv_online_max_size;
|
||||
OS (provided we compiled Innobase with it in), otherwise we will
|
||||
use simulated aio we build below with threads.
|
||||
Currently we support native aio on windows and linux */
|
||||
UNIV_INTERN my_bool srv_use_native_aio = TRUE;
|
||||
/* make srv_use_native_aio to be visible for other plugins */
|
||||
my_bool srv_use_native_aio = TRUE;
|
||||
UNIV_INTERN my_bool srv_numa_interleave = FALSE;
|
||||
|
||||
#ifdef __WIN__
|
||||
@ -596,6 +597,12 @@ static ulint srv_main_shutdown_loops = 0;
|
||||
/** Log writes involving flush. */
|
||||
static ulint srv_log_writes_and_flush = 0;
|
||||
|
||||
/** Number of times secondary index lookup triggered cluster lookup */
|
||||
ulint srv_sec_rec_cluster_reads = 0;
|
||||
|
||||
/** Number of times prefix optimization avoided triggering cluster lookup */
|
||||
ulint srv_sec_rec_cluster_reads_avoided = 0;
|
||||
|
||||
/* This is only ever touched by the master thread. It records the
|
||||
time when the last flush of log file has happened. The master
|
||||
thread ensures that we flush the log files at least once per
|
||||
@ -1993,6 +2000,12 @@ srv_export_innodb_status(void)
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
os_rmb;
|
||||
export_vars.innodb_sec_rec_cluster_reads =
|
||||
srv_sec_rec_cluster_reads;
|
||||
export_vars.innodb_sec_rec_cluster_reads_avoided =
|
||||
srv_sec_rec_cluster_reads_avoided;
|
||||
|
||||
mutex_exit(&srv_innodb_monitor_mutex);
|
||||
}
|
||||
|
||||
@ -3046,6 +3059,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();
|
||||
ulint old_ibuf_merge_activity_count
|
||||
@ -3119,6 +3134,7 @@ suspend_thread:
|
||||
srv_resume_thread(slot);
|
||||
|
||||
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
|
||||
my_thread_end();
|
||||
os_thread_exit(NULL);
|
||||
}
|
||||
|
||||
@ -3205,6 +3221,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;
|
||||
ulint tid_i = os_atomic_increment_ulint(&purge_tid_i, 1);
|
||||
|
||||
@ -3270,6 +3288,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);
|
||||
@ -3438,6 +3457,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;
|
||||
|
||||
@ -3551,6 +3572,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);
|
||||
@ -3616,3 +3638,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));
|
||||
}
|
||||
|
@ -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) 2017, MariaDB Corporation.
|
||||
@ -112,6 +112,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;
|
||||
@ -127,7 +130,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];
|
||||
@ -570,7 +573,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;
|
||||
@ -786,7 +789,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 */
|
||||
{
|
||||
@ -902,7 +905,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 */
|
||||
@ -1199,7 +1202,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;
|
||||
|
||||
@ -1276,7 +1279,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;
|
||||
@ -1375,13 +1378,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);
|
||||
|
||||
@ -1403,14 +1416,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
|
||||
@ -1434,8 +1449,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) {
|
||||
@ -1470,11 +1483,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. */
|
||||
@ -1519,10 +1544,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);
|
||||
@ -1633,6 +1659,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;
|
||||
|
||||
|
@ -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
|
||||
@ -690,7 +690,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;
|
||||
|
||||
|
@ -781,7 +781,8 @@ trx_undo_page_report_modify(
|
||||
}
|
||||
|
||||
pos = dict_index_get_nth_col_pos(index,
|
||||
col_no);
|
||||
col_no,
|
||||
NULL);
|
||||
ptr += mach_write_compressed(ptr, pos);
|
||||
|
||||
/* Save the old value of field */
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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
|
||||
@ -918,18 +918,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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user