summaryrefslogtreecommitdiff
path: root/storage/xtradb
diff options
context:
space:
mode:
authorSachin Setiya <sachin.setiya@mariadb.com>2017-05-30 15:28:52 +0530
committerSachin Setiya <sachin.setiya@mariadb.com>2017-05-30 15:28:52 +0530
commit92209ac6f69974169c543ae82da077f06f2b7c71 (patch)
tree1713781010a286fa9a493781a3eb001af062fd62 /storage/xtradb
parent0e3170e30d2a4e8f1ed6fd4bbe935355f7370a34 (diff)
parent725e47bfb524f4b1d29076c8777056bedd5f00ea (diff)
downloadmariadb-git-92209ac6f69974169c543ae82da077f06f2b7c71.tar.gz
Merge tag 'mariadb-10.0.31' into 10.0-galera
Signed-off-by: Sachin Setiya <sachin.setiya@mariadb.com>
Diffstat (limited to 'storage/xtradb')
-rw-r--r--storage/xtradb/btr/btr0cur.cc81
-rw-r--r--storage/xtradb/btr/btr0sea.cc2
-rw-r--r--storage/xtradb/buf/buf0buf.cc30
-rw-r--r--storage/xtradb/buf/buf0dblwr.cc4
-rw-r--r--storage/xtradb/buf/buf0dump.cc5
-rw-r--r--storage/xtradb/buf/buf0flu.cc38
-rw-r--r--storage/xtradb/buf/buf0lru.cc5
-rw-r--r--storage/xtradb/buf/buf0rea.cc14
-rw-r--r--storage/xtradb/dict/dict0boot.cc7
-rw-r--r--storage/xtradb/dict/dict0dict.cc21
-rw-r--r--storage/xtradb/dict/dict0mem.cc4
-rw-r--r--storage/xtradb/dict/dict0stats.cc6
-rw-r--r--storage/xtradb/dict/dict0stats_bg.cc4
-rw-r--r--storage/xtradb/fil/fil0fil.cc35
-rw-r--r--storage/xtradb/fts/fts0que.cc20
-rw-r--r--storage/xtradb/handler/ha_innodb.cc196
-rw-r--r--storage/xtradb/handler/ha_innodb.h2
-rw-r--r--storage/xtradb/handler/handler0alter.cc19
-rw-r--r--storage/xtradb/handler/i_s.cc285
-rw-r--r--storage/xtradb/ibuf/ibuf0ibuf.cc6
-rw-r--r--storage/xtradb/include/btr0cur.h25
-rw-r--r--storage/xtradb/include/buf0dblwr.h4
-rw-r--r--storage/xtradb/include/data0type.ic3
-rw-r--r--storage/xtradb/include/dict0dict.h11
-rw-r--r--storage/xtradb/include/dict0dict.ic9
-rw-r--r--storage/xtradb/include/fil0fil.h18
-rw-r--r--storage/xtradb/include/ha0ha.h6
-rw-r--r--storage/xtradb/include/ha_prototypes.h3
-rw-r--r--storage/xtradb/include/log0online.h2
-rw-r--r--storage/xtradb/include/mach0data.ic15
-rw-r--r--storage/xtradb/include/os0file.h347
-rw-r--r--storage/xtradb/include/os0file.ic215
-rw-r--r--storage/xtradb/include/os0sync.h70
-rw-r--r--storage/xtradb/include/page0zip.ic4
-rw-r--r--storage/xtradb/include/row0mysql.h10
-rw-r--r--storage/xtradb/include/srv0mon.h62
-rw-r--r--storage/xtradb/include/srv0srv.h33
-rw-r--r--storage/xtradb/include/srv0start.h4
-rw-r--r--storage/xtradb/include/trx0rec.h11
-rw-r--r--storage/xtradb/include/trx0xa.h15
-rw-r--r--storage/xtradb/include/univ.i42
-rw-r--r--storage/xtradb/include/ut0counter.h98
-rw-r--r--storage/xtradb/include/ut0rnd.ic7
-rw-r--r--storage/xtradb/lock/lock0lock.cc12
-rw-r--r--storage/xtradb/lock/lock0wait.cc22
-rw-r--r--storage/xtradb/log/log0log.cc19
-rw-r--r--storage/xtradb/log/log0online.cc63
-rw-r--r--storage/xtradb/log/log0recv.cc10
-rw-r--r--storage/xtradb/os/os0file.cc415
-rw-r--r--storage/xtradb/pars/pars0opt.cc6
-rw-r--r--storage/xtradb/pars/pars0pars.cc3
-rw-r--r--storage/xtradb/rem/rem0rec.cc6
-rw-r--r--storage/xtradb/row/row0ftsort.cc11
-rw-r--r--storage/xtradb/row/row0import.cc132
-rw-r--r--storage/xtradb/row/row0ins.cc9
-rw-r--r--storage/xtradb/row/row0log.cc19
-rw-r--r--storage/xtradb/row/row0merge.cc101
-rw-r--r--storage/xtradb/row/row0mysql.cc28
-rw-r--r--storage/xtradb/row/row0purge.cc4
-rw-r--r--storage/xtradb/row/row0sel.cc171
-rw-r--r--storage/xtradb/srv/srv0mon.cc5
-rw-r--r--storage/xtradb/srv/srv0srv.cc185
-rw-r--r--storage/xtradb/srv/srv0start.cc66
-rw-r--r--storage/xtradb/sync/sync0arr.cc7
-rw-r--r--storage/xtradb/sync/sync0sync.cc5
-rw-r--r--storage/xtradb/trx/trx0i_s.cc4
-rw-r--r--storage/xtradb/trx/trx0purge.cc5
-rw-r--r--storage/xtradb/trx/trx0rec.cc45
-rw-r--r--storage/xtradb/trx/trx0roll.cc4
-rw-r--r--storage/xtradb/trx/trx0sys.cc18
-rw-r--r--storage/xtradb/usr/usr0sess.cc3
71 files changed, 1886 insertions, 1290 deletions
diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc
index 1705de7ce36..c495e178b21 100644
--- a/storage/xtradb/btr/btr0cur.cc
+++ b/storage/xtradb/btr/btr0cur.cc
@@ -3,6 +3,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1268,18 +1269,21 @@ btr_cur_ins_lock_and_undo(
index, thr, mtr, inherit);
if (err != DB_SUCCESS
+ || !(~flags | (BTR_NO_UNDO_LOG_FLAG | BTR_KEEP_SYS_FLAG))
|| !dict_index_is_clust(index) || dict_index_is_ibuf(index)) {
return(err);
}
- err = trx_undo_report_row_operation(flags, TRX_UNDO_INSERT_OP,
- thr, index, entry,
- NULL, 0, NULL, NULL,
- &roll_ptr);
- if (err != DB_SUCCESS) {
-
- return(err);
+ if (flags & BTR_NO_UNDO_LOG_FLAG) {
+ roll_ptr = 0;
+ } else {
+ err = trx_undo_report_row_operation(thr, index, entry,
+ NULL, 0, NULL, NULL,
+ &roll_ptr);
+ if (err != DB_SUCCESS) {
+ return(err);
+ }
}
/* Now we can fill in the roll ptr field in entry */
@@ -1328,15 +1332,17 @@ btr_cur_optimistic_insert(
btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
ulint** offsets,/*!< out: offsets on *rec */
- mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
succeed */
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
- be stored externally by the caller, or
- NULL */
+ be stored externally by the caller */
ulint n_ext, /*!< in: number of externally stored columns */
- que_thr_t* thr, /*!< in: query thread or NULL */
+ que_thr_t* thr, /*!< in/out: query thread; can be NULL if
+ !(~flags
+ & (BTR_NO_LOCKING_FLAG
+ | BTR_NO_UNDO_LOG_FLAG)) */
mtr_t* mtr) /*!< in/out: mini-transaction;
if this function returns DB_SUCCESS on
a leaf page of a secondary index in a
@@ -1357,6 +1363,7 @@ btr_cur_optimistic_insert(
ulint rec_size;
dberr_t err;
+ ut_ad(thr || !(~flags & (BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG)));
*big_rec = NULL;
block = btr_cur_get_block(cursor);
@@ -1366,7 +1373,10 @@ btr_cur_optimistic_insert(
page = buf_block_get_frame(block);
index = cursor->index;
- ut_ad((thr && thr_get_trx(thr)->fake_changes)
+ const bool fake_changes = (~flags & (BTR_NO_LOCKING_FLAG
+ | BTR_NO_UNDO_LOG_FLAG))
+ && thr_get_trx(thr)->fake_changes;
+ ut_ad(fake_changes
|| mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
ut_ad(!dict_index_is_online_ddl(index)
|| dict_index_is_clust(index)
@@ -1507,7 +1517,7 @@ fail_err:
goto fail_err;
}
- if (UNIV_UNLIKELY(thr && thr_get_trx(thr)->fake_changes)) {
+ if (UNIV_UNLIKELY(fake_changes)) {
/* skip CHANGE, LOG */
*big_rec = big_rec_vec;
return(err); /* == DB_SUCCESS */
@@ -1625,15 +1635,17 @@ btr_cur_pessimistic_insert(
cursor stays valid */
ulint** offsets,/*!< out: offsets on *rec */
mem_heap_t** heap, /*!< in/out: pointer to memory heap
- that can be emptied, or NULL */
+ that can be emptied */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
succeed */
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
- be stored externally by the caller, or
- NULL */
+ be stored externally by the caller */
ulint n_ext, /*!< in: number of externally stored columns */
- que_thr_t* thr, /*!< in: query thread or NULL */
+ que_thr_t* thr, /*!< in/out: query thread; can be NULL if
+ !(~flags
+ & (BTR_NO_LOCKING_FLAG
+ | BTR_NO_UNDO_LOG_FLAG)) */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
dict_index_t* index = cursor->index;
@@ -1645,13 +1657,17 @@ btr_cur_pessimistic_insert(
ulint n_reserved = 0;
ut_ad(dtuple_check_typed(entry));
+ ut_ad(thr || !(~flags & (BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG)));
*big_rec = NULL;
- ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr,
+ const bool fake_changes = (~flags & (BTR_NO_LOCKING_FLAG
+ | BTR_NO_UNDO_LOG_FLAG))
+ && thr_get_trx(thr)->fake_changes;
+ ut_ad(fake_changes || mtr_memo_contains(mtr,
dict_index_get_lock(btr_cur_get_index(cursor)),
MTR_MEMO_X_LOCK));
- ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, btr_cur_get_block(cursor),
+ ut_ad(fake_changes || mtr_memo_contains(mtr, btr_cur_get_block(cursor),
MTR_MEMO_PAGE_X_FIX));
ut_ad(!dict_index_is_online_ddl(index)
|| dict_index_is_clust(index)
@@ -1712,7 +1728,7 @@ btr_cur_pessimistic_insert(
}
}
- if (UNIV_UNLIKELY(thr && thr_get_trx(thr)->fake_changes)) {
+ if (UNIV_UNLIKELY(fake_changes)) {
/* skip CHANGE, LOG */
if (n_reserved > 0) {
fil_space_release_free_extents(index->space,
@@ -1803,7 +1819,7 @@ btr_cur_upd_lock_and_undo(
ut_ad((thr != NULL) || (flags & BTR_NO_LOCKING_FLAG));
- if (UNIV_UNLIKELY(thr && thr_get_trx(thr)->fake_changes)) {
+ if (!(flags & BTR_NO_LOCKING_FLAG) && thr_get_trx(thr)->fake_changes) {
/* skip LOCK, UNDO */
return(DB_SUCCESS);
}
@@ -1838,9 +1854,10 @@ btr_cur_upd_lock_and_undo(
/* Append the info about the update in the undo log */
- return(trx_undo_report_row_operation(
- flags, TRX_UNDO_MODIFY_OP, thr,
- index, NULL, update,
+ return((flags & BTR_NO_UNDO_LOG_FLAG)
+ ? DB_SUCCESS
+ : trx_undo_report_row_operation(
+ thr, index, NULL, update,
cmpl_info, rec, offsets, roll_ptr));
}
@@ -2582,12 +2599,12 @@ btr_cur_pessimistic_update(
ulint** offsets,/*!< out: offsets on cursor->page_cur.rec */
mem_heap_t** offsets_heap,
/*!< in/out: pointer to memory heap
- that can be emptied, or NULL */
+ that can be emptied */
mem_heap_t* entry_heap,
/*!< in/out: memory heap for allocating
big_rec and the index tuple */
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
- be stored externally by the caller, or NULL */
+ be stored externally by the caller */
const upd_t* update, /*!< in: update vector; this is allowed also
contain trx id and roll ptr fields, but
the values in update vector have no effect */
@@ -3162,7 +3179,7 @@ btr_cur_del_mark_set_clust_rec(
return(err);
}
- err = trx_undo_report_row_operation(0, TRX_UNDO_MODIFY_OP, thr,
+ err = trx_undo_report_row_operation(thr,
index, NULL, NULL, 0, rec, offsets,
&roll_ptr);
if (err != DB_SUCCESS) {
@@ -3863,7 +3880,7 @@ static const unsigned rows_in_range_max_retries = 4;
/** We pretend that a range has that many records if the tree keeps changing
for rows_in_range_max_retries retries while we try to estimate the records
in a given range. */
-static const int64_t rows_in_range_arbitrary_ret_val = 10;
+static const ib_int64_t rows_in_range_arbitrary_ret_val = 10;
/** Estimates the number of rows in a given index range.
@param[in] index index
@@ -3881,7 +3898,7 @@ rows_in_range_arbitrary_ret_val as a result (if
nth_attempt >= rows_in_range_max_retries and the tree is modified between
the two dives). */
static
-int64_t
+ib_int64_t
btr_estimate_n_rows_in_range_low(
dict_index_t* index,
const dtuple_t* tuple1,
@@ -4017,7 +4034,7 @@ btr_estimate_n_rows_in_range_low(
return(rows_in_range_arbitrary_ret_val);
}
- const int64_t ret =
+ const ib_int64_t ret =
btr_estimate_n_rows_in_range_low(
index, tuple1, mode1,
tuple2, mode2, trx,
@@ -4083,7 +4100,7 @@ btr_estimate_n_rows_in_range_low(
@param[in] mode2 search mode for range end
@param[in] trx trx
@return estimated number of rows */
-int64_t
+ib_int64_t
btr_estimate_n_rows_in_range(
dict_index_t* index,
const dtuple_t* tuple1,
@@ -4092,7 +4109,7 @@ btr_estimate_n_rows_in_range(
ulint mode2,
trx_t* trx)
{
- const int64_t ret = btr_estimate_n_rows_in_range_low(
+ const ib_int64_t ret = btr_estimate_n_rows_in_range_low(
index, tuple1, mode1, tuple2, mode2, trx,
1 /* first attempt */);
diff --git a/storage/xtradb/btr/btr0sea.cc b/storage/xtradb/btr/btr0sea.cc
index 78cb9dfd6e0..2ed383b0dcb 100644
--- a/storage/xtradb/btr/btr0sea.cc
+++ b/storage/xtradb/btr/btr0sea.cc
@@ -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;
diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc
index a5d8b661c35..c9aa1cf5c13 100644
--- a/storage/xtradb/buf/buf0buf.cc
+++ b/storage/xtradb/buf/buf0buf.cc
@@ -2,6 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1432,8 +1433,6 @@ buf_pool_init_instance(
buf_pool->chunks = chunk =
(buf_chunk_t*) mem_zalloc(sizeof *chunk);
- UT_LIST_INIT(buf_pool->free);
-
if (!buf_chunk_init(buf_pool, chunk, buf_pool_size)) {
mem_free(chunk);
mem_free(buf_pool);
@@ -1455,7 +1454,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);
@@ -5593,23 +5592,22 @@ buf_print_io_instance(
pool_info->pages_written_rate);
if (pool_info->n_page_get_delta) {
- double hit_rate = ((1000 * pool_info->page_read_delta)
- / pool_info->n_page_get_delta);
+ double hit_rate = double(pool_info->page_read_delta)
+ / pool_info->n_page_get_delta;
- if (hit_rate > 1000) {
- hit_rate = 1000;
+ if (hit_rate > 1) {
+ hit_rate = 1;
}
- hit_rate = 1000 - hit_rate;
-
fprintf(file,
- "Buffer pool hit rate %lu / 1000,"
- " young-making rate %lu / 1000 not %lu / 1000\n",
- (ulint) hit_rate,
- (ulint) (1000 * pool_info->young_making_delta
- / pool_info->n_page_get_delta),
- (ulint) (1000 * pool_info->not_young_making_delta
- / pool_info->n_page_get_delta));
+ "Buffer pool hit rate " ULINTPF " / 1000,"
+ " young-making rate " ULINTPF " / 1000 not "
+ ULINTPF " / 1000\n",
+ ulint(1000 * (1 - hit_rate)),
+ ulint(1000 * double(pool_info->young_making_delta)
+ / pool_info->n_page_get_delta),
+ ulint(1000 * double(pool_info->not_young_making_delta)
+ / pool_info->n_page_get_delta));
} else {
fputs("No buffer pool page gets since the last printout\n",
file);
diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc
index 3c12d6da73f..46296814bb6 100644
--- a/storage/xtradb/buf/buf0dblwr.cc
+++ b/storage/xtradb/buf/buf0dblwr.cc
@@ -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)
{
diff --git a/storage/xtradb/buf/buf0dump.cc b/storage/xtradb/buf/buf0dump.cc
index df62c945288..51c41cc1b78 100644
--- a/storage/xtradb/buf/buf0dump.cc
+++ b/storage/xtradb/buf/buf0dump.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.
Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
@@ -604,6 +604,7 @@ buf_load()
if (dump_n == 0) {
ut_free(dump);
+ ut_free(dump_tmp);
ut_sprintf_timestamp(now);
buf_load_status(STATUS_NOTICE,
"Buffer pool(s) load completed at %s "
@@ -680,6 +681,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 +720,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);
diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc
index 018b29b7d95..4781b874032 100644
--- a/storage/xtradb/buf/buf0flu.cc
+++ b/storage/xtradb/buf/buf0flu.cc
@@ -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);
diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc
index 1aa2e7a9eb7..d31773c96cc 100644
--- a/storage/xtradb/buf/buf0lru.cc
+++ b/storage/xtradb/buf/buf0lru.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -1501,7 +1502,7 @@ loop:
n_iterations++;
- srv_stats.buf_pool_wait_free.add(n_iterations, 1);
+ srv_stats.buf_pool_wait_free.inc();
/* In case of backoff, do not ever attempt single page flushes
and wait for the cleaner to free some pages instead. */
@@ -1595,7 +1596,7 @@ loop:
++flush_failures;
}
- srv_stats.buf_pool_wait_free.add(n_iterations, 1);
+ srv_stats.buf_pool_wait_free.inc();
n_iterations++;
diff --git a/storage/xtradb/buf/buf0rea.cc b/storage/xtradb/buf/buf0rea.cc
index c28df72df92..9053f38924e 100644
--- a/storage/xtradb/buf/buf0rea.cc
+++ b/storage/xtradb/buf/buf0rea.cc
@@ -986,15 +986,11 @@ not_to_recover:
count++;
if (count > 1000) {
- fprintf(stderr,
- "InnoDB: Error: InnoDB has waited for"
- " 10 seconds for pending\n"
- "InnoDB: reads to the buffer pool to"
- " be finished.\n"
- "InnoDB: Number of pending reads %lu,"
- " pending pread calls %lu\n",
- (ulong) buf_pool->n_pend_reads,
- (ulong) os_file_n_pending_preads);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "waited for 10 seconds for " ULINTPF
+ " pending reads to the buffer pool to"
+ " be finished",
+ buf_pool->n_pend_reads);
os_aio_print_debug = TRUE;
}
diff --git a/storage/xtradb/dict/dict0boot.cc b/storage/xtradb/dict/dict0boot.cc
index 20ab5d75205..5d8cffa8de2 100644
--- a/storage/xtradb/dict/dict0boot.cc
+++ b/storage/xtradb/dict/dict0boot.cc
@@ -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 "
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index 13dd1d0c26c..39b1de44224 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -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));
}
/********************************************************************//**
diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc
index ee6de30cd40..0f48c7c69e3 100644
--- a/storage/xtradb/dict/dict0mem.cc
+++ b/storage/xtradb/dict/dict0mem.cc
@@ -321,8 +321,8 @@ dict_mem_table_col_rename_low(
ut_ad(from_len <= NAME_LEN);
ut_ad(to_len <= NAME_LEN);
- char from[NAME_LEN];
- strncpy(from, s, NAME_LEN);
+ char from[NAME_LEN + 1];
+ strncpy(from, s, NAME_LEN + 1);
if (from_len == to_len) {
/* The easy case: simply replace the column name in
diff --git a/storage/xtradb/dict/dict0stats.cc b/storage/xtradb/dict/dict0stats.cc
index c0a83c951a5..0063b6b9ed4 100644
--- a/storage/xtradb/dict/dict0stats.cc
+++ b/storage/xtradb/dict/dict0stats.cc
@@ -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
diff --git a/storage/xtradb/dict/dict0stats_bg.cc b/storage/xtradb/dict/dict0stats_bg.cc
index b3c8ef018f7..8cb419c6c37 100644
--- a/storage/xtradb/dict/dict0stats_bg.cc
+++ b/storage/xtradb/dict/dict0stats_bg.cc
@@ -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);
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 1a866a693ca..1a0105aaf0b 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -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__
@@ -1598,8 +1599,6 @@ fil_init(
fil_system->spaces = hash_create(hash_size);
fil_system->name_hash = hash_create(hash_size);
- UT_LIST_INIT(fil_system->LRU);
-
fil_system->max_n_open = max_n_open;
}
@@ -1943,7 +1942,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 */
@@ -2325,14 +2324,12 @@ fil_op_log_parse_or_replay(
} else if (log_flags & MLOG_FILE_FLAG_TEMP) {
/* Temporary table, do nothing */
} else {
- const char* path = NULL;
-
/* Create the database directory for name, if it does
not exist yet */
fil_create_directory_for_tablename(name);
if (fil_create_new_single_table_tablespace(
- space_id, name, path, flags,
+ space_id, name, NULL, flags,
DICT_TF2_USE_TABLESPACE,
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
ut_error;
@@ -3266,7 +3263,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 +3323,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 +5063,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 +5832,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 +6191,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 +6326,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);
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index 2e335c1c255..f24973e26fb 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -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);
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 9cb7d77ca84..4041ecde7b9 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.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.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
@@ -806,17 +806,31 @@ innobase_purge_changed_page_bitmaps(
/*================================*/
ulonglong lsn) __attribute__((unused)); /*!< in: LSN to purge files up to */
+/** 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;
-/*****************************************************************//**
-Check whether this is a fake change transaction.
-@return TRUE if a fake change transaction */
-static
-my_bool
-innobase_is_fake_change(
-/*====================*/
- handlerton *hton, /*!< in: InnoDB handlerton */
- THD* thd) __attribute__((unused)); /*!< in: MySQL thread handle of the user for
- whom the transaction is being committed */
+ 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.
@@ -1108,6 +1122,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}
};
@@ -1506,28 +1524,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.
@@ -2380,16 +2376,11 @@ innobase_get_stmt(
THD* thd, /*!< in: MySQL thread handle */
size_t* length) /*!< out: length of the SQL statement */
{
- const char* query = NULL;
- LEX_STRING *stmt = NULL;
- if (thd) {
- stmt = thd_query_string(thd);
- if (stmt) {
- *length = stmt->length;
- query = stmt->str;
- }
+ if (const LEX_STRING *stmt = thd_query_string(thd)) {
+ *length = stmt->length;
+ return stmt->str;
}
- return (query);
+ return NULL;
}
/**********************************************************************//**
@@ -3287,13 +3278,13 @@ innobase_convert_identifier(
ibool file_id)/*!< in: TRUE=id is a table or database name;
FALSE=id is an UTF-8 string */
{
+ char nz2[MAX_TABLE_NAME_LEN + 1];
const char* s = id;
int q;
if (file_id) {
char nz[MAX_TABLE_NAME_LEN + 1];
- char nz2[MAX_TABLE_NAME_LEN + 1];
/* Decode the table name. The MySQL function expects
a NUL-terminated string. The input and output strings
@@ -4078,10 +4069,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 "
@@ -4314,22 +4304,6 @@ innobase_purge_changed_page_bitmaps(
}
/*****************************************************************//**
-Check whether this is a fake change transaction.
-@return TRUE if a fake change transaction */
-static
-my_bool
-innobase_is_fake_change(
-/*====================*/
- handlerton *hton MY_ATTRIBUTE((unused)),
- /*!< in: InnoDB handlerton */
- THD* thd) /*!< in: MySQL thread handle of the user for
- whom the transaction is being committed */
-{
- trx_t* trx = check_trx_exists(thd);
- return UNIV_UNLIKELY(trx->fake_changes);
-}
-
-/*****************************************************************//**
Commits a transaction in an InnoDB database. */
static
void
@@ -7914,9 +7888,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()) {
@@ -8108,7 +8104,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)) {
@@ -8138,7 +8135,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);
@@ -8298,8 +8295,8 @@ ha_innobase::innobase_lock_autoinc(void)
break;
}
}
- /* Fall through to old style locking. */
-
+ /* Use old style locking. */
+ /* fall through */
case AUTOINC_OLD_STYLE_LOCKING:
DBUG_EXECUTE_IF("die_if_autoinc_old_lock_style_used",
ut_ad(0););
@@ -8896,8 +8893,8 @@ calc_row_difference(
}
}
- if (o_len != n_len || (o_len != UNIV_SQL_NULL &&
- 0 != memcmp(o_ptr, n_ptr, o_len))) {
+ if (o_len != n_len || (o_len != 0 && o_len != UNIV_SQL_NULL
+ && 0 != memcmp(o_ptr, n_ptr, o_len))) {
/* The field has changed */
ufield = uvect->fields + n_changed;
@@ -11658,7 +11655,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 */
+ /* ROW_FORMAT=DYNAMIC also shuns KEY_BLOCK_SIZE */
+ /* fall through */
case ROW_TYPE_COMPACT:
case ROW_TYPE_REDUNDANT:
if (kbs_specified) {
@@ -12040,7 +12038,8 @@ index_bad:
break;
}
zip_allowed = FALSE;
- /* fall through to set row_format = COMPACT */
+ /* Set ROW_FORMAT = COMPACT */
+ /* fall through */
case ROW_TYPE_NOT_USED:
case ROW_TYPE_FIXED:
case ROW_TYPE_PAGE:
@@ -12049,6 +12048,7 @@ index_bad:
thd, Sql_condition::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: assuming ROW_FORMAT=COMPACT.");
+ /* fall through */
case ROW_TYPE_DEFAULT:
/* If we fell through, set row format to Compact. */
row_format = ROW_TYPE_COMPACT;
@@ -12682,7 +12682,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)) {
@@ -14524,7 +14525,8 @@ fill_foreign_key_list(THD* thd,
{
ut_ad(mutex_own(&dict_sys->mutex));
- for (dict_foreign_set::iterator it = table->referenced_set.begin();
+ for (dict_foreign_set::const_iterator it
+ = table->referenced_set.begin();
it != table->referenced_set.end(); ++it) {
dict_foreign_t* foreign = *it;
@@ -18066,15 +18068,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);
+ all_evicted = buf_LRU_free_page(&block->page, false);
+ mutex_exit(&block->mutex);
+
+ if (all_evicted) {
+
mutex_enter(&buf_pool->LRU_list_mutex);
- }
+ block = UT_LIST_GET_LAST(buf_pool->unzip_LRU);
+ } else {
- block = prev_block;
+ block = prev_block;
+ }
}
mutex_exit(&buf_pool->LRU_list_mutex);
@@ -18889,32 +18893,6 @@ innodb_status_output_update(
}
/*************************************************************//**
-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.
@return 0 for valid algorithm */
@@ -18955,13 +18933,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);
}
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index da2f0f877f4..155348cfec1 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -522,7 +522,7 @@ innobase_index_name_is_reserved(
const KEY* key_info, /*!< in: Indexes to be created */
ulint num_of_keys) /*!< in: Number of indexes to
be created. */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((nonnull(1), warn_unused_result));
/*****************************************************************//**
#ifdef WITH_WSREP
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 4db33fab1a6..b21812e6f51 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -134,7 +134,6 @@ my_error_innodb(
break;
case DB_OUT_OF_FILE_SPACE:
my_error(ER_RECORD_FILE_FULL, MYF(0), table);
- ut_error;
break;
case DB_TEMP_FILE_WRITE_FAILURE:
my_error(ER_GET_ERRMSG, MYF(0),
@@ -1265,7 +1264,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)) {
@@ -1317,7 +1317,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])
@@ -2283,10 +2284,10 @@ online_retry_drop_indexes_with_trx(
@param drop_fk constraints being dropped
@param n_drop_fk number of constraints that are being dropped
@return whether the constraint is being dropped */
-inline MY_ATTRIBUTE((pure, nonnull, warn_unused_result))
+MY_ATTRIBUTE((pure, nonnull(1), warn_unused_result))
+inline
bool
innobase_dropping_foreign(
-/*======================*/
const dict_foreign_t* foreign,
dict_foreign_t** drop_fk,
ulint n_drop_fk)
@@ -2310,10 +2311,10 @@ column that is being dropped or modified to NOT NULL.
@retval true Not allowed (will call my_error())
@retval false Allowed
*/
-static MY_ATTRIBUTE((pure, nonnull, warn_unused_result))
+MY_ATTRIBUTE((pure, nonnull(1,4), warn_unused_result))
+static
bool
innobase_check_foreigns_low(
-/*========================*/
const dict_table_t* user_table,
dict_foreign_t** drop_fk,
ulint n_drop_fk,
@@ -2410,10 +2411,10 @@ column that is being dropped or modified to NOT NULL.
@retval true Not allowed (will call my_error())
@retval false Allowed
*/
-static MY_ATTRIBUTE((pure, nonnull, warn_unused_result))
+MY_ATTRIBUTE((pure, nonnull(1,2,3,4), warn_unused_result))
+static
bool
innobase_check_foreigns(
-/*====================*/
Alter_inplace_info* ha_alter_info,
const TABLE* altered_table,
const TABLE* old_table,
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index f2686f1049b..aac1074e152 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -155,6 +156,7 @@ struct buf_page_info_t{
if ((expr) != 0) { \
DBUG_RETURN(1); \
}
+#define BREAK_IF(expr) if ((expr)) break
#define RETURN_IF_INNODB_NOT_STARTED(plugin_name) \
do { \
@@ -2989,14 +2991,16 @@ i_s_fts_deleted_generic_fill(
fields = table->field;
+ int ret = 0;
+
for (ulint j = 0; j < ib_vector_size(deleted->doc_ids); ++j) {
doc_id_t doc_id;
doc_id = *(doc_id_t*) ib_vector_get_const(deleted->doc_ids, j);
- OK(fields[I_S_FTS_DOC_ID]->store((longlong) doc_id, true));
+ BREAK_IF(ret = fields[I_S_FTS_DOC_ID]->store(doc_id, true));
- OK(schema_table_store_record(thd, table));
+ BREAK_IF(ret = schema_table_store_record(thd, table));
}
trx_free_for_background(trx);
@@ -3007,7 +3011,7 @@ i_s_fts_deleted_generic_fill(
rw_lock_s_unlock(&dict_operation_lock);
- DBUG_RETURN(0);
+ DBUG_RETURN(ret);
}
/*******************************************************************//**
@@ -3245,13 +3249,13 @@ i_s_fts_index_cache_fill_one_index(
/*===============================*/
fts_index_cache_t* index_cache, /*!< in: FTS index cache */
THD* thd, /*!< in: thread */
+ fts_string_t* conv_str, /*!< in/out: buffer */
TABLE_LIST* tables) /*!< in/out: tables to fill */
{
TABLE* table = (TABLE*) tables->table;
Field** fields;
CHARSET_INFO* index_charset;
const ib_rbt_node_t* rbt_node;
- fts_string_t conv_str;
uint dummy_errors;
char* word_str;
@@ -3260,10 +3264,9 @@ i_s_fts_index_cache_fill_one_index(
fields = table->field;
index_charset = index_cache->charset;
- conv_str.f_len = system_charset_info->mbmaxlen
- * FTS_MAX_WORD_LEN_IN_CHAR;
- conv_str.f_str = static_cast<byte*>(ut_malloc(conv_str.f_len));
- conv_str.f_n_char = 0;
+ conv_str->f_n_char = 0;
+
+ int ret = 0;
/* Go through each word in the index cache */
for (rbt_node = rbt_first(index_cache->words);
@@ -3275,16 +3278,16 @@ i_s_fts_index_cache_fill_one_index(
/* Convert word from index charset to system_charset_info */
if (index_charset->cset != system_charset_info->cset) {
- conv_str.f_n_char = my_convert(
- reinterpret_cast<char*>(conv_str.f_str),
- static_cast<uint32>(conv_str.f_len),
+ conv_str->f_n_char = my_convert(
+ reinterpret_cast<char*>(conv_str->f_str),
+ static_cast<uint32>(conv_str->f_len),
system_charset_info,
reinterpret_cast<char*>(word->text.f_str),
static_cast<uint32>(word->text.f_len),
index_charset, &dummy_errors);
- ut_ad(conv_str.f_n_char <= conv_str.f_len);
- conv_str.f_str[conv_str.f_n_char] = 0;
- word_str = reinterpret_cast<char*>(conv_str.f_str);
+ ut_ad(conv_str->f_n_char <= conv_str->f_len);
+ conv_str->f_str[conv_str->f_n_char] = 0;
+ word_str = reinterpret_cast<char*>(conv_str->f_str);
} else {
word_str = reinterpret_cast<char*>(word->text.f_str);
}
@@ -3342,9 +3345,7 @@ i_s_fts_index_cache_fill_one_index(
}
}
- ut_free(conv_str.f_str);
-
- DBUG_RETURN(0);
+ DBUG_RETURN(ret);
}
/*******************************************************************//**
Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHED
@@ -3388,18 +3389,27 @@ i_s_fts_index_cache_fill(
ut_a(cache);
+ int ret = 0;
+ fts_string_t conv_str;
+ conv_str.f_len = system_charset_info->mbmaxlen
+ * FTS_MAX_WORD_LEN_IN_CHAR;
+ conv_str.f_str = static_cast<byte*>(ut_malloc(conv_str.f_len));
+
for (ulint 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));
- i_s_fts_index_cache_fill_one_index(index_cache, thd, tables);
+ BREAK_IF(ret = i_s_fts_index_cache_fill_one_index(
+ index_cache, thd, &conv_str, tables));
}
+ ut_free(conv_str.f_str);
+
dict_table_close(user_table, FALSE, FALSE);
- DBUG_RETURN(0);
+ DBUG_RETURN(ret);
}
/*******************************************************************//**
@@ -3702,8 +3712,6 @@ i_s_fts_index_table_fill_one_fetch(
}
}
- i_s_fts_index_table_free_one_fetch(words);
-
DBUG_RETURN(ret);
}
@@ -3717,13 +3725,13 @@ i_s_fts_index_table_fill_one_index(
/*===============================*/
dict_index_t* index, /*!< in: FTS index */
THD* thd, /*!< in: thread */
+ fts_string_t* conv_str, /*!< in/out: buffer */
TABLE_LIST* tables) /*!< in/out: tables to fill */
{
ib_vector_t* words;
mem_heap_t* heap;
fts_string_t word;
CHARSET_INFO* index_charset;
- fts_string_t conv_str;
dberr_t error;
int ret = 0;
@@ -3740,10 +3748,6 @@ i_s_fts_index_table_fill_one_index(
word.f_n_char = 0;
index_charset = fts_index_get_charset(index);
- conv_str.f_len = system_charset_info->mbmaxlen
- * FTS_MAX_WORD_LEN_IN_CHAR;
- conv_str.f_str = static_cast<byte*>(ut_malloc(conv_str.f_len));
- conv_str.f_n_char = 0;
/* Iterate through each auxiliary table as described in
fts_index_selector */
@@ -3777,17 +3781,17 @@ i_s_fts_index_table_fill_one_index(
/* Fill into tables */
ret = i_s_fts_index_table_fill_one_fetch(
- index_charset, thd, tables, words, &conv_str, has_more);
+ index_charset, thd, tables, words, conv_str,
+ has_more);
+ i_s_fts_index_table_free_one_fetch(words);
if (ret != 0) {
- i_s_fts_index_table_free_one_fetch(words);
goto func_exit;
}
} while (has_more);
}
func_exit:
- ut_free(conv_str.f_str);
mem_heap_free(heap);
DBUG_RETURN(ret);
@@ -3829,10 +3833,17 @@ i_s_fts_index_table_fill(
DBUG_RETURN(0);
}
+ int ret = 0;
+ fts_string_t conv_str;
+ conv_str.f_len = system_charset_info->mbmaxlen
+ * FTS_MAX_WORD_LEN_IN_CHAR;
+ conv_str.f_str = static_cast<byte*>(ut_malloc(conv_str.f_len));
+
for (index = dict_table_get_first_index(user_table);
index; index = dict_table_get_next_index(index)) {
if (index->type & DICT_FTS) {
- i_s_fts_index_table_fill_one_index(index, thd, tables);
+ BREAK_IF(ret = i_s_fts_index_table_fill_one_index(
+ index, thd, &conv_str, tables));
}
}
@@ -3840,7 +3851,9 @@ i_s_fts_index_table_fill(
rw_lock_s_unlock(&dict_operation_lock);
- DBUG_RETURN(0);
+ ut_free(conv_str.f_str);
+
+ DBUG_RETURN(ret);
}
/*******************************************************************//**
@@ -4005,6 +4018,8 @@ i_s_fts_config_fill(
DBUG_ASSERT(!dict_index_is_online_ddl(index));
}
+ int ret = 0;
+
while (fts_config_key[i]) {
fts_string_t value;
char* key_name;
@@ -4029,13 +4044,14 @@ i_s_fts_config_fill(
ut_free(key_name);
}
- OK(field_store_string(
- fields[FTS_CONFIG_KEY], fts_config_key[i]));
+ BREAK_IF(ret = field_store_string(
+ fields[FTS_CONFIG_KEY], fts_config_key[i]));
- OK(field_store_string(
- fields[FTS_CONFIG_VALUE], (const char*) value.f_str));
+ BREAK_IF(ret = field_store_string(
+ fields[FTS_CONFIG_VALUE],
+ reinterpret_cast<const char*>(value.f_str)));
- OK(schema_table_store_record(thd, table));
+ BREAK_IF(ret = schema_table_store_record(thd, table));
i++;
}
@@ -4048,7 +4064,7 @@ i_s_fts_config_fill(
rw_lock_s_unlock(&dict_operation_lock);
- DBUG_RETURN(0);
+ DBUG_RETURN(ret);
}
/*******************************************************************//**
@@ -4883,34 +4899,29 @@ i_s_innodb_buffer_page_fill(
state_str = NULL;
OK(fields[IDX_BUFFER_POOL_ID]->store(
- static_cast<double>(page_info->pool_id)));
+ page_info->pool_id, true));
OK(fields[IDX_BUFFER_BLOCK_ID]->store(
- static_cast<double>(page_info->block_id)));
+ page_info->block_id, true));
OK(fields[IDX_BUFFER_PAGE_SPACE]->store(
- static_cast<double>(page_info->space_id)));
+ page_info->space_id, true));
OK(fields[IDX_BUFFER_PAGE_NUM]->store(
- static_cast<double>(page_info->page_num)));
+ page_info->page_num, true));
OK(field_store_string(
fields[IDX_BUFFER_PAGE_TYPE],
i_s_page_type[page_info->page_type].type_str));
OK(fields[IDX_BUFFER_PAGE_FLUSH_TYPE]->store(
- page_info->flush_type));
+ page_info->flush_type, true));
OK(fields[IDX_BUFFER_PAGE_FIX_COUNT]->store(
- page_info->fix_count));
+ page_info->fix_count, true));
- if (page_info->hashed) {
- OK(field_store_string(
- fields[IDX_BUFFER_PAGE_HASHED], "YES"));
- } else {
- OK(field_store_string(
- fields[IDX_BUFFER_PAGE_HASHED], "NO"));
- }
+ OK(field_store_string(fields[IDX_BUFFER_PAGE_HASHED],
+ page_info->hashed ? "YES" : "NO"));
OK(fields[IDX_BUFFER_PAGE_NEWEST_MOD]->store(
(longlong) page_info->newest_mod, true));
@@ -4919,7 +4930,7 @@ i_s_innodb_buffer_page_fill(
(longlong) page_info->oldest_mod, true));
OK(fields[IDX_BUFFER_PAGE_ACCESS_TIME]->store(
- page_info->access_time));
+ page_info->access_time, true));
fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_null();
@@ -4928,44 +4939,48 @@ i_s_innodb_buffer_page_fill(
/* If this is an index page, fetch the index name
and table name */
if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
- const dict_index_t* index;
+ bool ret = false;
mutex_enter(&dict_sys->mutex);
- index = dict_index_get_if_in_cache_low(
- page_info->index_id);
-
- if (index) {
+ if (const dict_index_t* index =
+ dict_index_get_if_in_cache_low(
+ page_info->index_id)) {
table_name_end = innobase_convert_name(
table_name, sizeof(table_name),
index->table_name,
strlen(index->table_name),
thd, TRUE);
- OK(fields[IDX_BUFFER_PAGE_TABLE_NAME]->store(
- table_name,
- static_cast<uint>(table_name_end - table_name),
- system_charset_info));
- fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_notnull();
-
- OK(field_store_index_name(
- fields[IDX_BUFFER_PAGE_INDEX_NAME],
- index->name));
+ ret = fields[IDX_BUFFER_PAGE_TABLE_NAME]
+ ->store(table_name,
+ static_cast<uint>(
+ table_name_end
+ - table_name),
+ system_charset_info)
+ || field_store_index_name(
+ fields
+ [IDX_BUFFER_PAGE_INDEX_NAME],
+ index->name);
}
mutex_exit(&dict_sys->mutex);
+
+ OK(ret);
+
+ fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_notnull();
}
OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store(
- page_info->num_recs));
+ page_info->num_recs, true));
OK(fields[IDX_BUFFER_PAGE_DATA_SIZE]->store(
- page_info->data_size));
+ page_info->data_size, true));
OK(fields[IDX_BUFFER_PAGE_ZIP_SIZE]->store(
- page_info->zip_ssize
- ? (UNIV_ZIP_SIZE_MIN >> 1) << page_info->zip_ssize
- : 0));
+ page_info->zip_ssize
+ ? (UNIV_ZIP_SIZE_MIN >> 1) << page_info->zip_ssize
+ : 0, true));
#if BUF_PAGE_STATE_BITS > 3
# error "BUF_PAGE_STATE_BITS > 3, please ensure that all 1<<BUF_PAGE_STATE_BITS values are checked for"
@@ -5003,32 +5018,29 @@ i_s_innodb_buffer_page_fill(
switch (page_info->io_fix) {
case BUF_IO_NONE:
- OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
- "IO_NONE"));
+ state_str = "IO_NONE";
break;
case BUF_IO_READ:
- OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
- "IO_READ"));
+ state_str = "IO_READ";
break;
case BUF_IO_WRITE:
- OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
- "IO_WRITE"));
+ state_str = "IO_WRITE";
break;
case BUF_IO_PIN:
- OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
- "IO_PIN"));
+ state_str = "IO_PIN";
break;
}
+ OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
+ state_str));
+
OK(field_store_string(fields[IDX_BUFFER_PAGE_IS_OLD],
(page_info->is_old) ? "YES" : "NO"));
OK(fields[IDX_BUFFER_PAGE_FREE_CLOCK]->store(
page_info->freed_page_clock));
- if (schema_table_store_record(thd, table)) {
- DBUG_RETURN(1);
- }
+ OK(schema_table_store_record(thd, table));
}
DBUG_RETURN(0);
@@ -5569,17 +5581,10 @@ i_s_innodb_buf_page_lru_fill(
ulint num_page) /*!< in: number of page info
cached */
{
- TABLE* table;
- Field** fields;
- mem_heap_t* heap;
-
DBUG_ENTER("i_s_innodb_buf_page_lru_fill");
- table = tables->table;
-
- fields = table->field;
-
- heap = mem_heap_create(1000);
+ TABLE* table = tables->table;
+ Field** fields = table->field;
/* Iterate through the cached array and fill the I_S table rows */
for (ulint i = 0; i < num_page; i++) {
@@ -5594,43 +5599,37 @@ i_s_innodb_buf_page_lru_fill(
page_info = info_array + i;
OK(fields[IDX_BUF_LRU_POOL_ID]->store(
- static_cast<double>(page_info->pool_id)));
-
+ page_info->pool_id, true));
OK(fields[IDX_BUF_LRU_POS]->store(
- static_cast<double>(page_info->block_id)));
+ page_info->block_id, true));
OK(fields[IDX_BUF_LRU_PAGE_SPACE]->store(
- static_cast<double>(page_info->space_id)));
+ page_info->space_id, true));
OK(fields[IDX_BUF_LRU_PAGE_NUM]->store(
- static_cast<double>(page_info->page_num)));
+ page_info->page_num, true));
OK(field_store_string(
- fields[IDX_BUF_LRU_PAGE_TYPE],
- i_s_page_type[page_info->page_type].type_str));
+ fields[IDX_BUF_LRU_PAGE_TYPE],
+ i_s_page_type[page_info->page_type].type_str));
OK(fields[IDX_BUF_LRU_PAGE_FLUSH_TYPE]->store(
- static_cast<double>(page_info->flush_type)));
+ page_info->flush_type, true));
OK(fields[IDX_BUF_LRU_PAGE_FIX_COUNT]->store(
- static_cast<double>(page_info->fix_count)));
+ page_info->fix_count, true));
- if (page_info->hashed) {
- OK(field_store_string(
- fields[IDX_BUF_LRU_PAGE_HASHED], "YES"));
- } else {
- OK(field_store_string(
- fields[IDX_BUF_LRU_PAGE_HASHED], "NO"));
- }
+ OK(field_store_string(fields[IDX_BUF_LRU_PAGE_HASHED],
+ page_info->hashed ? "YES" : "NO"));
OK(fields[IDX_BUF_LRU_PAGE_NEWEST_MOD]->store(
- page_info->newest_mod, true));
+ page_info->newest_mod, true));
OK(fields[IDX_BUF_LRU_PAGE_OLDEST_MOD]->store(
- page_info->oldest_mod, true));
+ page_info->oldest_mod, true));
OK(fields[IDX_BUF_LRU_PAGE_ACCESS_TIME]->store(
- page_info->access_time));
+ page_info->access_time, true));
fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_null();
@@ -5639,43 +5638,47 @@ i_s_innodb_buf_page_lru_fill(
/* If this is an index page, fetch the index name
and table name */
if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
- const dict_index_t* index;
+ bool ret = false;
mutex_enter(&dict_sys->mutex);
- index = dict_index_get_if_in_cache_low(
- page_info->index_id);
-
- if (index) {
+ if (const dict_index_t* index =
+ dict_index_get_if_in_cache_low(
+ page_info->index_id)) {
table_name_end = innobase_convert_name(
table_name, sizeof(table_name),
index->table_name,
strlen(index->table_name),
thd, TRUE);
- OK(fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->store(
- table_name,
- static_cast<uint>(table_name_end - table_name),
- system_charset_info));
- fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_notnull();
-
- OK(field_store_index_name(
- fields[IDX_BUF_LRU_PAGE_INDEX_NAME],
- index->name));
+ ret = fields[IDX_BUF_LRU_PAGE_TABLE_NAME]
+ ->store(table_name,
+ static_cast<uint>(
+ table_name_end
+ - table_name),
+ system_charset_info)
+ || field_store_index_name(
+ fields
+ [IDX_BUF_LRU_PAGE_INDEX_NAME],
+ index->name);
}
mutex_exit(&dict_sys->mutex);
+
+ OK(ret);
+
+ fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_notnull();
}
OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store(
- page_info->num_recs));
+ page_info->num_recs, true));
OK(fields[IDX_BUF_LRU_PAGE_DATA_SIZE]->store(
- page_info->data_size));
+ page_info->data_size, true));
OK(fields[IDX_BUF_LRU_PAGE_ZIP_SIZE]->store(
- page_info->zip_ssize ?
- 512 << page_info->zip_ssize : 0));
+ page_info->zip_ssize
+ ? 512 << page_info->zip_ssize : 0, true));
state = static_cast<enum buf_page_state>(page_info->page_state);
@@ -5704,35 +5707,31 @@ i_s_innodb_buf_page_lru_fill(
switch (page_info->io_fix) {
case BUF_IO_NONE:
- OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
- "IO_NONE"));
+ state_str = "IO_NONE";
break;
case BUF_IO_READ:
- OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
- "IO_READ"));
+ state_str = "IO_READ";
break;
case BUF_IO_WRITE:
- OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
- "IO_WRITE"));
+ state_str = "IO_WRITE";
+ break;
+ case BUF_IO_PIN:
+ state_str = "IO_PIN";
break;
}
+ OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
+ state_str));
+
OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IS_OLD],
- (page_info->is_old) ? "YES" : "NO"));
+ page_info->is_old ? "YES" : "NO"));
OK(fields[IDX_BUF_LRU_PAGE_FREE_CLOCK]->store(
- page_info->freed_page_clock));
-
- if (schema_table_store_record(thd, table)) {
- mem_heap_free(heap);
- DBUG_RETURN(1);
- }
+ page_info->freed_page_clock, true));
- mem_heap_empty(heap);
+ OK(schema_table_store_record(thd, table));
}
- mem_heap_free(heap);
-
DBUG_RETURN(0);
}
diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc
index a9f039d3f0f..414d7fc39be 100644
--- a/storage/xtradb/ibuf/ibuf0ibuf.cc
+++ b/storage/xtradb/ibuf/ibuf0ibuf.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -2934,8 +2935,7 @@ ibuf_get_volume_buffered_hash(
fold = ut_fold_binary(data, len);
hash += (fold / (CHAR_BIT * sizeof *hash)) % size;
- bitmask = static_cast<ulint>(
- 1 << (fold % (CHAR_BIT * sizeof(*hash))));
+ bitmask = static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash)));
if (*hash & bitmask) {
@@ -3704,7 +3704,7 @@ fail_exit:
if (mode == BTR_MODIFY_PREV) {
err = btr_cur_optimistic_insert(
- BTR_NO_LOCKING_FLAG,
+ BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG,
cursor, &offsets, &offsets_heap,
ibuf_entry, &ins_rec,
&dummy_big_rec, 0, thr, &mtr);
diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h
index 19ab7d8bc3a..d973eb80c59 100644
--- a/storage/xtradb/include/btr0cur.h
+++ b/storage/xtradb/include/btr0cur.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -220,15 +221,17 @@ btr_cur_optimistic_insert(
btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
ulint** offsets,/*!< out: offsets on *rec */
- mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
succeed */
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
- be stored externally by the caller, or
- NULL */
+ be stored externally by the caller */
ulint n_ext, /*!< in: number of externally stored columns */
- que_thr_t* thr, /*!< in: query thread or NULL */
+ que_thr_t* thr, /*!< in/out: query thread; can be NULL if
+ !(~flags
+ & (BTR_NO_LOCKING_FLAG
+ | BTR_NO_UNDO_LOG_FLAG)) */
mtr_t* mtr) /*!< in/out: mini-transaction;
if this function returns DB_SUCCESS on
a leaf page of a secondary index in a
@@ -256,15 +259,17 @@ btr_cur_pessimistic_insert(
cursor stays valid */
ulint** offsets,/*!< out: offsets on *rec */
mem_heap_t** heap, /*!< in/out: pointer to memory heap
- that can be emptied, or NULL */
+ that can be emptied */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
succeed */
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
- be stored externally by the caller, or
- NULL */
+ be stored externally by the caller */
ulint n_ext, /*!< in: number of externally stored columns */
- que_thr_t* thr, /*!< in: query thread or NULL */
+ que_thr_t* thr, /*!< in/out: query thread; can be NULL if
+ !(~flags
+ & (BTR_NO_LOCKING_FLAG
+ | BTR_NO_UNDO_LOG_FLAG)) */
mtr_t* mtr) /*!< in/out: mini-transaction */
MY_ATTRIBUTE((nonnull(2,3,4,5,6,7,10), warn_unused_result));
/*************************************************************//**
@@ -392,12 +397,12 @@ btr_cur_pessimistic_update(
ulint** offsets,/*!< out: offsets on cursor->page_cur.rec */
mem_heap_t** offsets_heap,
/*!< in/out: pointer to memory heap
- that can be emptied, or NULL */
+ that can be emptied */
mem_heap_t* entry_heap,
/*!< in/out: memory heap for allocating
big_rec and the index tuple */
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
- be stored externally by the caller, or NULL */
+ be stored externally by the caller */
const upd_t* update, /*!< in: update vector; this is allowed also
contain trx id and roll ptr fields, but
the values in update vector have no effect */
diff --git a/storage/xtradb/include/buf0dblwr.h b/storage/xtradb/include/buf0dblwr.h
index 5582778825c..8e1b00db83c 100644
--- a/storage/xtradb/include/buf0dblwr.h
+++ b/storage/xtradb/include/buf0dblwr.h
@@ -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);
diff --git a/storage/xtradb/include/data0type.ic b/storage/xtradb/include/data0type.ic
index 555852474aa..8f5cee0fd5f 100644
--- a/storage/xtradb/include/data0type.ic
+++ b/storage/xtradb/include/data0type.ic
@@ -576,7 +576,8 @@ dtype_get_fixed_size_low(
#else /* !UNIV_HOTBACKUP */
return(len);
#endif /* !UNIV_HOTBACKUP */
- /* fall through for variable-length charsets */
+ /* Treat as variable-length. */
+ /* Fall through */
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_DECIMAL:
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index a2481fbad6f..ef6c32b1787 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -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 */
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index efc2c3f0e68..805092db715 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -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
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 3023b29b793..9bba03f5200 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -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 */
@@ -778,7 +778,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
@@ -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;
diff --git a/storage/xtradb/include/ha0ha.h b/storage/xtradb/include/ha0ha.h
index 7351b407e8c..58eb581e76a 100644
--- a/storage/xtradb/include/ha0ha.h
+++ b/storage/xtradb/include/ha0ha.h
@@ -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 */
/*************************************************************//**
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index bb43a626c2c..43399c8e218 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -143,7 +144,7 @@ enum durability_properties
thd_requested_durability(
/*=====================*/
const THD* thd) /*!< in: thread handle */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
+ MY_ATTRIBUTE((warn_unused_result));
/******************************************************************//**
Returns true if the transaction this thread is processing has edited
diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h
index 722336dd6b4..5c3e7d07fd9 100644
--- a/storage/xtradb/include/log0online.h
+++ b/storage/xtradb/include/log0online.h
@@ -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
diff --git a/storage/xtradb/include/mach0data.ic b/storage/xtradb/include/mach0data.ic
index 4b9275cc12c..26d6c879c9b 100644
--- a/storage/xtradb/include/mach0data.ic
+++ b/storage/xtradb/include/mach0data.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2009, 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
the terms of the GNU General Public License as published by the Free Software
@@ -779,13 +780,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++; /* fall through */
+ case 7: *--dest = *from++; /* fall through */
+ case 6: *--dest = *from++; /* fall through */
+ case 5: *--dest = *from++; /* fall through */
+ case 4: *--dest = *from++; /* fall through */
+ case 3: *--dest = *from++; /* fall through */
+ case 2: *--dest = *from++; /* fall through */
case 1: *--dest = *from;
}
}
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index 60a9c3475e7..5f11ba86275 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -1,8 +1,8 @@
/***********************************************************************
-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) 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted
by Percona Inc.. Those modifications are
@@ -52,16 +52,6 @@ extern ibool os_has_said_disk_full;
/** Flag: enable debug printout for asynchronous i/o */
extern ibool os_aio_print_debug;
-/** Number of pending os_file_pread() operations */
-extern ulint os_file_n_pending_preads;
-/** Number of pending os_file_pwrite() operations */
-extern ulint os_file_n_pending_pwrites;
-
-/** Number of pending read operations */
-extern ulint os_n_pending_reads;
-/** Number of pending write operations */
-extern ulint os_n_pending_writes;
-
#ifdef __WIN__
/** We define always WIN_ASYNC_IO, and check at run-time whether
@@ -79,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 */
@@ -88,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;
@@ -130,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 */
@@ -232,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()
@@ -241,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)
@@ -277,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); \
} \
@@ -287,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)
@@ -301,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_". */
@@ -323,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__)
@@ -344,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) \
@@ -359,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
@@ -374,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)
@@ -403,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 {
@@ -538,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
@@ -571,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
@@ -630,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
/****************************************************************//**
@@ -640,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 */
@@ -663,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 */
@@ -687,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 */
@@ -716,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 */
/*******************************************************************//**
@@ -729,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 */
@@ -748,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 */
@@ -769,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 */
@@ -798,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 */
@@ -815,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 */
@@ -867,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 */
@@ -884,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.
@@ -895,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));
/***********************************************************************//**
@@ -907,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 */
@@ -1142,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 */
diff --git a/storage/xtradb/include/os0file.ic b/storage/xtradb/include/os0file.ic
index 25a1397147e..c82a2559fed 100644
--- a/storage/xtradb/include/os0file.ic
+++ b/storage/xtradb/include/os0file.ic
@@ -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 */
diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h
index f6207555f1a..7bc591b2911 100644
--- a/storage/xtradb/include/os0sync.h
+++ b/storage/xtradb/include/os0sync.h
@@ -2,6 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -38,12 +39,12 @@ Created 9/6/1995 Heikki Tuuri
#include "ut0lst.h"
#include "sync0types.h"
-#if defined __i386__ || defined __x86_64__ || defined _M_IX86 \
- || defined _M_X64 || defined __WIN__
-
-#define IB_STRONG_MEMORY_MODEL
-
-#endif /* __i386__ || __x86_64__ || _M_IX86 || _M_X64 || __WIN__ */
+/** CPU cache line size */
+#ifdef __powerpc__
+#define CACHE_LINE_SIZE 128
+#else
+#define CACHE_LINE_SIZE 64
+#endif
#ifdef HAVE_WINDOWS_ATOMICS
typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
@@ -718,10 +719,7 @@ os_atomic_clear(volatile lock_word_t* ptr)
# define HAVE_ATOMIC_BUILTINS
# define HAVE_ATOMIC_BUILTINS_BYTE
-
-# ifndef _WIN32
-# define HAVE_ATOMIC_BUILTINS_64
-# endif
+# define HAVE_ATOMIC_BUILTINS_64
/**********************************************************//**
Atomic compare and exchange of signed integers (both 32 and 64 bit).
@@ -943,6 +941,58 @@ for synchronization */
"Memory barrier is not used"
#endif
+
+/** Simple counter aligned to CACHE_LINE_SIZE
+@tparam Type the integer type of the counter
+@tparam atomic whether to use atomic memory access */
+template <typename Type = ulint, bool atomic = false>
+struct MY_ALIGNED(CACHE_LINE_SIZE) simple_counter
+{
+ /** Increment the counter */
+ Type inc() { return add(1); }
+ /** Decrement the counter */
+ Type dec() { return sub(1); }
+
+ /** Add to the counter
+ @param[in] i amount to be added
+ @return the value of the counter after adding */
+ Type add(Type i)
+ {
+ compile_time_assert(!atomic || sizeof(Type) == sizeof(ulint));
+ if (atomic) {
+ /* GCC would perform a type check in this code
+ also in case the template is instantiated with
+ simple_counter<Type=not_ulint, atomic=false>.
+ On Solaris, os_atomic_increment_ulint() maps
+ to atomic_add_long_nv(), which expects the
+ parameter to be correctly typed. */
+ return os_atomic_increment_ulint(
+ reinterpret_cast<ulint*>(&m_counter), i);
+ } else {
+ return m_counter += i;
+ }
+ }
+ /** Subtract from the counter
+ @param[in] i amount to be subtracted
+ @return the value of the counter after adding */
+ Type sub(Type i)
+ {
+ compile_time_assert(!atomic || sizeof(Type) == sizeof(ulint));
+ if (atomic) {
+ return os_atomic_decrement_ulint(&m_counter, i);
+ } else {
+ return m_counter -= i;
+ }
+ }
+
+ /** @return the value of the counter (non-atomic access)! */
+ operator Type() const { return m_counter; }
+
+private:
+ /** The counter */
+ Type m_counter;
+};
+
#ifndef UNIV_NONINL
#include "os0sync.ic"
#endif
diff --git a/storage/xtradb/include/page0zip.ic b/storage/xtradb/include/page0zip.ic
index 6c7d8cd32c7..9a583086925 100644
--- a/storage/xtradb/include/page0zip.ic
+++ b/storage/xtradb/include/page0zip.ic
@@ -2,6 +2,7 @@
Copyright (c) 2005, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2017, MariaDB Corporation.
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
@@ -172,7 +173,8 @@ 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/row0mysql.h b/storage/xtradb/include/row0mysql.h
index e1148517d99..217a9547f1e 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -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();
diff --git a/storage/xtradb/include/srv0mon.h b/storage/xtradb/include/srv0mon.h
index 2d90f47eefe..09af5d4159b 100644
--- a/storage/xtradb/include/srv0mon.h
+++ b/storage/xtradb/include/srv0mon.h
@@ -2,6 +2,7 @@
Copyright (c) 2010, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2017, MariaDB Corporation.
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
@@ -541,22 +542,30 @@ on the counters */
/** Increment a monitor counter under mutex protection.
Use MONITOR_INC if appropriate mutex protection already exists.
+@param mutex mutex to acquire and release
@param monitor monitor to be incremented by 1
-@param mutex mutex to acquire and relese */
-# define MONITOR_MUTEX_INC(mutex, monitor) \
+@param enabled whether the monitor is enabled */
+#define MONITOR_MUTEX_INC_LOW(mutex, monitor, enabled) \
ut_ad(!mutex_own(mutex)); \
- if (MONITOR_IS_ON(monitor)) { \
+ if (enabled) { \
mutex_enter(mutex); \
if (++MONITOR_VALUE(monitor) > MONITOR_MAX_VALUE(monitor)) { \
MONITOR_MAX_VALUE(monitor) = MONITOR_VALUE(monitor); \
} \
mutex_exit(mutex); \
}
+/** Increment a monitor counter under mutex protection.
+Use MONITOR_INC if appropriate mutex protection already exists.
+@param mutex mutex to acquire and release
+@param monitor monitor to be incremented by 1 */
+#define MONITOR_MUTEX_INC(mutex, monitor) \
+ MONITOR_MUTEX_INC_LOW(mutex, monitor, MONITOR_IS_ON(monitor))
/** Decrement a monitor counter under mutex protection.
Use MONITOR_DEC if appropriate mutex protection already exists.
+@param mutex mutex to acquire and release
@param monitor monitor to be decremented by 1
-@param mutex mutex to acquire and relese */
-# define MONITOR_MUTEX_DEC(mutex, monitor) \
+@param enabled whether the monitor is enabled */
+#define MONITOR_MUTEX_DEC_LOW(mutex, monitor, enabled) \
ut_ad(!mutex_own(mutex)); \
if (MONITOR_IS_ON(monitor)) { \
mutex_enter(mutex); \
@@ -565,13 +574,20 @@ Use MONITOR_DEC if appropriate mutex protection already exists.
} \
mutex_exit(mutex); \
}
+/** Decrement a monitor counter under mutex protection.
+Use MONITOR_DEC if appropriate mutex protection already exists.
+@param mutex mutex to acquire and release
+@param monitor monitor to be decremented by 1 */
+#define MONITOR_MUTEX_DEC(mutex, monitor) \
+ MONITOR_MUTEX_DEC_LOW(mutex, monitor, MONITOR_IS_ON(monitor))
#if defined HAVE_ATOMIC_BUILTINS_64
/** Atomically increment a monitor counter.
Use MONITOR_INC if appropriate mutex protection exists.
-@param monitor monitor to be incremented by 1 */
-# define MONITOR_ATOMIC_INC(monitor) \
- if (MONITOR_IS_ON(monitor)) { \
+@param monitor monitor to be incremented by 1
+@param enabled whether the monitor is enabled */
+# define MONITOR_ATOMIC_INC_LOW(monitor, enabled) \
+ if (enabled) { \
ib_uint64_t value; \
value = os_atomic_increment_uint64( \
(ib_uint64_t*) &MONITOR_VALUE(monitor), 1); \
@@ -584,9 +600,10 @@ Use MONITOR_INC if appropriate mutex protection exists.
/** Atomically decrement a monitor counter.
Use MONITOR_DEC if appropriate mutex protection exists.
-@param monitor monitor to be decremented by 1 */
-# define MONITOR_ATOMIC_DEC(monitor) \
- if (MONITOR_IS_ON(monitor)) { \
+@param monitor monitor to be decremented by 1
+@param enabled whether the monitor is enabled */
+# define MONITOR_ATOMIC_DEC_LOW(monitor, enabled) \
+ if (enabled) { \
ib_uint64_t value; \
value = os_atomic_decrement_uint64( \
(ib_uint64_t*) &MONITOR_VALUE(monitor), 1); \
@@ -617,14 +634,29 @@ srv_mon_free(void);
/** Atomically increment a monitor counter.
Use MONITOR_INC if appropriate mutex protection exists.
-@param monitor monitor to be incremented by 1 */
-# define MONITOR_ATOMIC_INC(monitor) MONITOR_MUTEX_INC(&monitor_mutex, monitor)
+@param monitor monitor to be incremented by 1
+@param enabled whether the monitor is enabled */
+# define MONITOR_ATOMIC_INC_LOW(monitor, enabled) \
+ MONITOR_MUTEX_INC_LOW(&monitor_mutex, monitor, enabled)
/** Atomically decrement a monitor counter.
Use MONITOR_DEC if appropriate mutex protection exists.
-@param monitor monitor to be decremented by 1 */
-# define MONITOR_ATOMIC_DEC(monitor) MONITOR_MUTEX_DEC(&monitor_mutex, monitor)
+@param monitor monitor to be decremented by 1
+@param enabled whether the monitor is enabled */
+# define MONITOR_ATOMIC_DEC_LOW(monitor, enabled) \
+ MONITOR_MUTEX_DEC_LOW(&monitor_mutex, monitor, enabled)
#endif /* HAVE_ATOMIC_BUILTINS_64 */
+/** Atomically increment a monitor counter if it is enabled.
+Use MONITOR_INC if appropriate mutex protection exists.
+@param monitor monitor to be incremented by 1 */
+#define MONITOR_ATOMIC_INC(monitor) \
+ MONITOR_ATOMIC_INC_LOW(monitor, MONITOR_IS_ON(monitor))
+/** Atomically decrement a monitor counter if it is enabled.
+Use MONITOR_DEC if appropriate mutex protection exists.
+@param monitor monitor to be decremented by 1 */
+#define MONITOR_ATOMIC_DEC(monitor) \
+ MONITOR_ATOMIC_DEC_LOW(monitor, MONITOR_IS_ON(monitor))
+
#define MONITOR_DEC(monitor) \
if (MONITOR_IS_ON(monitor)) { \
MONITOR_VALUE(monitor)--; \
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 53098d7e426..064e6c6c30c 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -1,9 +1,9 @@
/*****************************************************************************
-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 Ab. All Rights Reserved.
+Copyright (c) 2013, 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -55,11 +55,10 @@ Created 10/10/1995 Heikki Tuuri
/* Global counters used inside InnoDB. */
struct srv_stats_t {
- typedef ib_counter_t<lsn_t, 1, single_indexer_t> lsn_ctr_1_t;
- typedef ib_counter_t<ulint, 1, single_indexer_t> ulint_ctr_1_t;
- typedef ib_counter_t<lint, 1, single_indexer_t> lint_ctr_1_t;
typedef ib_counter_t<ulint, 64> ulint_ctr_64_t;
- typedef ib_counter_t<ib_int64_t, 1, single_indexer_t> ib_int64_ctr_1_t;
+ typedef simple_counter<lsn_t> lsn_ctr_1_t;
+ typedef simple_counter<ulint> ulint_ctr_1_t;
+ typedef simple_counter<ib_int64_t> ib_int64_ctr_1_t;
/** Count the amount of data written in total (in bytes) */
ulint_ctr_1_t data_written;
@@ -73,8 +72,9 @@ struct srv_stats_t {
/** Amount of data written to the log files in bytes */
lsn_ctr_1_t os_log_written;
- /** Number of writes being done to the log files */
- lint_ctr_1_t os_log_pending_writes;
+ /** Number of writes being done to the log files.
+ Protected by log_sys->write_mutex. */
+ ulint_ctr_1_t os_log_pending_writes;
/** We increase this counter, when we don't have enough
space in the log buffer and have to flush it */
@@ -113,7 +113,7 @@ struct srv_stats_t {
ulint_ctr_1_t n_lock_wait_count;
/** Number of threads currently waiting on database locks */
- lint_ctr_1_t n_lock_wait_current_count;
+ simple_counter<ulint, true> n_lock_wait_current_count;
/** Number of rows read. */
ulint_ctr_64_t n_rows_read;
@@ -614,6 +614,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;
@@ -994,6 +999,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;
@@ -1110,6 +1122,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. */
diff --git a/storage/xtradb/include/srv0start.h b/storage/xtradb/include/srv0start.h
index 963b767f0fb..a60776a4665 100644
--- a/storage/xtradb/include/srv0start.h
+++ b/storage/xtradb/include/srv0start.h
@@ -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 {
diff --git a/storage/xtradb/include/trx0rec.h b/storage/xtradb/include/trx0rec.h
index 359937e3583..a6e202d04e4 100644
--- a/storage/xtradb/include/trx0rec.h
+++ b/storage/xtradb/include/trx0rec.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -212,10 +213,6 @@ UNIV_INTERN
dberr_t
trx_undo_report_row_operation(
/*==========================*/
- ulint flags, /*!< in: if BTR_NO_UNDO_LOG_FLAG bit is
- set, does nothing */
- ulint op_type, /*!< in: TRX_UNDO_INSERT_OP or
- TRX_UNDO_MODIFY_OP */
que_thr_t* thr, /*!< in: query thread */
dict_index_t* index, /*!< in: clustered index */
const dtuple_t* clust_entry, /*!< in: in the case of an insert,
@@ -233,7 +230,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(1,2,8), warn_unused_result));
/******************************************************************//**
Copies an undo record to heap. This function can be called if we know that
the undo log record exists.
@@ -313,10 +310,6 @@ record */
storage fields: used by purge to
free the external storage */
-/* Operation type flags used in trx_undo_report_row_operation */
-#define TRX_UNDO_INSERT_OP 1
-#define TRX_UNDO_MODIFY_OP 2
-
#ifndef UNIV_NONINL
#include "trx0rec.ic"
#endif
diff --git a/storage/xtradb/include/trx0xa.h b/storage/xtradb/include/trx0xa.h
index 7caddfb7ba4..4d5adc68dcd 100644
--- a/storage/xtradb/include/trx0xa.h
+++ b/storage/xtradb/include/trx0xa.h
@@ -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 */
/* @{ */
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 6acb0eec319..f554c50ff83 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -45,10 +45,10 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 6
-#define INNODB_VERSION_BUGFIX 35
+#define INNODB_VERSION_BUGFIX 36
#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
@@ -304,22 +298,12 @@ definitions: */
#endif /* !UNIV_MUST_NOT_INLINE */
-#ifdef _WIN32
-#define UNIV_WORD_SIZE 4
-#elif defined(_WIN64)
-#define UNIV_WORD_SIZE 8
-#else
-/** MySQL config.h generated by GNU autoconf will define SIZEOF_LONG in Posix */
-#define UNIV_WORD_SIZE SIZEOF_LONG
-#endif
+#define UNIV_WORD_SIZE SIZEOF_SIZE_T
/** The following alignment is used in memory allocations in memory heap
management to ensure correct alignment for doubles etc. */
#define UNIV_MEM_ALIGNMENT 8
-/** The following alignment is used in aligning lints etc. */
-#define UNIV_WORD_ALIGNMENT UNIV_WORD_SIZE
-
/*
DATABASE VERSION CONTROL
========================
@@ -448,13 +432,12 @@ the word size of the machine, that is on a 32-bit platform 32 bits, and on a
macro ULINTPF. */
-#ifdef __WIN__
+#ifdef _WIN32
/* Use the integer types and formatting strings defined in Visual Studio. */
-# define UINT32PF "%I32u"
-# define INT64PF "%I64d"
-# define UINT64PF "%I64u"
-# define UINT64PFx "%016I64x"
-# define DBUG_LSN_PF "%llu"
+# define UINT32PF "%u"
+# define INT64PF "%lld"
+# define UINT64PF "%llu"
+# define UINT64PFx "%016llx"
typedef __int64 ib_int64_t;
typedef unsigned __int64 ib_uint64_t;
typedef unsigned __int32 ib_uint32_t;
@@ -464,13 +447,12 @@ typedef unsigned __int32 ib_uint32_t;
# define INT64PF "%" PRId64
# define UINT64PF "%" PRIu64
# define UINT64PFx "%016" PRIx64
-# define DBUG_LSN_PF UINT64PF
typedef int64_t ib_int64_t;
typedef uint64_t ib_uint64_t;
typedef uint32_t ib_uint32_t;
-# endif /* __WIN__ */
+#endif
-# define IB_ID_FMT UINT64PF
+#define IB_ID_FMT UINT64PF
#ifdef _WIN64
typedef unsigned __int64 ulint;
diff --git a/storage/xtradb/include/ut0counter.h b/storage/xtradb/include/ut0counter.h
index 63a133a175d..edc0db3b03d 100644
--- a/storage/xtradb/include/ut0counter.h
+++ b/storage/xtradb/include/ut0counter.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 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
the terms of the GNU General Public License as published by the Free Software
@@ -30,13 +31,7 @@ Created 2012/04/12 by Sunny Bains
#include "univ.i"
#include <string.h>
#include "os0thread.h"
-
-/** CPU cache line size */
-#ifdef __powerpc__
-#define CACHE_LINE_SIZE 128
-#else
-#define CACHE_LINE_SIZE 64
-#endif
+#include "os0sync.h"
/** Default number of slots to use in ib_counter_t */
#define IB_N_SLOTS 64
@@ -44,8 +39,6 @@ Created 2012/04/12 by Sunny Bains
/** Get the offset into the counter array. */
template <typename Type, int N>
struct generic_indexer_t {
- /** Default constructor/destructor should be OK. */
-
/** @return offset within m_counter */
size_t offset(size_t index) const UNIV_NOTHROW {
return(((index % N) + 1) * (CACHE_LINE_SIZE / sizeof(Type)));
@@ -58,8 +51,6 @@ struct generic_indexer_t {
use the thread id. */
template <typename Type, int N>
struct get_sched_indexer_t : public generic_indexer_t<Type, N> {
- /** Default constructor/destructor should be OK. */
-
/* @return result from sched_getcpu(), the thread id if it fails. */
size_t get_rnd_index() const UNIV_NOTHROW {
@@ -76,31 +67,17 @@ struct get_sched_indexer_t : public generic_indexer_t<Type, N> {
/** Use the thread id to index into the counter array. */
template <typename Type, int N>
struct thread_id_indexer_t : public generic_indexer_t<Type, N> {
- /** Default constructor/destructor should are OK. */
-
/* @return a random number, currently we use the thread id. Where
thread id is represented as a pointer, it may not work as
effectively. */
size_t get_rnd_index() const UNIV_NOTHROW {
return((lint) os_thread_get_curr_id());
}
-};
-
-/** For counters wher N=1 */
-template <typename Type, int N=1>
-struct single_indexer_t {
- /** Default constructor/destructor should are OK. */
-
- /** @return offset within m_counter */
- size_t offset(size_t index) const UNIV_NOTHROW {
- ut_ad(N == 1);
- return((CACHE_LINE_SIZE / sizeof(Type)));
- }
- /* @return 1 */
- size_t get_rnd_index() const UNIV_NOTHROW {
- ut_ad(N == 1);
- return(1);
+ /** @return a random offset to the array */
+ size_t get_rnd_offset() const UNIV_NOTHROW
+ {
+ return(generic_indexer_t<Type, N>::offset(get_rnd_index()));
}
};
@@ -112,17 +89,11 @@ template <
typename Type,
int N = IB_N_SLOTS,
template<typename, int> class Indexer = thread_id_indexer_t>
-class ib_counter_t {
-public:
- ib_counter_t() { memset(m_counter, 0x0, sizeof(m_counter)); }
-
+struct MY_ALIGNED(CACHE_LINE_SIZE) ib_counter_t
+{
+#ifdef UNIV_DEBUG
~ib_counter_t()
{
- ut_ad(validate());
- }
-
- bool validate() UNIV_NOTHROW {
-#ifdef UNIV_DEBUG
size_t n = (CACHE_LINE_SIZE / sizeof(Type));
/* Check that we aren't writing outside our defined bounds. */
@@ -131,27 +102,23 @@ public:
ut_ad(m_counter[i + j] == 0);
}
}
-#endif /* UNIV_DEBUG */
- return(true);
}
+#endif /* UNIV_DEBUG */
- /** If you can't use a good index id. Increment by 1. */
+ /** Increment the counter by 1. */
void inc() UNIV_NOTHROW { add(1); }
- /** If you can't use a good index id.
- * @param n - is the amount to increment */
- void add(Type n) UNIV_NOTHROW {
- size_t i = m_policy.offset(m_policy.get_rnd_index());
-
- ut_ad(i < UT_ARR_SIZE(m_counter));
+ /** Increment the counter by 1.
+ @param[in] index a reasonably thread-unique identifier */
+ void inc(size_t index) UNIV_NOTHROW { add(index, 1); }
- m_counter[i] += n;
- }
+ /** Add to the counter.
+ @param[in] n amount to be added */
+ void add(Type n) UNIV_NOTHROW { add(m_policy.get_rnd_offset(), n); }
- /** Use this if you can use a unique indentifier, saves a
- call to get_rnd_index().
- @param i - index into a slot
- @param n - amount to increment */
+ /** Add to the counter.
+ @param[in] index a reasonably thread-unique identifier
+ @param[in] n amount to be added */
void add(size_t index, Type n) UNIV_NOTHROW {
size_t i = m_policy.offset(index);
@@ -160,31 +127,6 @@ public:
m_counter[i] += n;
}
- /** If you can't use a good index id. Decrement by 1. */
- void dec() UNIV_NOTHROW { sub(1); }
-
- /** If you can't use a good index id.
- * @param - n is the amount to decrement */
- void sub(Type n) UNIV_NOTHROW {
- size_t i = m_policy.offset(m_policy.get_rnd_index());
-
- ut_ad(i < UT_ARR_SIZE(m_counter));
-
- m_counter[i] -= n;
- }
-
- /** Use this if you can use a unique indentifier, saves a
- call to get_rnd_index().
- @param i - index into a slot
- @param n - amount to decrement */
- void sub(size_t index, Type n) UNIV_NOTHROW {
- size_t i = m_policy.offset(index);
-
- ut_ad(i < UT_ARR_SIZE(m_counter));
-
- m_counter[i] -= n;
- }
-
/* @return total value - not 100% accurate, since it is not atomic. */
operator Type() const UNIV_NOTHROW {
Type total = 0;
diff --git a/storage/xtradb/include/ut0rnd.ic b/storage/xtradb/include/ut0rnd.ic
index 024c59e553b..987dfac03c1 100644
--- a/storage/xtradb/include/ut0rnd.ic
+++ b/storage/xtradb/include/ut0rnd.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2009, 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
the terms of the GNU General Public License as published by the Free Software
@@ -237,16 +238,22 @@ ut_fold_binary(
switch (len & 0x7) {
case 7:
fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ /* fall through */
case 6:
fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ /* fall through */
case 5:
fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ /* fall through */
case 4:
fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ /* fall through */
case 3:
fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ /* fall through */
case 2:
fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
+ /* fall through */
case 1:
fold = ut_fold_ulint_pair(fold, (ulint)(*str++));
}
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index c09a3ac2550..71d09bdb8c8 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -5227,13 +5227,11 @@ lock_rec_unlock(
trx_mutex_exit(trx);
stmt = innobase_get_stmt(trx->mysql_thd, &stmt_len);
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Error: unlock row could not"
- " find a %lu mode lock on the record\n",
- (ulong) lock_mode);
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: current statement: %.*s\n",
+
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "unlock row could not find a %u mode lock on the record;"
+ " statement=%.*s",
+ lock_mode,
(int) stmt_len, stmt);
return;
diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc
index 7d7670e9224..92be74d1412 100644
--- a/storage/xtradb/lock/lock0wait.cc
+++ b/storage/xtradb/lock/lock0wait.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2014, 2017, MariaDB Corporation.
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
@@ -270,6 +271,9 @@ lock_wait_suspend_thread(
slot = lock_wait_table_reserve_slot(thr, lock_wait_timeout);
+ lock_wait_mutex_exit();
+ trx_mutex_exit(trx);
+
if (thr->lock_state == QUE_THR_LOCK_ROW) {
srv_stats.n_lock_wait_count.inc();
srv_stats.n_lock_wait_current_count.inc();
@@ -281,19 +285,21 @@ lock_wait_suspend_thread(
}
}
- lock_wait_mutex_exit();
- trx_mutex_exit(trx);
-
ulint lock_type = ULINT_UNDEFINED;
- lock_mutex_enter();
-
+ /* The wait_lock can be cleared by another thread when the
+ lock is released. But the wait can only be initiated by the
+ current thread which owns the transaction. Only acquire the
+ mutex if the wait_lock is still active. */
if (const lock_t* wait_lock = trx->lock.wait_lock) {
- lock_type = lock_get_type_low(wait_lock);
+ lock_mutex_enter();
+ wait_lock = trx->lock.wait_lock;
+ if (wait_lock) {
+ lock_type = lock_get_type_low(wait_lock);
+ }
+ lock_mutex_exit();
}
- lock_mutex_exit();
-
had_dict_lock = trx->dict_operation_lock_mode;
switch (had_dict_lock) {
diff --git a/storage/xtradb/log/log0log.cc b/storage/xtradb/log/log0log.cc
index 5ef9203ce72..47261aa633a 100644
--- a/storage/xtradb/log/log0log.cc
+++ b/storage/xtradb/log/log0log.cc
@@ -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,
diff --git a/storage/xtradb/log/log0online.cc b/storage/xtradb/log/log0online.cc
index 764c9e0c52f..ee5136376fa 100644
--- a/storage/xtradb/log/log0online.cc
+++ b/storage/xtradb/log/log0online.cc
@@ -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);
@@ -1440,6 +1453,7 @@ log_online_setup_bitmap_file_range(
if (UNIV_UNLIKELY(array_pos >= bitmap_files->count)) {
log_online_diagnose_inconsistent_dir(bitmap_files);
+ os_file_closedir(bitmap_dir);
return FALSE;
}
@@ -1542,10 +1556,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 +1643,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 +1661,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 +1700,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 +1757,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 +1868,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++) {
diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc
index afb8b7f00b8..6f76d151af3 100644
--- a/storage/xtradb/log/log0recv.cc
+++ b/storage/xtradb/log/log0recv.cc
@@ -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. */
@@ -1792,7 +1794,7 @@ recv_recover_page_func(
}
DBUG_PRINT("ib_log",
- ("apply " DBUG_LSN_PF ": %u len %u "
+ ("apply " LSN_PF ": %u len %u "
"page %u:%u", recv->start_lsn,
(unsigned) recv->type,
(unsigned) recv->len,
@@ -2440,7 +2442,7 @@ loop:
recv_sys->recovered_lsn = new_recovered_lsn;
DBUG_PRINT("ib_log",
- ("scan " DBUG_LSN_PF ": log rec %u len %u "
+ ("scan " LSN_PF ": log rec %u len %u "
"page %u:%u", old_lsn,
(unsigned) type, (unsigned) len,
(unsigned) space, (unsigned) page_no));
@@ -2531,7 +2533,7 @@ loop:
#endif /* UNIV_LOG_DEBUG */
DBUG_PRINT("ib_log",
- ("scan " DBUG_LSN_PF ": multi-log rec %u "
+ ("scan " LSN_PF ": multi-log rec %u "
"len %u page %u:%u",
recv_sys->recovered_lsn,
(unsigned) type, (unsigned) len,
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 2a651a84a1a..cd0e8b8db60 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -1,8 +1,8 @@
/***********************************************************************
-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. All Rights Reserved.
+Copyright (c) 2013, 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted
by Percona Inc.. Those modifications are
@@ -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
@@ -190,7 +192,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
@@ -297,21 +299,6 @@ UNIV_INTERN time_t os_last_printout;
UNIV_INTERN ibool os_has_said_disk_full = FALSE;
-#if !defined(UNIV_HOTBACKUP) \
- && (!defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8)
-/** The mutex protecting the following counts of pending I/O operations */
-static os_ib_mutex_t os_file_count_mutex;
-#endif /* !UNIV_HOTBACKUP && (!HAVE_ATOMIC_BUILTINS || UNIV_WORD_SIZE < 8) */
-
-/** Number of pending os_file_pread() operations */
-UNIV_INTERN ulint os_file_n_pending_preads = 0;
-/** Number of pending os_file_pwrite() operations */
-UNIV_INTERN ulint os_file_n_pending_pwrites = 0;
-/** Number of pending write operations */
-UNIV_INTERN ulint os_n_pending_writes = 0;
-/** Number of pending read operations */
-UNIV_INTERN ulint os_n_pending_reads = 0;
-
#ifdef UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
/**********************************************************************//**
@@ -893,10 +880,6 @@ void
os_io_init_simple(void)
/*===================*/
{
-#if !defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8
- os_file_count_mutex = os_mutex_create();
-#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD_SIZE < 8 */
-
for (ulint i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) {
os_file_seek_mutexes[i] = os_mutex_create();
}
@@ -1457,7 +1440,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
@@ -1471,7 +1454,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__
@@ -1479,7 +1462,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));
@@ -1496,8 +1478,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) {
@@ -1521,11 +1503,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
@@ -1533,11 +1515,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);
if (create_mode != OS_FILE_OPEN && create_mode != OS_FILE_OPEN_RAW)
WAIT_ALLOW_WRITES();
@@ -1582,19 +1563,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);
}
@@ -1603,11 +1584,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 */
@@ -1719,7 +1700,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
@@ -1735,24 +1716,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__ */
@@ -1803,7 +1785,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;
@@ -1828,8 +1811,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
@@ -1866,11 +1849,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
@@ -1889,19 +1872,17 @@ os_file_create_func(
*success = TRUE;
retry = FALSE;
if (srv_use_native_aio && ((attributes & FILE_FLAG_OVERLAPPED) != 0)) {
- ut_a(CreateIoCompletionPort(file, completion_port, 0, 0));
+ ut_a(CreateIoCompletionPort(file.m_file, completion_port, 0, 0));
}
}
} while (retry);
- if (file != INVALID_HANDLE_VALUE
- && srv_use_atomic_writes
- && type == OS_DATA_FILE &&
- !os_file_set_atomic_writes(name, file)) {
- CloseHandle(file);
+ if (srv_use_atomic_writes && type == OS_DATA_FILE &&
+ !os_file_set_atomic_writes(name, file.m_file)) {
+ CloseHandle(file.m_file);
*success = FALSE;
- file = INVALID_HANDLE_VALUE;
+ file.m_file = INVALID_HANDLE_VALUE;
}
#else /* __WIN__ */
@@ -1947,7 +1928,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);
@@ -1967,9 +1949,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
@@ -1993,14 +1975,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) {
@@ -2012,7 +1995,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);
}
@@ -2023,17 +2006,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__ */
@@ -2265,8 +2249,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 */
{
@@ -2276,10 +2260,10 @@ os_file_close_no_error_handling(
ret = CloseHandle(file);
if (ret) {
- return(TRUE);
+ return(true);
}
- return(FALSE);
+ return(false);
#else
int ret;
@@ -2287,10 +2271,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__ */
}
@@ -2301,14 +2358,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);
@@ -2318,7 +2375,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__ */
}
@@ -2331,7 +2389,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;
@@ -2343,7 +2401,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);
@@ -2423,8 +2481,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 */
{
@@ -2603,10 +2661,6 @@ os_file_pread(
trx_t* trx)
{
off_t offs;
-#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
- ssize_t n_bytes;
- ssize_t n_read;
-#endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
ulint sec;
ulint ms;
ib_uint64_t start_time;
@@ -2636,22 +2690,16 @@ os_file_pread(
} else {
start_time = 0;
}
-#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
-#if defined(HAVE_ATOMIC_BUILTINS) && UNIV_WORD_SIZE == 8
- (void) os_atomic_increment_ulint(&os_n_pending_reads, 1);
- (void) os_atomic_increment_ulint(&os_file_n_pending_preads, 1);
- MONITOR_ATOMIC_INC(MONITOR_OS_PENDING_READS);
-#else
- os_mutex_enter(os_file_count_mutex);
- os_file_n_pending_preads++;
- os_n_pending_reads++;
- MONITOR_INC(MONITOR_OS_PENDING_READS);
- os_mutex_exit(os_file_count_mutex);
-#endif /* HAVE_ATOMIC_BUILTINS && UNIV_WORD == 8 */
+
+ const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_READS);
+#ifdef HAVE_PREAD
+ MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_READS, monitor);
+
+ ssize_t n_bytes;
/* Handle partial reads and signal interruptions correctly */
for (n_bytes = 0; n_bytes < (ssize_t) n; ) {
- n_read = pread(file, buf, (ssize_t)n - n_bytes, offs);
+ ssize_t n_read = pread(file, buf, (ssize_t)n - n_bytes, offs);
if (n_read > 0) {
n_bytes += n_read;
offs += n_read;
@@ -2663,17 +2711,7 @@ os_file_pread(
}
}
-#if defined(HAVE_ATOMIC_BUILTINS) && UNIV_WORD_SIZE == 8
- (void) os_atomic_decrement_ulint(&os_n_pending_reads, 1);
- (void) os_atomic_decrement_ulint(&os_file_n_pending_preads, 1);
- MONITOR_ATOMIC_DEC(MONITOR_OS_PENDING_READS);
-#else
- os_mutex_enter(os_file_count_mutex);
- os_file_n_pending_preads--;
- os_n_pending_reads--;
- MONITOR_DEC(MONITOR_OS_PENDING_READS);
- os_mutex_exit(os_file_count_mutex);
-#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD == 8 */
+ MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor);
if (UNIV_UNLIKELY(start_time != 0))
{
@@ -2692,15 +2730,7 @@ os_file_pread(
ulint i;
#endif /* !UNIV_HOTBACKUP */
-#if defined(HAVE_ATOMIC_BUILTINS) && UNIV_WORD_SIZE == 8
- (void) os_atomic_increment_ulint(&os_n_pending_reads, 1);
- MONITOR_ATOMIC_INC(MONITOR_OS_PENDING_READS);
-#else
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads++;
- MONITOR_INC(MONITOR_OS_PENDING_READS);
- os_mutex_exit(os_file_count_mutex);
-#endif /* HAVE_ATOMIC_BUILTINS && UNIV_WORD == 8 */
+ MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_READS, monitor);
#ifndef UNIV_HOTBACKUP
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
@@ -2730,15 +2760,7 @@ os_file_pread(
os_mutex_exit(os_file_seek_mutexes[i]);
#endif /* !UNIV_HOTBACKUP */
-#if defined(HAVE_ATOMIC_BUILTINS) && UNIV_WORD_SIZE == 8
- (void) os_atomic_decrement_ulint(&os_n_pending_reads, 1);
- MONITOR_ATOIC_DEC(MONITOR_OS_PENDING_READS);
-#else
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- MONITOR_DEC(MONITOR_OS_PENDING_READS);
- os_mutex_exit(os_file_count_mutex);
-#endif /* HAVE_ATOMIC_BUILTINS && UNIV_WORD_SIZE == 8 */
+ MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor);
if (UNIV_UNLIKELY(start_time != 0)
{
@@ -2784,18 +2806,9 @@ os_file_pwrite(
os_n_file_writes++;
-#if defined(HAVE_PWRITE) && !defined(HAVE_BROKEN_PREAD)
-#if !defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8
- os_mutex_enter(os_file_count_mutex);
- os_file_n_pending_pwrites++;
- os_n_pending_writes++;
- MONITOR_INC(MONITOR_OS_PENDING_WRITES);
- os_mutex_exit(os_file_count_mutex);
-#else
- (void) os_atomic_increment_ulint(&os_n_pending_writes, 1);
- (void) os_atomic_increment_ulint(&os_file_n_pending_pwrites, 1);
- MONITOR_ATOMIC_INC(MONITOR_OS_PENDING_WRITES);
-#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD < 8 */
+ const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_WRITES);
+#ifdef HAVE_PWRITE
+ MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_WRITES, monitor);
/* Handle partial writes and signal interruptions correctly */
for (ret = 0; ret < (ssize_t) n; ) {
@@ -2814,17 +2827,7 @@ os_file_pwrite(
}
}
-#if !defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8
- os_mutex_enter(os_file_count_mutex);
- os_file_n_pending_pwrites--;
- os_n_pending_writes--;
- MONITOR_DEC(MONITOR_OS_PENDING_WRITES);
- os_mutex_exit(os_file_count_mutex);
-#else
- (void) os_atomic_decrement_ulint(&os_n_pending_writes, 1);
- (void) os_atomic_decrement_ulint(&os_file_n_pending_pwrites, 1);
- MONITOR_ATOMIC_DEC(MONITOR_OS_PENDING_WRITES);
-#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD < 8 */
+ MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_WRITES, monitor);
return(ret);
#else
@@ -2834,10 +2837,7 @@ os_file_pwrite(
ulint i;
# endif /* !UNIV_HOTBACKUP */
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes++;
- MONITOR_INC(MONITOR_OS_PENDING_WRITES);
- os_mutex_exit(os_file_count_mutex);
+ MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_WRITES, monitor);
# ifndef UNIV_HOTBACKUP
/* Protect the seek / write operation with a mutex */
@@ -2871,14 +2871,10 @@ func_exit:
os_mutex_exit(os_file_seek_mutexes[i]);
# endif /* !UNIV_HOTBACKUP */
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes--;
- MONITOR_DEC(MONITOR_OS_PENDING_WRITES);
- os_mutex_exit(os_file_count_mutex);
-
+ MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_WRITES, monitor);
return(ret);
}
-#endif /* !UNIV_HOTBACKUP */
+#endif /* HAVE_PWRITE */
}
#endif
@@ -2910,15 +2906,13 @@ os_file_read_func(
os_n_file_reads++;
os_bytes_read_since_printout += n;
+ const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_READS);
try_again:
ut_ad(buf);
ut_ad(n > 0);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads++;
- MONITOR_INC(MONITOR_OS_PENDING_READS);
- os_mutex_exit(os_file_count_mutex);
+ MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_READS, monitor);
memset (&overlapped, 0, sizeof (overlapped));
overlapped.Offset = (DWORD)(offset & 0xFFFFFFFF);
@@ -2931,10 +2925,7 @@ try_again:
else if(GetLastError() == ERROR_IO_PENDING) {
ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
}
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- MONITOR_DEC(MONITOR_OS_PENDING_READS);
- os_mutex_exit(os_file_count_mutex);
+ MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor);
if (ret && len == n) {
return(TRUE);
@@ -3018,15 +3009,13 @@ os_file_read_no_error_handling_func(
os_n_file_reads++;
os_bytes_read_since_printout += n;
+ const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_READS);
try_again:
ut_ad(buf);
ut_ad(n > 0);
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads++;
- MONITOR_INC(MONITOR_OS_PENDING_READS);
- os_mutex_exit(os_file_count_mutex);
+ MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_READS, monitor);
memset (&overlapped, 0, sizeof (overlapped));
overlapped.Offset = (DWORD)(offset & 0xFFFFFFFF);
@@ -3039,10 +3028,7 @@ try_again:
else if(GetLastError() == ERROR_IO_PENDING) {
ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
}
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- MONITOR_DEC(MONITOR_OS_PENDING_READS);
- os_mutex_exit(os_file_count_mutex);
+ MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor);
if (ret && len == n) {
return(TRUE);
@@ -3136,12 +3122,10 @@ os_file_write_func(
ut_ad(buf);
ut_ad(n > 0);
+ const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_WRITES);
retry:
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes++;
- MONITOR_INC(MONITOR_OS_PENDING_WRITES);
- os_mutex_exit(os_file_count_mutex);
+ MONITOR_ATOMIC_INC_LOW(MONITOR_OS_PENDING_WRITES, monitor);
memset (&overlapped, 0, sizeof (overlapped));
overlapped.Offset = (DWORD)(offset & 0xFFFFFFFF);
@@ -3156,10 +3140,7 @@ retry:
ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
}
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes--;
- MONITOR_DEC(MONITOR_OS_PENDING_WRITES);
- os_mutex_exit(os_file_count_mutex);
+ MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_WRITES, monitor);
if (ret && len == n) {
@@ -4254,10 +4235,6 @@ os_aio_free(void)
}
}
-#if !defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8
- os_mutex_free(os_file_count_mutex);
-#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD_SIZE < 8 */
-
for (ulint i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) {
os_mutex_free(os_file_seek_mutexes[i]);
}
@@ -4438,7 +4415,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
@@ -4561,10 +4538,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;
@@ -4798,7 +4775,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 */
@@ -4821,7 +4798,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);
@@ -4843,7 +4819,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);
@@ -4919,7 +4895,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;
@@ -4941,7 +4917,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)
@@ -5061,7 +5037,6 @@ os_aio_windows_handle(
break;
}
}
-
*message1 = slot->message1;
*message2 = slot->message2;
@@ -5088,11 +5063,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, 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:
@@ -5347,12 +5322,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);
@@ -5579,12 +5556,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 */
@@ -5933,19 +5909,24 @@ os_aio_print(
time_elapsed = 0.001 + difftime(current_time, os_last_printout);
fprintf(file,
- "Pending flushes (fsync) log: %lu; buffer pool: %lu\n"
- "%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n",
- (ulong) fil_n_pending_log_flushes,
- (ulong) fil_n_pending_tablespace_flushes,
- (ulong) os_n_file_reads,
- (ulong) os_n_file_writes,
- (ulong) os_n_fsyncs);
-
- if (os_file_n_pending_preads != 0 || os_file_n_pending_pwrites != 0) {
+ "Pending flushes (fsync) log: " ULINTPF
+ "; buffer pool: " ULINTPF "\n"
+ ULINTPF " OS file reads, "
+ ULINTPF " OS file writes, "
+ ULINTPF " OS fsyncs\n",
+ fil_n_pending_log_flushes,
+ fil_n_pending_tablespace_flushes,
+ os_n_file_reads,
+ os_n_file_writes,
+ os_n_fsyncs);
+
+ const ulint n_reads = ulint(MONITOR_VALUE(MONITOR_OS_PENDING_READS));
+ const ulint n_writes = ulint(MONITOR_VALUE(MONITOR_OS_PENDING_WRITES));
+
+ if (n_reads != 0 || n_writes != 0) {
fprintf(file,
- "%lu pending preads, %lu pending pwrites\n",
- (ulong) os_file_n_pending_preads,
- (ulong) os_file_n_pending_pwrites);
+ ULINTPF " pending reads, " ULINTPF " pending writes\n",
+ n_reads, n_writes);
}
if (os_n_file_reads == os_n_file_reads_old) {
diff --git a/storage/xtradb/pars/pars0opt.cc b/storage/xtradb/pars/pars0opt.cc
index cbed2b39eeb..5a7e1861d74 100644
--- a/storage/xtradb/pars/pars0opt.cc
+++ b/storage/xtradb/pars/pars0opt.cc
@@ -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) {
diff --git a/storage/xtradb/pars/pars0pars.cc b/storage/xtradb/pars/pars0pars.cc
index b116357c5b9..ea65d16e9dc 100644
--- a/storage/xtradb/pars/pars0pars.cc
+++ b/storage/xtradb/pars/pars0pars.cc
@@ -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;
diff --git a/storage/xtradb/rem/rem0rec.cc b/storage/xtradb/rem/rem0rec.cc
index 8daece64b68..148030a5a95 100644
--- a/storage/xtradb/rem/rem0rec.cc
+++ b/storage/xtradb/rem/rem0rec.cc
@@ -1293,8 +1293,10 @@ rec_convert_dtuple_to_rec_comp(
}
}
- memcpy(end, dfield_get_data(field), len);
- end += len;
+ if (len) {
+ memcpy(end, dfield_get_data(field), len);
+ end += len;
+ }
}
}
diff --git a/storage/xtradb/row/row0ftsort.cc b/storage/xtradb/row/row0ftsort.cc
index 134127c6adf..734b4f8b2f7 100644
--- a/storage/xtradb/row/row0ftsort.cc
+++ b/storage/xtradb/row/row0ftsort.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2010, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -228,9 +229,6 @@ row_fts_psort_info_init(
each parallel sort thread. Each "sort bucket" holds records for
a particular "FTS index partition" */
for (j = 0; j < fts_sort_pll_degree; j++) {
-
- UT_LIST_INIT(psort_info[j].fts_doc_list);
-
for (i = 0; i < FTS_NUM_AUX_INDEX; i++) {
psort_info[j].merge_file[i] =
@@ -1251,10 +1249,9 @@ row_fts_build_sel_tree_level(
int child_left;
int child_right;
ulint i;
- ulint num_item;
+ ulint num_item = ulint(1) << level;
- start = static_cast<ulint>((1 << level) - 1);
- num_item = static_cast<ulint>(1 << level);
+ start = num_item - 1;
for (i = 0; i < num_item; i++) {
child_left = sel_tree[(start + i) * 2 + 1];
@@ -1323,7 +1320,7 @@ row_fts_build_sel_tree(
treelevel++;
}
- start = (1 << treelevel) - 1;
+ start = (ulint(1) << treelevel) - 1;
for (i = 0; i < (int) fts_sort_pll_degree; i++) {
sel_tree[i + start] = i;
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index e1fef3d3716..bc7b5206a64 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2017, MariaDB Corporation.
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
@@ -573,8 +574,8 @@ AbstractCallback::init(
} else if (!is_compressed_table() && m_page_size != UNIV_PAGE_SIZE) {
ib_logf(IB_LOG_LEVEL_ERROR,
- "Page size %lu of ibd file is not the same "
- "as the server page size %lu",
+ "Page size " ULINTPF " of ibd file is not the same "
+ "as the server page size " ULINTPF,
m_page_size, UNIV_PAGE_SIZE);
return(DB_CORRUPTION);
@@ -583,8 +584,8 @@ AbstractCallback::init(
ib_logf(IB_LOG_LEVEL_ERROR,
"File size " UINT64PF " is not a multiple "
- "of the page size %lu",
- (ib_uint64_t) file_size, (ulong) m_page_size);
+ "of the page size " ULINTPF,
+ (ib_uint64_t) file_size, m_page_size);
return(DB_CORRUPTION);
}
@@ -725,8 +726,8 @@ FetchIndexRootPages::operator() (
if (block->page.offset * m_page_size != offset) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Page offset doesn't match file offset: "
- "page offset: %lu, file offset: %lu",
- (ulint) block->page.offset,
+ "page offset: %u, file offset: " ULINTPF,
+ block->page.offset,
(ulint) (offset / m_page_size));
err = DB_CORRUPTION;
@@ -1159,10 +1160,9 @@ row_import::match_index_columns(
ib_errf(thd, IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
- "Index field count %lu doesn't match"
- " tablespace metadata file value %lu",
- (ulong) index->n_fields,
- (ulong) cfg_index->m_n_fields);
+ "Index field count %u doesn't match"
+ " tablespace metadata file value " ULINTPF,
+ index->n_fields, cfg_index->m_n_fields);
return(DB_ERROR);
}
@@ -1179,34 +1179,31 @@ row_import::match_index_columns(
ER_TABLE_SCHEMA_MISMATCH,
"Index field name %s doesn't match"
" tablespace metadata field name %s"
- " for field position %lu",
- field->name, cfg_field->name, (ulong) i);
+ " for field position " ULINTPF,
+ field->name, cfg_field->name, i);
err = DB_ERROR;
}
if (cfg_field->prefix_len != field->prefix_len) {
ib_errf(thd, IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Index %s field %s prefix len %lu"
- " doesn't match metadata file value"
- " %lu",
- index->name, field->name,
- (ulong) field->prefix_len,
- (ulong) cfg_field->prefix_len);
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Index %s field %s prefix len %u"
+ " doesn't match metadata file value %u",
+ index->name, field->name,
+ field->prefix_len, cfg_field->prefix_len);
err = DB_ERROR;
}
if (cfg_field->fixed_len != field->fixed_len) {
ib_errf(thd, IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Index %s field %s fixed len %lu"
- " doesn't match metadata file value"
- " %lu",
- index->name, field->name,
- (ulong) field->fixed_len,
- (ulong) cfg_field->fixed_len);
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Index %s field %s fixed len %u"
+ " doesn't match metadata file value %u",
+ index->name, field->name,
+ field->fixed_len,
+ cfg_field->fixed_len);
err = DB_ERROR;
}
@@ -1248,12 +1245,11 @@ row_import::match_table_columns(
} else if (cfg_col_index != col->ind) {
ib_errf(thd, IB_LOG_LEVEL_ERROR,
- ER_TABLE_SCHEMA_MISMATCH,
- "Column %s ordinal value mismatch, it's at "
- "%lu in the table and %lu in the tablespace "
- "meta-data file",
- col_name,
- (ulong) col->ind, (ulong) cfg_col_index);
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Column %s ordinal value mismatch, it's at %u"
+ " in the table and " ULINTPF
+ " in the tablespace meta-data file",
+ col_name, col->ind, cfg_col_index);
err = DB_ERROR;
} else {
@@ -1335,23 +1331,20 @@ row_import::match_schema(
THD* thd) UNIV_NOTHROW
{
/* Do some simple checks. */
- const unsigned relevant_flags = m_flags & ~DICT_TF_MASK_DATA_DIR;
- const unsigned relevant_table_flags
- = m_table->flags & ~DICT_TF_MASK_DATA_DIR;
- if (relevant_flags != relevant_table_flags) {
+ if ((m_table->flags ^ m_flags) & ~DICT_TF_MASK_DATA_DIR) {
ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
- "Table flags don't match, server table has 0x%x "
- "and the meta-data file has 0x%x",
- relevant_table_flags, relevant_flags);
+ "Table flags don't match, server table has 0x%x"
+ " and the meta-data file has 0x%lx",
+ m_table->flags, ulong(m_flags));
return(DB_ERROR);
} else if (m_table->n_cols != m_n_cols) {
ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
- "Number of columns don't match, table has %lu "
- "columns but the tablespace meta-data file has "
- "%lu columns",
- (ulong) m_table->n_cols, (ulong) m_n_cols);
+ "Number of columns don't match, table has %u "
+ "columns but the tablespace meta-data file has "
+ ULINTPF " columns",
+ m_table->n_cols, m_n_cols);
return(DB_ERROR);
} else if (UT_LIST_GET_LEN(m_table->indexes) != m_n_indexes) {
@@ -1361,11 +1354,10 @@ row_import::match_schema(
table matching the IMPORT definition. */
ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
- "Number of indexes don't match, table has %lu "
- "indexes but the tablespace meta-data file has "
- "%lu indexes",
- (ulong) UT_LIST_GET_LEN(m_table->indexes),
- (ulong) m_n_indexes);
+ "Number of indexes don't match, table has " ULINTPF
+ " indexes but the tablespace meta-data file has "
+ ULINTPF " indexes",
+ UT_LIST_GET_LEN(m_table->indexes), m_n_indexes);
return(DB_ERROR);
}
@@ -1441,8 +1433,8 @@ row_import::set_root_by_heuristic() UNIV_NOTHROW
table_name, sizeof(table_name), m_table->name, FALSE);
ib_logf(IB_LOG_LEVEL_WARN,
- "Table %s should have %lu indexes but the tablespace "
- "has %lu indexes",
+ "Table %s should have " ULINTPF
+ " indexes but the tablespace has " ULINTPF " indexes",
table_name,
UT_LIST_GET_LEN(m_table->indexes),
m_n_indexes);
@@ -1680,9 +1672,10 @@ PageConverter::adjust_cluster_index_blob_column(
ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
ER_INNODB_INDEX_CORRUPT,
- "Externally stored column(%lu) has a reference "
- "length of %lu in the cluster index %s",
- (ulong) i, (ulong) len, index_name);
+ "Externally stored column(" ULINTPF
+ ") has a reference length of " ULINTPF
+ " in the cluster index %s",
+ i, len, index_name);
return(DB_CORRUPTION);
}
@@ -2025,6 +2018,7 @@ PageConverter::update_page(
case FIL_PAGE_TYPE_XDES:
err = set_current_xdes(
buf_block_get_page_no(block), get_frame(block));
+ /* fall through */
case FIL_PAGE_INODE:
case FIL_PAGE_TYPE_TRX_SYS:
case FIL_PAGE_IBUF_FREE_LIST:
@@ -2043,7 +2037,8 @@ PageConverter::update_page(
return(err);
}
- ib_logf(IB_LOG_LEVEL_WARN, "Unknown page type (%lu)", page_type);
+ ib_logf(IB_LOG_LEVEL_WARN, "Unknown page type (" ULINTPF ")",
+ page_type);
return(DB_CORRUPTION);
}
@@ -2077,7 +2072,8 @@ PageConverter::validate(
if (checksum != 0) {
/* Checksum check passed in buf_page_is_corrupted(). */
ib_logf(IB_LOG_LEVEL_WARN,
- "%s: Page %lu checksum %lu should be zero.",
+ "%s: Page %lu checksum " ULINTPF
+ " should be zero.",
m_filepath, (ulong) (offset / m_page_size),
checksum);
}
@@ -2391,11 +2387,10 @@ row_import_adjust_root_pages_of_secondary_indexes(
ib_errf(trx->mysql_thd,
IB_LOG_LEVEL_WARN,
ER_INNODB_INDEX_CORRUPT,
- "Index '%s' contains %lu entries, "
- "should be %lu, you should recreate "
+ "Index '%s' contains " ULINTPF " entries, "
+ "should be " ULINTPF ", you should recreate "
"this index.", index_name,
- (ulong) purge.get_n_rows(),
- (ulong) n_rows_in_table);
+ purge.get_n_rows(), n_rows_in_table);
index->type |= DICT_CORRUPT;
@@ -2746,7 +2741,7 @@ row_import_read_index_data(
if (len > OS_FILE_MAX_PATH) {
ib_errf(thd, IB_LOG_LEVEL_ERROR,
ER_INNODB_INDEX_CORRUPT,
- "Index name length (%lu) is too long, "
+ "Index name length (" ULINTPF ") is too long, "
"the meta-data is corrupt", len);
return(DB_CORRUPTION);
@@ -2827,8 +2822,8 @@ row_import_read_indexes(
} else if (cfg->m_n_indexes > 1024) {
// FIXME: What is the upper limit? */
ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- "Number of indexes in meta-data file is too high: %lu",
- (ulong) cfg->m_n_indexes);
+ "Number of indexes in meta-data file is too high: "
+ ULINTPF, cfg->m_n_indexes);
cfg->m_n_indexes = 0;
return(DB_CORRUPTION);
@@ -2926,8 +2921,8 @@ row_import_read_columns(
if (len == 0 || len > 128) {
ib_errf(thd, IB_LOG_LEVEL_ERROR,
ER_IO_READ_ERROR,
- "Column name length %lu, is invalid",
- (ulong) len);
+ "Column name length " ULINTPF ", is invalid",
+ len);
return(DB_CORRUPTION);
}
@@ -3098,8 +3093,9 @@ row_import_read_v1(
ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
"Tablespace to be imported has a different "
"page size than this server. Server page size "
- "is %lu, whereas tablespace page size is %lu",
- UNIV_PAGE_SIZE, (ulong) cfg->m_page_size);
+ "is " ULINTPF ", whereas tablespace page size is "
+ ULINTPF,
+ UNIV_PAGE_SIZE, cfg->m_page_size);
return(DB_ERROR);
}
@@ -3164,8 +3160,8 @@ row_import_read_meta_data(
return(row_import_read_v1(file, thd, &cfg));
default:
ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
- "Unsupported meta-data version number (%lu), "
- "file ignored", (ulong) cfg.m_version);
+ "Unsupported meta-data version number (" ULINTPF "), "
+ "file ignored", cfg.m_version);
}
return(DB_ERROR);
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index fdd9625c37e..2d6b57221bd 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -2166,14 +2167,10 @@ for a clustered index!
@retval DB_SUCCESS if no error
@retval DB_DUPLICATE_KEY if error,
@retval DB_LOCK_WAIT if we have to wait for a lock on a possible duplicate
-record
-@retval DB_SUCCESS_LOCKED_REC if an exact match of the record was found
-in online table rebuild (flags & (BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG)) */
+record */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
row_ins_duplicate_error_in_clust(
-/*=============================*/
- ulint flags, /*!< in: undo logging and locking flags */
btr_cur_t* cursor, /*!< in: B-tree cursor */
const dtuple_t* entry, /*!< in: entry to insert */
que_thr_t* thr, /*!< in: query thread */
@@ -2448,7 +2445,7 @@ row_ins_clust_index_entry_low(
DB_LOCK_WAIT */
err = row_ins_duplicate_error_in_clust(
- flags, &cursor, entry, thr, &mtr);
+ &cursor, entry, thr, &mtr);
}
if (err != DB_SUCCESS) {
diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc
index 3c5d5773aee..874c0901451 100644
--- a/storage/xtradb/row/row0log.cc
+++ b/storage/xtradb/row/row0log.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -363,9 +364,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 +480,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) {
@@ -1872,6 +1873,7 @@ row_log_table_apply_update(
When applying the subsequent ROW_T_DELETE, no matching
record will be found. */
+ /* fall through */
case DB_SUCCESS:
ut_ad(row != NULL);
break;
@@ -2609,11 +2611,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 +3437,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);
diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc
index bcc37fb530c..fb65507e37d 100644
--- a/storage/xtradb/row/row0merge.cc
+++ b/storage/xtradb/row/row0merge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2014, 2017, MariaDB Corporation.
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
@@ -96,7 +96,8 @@ row_merge_tuple_print(
}
ut_print_buf(f, dfield_get_data(field), len);
if (len != field_len) {
- fprintf(f, " (total %lu bytes)", field_len);
+ fprintf(f, " (total " ULINTPF " bytes)",
+ field_len);
}
}
}
@@ -789,9 +790,9 @@ row_merge_buf_write(
ut_ad(b < &block[srv_sort_buf_size]);
#ifdef UNIV_DEBUG
if (row_merge_print_write) {
- fprintf(stderr, "row_merge_buf_write %p,%d,%lu %lu",
- (void*) b, of->fd, (ulong) of->offset,
- (ulong) i);
+ fprintf(stderr, "row_merge_buf_write %p,%d,"
+ ULINTPF " " ULINTPF,
+ (void*) b, of->fd, of->offset, i);
row_merge_tuple_print(stderr, entry, n_fields);
}
#endif /* UNIV_DEBUG */
@@ -808,8 +809,8 @@ row_merge_buf_write(
#endif /* UNIV_DEBUG_VALGRIND */
#ifdef UNIV_DEBUG
if (row_merge_print_write) {
- fprintf(stderr, "row_merge_buf_write %p,%d,%lu EOF\n",
- (void*) b, of->fd, (ulong) of->offset);
+ fprintf(stderr, "row_merge_buf_write %p,%d," ULINTPF " EOF\n",
+ (void*) b, of->fd, of->offset);
}
#endif /* UNIV_DEBUG */
}
@@ -865,20 +866,14 @@ row_merge_read(
#ifdef UNIV_DEBUG
if (row_merge_print_block_read) {
- fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n",
- fd, (ulong) offset);
+ fprintf(stderr, "row_merge_read fd=%d ofs=" ULINTPF "\n",
+ fd, offset);
}
#endif /* UNIV_DEBUG */
-#ifdef UNIV_DEBUG
- if (row_merge_print_block_read) {
- fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n",
- fd, (ulong) offset);
- }
-#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);
@@ -912,12 +907,12 @@ 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) {
- fprintf(stderr, "row_merge_write fd=%d ofs=%lu\n",
- fd, (ulong) offset);
+ fprintf(stderr, "row_merge_write fd=%d ofs=" ULINTPF "\n",
+ fd, offset);
}
#endif /* UNIV_DEBUG */
@@ -965,9 +960,10 @@ row_merge_read_rec(
*mrec = NULL;
#ifdef UNIV_DEBUG
if (row_merge_print_read) {
- fprintf(stderr, "row_merge_read %p,%p,%d,%lu EOF\n",
+ fprintf(stderr, "row_merge_read %p,%p,%d," ULINTPF
+ " EOF\n",
(const void*) b, (const void*) block,
- fd, (ulong) *foffs);
+ fd, *foffs);
}
#endif /* UNIV_DEBUG */
return(NULL);
@@ -1082,9 +1078,9 @@ err_exit:
func_exit:
#ifdef UNIV_DEBUG
if (row_merge_print_read) {
- fprintf(stderr, "row_merge_read %p,%p,%d,%lu ",
+ fprintf(stderr, "row_merge_read %p,%p,%d," ULINTPF " ",
(const void*) b, (const void*) block,
- fd, (ulong) *foffs);
+ fd, *foffs);
rec_print_comp(stderr, *mrec, offsets);
putc('\n', stderr);
}
@@ -1118,8 +1114,8 @@ row_merge_write_rec_low(
ut_ad(e == rec_offs_extra_size(offsets) + 1);
if (row_merge_print_write) {
- fprintf(stderr, "row_merge_write %p,%d,%lu ",
- (void*) b, fd, (ulong) foffs);
+ fprintf(stderr, "row_merge_write %p,%d," ULINTPF " ",
+ (void*) b, fd, foffs);
rec_print_comp(stderr, mrec, offsets);
putc('\n', stderr);
}
@@ -1221,8 +1217,8 @@ row_merge_write_eof(
ut_ad(foffs);
#ifdef UNIV_DEBUG
if (row_merge_print_write) {
- fprintf(stderr, "row_merge_write %p,%p,%d,%lu EOF\n",
- (void*) b, (void*) block, fd, (ulong) *foffs);
+ fprintf(stderr, "row_merge_write %p,%p,%d," ULINTPF " EOF\n",
+ (void*) b, (void*) block, fd, *foffs);
}
#endif /* UNIV_DEBUG */
@@ -2067,11 +2063,12 @@ row_merge_blocks(
#ifdef UNIV_DEBUG
if (row_merge_print_block) {
fprintf(stderr,
- "row_merge_blocks fd=%d ofs=%lu + fd=%d ofs=%lu"
- " = fd=%d ofs=%lu\n",
- file->fd, (ulong) *foffs0,
- file->fd, (ulong) *foffs1,
- of->fd, (ulong) of->offset);
+ "row_merge_blocks fd=%d ofs=" ULINTPF
+ " + fd=%d ofs=" ULINTPF
+ " = fd=%d ofs=" ULINTPF "\n",
+ file->fd, *foffs0,
+ file->fd, *foffs1,
+ of->fd, of->offset);
}
#endif /* UNIV_DEBUG */
@@ -2170,10 +2167,10 @@ row_merge_blocks_copy(
#ifdef UNIV_DEBUG
if (row_merge_print_block) {
fprintf(stderr,
- "row_merge_blocks_copy fd=%d ofs=%lu"
- " = fd=%d ofs=%lu\n",
- file->fd, (ulong) foffs0,
- of->fd, (ulong) of->offset);
+ "row_merge_blocks_copy fd=%d ofs=" ULINTPF
+ " = fd=%d ofs=" ULINTPF "\n",
+ file->fd, *foffs0,
+ of->fd, of->offset);
}
#endif /* UNIV_DEBUG */
@@ -3148,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) {
@@ -3202,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
}
/*********************************************************************//**
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 68b4e1ecea5..eca26ce9763 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -1452,11 +1452,10 @@ error_exit:
que_thr_stop_for_mysql_no_error(thr, trx);
if (UNIV_LIKELY(!(trx->fake_changes))) {
-
if (table->is_system_db) {
- srv_stats.n_system_rows_inserted.add((size_t)trx->id, 1);
+ srv_stats.n_system_rows_inserted.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_inserted.add((size_t)trx->id, 1);
+ srv_stats.n_rows_inserted.inc(size_t(trx->id));
}
if (prebuilt->clust_index_was_generated) {
@@ -1858,17 +1857,15 @@ run_again:
dict_table_n_rows_dec(prebuilt->table);
if (table->is_system_db) {
- srv_stats.n_system_rows_deleted.add(
- (size_t)trx->id, 1);
+ srv_stats.n_system_rows_deleted.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ srv_stats.n_rows_deleted.inc(size_t(trx->id));
}
} else {
if (table->is_system_db) {
- srv_stats.n_system_rows_updated.add(
- (size_t)trx->id, 1);
+ srv_stats.n_system_rows_updated.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ srv_stats.n_rows_updated.inc(size_t(trx->id));
}
}
@@ -2106,17 +2103,15 @@ run_again:
dict_table_n_rows_dec(table);
if (table->is_system_db) {
- srv_stats.n_system_rows_deleted.add(
- (size_t)trx->id, 1);
+ srv_stats.n_system_rows_deleted.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ srv_stats.n_rows_deleted.inc(size_t(trx->id));
}
} else {
if (table->is_system_db) {
- srv_stats.n_system_rows_updated.add(
- (size_t)trx->id, 1);
+ srv_stats.n_system_rows_updated.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ srv_stats.n_rows_updated.inc(size_t(trx->id));
}
}
@@ -5426,7 +5421,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) */
+ /* (this error is ignored by CHECK TABLE) */
+ /* fall through */
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..d1a7ac2036e 100644
--- a/storage/xtradb/row/row0purge.cc
+++ b/storage/xtradb/row/row0purge.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, 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
the terms of the GNU General Public License as published by the Free Software
@@ -488,8 +489,9 @@ row_purge_remove_sec_if_poss_leaf(
success = false;
}
}
- /* fall through (the index entry is still needed,
+ /* (The index entry is still needed,
or the deletion succeeded) */
+ /* fall through */
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 fd23d83e0e5..b0c6565ab2e 100644
--- a/storage/xtradb/row/row0sel.cc
+++ b/storage/xtradb/row/row0sel.cc
@@ -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);
@@ -3671,7 +3684,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 +3709,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 +3967,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 +4226,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 +4738,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... */
+
+ 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 (index != clust_index && prebuilt->need_to_access_clustered) {
-
+ if (use_clustered_index) {
requires_clust_rec:
ut_ad(index != clust_index);
/* We use a 'goto' to the preceding label if a consistent
diff --git a/storage/xtradb/srv/srv0mon.cc b/storage/xtradb/srv/srv0mon.cc
index 4a709160ea6..ea21a4c1454 100644
--- a/storage/xtradb/srv/srv0mon.cc
+++ b/storage/xtradb/srv/srv0mon.cc
@@ -2,6 +2,7 @@
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2017, MariaDB Corporation.
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
@@ -643,11 +644,11 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_DEFAULT_START, MONITOR_OVLD_OS_FSYNC},
{"os_pending_reads", "os", "Number of reads pending",
- MONITOR_NONE,
+ MONITOR_DEFAULT_ON,
MONITOR_DEFAULT_START, MONITOR_OS_PENDING_READS},
{"os_pending_writes", "os", "Number of writes pending",
- MONITOR_NONE,
+ MONITOR_DEFAULT_ON,
MONITOR_DEFAULT_START, MONITOR_OS_PENDING_WRITES},
{"os_log_bytes_written", "os",
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index 839e0f31831..c9210ac7cab 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -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.
@@ -164,7 +164,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;
UNIV_INTERN my_bool srv_lock_timeout_active = FALSE;
@@ -414,7 +415,7 @@ UNIV_INTERN my_bool srv_cleaner_thread_priority = FALSE;
UNIV_INTERN my_bool srv_master_thread_priority = FALSE;
/* The number of purge threads to use.*/
-UNIV_INTERN ulong srv_n_purge_threads = 1;
+UNIV_INTERN ulong srv_n_purge_threads;
/* the number of pages to purge in one batch */
UNIV_INTERN ulong srv_purge_batch_size = 20;
@@ -610,6 +611,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
@@ -633,16 +640,16 @@ current_time % 5 != 0. */
/** Acquire the system_mutex. */
#define srv_sys_mutex_enter() do { \
- mutex_enter(&srv_sys->mutex); \
+ mutex_enter(&srv_sys.mutex); \
} while (0)
/** Test if the system mutex is owned. */
-#define srv_sys_mutex_own() (mutex_own(&srv_sys->mutex) \
+#define srv_sys_mutex_own() (mutex_own(&srv_sys.mutex) \
&& !srv_read_only_mode)
/** Release the system mutex. */
#define srv_sys_mutex_exit() do { \
- mutex_exit(&srv_sys->mutex); \
+ mutex_exit(&srv_sys.mutex); \
} while (0)
#define fetch_lock_wait_timeout(trx) \
@@ -737,7 +744,7 @@ struct srv_sys_t{
ulint n_sys_threads; /*!< size of the sys_threads
array */
- srv_slot_t* sys_threads; /*!< server thread table;
+ srv_slot_t sys_threads[32 + 1]; /*!< server thread table;
os_event_set() and
os_event_reset() on
sys_threads[]->event are
@@ -761,7 +768,7 @@ struct srv_sys_t{
UNIV_INTERN ib_mutex_t server_mutex;
#endif /* !HAVE_ATOMIC_BUILTINS */
-static srv_sys_t* srv_sys = NULL;
+static srv_sys_t srv_sys;
/** Event to signal srv_monitor_thread. Not protected by a mutex.
Set after setting srv_print_innodb_monitor. */
@@ -783,10 +790,10 @@ and/or load it during startup. */
UNIV_INTERN char srv_buffer_pool_dump_at_shutdown = FALSE;
UNIV_INTERN char srv_buffer_pool_load_at_startup = FALSE;
-/** Slot index in the srv_sys->sys_threads array for the purge thread. */
+/** Slot index in the srv_sys.sys_threads array for the purge thread. */
static const ulint SRV_PURGE_SLOT = 1;
-/** Slot index in the srv_sys->sys_threads array for the master thread. */
+/** Slot index in the srv_sys.sys_threads array for the master thread. */
static const ulint SRV_MASTER_SLOT = 0;
UNIV_INTERN os_event_t srv_checkpoint_completed_event;
@@ -896,21 +903,21 @@ srv_reserve_slot(
switch (type) {
case SRV_MASTER:
- slot = &srv_sys->sys_threads[SRV_MASTER_SLOT];
+ slot = &srv_sys.sys_threads[SRV_MASTER_SLOT];
break;
case SRV_PURGE:
- slot = &srv_sys->sys_threads[SRV_PURGE_SLOT];
+ slot = &srv_sys.sys_threads[SRV_PURGE_SLOT];
break;
case SRV_WORKER:
/* Find an empty slot, skip the master and purge slots. */
- for (slot = &srv_sys->sys_threads[2];
+ for (slot = &srv_sys.sys_threads[2];
slot->in_use;
++slot) {
- ut_a(slot < &srv_sys->sys_threads[
- srv_sys->n_sys_threads]);
+ ut_a(slot < &srv_sys.sys_threads[
+ srv_sys.n_sys_threads]);
}
break;
@@ -926,7 +933,7 @@ srv_reserve_slot(
ut_ad(srv_slot_get_type(slot) == type);
- ++srv_sys->n_threads_active[type];
+ ++srv_sys.n_threads_active[type];
srv_sys_mutex_exit();
@@ -956,27 +963,27 @@ srv_suspend_thread_low(
case SRV_MASTER:
/* We have only one master thread and it
should be the first entry always. */
- ut_a(srv_sys->n_threads_active[type] == 1);
+ ut_a(srv_sys.n_threads_active[type] == 1);
break;
case SRV_PURGE:
/* We have only one purge coordinator thread
and it should be the second entry always. */
- ut_a(srv_sys->n_threads_active[type] == 1);
+ ut_a(srv_sys.n_threads_active[type] == 1);
break;
case SRV_WORKER:
ut_a(srv_n_purge_threads > 1);
- ut_a(srv_sys->n_threads_active[type] > 0);
+ ut_a(srv_sys.n_threads_active[type] > 0);
break;
}
ut_a(!slot->suspended);
slot->suspended = TRUE;
- ut_a(srv_sys->n_threads_active[type] > 0);
+ ut_a(srv_sys.n_threads_active[type] > 0);
- srv_sys->n_threads_active[type]--;
+ srv_sys.n_threads_active[type]--;
return(os_event_reset(slot->event));
}
@@ -1031,7 +1038,7 @@ srv_resume_thread(srv_slot_t* slot, ib_int64_t sig_count = 0, bool wait = true,
ut_ad(slot->suspended);
slot->suspended = FALSE;
- ++srv_sys->n_threads_active[slot->type];
+ ++srv_sys.n_threads_active[slot->type];
srv_sys_mutex_exit();
return(timeout);
}
@@ -1053,8 +1060,8 @@ srv_release_threads(enum srv_thread_type type, ulint n)
srv_sys_mutex_enter();
- for (ulint i = 0; i < srv_sys->n_sys_threads; i++) {
- srv_slot_t* slot = &srv_sys->sys_threads[i];
+ for (ulint i = 0; i < srv_sys.n_sys_threads; i++) {
+ srv_slot_t* slot = &srv_sys.sys_threads[i];
if (!slot->in_use || srv_slot_get_type(slot) != type) {
continue;
@@ -1074,7 +1081,7 @@ srv_release_threads(enum srv_thread_type type, ulint n)
should be the first entry always. */
ut_a(n == 1);
ut_a(i == SRV_MASTER_SLOT);
- ut_a(srv_sys->n_threads_active[type] == 0);
+ ut_a(srv_sys.n_threads_active[type] == 0);
break;
case SRV_PURGE:
@@ -1083,12 +1090,12 @@ srv_release_threads(enum srv_thread_type type, ulint n)
ut_a(n == 1);
ut_a(i == SRV_PURGE_SLOT);
ut_a(srv_n_purge_threads > 0);
- ut_a(srv_sys->n_threads_active[type] == 0);
+ ut_a(srv_sys.n_threads_active[type] == 0);
break;
case SRV_WORKER:
ut_a(srv_n_purge_threads > 1);
- ut_a(srv_sys->n_threads_active[type]
+ ut_a(srv_sys.n_threads_active[type]
< srv_n_purge_threads - 1);
break;
}
@@ -1126,9 +1133,6 @@ void
srv_init(void)
/*==========*/
{
- ulint n_sys_threads = 0;
- ulint srv_sys_sz = sizeof(*srv_sys);
-
#ifndef HAVE_ATOMIC_BUILTINS
mutex_create(server_mutex_key, &server_mutex, SYNC_ANY_LATCH);
#endif /* !HAVE_ATOMIC_BUILTINS */
@@ -1136,29 +1140,19 @@ srv_init(void)
mutex_create(srv_innodb_monitor_mutex_key,
&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
- if (!srv_read_only_mode) {
-
- /* Number of purge threads + master thread */
- n_sys_threads = srv_n_purge_threads + 1;
-
- srv_sys_sz += n_sys_threads * sizeof(*srv_sys->sys_threads);
- }
-
- srv_sys = static_cast<srv_sys_t*>(mem_zalloc(srv_sys_sz));
-
- srv_sys->n_sys_threads = n_sys_threads;
+ srv_sys.n_sys_threads = srv_read_only_mode
+ ? 0
+ : srv_n_purge_threads + 1/* purge coordinator */;
if (!srv_read_only_mode) {
- mutex_create(srv_sys_mutex_key, &srv_sys->mutex, SYNC_THREADS);
+ mutex_create(srv_sys_mutex_key, &srv_sys.mutex, SYNC_THREADS);
mutex_create(srv_sys_tasks_mutex_key,
- &srv_sys->tasks_mutex, SYNC_ANY_LATCH);
+ &srv_sys.tasks_mutex, SYNC_ANY_LATCH);
- srv_sys->sys_threads = (srv_slot_t*) &srv_sys[1];
-
- for (ulint i = 0; i < srv_sys->n_sys_threads; ++i) {
- srv_slot_t* slot = &srv_sys->sys_threads[i];
+ for (ulint i = 0; i < srv_sys.n_sys_threads; ++i) {
+ srv_slot_t* slot = &srv_sys.sys_threads[i];
slot->event = os_event_create();
@@ -1178,8 +1172,6 @@ srv_init(void)
if (srv_track_changed_pages) {
os_event_set(srv_redo_log_tracked_event);
}
-
- UT_LIST_INIT(srv_sys->tasks);
}
/* page_zip_stat_per_index_mutex is acquired from:
@@ -1227,8 +1219,8 @@ srv_free(void)
if (!srv_read_only_mode) {
- for (ulint i = 0; i < srv_sys->n_sys_threads; i++)
- os_event_free(srv_sys->sys_threads[i].event);
+ for (ulint i = 0; i < srv_sys.n_sys_threads; i++)
+ os_event_free(srv_sys.sys_threads[i].event);
os_event_free(srv_error_event);
srv_error_event = NULL;
@@ -1240,8 +1232,8 @@ srv_free(void)
srv_checkpoint_completed_event = NULL;
os_event_free(srv_redo_log_tracked_event);
srv_redo_log_tracked_event = NULL;
- mutex_free(&srv_sys->mutex);
- mutex_free(&srv_sys->tasks_mutex);
+ mutex_free(&srv_sys.mutex);
+ mutex_free(&srv_sys.tasks_mutex);
}
#ifdef WITH_INNODB_DISALLOW_WRITES
@@ -1254,9 +1246,6 @@ srv_free(void)
mutex_free(&srv_innodb_monitor_mutex);
mutex_free(&page_zip_stat_per_index_mutex);
- mem_free(srv_sys);
- srv_sys = NULL;
-
trx_i_s_cache_free(trx_i_s_cache);
}
@@ -1761,10 +1750,10 @@ srv_export_innodb_status(void)
mutex_enter(&srv_innodb_monitor_mutex);
export_vars.innodb_data_pending_reads =
- os_n_pending_reads;
+ ulint(MONITOR_VALUE(MONITOR_OS_PENDING_READS));
export_vars.innodb_data_pending_writes =
- os_n_pending_writes;
+ ulint(MONITOR_VALUE(MONITOR_OS_PENDING_WRITES));
export_vars.innodb_data_pending_fsyncs =
fil_n_pending_log_flushes
@@ -2019,6 +2008,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);
}
@@ -2346,9 +2341,9 @@ srv_inc_activity_count(
is caused by the background
change buffer merge */
{
- srv_sys->activity_count.inc();
+ srv_sys.activity_count.inc();
if (ibuf_merge_activity)
- srv_sys->ibuf_merge_activity_count.inc();
+ srv_sys.ibuf_merge_activity_count.inc();
}
/**********************************************************************//**
@@ -2370,7 +2365,7 @@ srv_get_active_thread_type(void)
srv_sys_mutex_enter();
for (ulint i = SRV_WORKER; i <= SRV_MASTER; ++i) {
- if (srv_sys->n_threads_active[i] != 0) {
+ if (srv_sys.n_threads_active[i] != 0) {
ret = static_cast<srv_thread_type>(i);
break;
}
@@ -2527,7 +2522,8 @@ purge_archived_logs(
if (dirnamelen + strlen(fileinfo.name) + 2 > OS_FILE_MAX_PATH)
continue;
- snprintf(archived_log_filename + dirnamelen, OS_FILE_MAX_PATH,
+ snprintf(archived_log_filename + dirnamelen,
+ OS_FILE_MAX_PATH - dirnamelen - 1,
"%s", fileinfo.name);
if (before_no) {
@@ -2623,12 +2619,12 @@ srv_active_wake_master_thread(void)
srv_inc_activity_count();
- if (srv_sys->n_threads_active[SRV_MASTER] == 0) {
+ if (srv_sys.n_threads_active[SRV_MASTER] == 0) {
srv_slot_t* slot;
srv_sys_mutex_enter();
- slot = &srv_sys->sys_threads[SRV_MASTER_SLOT];
+ slot = &srv_sys.sys_threads[SRV_MASTER_SLOT];
/* Only if the master thread has been started. */
@@ -2655,7 +2651,7 @@ srv_wake_purge_thread_if_not_active(void)
ut_ad(!srv_sys_mutex_own());
if (purge_sys->state == PURGE_STATE_RUN
- && srv_sys->n_threads_active[SRV_PURGE] == 0) {
+ && srv_sys.n_threads_active[SRV_PURGE] == 0) {
srv_release_threads(SRV_PURGE, 1);
}
@@ -2684,7 +2680,7 @@ ulint
srv_get_activity_count(void)
/*========================*/
{
- return(srv_sys->activity_count);
+ return(srv_sys.activity_count);
}
/** Get current server ibuf merge activity count.
@@ -2693,7 +2689,7 @@ static
ulint
srv_get_ibuf_merge_activity_count(void)
{
- return(srv_sys->ibuf_merge_activity_count);
+ return(srv_sys.ibuf_merge_activity_count);
}
/*******************************************************************//**
@@ -2712,14 +2708,14 @@ srv_check_activity(
ULINT_UNDEFINED */
ulint old_ibuf_merge_activity_count)
{
- ulint new_activity_count = srv_sys->activity_count;
+ ulint new_activity_count = srv_sys.activity_count;
if (old_ibuf_merge_activity_count == ULINT_UNDEFINED)
return(new_activity_count != old_activity_count);
/* If we care about ibuf merge activity, then the server is considered
idle if all activity, if any, was due to ibuf merge. */
ulint new_ibuf_merge_activity_count
- = srv_sys->ibuf_merge_activity_count;
+ = srv_sys.ibuf_merge_activity_count;
ut_ad(new_ibuf_merge_activity_count <= new_activity_count);
ut_ad(new_ibuf_merge_activity_count >= old_ibuf_merge_activity_count);
@@ -3085,6 +3081,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
@@ -3110,7 +3108,7 @@ DECLARE_THREAD(srv_master_thread)(
srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
slot = srv_reserve_slot(SRV_MASTER);
- ut_a(slot == srv_sys->sys_threads);
+ ut_a(slot == srv_sys.sys_threads);
last_print_time = ut_time();
loop:
@@ -3158,6 +3156,7 @@ suspend_thread:
srv_resume_thread(slot);
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ my_thread_end();
os_thread_exit(NULL);
}
@@ -3206,18 +3205,18 @@ srv_task_execute(void)
ut_ad(!srv_read_only_mode);
ut_a(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);
- mutex_enter(&srv_sys->tasks_mutex);
+ mutex_enter(&srv_sys.tasks_mutex);
- if (UT_LIST_GET_LEN(srv_sys->tasks) > 0) {
+ if (UT_LIST_GET_LEN(srv_sys.tasks) > 0) {
- thr = UT_LIST_GET_FIRST(srv_sys->tasks);
+ thr = UT_LIST_GET_FIRST(srv_sys.tasks);
ut_a(que_node_get_type(thr->child) == QUE_NODE_PURGE);
- UT_LIST_REMOVE(queue, srv_sys->tasks, thr);
+ UT_LIST_REMOVE(queue, srv_sys.tasks, thr);
}
- mutex_exit(&srv_sys->tasks_mutex);
+ mutex_exit(&srv_sys.tasks_mutex);
if (thr != NULL) {
@@ -3244,6 +3243,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);
@@ -3267,7 +3268,7 @@ DECLARE_THREAD(srv_worker_thread)(
srv_sys_mutex_enter();
- ut_a(srv_sys->n_threads_active[SRV_WORKER] < srv_n_purge_threads);
+ ut_a(srv_sys.n_threads_active[SRV_WORKER] < srv_n_purge_threads);
srv_sys_mutex_exit();
@@ -3309,6 +3310,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);
@@ -3477,6 +3479,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;
@@ -3590,6 +3594,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);
@@ -3607,11 +3612,11 @@ srv_que_task_enqueue_low(
que_thr_t* thr) /*!< in: query thread */
{
ut_ad(!srv_read_only_mode);
- mutex_enter(&srv_sys->tasks_mutex);
+ mutex_enter(&srv_sys.tasks_mutex);
- UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
+ UT_LIST_ADD_LAST(queue, srv_sys.tasks, thr);
- mutex_exit(&srv_sys->tasks_mutex);
+ mutex_exit(&srv_sys.tasks_mutex);
srv_release_threads(SRV_WORKER, 1);
}
@@ -3628,11 +3633,11 @@ srv_get_task_queue_length(void)
ut_ad(!srv_read_only_mode);
- mutex_enter(&srv_sys->tasks_mutex);
+ mutex_enter(&srv_sys.tasks_mutex);
- n_tasks = UT_LIST_GET_LEN(srv_sys->tasks);
+ n_tasks = UT_LIST_GET_LEN(srv_sys.tasks);
- mutex_exit(&srv_sys->tasks_mutex);
+ mutex_exit(&srv_sys.tasks_mutex);
return(n_tasks);
}
@@ -3655,3 +3660,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));
+}
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index 04b7d318798..4192e0f0640 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -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];
@@ -574,7 +577,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;
@@ -790,7 +793,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 */
{
@@ -906,7 +909,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 */
@@ -1203,7 +1206,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;
@@ -1280,7 +1283,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;
@@ -1379,13 +1382,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);
@@ -1407,14 +1420,16 @@ srv_undo_tablespaces_init(
if (!create_new_db) {
n_undo_tablespaces = trx_rseg_get_n_undo_tablespaces(
undo_tablespace_ids);
- } else {
- n_undo_tablespaces = n_conf_tablespaces;
- for (i = 1; i <= n_undo_tablespaces; ++i) {
- undo_tablespace_ids[i - 1] = i;
+ if (n_undo_tablespaces != 0) {
+ srv_undo_space_id_start = undo_tablespace_ids[0];
+ prev_space_id = srv_undo_space_id_start - 1;
}
- undo_tablespace_ids[i] = ULINT_UNDEFINED;
+ } else {
+ n_undo_tablespaces = n_conf_tablespaces;
+
+ undo_tablespace_ids[n_conf_tablespaces] = ULINT_UNDEFINED;
}
/* Open all the undo tablespaces that are currently in use. If we
@@ -1438,8 +1453,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) {
@@ -1474,11 +1487,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. */
@@ -1523,10 +1548,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);
@@ -1637,6 +1663,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;
diff --git a/storage/xtradb/sync/sync0arr.cc b/storage/xtradb/sync/sync0arr.cc
index e16eddae80c..7325cb49145 100644
--- a/storage/xtradb/sync/sync0arr.cc
+++ b/storage/xtradb/sync/sync0arr.cc
@@ -1161,9 +1161,10 @@ sync_array_print_long_waits(
now the values of pending calls of these. */
fprintf(stderr,
- "InnoDB: Pending preads %lu, pwrites %lu\n",
- (ulong) os_file_n_pending_preads,
- (ulong) os_file_n_pending_pwrites);
+ "InnoDB: Pending reads " UINT64PF
+ ", writes " UINT64PF "\n",
+ MONITOR_VALUE(MONITOR_OS_PENDING_READS),
+ MONITOR_VALUE(MONITOR_OS_PENDING_WRITES));
srv_print_innodb_monitor = TRUE;
os_event_set(srv_monitor_event);
diff --git a/storage/xtradb/sync/sync0sync.cc b/storage/xtradb/sync/sync0sync.cc
index c270b73e5a0..48cfbf4d6c3 100644
--- a/storage/xtradb/sync/sync0sync.cc
+++ b/storage/xtradb/sync/sync0sync.cc
@@ -1220,6 +1220,7 @@ sync_thread_add_level(
upgrading in innobase_start_or_create_for_mysql(). */
break;
}
+ /* fall through */
case SYNC_MEM_POOL:
case SYNC_MEM_HASH:
case SYNC_RECV:
@@ -1282,9 +1283,9 @@ sync_thread_add_level(
}
}
ut_ad(found_current);
-
- /* fallthrough */
}
+
+ /* fall through */
case SYNC_BUF_FLUSH_LIST:
case SYNC_BUF_LRU_LIST:
case SYNC_BUF_FREE_LIST:
diff --git a/storage/xtradb/trx/trx0i_s.cc b/storage/xtradb/trx/trx0i_s.cc
index eacd9212d2f..0c9618d98eb 100644
--- a/storage/xtradb/trx/trx0i_s.cc
+++ b/storage/xtradb/trx/trx0i_s.cc
@@ -507,7 +507,9 @@ fill_trx_row(
row->trx_mysql_thread_id = thd_get_thread_id(trx->mysql_thd);
- stmt = innobase_get_stmt(trx->mysql_thd, &stmt_len);
+ stmt = trx->mysql_thd
+ ? innobase_get_stmt(trx->mysql_thd, &stmt_len)
+ : NULL;
if (stmt != NULL) {
char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];
diff --git a/storage/xtradb/trx/trx0purge.cc b/storage/xtradb/trx/trx0purge.cc
index 6b7b7df4cd8..474ca077ce5 100644
--- a/storage/xtradb/trx/trx0purge.cc
+++ b/storage/xtradb/trx/trx0purge.cc
@@ -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;
diff --git a/storage/xtradb/trx/trx0rec.cc b/storage/xtradb/trx/trx0rec.cc
index 5fa74846243..8c0904dd57b 100644
--- a/storage/xtradb/trx/trx0rec.cc
+++ b/storage/xtradb/trx/trx0rec.cc
@@ -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 */
@@ -1185,10 +1186,6 @@ UNIV_INTERN
dberr_t
trx_undo_report_row_operation(
/*==========================*/
- ulint flags, /*!< in: if BTR_NO_UNDO_LOG_FLAG bit is
- set, does nothing */
- ulint op_type, /*!< in: TRX_UNDO_INSERT_OP or
- TRX_UNDO_MODIFY_OP */
que_thr_t* thr, /*!< in: query thread */
dict_index_t* index, /*!< in: clustered index */
const dtuple_t* clust_entry, /*!< in: in the case of an insert,
@@ -1222,16 +1219,8 @@ trx_undo_report_row_operation(
ut_a(dict_index_is_clust(index));
ut_ad(!rec || rec_offs_validate(rec, index, offsets));
- if (flags & BTR_NO_UNDO_LOG_FLAG) {
-
- *roll_ptr = 0;
-
- return(DB_SUCCESS);
- }
-
ut_ad(thr);
- ut_ad((op_type != TRX_UNDO_INSERT_OP)
- || (clust_entry && !update && !rec));
+ ut_ad(!clust_entry || (!update && !rec));
trx = thr_get_trx(thr);
@@ -1252,8 +1241,7 @@ trx_undo_report_row_operation(
/* If the undo log is not assigned yet, assign one */
- switch (op_type) {
- case TRX_UNDO_INSERT_OP:
+ if (clust_entry) {
undo = trx->insert_undo;
if (undo == NULL) {
@@ -1269,10 +1257,7 @@ trx_undo_report_row_operation(
ut_ad(err == DB_SUCCESS);
}
- break;
- default:
- ut_ad(op_type == TRX_UNDO_MODIFY_OP);
-
+ } else {
undo = trx->update_undo;
if (undo == NULL) {
@@ -1296,23 +1281,15 @@ trx_undo_report_row_operation(
buf_block_dbg_add_level(undo_block, SYNC_TRX_UNDO_PAGE);
do {
- page_t* undo_page;
- ulint offset;
-
- undo_page = buf_block_get_frame(undo_block);
ut_ad(page_no == buf_block_get_page_no(undo_block));
- switch (op_type) {
- case TRX_UNDO_INSERT_OP:
- offset = trx_undo_page_report_insert(
- undo_page, trx, index, clust_entry, &mtr);
- break;
- default:
- ut_ad(op_type == TRX_UNDO_MODIFY_OP);
- offset = trx_undo_page_report_modify(
+ page_t* undo_page = buf_block_get_frame(undo_block);
+ ulint offset = clust_entry
+ ? trx_undo_page_report_insert(
+ undo_page, trx, index, clust_entry, &mtr)
+ : trx_undo_page_report_modify(
undo_page, trx, index, rec, offsets, update,
cmpl_info, &mtr);
- }
if (UNIV_UNLIKELY(offset == 0)) {
/* The record did not fit on the page. We erase the
@@ -1363,7 +1340,7 @@ trx_undo_report_row_operation(
mutex_exit(&trx->undo_mutex);
*roll_ptr = trx_undo_build_roll_ptr(
- op_type == TRX_UNDO_INSERT_OP,
+ clust_entry != NULL,
rseg->id, page_no, offset);
return(DB_SUCCESS);
}
diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc
index df11414150b..ba1eb028e3a 100644
--- a/storage/xtradb/trx/trx0roll.cc
+++ b/storage/xtradb/trx/trx0roll.cc
@@ -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
@@ -815,6 +815,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
@@ -825,6 +826,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. */
diff --git a/storage/xtradb/trx/trx0sys.cc b/storage/xtradb/trx/trx0sys.cc
index 5126711fb82..9a0b7180435 100644
--- a/storage/xtradb/trx/trx0sys.cc
+++ b/storage/xtradb/trx/trx0sys.cc
@@ -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
@@ -1052,18 +1052,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;
diff --git a/storage/xtradb/usr/usr0sess.cc b/storage/xtradb/usr/usr0sess.cc
index ab7ba6bea09..e1bd71ff1a0 100644
--- a/storage/xtradb/usr/usr0sess.cc
+++ b/storage/xtradb/usr/usr0sess.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, 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
the terms of the GNU General Public License as published by the Free Software
@@ -48,8 +49,6 @@ sess_open(void)
sess->trx = trx_allocate_for_background();
sess->trx->sess = sess;
- UT_LIST_INIT(sess->graphs);
-
return(sess);
}