summaryrefslogtreecommitdiff
path: root/storage/tokudb
diff options
context:
space:
mode:
Diffstat (limited to 'storage/tokudb')
-rw-r--r--storage/tokudb/CMakeLists.txt33
-rw-r--r--storage/tokudb/README.md36
-rw-r--r--storage/tokudb/doc2/sysbench.update.ma10.tokudb754.loglog.pngbin0 -> 6947 bytes
-rw-r--r--storage/tokudb/doc2/sysbench.update.ma10.tokudb754.pngbin0 -> 7351 bytes
-rw-r--r--storage/tokudb/doc2/sysbench.update.ma55.tokudb753.binlog.pngbin0 -> 6723 bytes
-rw-r--r--storage/tokudb/doc2/sysbench.update.ma55.tokudb753.loglog.pngbin0 -> 7367 bytes
-rw-r--r--storage/tokudb/doc2/sysbench.update.ma55.tokudb753.pngbin0 -> 7561 bytes
-rw-r--r--storage/tokudb/doc2/sysbench.update.my55.tokudb753.loglog.pngbin0 -> 6899 bytes
-rw-r--r--storage/tokudb/doc2/sysbench.update.ps56.tokudb754.loglog.pngbin0 -> 7008 bytes
-rw-r--r--storage/tokudb/doc2/sysbench.update.ps56.tokudb754.pngbin0 -> 7434 bytes
-rw-r--r--storage/tokudb/ft-index/buildheader/make_tdb.cc1
-rw-r--r--storage/tokudb/ft-index/ft/ft-internal.h1
-rw-r--r--storage/tokudb/ft-index/ft/ft-ops.cc12
-rw-r--r--storage/tokudb/ft-index/locktree/lock_request.cc32
-rw-r--r--storage/tokudb/ft-index/locktree/lock_request.h6
-rw-r--r--storage/tokudb/ft-index/locktree/locktree.cc1
-rw-r--r--storage/tokudb/ft-index/locktree/tests/lock_request_start_retry_race.cc193
-rw-r--r--storage/tokudb/ft-index/src/ydb_row_lock.cc1
-rw-r--r--storage/tokudb/ft-index/src/ydb_txn.cc6
-rw-r--r--storage/tokudb/ha_tokudb.cc11
-rw-r--r--storage/tokudb/ha_tokudb.h2
-rw-r--r--storage/tokudb/ha_tokudb_alter_56.cc4
-rw-r--r--storage/tokudb/hatoku_hton.cc46
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result1
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/information-schema-global-status.result1
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bf_create_select.test8
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bf_create_select_hash_part.test8
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bf_create_select_range_part.test8
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bf_create_temp_select.test8
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bf_delete.test7
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bf_insert_select.test6
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bf_insert_select_dup_key.test8
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bf_replace_select.test7
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bf_select_hash_part.test8
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/bf_select_range_part.test8
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/change_column_varchar.test1
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/disabled.def3
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/r/db762.result7
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/r/db766.result7
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/r/db768.result10
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/r/db771.result11
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/t/5585-master.opt1
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/t/db762.test13
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/t/db766.test12
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/t/db768.test12
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/t/db771.test13
-rw-r--r--storage/tokudb/tokudb_update_fun.cc2
47 files changed, 468 insertions, 87 deletions
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index 416f6355d32..b703278f3eb 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -18,8 +18,15 @@ IF(NOT LIBJEMALLOC)
MESSAGE(WARNING "TokuDB is enabled, but jemalloc is not. This configuration is not supported")
ENDIF()
+IF (HAVE_WVLA)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-vla")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-vla")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wno-vla")
+ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-vla")
+ENDIF()
+
############################################
-SET(TOKUDB_VERSION "tokudb-7.5.3")
+SET(TOKUDB_VERSION "tokudb-7.5.4")
SET(TOKUDB_DEB_FILES "usr/lib/mysql/plugin/ha_tokudb.so\netc/mysql/conf.d/tokudb.cnf\nusr/bin/tokuftdump\nusr/share/doc/mariadb-server-10.1/README-TOKUDB\nusr/share/doc/mariadb-server-10.1/README.md" PARENT_SCOPE)
SET(USE_BDB OFF CACHE BOOL "")
MARK_AS_ADVANCED(BUILDNAME)
@@ -66,18 +73,34 @@ include(CheckCXXCompilerFlag)
macro(set_cflags_if_supported)
foreach(flag ${ARGN})
- check_c_compiler_flag(${flag} HAVE_C_${flag})
- if (HAVE_C_${flag})
+ string(REGEX REPLACE "-" "_" temp_flag ${flag})
+ check_c_compiler_flag(${flag} HAVE_C_${temp_flag})
+ if (HAVE_C_${temp_flag})
set(CMAKE_C_FLAGS "${flag} ${CMAKE_C_FLAGS}")
endif ()
- check_cxx_compiler_flag(${flag} HAVE_CXX_${flag})
- if (HAVE_CXX_${flag})
+ check_cxx_compiler_flag(${flag} HAVE_CXX_${temp_flag})
+ if (HAVE_CXX_${temp_flag})
set(CMAKE_CXX_FLAGS "${flag} ${CMAKE_CXX_FLAGS}")
endif ()
endforeach(flag)
endmacro(set_cflags_if_supported)
+macro(append_cflags_if_supported)
+ foreach(flag ${ARGN})
+ string(REGEX REPLACE "-" "_" temp_flag ${flag})
+ check_c_compiler_flag(${flag} HAVE_C_${temp_flag})
+ if (HAVE_C_${temp_flag})
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ endif ()
+ check_cxx_compiler_flag(${flag} HAVE_CXX_${temp_flag})
+ if (HAVE_CXX_${temp_flag})
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ endif ()
+ endforeach(flag)
+endmacro(append_cflags_if_supported)
+
set_cflags_if_supported(-Wno-missing-field-initializers)
+append_cflags_if_supported(-Wno-vla)
ADD_SUBDIRECTORY(ft-index)
diff --git a/storage/tokudb/README.md b/storage/tokudb/README.md
index dc7362a5124..2ab2e21a5a1 100644
--- a/storage/tokudb/README.md
+++ b/storage/tokudb/README.md
@@ -1,11 +1,10 @@
TokuDB
======
-TokuDB is a high-performance, write optimized, transactional storage engine for MySQL and
-MariaDB. For more details, see our [product page][products].
+TokuDB is a high-performance, write optimized, transactional storage engine for MySQL, MariaDB, and Percona Server.
+For more details, see our [product page][products].
-This repository contains the MySQL plugin that uses the [TokuFT][tokuft]
-core.
+This repository contains the MySQL plugin that uses the [TokuFT][tokuft] core.
There are also patches to the MySQL and MariaDB kernels, available in our
forks of [mysql][mysql] and [mariadb][mariadb].
@@ -15,23 +14,30 @@ forks of [mysql][mysql] and [mariadb][mariadb].
[mysql]: http://github.com/Tokutek/mysql
[mariadb]: http://github.com/Tokutek/mariadb
-
-Building
+Download
--------
+* [MySQL 5.5 + TokuDB](http://www.tokutek.com/tokudb-for-mysql/download-community/)
+* [MariaDB 5.5 + TokuDB](http://www.tokutek.com/tokudb-for-mysql/download-community/)
+* [MariaDB 10.0 + TokuDB](https://downloads.mariadb.org/)
+* [Percona Server 5.6 + TokuDB](http://www.percona.com/downloads/)
+
+Build
+-----
+
The `scripts/` directory contains a script that can be used to build a
working MySQL or MariaDB with Tokutek patches, and with the TokuDB storage
engine, called `make.mysql.bash`. This script will download copies of the
needed source code from github and build everything.
-To build MySQL 5.5.39 with TokuDB 7.5.2:
+To build MySQL 5.5.40 with TokuDB 7.5.3:
```sh
-scripts/make.mysql.bash --mysqlbuild=mysql-5.5.39-tokudb-7.5.2-linux-x86_64
+scripts/make.mysql.bash --mysqlbuild=mysql-5.5.40-tokudb-7.5.3-linux-x86_64
```
-To build MariaDB 5.5.39 with TokuDB 7.5.2:
+To build MariaDB 5.5.40 with TokuDB 7.5.3:
```sh
-scripts/make.mysql.bash --mysqlbuild=mariadb-5.5.39-tokudb-7.5.2-linux-x86_64
+scripts/make.mysql.bash --mysqlbuild=mariadb-5.5.40-tokudb-7.5.3-linux-x86_64
```
Before you start, make sure you have a C++11-compatible compiler (GCC >=
@@ -54,10 +60,10 @@ scripts/make.mysql.debug.env.bash
```
-Contributing
-------------
+Contribute
+----------
-Please report bugs in TokuDB here on github.
+Please report TokuDB bugs at https://tokutek.atlassian.net/browse/DB.
We have two publicly accessible mailing lists:
@@ -66,7 +72,7 @@ We have two publicly accessible mailing lists:
- tokudb-dev@googlegroups.com is for discussion of the development of
TokuDB.
-We are also available on IRC on freenode.net, in the #tokutek channel.
+We are on IRC on freenode.net, in the #tokutek channel.
License
@@ -74,7 +80,7 @@ License
TokuDB is available under the GPL version 2. See [COPYING][copying]
-The TokuKV component of TokuDB is available under the GPL version 2, with
+The TokuFT component of TokuDB is available under the GPL version 2, with
slight modifications. See [README-TOKUDB][license].
[copying]: http://github.com/Tokutek/tokudb-engine/blob/master/COPYING
diff --git a/storage/tokudb/doc2/sysbench.update.ma10.tokudb754.loglog.png b/storage/tokudb/doc2/sysbench.update.ma10.tokudb754.loglog.png
new file mode 100644
index 00000000000..99b15ff642f
--- /dev/null
+++ b/storage/tokudb/doc2/sysbench.update.ma10.tokudb754.loglog.png
Binary files differ
diff --git a/storage/tokudb/doc2/sysbench.update.ma10.tokudb754.png b/storage/tokudb/doc2/sysbench.update.ma10.tokudb754.png
new file mode 100644
index 00000000000..7297013b51f
--- /dev/null
+++ b/storage/tokudb/doc2/sysbench.update.ma10.tokudb754.png
Binary files differ
diff --git a/storage/tokudb/doc2/sysbench.update.ma55.tokudb753.binlog.png b/storage/tokudb/doc2/sysbench.update.ma55.tokudb753.binlog.png
new file mode 100644
index 00000000000..510f1811e5a
--- /dev/null
+++ b/storage/tokudb/doc2/sysbench.update.ma55.tokudb753.binlog.png
Binary files differ
diff --git a/storage/tokudb/doc2/sysbench.update.ma55.tokudb753.loglog.png b/storage/tokudb/doc2/sysbench.update.ma55.tokudb753.loglog.png
new file mode 100644
index 00000000000..81fecd37684
--- /dev/null
+++ b/storage/tokudb/doc2/sysbench.update.ma55.tokudb753.loglog.png
Binary files differ
diff --git a/storage/tokudb/doc2/sysbench.update.ma55.tokudb753.png b/storage/tokudb/doc2/sysbench.update.ma55.tokudb753.png
new file mode 100644
index 00000000000..e5ed5f90b63
--- /dev/null
+++ b/storage/tokudb/doc2/sysbench.update.ma55.tokudb753.png
Binary files differ
diff --git a/storage/tokudb/doc2/sysbench.update.my55.tokudb753.loglog.png b/storage/tokudb/doc2/sysbench.update.my55.tokudb753.loglog.png
new file mode 100644
index 00000000000..1fe55b07b19
--- /dev/null
+++ b/storage/tokudb/doc2/sysbench.update.my55.tokudb753.loglog.png
Binary files differ
diff --git a/storage/tokudb/doc2/sysbench.update.ps56.tokudb754.loglog.png b/storage/tokudb/doc2/sysbench.update.ps56.tokudb754.loglog.png
new file mode 100644
index 00000000000..52985276249
--- /dev/null
+++ b/storage/tokudb/doc2/sysbench.update.ps56.tokudb754.loglog.png
Binary files differ
diff --git a/storage/tokudb/doc2/sysbench.update.ps56.tokudb754.png b/storage/tokudb/doc2/sysbench.update.ps56.tokudb754.png
new file mode 100644
index 00000000000..39b1c591730
--- /dev/null
+++ b/storage/tokudb/doc2/sysbench.update.ps56.tokudb754.png
Binary files differ
diff --git a/storage/tokudb/ft-index/buildheader/make_tdb.cc b/storage/tokudb/ft-index/buildheader/make_tdb.cc
index 9890b8ed34b..88f8882df78 100644
--- a/storage/tokudb/ft-index/buildheader/make_tdb.cc
+++ b/storage/tokudb/ft-index/buildheader/make_tdb.cc
@@ -585,6 +585,7 @@ static void print_db_txn_struct (void) {
"uint64_t (*id64) (DB_TXN*)",
"void (*set_client_id)(DB_TXN *, uint64_t client_id)",
"uint64_t (*get_client_id)(DB_TXN *)",
+ "bool (*is_prepared)(DB_TXN *)",
NULL};
sort_and_dump_fields("db_txn", false, extra);
}
diff --git a/storage/tokudb/ft-index/ft/ft-internal.h b/storage/tokudb/ft-index/ft/ft-internal.h
index 3cd39705571..88fc5dca686 100644
--- a/storage/tokudb/ft-index/ft/ft-internal.h
+++ b/storage/tokudb/ft-index/ft/ft-internal.h
@@ -616,6 +616,7 @@ typedef enum {
FT_PRO_RIGHTMOST_LEAF_SHORTCUT_SUCCESS,
FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_POS,
FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_REACTIVE,
+ FT_CURSOR_SKIP_DELETED_LEAF_ENTRY, // how many deleted leaf entries were skipped by a cursor
FT_STATUS_NUM_ROWS
} ft_status_entry;
diff --git a/storage/tokudb/ft-index/ft/ft-ops.cc b/storage/tokudb/ft-index/ft/ft-ops.cc
index 481d80fdbe4..34c9c46f1c6 100644
--- a/storage/tokudb/ft-index/ft/ft-ops.cc
+++ b/storage/tokudb/ft-index/ft/ft-ops.cc
@@ -377,6 +377,8 @@ status_init(void)
STATUS_INIT(FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_POS, nullptr, PARCOUNT, "promotion: tried the rightmost leaf shorcut but failed (out-of-bounds)", TOKU_ENGINE_STATUS);
STATUS_INIT(FT_PRO_RIGHTMOST_LEAF_SHORTCUT_FAIL_REACTIVE,nullptr, PARCOUNT, "promotion: tried the rightmost leaf shorcut but failed (child reactive)", TOKU_ENGINE_STATUS);
+ STATUS_INIT(FT_CURSOR_SKIP_DELETED_LEAF_ENTRY, CURSOR_SKIP_DELETED_LEAF_ENTRY, PARCOUNT, "cursor skipped deleted leaf entries", TOKU_ENGINE_STATUS|TOKU_GLOBAL_STATUS);
+
ft_status.initialized = true;
}
static void status_destroy(void) {
@@ -3378,13 +3380,13 @@ ok: ;
if (le_val_is_del(le, ftcursor->is_snapshot_read, ftcursor->ttxn)) {
// Provisionally deleted stuff is gone.
// So we need to scan in the direction to see if we can find something.
- // Every 100 deleted leaf entries check if the leaf's key is within the search bounds.
- for (uint n_deleted = 1; ; n_deleted++) {
+ // Every 64 deleted leaf entries check if the leaf's key is within the search bounds.
+ for (uint64_t n_deleted = 1; ; n_deleted++) {
switch (search->direction) {
case FT_SEARCH_LEFT:
idx++;
- if (idx >= bn->data_buffer.num_klpairs() ||
- ((n_deleted % 64) == 0 && !search_continue(search, key, keylen))) {
+ if (idx >= bn->data_buffer.num_klpairs() || ((n_deleted % 64) == 0 && !search_continue(search, key, keylen))) {
+ STATUS_INC(FT_CURSOR_SKIP_DELETED_LEAF_ENTRY, n_deleted);
if (ftcursor->interrupt_cb && ftcursor->interrupt_cb(ftcursor->interrupt_cb_extra)) {
return TOKUDB_INTERRUPTED;
}
@@ -3393,6 +3395,7 @@ ok: ;
break;
case FT_SEARCH_RIGHT:
if (idx == 0) {
+ STATUS_INC(FT_CURSOR_SKIP_DELETED_LEAF_ENTRY, n_deleted);
if (ftcursor->interrupt_cb && ftcursor->interrupt_cb(ftcursor->interrupt_cb_extra)) {
return TOKUDB_INTERRUPTED;
}
@@ -3406,6 +3409,7 @@ ok: ;
r = bn->data_buffer.fetch_klpair(idx, &le, &keylen, &key);
assert_zero(r); // we just validated the index
if (!le_val_is_del(le, ftcursor->is_snapshot_read, ftcursor->ttxn)) {
+ STATUS_INC(FT_CURSOR_SKIP_DELETED_LEAF_ENTRY, n_deleted);
goto got_a_good_value;
}
}
diff --git a/storage/tokudb/ft-index/locktree/lock_request.cc b/storage/tokudb/ft-index/locktree/lock_request.cc
index 97fa780bb04..18f6051afdf 100644
--- a/storage/tokudb/ft-index/locktree/lock_request.cc
+++ b/storage/tokudb/ft-index/locktree/lock_request.cc
@@ -113,12 +113,19 @@ void lock_request::create(void) {
m_complete_r = 0;
m_state = state::UNINITIALIZED;
+ m_info = nullptr;
toku_cond_init(&m_wait_cond, nullptr);
+
+ m_start_test_callback = nullptr;
+ m_retry_test_callback = nullptr;
}
// destroy a lock request.
void lock_request::destroy(void) {
+ invariant(m_state != state::PENDING);
+ invariant(m_state != state::DESTROYED);
+ m_state = state::DESTROYED;
toku_destroy_dbt(&m_left_key_copy);
toku_destroy_dbt(&m_right_key_copy);
toku_cond_destroy(&m_wait_cond);
@@ -135,7 +142,7 @@ void lock_request::set(locktree *lt, TXNID txnid, const DBT *left_key, const DBT
toku_destroy_dbt(&m_right_key_copy);
m_type = lock_type;
m_state = state::INITIALIZED;
- m_info = lt->get_lock_request_info();
+ m_info = lt ? lt->get_lock_request_info() : nullptr;
m_big_txn = big_txn;
}
@@ -223,15 +230,18 @@ int lock_request::start(void) {
insert_into_lock_requests();
if (deadlock_exists(conflicts)) {
remove_from_lock_requests();
- complete(DB_LOCK_DEADLOCK);
+ r = DB_LOCK_DEADLOCK;
}
toku_mutex_unlock(&m_info->mutex);
- } else {
+ if (m_start_test_callback) m_start_test_callback(); // test callback
+ }
+
+ if (r != DB_LOCK_NOTGRANTED) {
complete(r);
}
conflicts.destroy();
- return m_state == state::COMPLETE ? m_complete_r : r;
+ return r;
}
// sleep on the lock request until it becomes resolved or the wait time has elapsed.
@@ -292,8 +302,8 @@ int lock_request::wait(uint64_t wait_time_ms, uint64_t killed_time_ms, int (*kil
// complete this lock request with the given return value
void lock_request::complete(int complete_r) {
- m_state = state::COMPLETE;
m_complete_r = complete_r;
+ m_state = state::COMPLETE;
}
const DBT *lock_request::get_left_key(void) const {
@@ -331,6 +341,7 @@ int lock_request::retry(void) {
if (r == 0) {
remove_from_lock_requests();
complete(r);
+ if (m_retry_test_callback) m_retry_test_callback(); // test callback
toku_cond_broadcast(&m_wait_cond);
}
@@ -416,7 +427,8 @@ void lock_request::remove_from_lock_requests(void) {
uint32_t idx;
lock_request *request;
int r = m_info->pending_lock_requests.find_zero<TXNID, find_by_txnid>(m_txnid, &request, &idx);
- invariant_zero(r && request == this);
+ invariant_zero(r);
+ invariant(request == this);
r = m_info->pending_lock_requests.delete_at(idx);
invariant_zero(r);
}
@@ -432,4 +444,12 @@ int lock_request::find_by_txnid(lock_request * const &request, const TXNID &txni
}
}
+void lock_request::set_start_test_callback(void (*f)(void)) {
+ m_start_test_callback = f;
+}
+
+void lock_request::set_retry_test_callback(void (*f)(void)) {
+ m_retry_test_callback = f;
+}
+
} /* namespace toku */
diff --git a/storage/tokudb/ft-index/locktree/lock_request.h b/storage/tokudb/ft-index/locktree/lock_request.h
index d1a4c2822e0..c504961fcc0 100644
--- a/storage/tokudb/ft-index/locktree/lock_request.h
+++ b/storage/tokudb/ft-index/locktree/lock_request.h
@@ -164,6 +164,8 @@ public:
// The rest remain pending.
static void retry_all_lock_requests(locktree *lt);
+ void set_start_test_callback(void (*f)(void));
+ void set_retry_test_callback(void (*f)(void));
private:
enum state {
@@ -171,6 +173,7 @@ private:
INITIALIZED,
PENDING,
COMPLETE,
+ DESTROYED,
};
// The keys for a lock request are stored "unowned" in m_left_key
@@ -236,6 +239,9 @@ private:
static int find_by_txnid(lock_request * const &request, const TXNID &txnid);
+ void (*m_start_test_callback)(void);
+ void (*m_retry_test_callback)(void);
+
friend class lock_request_unit_test;
};
ENSURE_POD(lock_request);
diff --git a/storage/tokudb/ft-index/locktree/locktree.cc b/storage/tokudb/ft-index/locktree/locktree.cc
index 27e528db8e8..fc2470e98bd 100644
--- a/storage/tokudb/ft-index/locktree/locktree.cc
+++ b/storage/tokudb/ft-index/locktree/locktree.cc
@@ -152,6 +152,7 @@ void locktree::create(locktree_manager *mgr, DICTIONARY_ID dict_id, const compar
void locktree::destroy(void) {
invariant(m_reference_count == 0);
+ invariant(m_lock_request_info.pending_lock_requests.size() == 0);
m_cmp.destroy();
m_rangetree->destroy();
toku_free(m_rangetree);
diff --git a/storage/tokudb/ft-index/locktree/tests/lock_request_start_retry_race.cc b/storage/tokudb/ft-index/locktree/tests/lock_request_start_retry_race.cc
new file mode 100644
index 00000000000..86ef2dd9cc5
--- /dev/null
+++ b/storage/tokudb/ft-index/locktree/tests/lock_request_start_retry_race.cc
@@ -0,0 +1,193 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+#ident "$Id$"
+/*
+COPYING CONDITIONS NOTICE:
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation, and provided that the
+ following conditions are met:
+
+ * Redistributions of source code must retain this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below).
+
+ * Redistributions in binary form must reproduce this COPYING
+ CONDITIONS NOTICE, the COPYRIGHT NOTICE (below), the
+ DISCLAIMER (below), the UNIVERSITY PATENT NOTICE (below), the
+ PATENT MARKING NOTICE (below), and the PATENT RIGHTS
+ GRANT (below) in the documentation and/or other materials
+ provided with the distribution.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+COPYRIGHT NOTICE:
+
+ TokuFT, Tokutek Fractal Tree Indexing Library.
+ Copyright (C) 2007-2013 Tokutek, Inc.
+
+DISCLAIMER:
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+UNIVERSITY PATENT NOTICE:
+
+ The technology is licensed by the Massachusetts Institute of
+ Technology, Rutgers State University of New Jersey, and the Research
+ Foundation of State University of New York at Stony Brook under
+ United States of America Serial No. 11/760379 and to the patents
+ and/or patent applications resulting from it.
+
+PATENT MARKING NOTICE:
+
+ This software is covered by US Patent No. 8,185,551.
+ This software is covered by US Patent No. 8,489,638.
+
+PATENT RIGHTS GRANT:
+
+ "THIS IMPLEMENTATION" means the copyrightable works distributed by
+ Tokutek as part of the Fractal Tree project.
+
+ "PATENT CLAIMS" means the claims of patents that are owned or
+ licensable by Tokutek, both currently or in the future; and that in
+ the absence of this license would be infringed by THIS
+ IMPLEMENTATION or by using or running THIS IMPLEMENTATION.
+
+ "PATENT CHALLENGE" shall mean a challenge to the validity,
+ patentability, enforceability and/or non-infringement of any of the
+ PATENT CLAIMS or otherwise opposing any of the PATENT CLAIMS.
+
+ Tokutek hereby grants to you, for the term and geographical scope of
+ the PATENT CLAIMS, a non-exclusive, no-charge, royalty-free,
+ irrevocable (except as stated in this section) patent license to
+ make, have made, use, offer to sell, sell, import, transfer, and
+ otherwise run, modify, and propagate the contents of THIS
+ IMPLEMENTATION, where such license applies only to the PATENT
+ CLAIMS. This grant does not include claims that would be infringed
+ only as a consequence of further modifications of THIS
+ IMPLEMENTATION. If you or your agent or licensee institute or order
+ or agree to the institution of patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ THIS IMPLEMENTATION constitutes direct or contributory patent
+ infringement, or inducement of patent infringement, then any rights
+ granted to you under this License shall terminate as of the date
+ such litigation is filed. If you or your agent or exclusive
+ licensee institute or order or agree to the institution of a PATENT
+ CHALLENGE, then Tokutek may terminate any rights granted to you
+ under this License.
+*/
+
+#ident "Copyright (c) 2014 Tokutek Inc. All rights reserved."
+#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
+
+#include <iostream>
+#include "test.h"
+#include "locktree.h"
+#include "lock_request.h"
+
+// Test FT-633, the data race on the lock request between ::start and ::retry
+// This test is non-deterministic. It uses sleeps at 2 critical places to
+// expose the data race on the lock requests state.
+
+namespace toku {
+
+struct locker_arg {
+ locktree *_lt;
+ TXNID _id;
+ const DBT *_key;
+
+ locker_arg(locktree *lt, TXNID id, const DBT *key) : _lt(lt), _id(id), _key(key) {
+ }
+};
+
+static void locker_callback(void) {
+ usleep(10000);
+}
+
+static void run_locker(locktree *lt, TXNID txnid, const DBT *key) {
+ int i;
+ for (i = 0; i < 1000; i++) {
+
+ lock_request request;
+ request.create();
+
+ request.set(lt, txnid, key, key, lock_request::type::WRITE, false);
+
+ // set the test callbacks
+ request.set_start_test_callback(locker_callback);
+ request.set_retry_test_callback(locker_callback);
+
+ // try to acquire the lock
+ int r = request.start();
+ if (r == DB_LOCK_NOTGRANTED) {
+ // wait for the lock to be granted
+ r = request.wait(10 * 1000);
+ }
+
+ if (r == 0) {
+ // release the lock
+ range_buffer buffer;
+ buffer.create();
+ buffer.append(key, key);
+ lt->release_locks(txnid, &buffer);
+ buffer.destroy();
+
+ // retry pending lock requests
+ lock_request::retry_all_lock_requests(lt);
+ }
+
+ request.destroy();
+ memset(&request, 0xab, sizeof request);
+
+ toku_pthread_yield();
+ if ((i % 10) == 0)
+ std::cout << toku_pthread_self() << " " << i << std::endl;
+ }
+}
+
+static void *locker(void *v_arg) {
+ locker_arg *arg = static_cast<locker_arg *>(v_arg);
+ run_locker(arg->_lt, arg->_id, arg->_key);
+ return arg;
+}
+
+} /* namespace toku */
+
+int main(void) {
+ int r;
+
+ toku::locktree lt;
+ DICTIONARY_ID dict_id = { 1 };
+ lt.create(nullptr, dict_id, toku::dbt_comparator);
+
+ const DBT *one = toku::get_dbt(1);
+
+ const int n_workers = 2;
+ toku_pthread_t ids[n_workers];
+ for (int i = 0; i < n_workers; i++) {
+ toku::locker_arg *arg = new toku::locker_arg(&lt, i, one);
+ r = toku_pthread_create(&ids[i], nullptr, toku::locker, arg);
+ assert_zero(r);
+ }
+ for (int i = 0; i < n_workers; i++) {
+ void *ret;
+ r = toku_pthread_join(ids[i], &ret);
+ assert_zero(r);
+ toku::locker_arg *arg = static_cast<toku::locker_arg *>(ret);
+ delete arg;
+ }
+
+ lt.release_reference();
+ lt.destroy();
+ return 0;
+}
+
diff --git a/storage/tokudb/ft-index/src/ydb_row_lock.cc b/storage/tokudb/ft-index/src/ydb_row_lock.cc
index 5ca853d92d9..4dd527220ec 100644
--- a/storage/tokudb/ft-index/src/ydb_row_lock.cc
+++ b/storage/tokudb/ft-index/src/ydb_row_lock.cc
@@ -307,6 +307,7 @@ void toku_db_grab_write_lock (DB *db, DBT *key, TOKUTXN tokutxn) {
int r = request.start();
invariant_zero(r);
db_txn_note_row_lock(db, txn_anc, key, key);
+ request.destroy();
}
void toku_db_release_lt_key_ranges(DB_TXN *txn, txn_lt_key_ranges *ranges) {
diff --git a/storage/tokudb/ft-index/src/ydb_txn.cc b/storage/tokudb/ft-index/src/ydb_txn.cc
index dd428c4d502..ce06e78b23f 100644
--- a/storage/tokudb/ft-index/src/ydb_txn.cc
+++ b/storage/tokudb/ft-index/src/ydb_txn.cc
@@ -422,6 +422,11 @@ static int toku_txn_discard(DB_TXN *txn, uint32_t flags) {
return 0;
}
+static bool toku_txn_is_prepared(DB_TXN *txn) {
+ TOKUTXN ttxn = db_txn_struct_i(txn)->tokutxn;
+ return toku_txn_get_state(ttxn) == TOKUTXN_PREPARING;
+}
+
static inline void txn_func_init(DB_TXN *txn) {
#define STXN(name) txn->name = locked_txn_ ## name
STXN(abort);
@@ -438,6 +443,7 @@ static inline void txn_func_init(DB_TXN *txn) {
SUTXN(discard);
#undef SUTXN
txn->id64 = toku_txn_id64;
+ txn->is_prepared = toku_txn_is_prepared;
}
//
diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc
index f2182efec37..532ce7004e7 100644
--- a/storage/tokudb/ha_tokudb.cc
+++ b/storage/tokudb/ha_tokudb.cc
@@ -1742,7 +1742,7 @@ int ha_tokudb::initialize_share(const char* name, int mode) {
// initialize cardinality info from the status dictionary
share->n_rec_per_key = tokudb::compute_total_key_parts(table_share);
- share->rec_per_key = (uint64_t *) tokudb_my_realloc(share->rec_per_key, share->n_rec_per_key * sizeof (uint64_t), MYF(MY_FAE));
+ share->rec_per_key = (uint64_t *) tokudb_my_realloc(share->rec_per_key, share->n_rec_per_key * sizeof (uint64_t), MYF(MY_FAE + MY_ALLOW_ZERO_PTR));
error = tokudb::get_card_from_status(share->status_block, txn, share->n_rec_per_key, share->rec_per_key);
if (error) {
for (uint i = 0; i < share->n_rec_per_key; i++)
@@ -5992,6 +5992,9 @@ int ha_tokudb::extra(enum ha_extra_function operation) {
case HA_EXTRA_NO_IGNORE_NO_KEY:
using_ignore_no_key = false;
break;
+ case HA_EXTRA_NOT_USED:
+ case HA_EXTRA_PREPARE_FOR_RENAME:
+ break; // must do nothing and return 0
default:
break;
}
@@ -6237,7 +6240,11 @@ int ha_tokudb::start_stmt(THD * thd, thr_lock_type lock_type) {
int error = 0;
tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);
- DBUG_ASSERT(trx);
+ if (!trx) {
+ error = create_tokudb_trx_data_instance(&trx);
+ if (error) { goto cleanup; }
+ thd_set_ha_data(thd, tokudb_hton, trx);
+ }
/*
note that trx->stmt may have been already initialized as start_stmt()
diff --git a/storage/tokudb/ha_tokudb.h b/storage/tokudb/ha_tokudb.h
index 10be517f7ea..bbc84e050b8 100644
--- a/storage/tokudb/ha_tokudb.h
+++ b/storage/tokudb/ha_tokudb.h
@@ -834,7 +834,7 @@ static inline bool key_is_clustering(const KEY *key) {
#else
static inline bool key_is_clustering(const KEY *key) {
- return key->option_struct && key->option_struct->clustering;
+ return key->flags & HA_CLUSTERING;
}
#endif
diff --git a/storage/tokudb/ha_tokudb_alter_56.cc b/storage/tokudb/ha_tokudb_alter_56.cc
index adc854d6367..d574bae9a33 100644
--- a/storage/tokudb/ha_tokudb_alter_56.cc
+++ b/storage/tokudb/ha_tokudb_alter_56.cc
@@ -765,7 +765,9 @@ bool ha_tokudb::commit_inplace_alter_table(TABLE *altered_table, Alter_inplace_i
#else
THD::killed_state saved_killed_state = thd->killed;
thd->killed = THD::NOT_KILLED;
- for (volatile uint i = 0; wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED); i++) {
+ // MySQL does not handle HA_EXTRA_NOT_USED so we use HA_EXTRA_PREPARE_FOR_RENAME since it is passed through
+ // the partition storage engine and is treated as a NOP by tokudb
+ for (volatile uint i = 0; wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME); i++) {
if (thd->killed != THD::NOT_KILLED)
thd->killed = THD::NOT_KILLED;
sleep(1);
diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc
index a6af0152088..9c2e461c338 100644
--- a/storage/tokudb/hatoku_hton.cc
+++ b/storage/tokudb/hatoku_hton.cc
@@ -415,10 +415,10 @@ static int tokudb_init_func(void *p) {
tokudb_hton->commit = tokudb_commit;
tokudb_hton->rollback = tokudb_rollback;
#if TOKU_INCLUDE_XA
- tokudb_hton->prepare=tokudb_xa_prepare;
- tokudb_hton->recover=tokudb_xa_recover;
- tokudb_hton->commit_by_xid=tokudb_commit_by_xid;
- tokudb_hton->rollback_by_xid=tokudb_rollback_by_xid;
+ tokudb_hton->prepare = tokudb_xa_prepare;
+ tokudb_hton->recover = tokudb_xa_recover;
+ tokudb_hton->commit_by_xid = tokudb_commit_by_xid;
+ tokudb_hton->rollback_by_xid = tokudb_rollback_by_xid;
#endif
tokudb_hton->table_options= tokudb_table_options;
@@ -775,16 +775,35 @@ static void tokudb_cleanup_handlers(tokudb_trx_data *trx, DB_TXN *txn) {
}
}
+#if MYSQL_VERSION_ID >= 50600
+extern "C" enum durability_properties thd_get_durability_property(const MYSQL_THD thd);
+#endif
+
+// Determine if an fsync is used when a transaction is committed.
+static bool tokudb_fsync_on_commit(THD *thd, tokudb_trx_data *trx, DB_TXN *txn) {
+#if MYSQL_VERSION_ID >= 50600
+ // Check the client durability property which is set during 2PC
+ if (thd_get_durability_property(thd) == HA_IGNORE_DURABILITY)
+ return false;
+#endif
+#if defined(MARIADB_BASE_VERSION)
+ // Check is the txn is prepared and the binlog is open
+ if (txn->is_prepared(txn) && mysql_bin_log.is_open())
+ return false;
+#endif
+ return THDVAR(thd, commit_sync) != 0;
+}
+
static int tokudb_commit(handlerton * hton, THD * thd, bool all) {
TOKUDB_DBUG_ENTER("");
DBUG_PRINT("trans", ("ending transaction %s", all ? "all" : "stmt"));
- uint32_t syncflag = THDVAR(thd, commit_sync) ? 0 : DB_TXN_NOSYNC;
tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton);
DB_TXN **txn = all ? &trx->all : &trx->stmt;
DB_TXN *this_txn = *txn;
if (this_txn) {
+ uint32_t syncflag = tokudb_fsync_on_commit(thd, trx, this_txn) ? 0 : DB_TXN_NOSYNC;
if (tokudb_debug & TOKUDB_DEBUG_TXN) {
- TOKUDB_TRACE("commit trx %u txn %p", all, this_txn);
+ TOKUDB_TRACE("commit trx %u txn %p syncflag %u", all, this_txn, syncflag);
}
// test hook to induce a crash on a debug build
DBUG_EXECUTE_IF("tokudb_crash_commit_before", DBUG_SUICIDE(););
@@ -838,7 +857,7 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) {
TOKUDB_DBUG_ENTER("");
int r = 0;
- /* if support_xa is disable, just return */
+ // if tokudb_support_xa is disable, just return
if (!THDVAR(thd, support_xa)) {
TOKUDB_DBUG_RETURN(r);
}
@@ -1598,12 +1617,12 @@ static ST_FIELD_INFO tokudb_fractal_tree_info_field_info[] = {
static int tokudb_report_fractal_tree_info_for_db(const DBT *dname, const DBT *iname, TABLE *table, THD *thd) {
int error;
- DB *db;
uint64_t bt_num_blocks_allocated;
uint64_t bt_num_blocks_in_use;
uint64_t bt_size_allocated;
uint64_t bt_size_in_use;
+ DB *db = NULL;
error = db_create(&db, db_env, 0);
if (error) {
goto exit;
@@ -1615,12 +1634,6 @@ static int tokudb_report_fractal_tree_info_for_db(const DBT *dname, const DBT *i
error = db->get_fractal_tree_info64(db,
&bt_num_blocks_allocated, &bt_num_blocks_in_use,
&bt_size_allocated, &bt_size_in_use);
- {
- int close_error = db->close(db, 0);
- if (!error) {
- error = close_error;
- }
- }
if (error) {
goto exit;
}
@@ -1652,6 +1665,11 @@ static int tokudb_report_fractal_tree_info_for_db(const DBT *dname, const DBT *i
error = schema_table_store_record(thd, table);
exit:
+ if (db) {
+ int close_error = db->close(db, 0);
+ if (error == 0)
+ error = close_error;
+ }
return error;
}
diff --git a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result
index 7f3d4265662..5018e2db278 100644
--- a/storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result
+++ b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result
@@ -6,6 +6,7 @@ Table Create Table
t CREATE TABLE `t` (
`a` varchar(1) DEFAULT NULL
) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib'
+INSERT INTO t VALUES (null);
ALTER TABLE t CHANGE COLUMN a a VARCHAR(2);
ALTER TABLE t CHANGE COLUMN a a VARCHAR(2);
ALTER TABLE t CHANGE COLUMN a a VARCHAR(3);
diff --git a/storage/tokudb/mysql-test/tokudb/r/information-schema-global-status.result b/storage/tokudb/mysql-test/tokudb/r/information-schema-global-status.result
index 369c14fe4fe..7d0e83260e1 100644
--- a/storage/tokudb/mysql-test/tokudb/r/information-schema-global-status.result
+++ b/storage/tokudb/mysql-test/tokudb/r/information-schema-global-status.result
@@ -65,6 +65,7 @@ TOKUDB_CHECKPOINT_LONG_BEGIN_COUNT
TOKUDB_CHECKPOINT_LONG_BEGIN_TIME
TOKUDB_CHECKPOINT_PERIOD
TOKUDB_CHECKPOINT_TAKEN
+TOKUDB_CURSOR_SKIP_DELETED_LEAF_ENTRY
TOKUDB_DB_CLOSES
TOKUDB_DB_OPENS
TOKUDB_DB_OPEN_CURRENT
diff --git a/storage/tokudb/mysql-test/tokudb/t/bf_create_select.test b/storage/tokudb/mysql-test/tokudb/t/bf_create_select.test
index 20455da874f..8c457b75f27 100644
--- a/storage/tokudb/mysql-test/tokudb/t/bf_create_select.test
+++ b/storage/tokudb/mysql-test/tokudb/t/bf_create_select.test
@@ -65,8 +65,8 @@ while ($i < $maxq) {
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# Check that the time with bulk fetch off is at least twice that whith bulk fetch on
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# Check that the time with bulk fetch off is greater that with bulk fetch on
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo index $verdict $time_elapsed_on $time_elapsed_off; }
if (!$verdict) { echo index $time_elapsed_on $time_elapsed_off; }
@@ -94,8 +94,8 @@ while ($i < $maxq) {
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# Check that the time with bulk fetch off is at least twice that whith bulk fetch on
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# Check that the time with bulk fetch off is greater that with bulk fetch on
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo range $verdict $time_elapsed_on $time_elapsed_off; }
if (!$verdict) { echo range $time_elapsed_on $time_elapsed_off; }
diff --git a/storage/tokudb/mysql-test/tokudb/t/bf_create_select_hash_part.test b/storage/tokudb/mysql-test/tokudb/t/bf_create_select_hash_part.test
index 4df0a138be8..34995b4ba2f 100644
--- a/storage/tokudb/mysql-test/tokudb/t/bf_create_select_hash_part.test
+++ b/storage/tokudb/mysql-test/tokudb/t/bf_create_select_hash_part.test
@@ -65,8 +65,8 @@ while ($i < $maxq) {
}
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# check that bulk fetch on is at least 1.5 times faster than bulk fetch off
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 1.5 * $time_elapsed_on`;
+# check that bulk fetch on is greater than bulk fetch off
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo index $verdict $time_elapsed_off $time_elapsed_on; }
if (!$verdict) { echo index $time_elapsed_off $time_elapsed_on; }
@@ -93,8 +93,8 @@ while ($i < $maxq) {
}
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# check that bulk fetch on is at least 1.5 times faster than bulk fetch off
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 1.5 * $time_elapsed_on`;
+# check that bulk fetch on is greater than bulk fetch off
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo range $verdict $time_elapsed_off $time_elapsed_on; }
if (!$verdict) { echo range $time_elapsed_off $time_elapsed_on; }
diff --git a/storage/tokudb/mysql-test/tokudb/t/bf_create_select_range_part.test b/storage/tokudb/mysql-test/tokudb/t/bf_create_select_range_part.test
index b66b2c42808..a53249893f4 100644
--- a/storage/tokudb/mysql-test/tokudb/t/bf_create_select_range_part.test
+++ b/storage/tokudb/mysql-test/tokudb/t/bf_create_select_range_part.test
@@ -72,8 +72,8 @@ while ($i < $maxq) {
}
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# check that bulk fetch on is at least 2 times faster than bulk fetch off
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# check that bulk fetch on is greater than bulk fetch off
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo index $verdict $time_elapsed_off $time_elapsed_on; }
if (!$verdict) { echo index $time_elapsed_off $time_elapsed_on; }
@@ -100,8 +100,8 @@ while ($i < $maxq) {
}
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# check that bulk fetch on is at least 2 times faster than bulk fetch off
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# check that bulk fetch on is greater than bulk fetch off
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo range $verdict $time_elapsed_off $time_elapsed_on; }
if (!$verdict) { echo range $time_elapsed_off $time_elapsed_on; }
diff --git a/storage/tokudb/mysql-test/tokudb/t/bf_create_temp_select.test b/storage/tokudb/mysql-test/tokudb/t/bf_create_temp_select.test
index 52cb886a410..4f8211a51d9 100644
--- a/storage/tokudb/mysql-test/tokudb/t/bf_create_temp_select.test
+++ b/storage/tokudb/mysql-test/tokudb/t/bf_create_temp_select.test
@@ -65,8 +65,8 @@ while ($i < $maxq) {
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# Check that the time with bulk fetch off is at least twice that whith bulk fetch on
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# Check that the time with bulk fetch off is greater that with bulk fetch on
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo index $verdict $time_elapsed_on $time_elapsed_off; }
if (!$verdict) { echo index $time_elapsed_on $time_elapsed_off; }
@@ -94,8 +94,8 @@ while ($i < $maxq) {
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# Check that the time with bulk fetch off is at least twice that whith bulk fetch on
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# Check that the time with bulk fetch off is greater than with bulk fetch on
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo range $verdict $time_elapsed_on $time_elapsed_off; }
if (!$verdict) { echo range $time_elapsed_on $time_elapsed_off; }
diff --git a/storage/tokudb/mysql-test/tokudb/t/bf_delete.test b/storage/tokudb/mysql-test/tokudb/t/bf_delete.test
index f98e87f1ec1..a55d78784cc 100644
--- a/storage/tokudb/mysql-test/tokudb/t/bf_delete.test
+++ b/storage/tokudb/mysql-test/tokudb/t/bf_delete.test
@@ -1,5 +1,4 @@
-# Verify that index scans for delete statements use bulk fetch and are
-# at least twice as fast
+# Verify that index scans for delete statements use bulk fetch are faster than when not using bulk fetch
source include/have_tokudb.inc;
source include/big_test.inc;
@@ -62,8 +61,8 @@ while ($i < $maxq) {
}
let $time_elapsed_bf_off = `select unix_timestamp() - $s`;
-# verify that a delete scan with bulk fetch ON is at least 2 times faster than with bulk fetch OFF
-let $verdict = `select $time_elapsed_bf_on > 0 && $time_elapsed_bf_off >= 2 * $time_elapsed_bf_on`;
+# verify that a delete scan with bulk fetch ON is greater than with bulk fetch OFF
+let $verdict = `select $time_elapsed_bf_on > 0 && $time_elapsed_bf_off > $time_elapsed_bf_on`;
echo $verdict;
if ($debug) { echo range $verdict $time_elapsed_bf_on $time_elapsed_bf_off; }
if (!$verdict) { echo range $time_elapsed_bf_on $time_elapsed_bf_off; }
diff --git a/storage/tokudb/mysql-test/tokudb/t/bf_insert_select.test b/storage/tokudb/mysql-test/tokudb/t/bf_insert_select.test
index 5fcb8fa58b5..8d96c26bc29 100644
--- a/storage/tokudb/mysql-test/tokudb/t/bf_insert_select.test
+++ b/storage/tokudb/mysql-test/tokudb/t/bf_insert_select.test
@@ -66,8 +66,8 @@ while ($i < $maxq) {
}
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# check that bulk fetch on is at least 2 times faster than bulk fetch off
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# check that the time with bulk fetch on is greater than with bulk fetch off
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo index $verdict $time_elapsed_off $time_elapsed_on; }
if (!$verdict) { echo index $time_elapsed_off $time_elapsed_on; }
@@ -92,7 +92,7 @@ while ($i < $maxq) {
}
let $time_elapsed_off = `select unix_timestamp() - $s`;
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo range $verdict $time_elapsed_off $time_elapsed_on; }
if (!$verdict) { echo range $time_elapsed_off $time_elapsed_on; }
diff --git a/storage/tokudb/mysql-test/tokudb/t/bf_insert_select_dup_key.test b/storage/tokudb/mysql-test/tokudb/t/bf_insert_select_dup_key.test
index 51c6d66d706..1b015b2c272 100644
--- a/storage/tokudb/mysql-test/tokudb/t/bf_insert_select_dup_key.test
+++ b/storage/tokudb/mysql-test/tokudb/t/bf_insert_select_dup_key.test
@@ -70,8 +70,8 @@ while ($i < $maxq) {
}
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# check that bulk fetch on is at least 2 times faster than bulk fetch off
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# check that bulk fetch on is greater than with bulk fetch off
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo index $verdict $time_elapsed_off $time_elapsed_on; }
if (!$verdict) { echo index $time_elapsed_off $time_elapsed_on; }
@@ -96,8 +96,8 @@ while ($i < $maxq) {
}
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# check that bulk fetch on is at least 2 times faster than bulk fetch off
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# check that bulk fetch on is greater than bulk fetch off
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo range $verdict $time_elapsed_off $time_elapsed_on; }
if (!$verdict) { echo range $time_elapsed_off $time_elapsed_on; }
diff --git a/storage/tokudb/mysql-test/tokudb/t/bf_replace_select.test b/storage/tokudb/mysql-test/tokudb/t/bf_replace_select.test
index 1ca754454eb..72cda349f80 100644
--- a/storage/tokudb/mysql-test/tokudb/t/bf_replace_select.test
+++ b/storage/tokudb/mysql-test/tokudb/t/bf_replace_select.test
@@ -66,8 +66,8 @@ while ($i < $maxq) {
}
let $time_elapsed_off = `select unix_timestamp() - $s`;
-# check that bulk fetch on is at least 2 times faster than bulk fetch off
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# check that the time with bulk fetch on is greater than with bulk fetch off
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo index $verdict $time_elapsed_off $time_elapsed_on; }
if (!$verdict) { echo index $time_elapsed_off $time_elapsed_on; }
@@ -92,7 +92,8 @@ while ($i < $maxq) {
}
let $time_elapsed_off = `select unix_timestamp() - $s`;
-let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off >= 2 * $time_elapsed_on`;
+# check that the time with bulk fetch on is greater than with bulk fetch off
+let $verdict = `select $time_elapsed_on > 0 && $time_elapsed_off > $time_elapsed_on`;
echo $verdict;
if ($debug) { echo range $verdict $time_elapsed_off $time_elapsed_on; }
if (!$verdict) { echo range $time_elapsed_off $time_elapsed_on; }
diff --git a/storage/tokudb/mysql-test/tokudb/t/bf_select_hash_part.test b/storage/tokudb/mysql-test/tokudb/t/bf_select_hash_part.test
index 2271a2086be..46986278743 100644
--- a/storage/tokudb/mysql-test/tokudb/t/bf_select_hash_part.test
+++ b/storage/tokudb/mysql-test/tokudb/t/bf_select_hash_part.test
@@ -65,8 +65,8 @@ let $time_bf_off = `select unix_timestamp() - $s`;
if ($debug) { echo index scans took $time_bf_off.; }
-# check that the scan time with bulk fetch off is at least 1.5 times as long as with bulk fetch on
-let $verdict = `select $time_bf_on > 0 && $time_bf_off >= 1.5 * $time_bf_on`;
+# check that the scan time with bulk fetch off is greater than with bulk fetch on
+let $verdict = `select $time_bf_on > 0 && $time_bf_off > $time_bf_on`;
echo $verdict;
if ($debug) { echo index $verdict $time_bf_on $time_bf_off; }
if (!$verdict) { echo index $time_bf_on $time_bf_off; }
@@ -93,8 +93,8 @@ let $time_bf_off = `select unix_timestamp() - $s`;
if ($debug) { echo range scans took $time_bf_off.; }
-# check that the scan time with bulk fetch off is at least 1.5 times as long as with bulk fetch on
-let $verdict = `select $time_bf_on > 0 && $time_bf_off >= 1.5 * $time_bf_on`;
+# check that the scan time with bulk fetch off is greater than with bulk fetch on
+let $verdict = `select $time_bf_on > 0 && $time_bf_off > $time_bf_on`;
echo $verdict;
if ($debug) { echo range $verdict $time_bf_on $time_bf_off; }
if (!$verdict) { echo range $time_bf_on $time_bf_off; }
diff --git a/storage/tokudb/mysql-test/tokudb/t/bf_select_range_part.test b/storage/tokudb/mysql-test/tokudb/t/bf_select_range_part.test
index 9dcb044d4d4..7e608777798 100644
--- a/storage/tokudb/mysql-test/tokudb/t/bf_select_range_part.test
+++ b/storage/tokudb/mysql-test/tokudb/t/bf_select_range_part.test
@@ -70,8 +70,8 @@ while ($i < $maxq) {
}
let $time_bf_off = `select unix_timestamp() - $s`;
-# check that the scan time with bulk fetch off is at least 1.5 times as long as with bulk fetch on
-let $verdict = `select $time_bf_on > 0 && $time_bf_off >= 1.5 * $time_bf_on`;
+# check that the scan time with bulk fetch off is greater than with bulk fetch on
+let $verdict = `select $time_bf_on > 0 && $time_bf_off > $time_bf_on`;
echo $verdict;
if ($debug) { echo index $verdict $time_bf_on $time_bf_off; }
if (!$verdict) { echo index scan $time_bf_on $time_bf_off; }
@@ -94,8 +94,8 @@ while ($i < $maxq) {
}
let $time_bf_off = `select unix_timestamp() - $s`;
-# check that the scan time with bulk fetch off is at least 1.5 times as long as with bulk fetch on
-let $verdict = `select $time_bf_on > 0 && $time_bf_off >= 1.5 * $time_bf_on`;
+# check that the scan time with bulk fetch off is greater than with bulk fetch on
+let $verdict = `select $time_bf_on > 0 && $time_bf_off > $time_bf_on`;
echo $verdict;
if ($debug) { echo range $verdict $time_bf_on $time_bf_off; }
if (!$verdict) { echo range $time_bf_on $time_bf_off; }
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_varchar.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar.test
index f2b4e3cbf78..6543952ad29 100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_varchar.test
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar.test
@@ -9,6 +9,7 @@ SET SESSION TOKUDB_DISABLE_SLOW_ALTER=ON;
CREATE TABLE t (a VARCHAR(1)) ENGINE=TokuDB;
SHOW CREATE TABLE t;
+INSERT INTO t VALUES (null);
# 1->1
let $i=1
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/disabled.def b/storage/tokudb/mysql-test/tokudb_bugs/disabled.def
index 0bf13a5e86e..86d38a530da 100644
--- a/storage/tokudb/mysql-test/tokudb_bugs/disabled.def
+++ b/storage/tokudb/mysql-test/tokudb_bugs/disabled.def
@@ -9,3 +9,6 @@ fileops-3: how this could work, if alter needs an exclusive mdl lock?
checkpoint_lock_2: test can not work when the checkpoint_safe_lock is a fair rwlock
+# this test was added in 7.5.4 and fails in 10.0
+# but running this very test in 7.5.3 fails in exactly the same manner
+db768: never worked. tokutek was informed, 2015-01-14
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db762.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db762.result
new file mode 100644
index 00000000000..159957dba3e
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db762.result
@@ -0,0 +1,7 @@
+drop table if exists t1,t2;
+create table t1 (x int) engine=innodb;
+lock table t1 read;
+create temporary table t2 (x int) engine=tokudb;
+insert into t2 values (1);
+unlock tables;
+drop table t1, t2;
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db766.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db766.result
new file mode 100644
index 00000000000..e109b0a7f15
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db766.result
@@ -0,0 +1,7 @@
+set default_storage_engine=TokuDB;
+drop table if exists t1;
+CREATE TABLE t1(c1 INT,c2 CHAR)PARTITION BY KEY(c1) PARTITIONS 5;
+insert INTO t1 values(1,1),(2,1),(2,2),(2,3);
+ALTER TABLE t1 ADD UNIQUE INDEX i1(c1);
+ERROR 23000: Can't write; duplicate key in table 't1'
+drop table t1;
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db768.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db768.result
new file mode 100644
index 00000000000..f302114b45c
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db768.result
@@ -0,0 +1,10 @@
+set default_storage_engine='tokudb';
+drop table if exists t;
+create table t (id int primary key);
+set autocommit=OFF;
+lock tables t write;
+optimize table t;
+Table Op Msg_type Msg_text
+test.t optimize status OK
+unlock tables;
+drop table t;
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db771.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db771.result
new file mode 100644
index 00000000000..3fc012a732f
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db771.result
@@ -0,0 +1,11 @@
+set default_storage_engine=tokudb;
+drop table if exists t1;
+CREATE TABLE t1 (a int key, b varchar(32), c varchar(32));
+REPLACE t1 SET a = 4;
+ALTER TABLE t1 CHANGE COLUMN c c VARCHAR(500);
+update t1 set b='hi';
+update t1 set c='there';
+select * from t1;
+a b c
+4 hi there
+drop table t1;
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/5585-master.opt b/storage/tokudb/mysql-test/tokudb_bugs/t/5585-master.opt
new file mode 100644
index 00000000000..017432e797d
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_bugs/t/5585-master.opt
@@ -0,0 +1 @@
+--tokudb-cache-size=1000000000 --innodb-buffer-pool-size=1000000000
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db762.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db762.test
new file mode 100644
index 00000000000..4428e9df8ec
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db762.test
@@ -0,0 +1,13 @@
+# test for DB-762 and DB-767
+source include/have_tokudb.inc;
+source include/have_innodb.inc;
+disable_warnings;
+drop table if exists t1,t2;
+enable_warnings;
+create table t1 (x int) engine=innodb;
+lock table t1 read;
+create temporary table t2 (x int) engine=tokudb;
+insert into t2 values (1);
+unlock tables;
+drop table t1, t2;
+
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db766.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db766.test
new file mode 100644
index 00000000000..3aad3404296
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db766.test
@@ -0,0 +1,12 @@
+# reproducer for DB-766
+source include/have_tokudb.inc;
+source include/have_partition.inc;
+set default_storage_engine=TokuDB;
+disable_warnings;
+drop table if exists t1;
+enable_warnings;
+CREATE TABLE t1(c1 INT,c2 CHAR)PARTITION BY KEY(c1) PARTITIONS 5;
+insert INTO t1 values(1,1),(2,1),(2,2),(2,3);
+--error ER_DUP_KEY
+ALTER TABLE t1 ADD UNIQUE INDEX i1(c1);
+drop table t1;
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db768.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db768.test
new file mode 100644
index 00000000000..be2155f5c18
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db768.test
@@ -0,0 +1,12 @@
+# test case for DB-768
+source include/have_tokudb.inc;
+set default_storage_engine='tokudb';
+disable_warnings;
+drop table if exists t;
+enable_warnings;
+create table t (id int primary key);
+set autocommit=OFF;
+lock tables t write;
+optimize table t;
+unlock tables;
+drop table t;
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db771.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db771.test
new file mode 100644
index 00000000000..039ad7471c1
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db771.test
@@ -0,0 +1,13 @@
+# test case for DB-771
+source include/have_tokudb.inc;
+set default_storage_engine=tokudb;
+disable_warnings;
+drop table if exists t1;
+enable_warnings;
+CREATE TABLE t1 (a int key, b varchar(32), c varchar(32));
+REPLACE t1 SET a = 4;
+ALTER TABLE t1 CHANGE COLUMN c c VARCHAR(500);
+update t1 set b='hi';
+update t1 set c='there';
+select * from t1;
+drop table t1;
diff --git a/storage/tokudb/tokudb_update_fun.cc b/storage/tokudb/tokudb_update_fun.cc
index 3ab7510121a..9754dc989a2 100644
--- a/storage/tokudb/tokudb_update_fun.cc
+++ b/storage/tokudb/tokudb_update_fun.cc
@@ -851,7 +851,7 @@ static int tokudb_expand_variable_offsets(
DBT new_val; memset(&new_val, 0, sizeof new_val);
if (old_val != NULL) {
- assert(offset_start + number_of_offsets < old_val->size);
+ assert(offset_start + number_of_offsets <= old_val->size);
// compute the new val from the old val
uchar *old_val_ptr = (uchar *)old_val->data;