summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2018-01-23 18:04:34 +0200
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2018-01-23 18:04:34 +0200
commitcd33250d2acf65361ee2ead625c626bfd2f51046 (patch)
tree99a17eed2623f31a1c2b9373cf82fce3e762cca4 /storage
parentb4606367d7ba82652a346320d458c25c391847ea (diff)
downloadmariadb-git-cd33250d2acf65361ee2ead625c626bfd2f51046.tar.gz
5.6.38-83.0
Diffstat (limited to 'storage')
-rw-r--r--storage/xtradb/btr/btr0pcur.cc40
-rw-r--r--storage/xtradb/buf/buf0rea.cc29
-rw-r--r--storage/xtradb/dict/dict0stats_bg.cc2
-rw-r--r--storage/xtradb/fil/fil0fil.cc11
-rw-r--r--storage/xtradb/fts/fts0fts.cc84
-rw-r--r--storage/xtradb/fts/fts0opt.cc11
-rw-r--r--storage/xtradb/fts/fts0que.cc7
-rw-r--r--storage/xtradb/handler/ha_innodb.cc41
-rw-r--r--storage/xtradb/handler/handler0alter.cc51
-rw-r--r--storage/xtradb/include/data0type.ic3
-rw-r--r--storage/xtradb/include/dict0dict.ic23
-rw-r--r--storage/xtradb/include/dict0mem.h4
-rw-r--r--storage/xtradb/include/dict0stats_bg.h4
-rw-r--r--storage/xtradb/include/fil0fil.h12
-rw-r--r--storage/xtradb/include/log0online.h6
-rw-r--r--storage/xtradb/include/mach0data.ic14
-rw-r--r--storage/xtradb/include/os0file.h27
-rw-r--r--storage/xtradb/include/os0file.ic6
-rw-r--r--storage/xtradb/include/page0zip.ic2
-rw-r--r--storage/xtradb/include/srv0srv.h13
-rw-r--r--storage/xtradb/include/trx0rec.h2
-rw-r--r--storage/xtradb/include/univ.i2
-rw-r--r--storage/xtradb/include/ut0rnd.ic12
-rw-r--r--storage/xtradb/lock/lock0wait.cc79
-rw-r--r--storage/xtradb/log/log0online.cc2
-rw-r--r--storage/xtradb/os/os0file.cc146
-rw-r--r--storage/xtradb/page/page0page.cc2
-rw-r--r--storage/xtradb/row/row0import.cc1
-rw-r--r--storage/xtradb/row/row0log.cc1
-rw-r--r--storage/xtradb/row/row0mysql.cc16
-rw-r--r--storage/xtradb/row/row0purge.cc4
-rw-r--r--storage/xtradb/row/row0sel.cc33
-rw-r--r--storage/xtradb/srv/srv0srv.cc10
-rw-r--r--storage/xtradb/sync/sync0sync.cc3
34 files changed, 604 insertions, 99 deletions
diff --git a/storage/xtradb/btr/btr0pcur.cc b/storage/xtradb/btr/btr0pcur.cc
index 28a60de6ba2..2965cbcaf9e 100644
--- a/storage/xtradb/btr/btr0pcur.cc
+++ b/storage/xtradb/btr/btr0pcur.cc
@@ -33,6 +33,40 @@ Created 2/23/1996 Heikki Tuuri
#include "rem0cmp.h"
#include "trx0trx.h"
#include "srv0srv.h"
+
+/** Updates fragmentation statistics for a single page transition.
+@param[in] page the current page being processed
+@param[in] page_no page number to move to (next_page_no
+ if forward_direction is true,
+ prev_page_no otherwise.
+@param[in] forward_direction move direction: true means moving
+ forward, false - backward. */
+static
+void
+btr_update_scan_stats(const page_t* page, ulint page_no, bool forward_direction)
+{
+ fragmentation_stats_t stats;
+ memset(&stats, 0, sizeof(stats));
+ ulint extracted_page_no = page_get_page_no(page);
+ ulint delta = forward_direction ?
+ page_no - extracted_page_no :
+ extracted_page_no - page_no;
+
+ if (delta == 1) {
+ ++stats.scan_pages_contiguous;
+ } else {
+ ++stats.scan_pages_disjointed;
+ }
+ stats.scan_pages_total_seek_distance +=
+ extracted_page_no > page_no ?
+ extracted_page_no - page_no :
+ page_no - extracted_page_no;
+
+ stats.scan_data_size += page_get_data_size(page);
+ stats.scan_deleted_recs_size +=
+ page_header_get_field(page, PAGE_GARBAGE);
+ thd_add_fragmentation_stats(current_thd, &stats);
+}
/**************************************************************//**
Allocates memory for a persistent cursor object and initializes the cursor.
@return own: persistent cursor */
@@ -426,6 +460,8 @@ btr_pcur_move_to_next_page(
ut_ad(next_page_no != FIL_NULL);
+ btr_update_scan_stats(page, next_page_no, true /* forward */);
+
next_block = btr_block_get(space, zip_size, next_page_no,
cursor->latch_mode,
btr_pcur_get_btr_cur(cursor)->index, mtr);
@@ -509,6 +545,10 @@ btr_pcur_move_backward_from_page(
prev_page_no = btr_page_get_prev(page, mtr);
+ if (prev_page_no != FIL_NULL) {
+ btr_update_scan_stats(page, prev_page_no, false /* backward */);
+ }
+
if (prev_page_no == FIL_NULL) {
} else if (btr_pcur_is_before_first_on_page(cursor)) {
diff --git a/storage/xtradb/buf/buf0rea.cc b/storage/xtradb/buf/buf0rea.cc
index c28df72df92..2e935c52a59 100644
--- a/storage/xtradb/buf/buf0rea.cc
+++ b/storage/xtradb/buf/buf0rea.cc
@@ -123,7 +123,12 @@ buf_read_page_low(
use to stop dangling page reads from a tablespace
which we have DISCARDed + IMPORTed back */
ulint offset, /*!< in: page number */
- trx_t* trx)
+ trx_t* trx,
+ bool should_buffer) /*!< in: whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
{
buf_page_t* bpage;
ulint wake_later;
@@ -229,14 +234,15 @@ not_to_recover:
*err = _fil_io(OS_FILE_READ | wake_later
| ignore_nonexistent_pages,
sync, space, zip_size, offset, 0, zip_size,
- bpage->zip.data, bpage, trx);
+ bpage->zip.data, bpage, trx, should_buffer);
} else {
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
*err = _fil_io(OS_FILE_READ | wake_later
| ignore_nonexistent_pages,
sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
- ((buf_block_t*) bpage)->frame, bpage, trx);
+ ((buf_block_t*) bpage)->frame, bpage, trx,
+ should_buffer);
}
if (sync) {
@@ -395,7 +401,7 @@ read_ahead:
&err, false,
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
space, zip_size, FALSE,
- tablespace_version, i, trx);
+ tablespace_version, i, trx, false);
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -459,7 +465,7 @@ buf_read_page(
count = buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space,
zip_size, FALSE,
- tablespace_version, offset, trx);
+ tablespace_version, offset, trx, false);
srv_stats.buf_pool_reads.add(count);
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
@@ -507,7 +513,7 @@ buf_read_page_async(
| OS_AIO_SIMULATED_WAKE_LATER
| BUF_READ_IGNORE_NONEXISTENT_PAGES,
space, zip_size, FALSE,
- tablespace_version, offset, NULL);
+ tablespace_version, offset, NULL, false);
srv_stats.buf_pool_reads.add(count);
/* We do not increment number of I/O operations used for LRU policy
@@ -775,7 +781,8 @@ buf_read_ahead_linear(
count += buf_read_page_low(
&err, false,
ibuf_mode,
- space, zip_size, FALSE, tablespace_version, i, trx);
+ space, zip_size, FALSE, tablespace_version,
+ i, trx, true);
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -788,6 +795,7 @@ buf_read_ahead_linear(
}
}
}
+ os_aio_dispatch_read_array_submit();
/* In simulated aio we wake the aio handler threads only after
queuing all aio requests, in native aio the following call does
@@ -865,7 +873,7 @@ buf_read_ibuf_merge_pages(
buf_read_page_low(&err, sync && (i + 1 == n_stored),
BUF_READ_ANY_PAGE, space_ids[i],
zip_size, TRUE, space_versions[i],
- page_nos[i], NULL);
+ page_nos[i], NULL, false);
if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) {
tablespace_deleted:
@@ -1005,12 +1013,13 @@ not_to_recover:
if ((i + 1 == n_stored) && sync) {
buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space,
zip_size, TRUE, tablespace_version,
- page_nos[i], NULL);
+ page_nos[i], NULL, false);
} else {
buf_read_page_low(&err, false, BUF_READ_ANY_PAGE
| OS_AIO_SIMULATED_WAKE_LATER,
space, zip_size, TRUE,
- tablespace_version, page_nos[i], NULL);
+ tablespace_version, page_nos[i],
+ NULL, false);
}
}
diff --git a/storage/xtradb/dict/dict0stats_bg.cc b/storage/xtradb/dict/dict0stats_bg.cc
index 975c8a50803..bc8fbe6ece4 100644
--- a/storage/xtradb/dict/dict0stats_bg.cc
+++ b/storage/xtradb/dict/dict0stats_bg.cc
@@ -195,7 +195,7 @@ dict_stats_wait_bg_to_stop_using_table(
unlocking/locking the data dict */
{
while (!dict_stats_stop_bg(table)) {
- DICT_STATS_BG_YIELD(trx);
+ DICT_BG_YIELD(trx);
}
}
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index d701bddebfc..081c518afec 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -5253,7 +5253,7 @@ retry:
success = os_aio(OS_FILE_WRITE, OS_AIO_SYNC,
node->name, node->handle, buf,
offset, page_size * n_pages,
- NULL, NULL, space_id, NULL);
+ NULL, NULL, space_id, NULL, false);
#endif /* UNIV_HOTBACKUP */
if (success) {
os_has_said_disk_full = FALSE;
@@ -5630,7 +5630,12 @@ _fil_io(
appropriately aligned */
void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
- trx_t* trx)
+ trx_t* trx,
+ bool should_buffer) /*!< in: whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
{
ulint mode;
fil_space_t* space;
@@ -5848,7 +5853,7 @@ _fil_io(
/* Queue the aio request */
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
- offset, len, node, message, space_id, trx);
+ offset, len, node, message, space_id, trx, should_buffer);
#else
/* In mysqlbackup do normal i/o, not aio */
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index a0f0fab5566..a29e046eb84 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -25,6 +25,7 @@ Full Text Search interface
#include "row0mysql.h"
#include "row0upd.h"
#include "dict0types.h"
+#include "dict0stats_bg.h"
#include "row0sel.h"
#include "fts0fts.h"
@@ -867,18 +868,37 @@ fts_drop_index(
err = fts_drop_index_tables(trx, index);
- fts_free(table);
-
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry){
+ fts_free(table);
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
return(err);
}
- current_doc_id = table->fts->cache->next_doc_id;
- first_doc_id = table->fts->cache->first_doc_id;
- fts_cache_clear(table->fts->cache);
- fts_cache_destroy(table->fts->cache);
- table->fts->cache = fts_cache_create(table);
- table->fts->cache->next_doc_id = current_doc_id;
- table->fts->cache->first_doc_id = first_doc_id;
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry){
+ current_doc_id = table->fts->cache->next_doc_id;
+ first_doc_id = table->fts->cache->first_doc_id;
+ fts_cache_clear(table->fts->cache);
+ fts_cache_destroy(table->fts->cache);
+ table->fts->cache = fts_cache_create(table);
+ table->fts->cache->next_doc_id = current_doc_id;
+ table->fts->cache->first_doc_id = first_doc_id;
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
} else {
fts_cache_t* cache = table->fts->cache;
fts_index_cache_t* index_cache;
@@ -888,9 +908,17 @@ fts_drop_index(
index_cache = fts_find_index_cache(cache, index);
if (index_cache != NULL) {
- if (index_cache->words) {
- fts_words_free(index_cache->words);
- rbt_free(index_cache->words);
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry && index_cache->words) {
+ fts_words_free(index_cache->words);
+ rbt_free(index_cache->words);
+ break;
+ }
+ DICT_BG_YIELD(trx);
}
ib_vector_remove(cache->indexes, *(void**) index_cache);
@@ -4611,10 +4639,16 @@ begin_sync:
index_cache = static_cast<fts_index_cache_t*>(
ib_vector_get(cache->indexes, i));
- if (index_cache->index->to_be_dropped) {
+ if (index_cache->index->to_be_dropped
+ || index_cache->index->table->to_be_dropped) {
continue;
}
+ index_cache->index->index_fts_syncing = true;
+ DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits",
+ os_thread_sleep(10000000);
+ );
+
error = fts_sync_index(sync, index_cache);
if (error != DB_SUCCESS && !sync->interrupted) {
@@ -4647,11 +4681,33 @@ begin_sync:
end_sync:
if (error == DB_SUCCESS && !sync->interrupted) {
error = fts_sync_commit(sync);
+ if (error == DB_SUCCESS) {
+ for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
+ fts_index_cache_t* index_cache;
+ index_cache = static_cast<fts_index_cache_t*>(
+ ib_vector_get(cache->indexes, i));
+ if (index_cache->index->index_fts_syncing) {
+ index_cache->index->index_fts_syncing
+ = false;
+ }
+ }
+ }
} else {
fts_sync_rollback(sync);
}
rw_lock_x_lock(&cache->lock);
+ /* Clear fts syncing flags of any indexes incase sync is
+ interrupeted */
+ for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
+ fts_index_cache_t* index_cache;
+ index_cache = static_cast<fts_index_cache_t*>(
+ ib_vector_get(cache->indexes, i));
+ if (index_cache->index->index_fts_syncing == true) {
+ index_cache->index->index_fts_syncing = false;
+ }
+ }
+
sync->interrupted = false;
sync->in_progress = false;
os_event_set(sync->event);
diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc
index 19098dc00ef..0a9728abe1d 100644
--- a/storage/xtradb/fts/fts0opt.cc
+++ b/storage/xtradb/fts/fts0opt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 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
@@ -2970,13 +2970,6 @@ fts_optimize_sync_table(
{
dict_table_t* table = NULL;
- /* Prevent DROP INDEX etc. from running when we are syncing
- cache in background. */
- if (!rw_lock_s_lock_nowait(&dict_operation_lock, __FILE__, __LINE__)) {
- /* Exit when fail to get dict operation lock. */
- return;
- }
-
table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (table) {
@@ -2986,8 +2979,6 @@ fts_optimize_sync_table(
dict_table_close(table, FALSE, FALSE);
}
-
- rw_lock_s_unlock(&dict_operation_lock);
}
/**********************************************************************//**
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index d926d9b0675..84f616b7800 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 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
@@ -3652,6 +3652,11 @@ fts_query_free(
fts_doc_ids_free(query->deleted);
}
+ if (query->intersection) {
+ fts_query_free_doc_ids(query, query->intersection);
+ query->intersection = NULL;
+ }
+
if (query->doc_ids) {
fts_query_free_doc_ids(query, query->doc_ids);
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 5926ef77794..7b695fd4c5a 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1000,6 +1000,24 @@ static SHOW_VAR innodb_status_variables[]= {
(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},
+ {"buffered_aio_submitted",
+ (char*) &export_vars.innodb_buffered_aio_submitted, SHOW_LONG},
+
+ {"scan_pages_contiguous",
+ (char*) &export_vars.innodb_fragmentation_stats.scan_pages_contiguous,
+ SHOW_LONG},
+ {"scan_pages_disjointed",
+ (char*) &export_vars.innodb_fragmentation_stats.scan_pages_disjointed,
+ SHOW_LONG},
+ {"scan_pages_total_seek_distance",
+ (char*) &export_vars.innodb_fragmentation_stats.scan_pages_total_seek_distance,
+ SHOW_LONG},
+ {"scan_data_size",
+ (char*) &export_vars.innodb_fragmentation_stats.scan_data_size,
+ SHOW_LONG},
+ {"scan_deleted_recs_size",
+ (char*) &export_vars.innodb_fragmentation_stats.scan_deleted_recs_size,
+ SHOW_LONG},
{NullS, NullS, SHOW_LONG}
};
@@ -2847,7 +2865,7 @@ ha_innobase::ha_innobase(
HA_BINLOG_ROW_CAPABLE |
HA_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ |
HA_TABLE_SCAN_ON_INDEX | HA_CAN_FULLTEXT |
- HA_CAN_FULLTEXT_EXT | HA_CAN_EXPORT),
+ HA_CAN_FULLTEXT_EXT | HA_CAN_EXPORT | HA_ONLINE_ANALYZE),
start_of_scan(0),
num_write_row(0)
{}
@@ -7608,7 +7626,8 @@ ha_innobase::innobase_lock_autoinc(void)
break;
}
}
- /* Fall through to old style locking. */
+ // fallthrough
+ // to old style locking.
case AUTOINC_OLD_STYLE_LOCKING:
DBUG_EXECUTE_IF("die_if_autoinc_old_lock_style_used",
@@ -10312,7 +10331,8 @@ create_options_are_invalid(
case ROW_TYPE_DYNAMIC:
CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE(use_tablespace);
CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE;
- /* fall through since dynamic also shuns KBS */
+ // fallthrough
+ // since dynamic also shuns KBS
case ROW_TYPE_COMPACT:
case ROW_TYPE_REDUNDANT:
if (kbs_specified) {
@@ -10700,7 +10720,8 @@ index_bad:
break;
}
zip_allowed = FALSE;
- /* fall through to set row_format = COMPACT */
+ // fallthrough
+ // to set row_format = COMPACT
case ROW_TYPE_NOT_USED:
case ROW_TYPE_FIXED:
case ROW_TYPE_PAGE:
@@ -10709,9 +10730,11 @@ index_bad:
thd, Sql_condition::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: assuming ROW_FORMAT=COMPACT.");
+ // fallthrough
case ROW_TYPE_DEFAULT:
/* If we fell through, set row format to Compact. */
row_format = ROW_TYPE_COMPACT;
+ // fallthrough
case ROW_TYPE_COMPACT:
break;
}
@@ -17537,7 +17560,7 @@ buffer_pool_load_now(
const void* save) /*!< in: immediate result from
check function */
{
- if (*(my_bool*) save) {
+ if (*(my_bool*) save && !srv_read_only_mode) {
buf_load_start();
}
}
@@ -18649,6 +18672,13 @@ static MYSQL_SYSVAR_BOOL(print_all_deadlocks, srv_print_all_deadlocks,
"Print all deadlocks to MySQL error log (off by default)",
NULL, NULL, FALSE);
+static MYSQL_SYSVAR_BOOL(
+ print_lock_wait_timeout_info,
+ srv_print_lock_wait_timeout_info,
+ PLUGIN_VAR_OPCMDARG,
+ "Print lock wait timeout info to MySQL error log (off by default)",
+ NULL, NULL, FALSE);
+
static MYSQL_SYSVAR_ULONG(compression_failure_threshold_pct,
zip_failure_threshold_pct, PLUGIN_VAR_OPCMDARG,
"If the compression failure rate of a table is greater than this number"
@@ -18921,6 +18951,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(foreground_preflush),
MYSQL_SYSVAR(empty_free_list_algorithm),
MYSQL_SYSVAR(print_all_deadlocks),
+ MYSQL_SYSVAR(print_lock_wait_timeout_info),
MYSQL_SYSVAR(cmp_per_index_enabled),
MYSQL_SYSVAR(undo_logs),
MYSQL_SYSVAR(rollback_segments),
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index d6576fe27d5..7e155c99b9d 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2005, 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
@@ -5652,7 +5652,47 @@ ha_innobase::commit_inplace_alter_table(
break;
}
- DICT_STATS_BG_YIELD(trx);
+ DICT_BG_YIELD(trx);
+ }
+
+ /* Make a concurrent Drop fts Index to wait until sync of that
+ fts index is happening in the background */
+ for (;;) {
+ bool retry = false;
+
+ for (inplace_alter_handler_ctx** pctx = ctx_array;
+ *pctx; pctx++) {
+ int count =0;
+ ha_innobase_inplace_ctx* ctx
+ = static_cast<ha_innobase_inplace_ctx*>(*pctx);
+ DBUG_ASSERT(new_clustered == ctx->need_rebuild());
+
+ if (dict_fts_index_syncing(ctx->old_table)) {
+ count++;
+ if (count == 100) {
+ fprintf(stderr,
+ "Drop index waiting for background sync"
+ "to finish\n");
+ }
+ retry = true;
+ }
+
+ if (new_clustered && dict_fts_index_syncing(ctx->new_table)) {
+ count++;
+ if (count == 100) {
+ fprintf(stderr,
+ "Drop index waiting for background sync"
+ "to finish\n");
+ }
+ retry = true;
+ }
+ }
+
+ if (!retry) {
+ break;
+ }
+
+ DICT_BG_YIELD(trx);
}
/* Apply the changes to the data dictionary tables, for all
@@ -5968,8 +6008,13 @@ foreign_fail:
ut_d(dict_table_check_for_dup_indexes(
ctx->new_table, CHECK_ABORTED_OK));
- ut_a(fts_check_cached_index(ctx->new_table));
+#ifdef UNIV_DEBUG
+ if (!(ctx->new_table->fts != NULL
+ && ctx->new_table->fts->cache->sync->in_progress)) {
+ ut_a(fts_check_cached_index(ctx->new_table));
+ }
+#endif
if (new_clustered) {
/* Since the table has been rebuilt, we remove
all persistent statistics corresponding to the
diff --git a/storage/xtradb/include/data0type.ic b/storage/xtradb/include/data0type.ic
index 29dc480a19c..552d62eef00 100644
--- a/storage/xtradb/include/data0type.ic
+++ b/storage/xtradb/include/data0type.ic
@@ -575,7 +575,8 @@ dtype_get_fixed_size_low(
#else /* !UNIV_HOTBACKUP */
return(len);
#endif /* !UNIV_HOTBACKUP */
- /* fall through for variable-length charsets */
+ // fallthrough
+ // for variable-length charsets
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_DECIMAL:
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 32bc4f376d9..72020715bef 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -910,6 +910,27 @@ dict_table_x_lock_indexes(
}
/*********************************************************************//**
+Returns true if the particular FTS index in the table is still syncing
+in the background, false otherwise.
+@param [in] table Table containing FTS index
+@return True if sync of fts index is still going in the background */
+UNIV_INLINE
+bool
+dict_fts_index_syncing(
+ dict_table_t* table)
+{
+ dict_index_t* index;
+
+ for (index = dict_table_get_first_index(table);
+ index != NULL;
+ index = dict_table_get_next_index(index)) {
+ if (index->index_fts_syncing) {
+ return(true);
+ }
+ }
+ return(false);
+}
+/*********************************************************************//**
Release the exclusive locks on all index tree. */
UNIV_INLINE
void
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index a64cb71370e..b6d2ab9fad1 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -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) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@@ -617,6 +617,8 @@ struct dict_index_t{
dict_sys->mutex. Other changes are
protected by index->lock. */
dict_field_t* fields; /*!< array of field descriptions */
+ bool index_fts_syncing;/*!< Whether the fts index is
+ still syncing in the background */
#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(dict_index_t)
indexes;/*!< list of indexes of the table */
diff --git a/storage/xtradb/include/dict0stats_bg.h b/storage/xtradb/include/dict0stats_bg.h
index 82cd2b468b9..bf77cd125fb 100644
--- a/storage/xtradb/include/dict0stats_bg.h
+++ b/storage/xtradb/include/dict0stats_bg.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -59,7 +59,7 @@ dict_stats_recalc_pool_del(
/** Yield the data dictionary latch when waiting
for the background thread to stop accessing a table.
@param trx transaction holding the data dictionary locks */
-#define DICT_STATS_BG_YIELD(trx) do { \
+#define DICT_BG_YIELD(trx) do { \
row_mysql_unlock_data_dictionary(trx); \
os_thread_sleep(250000); \
row_mysql_lock_data_dictionary(trx); \
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 78222b3122a..a9593cc4dec 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -597,7 +597,7 @@ fil_create_new_single_table_tablespace(
ulint size) /*!< in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((nonnull(2), warn_unused_result));
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
@@ -751,8 +751,10 @@ fil_space_get_n_reserved_extents(
Reads or writes data. This operation is asynchronous (aio).
@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
i/o on a tablespace which does not exist */
-#define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message) \
- _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, NULL)
+#define fil_io(type, sync, space_id, zip_size, block_offset, \
+ byte_offset, len, buf, message) \
+ _fil_io(type, sync, space_id, zip_size, block_offset, \
+ byte_offset, len, buf, message, NULL, false)
UNIV_INTERN
dberr_t
@@ -783,7 +785,9 @@ _fil_io(
appropriately aligned */
void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
- trx_t* trx)
+ trx_t* trx,
+ bool should_buffer) /*!< in: whether to buffer an aio request.
+ Only used by aio read ahead*/
MY_ATTRIBUTE((nonnull(8)));
/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h
index 5c3e7d07fd9..2d05c827545 100644
--- a/storage/xtradb/include/log0online.h
+++ b/storage/xtradb/include/log0online.h
@@ -129,7 +129,11 @@ 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 */
+ /** Name with full path
+ 61 is a nice magic constant for the extra space needed for the sprintf
+ template in the cc file
+ */
+ char name[FN_REFLEN+61];
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,
diff --git a/storage/xtradb/include/mach0data.ic b/storage/xtradb/include/mach0data.ic
index 27b9f62b552..10fc6fe119b 100644
--- a/storage/xtradb/include/mach0data.ic
+++ b/storage/xtradb/include/mach0data.ic
@@ -792,13 +792,13 @@ mach_swap_byte_order(
dest += len;
switch (len & 0x7) {
- case 0: *--dest = *from++;
- case 7: *--dest = *from++;
- case 6: *--dest = *from++;
- case 5: *--dest = *from++;
- case 4: *--dest = *from++;
- case 3: *--dest = *from++;
- case 2: *--dest = *from++;
+ case 0: *--dest = *from++; // fallthrough
+ case 7: *--dest = *from++; // fallthrough
+ case 6: *--dest = *from++; // fallthrough
+ case 5: *--dest = *from++; // fallthrough
+ case 4: *--dest = *from++; // fallthrough
+ case 3: *--dest = *from++; // fallthrough
+ case 2: *--dest = *from++; // fallthrough
case 1: *--dest = *from;
}
}
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index 4dab704ad50..f7531d99f38 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -371,9 +371,9 @@ The wrapper functions have the prefix of "innodb_". */
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) \
+ n, message1, message2, space_id, trx, should_buffer) \
pfs_os_aio_func(type, mode, name, file, buf, offset, \
- n, message1, message2, space_id, trx, \
+ n, message1, message2, space_id, trx, should_buffer, \
__FILE__, __LINE__)
# define os_file_read_pfs(file, buf, offset, n) \
@@ -443,9 +443,9 @@ to original un-instrumented file I/O APIs */
os_file_close_no_error_handling_func(file)
# define os_aio(type, mode, name, file, buf, offset, n, message1, \
- message2, space_id, trx) \
+ message2, space_id, trx, should_buffer) \
os_aio_func(type, mode, name, file, buf, offset, n, \
- message1, message2, space_id, trx)
+ message1, message2, space_id, trx, should_buffer)
# define os_file_read_pfs(file, buf, offset, n) \
os_file_read_func(file, buf, offset, n, NULL)
@@ -975,6 +975,12 @@ pfs_os_aio_func(
OS_AIO_SYNC */
ulint space_id,
trx_t* trx,
+ bool should_buffer,
+ /*!< in: Whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
const char* src_file,/*!< in: file name where func invoked */
ulint src_line);/*!< in: line where the func invoked */
/*******************************************************************//**
@@ -1389,7 +1395,13 @@ os_aio_func(
aio operation); ignored if mode is
OS_AIO_SYNC */
ulint space_id,
- trx_t* trx);
+ trx_t* trx,
+ bool should_buffer);
+ /*!< in: Whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
/************************************************************************//**
Wakes up all async i/o threads so that they know to exit themselves in
shutdown. */
@@ -1558,6 +1570,11 @@ os_aio_linux_handle(
ulint* space_id);
#endif /* LINUX_NATIVE_AIO */
+/** Submit buffered AIO requests on the given segment to the kernel. */
+UNIV_INTERN
+void
+os_aio_dispatch_read_array_submit();
+
#ifndef UNIV_NONINL
#include "os0file.ic"
#endif
diff --git a/storage/xtradb/include/os0file.ic b/storage/xtradb/include/os0file.ic
index c82a2559fed..98474a33c7e 100644
--- a/storage/xtradb/include/os0file.ic
+++ b/storage/xtradb/include/os0file.ic
@@ -246,6 +246,9 @@ pfs_os_aio_func(
OS_AIO_SYNC */
ulint space_id,
trx_t* trx,
+ bool should_buffer,
+ /*!< in: whether to buffer an aio request.
+ Only used by aio read ahead*/
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
@@ -261,7 +264,8 @@ pfs_os_aio_func(
src_file, src_line);
result = os_aio_func(type, mode, name, file, buf, offset,
- n, message1, message2, space_id, trx);
+ n, message1, message2, space_id, trx,
+ should_buffer);
register_pfs_file_io_end(locker, n);
diff --git a/storage/xtradb/include/page0zip.ic b/storage/xtradb/include/page0zip.ic
index 6c7d8cd32c7..61e6f37c612 100644
--- a/storage/xtradb/include/page0zip.ic
+++ b/storage/xtradb/include/page0zip.ic
@@ -172,7 +172,7 @@ page_zip_rec_needs_ext(
ignored if zip_size == 0 */
ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
{
- ut_ad(rec_size > comp ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES);
+ ut_ad(rec_size > (comp ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES));
ut_ad(ut_is_2pow(zip_size));
ut_ad(comp || !zip_size);
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 0fb563f539c..248083db10f 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -52,6 +52,8 @@ Created 10/10/1995 Heikki Tuuri
#include "buf0checksum.h"
#include "ut0counter.h"
+#include <sql_class.h>
+
/* Global counters used inside InnoDB. */
struct srv_stats_t {
typedef ib_counter_t<lsn_t, 1, single_indexer_t> lsn_ctr_1_t;
@@ -129,6 +131,9 @@ struct srv_stats_t {
ulint_ctr_1_t lock_deadlock_count;
ulint_ctr_1_t n_lock_max_wait_time;
+
+ /** Number of buffered aio requests submitted */
+ ulint_ctr_64_t n_aio_submitted;
};
extern const char* srv_main_thread_op_info;
@@ -586,6 +591,9 @@ extern ulong srv_sync_array_size;
/* print all user-level transactions deadlocks to mysqld stderr */
extern my_bool srv_print_all_deadlocks;
+/* print lock wait timeout info to mysqld stderr */
+extern my_bool srv_print_lock_wait_timeout_info;
+
extern my_bool srv_cmp_per_index_enabled;
/** Number of times secondary index lookup triggered cluster lookup */
@@ -1100,6 +1108,11 @@ struct export_var_t{
ulint innodb_sec_rec_cluster_reads; /*!< srv_sec_rec_cluster_reads */
ulint innodb_sec_rec_cluster_reads_avoided; /*!< srv_sec_rec_cluster_reads_avoided */
+
+ ulint innodb_buffered_aio_submitted;
+
+ fragmentation_stats_t innodb_fragmentation_stats;/*!< Fragmentation
+ statistics */
};
/** Thread slot in the thread table. */
diff --git a/storage/xtradb/include/trx0rec.h b/storage/xtradb/include/trx0rec.h
index 359937e3583..c7820480fe0 100644
--- a/storage/xtradb/include/trx0rec.h
+++ b/storage/xtradb/include/trx0rec.h
@@ -233,7 +233,7 @@ trx_undo_report_row_operation(
inserted undo log record,
0 if BTR_NO_UNDO_LOG
flag was specified */
- MY_ATTRIBUTE((nonnull(3,4,10), warn_unused_result));
+ MY_ATTRIBUTE((nonnull(4,10), warn_unused_result));
/******************************************************************//**
Copies an undo record to heap. This function can be called if we know that
the undo log record exists.
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 639faca0fe3..ce2de004dd4 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -47,7 +47,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_BUGFIX MYSQL_VERSION_PATCH
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 82.2
+#define PERCONA_INNODB_VERSION 83.0
#endif
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
diff --git a/storage/xtradb/include/ut0rnd.ic b/storage/xtradb/include/ut0rnd.ic
index 024c59e553b..5351c8d9d5a 100644
--- a/storage/xtradb/include/ut0rnd.ic
+++ b/storage/xtradb/include/ut0rnd.ic
@@ -236,17 +236,17 @@ ut_fold_binary(
switch (len & 0x7) {
case 7:
- fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ fold = ut_fold_ulint_pair(fold, (ulint)(*str++)); // fallthrough
case 6:
- fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ fold = ut_fold_ulint_pair(fold, (ulint)(*str++)); // fallthrough
case 5:
- fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ fold = ut_fold_ulint_pair(fold, (ulint)(*str++)); // fallthrough
case 4:
- fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ fold = ut_fold_ulint_pair(fold, (ulint)(*str++)); // fallthrough
case 3:
- fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ fold = ut_fold_ulint_pair(fold, (ulint)(*str++)); // fallthrough
case 2:
- fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ fold = ut_fold_ulint_pair(fold, (ulint)(*str++)); // fallthrough
case 1:
fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
}
diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc
index e2e7c4207a1..277fc000502 100644
--- a/storage/xtradb/lock/lock0wait.cc
+++ b/storage/xtradb/lock/lock0wait.cc
@@ -32,6 +32,20 @@ Created 25/5/2010 Sunny Bains
#include "srv0start.h"
#include "ha_prototypes.h"
#include "lock0priv.h"
+#include "lock0iter.h"
+
+#include <sstream>
+
+extern "C"
+LEX_STRING* thd_query_string(MYSQL_THD thd);
+
+struct blocking_trx_info {
+ uint64_t trx_id;
+ uint32_t thread_id;
+ int64_t query_id;
+};
+
+static const size_t MAX_BLOCKING_TRX_IN_REPORT = 10;
/*********************************************************************//**
Print the contents of the lock_sys_t::waiting_threads array. */
@@ -184,6 +198,46 @@ lock_wait_table_reserve_slot(
return(NULL);
}
+/** Print lock wait timeout info to stderr. It's supposed this function
+is executed in trx's THD thread as it calls some non-thread-safe
+functions to get some info from THD.
+@param[in] trx requested trx
+@param[in] blocking blocking info array
+@param[in] blocking_count blocking info array size */
+void
+print_lock_wait_timeout(
+ const trx_t &trx,
+ blocking_trx_info *blocking,
+ size_t blocking_count)
+{
+ std::ostringstream outs;
+
+ outs << "Lock wait timeout info:\n";
+ outs << "Requested thread id: " <<
+ thd_get_thread_id(trx.mysql_thd) <<
+ "\n";
+ outs << "Requested trx id: " << trx.id << "\n";
+ outs << "Requested query: " <<
+ thd_query_string(trx.mysql_thd)->str << "\n";
+
+ outs << "Total blocking transactions count: " <<
+ blocking_count <<
+ "\n";
+
+ for (size_t i = 0; i < blocking_count; ++i) {
+ outs << "Blocking transaction number: " << (i + 1) << "\n";
+ outs << "Blocking thread id: " <<
+ blocking[i].thread_id <<
+ "\n";
+ outs << "Blocking query id: " <<
+ blocking[i].query_id <<
+ "\n";
+ outs << "Blocking trx id: " << blocking[i].trx_id << "\n";
+ }
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " %s", outs.str().c_str());
+}
+
/***************************************************************//**
Puts a user OS thread to wait for a lock to be released. If an error
occurs during the wait trx->error_state associated with thr is
@@ -207,6 +261,8 @@ lock_wait_suspend_thread(
ulint sec;
ulint ms;
ulong lock_wait_timeout;
+ blocking_trx_info blocking[MAX_BLOCKING_TRX_IN_REPORT];
+ size_t blocking_count = 0;
trx = thr_get_trx(thr);
@@ -272,6 +328,27 @@ lock_wait_suspend_thread(
if (const lock_t* wait_lock = trx->lock.wait_lock) {
lock_type = lock_get_type_low(wait_lock);
+ if (srv_print_lock_wait_timeout_info) {
+ lock_queue_iterator_t iter;
+ const lock_t* curr_lock;
+ lock_queue_iterator_reset(&iter, wait_lock, ULINT_UNDEFINED);
+ for (curr_lock = lock_queue_iterator_get_prev(&iter);
+ curr_lock != NULL;
+ curr_lock = lock_queue_iterator_get_prev(&iter)) {
+ if (lock_has_to_wait(trx->lock.wait_lock, curr_lock)) {
+ blocking[blocking_count].trx_id = lock_get_trx_id(curr_lock);
+ blocking[blocking_count].thread_id =
+ curr_lock->trx->mysql_thd ?
+ thd_get_thread_id(curr_lock->trx->mysql_thd) : 0;
+ blocking[blocking_count].query_id =
+ curr_lock->trx->mysql_thd ?
+ thd_get_query_id(curr_lock->trx->mysql_thd) : 0;
+ /* Only limited number of blocking transaction infos is implemented*/
+ if ((++blocking_count) >= MAX_BLOCKING_TRX_IN_REPORT)
+ break;
+ }
+ }
+ }
}
lock_mutex_exit();
@@ -377,6 +454,8 @@ lock_wait_suspend_thread(
&& wait_time > (double) lock_wait_timeout) {
trx->error_state = DB_LOCK_WAIT_TIMEOUT;
+ if (srv_print_lock_wait_timeout_info)
+ print_lock_wait_timeout(*trx, blocking, blocking_count);
MONITOR_INC(MONITOR_TIMEOUT);
}
diff --git a/storage/xtradb/log/log0online.cc b/storage/xtradb/log/log0online.cc
index 99762c00a08..9e9e3a4c284 100644
--- a/storage/xtradb/log/log0online.cc
+++ b/storage/xtradb/log/log0online.cc
@@ -489,7 +489,7 @@ log_online_make_bitmap_name(
/*=========================*/
lsn_t start_lsn) /*!< in: the start LSN name part */
{
- ut_snprintf(log_bmp_sys->out.name, FN_REFLEN, bmp_file_name_template,
+ ut_snprintf(log_bmp_sys->out.name, sizeof(log_bmp_sys->out.name), bmp_file_name_template,
log_bmp_sys->bmp_file_home, bmp_file_name_stem,
log_bmp_sys->out_seq_num, start_lsn);
}
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 9b2a2746976..966eb31e260 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -247,6 +247,16 @@ struct os_aio_array_t{
There is one such event for each
possible pending IO. The size of the
array is equal to n_slots. */
+ struct iocb** pending;
+ /* Array to buffer the not-submitted aio
+ requests. The array length is n_slots.
+ It is divided into n_segments segments.
+ pending requests on each segment are buffered
+ separately.*/
+ ulint* count;
+ /* Array of length n_segments. Each element
+ counts the number of not-submitted aio
+ request on that segment.*/
#endif /* LINUX_NATIV_AIO */
};
@@ -4084,6 +4094,13 @@ os_aio_array_create(
memset(io_event, 0x0, sizeof(*io_event) * n);
array->aio_events = io_event;
+ array->pending = static_cast<struct iocb**>(
+ ut_malloc(n * sizeof(struct iocb*)));
+ memset(array->pending, 0x0, sizeof(struct iocb*) * n);
+ array->count = static_cast<ulint*>(
+ ut_malloc(n_segments * sizeof(ulint)));
+ memset(array->count, 0x0, sizeof(ulint) * n_segments);
+
skip_native_aio:
#endif /* LINUX_NATIVE_AIO */
for (ulint i = 0; i < n; i++) {
@@ -4140,6 +4157,16 @@ os_aio_array_free(
if (srv_use_native_aio) {
ut_free(array->aio_events);
ut_free(array->aio_ctx);
+
+#ifdef UNIV_DEBUG
+ for (size_t idx = 0; idx < array->n_slots; ++idx)
+ ut_ad(array->pending[idx] == NULL);
+ for (size_t idx = 0; idx < array->n_segments; ++idx)
+ ut_ad(array->count[idx] == 0);
+#endif
+
+ ut_free(array->pending);
+ ut_free(array->count);
}
#endif /* LINUX_NATIVE_AIO */
@@ -4769,6 +4796,83 @@ readahead requests. */
#endif /* __WIN__ */
}
+/** Submit buffered AIO requests on the given segment to the kernel
+(low level function).
+@param acquire_mutex specifies whether to lock array mutex
+*/
+static
+void
+os_aio_dispatch_read_array_submit_low(bool acquire_mutex MY_ATTRIBUTE((unused)))
+{
+ if (!srv_use_native_aio) {
+ return;
+ }
+#if defined(LINUX_NATIVE_AIO)
+ os_aio_array_t* array = os_aio_read_array;
+ ulint total_submitted = 0;
+ if (acquire_mutex)
+ os_mutex_enter(array->mutex);
+ /* Submit aio requests buffered on all segments. */
+ for (ulint i = 0; i < array->n_segments; i++) {
+ const int count = array->count[i];
+ int offset = 0;
+ while (offset != count) {
+ struct iocb** const iocb_array = array->pending
+ + i * array->n_slots / array->n_segments
+ + offset;
+ const int partial_count = count - offset;
+ /* io_submit() returns number of successfully queued
+ requests or (-errno).
+ It returns 0 only if the number of iocb blocks passed
+ is also 0. */
+ const int submitted = io_submit(array->aio_ctx[i],
+ partial_count, iocb_array);
+
+ /* This assertion prevents infinite loop in both
+ debug and release modes. */
+ ut_a(submitted != 0);
+
+ if (submitted < 0) {
+ /* Terminating with fatal error */
+ const char* errmsg =
+ strerror(-submitted);
+ ib_logf(IB_LOG_LEVEL_FATAL,
+ "Trying to sumbit %d aio requests, "
+ "io_submit() set errno to %d: %s",
+ partial_count, -submitted,
+ errmsg ? errmsg : "<unknown>");
+ }
+ ut_ad(submitted <= partial_count);
+ if (submitted < partial_count)
+ {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Trying to sumbit %d aio requests, "
+ "io_submit() submitted only %d",
+ partial_count, submitted);
+ }
+ offset += submitted;
+ }
+ total_submitted += count;
+ }
+ /* Reset the aio request buffer. */
+ memset(array->pending, 0x0, sizeof(struct iocb*) * array->n_slots);
+ memset(array->count, 0x0, sizeof(ulint) * array->n_segments);
+
+ if (acquire_mutex)
+ os_mutex_exit(array->mutex);
+
+ srv_stats.n_aio_submitted.add(total_submitted);
+#endif
+}
+
+/** Submit buffered AIO requests on the given segment to the kernel. */
+UNIV_INTERN
+void
+os_aio_dispatch_read_array_submit()
+{
+ os_aio_dispatch_read_array_submit_low(true);
+}
+
#if defined(LINUX_NATIVE_AIO)
/*******************************************************************//**
Dispatch an AIO request to the kernel.
@@ -4778,10 +4882,11 @@ ibool
os_aio_linux_dispatch(
/*==================*/
os_aio_array_t* array, /*!< in: io request array. */
- os_aio_slot_t* slot) /*!< in: an already reserved slot. */
+ os_aio_slot_t* slot, /*!< in: an already reserved slot. */
+ bool should_buffer) /*!< in: should buffer the request
+ rather than submit. */
{
int ret;
- ulint io_ctx_index;
struct iocb* iocb;
ut_ad(slot != NULL);
@@ -4793,9 +4898,31 @@ os_aio_linux_dispatch(
The iocb struct is directly in the slot.
The io_context is one per segment. */
+ ulint slots_per_segment = array->n_slots / array->n_segments;
iocb = &slot->control;
- io_ctx_index = (slot->pos * array->n_segments) / array->n_slots;
+ ulint io_ctx_index = slot->pos / slots_per_segment;
+ if (should_buffer) {
+ ut_ad(array == os_aio_read_array);
+ os_mutex_enter(array->mutex);
+ /* There are array->n_slots elements in array->pending,
+ which is divided into array->n_segments area of equal size.
+ The iocb of each segment are buffered in its corresponding area
+ in the pending array consecutively as they come.
+ array->count[i] records the number of buffered aio requests
+ in the ith segment.*/
+ ulint& count = array->count[io_ctx_index];
+ ut_ad(count != slots_per_segment);
+ ulint n = io_ctx_index * slots_per_segment + count;
+ array->pending[n] = iocb;
+ ++count;
+ if (count == slots_per_segment) {
+ os_aio_dispatch_read_array_submit_low(false);
+ }
+ os_mutex_exit(array->mutex);
+ return(TRUE);
+ }
+ /* Submit the given request. */
ret = io_submit(array->aio_ctx[io_ctx_index], 1, &iocb);
#if defined(UNIV_AIO_DEBUG)
@@ -4855,7 +4982,13 @@ os_aio_func(
aio operation); ignored if mode is
OS_AIO_SYNC */
ulint space_id,
- trx_t* trx)
+ trx_t* trx,
+ bool should_buffer)
+ /*!< in: Whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
{
os_aio_array_t* array;
os_aio_slot_t* slot;
@@ -4965,7 +5098,8 @@ try_again:
ret = ReadFile(file.m_file, buf, (DWORD) n, &len,
&(slot->control));
#elif defined(LINUX_NATIVE_AIO)
- if (!os_aio_linux_dispatch(array, slot)) {
+ if (!os_aio_linux_dispatch(array, slot,
+ should_buffer)) {
goto err_exit;
}
#endif /* WIN_ASYNC_IO */
@@ -4984,7 +5118,7 @@ try_again:
ret = WriteFile(file.m_file, buf, (DWORD) n, &len,
&(slot->control));
#elif defined(LINUX_NATIVE_AIO)
- if (!os_aio_linux_dispatch(array, slot)) {
+ if (!os_aio_linux_dispatch(array, slot, false)) {
goto err_exit;
}
#endif /* WIN_ASYNC_IO */
diff --git a/storage/xtradb/page/page0page.cc b/storage/xtradb/page/page0page.cc
index 48c4b53aaa4..a340c04913a 100644
--- a/storage/xtradb/page/page0page.cc
+++ b/storage/xtradb/page/page0page.cc
@@ -2832,7 +2832,7 @@ page_warn_strict_checksum(
ulint space_id,
ulint page_no)
{
- srv_checksum_algorithm_t curr_algo_nonstrict;
+ srv_checksum_algorithm_t curr_algo_nonstrict = srv_checksum_algorithm_t();
switch (curr_algo) {
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
curr_algo_nonstrict = SRV_CHECKSUM_ALGORITHM_CRC32;
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index 11c4333577e..ac26c318cb2 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -2025,6 +2025,7 @@ PageConverter::update_page(
case FIL_PAGE_TYPE_XDES:
err = set_current_xdes(
buf_block_get_page_no(block), get_frame(block));
+ // fallthrough
case FIL_PAGE_INODE:
case FIL_PAGE_TYPE_TRX_SYS:
case FIL_PAGE_IBUF_FREE_LIST:
diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc
index 4596e2fb951..4fa2ed5cf56 100644
--- a/storage/xtradb/row/row0log.cc
+++ b/storage/xtradb/row/row0log.cc
@@ -1872,6 +1872,7 @@ row_log_table_apply_update(
When applying the subsequent ROW_T_DELETE, no matching
record will be found. */
+ return(DB_SUCCESS);
case DB_SUCCESS:
ut_ad(row != NULL);
break;
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 15a386f7660..9d1fcfc0393 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -57,6 +57,7 @@ Created 9/17/2000 Heikki Tuuri
#include "log0log.h"
#include "btr0sea.h"
#include "fil0fil.h"
+#include "srv0srv.h"
#include "ibuf0ibuf.h"
#include "fts0fts.h"
#include "fts0types.h"
@@ -4448,6 +4449,16 @@ row_drop_table_for_mysql(
ut_ad(!table->fts->add_wq);
ut_ad(lock_trx_has_sys_table_locks(trx) == 0);
+ for (;;) {
+ bool retry = false;
+ if (dict_fts_index_syncing(table)) {
+ retry = true;
+ }
+ if (!retry) {
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
row_mysql_unlock_data_dictionary(trx);
fts_optimize_remove_table(table);
row_mysql_lock_data_dictionary(trx);
@@ -5892,7 +5903,8 @@ loop:
fputs(" InnoDB: Warning: CHECK TABLE on ", stderr);
dict_index_name_print(stderr, prebuilt->trx, index);
fprintf(stderr, " returned %lu\n", ret);
- /* fall through (this error is ignored by CHECK TABLE) */
+ // fallthrough
+ // (this error is ignored by CHECK TABLE)
case DB_END_OF_INDEX:
func_exit:
mem_free(buf);
diff --git a/storage/xtradb/row/row0purge.cc b/storage/xtradb/row/row0purge.cc
index 35b3520749b..45a8ae4102c 100644
--- a/storage/xtradb/row/row0purge.cc
+++ b/storage/xtradb/row/row0purge.cc
@@ -488,8 +488,8 @@ row_purge_remove_sec_if_poss_leaf(
success = false;
}
}
- /* fall through (the index entry is still needed,
- or the deletion succeeded) */
+ // fallthrough
+ // (the index entry is still needed, or the deletion succeeded)
case ROW_NOT_DELETED_REF:
/* The index entry is still needed. */
case ROW_BUFFERED:
diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc
index 5866021cffa..060c12e7e2e 100644
--- a/storage/xtradb/row/row0sel.cc
+++ b/storage/xtradb/row/row0sel.cc
@@ -2993,8 +2993,8 @@ row_sel_store_mysql_rec(
const ulint* offsets,
bool clust_templ_for_sec)
{
- ulint i;
- std::vector<ulint> template_col;
+ ulint i;
+ std::vector<const dict_col_t*> template_col;
ut_ad(rec_clust || index == prebuilt->index);
ut_ad(!rec_clust || dict_index_is_clust(index));
@@ -3008,13 +3008,24 @@ row_sel_store_mysql_rec(
mem_heap_empty(prebuilt->compress_heap);
if (clust_templ_for_sec) {
- /* Store all clustered index field of
+ /* Store all clustered index column of
secondary index record. */
for (i = 0; i < dict_index_get_n_fields(
prebuilt->index); i++) {
ulint sec_field = dict_index_get_nth_field_pos(
index, prebuilt->index, i);
- template_col.push_back(sec_field);
+
+ if (sec_field == ULINT_UNDEFINED) {
+ template_col.push_back(NULL);
+ continue;
+ }
+
+ const dict_field_t* field =
+ dict_index_get_nth_field(index, sec_field);
+ const dict_col_t* col =
+ dict_field_get_col(field);
+
+ template_col.push_back(col);
}
}
@@ -3034,9 +3045,13 @@ row_sel_store_mysql_rec(
== 0 || templ->rec_field_is_prefix);
if (clust_templ_for_sec) {
- std::vector<ulint>::iterator it;
+ std::vector<const dict_col_t*>::iterator it;
+ const dict_field_t* field =
+ dict_index_get_nth_field(index, field_no);
+ const dict_col_t* col = dict_field_get_col(
+ field);
it = std::find(template_col.begin(),
- template_col.end(), field_no);
+ template_col.end(), col);
if (it == template_col.end()) {
continue;
@@ -4393,6 +4408,10 @@ rec_loop:
if (page_rec_is_supremum(rec)) {
+ DBUG_EXECUTE_IF("compare_end_range",
+ if (end_loop < 100) {
+ end_loop = 100;
+ });
/** Compare the last record of the page with end range
passed to InnoDB when there is no ICP and number of loops
in row_search_for_mysql for rows found but not
@@ -4433,7 +4452,7 @@ rec_loop:
/** In case of prebuilt->fetch,
set the error in prebuilt->end_range. */
- if (prebuilt->n_fetch_cached > 0) {
+ if (next_buf != NULL) {
prebuilt->end_range = true;
}
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index 2153440886c..e0e3f995bae 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -428,6 +428,10 @@ UNIV_INTERN ulong srv_force_recovery_crash;
UNIV_INTERN my_bool srv_print_all_deadlocks = FALSE;
+/** Print lock wait timeout info to mysqld stderr */
+
+my_bool srv_print_lock_wait_timeout_info = FALSE;
+
/** Enable INFORMATION_SCHEMA.innodb_cmp_per_index */
UNIV_INTERN my_bool srv_cmp_per_index_enabled = FALSE;
@@ -1908,6 +1912,12 @@ srv_export_innodb_status(void)
export_vars.innodb_sec_rec_cluster_reads_avoided =
srv_sec_rec_cluster_reads_avoided;
+ export_vars.innodb_buffered_aio_submitted =
+ srv_stats.n_aio_submitted;
+
+ thd_get_fragmentation_stats(current_thd,
+ &export_vars.innodb_fragmentation_stats);
+
mutex_exit(&srv_innodb_monitor_mutex);
}
diff --git a/storage/xtradb/sync/sync0sync.cc b/storage/xtradb/sync/sync0sync.cc
index b795100972c..7d0314c1ef6 100644
--- a/storage/xtradb/sync/sync0sync.cc
+++ b/storage/xtradb/sync/sync0sync.cc
@@ -1230,6 +1230,7 @@ sync_thread_add_level(
upgrading in innobase_start_or_create_for_mysql(). */
break;
}
+ // fallthrough
case SYNC_MEM_POOL:
case SYNC_MEM_HASH:
case SYNC_RECV:
@@ -1293,8 +1294,8 @@ sync_thread_add_level(
}
ut_ad(found_current);
- /* fallthrough */
}
+ // fallthrough
case SYNC_BUF_FLUSH_LIST:
case SYNC_BUF_LRU_LIST:
case SYNC_BUF_FREE_LIST: