summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorDaniel Black <danielgb@au.ibm.com>2018-02-04 22:20:52 +1100
committerGitHub <noreply@github.com>2018-02-04 22:20:52 +1100
commita0a9958098604a57f2c53d1a1b0d50407a328da3 (patch)
tree288f260c526778d13abd6ce4a0276104a8271883 /storage
parent67f3fb1bc54682a29ee3b407f60b798780db698f (diff)
parentaba15b864af664276261dcbbdaef35268d407af1 (diff)
downloadmariadb-git-a0a9958098604a57f2c53d1a1b0d50407a328da3.tar.gz
Merge branch '10.1' into 10.1-wsrep_sst_rsync_read_MYSQL_BASE_VERSION_config
Diffstat (limited to 'storage')
-rw-r--r--storage/connect/CMakeLists.txt4
-rw-r--r--storage/connect/fmdlex.c2
-rw-r--r--storage/connect/global.h3
-rw-r--r--storage/connect/ha_connect.cc55
-rw-r--r--storage/connect/inihandl.cpp (renamed from storage/connect/inihandl.c)35
-rw-r--r--storage/connect/jsonudf.cpp13
-rw-r--r--storage/connect/myconn.cpp5
-rw-r--r--storage/connect/mysql-test/connect/disabled.def1
-rw-r--r--storage/connect/plgdbutl.cpp2
-rw-r--r--storage/connect/plugutil.cpp73
-rw-r--r--storage/connect/tabtbl.cpp22
-rw-r--r--storage/connect/tabtbl.h50
-rw-r--r--storage/connect/user_connect.cc23
-rw-r--r--storage/federatedx/ha_federatedx.h2
-rw-r--r--storage/heap/ha_heap.cc9
-rw-r--r--storage/innobase/CMakeLists.txt3
-rw-r--r--storage/innobase/api/api0api.cc2
-rw-r--r--storage/innobase/btr/btr0cur.cc34
-rw-r--r--storage/innobase/btr/btr0pcur.cc2
-rw-r--r--storage/innobase/buf/buf0buddy.cc3
-rw-r--r--storage/innobase/buf/buf0dump.cc1
-rw-r--r--storage/innobase/buf/buf0lru.cc81
-rw-r--r--storage/innobase/data/data0type.cc10
-rw-r--r--storage/innobase/dict/dict0dict.cc1
-rw-r--r--storage/innobase/dict/dict0mem.cc9
-rw-r--r--storage/innobase/fil/fil0fil.cc2
-rw-r--r--storage/innobase/fts/fts0fts.cc22
-rw-r--r--storage/innobase/fts/fts0que.cc20
-rw-r--r--storage/innobase/handler/ha_innodb.cc4
-rw-r--r--storage/innobase/handler/handler0alter.cc5
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc4
-rw-r--r--storage/innobase/include/btr0cur.h12
-rw-r--r--storage/innobase/include/data0type.h50
-rw-r--r--storage/innobase/include/data0type.ic56
-rw-r--r--storage/innobase/include/dict0dict.h14
-rw-r--r--storage/innobase/include/dict0dict.ic34
-rw-r--r--storage/innobase/include/dict0mem.h11
-rw-r--r--storage/innobase/include/fil0fil.h2
-rw-r--r--storage/innobase/include/log0crypt.h6
-rw-r--r--storage/innobase/include/mem0mem.ic12
-rw-r--r--storage/innobase/include/mtr0mtr.h16
-rw-r--r--storage/innobase/include/mtr0mtr.ic6
-rw-r--r--storage/innobase/include/rem0rec.ic3
-rw-r--r--storage/innobase/include/row0mysql.h12
-rw-r--r--storage/innobase/include/trx0rec.h3
-rw-r--r--storage/innobase/include/trx0undo.h13
-rw-r--r--storage/innobase/include/univ.i8
-rw-r--r--storage/innobase/include/ut0ut.h3
-rw-r--r--storage/innobase/lock/lock0lock.cc4
-rw-r--r--storage/innobase/log/log0crypt.cc54
-rw-r--r--storage/innobase/log/log0log.cc7
-rw-r--r--storage/innobase/mem/mem0mem.cc13
-rw-r--r--storage/innobase/rem/rem0rec.cc18
-rw-r--r--storage/innobase/row/row0ext.cc3
-rw-r--r--storage/innobase/row/row0ftsort.cc22
-rw-r--r--storage/innobase/row/row0import.cc9
-rw-r--r--storage/innobase/row/row0ins.cc33
-rw-r--r--storage/innobase/row/row0log.cc16
-rw-r--r--storage/innobase/row/row0merge.cc25
-rw-r--r--storage/innobase/row/row0mysql.cc12
-rw-r--r--storage/innobase/row/row0purge.cc4
-rw-r--r--storage/innobase/row/row0quiesce.cc8
-rw-r--r--storage/innobase/row/row0row.cc9
-rw-r--r--storage/innobase/row/row0sel.cc33
-rw-r--r--storage/innobase/row/row0umod.cc14
-rw-r--r--storage/innobase/row/row0upd.cc15
-rw-r--r--storage/innobase/srv/srv0srv.cc4
-rw-r--r--storage/innobase/trx/trx0purge.cc26
-rw-r--r--storage/innobase/trx/trx0rec.cc22
-rw-r--r--storage/innobase/trx/trx0roll.cc9
-rw-r--r--storage/innobase/trx/trx0undo.cc10
-rw-r--r--storage/innobase/ut/ut0ut.cc7
-rw-r--r--storage/maria/ha_maria.cc7
-rw-r--r--storage/maria/ma_blockrec.c20
-rw-r--r--storage/maria/ma_page.c40
-rw-r--r--storage/maria/ma_search.c14
-rw-r--r--storage/maria/ma_state.c24
-rw-r--r--storage/maria/ma_state.h1
-rw-r--r--storage/maria/ma_write.c2
-rw-r--r--storage/maria/maria_def.h3
-rw-r--r--storage/maria/unittest/ma_test_loghandler_multigroup-t.c6
-rw-r--r--storage/maria/unittest/ma_test_loghandler_nologs-t.c2
-rw-r--r--storage/myisam/mi_locking.c8
-rw-r--r--storage/myisam/mi_search.c14
-rw-r--r--storage/tokudb/CMakeLists.txt4
-rw-r--r--storage/tokudb/PerconaFT/CMakeLists.txt7
-rw-r--r--storage/tokudb/PerconaFT/buildheader/make_tdb.cc13
-rw-r--r--storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake10
-rw-r--r--storage/tokudb/PerconaFT/ft/cachetable/background_job_manager.cc9
-rw-r--r--storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc82
-rw-r--r--storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc36
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-ops.cc304
-rw-r--r--storage/tokudb/PerconaFT/ft/ft.cc17
-rw-r--r--storage/tokudb/PerconaFT/ft/loader/callbacks.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/loader/dbufio.cc163
-rw-r--r--storage/tokudb/PerconaFT/ft/loader/loader-internal.h37
-rw-r--r--storage/tokudb/PerconaFT/ft/loader/loader.cc365
-rw-r--r--storage/tokudb/PerconaFT/ft/loader/loader.h5
-rw-r--r--storage/tokudb/PerconaFT/ft/logger/log-internal.h8
-rw-r--r--storage/tokudb/PerconaFT/ft/logger/logcursor.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/logger/logger.cc79
-rw-r--r--storage/tokudb/PerconaFT/ft/logger/recover.cc14
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/block_allocator.cc1
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/block_table.cc13
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc10
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/sub_block.cc3
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/workset.h14
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-4357.cc31
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-4365.cc42
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-5097.cc11
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-5978-2.cc20
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-5978.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-checkpoint-pending.cc24
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-cleaner-thread-attrs-accumulate.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-clone-checkpoint.cc11
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-pin-checkpoint.cc21
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-put-checkpoint.cc21
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-rwlock-test.cc47
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin-nonblocking.cc30
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin.cc30
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-test.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-unpin-remove-and-checkpoint.cc17
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ftloader-test-extractor-errors.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ftloader-test-merge-files-dbufio.cc12
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ftloader-test-writer-errors.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/log-test4.cc13
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/log-test5.cc16
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/log-test6.cc13
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/recovery-bad-last-entry.cc15
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-bjm.cc14
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test3681.cc34
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/roll.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/rollback_log_node_cache.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/txn.cc119
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/txn_child_manager.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/txn_manager.cc10
-rw-r--r--storage/tokudb/PerconaFT/locktree/lock_request.cc2
-rw-r--r--storage/tokudb/PerconaFT/locktree/locktree.cc8
-rw-r--r--storage/tokudb/PerconaFT/locktree/manager.cc10
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_1big7lt_1small.cc10
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_1lt.cc6
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_2lt.cc6
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_stalls.cc13
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/manager_parallel_locktree_get_release.cc3
-rw-r--r--storage/tokudb/PerconaFT/locktree/treenode.cc8
-rw-r--r--storage/tokudb/PerconaFT/portability/CMakeLists.txt5
-rw-r--r--storage/tokudb/PerconaFT/portability/file.cc498
-rw-r--r--storage/tokudb/PerconaFT/portability/memory.cc8
-rw-r--r--storage/tokudb/PerconaFT/portability/portability.cc60
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/rwlock_condvar.h4
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rdlock.cc2
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rwr.cc14
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/test-stat.cc9
-rw-r--r--storage/tokudb/PerconaFT/portability/tests/test-toku-malloc.cc8
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_assert.h14
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc365
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_instr_mysql.h249
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_instrumentation.h339
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_os.h10
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_portability.h328
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_pthread.h450
-rw-r--r--storage/tokudb/PerconaFT/src/indexer-undo-do.cc2
-rw-r--r--storage/tokudb/PerconaFT/src/indexer.cc19
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-first-empty.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-first.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-last.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-next-prev-deadlock.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-next-prev.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-prelock-range.cc13
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-put-timeout.cc17
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-put-wakeup.cc17
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-put.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-set-range-0.cc11
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-set-range-n.cc11
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-set-range-reverse-0.cc11
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-set.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/blocking-table-lock.cc13
-rw-r--r--storage/tokudb/PerconaFT/src/tests/checkpoint_fairness.cc12
-rw-r--r--storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc37
-rw-r--r--storage/tokudb/PerconaFT/src/tests/db-put-simple-deadlock-threads.cc9
-rw-r--r--storage/tokudb/PerconaFT/src/tests/db-put-simple-lockwait.cc7
-rw-r--r--storage/tokudb/PerconaFT/src/tests/db-put-update-deadlock.cc15
-rw-r--r--storage/tokudb/PerconaFT/src/tests/filesize.cc6
-rw-r--r--storage/tokudb/PerconaFT/src/tests/hotindexer-bw.cc26
-rw-r--r--storage/tokudb/PerconaFT/src/tests/hotindexer-multiclient.cc22
-rw-r--r--storage/tokudb/PerconaFT/src/tests/hotindexer-put-abort.cc9
-rw-r--r--storage/tokudb/PerconaFT/src/tests/hotindexer-put-commit.cc14
-rw-r--r--storage/tokudb/PerconaFT/src/tests/hotindexer-with-queries.cc13
-rw-r--r--storage/tokudb/PerconaFT/src/tests/locktree_escalation_stalls.cc13
-rw-r--r--storage/tokudb/PerconaFT/src/tests/recover-test_crash_in_flusher_thread.h19
-rw-r--r--storage/tokudb/PerconaFT/src/tests/recovery_stress.cc15
-rw-r--r--storage/tokudb/PerconaFT/src/tests/stress_openclose.h11
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test3039.cc44
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_1672532.cc210
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_3645.cc46
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_4015.cc14
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_abort1.cc20
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_abort4.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_abort5.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_forkjoin.cc9
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_groupcommit_count.cc14
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_groupcommit_perf.cc14
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_iterate_pending_lock_requests.cc11
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_lock_timeout_callback.cc3
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_log1.cc10
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_log1_abort.cc12
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_logmax.cc21
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_multiple_checkpoints_block_commit.cc15
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_stress_hot_indexing.cc7
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_thread_insert.cc9
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_txn_abort7.cc21
-rw-r--r--storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h49
-rw-r--r--storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc4
-rw-r--r--storage/tokudb/PerconaFT/src/ydb.cc31
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_db.cc105
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_db.h3
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_env_func.cc2
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_txn.cc10
-rw-r--r--storage/tokudb/PerconaFT/tools/CMakeLists.txt1
-rw-r--r--storage/tokudb/PerconaFT/util/dbt.cc3
-rw-r--r--storage/tokudb/PerconaFT/util/fmutex.h6
-rw-r--r--storage/tokudb/PerconaFT/util/frwlock.cc510
-rw-r--r--storage/tokudb/PerconaFT/util/frwlock.h142
-rw-r--r--storage/tokudb/PerconaFT/util/kibbutz.cc28
-rw-r--r--storage/tokudb/PerconaFT/util/minicron.cc31
-rw-r--r--storage/tokudb/PerconaFT/util/nb_mutex.h52
-rw-r--r--storage/tokudb/PerconaFT/util/queue.cc13
-rw-r--r--storage/tokudb/PerconaFT/util/rwlock.h88
-rw-r--r--storage/tokudb/PerconaFT/util/tests/marked-omt-test.cc18
-rw-r--r--storage/tokudb/PerconaFT/util/tests/minicron-test.cc9
-rw-r--r--storage/tokudb/PerconaFT/util/tests/queue-test.cc6
-rw-r--r--storage/tokudb/PerconaFT/util/tests/rwlock_condvar.h6
-rw-r--r--storage/tokudb/PerconaFT/util/tests/sm-basic.cc3
-rw-r--r--storage/tokudb/PerconaFT/util/tests/sm-crash-double-free.cc6
-rw-r--r--storage/tokudb/PerconaFT/util/tests/test-frwlock-fair-writers.cc4
-rw-r--r--storage/tokudb/PerconaFT/util/tests/test-rwlock-cheapness.cc11
-rw-r--r--storage/tokudb/PerconaFT/util/tests/test-rwlock.cc39
-rw-r--r--storage/tokudb/PerconaFT/util/tests/threadpool-test.cc7
-rw-r--r--storage/tokudb/PerconaFT/util/threadpool.cc31
-rw-r--r--storage/tokudb/ha_tokudb.cc139
-rw-r--r--storage/tokudb/ha_tokudb.h16
-rw-r--r--storage/tokudb/ha_tokudb_update.cc4
-rw-r--r--storage/tokudb/hatoku_cmp.cc1
-rw-r--r--storage/tokudb/hatoku_defines.h28
-rw-r--r--storage/tokudb/hatoku_hton.cc52
-rw-r--r--storage/tokudb/hatoku_hton.h5
-rw-r--r--storage/tokudb/mysql-test/tokudb/disabled.def1
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result11
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-1.result13
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-2.result17
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/nonflushing_analyze_debug.result19
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/row_format.result39
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test6
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-1.test23
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-2.test29
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/nonflushing_analyze_debug.test10
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/row_format.test21
-rw-r--r--storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb_parts/disabled.def1
-rw-r--r--storage/tokudb/mysql-test/tokudb_parts/r/nonflushing_analyze_debug.result50
-rw-r--r--storage/tokudb/mysql-test/tokudb_parts/t/nonflushing_analyze_debug.test29
-rw-r--r--storage/tokudb/mysql-test/tokudb_perfschema/r/crash_tokudb.result30
-rw-r--r--storage/tokudb/mysql-test/tokudb_perfschema/r/start_server_tokudb.result114
-rw-r--r--storage/tokudb/mysql-test/tokudb_perfschema/t/crash_tokudb.test36
-rw-r--r--storage/tokudb/mysql-test/tokudb_perfschema/t/start_server_tokudb.test10
-rw-r--r--storage/tokudb/mysql-test/tokudb_perfschema/t/suite.opt1
-rw-r--r--storage/tokudb/tokudb_background.cc30
-rw-r--r--storage/tokudb/tokudb_background.h4
-rw-r--r--storage/tokudb/tokudb_information_schema.cc14
-rw-r--r--storage/tokudb/tokudb_thread.cc1
-rw-r--r--storage/tokudb/tokudb_thread.h298
-rw-r--r--storage/xtradb/api/api0api.cc2
-rw-r--r--storage/xtradb/btr/btr0cur.cc41
-rw-r--r--storage/xtradb/btr/btr0pcur.cc3
-rw-r--r--storage/xtradb/buf/buf0buddy.cc3
-rw-r--r--storage/xtradb/buf/buf0lru.cc140
-rw-r--r--storage/xtradb/buf/buf0rea.cc35
-rw-r--r--storage/xtradb/data/data0type.cc10
-rw-r--r--storage/xtradb/dict/dict0dict.cc1
-rw-r--r--storage/xtradb/dict/dict0mem.cc5
-rw-r--r--storage/xtradb/dict/dict0stats_bg.cc2
-rw-r--r--storage/xtradb/fil/fil0fil.cc22
-rw-r--r--storage/xtradb/fts/fts0fts.cc92
-rw-r--r--storage/xtradb/fts/fts0opt.cc11
-rw-r--r--storage/xtradb/fts/fts0que.cc6
-rw-r--r--storage/xtradb/handler/ha_innodb.cc13
-rw-r--r--storage/xtradb/handler/handler0alter.cc54
-rw-r--r--storage/xtradb/ibuf/ibuf0ibuf.cc4
-rw-r--r--storage/xtradb/include/btr0cur.h12
-rw-r--r--storage/xtradb/include/data0type.h51
-rw-r--r--storage/xtradb/include/data0type.ic56
-rw-r--r--storage/xtradb/include/dict0dict.h14
-rw-r--r--storage/xtradb/include/dict0dict.ic57
-rw-r--r--storage/xtradb/include/dict0mem.h15
-rw-r--r--storage/xtradb/include/dict0stats_bg.h4
-rw-r--r--storage/xtradb/include/fil0fil.h26
-rw-r--r--storage/xtradb/include/log0crypt.h6
-rw-r--r--storage/xtradb/include/log0online.h6
-rw-r--r--storage/xtradb/include/mem0mem.ic12
-rw-r--r--storage/xtradb/include/mtr0mtr.h16
-rw-r--r--storage/xtradb/include/mtr0mtr.ic6
-rw-r--r--storage/xtradb/include/os0file.h35
-rw-r--r--storage/xtradb/include/os0file.ic5
-rw-r--r--storage/xtradb/include/rem0rec.ic3
-rw-r--r--storage/xtradb/include/row0mysql.h12
-rw-r--r--storage/xtradb/include/srv0srv.h10
-rw-r--r--storage/xtradb/include/trx0rec.h5
-rw-r--r--storage/xtradb/include/trx0undo.h13
-rw-r--r--storage/xtradb/include/univ.i10
-rw-r--r--storage/xtradb/lock/lock0lock.cc4
-rw-r--r--storage/xtradb/lock/lock0wait.cc58
-rw-r--r--storage/xtradb/log/log0crypt.cc54
-rw-r--r--storage/xtradb/log/log0log.cc7
-rw-r--r--storage/xtradb/log/log0online.cc6
-rw-r--r--storage/xtradb/mem/mem0mem.cc13
-rw-r--r--storage/xtradb/os/os0file.cc146
-rw-r--r--storage/xtradb/page/page0page.cc2
-rw-r--r--storage/xtradb/rem/rem0rec.cc19
-rw-r--r--storage/xtradb/row/row0ext.cc3
-rw-r--r--storage/xtradb/row/row0ftsort.cc22
-rw-r--r--storage/xtradb/row/row0import.cc9
-rw-r--r--storage/xtradb/row/row0ins.cc33
-rw-r--r--storage/xtradb/row/row0log.cc16
-rw-r--r--storage/xtradb/row/row0merge.cc25
-rw-r--r--storage/xtradb/row/row0mysql.cc25
-rw-r--r--storage/xtradb/row/row0purge.cc4
-rw-r--r--storage/xtradb/row/row0quiesce.cc8
-rw-r--r--storage/xtradb/row/row0row.cc9
-rw-r--r--storage/xtradb/row/row0sel.cc31
-rw-r--r--storage/xtradb/row/row0umod.cc14
-rw-r--r--storage/xtradb/row/row0upd.cc15
-rw-r--r--storage/xtradb/srv/srv0srv.cc10
-rw-r--r--storage/xtradb/trx/trx0purge.cc26
-rw-r--r--storage/xtradb/trx/trx0rec.cc22
-rw-r--r--storage/xtradb/trx/trx0roll.cc9
-rw-r--r--storage/xtradb/trx/trx0undo.cc10
340 files changed, 6869 insertions, 3274 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 69b2ef78316..e283da97c4b 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -61,7 +61,7 @@ IF(UNIX)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -fexceptions -fPIC ")
get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
- SET(CONNECT_SOURCES ${CONNECT_SOURCES} inihandl.c)
+ SET(CONNECT_SOURCES ${CONNECT_SOURCES} inihandl.cpp)
SET(IPHLPAPI_LIBRARY "")
ELSE(NOT UNIX)
SET(CONNECT_SOURCES ${CONNECT_SOURCES}
@@ -228,7 +228,7 @@ int main() {
ENDIF(CONNECT_WITH_ODBC)
#
-# JDBC with MongoDB Java Driver included but disabled
+# JDBC with MongoDB Java Driver included but disabled if without MONGO
#
# OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON)
diff --git a/storage/connect/fmdlex.c b/storage/connect/fmdlex.c
index 64429d9b93e..a8d48a5d3b1 100644
--- a/storage/connect/fmdlex.c
+++ b/storage/connect/fmdlex.c
@@ -529,7 +529,7 @@ YY_DECL
pp->Num = 0;
if (pp->InFmt) {*pp->InFmt = '\0'; pp->InFmt[pp->Outsize -1] = '\0'; }
if (pp->OutFmt) {*pp->OutFmt = '\0'; pp->OutFmt[pp->Outsize -1] = '\0'; }
- pp->Curp = pp->Format;
+ pp->Curp = (char*) pp->Format;
yy_init = 1; /* This is a new input */
diff --git a/storage/connect/global.h b/storage/connect/global.h
index de7a9fb3c03..e4b00786efa 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -217,7 +217,8 @@ DllExport int PlugExit(PGLOBAL); // Plug global termination
DllExport LPSTR PlugRemoveType(LPSTR, LPCSTR);
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR prefix, LPCSTR name, LPCSTR dir);
DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
-DllExport void *PlugAllocMem(PGLOBAL, uint);
+DllExport bool AllocSarea(PGLOBAL, uint);
+DllExport void FreeSarea(PGLOBAL);
DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
DllExport char *PlugDup(PGLOBAL g, const char *str);
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 787ec2affc1..5964b1d049f 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -215,9 +215,9 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
PQRYRES VirColumns(PGLOBAL g, bool info);
PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info);
-#if defined(MONGO_SUPPORT)
+#if defined(JAVA_SUPPORT)
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ url, PTOS topt, bool info);
-#endif // MONGO_SUPPORT
+#endif // JAVA_SUPPORT
int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v);
void PushWarning(PGLOBAL g, THD *thd, int level);
bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, PCSZ host, PCSZ db,
@@ -371,13 +371,6 @@ static MYSQL_THDVAR_BOOL(enable_mongo, PLUGIN_VAR_RQCMDARG,
NULL, NULL, MONGO_ENABLED);
#endif // 0
-#if defined(MONGO_SUPPORT)
-// Enabling MONGO table type
-static MYSQL_THDVAR_BOOL(enable_mongo, PLUGIN_VAR_RQCMDARG,
- "Enabling the MongoDB access",
- NULL, NULL, MONGO_ENABLED);
-#endif // MONGO_SUPPORT
-
#if defined(XMSG) || defined(NEWMSG)
const char *language_names[]=
{
@@ -442,10 +435,6 @@ char *GetJavaWrapper(void)
//bool MongoEnabled(void) { return THDVAR(current_thd, enable_mongo); }
#endif // JAVA_SUPPORT
-#if defined(MONGO_SUPPORT)
-bool MongoEnabled(void) { return THDVAR(current_thd, enable_mongo); }
-#endif // MONGO_SUPPORT
-
extern "C" const char *msglang(void)
{
#if defined(FRENCH)
@@ -3020,7 +3009,9 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
return NULL;
if (!x) {
+ const char *p;
char *s = (ishav) ? havg : body;
+ uint j, k, n;
// Append the value to the filter
switch (args[i]->field_type()) {
@@ -3076,16 +3067,38 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
strcat(s, "'}");
break;
default:
- strcat(s, "'");
- strncat(s, res->ptr(), res->length());
- strcat(s, "'");
- } // endswitch field type
+ j = strlen(s);
+ s[j++] = '\'';
+ p = res->ptr();
+ n = res->length();
+
+ for (k = 0; k < n; k++) {
+ if (p[k] == '\'')
+ s[j++] = '\'';
+
+ s[j++] = p[k];
+ } // endfor k
+
+ s[j++] = '\'';
+ s[j] = 0;
+ } // endswitch field type
} else {
- strcat(s, "'");
- strncat(s, res->ptr(), res->length());
- strcat(s, "'");
- } // endif tty
+ j = strlen(s);
+ s[j++] = '\'';
+ p = res->ptr();
+ n = res->length();
+
+ for (k = 0; k < n; k++) {
+ if (p[k] == '\'')
+ s[j++] = '\'';
+
+ s[j++] = p[k];
+ } // endfor k
+
+ s[j++] = '\'';
+ s[j] = 0;
+ } // endif tty
break;
default:
diff --git a/storage/connect/inihandl.c b/storage/connect/inihandl.cpp
index 0ce0eb9fa0d..96ae0a67a6b 100644
--- a/storage/connect/inihandl.c
+++ b/storage/connect/inihandl.cpp
@@ -37,7 +37,7 @@
// The types and variables used locally
//typedef int bool;
typedef unsigned int uint;
-#define SVP(S) ((S) ? S : "<null>")
+//#define SVP(S) ((S) ? S : "<null>")
#define _strlwr(P) strlwr(P) //OB: changed this line
#define MAX_PATHNAME_LEN 256
#define N_CACHED_PROFILES 10
@@ -61,8 +61,8 @@ void htrc(char const *fmt, ...)
} /* end of htrc */
#else // !TEST_MODULE
// Normal included functions
-extern int trace;
-void htrc(char const *fmt, ...);
+//extern int trace;
+//void htrc(char const *fmt, ...);
#endif // !TEST MODULE
@@ -112,10 +112,11 @@ static PROFILE *MRUProfile[N_CACHED_PROFILES] = {NULL};
//static CRITICAL_SECTION PROFILE_CritSect = CRITICAL_SECTION_INIT("PROFILE_CritSect");
-static const char hex[16] = "0123456789ABCDEF";
+static const char hex[17] = "0123456789ABCDEF";
BOOL WritePrivateProfileString(LPCSTR section, LPCSTR entry,
- LPCSTR string, LPCSTR filename );
+ LPCSTR string, LPCSTR filename);
+
/***********************************************************************
* PROFILE_CopyEntry
*
@@ -254,7 +255,7 @@ static PROFILESECTION *PROFILE_Load( FILE *file )
PROFILESECTION* *next_section;
PROFILEKEY *key, *prev_key, **next_key;
- first_section = malloc(sizeof(*section));
+ first_section = (PROFILESECTION*)malloc(sizeof(*section));
if (first_section == NULL)
return NULL;
@@ -281,7 +282,7 @@ static PROFILESECTION *PROFILE_Load( FILE *file )
*p2 = '\0';
p++;
- if (!(section = malloc(sizeof(*section) + strlen(p))))
+ if (!(section = (PROFILESECTION*)malloc(sizeof(*section) + strlen(p))))
break;
strcpy(section->name, p);
@@ -319,13 +320,13 @@ static PROFILESECTION *PROFILE_Load( FILE *file )
} // endif p2
if (*p || !prev_key || *prev_key->name) {
- if (!(key = malloc(sizeof(*key) + strlen(p))))
+ if (!(key = (PROFILEKEY*)malloc(sizeof(*key) + strlen(p))))
break;
strcpy(key->name, p);
if (p2) {
- key->value = malloc(strlen(p2)+1);
+ key->value = (char*)malloc(strlen(p2)+1);
strcpy(key->value, p2);
} else
key->value = NULL;
@@ -452,7 +453,7 @@ static BOOL PROFILE_Open(LPCSTR filename)
/* First time around */
if (!CurProfile)
for (i = 0; i < N_CACHED_PROFILES; i++) {
- MRUProfile[i] = malloc(sizeof(PROFILE));
+ MRUProfile[i] = (PROFILE*)malloc(sizeof(PROFILE));
if (MRUProfile[i] == NULL)
break;
@@ -520,7 +521,7 @@ static BOOL PROFILE_Open(LPCSTR filename)
// strcpy(newdos_name, filename);
// CurProfile->dos_name = newdos_name;
- CurProfile->filename = malloc(strlen(filename) + 1);
+ CurProfile->filename = (char*)malloc(strlen(filename) + 1);
strcpy(CurProfile->filename, filename);
/* Try to open the profile file, first in $HOME/.wine */
@@ -783,7 +784,7 @@ static PROFILEKEY *PROFILE_Find(PROFILESECTION* *section,
if (!create)
return NULL;
- if (!(*key = malloc(sizeof(PROFILEKEY) + strlen(key_name))))
+ if (!(*key = (PROFILEKEY*)malloc(sizeof(PROFILEKEY) + strlen(key_name))))
return NULL;
strcpy((*key)->name, key_name);
@@ -798,7 +799,7 @@ static PROFILEKEY *PROFILE_Find(PROFILESECTION* *section,
if (!create)
return NULL;
- *section = malloc(sizeof(PROFILESECTION) + strlen(section_name));
+ *section = (PROFILESECTION*)malloc(sizeof(PROFILESECTION) + strlen(section_name));
if (*section == NULL)
return NULL;
@@ -806,7 +807,7 @@ static PROFILEKEY *PROFILE_Find(PROFILESECTION* *section,
strcpy((*section)->name, section_name);
(*section)->next = NULL;
- if (!((*section)->key = malloc(sizeof(PROFILEKEY) + strlen(key_name)))) {
+ if (!((*section)->key = (tagPROFILEKEY*)malloc(sizeof(PROFILEKEY) + strlen(key_name)))) {
free(*section);
return NULL;
} // endif malloc
@@ -1052,7 +1053,7 @@ static BOOL PROFILE_SetString(LPCSTR section_name, LPCSTR key_name,
} else if (trace > 1)
htrc(" creating key\n" );
- key->value = malloc(strlen(value) + 1);
+ key->value = (char*)malloc(strlen(value) + 1);
strcpy(key->value, value);
CurProfile->changed = TRUE;
} // endelse
@@ -1125,7 +1126,7 @@ static int PROFILE_GetPrivateProfileString(LPCSTR section, LPCSTR entry,
if (*p == ' ') { /* ouch, contained trailing ' ' */
int len = p - (LPSTR)def_val;
- pDefVal = malloc(len + 1);
+ pDefVal = (LPSTR)malloc(len + 1);
strncpy(pDefVal, def_val, len);
pDefVal[len] = '\0';
} // endif *p
@@ -1277,7 +1278,7 @@ BOOL WritePrivateProfileSection(LPCSTR section,
ret = TRUE;
while (*string) {
- LPSTR buf = malloc(strlen(string) + 1);
+ LPSTR buf = (LPSTR)malloc(strlen(string) + 1);
strcpy(buf, string);
if ((p = strchr(buf, '='))) {
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 504ea837fee..33af95a2bbc 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -1505,23 +1505,16 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n,
ml += g->More;
if (ml > g->Sarea_Size) {
-#if !defined(DEVELOPMENT)
- if (trace)
-#endif
- htrc("Freeing Sarea at %p size=%d\n", g->Sarea, g->Sarea_Size);
-
- free(g->Sarea);
+ FreeSarea(g);
- if (!(g->Sarea = PlugAllocMem(g, ml))) {
+ if (AllocSarea(g, ml)) {
char errmsg[MAX_STR];
snprintf(errmsg, sizeof(errmsg)-1, MSG(WORK_AREA), g->Message);
strcpy(g->Message, errmsg);
- g->Sarea_Size = 0;
return true;
- } // endif Alloc
+ } // endif SareaAlloc
- g->Sarea_Size = ml;
g->Createas = 0;
g->Xchk = NULL;
initid->max_length = rl;
diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp
index 08bb24e14df..fe00f6a1eab 100644
--- a/storage/connect/myconn.cpp
+++ b/storage/connect/myconn.cpp
@@ -933,8 +933,9 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb)
crp->Prec = (crp->Type == TYPE_DOUBLE || crp->Type == TYPE_DECIM)
? fld->decimals : 0;
- crp->Length = MY_MAX(fld->length, fld->max_length);
- crp->Clen = GetTypeSize(crp->Type, crp->Length);
+ CHARSET_INFO *cs= get_charset(fld->charsetnr, MYF(0));
+ crp->Clen = GetTypeSize(crp->Type, fld->length);
+ crp->Length = fld->length / (cs ? cs->mbmaxlen : 1);
uns = (fld->flags & (UNSIGNED_FLAG | ZEROFILL_FLAG)) ? true : false;
if (!(crp->Kdata = AllocValBlock(g, NULL, crp->Type, m_Rows,
diff --git a/storage/connect/mysql-test/connect/disabled.def b/storage/connect/mysql-test/connect/disabled.def
index 6d59369a4df..0dcf030613d 100644
--- a/storage/connect/mysql-test/connect/disabled.def
+++ b/storage/connect/mysql-test/connect/disabled.def
@@ -19,3 +19,4 @@ json_java_3 : Need MongoDB running and its Java Driver installed
mongo_c : Need MongoDB running and its C Driver installed
mongo_java_2 : Need MongoDB running and its Java Driver installed
mongo_java_3 : Need MongoDB running and its Java Driver installed
+tbl_thread : Bug MDEV-9844,10179,14214 03/01/2018 OB Option THREAD removed
diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp
index 0a6507315db..f669d644637 100644
--- a/storage/connect/plgdbutl.cpp
+++ b/storage/connect/plgdbutl.cpp
@@ -334,7 +334,7 @@ PDBUSER PlgMakeUser(PGLOBAL g)
{
PDBUSER dbuserp;
- if (!(dbuserp = (PDBUSER)PlugAllocMem(g, (uint)sizeof(DBUSERBLK)))) {
+ if (!(dbuserp = (PDBUSER)malloc(sizeof(DBUSERBLK)))) {
sprintf(g->Message, MSG(MALLOC_ERROR), "PlgMakeUser");
return NULL;
} // endif dbuserp
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp
index 0855e265704..7b408870238 100644
--- a/storage/connect/plugutil.cpp
+++ b/storage/connect/plugutil.cpp
@@ -138,7 +138,7 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
if (trace > 1)
htrc("PlugInit: Language='%s'\n",
- ((!Language) ? "Null" : (char*)Language));
+ ((!Language) ? "Null" : (char*)Language));
try {
g = new GLOBAL;
@@ -160,13 +160,11 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
/*******************************************************************/
/* Allocate the main work segment. */
/*******************************************************************/
- if (worksize && !(g->Sarea = PlugAllocMem(g, worksize))) {
+ if (worksize && AllocSarea(g, worksize)) {
char errmsg[MAX_STR];
snprintf(errmsg, sizeof(errmsg) - 1, MSG(WORK_AREA), g->Message);
strcpy(g->Message, errmsg);
- g->Sarea_Size = 0;
- } else
- g->Sarea_Size = worksize;
+ } // endif Sarea
g->jump_level = -1; /* New setting to allow recursive call of Plug */
return(g);
@@ -183,15 +181,7 @@ int PlugExit(PGLOBAL g)
if (dup)
free(dup);
- if (g->Sarea) {
-#if !defined(DEVELOPMENT)
- if (trace)
-#endif
- htrc("Freeing Sarea at %p size=%d\n", g->Sarea, g->Sarea_Size);
-
- free(g->Sarea);
- } // endif Sarea
-
+ FreeSarea(g);
delete g;
} // endif g
@@ -459,30 +449,65 @@ short GetLineLength(PGLOBAL g)
/***********************************************************************/
/* Program for memory allocation of work and language areas. */
/***********************************************************************/
-void *PlugAllocMem(PGLOBAL g, uint size)
+bool AllocSarea(PGLOBAL g, uint size)
{
- void *areap; /* Pointer to allocated area */
-
/*********************************************************************/
/* This is the allocation routine for the WIN32/UNIX/AIX version. */
/*********************************************************************/
- if (!(areap = malloc(size)))
- sprintf(g->Message, MSG(MALLOC_ERROR), "malloc");
+#if defined(__WIN__)
+ if (size >= 1048576) // 1M
+ g->Sarea = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+ else
+#endif
+ g->Sarea = malloc(size);
+
+ if (!g->Sarea) {
+ sprintf(g->Message, MSG(MALLOC_ERROR), "malloc");
+ g->Sarea_Size = 0;
+ } else
+ g->Sarea_Size = size;
#if defined(DEVELOPMENT)
if (true) {
#else
if (trace) {
#endif
- if (areap)
- htrc("Memory of %u allocated at %p\n", size, areap);
+ if (g->Sarea)
+ htrc("Work area of %u allocated at %p\n", size, g->Sarea);
else
- htrc("PlugAllocMem: %s\n", g->Message);
+ htrc("SareaAlloc: %s\n", g->Message);
} // endif trace
- return (areap);
-} // end of PlugAllocMem
+ return (!g->Sarea);
+} // end of AllocSarea
+
+/***********************************************************************/
+/* Program for memory freeing the work area. */
+/***********************************************************************/
+void FreeSarea(PGLOBAL g)
+{
+ if (g->Sarea) {
+#if defined(__WIN__)
+ if (g->Sarea_Size >= 1048576) // 1M
+ VirtualFree(g->Sarea, 0, MEM_RELEASE);
+ else
+#endif
+ free(g->Sarea);
+
+#if defined(DEVELOPMENT)
+ if (true)
+#else
+ if (trace)
+#endif
+ htrc("Freeing Sarea at %p size = %d\n", g->Sarea, g->Sarea_Size);
+
+ g->Sarea = NULL;
+ g->Sarea_Size = 0;
+ } // endif Sarea
+
+ return;
+} // end of FreeSarea
/***********************************************************************/
/* Program for SubSet initialization of memory pools. */
diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp
index d3fb31fb57a..7925e8f29a8 100644
--- a/storage/connect/tabtbl.cpp
+++ b/storage/connect/tabtbl.cpp
@@ -1,12 +1,9 @@
/************* TabTbl C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: TABTBL */
/* ------------- */
-/* Version 1.8 */
+/* Version 1.9 */
/* */
-/* COPYRIGHT: */
-/* ---------- */
-/* (C) Copyright to PlugDB Software Development 2008-2017 */
-/* Author: Olivier BERTRAND */
+/* Author: Olivier BERTRAND 2008-2018 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -168,9 +165,14 @@ PTDB TBLDEF::GetTable(PGLOBAL g, MODE)
{
if (Catfunc == FNC_COL)
return new(g) TDBTBC(this);
- else if (Thread)
- return new(g) TDBTBM(this);
- else
+ else if (Thread) {
+#if defined(DEVELOPMENT)
+ return new(g) TDBTBM(this);
+#else
+ strcpy(g->Message, "Option THREAD is no more supported");
+ return NULL;
+#endif // DEVELOPMENT
+ } else
return new(g) TDBTBL(this);
} // end of GetTable
@@ -560,6 +562,7 @@ void TBTBLK::ReadColumn(PGLOBAL)
} // end of ReadColumn
+#if defined(DEVELOPMENT)
/* ------------------------- Class TDBTBM ---------------------------- */
/***********************************************************************/
@@ -650,7 +653,7 @@ bool TDBTBM::IsLocal(PTABLE tbp)
return ((!stricmp(tdbp->Host, "localhost") ||
!strcmp(tdbp->Host, "127.0.0.1")) &&
- tdbp->Port == (int)GetDefaultPort());
+ (int) tdbp->Port == (int)GetDefaultPort());
} // end of IsLocal
/***********************************************************************/
@@ -865,5 +868,6 @@ int TDBTBM::ReadNextRemote(PGLOBAL g)
return RC_OK;
} // end of ReadNextRemote
+#endif // DEVELOPMENT
/* ------------------------------------------------------------------- */
diff --git a/storage/connect/tabtbl.h b/storage/connect/tabtbl.h
index f02bf620aae..e7a84395787 100644
--- a/storage/connect/tabtbl.h
+++ b/storage/connect/tabtbl.h
@@ -11,30 +11,9 @@
typedef class TBLDEF *PTBLDEF;
typedef class TDBTBL *PTDBTBL;
-typedef class TDBTBM *PTDBTBM;
typedef class MYSQLC *PMYC;
/***********************************************************************/
-/* Defines the structures used for distributed TBM tables. */
-/***********************************************************************/
-typedef struct _TBMtable *PTBMT;
-
-typedef struct _TBMtable {
- PTBMT Next; // Points to next data table struct
- PTABLE Tap; // Points to the sub table
- PGLOBAL G; // Needed in thread routine
- bool Complete; // TRUE when all results are read
- bool Ready; // TRUE when results are there
- int Rows; // Total number of rows read so far
- int ProgCur; // Current pos
- int ProgMax; // Max pos
- int Rc; // Return code
- THD *Thd;
- pthread_attr_t attr; // ???
- pthread_t Tid; // CheckOpen thread ID
- } TBMT;
-
-/***********************************************************************/
/* TBL table. */
/***********************************************************************/
class DllExport TBLDEF : public PRXDEF { /* Logical table description */
@@ -123,7 +102,33 @@ class TBTBLK : public TIDBLK {
protected:
// Must not have additional members
- }; // end of class TBTBLK
+}; // end of class TBTBLK
+
+#if defined(DEVELOPMENT)
+/***********************************************************************/
+/* This table type is buggy and removed until a fix is found. */
+/***********************************************************************/
+typedef class TDBTBM *PTDBTBM;
+
+/***********************************************************************/
+/* Defines the structures used for distributed TBM tables. */
+/***********************************************************************/
+typedef struct _TBMtable *PTBMT;
+
+typedef struct _TBMtable {
+ PTBMT Next; // Points to next data table struct
+ PTABLE Tap; // Points to the sub table
+ PGLOBAL G; // Needed in thread routine
+ bool Complete; // TRUE when all results are read
+ bool Ready; // TRUE when results are there
+ int Rows; // Total number of rows read so far
+ int ProgCur; // Current pos
+ int ProgMax; // Max pos
+ int Rc; // Return code
+ THD *Thd;
+ pthread_attr_t attr; // ???
+ pthread_t Tid; // CheckOpen thread ID
+} TBMT;
/***********************************************************************/
/* This is the TBM Access Method class declaration. */
@@ -160,3 +165,4 @@ class DllExport TDBTBM : public TDBTBL {
}; // end of class TDBTBM
pthread_handler_t ThreadOpen(void *p);
+#endif // DEVELOPMENT
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
index 94d2c8ad5fd..cb62667c0fe 100644
--- a/storage/connect/user_connect.cc
+++ b/storage/connect/user_connect.cc
@@ -156,29 +156,20 @@ void user_connect::SetHandler(ha_connect *hc)
bool user_connect::CheckCleanup(bool force)
{
if (thdp->query_id > last_query_id || force) {
- uint worksize= GetWorkSize();
+ uint worksize= GetWorkSize(), size = g->Sarea_Size;
PlugCleanup(g, true);
- if (g->Sarea_Size != worksize) {
- if (g->Sarea) {
-#if !defined(DEVELOPMENT)
- if (trace)
-#endif
- htrc("CheckCleanup: Free Sarea at %p size=%d\n",
- g->Sarea, g->Sarea_Size);
-
- free(g->Sarea);
- } // endif Size
+ if (size != worksize) {
+ FreeSarea(g);
// Check whether the work area could be allocated
- if (!(g->Sarea = PlugAllocMem(g, worksize))) {
- g->Sarea = PlugAllocMem(g, g->Sarea_Size);
+ if (AllocSarea(g, worksize)) {
+ AllocSarea(g, size);
SetWorkSize(g->Sarea_Size); // Was too big
- } else
- g->Sarea_Size = worksize; // Ok
+ } // endif sarea
- } // endif worksize
+ } // endif worksize
PlugSubSet(g, g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h
index abf25abe0c5..f3af7258623 100644
--- a/storage/federatedx/ha_federatedx.h
+++ b/storage/federatedx/ha_federatedx.h
@@ -169,7 +169,7 @@ public:
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return alloc_root(mem_root, size); }
static void operator delete(void *ptr, size_t size)
- { TRASH(ptr, size); }
+ { TRASH_FREE(ptr, size); }
virtual int query(const char *buffer, uint length)=0;
virtual FEDERATEDX_IO_RESULT *store_result()=0;
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index 970c503497f..3513ddb4c2f 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -91,6 +91,15 @@ ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
+ if (table->s->reclength < sizeof (char*))
+ {
+ MEM_UNDEFINED(table->s->default_values + table->s->reclength,
+ sizeof(char*) - table->s->reclength);
+ table->s->reclength= sizeof(char*);
+ MEM_UNDEFINED(table->record[0], table->s->reclength);
+ MEM_UNDEFINED(table->record[1], table->s->reclength);
+ }
+
internal_table= MY_TEST(test_if_locked & HA_OPEN_INTERNAL_TABLE);
if (internal_table || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
{
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index ad231236804..7eecefc90fd 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 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
@@ -520,3 +520,4 @@ MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE
MODULE_OUTPUT_NAME ha_innodb
LINK_LIBRARIES ${ZLIB_LIBRARY} ${LIBSYSTEMD} ${LINKER_SCRIPT})
+ADD_DEPENDENCIES(innobase GenError)
diff --git a/storage/innobase/api/api0api.cc b/storage/innobase/api/api0api.cc
index bc83e98374f..fd14fdefd18 100644
--- a/storage/innobase/api/api0api.cc
+++ b/storage/innobase/api/api0api.cc
@@ -398,7 +398,7 @@ ib_read_tuple(
data = btr_rec_copy_externally_stored_field(
copy, offsets, zip_size, i, &len,
- tuple->heap, NULL);
+ tuple->heap);
ut_a(len != UNIV_SQL_NULL);
}
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index bb010190af7..09d84d1ecbc 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -3792,8 +3792,7 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
ulint mode1, /*!< in: search mode for range start */
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
- ulint mode2, /*!< in: search mode for range end */
- trx_t* trx) /*!< in: trx */
+ ulint mode2) /*!< in: search mode for range end */
{
btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS];
btr_path_t path2[BTR_PATH_ARRAY_N_SLOTS];
@@ -3811,7 +3810,7 @@ btr_estimate_n_rows_in_range(
table_n_rows = dict_table_get_n_rows(index->table);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
cursor.path_arr = path1;
@@ -3833,7 +3832,7 @@ btr_estimate_n_rows_in_range(
return (0);
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
cursor.path_arr = path2;
@@ -5466,8 +5465,7 @@ btr_copy_blob_prefix(
ulint len, /*!< in: length of buf, in bytes */
ulint space_id,/*!< in: space id of the BLOB pages */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset, /*!< in: offset on the first BLOB page */
- trx_t* trx) /*!< in: transaction handle */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
ulint copied_len = 0;
@@ -5479,7 +5477,7 @@ btr_copy_blob_prefix(
ulint part_len;
ulint copy_len;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
block = buf_page_get(space_id, 0, page_no, RW_S_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
@@ -5682,8 +5680,7 @@ btr_copy_externally_stored_field_prefix_low(
zero for uncompressed BLOBs */
ulint space_id,/*!< in: space id of the first BLOB page */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset, /*!< in: offset on the first BLOB page */
- trx_t* trx) /*!< in: transaction handle */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
if (UNIV_UNLIKELY(len == 0)) {
return(0);
@@ -5694,7 +5691,7 @@ btr_copy_externally_stored_field_prefix_low(
space_id, page_no, offset));
} else {
return(btr_copy_blob_prefix(buf, len, space_id,
- page_no, offset, trx));
+ page_no, offset));
}
}
@@ -5715,8 +5712,7 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len,/*!< in: length of data, in bytes */
- trx_t* trx) /*!< in: transaction handle */
+ ulint local_len)/*!< in: length of data, in bytes */
{
ulint space_id;
ulint page_no;
@@ -5755,7 +5751,7 @@ btr_copy_externally_stored_field_prefix(
len - local_len,
zip_size,
space_id, page_no,
- offset, trx));
+ offset));
}
/*******************************************************************//**
@@ -5774,8 +5770,7 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx) /*!< in: transaction handle */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint space_id;
ulint page_no;
@@ -5806,8 +5801,7 @@ btr_copy_externally_stored_field(
extern_len,
zip_size,
space_id,
- page_no, offset,
- trx);
+ page_no, offset);
return(buf);
}
@@ -5826,8 +5820,7 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx) /*!< in: transaction handle */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint local_len;
const byte* data;
@@ -5858,7 +5851,6 @@ btr_rec_copy_externally_stored_field(
}
return(btr_copy_externally_stored_field(len, data,
- zip_size, local_len, heap,
- trx));
+ zip_size, local_len, heap));
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc
index ff80cfb29ad..5ba9409a7b1 100644
--- a/storage/innobase/btr/btr0pcur.cc
+++ b/storage/innobase/btr/btr0pcur.cc
@@ -496,7 +496,7 @@ btr_pcur_move_backward_from_page(
mtr_commit(mtr);
- mtr_start_trx(mtr, mtr->trx);
+ mtr_start(mtr);
btr_pcur_restore_position(latch_mode2, cursor, mtr);
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc
index f2ab73217e0..7a441b4239a 100644
--- a/storage/innobase/buf/buf0buddy.cc
+++ b/storage/innobase/buf/buf0buddy.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -649,7 +650,7 @@ buf_buddy_free_low(
buf_pool->buddy_stat[i].used--;
recombine:
- UNIV_MEM_ASSERT_AND_ALLOC(buf, BUF_BUDDY_LOW << i);
+ UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i);
if (i == BUF_BUDDY_SIZES) {
buf_buddy_block_free(buf_pool, buf);
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index 703c425e127..793d6cdd68e 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -613,6 +613,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 "
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index a047b28f4fd..9e89a291c80 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -90,6 +90,10 @@ during LRU eviction. */
frames in the buffer pool, we set this to TRUE */
static ibool buf_lru_switched_on_innodb_mon = FALSE;
+/** True if diagnostic message about difficult to find free blocks
+in the buffer bool has already printed. */
+static bool buf_lru_free_blocks_error_printed;
+
/******************************************************************//**
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics,
@@ -1045,8 +1049,6 @@ buf_LRU_get_free_block(
ibool freed = FALSE;
ulint n_iterations = 0;
ulint flush_failures = 0;
- ibool mon_value_was = FALSE;
- ibool started_monitor = FALSE;
MONITOR_INC(MONITOR_LRU_GET_FREE_SEARCH);
loop:
@@ -1054,6 +1056,11 @@ loop:
buf_LRU_check_size_of_non_data_objects(buf_pool);
+ DBUG_EXECUTE_IF("ib_lru_force_no_free_page",
+ if (!buf_lru_free_blocks_error_printed) {
+ n_iterations = 21;
+ goto not_found;});
+
/* If there is a block in the free list, take it */
block = buf_LRU_get_free_only(buf_pool);
@@ -1062,16 +1069,11 @@ loop:
buf_pool_mutex_exit(buf_pool);
ut_ad(buf_pool_from_block(block) == buf_pool);
memset(&block->page.zip, 0, sizeof block->page.zip);
-
- if (started_monitor) {
- srv_print_innodb_monitor =
- static_cast<my_bool>(mon_value_was);
- }
-
return(block);
}
freed = FALSE;
+
if (buf_pool->try_LRU_scan || n_iterations > 0) {
/* If no block was in the free list, search from the
end of the LRU list and try to free a block there.
@@ -1094,6 +1096,10 @@ loop:
}
}
+#ifndef DBUG_OFF
+not_found:
+#endif
+
buf_pool_mutex_exit(buf_pool);
if (freed) {
@@ -1101,40 +1107,26 @@ loop:
}
- if (n_iterations > 20) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: difficult to find free blocks in\n"
- "InnoDB: the buffer pool (%lu search iterations)!\n"
- "InnoDB: %lu failed attempts to flush a page!"
- " Consider\n"
- "InnoDB: increasing the buffer pool size.\n"
- "InnoDB: It is also possible that"
- " in your Unix version\n"
- "InnoDB: fsync is very slow, or"
- " completely frozen inside\n"
- "InnoDB: the OS kernel. Then upgrading to"
- " a newer version\n"
- "InnoDB: of your operating system may help."
- " Look at the\n"
- "InnoDB: number of fsyncs in diagnostic info below.\n"
- "InnoDB: Pending flushes (fsync) log: %lu;"
- " buffer pool: %lu\n"
- "InnoDB: %lu OS file reads, %lu OS file writes,"
- " %lu OS fsyncs\n"
- "InnoDB: Starting InnoDB Monitor to print further\n"
- "InnoDB: diagnostics to the standard output.\n",
- (ulong) n_iterations,
- (ulong) flush_failures,
- (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);
-
- mon_value_was = srv_print_innodb_monitor;
- started_monitor = TRUE;
- srv_print_innodb_monitor = TRUE;
- os_event_set(srv_monitor_event);
+ if (n_iterations > 20 && !buf_lru_free_blocks_error_printed) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Difficult to find free blocks in"
+ " the buffer pool (" ULINTPF " search iterations)! "
+ ULINTPF " failed attempts to flush a page!",
+ n_iterations, flush_failures);
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Consider increasing the buffer pool size.");
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Pending flushes (fsync) log: " ULINTPF
+ " buffer pool: " ULINTPF
+ " OS file reads: " ULINTPF " OS file writes: "
+ ULINTPF " OS fsyncs: " ULINTPF "",
+ fil_n_pending_log_flushes,
+ fil_n_pending_tablespace_flushes,
+ os_n_file_reads,
+ os_n_file_writes,
+ os_n_fsyncs);
+
+ buf_lru_free_blocks_error_printed = true;
}
/* If we have scanned the whole LRU and still are unable to
@@ -1916,8 +1908,7 @@ buf_LRU_block_free_non_file_page(
UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page));
ut_d(block->page.in_free_list = TRUE);
-
- UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
+ UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE);
}
/******************************************************************//**
diff --git a/storage/innobase/data/data0type.cc b/storage/innobase/data/data0type.cc
index 0b9e08544a5..34ca399f9b2 100644
--- a/storage/innobase/data/data0type.cc
+++ b/storage/innobase/data/data0type.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -49,8 +50,10 @@ ulint
dtype_get_at_most_n_mbchars(
/*========================*/
ulint prtype, /*!< in: precise type */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of
+ a multi-byte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of
+ a multi-byte character, in bytes */
ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
@@ -58,9 +61,6 @@ dtype_get_at_most_n_mbchars(
const char* str) /*!< in: the string whose prefix
length is being determined */
{
- ulint mbminlen = DATA_MBMINLEN(mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen);
-
ut_a(data_len != UNIV_SQL_NULL);
ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen));
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 8d7c1275c3b..7ec4364becc 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -3398,6 +3398,7 @@ dict_foreign_find_index(
if (types_idx != index
&& !(index->type & DICT_FTS)
&& !index->to_be_dropped
+ && !dict_index_is_online_ddl(index)
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
index, types_idx,
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index 0e5e9f65b04..dd8155c09eb 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -319,8 +319,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
@@ -532,7 +532,8 @@ dict_mem_fill_column_struct(
column->len = (unsigned int) col_len;
#ifndef UNIV_HOTBACKUP
dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
- dict_col_set_mbminmaxlen(column, mbminlen, mbmaxlen);
+ column->mbminlen = mbminlen;
+ column->mbmaxlen = mbmaxlen;
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index c9ecf3dab0b..b4102e48628 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -2074,7 +2074,7 @@ fil_write_flushed_lsn(
{
byte* buf1;
byte* buf;
- dberr_t err;
+ dberr_t err = DB_TABLESPACE_NOT_FOUND;
buf1 = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
buf = static_cast<byte*>(ut_align(buf1, UNIV_PAGE_SIZE));
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 2ba58c9a590..dc121083c6e 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -2001,7 +2001,7 @@ fts_create_one_index_table(
? DATA_VARCHAR : DATA_VARMYSQL,
field->col->prtype,
FTS_MAX_WORD_LEN_IN_CHAR
- * DATA_MBMAXLEN(field->col->mbminmaxlen));
+ * field->col->mbmaxlen);
dict_mem_table_add_col(new_table, heap, "first_doc_id", DATA_INT,
DATA_NOT_NULL | DATA_UNSIGNED,
@@ -3362,8 +3362,7 @@ fts_fetch_doc_from_rec(
dict_table_zip_size(table),
clust_pos, &doc->text.f_len,
static_cast<mem_heap_t*>(
- doc->self_heap->arg),
- NULL);
+ doc->self_heap->arg));
} else {
doc->text.f_str = (byte*) rec_get_nth_field(
clust_rec, offsets, clust_pos,
@@ -4762,9 +4761,17 @@ fts_process_token(
t_str.f_str = static_cast<byte*>(
mem_heap_alloc(heap, t_str.f_len));
- newlen = innobase_fts_casedn_str(
- doc->charset, (char*) str.f_str, str.f_len,
- (char*) t_str.f_str, t_str.f_len);
+ /* For binary collations, a case sensitive search is
+ performed. Hence don't convert to lower case. */
+ if (my_binary_compare(result_doc->charset)) {
+ memcpy(t_str.f_str, str.f_str, str.f_len);
+ t_str.f_str[str.f_len]= 0;
+ newlen= str.f_len;
+ } else {
+ newlen = innobase_fts_casedn_str(
+ doc->charset, (char*) str.f_str, str.f_len,
+ (char*) t_str.f_str, t_str.f_len);
+ }
t_str.f_len = newlen;
t_str.f_str[newlen] = 0;
@@ -7592,8 +7599,7 @@ fts_init_recover_doc(
&doc.text.f_len,
static_cast<byte*>(dfield_get_data(dfield)),
zip_size, len,
- static_cast<mem_heap_t*>(doc.self_heap->arg),
- NULL);
+ static_cast<mem_heap_t*>(doc.self_heap->arg));
} else {
doc.text.f_str = static_cast<byte*>(
dfield_get_data(dfield));
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index b874309964b..3a543836837 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -1917,8 +1917,7 @@ fts_query_fetch_document(
if (dfield_is_ext(dfield)) {
data = btr_copy_externally_stored_field(
&cur_len, data, phrase->zip_size,
- dfield_get_len(dfield), phrase->heap,
- NULL);
+ dfield_get_len(dfield), phrase->heap);
} else {
cur_len = dfield_get_len(dfield);
}
@@ -3763,10 +3762,19 @@ fts_query_str_preprocess(
str_len = query_len * charset->casedn_multiply + 1;
str_ptr = static_cast<byte*>(ut_malloc(str_len));
- *result_len = innobase_fts_casedn_str(
- charset, const_cast<char*>(reinterpret_cast<const char*>(
- query_str)), query_len,
- reinterpret_cast<char*>(str_ptr), str_len);
+ /* For binary collations, a case sensitive search is
+ performed. Hence don't convert to lower case. */
+ if (my_binary_compare(charset)) {
+ memcpy(str_ptr, query_str, query_len);
+ str_ptr[query_len]= 0;
+ *result_len= query_len;
+ } else {
+ *result_len = innobase_fts_casedn_str(
+ charset, const_cast<char*>
+ (reinterpret_cast<const char*>( query_str)),
+ query_len,
+ reinterpret_cast<char*>(str_ptr), str_len);
+ }
ut_ad(*result_len < str_len);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index a45b63d0159..b66f74873a9 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -3094,13 +3094,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
@@ -13109,7 +13109,7 @@ ha_innobase::records_in_range(
n_rows = btr_estimate_n_rows_in_range(index, range_start,
mode1, range_end,
- mode2, prebuilt->trx);
+ mode2);
} else {
n_rows = HA_POS_ERROR;
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index bdc4987b5c9..f8e61631dfe 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -1197,8 +1197,7 @@ innobase_col_to_mysql(
#ifdef UNIV_DEBUG
case DATA_MYSQL:
ut_ad(flen >= len);
- ut_ad(DATA_MBMAXLEN(col->mbminmaxlen)
- >= DATA_MBMINLEN(col->mbminmaxlen));
+ ut_ad(col->mbmaxlen >= col->mbminlen);
memcpy(dest, data, len);
break;
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index c621ed5f71a..2b406e116b0 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -4603,7 +4603,7 @@ ibuf_merge_or_delete_for_page(
function. When the counter is > 0, that prevents tablespace
from being dropped. */
- space = fil_space_acquire(space_id);
+ space = fil_space_acquire_silent(space_id);
if (UNIV_UNLIKELY(!space)) {
/* Do not try to read the bitmap page from space;
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 30010da9d8f..51ff300fa1f 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -566,8 +566,7 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
ulint mode1, /*!< in: search mode for range start */
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
- ulint mode2, /*!< in: search mode for range end */
- trx_t* trx); /*!< in: trx */
+ ulint mode2); /*!< in: search mode for range end */
/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where 1 <= n <= dict_index_get_n_unique(index).
@@ -703,8 +702,7 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len,/*!< in: length of data, in bytes */
- trx_t* trx); /*!< in: transaction handle */
+ ulint local_len);/*!< in: length of data, in bytes */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap. The
clustered index record must be protected by a lock or a page latch.
@@ -721,8 +719,7 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx); /*!< in: transaction handle */
+ mem_heap_t* heap); /*!< in: mem heap */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap.
@return the field copied to heap, or NULL if the field is incomplete */
@@ -737,8 +734,7 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx); /*!< in: transaction handle */
+ mem_heap_t* heap); /*!< in: mem heap */
/*******************************************************************//**
Flags the data tuple fields that are marked as extern storage in the
update vector. We use this function to remember which fields we must
diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h
index 111664b0b52..28182782105 100644
--- a/storage/innobase/include/data0type.h
+++ b/storage/innobase/include/data0type.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -181,18 +182,7 @@ store the charset-collation number; one byte is left unused, though */
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
/* Maximum multi-byte character length in bytes, plus 1 */
-#define DATA_MBMAX 5
-
-/* Pack mbminlen, mbmaxlen to mbminmaxlen. */
-#define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \
- ((mbmaxlen) * DATA_MBMAX + (mbminlen))
-/* Get mbminlen from mbminmaxlen. Cast the result of UNIV_EXPECT to ulint
-because in GCC it returns a long. */
-#define DATA_MBMINLEN(mbminmaxlen) ((ulint) \
- UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \
- 1))
-/* Get mbmaxlen from mbminmaxlen. */
-#define DATA_MBMAXLEN(mbminmaxlen) ((ulint) ((mbminmaxlen) / DATA_MBMAX))
+#define DATA_MBMAX 8
/* We now support 15 bits (up to 32767) collation number */
#define MAX_CHAR_COLL_NUM 32767
@@ -219,8 +209,10 @@ ulint
dtype_get_at_most_n_mbchars(
/*========================*/
ulint prtype, /*!< in: precise type */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of
+ a multi-byte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of
+ a multi-byte character, in bytes */
ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
@@ -365,19 +357,6 @@ dtype_get_mbmaxlen(
/*===============*/
const dtype_t* type); /*!< in: type */
/*********************************************************************//**
-Sets the minimum and maximum length of a character, in bytes. */
-UNIV_INLINE
-void
-dtype_set_mbminmaxlen(
-/*==================*/
- dtype_t* type, /*!< in/out: type */
- ulint mbminlen, /*!< in: minimum length of a char,
- in bytes, or 0 if this is not
- a character type */
- ulint mbmaxlen); /*!< in: maximum length of a char,
- in bytes, or 0 if this is not
- a character type */
-/*********************************************************************//**
Gets the padding character code for the type.
@return padding character code, or ULINT_UNDEFINED if no padding specified */
UNIV_INLINE
@@ -397,7 +376,9 @@ dtype_get_fixed_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of a
+ ulint mbminlen, /*!< in: minimum length of a
+ multibyte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of a
multibyte character, in bytes */
ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
#ifndef UNIV_HOTBACKUP
@@ -411,8 +392,8 @@ dtype_get_min_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen); /*!< in: minimum and maximum length of a
- multibyte character */
+ ulint mbminlen, /*!< in: minimum length of a character */
+ ulint mbmaxlen); /*!< in: maximum length of a character */
/***********************************************************************//**
Returns the maximum size of a data type. Note: types in system tables may be
incomplete and return incorrect information.
@@ -529,11 +510,10 @@ struct dtype_t{
the string, MySQL uses 1 or 2
bytes to store the string length) */
#ifndef UNIV_HOTBACKUP
- unsigned mbminmaxlen:5; /*!< minimum and maximum length of a
- character, in bytes;
- DATA_MBMINMAXLEN(mbminlen,mbmaxlen);
- mbminlen=DATA_MBMINLEN(mbminmaxlen);
- mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */
+ unsigned mbminlen:3; /*!< minimum length of a character,
+ in bytes */
+ unsigned mbmaxlen:3; /*!< maximum length of a character,
+ in bytes */
#endif /* !UNIV_HOTBACKUP */
};
diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic
index bf433036e61..eaa90f6d33a 100644
--- a/storage/innobase/include/data0type.ic
+++ b/storage/innobase/include/data0type.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -104,27 +104,6 @@ dtype_get_mblen(
}
/*********************************************************************//**
-Sets the minimum and maximum length of a character, in bytes. */
-UNIV_INLINE
-void
-dtype_set_mbminmaxlen(
-/*==================*/
- dtype_t* type, /*!< in/out: type */
- ulint mbminlen, /*!< in: minimum length of a char,
- in bytes, or 0 if this is not
- a character type */
- ulint mbmaxlen) /*!< in: maximum length of a char,
- in bytes, or 0 if this is not
- a character type */
-{
- ut_ad(mbminlen < DATA_MBMAX);
- ut_ad(mbmaxlen < DATA_MBMAX);
- ut_ad(mbminlen <= mbmaxlen);
-
- type->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen);
-}
-
-/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
@@ -136,7 +115,8 @@ dtype_set_mblen(
ulint mbmaxlen;
dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen);
- dtype_set_mbminmaxlen(type, mbminlen, mbmaxlen);
+ type->mbminlen = mbminlen;
+ type->mbmaxlen = mbmaxlen;
ut_ad(dtype_validate(type));
}
@@ -232,8 +212,7 @@ dtype_get_mbminlen(
/*===============*/
const dtype_t* type) /*!< in: type */
{
- ut_ad(type);
- return(DATA_MBMINLEN(type->mbminmaxlen));
+ return type->mbminlen;
}
/*********************************************************************//**
Gets the maximum length of a character, in bytes.
@@ -245,8 +224,7 @@ dtype_get_mbmaxlen(
/*===============*/
const dtype_t* type) /*!< in: type */
{
- ut_ad(type);
- return(DATA_MBMAXLEN(type->mbminmaxlen));
+ return type->mbmaxlen;
}
/*********************************************************************//**
@@ -522,8 +500,10 @@ dtype_get_fixed_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multibyte character, in bytes */
+ ulint mbminlen, /*!< in: minimum length of a
+ multibyte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of a
+ multibyte character, in bytes */
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
switch (mtype) {
@@ -564,11 +544,10 @@ dtype_get_fixed_size_low(
dtype_get_charset_coll(prtype),
&i_mbminlen, &i_mbmaxlen);
- ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen)
- == mbminmaxlen);
+ ut_ad(i_mbminlen == mbminlen);
+ ut_ad(i_mbmaxlen == mbmaxlen);
#endif /* UNIV_DEBUG */
- if (DATA_MBMINLEN(mbminmaxlen)
- == DATA_MBMAXLEN(mbminmaxlen)) {
+ if (mbminlen == mbmaxlen) {
return(len);
}
}
@@ -601,8 +580,8 @@ dtype_get_min_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen) /*!< in: minimum and maximum length of a
- multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of a character */
+ ulint mbmaxlen) /*!< in: maximum length of a character */
{
switch (mtype) {
case DATA_SYS:
@@ -632,9 +611,6 @@ dtype_get_min_size_low(
if (prtype & DATA_BINARY_TYPE) {
return(len);
} else {
- ulint mbminlen = DATA_MBMINLEN(mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen);
-
if (mbminlen == mbmaxlen) {
return(len);
}
@@ -705,9 +681,9 @@ dtype_get_sql_null_size(
{
#ifndef UNIV_HOTBACKUP
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- type->mbminmaxlen, comp));
+ type->mbminlen, type->mbmaxlen, comp));
#else /* !UNIV_HOTBACKUP */
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- 0, 0));
+ 0, 0, 0));
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 0d5ade1631e..7011f4a9226 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2015, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -197,18 +197,6 @@ dict_col_get_mbmaxlen(
const dict_col_t* col) /*!< in: column */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
-Sets the minimum and maximum number of bytes per character. */
-UNIV_INLINE
-void
-dict_col_set_mbminmaxlen(
-/*=====================*/
- dict_col_t* col, /*!< in/out: column */
- ulint mbminlen, /*!< in: minimum multi-byte
- character size, in bytes */
- ulint mbmaxlen) /*!< in: minimum multi-byte
- character size, in bytes */
- MY_ATTRIBUTE((nonnull));
-/*********************************************************************//**
Gets the column data type. */
UNIV_INLINE
void
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index 22b96a58f66..bc72d441081 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -41,7 +41,7 @@ dict_col_get_mbminlen(
/*==================*/
const dict_col_t* col) /*!< in: column */
{
- return(DATA_MBMINLEN(col->mbminmaxlen));
+ return col->mbminlen;
}
/*********************************************************************//**
Gets the maximum number of bytes per character.
@@ -52,25 +52,7 @@ dict_col_get_mbmaxlen(
/*==================*/
const dict_col_t* col) /*!< in: column */
{
- return(DATA_MBMAXLEN(col->mbminmaxlen));
-}
-/*********************************************************************//**
-Sets the minimum and maximum number of bytes per character. */
-UNIV_INLINE
-void
-dict_col_set_mbminmaxlen(
-/*=====================*/
- dict_col_t* col, /*!< in/out: column */
- ulint mbminlen, /*!< in: minimum multi-byte
- character size, in bytes */
- ulint mbmaxlen) /*!< in: minimum multi-byte
- character size, in bytes */
-{
- ut_ad(mbminlen < DATA_MBMAX);
- ut_ad(mbmaxlen < DATA_MBMAX);
- ut_ad(mbminlen <= mbmaxlen);
-
- col->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen);
+ return col->mbmaxlen;
}
/*********************************************************************//**
Gets the column data type. */
@@ -87,7 +69,8 @@ dict_col_copy_type(
type->mtype = col->mtype;
type->prtype = col->prtype;
type->len = col->len;
- type->mbminmaxlen = col->mbminmaxlen;
+ type->mbminlen = col->mbminlen;
+ type->mbmaxlen = col->mbmaxlen;
}
#endif /* !UNIV_HOTBACKUP */
@@ -109,7 +92,8 @@ dict_col_type_assert_equal(
ut_ad(col->prtype == type->prtype);
//ut_ad(col->len == type->len);
# ifndef UNIV_HOTBACKUP
- ut_ad(col->mbminmaxlen == type->mbminmaxlen);
+ ut_ad(col->mbminlen == type->mbminlen);
+ ut_ad(col->mbmaxlen == type->mbmaxlen);
# endif /* !UNIV_HOTBACKUP */
return(TRUE);
@@ -127,7 +111,7 @@ dict_col_get_min_size(
const dict_col_t* col) /*!< in: column */
{
return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
- col->mbminmaxlen));
+ col->mbminlen, col->mbmaxlen));
}
/***********************************************************************//**
Returns the maximum size of the column.
@@ -152,7 +136,7 @@ dict_col_get_fixed_size(
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
- col->mbminmaxlen, comp));
+ col->mbminlen, col->mbmaxlen, comp));
}
/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 9a6cc0aa0c1..3c9bd80431e 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -526,11 +526,10 @@ struct dict_col_t{
the string, MySQL uses 1 or 2
bytes to store the string length) */
- unsigned mbminmaxlen:5; /*!< minimum and maximum length of a
- character, in bytes;
- DATA_MBMINMAXLEN(mbminlen,mbmaxlen);
- mbminlen=DATA_MBMINLEN(mbminmaxlen);
- mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */
+ unsigned mbminlen:3; /*!< minimum length of a
+ character, in bytes */
+ unsigned mbmaxlen:3; /*!< maximum length of a
+ character, in bytes */
/*----------------------*/
/* End of definitions copied from dtype_t */
/* @} */
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 81f207d1e20..312b09e1f2d 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
diff --git a/storage/innobase/include/log0crypt.h b/storage/innobase/include/log0crypt.h
index 0ad7e7d7037..b7a221e0a81 100644
--- a/storage/innobase/include/log0crypt.h
+++ b/storage/innobase/include/log0crypt.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (C) 2014, 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2014, 2018, 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
@@ -73,6 +73,8 @@ log_encrypt_before_write(
/*=====================*/
ib_uint64_t next_checkpoint_no, /*!< in: log group to be flushed */
byte* block, /*!< in/out: pointer to a log block */
+ lsn_t lsn, /*!< in: log sequence number of
+ the start of the buffer */
const ulint size); /*!< in: size of log blocks */
/********************************************************
@@ -83,6 +85,8 @@ void
log_decrypt_after_read(
/*===================*/
byte* frame, /*!< in/out: log segment */
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
const ulint size); /*!< in: log segment size */
/* Error codes for crypt info */
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index 63e68150b61..2b4638718fd 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -305,8 +305,8 @@ mem_heap_free_heap_top(
mem_block_set_free(block, old_top - (byte*) block);
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
- UNIV_MEM_ASSERT_W(old_top, (byte*) block + block->len - old_top);
#if defined UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top);
/* In the debug version erase block from top up */
mem_erase_buf(old_top, (byte*) block + block->len - old_top);
@@ -315,7 +315,7 @@ mem_heap_free_heap_top(
mem_current_allocated_memory -= (total_size - size);
mutex_exit(&mem_hash_mutex);
#endif /* UNIV_MEM_DEBUG */
- UNIV_MEM_ALLOC(old_top, (byte*) block + block->len - old_top);
+ UNIV_MEM_FREE(old_top, (byte*)block + block->len - old_top);
/* If free == start, we may free the block if it is not the first
one */
@@ -396,11 +396,11 @@ mem_heap_free_top(
/* Subtract the free field of block */
mem_block_set_free(block, mem_block_get_free(block)
- MEM_SPACE_NEEDED(n));
- UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n);
#ifdef UNIV_MEM_DEBUG
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
+ UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
/* In the debug version check the consistency, and erase field */
mem_field_erase((byte*) block + mem_block_get_free(block), n);
#endif
@@ -412,11 +412,7 @@ mem_heap_free_top(
== mem_block_get_start(block))) {
mem_heap_block_free(heap, block);
} else {
- /* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a
- subsequent invocation of mem_heap_free_top().
- Originally, this was UNIV_MEM_FREE(), to catch writes
- to freed memory. */
- UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
+ UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n);
}
}
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index c3307985532..1df9fba5e9e 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -36,7 +36,6 @@ Created 11/26/1995 Heikki Tuuri
#include "ut0byte.h"
#include "mtr0types.h"
#include "page0types.h"
-#include "trx0types.h"
/* Logging modes for a mini-transaction */
#define MTR_LOG_ALL 21 /* default mode: log all operations
@@ -214,22 +213,10 @@ functions). The page number parameter was originally written as 0. @{ */
Starts a mini-transaction. */
UNIV_INLINE
void
-mtr_start_trx(
-/*======*/
- mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx) /*!< in: transaction */
- MY_ATTRIBUTE((nonnull (1)));
-/***************************************************************//**
-Starts a mini-transaction. */
-UNIV_INLINE
-void
mtr_start(
/*======*/
mtr_t* mtr) /*!< out: mini-transaction */
-{
- mtr_start_trx(mtr, NULL);
-}
- MY_ATTRIBUTE((nonnull))
+ MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Commits a mini-transaction. */
UNIV_INTERN
@@ -437,7 +424,6 @@ struct mtr_t{
#ifdef UNIV_DEBUG
ulint magic_n;
#endif /* UNIV_DEBUG */
- trx_t* trx; /*!< transaction */
};
#ifdef UNIV_DEBUG
diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic
index 37cea34d4eb..3f897ae1d10 100644
--- a/storage/innobase/include/mtr0mtr.ic
+++ b/storage/innobase/include/mtr0mtr.ic
@@ -43,10 +43,9 @@ mtr_block_dirtied(
Starts a mini-transaction. */
UNIV_INLINE
void
-mtr_start_trx(
+mtr_start(
/*======*/
- mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx) /*!< in: transaction */
+ mtr_t* mtr) /*!< out: mini-transaction */
{
UNIV_MEM_INVALID(mtr, sizeof *mtr);
@@ -59,7 +58,6 @@ mtr_start_trx(
mtr->made_dirty = FALSE;
mtr->n_log_recs = 0;
mtr->n_freed_pages = 0;
- mtr->trx = trx;
ut_d(mtr->state = MTR_ACTIVE);
ut_d(mtr->magic_n = MTR_MAGIC_N);
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
index 5811a77a48b..89f6902059d 100644
--- a/storage/innobase/include/rem0rec.ic
+++ b/storage/innobase/include/rem0rec.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -922,7 +923,7 @@ rec_offs_set_n_alloc(
{
ut_ad(offsets);
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
- UNIV_MEM_ASSERT_AND_ALLOC(offsets, n_alloc * sizeof *offsets);
+ UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets);
offsets[0] = n_alloc;
}
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index 71e3b9bb19e..a38e9b6b3d5 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -589,18 +589,6 @@ void
row_mysql_close(void);
/*=================*/
-/*********************************************************************//**
-Reassigns the table identifier of a table.
-@return error code or DB_SUCCESS */
-UNIV_INTERN
-dberr_t
-row_mysql_table_id_reassign(
-/*========================*/
- dict_table_t* table, /*!< in/out: table */
- trx_t* trx, /*!< in/out: transaction */
- table_id_t* new_id) /*!< out: new table id */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-
/* A struct describing a place for an individual column in the MySQL
row format which is presented to the table handler in ha_innobase.
This template struct is used to speed up row transformations between
diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h
index 630818a8648..ec15250ec7b 100644
--- a/storage/innobase/include/trx0rec.h
+++ b/storage/innobase/include/trx0rec.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -196,6 +196,7 @@ trx_undo_rec_get_partial_row(
used, as we do NOT copy the data in the
record! */
dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: updated columns */
dtuple_t** row, /*!< out, own: partial row */
ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h
index 42ac62916e0..266ca32548c 100644
--- a/storage/innobase/include/trx0undo.h
+++ b/storage/innobase/include/trx0undo.h
@@ -246,13 +246,22 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end(
+trx_undo_truncate_end_func(
/*=======================*/
- trx_t* trx, /*!< in: transaction whose undo log it is */
+#ifdef UNIV_DEBUG
+ const trx_t* trx, /*!< in: transaction whose undo log it is */
+#endif /* UNIV_DEBUG */
trx_undo_t* undo, /*!< in/out: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
MY_ATTRIBUTE((nonnull));
+#ifdef UNIV_DEBUG
+# define trx_undo_truncate_end(trx,undo,limit) \
+ trx_undo_truncate_end_func(trx,undo,limit)
+#else /* UNIV_DEBUG */
+# define trx_undo_truncate_end(trx,undo,limit) \
+ trx_undo_truncate_end_func(undo,limit)
+#endif /* UNIV_DEBUG */
/***********************************************************************//**
Truncates an undo log from the start. This function is used during a purge
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index f00cb179f56..24bcab56870 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -677,14 +677,6 @@ typedef void* os_thread_ret_t;
# define UNIV_MEM_ASSERT_W(addr, size) do {} while(0)
# define UNIV_MEM_TRASH(addr, c, size) do {} while(0)
#endif
-#define UNIV_MEM_ASSERT_AND_FREE(addr, size) do { \
- UNIV_MEM_ASSERT_W(addr, size); \
- UNIV_MEM_FREE(addr, size); \
-} while (0)
-#define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) do { \
- UNIV_MEM_ASSERT_W(addr, size); \
- UNIV_MEM_ALLOC(addr, size); \
-} while (0)
extern ulong srv_page_size_shift;
extern ulong srv_page_size;
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index cdf517ce176..ffdb13ddf43 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 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
@@ -291,6 +291,7 @@ UNIV_INTERN
ulint
ut_time_ms(void);
/*============*/
+
#endif /* !UNIV_HOTBACKUP */
/**********************************************************//**
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 61385891b76..64e7a8b96ad 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation
+Copyright (c) 2014, 2018, 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
@@ -6910,7 +6910,7 @@ lock_rec_block_validate(
/* Make sure that the tablespace is not deleted while we are
trying to access the page. */
- if (fil_space_t* space = fil_space_acquire(space_id)) {
+ if (fil_space_t* space = fil_space_acquire_silent(space_id)) {
mtr_start(&mtr);
block = buf_page_get_gen(
diff --git a/storage/innobase/log/log0crypt.cc b/storage/innobase/log/log0crypt.cc
index 13d69118779..ec3c72cab43 100644
--- a/storage/innobase/log/log0crypt.cc
+++ b/storage/innobase/log/log0crypt.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (C) 2014, 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2014, 2018, 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
@@ -71,22 +71,6 @@ struct crypt_info_t {
static std::deque<crypt_info_t> crypt_info;
/*********************************************************************//**
-Get a log block's start lsn.
-@return a log block's start lsn */
-static inline
-lsn_t
-log_block_get_start_lsn(
-/*====================*/
- lsn_t lsn, /*!< in: checkpoint lsn */
- ulint log_block_no) /*!< in: log block number */
-{
- lsn_t start_lsn =
- (lsn & (lsn_t)0xffffffff00000000ULL) |
- (((log_block_no - 1) & (lsn_t)0x3fffffff) << 9);
- return start_lsn;
-}
-
-/*********************************************************************//**
Get crypt info from checkpoint.
@return a crypt info or NULL if not present. */
static
@@ -162,6 +146,8 @@ Crypt_result
log_blocks_crypt(
/*=============*/
const byte* block, /*!< in: blocks before encrypt/decrypt*/
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
ulint size, /*!< in: size of block */
byte* dst_block, /*!< out: blocks after encrypt/decrypt */
int what, /*!< in: encrypt or decrypt*/
@@ -171,21 +157,18 @@ log_blocks_crypt(
Crypt_result rc = MY_AES_OK;
uint dst_len;
byte aes_ctr_counter[MY_AES_BLOCK_SIZE];
- byte is_encrypt= what == ENCRYPTION_FLAG_ENCRYPT;
- lsn_t lsn = is_encrypt ? log_sys->lsn : srv_start_lsn;
const uint src_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE;
- for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE) {
+ for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE,
+ lsn += OS_FILE_LOG_BLOCK_SIZE) {
ulint log_block_no = log_block_get_hdr_no(log_block);
- lsn_t log_block_start_lsn = log_block_get_start_lsn(
- lsn, log_block_no);
const crypt_info_t* info = crypt_info == NULL ? get_crypt_info(log_block) :
crypt_info;
#ifdef DEBUG_CRYPT
fprintf(stderr,
"%s %lu chkpt: %lu key: %u lsn: %lu\n",
- is_encrypt ? "crypt" : "decrypt",
+ what == ENCRYPTION_FLAG_ENCRYPT ? "crypt" : "decrypt",
log_block_no,
log_block_get_checkpoint_no(log_block),
info ? info->key_version : 0,
@@ -214,7 +197,7 @@ log_blocks_crypt(
// (1-byte, only 5 bits are used). "+" means concatenate.
bzero(aes_ctr_counter, MY_AES_BLOCK_SIZE);
memcpy(aes_ctr_counter, info->crypt_nonce, 3);
- mach_write_to_8(aes_ctr_counter + 3, log_block_start_lsn);
+ mach_write_to_8(aes_ctr_counter + 3, lsn);
mach_write_to_4(aes_ctr_counter + 11, log_block_no);
bzero(aes_ctr_counter + 15, 1);
@@ -460,19 +443,6 @@ add_crypt_info(
}
/*********************************************************************//**
-Encrypt log blocks. */
-UNIV_INTERN
-Crypt_result
-log_blocks_encrypt(
-/*===============*/
- const byte* block, /*!< in: blocks before encryption */
- const ulint size, /*!< in: size of blocks, must be multiple of a log block */
- byte* dst_block) /*!< out: blocks after encryption */
-{
- return log_blocks_crypt(block, size, dst_block, ENCRYPTION_FLAG_ENCRYPT, NULL);
-}
-
-/*********************************************************************//**
Set next checkpoint's key version to latest one, and generate current
key. Key version 0 means no encryption. */
UNIV_INTERN
@@ -523,6 +493,8 @@ log_encrypt_before_write(
/*=====================*/
ib_uint64_t next_checkpoint_no, /*!< in: log group to be flushed */
byte* block, /*!< in/out: pointer to a log block */
+ lsn_t lsn, /*!< in: log sequence number of
+ the start of the buffer */
const ulint size) /*!< in: size of log blocks */
{
ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0);
@@ -541,7 +513,8 @@ log_encrypt_before_write(
byte* dst_frame = (byte*)malloc(size);
//encrypt log blocks content
- Crypt_result result = log_blocks_crypt(block, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT, NULL);
+ Crypt_result result = log_blocks_crypt(
+ block, lsn, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT, NULL);
if (result == MY_AES_OK) {
ut_ad(block[0] == dst_frame[0]);
@@ -561,13 +534,16 @@ void
log_decrypt_after_read(
/*===================*/
byte* frame, /*!< in/out: log segment */
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
const ulint size) /*!< in: log segment size */
{
ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0);
byte* dst_frame = (byte*)malloc(size);
// decrypt log blocks content
- Crypt_result result = log_blocks_crypt(frame, size, dst_frame, ENCRYPTION_FLAG_DECRYPT, NULL);
+ Crypt_result result = log_blocks_crypt(
+ frame, lsn, size, dst_frame, ENCRYPTION_FLAG_DECRYPT, NULL);
if (result == MY_AES_OK) {
memcpy(frame, dst_frame, size);
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 1c9cbc3a219..7a242b76e85 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -1380,7 +1380,7 @@ loop:
ut_a(next_offset / UNIV_PAGE_SIZE <= ULINT_MAX);
log_encrypt_before_write(log_sys->next_checkpoint_no,
- buf, write_len);
+ buf, start_lsn, write_len);
fil_io(OS_FILE_WRITE | OS_FILE_LOG, true, group->space_id, 0,
(ulint) (next_offset / UNIV_PAGE_SIZE),
@@ -2335,7 +2335,7 @@ loop:
log_block_get_checksum(buf), source_offset);
#endif
- log_decrypt_after_read(buf, len);
+ log_decrypt_after_read(buf, start_lsn, len);
#ifdef DEBUG_CRYPT
fprintf(stderr, "AFTER DECRYPT: block: %lu checkpoint: %lu %.8lx %.8lx\n",
@@ -2576,7 +2576,8 @@ loop:
MONITOR_INC(MONITOR_LOG_IO);
//TODO (jonaso): This must be dead code??
- log_encrypt_before_write(log_sys->next_checkpoint_no, buf, len);
+ log_encrypt_before_write(log_sys->next_checkpoint_no,
+ buf, start_lsn, len);
fil_io(OS_FILE_WRITE | OS_FILE_LOG, false, group->archive_space_id,
(ulint) (next_offset / UNIV_PAGE_SIZE),
diff --git a/storage/innobase/mem/mem0mem.cc b/storage/innobase/mem/mem0mem.cc
index e066aff5b30..b9f190509ee 100644
--- a/storage/innobase/mem/mem0mem.cc
+++ b/storage/innobase/mem/mem0mem.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -506,13 +507,13 @@ mem_heap_block_free(
#ifndef UNIV_HOTBACKUP
if (!srv_use_sys_malloc) {
#ifdef UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*) block, len);
-#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ mem_erase_buf((byte*)block, len);
#endif /* UNIV_MEM_DEBUG */
+ UNIV_MEM_FREE(block, len);
}
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
@@ -526,13 +527,13 @@ mem_heap_block_free(
}
#else /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*) block, len);
-#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ mem_erase_buf((byte*)block, len);
#endif /* UNIV_MEM_DEBUG */
+ UNIV_MEM_FREE(block, len);
ut_free(block);
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index b6bbe3347bd..af32d0519e2 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -861,13 +862,10 @@ rec_get_converted_size_comp_prefix_low(
if (fixed_len) {
#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
-
ut_ad(len <= fixed_len);
- ut_ad(!mbmaxlen || len >= mbminlen
- * (fixed_len / mbmaxlen));
+ ut_ad(!col->mbmaxlen || len >= col->mbminlen
+ * (fixed_len / col->mbmaxlen));
/* dict_index_add_col() should guarantee this */
ut_ad(!field->prefix_len
@@ -1254,14 +1252,10 @@ rec_convert_dtuple_to_rec_comp(
it is 128 or more, or when the field is stored externally. */
if (fixed_len) {
#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(
- ifield->col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(
- ifield->col->mbminmaxlen);
-
ut_ad(len <= fixed_len);
- ut_ad(!mbmaxlen || len >= mbminlen
- * (fixed_len / mbmaxlen));
+ ut_ad(!ifield->col->mbmaxlen
+ || len >= ifield->col->mbminlen
+ * (fixed_len / ifield->col->mbmaxlen));
ut_ad(!dfield_is_ext(field));
#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(field)) {
diff --git a/storage/innobase/row/row0ext.cc b/storage/innobase/row/row0ext.cc
index ad852577ad2..32b78391d6a 100644
--- a/storage/innobase/row/row0ext.cc
+++ b/storage/innobase/row/row0ext.cc
@@ -78,8 +78,7 @@ row_ext_cache_fill(
crashed during the execution of
btr_free_externally_stored_field(). */
ext->len[i] = btr_copy_externally_stored_field_prefix(
- buf, ext->max_len, zip_size, field, f_len,
- NULL);
+ buf, ext->max_len, zip_size, field, f_len);
}
}
}
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 40ddb3a6a87..5ab577ce020 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -103,8 +103,9 @@ row_merge_create_fts_sort_index(
field->col->prtype = idx_field->col->prtype | DATA_NOT_NULL;
field->col->mtype = charset == &my_charset_latin1
? DATA_VARCHAR : DATA_VARMYSQL;
- field->col->mbminmaxlen = idx_field->col->mbminmaxlen;
- field->col->len = HA_FT_MAXCHARLEN * DATA_MBMAXLEN(field->col->mbminmaxlen);
+ field->col->mbminlen = idx_field->col->mbminlen;
+ field->col->mbmaxlen = idx_field->col->mbmaxlen;
+ field->col->len = HA_FT_MAXCHARLEN * field->col->mbmaxlen;
field->fixed_len = 0;
@@ -147,7 +148,8 @@ row_merge_create_fts_sort_index(
field->col->prtype = DATA_NOT_NULL | DATA_BINARY_TYPE;
- field->col->mbminmaxlen = 0;
+ field->col->mbminlen = 0;
+ field->col->mbmaxlen = 0;
/* The third field is on the word's position in the original doc */
field = dict_index_get_nth_field(new_index, 2);
@@ -159,7 +161,8 @@ row_merge_create_fts_sort_index(
field->col->len = 4 ;
field->fixed_len = 4;
field->col->prtype = DATA_NOT_NULL;
- field->col->mbminmaxlen = 0;
+ field->col->mbminlen = 0;
+ field->col->mbmaxlen = 0;
return(new_index);
}
@@ -537,7 +540,8 @@ row_merge_fts_doc_tokenize(
field->type.mtype = DATA_INT;
field->type.prtype = DATA_NOT_NULL | DATA_BINARY_TYPE;
field->type.len = len;
- field->type.mbminmaxlen = 0;
+ field->type.mbminlen = 0;
+ field->type.mbmaxlen = 0;
cur_len += len;
dfield_dup(field, buf->heap);
@@ -556,7 +560,8 @@ row_merge_fts_doc_tokenize(
field->type.mtype = DATA_INT;
field->type.prtype = DATA_NOT_NULL;
field->type.len = len;
- field->type.mbminmaxlen = 0;
+ field->type.mbminlen = 0;
+ field->type.mbmaxlen = 0;
cur_len += len;
dfield_dup(field, buf->heap);
@@ -706,8 +711,7 @@ loop:
doc.text.f_str =
btr_copy_externally_stored_field(
&doc.text.f_len, data,
- zip_size, data_len, blob_heap,
- NULL);
+ zip_size, data_len, blob_heap);
} else {
doc.text.f_str = data;
doc.text.f_len = data_len;
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 9cf55699d3f..cc5fe0acf92 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -1258,7 +1258,8 @@ row_import::match_table_columns(
err = DB_ERROR;
}
- if (cfg_col->mbminmaxlen != col->mbminmaxlen) {
+ if (cfg_col->mbminlen != col->mbminlen
+ || cfg_col->mbmaxlen != col->mbmaxlen) {
ib_errf(thd,
IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
@@ -2876,7 +2877,9 @@ row_import_read_columns(
col->len = mach_read_from_4(ptr);
ptr += sizeof(ib_uint32_t);
- col->mbminmaxlen = mach_read_from_4(ptr);
+ ulint mbminmaxlen = mach_read_from_4(ptr);
+ col->mbmaxlen = mbminmaxlen / 5;
+ col->mbminlen = mbminmaxlen % 5;
ptr += sizeof(ib_uint32_t);
col->ind = mach_read_from_4(ptr);
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index bc369ad444b..c50eaa2a653 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -565,7 +565,8 @@ row_ins_cascade_calc_update_vec(
if (!dfield_is_null(&ufield->new_val)
&& dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype,
+ col->mbminlen, col->mbmaxlen,
col->len,
ufield_len,
static_cast<char*>(
@@ -1324,7 +1325,7 @@ row_ins_foreign_check_on_constraint(
row_mysql_freeze_data_dictionary(thr_get_trx(thr));
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
/* Restore pcur position */
@@ -1352,7 +1353,7 @@ nonstandard_exit_func:
btr_pcur_store_position(pcur, mtr);
mtr_commit(mtr);
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr);
@@ -1565,7 +1566,7 @@ run_again:
}
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Store old value on n_fields_cmp */
@@ -2360,7 +2361,7 @@ row_ins_clust_index_entry_low(
|| n_uniq == dict_index_get_n_unique(index));
ut_ad(!n_uniq || n_uniq == dict_index_get_n_unique(index));
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_LEAF && dict_index_is_online_ddl(index)) {
mode = BTR_MODIFY_LEAF | BTR_ALREADY_S_LATCHED;
@@ -2579,10 +2580,9 @@ Starts a mini-transaction and checks if the index will be dropped.
@return true if the index is to be dropped */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
bool
-row_ins_sec_mtr_start_trx_and_check_if_aborted(
+row_ins_sec_mtr_start_and_check_if_aborted(
/*=======================================*/
mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx, /*!< in: transaction handle */
dict_index_t* index, /*!< in/out: secondary index */
bool check, /*!< in: whether to check */
ulint search_mode)
@@ -2590,7 +2590,7 @@ row_ins_sec_mtr_start_trx_and_check_if_aborted(
{
ut_ad(!dict_index_is_clust(index));
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
if (!check) {
return(false);
@@ -2648,14 +2648,13 @@ row_ins_sec_index_entry_low(
ulint n_unique;
mtr_t mtr;
ulint* offsets = NULL;
- trx_t* trx = thr_get_trx(thr);
ut_ad(!dict_index_is_clust(index));
ut_ad(mode == BTR_MODIFY_LEAF || mode == BTR_MODIFY_TREE);
cursor.thr = thr;
ut_ad(thr_get_trx(thr)->id);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Ensure that we acquire index->lock when inserting into an
index with index->online_status == ONLINE_INDEX_COMPLETE, but
@@ -2693,7 +2692,7 @@ row_ins_sec_index_entry_low(
if (err != DB_SUCCESS) {
if (err == DB_DECRYPTION_FAILED) {
- ib_push_warning(trx->mysql_thd,
+ ib_push_warning(thr_get_trx(thr)->mysql_thd,
DB_DECRYPTION_FAILED,
"Table %s is encrypted but encryption service or"
" used key_id is not available. "
@@ -2729,8 +2728,8 @@ row_ins_sec_index_entry_low(
DEBUG_SYNC_C("row_ins_sec_index_unique");
- if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
- &mtr, trx, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_and_check_if_aborted(
+ &mtr, index, check, search_mode)) {
goto func_exit;
}
@@ -2764,8 +2763,8 @@ row_ins_sec_index_entry_low(
return(err);
}
- if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
- &mtr, trx, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_and_check_if_aborted(
+ &mtr, index, check, search_mode)) {
goto func_exit;
}
@@ -3074,7 +3073,7 @@ row_ins_index_entry_set_vals(
= dict_field_get_col(ind_field);
len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype, col->mbminlen, col->mbmaxlen,
ind_field->prefix_len,
len,
static_cast<const char*>(
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 49627a65014..fd5a13bbaab 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -1064,7 +1064,7 @@ row_log_table_get_pk_col(
mem_heap_alloc(heap, field_len));
len = btr_copy_externally_stored_field_prefix(
- blob_field, field_len, zip_size, field, len, NULL);
+ blob_field, field_len, zip_size, field, len);
if (len >= max_len + 1) {
return(DB_TOO_BIG_INDEX_COL);
}
@@ -1183,7 +1183,7 @@ row_log_table_get_pk(
dict_field_t* ifield;
dfield_t* dfield;
ulint prtype;
- ulint mbminmaxlen;
+ ulint mbminlen, mbmaxlen;
ifield = dict_index_get_nth_field(new_index, new_i);
dfield = dtuple_get_nth_field(tuple, new_i);
@@ -1212,7 +1212,8 @@ err_exit:
goto func_exit;
}
- mbminmaxlen = col->mbminmaxlen;
+ mbminlen = col->mbminlen;
+ mbmaxlen = col->mbmaxlen;
prtype = col->prtype;
} else {
/* No matching column was found in the old
@@ -1222,7 +1223,8 @@ err_exit:
dfield_copy(dfield, dtuple_get_nth_field(
log->add_cols, col_no));
- mbminmaxlen = dfield->type.mbminmaxlen;
+ mbminlen = dfield->type.mbminlen;
+ mbmaxlen = dfield->type.mbmaxlen;
prtype = dfield->type.prtype;
}
@@ -1231,7 +1233,7 @@ err_exit:
if (ifield->prefix_len) {
ulint len = dtype_get_at_most_n_mbchars(
- prtype, mbminmaxlen,
+ prtype, mbminlen, mbmaxlen,
ifield->prefix_len,
dfield_get_len(dfield),
static_cast<const char*>(
@@ -1455,7 +1457,7 @@ row_log_table_apply_convert_mrec(
data = btr_rec_copy_externally_stored_field(
mrec, offsets,
dict_table_zip_size(index->table),
- i, &len, heap, NULL);
+ i, &len, heap);
ut_a(data);
dfield_set_data(dfield, data, len);
blob_done:
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index f4120e5fd90..80ab10cdbc0 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2014, 2018, 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
@@ -267,8 +267,8 @@ row_merge_buf_redundant_convert(
ulint zip_size,
mem_heap_t* heap)
{
- ut_ad(DATA_MBMINLEN(field->type.mbminmaxlen) == 1);
- ut_ad(DATA_MBMAXLEN(field->type.mbminmaxlen) > 1);
+ ut_ad(field->type.mbminlen == 1);
+ ut_ad(field->type.mbmaxlen > 1);
byte* buf = (byte*) mem_heap_alloc(heap, len);
ulint field_len = row_field->len;
@@ -284,7 +284,7 @@ row_merge_buf_redundant_convert(
field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE));
byte* data = btr_copy_externally_stored_field(
- &ext_len, field_data, zip_size, field_len, heap, NULL);
+ &ext_len, field_data, zip_size, field_len, heap);
ut_ad(ext_len < len);
@@ -394,7 +394,8 @@ row_merge_buf_add(
field->type.mtype = ifield->col->mtype;
field->type.prtype = ifield->col->prtype;
- field->type.mbminmaxlen = DATA_MBMINMAXLEN(0, 0);
+ field->type.mbminlen = 0;
+ field->type.mbmaxlen = 0;
field->type.len = ifield->col->len;
} else {
row_field = dtuple_get_nth_field(row, col_no);
@@ -529,7 +530,7 @@ row_merge_buf_add(
if (ifield->prefix_len) {
len = dtype_get_at_most_n_mbchars(
col->prtype,
- col->mbminmaxlen,
+ col->mbminlen, col->mbmaxlen,
ifield->prefix_len,
len,
static_cast<char*>(dfield_get_data(field)));
@@ -540,8 +541,7 @@ row_merge_buf_add(
fixed_len = ifield->fixed_len;
if (fixed_len && !dict_table_is_comp(index->table)
- && DATA_MBMINLEN(col->mbminmaxlen)
- != DATA_MBMAXLEN(col->mbminmaxlen)) {
+ && col->mbminlen != col->mbmaxlen) {
/* CHAR in ROW_FORMAT=REDUNDANT is always
fixed-length, but in the temporary file it is
variable-length for variable-length character
@@ -551,14 +551,11 @@ row_merge_buf_add(
if (fixed_len) {
#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
-
/* len should be between size calcualted base on
mbmaxlen and mbminlen */
ut_ad(len <= fixed_len);
- ut_ad(!mbmaxlen || len >= mbminlen
- * (fixed_len / mbmaxlen));
+ ut_ad(!col->mbmaxlen || len >= col->mbminlen
+ * (fixed_len / col->mbmaxlen));
ut_ad(!dfield_is_ext(field));
#endif /* UNIV_DEBUG */
@@ -2623,7 +2620,7 @@ row_merge_copy_blobs(
BLOB pointers are read (row_merge_read_clustered_index())
and dereferenced (below). */
data = btr_rec_copy_externally_stored_field(
- mrec, offsets, zip_size, i, &len, heap, NULL);
+ mrec, offsets, zip_size, i, &len, heap);
/* Because we have locked the table, any records
written by incomplete transactions must have been
rolled back already. There must not be any incomplete
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index b78a8b58ac8..36ca5c7767b 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -1986,7 +1986,7 @@ row_unlock_for_mysql(
trx_id_t rec_trx_id;
mtr_t mtr;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Restore the cursor position and find the record */
@@ -2871,7 +2871,7 @@ func_exit:
/*********************************************************************//**
Reassigns the table identifier of a table.
@return error code or DB_SUCCESS */
-UNIV_INTERN
+static
dberr_t
row_mysql_table_id_reassign(
/*========================*/
@@ -3562,7 +3562,7 @@ row_truncate_table_for_mysql(
index = dict_table_get_next_index(index);
} while (index);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
fsp_header_init(space_id,
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
@@ -3591,7 +3591,7 @@ row_truncate_table_for_mysql(
sys_index = dict_table_get_first_index(dict_sys->sys_indexes);
dict_index_copy_types(tuple, sys_index, 1);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_MODIFY_LEAF, &pcur, &mtr);
for (;;) {
@@ -3638,7 +3638,7 @@ row_truncate_table_for_mysql(
a page in this mini-transaction, and the rest of
this loop could latch another index page. */
mtr_commit(&mtr);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
btr_pcur_restore_position(BTR_MODIFY_LEAF,
&pcur, &mtr);
}
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 1ed8b7377d9..98504b1e973 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -823,7 +823,7 @@ err_exit:
if (!(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
ptr = trx_undo_rec_get_partial_row(
- ptr, clust_index, &node->row,
+ ptr, clust_index, node->update, &node->row,
type == TRX_UNDO_UPD_DEL_REC,
node->heap);
}
diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc
index 6c4e6adb96c..53b4040f74e 100644
--- a/storage/innobase/row/row0quiesce.cc
+++ b/storage/innobase/row/row0quiesce.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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,7 +237,11 @@ row_quiesce_write_table(
mach_write_to_4(ptr, col->len);
ptr += sizeof(ib_uint32_t);
- mach_write_to_4(ptr, col->mbminmaxlen);
+ /* FIXME: This will not work if mbminlen>4.
+ This field is also redundant, because the lengths
+ are a property of the character set encoding, which
+ in turn is encodedin prtype above. */
+ mach_write_to_4(ptr, col->mbmaxlen * 5 + col->mbminlen);
ptr += sizeof(ib_uint32_t);
mach_write_to_4(ptr, col->ind);
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index 96d25e15777..9bf9e7182ca 100644
--- a/storage/innobase/row/row0row.cc
+++ b/storage/innobase/row/row0row.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -173,7 +174,7 @@ row_build_index_entry_low(
/* If a column prefix index, take only the prefix. */
if (ind_field->prefix_len) {
len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype, col->mbminlen, col->mbmaxlen,
ind_field->prefix_len, len,
static_cast<char*>(dfield_get_data(dfield)));
dfield_set_len(dfield, len);
@@ -588,7 +589,8 @@ row_build_row_ref(
dfield_set_len(dfield,
dtype_get_at_most_n_mbchars(
dtype->prtype,
- dtype->mbminmaxlen,
+ dtype->mbminlen,
+ dtype->mbmaxlen,
clust_col_prefix_len,
len, (char*) field));
}
@@ -702,7 +704,8 @@ notfound:
dfield_set_len(dfield,
dtype_get_at_most_n_mbchars(
dtype->prtype,
- dtype->mbminmaxlen,
+ dtype->mbminlen,
+ dtype->mbmaxlen,
clust_col_prefix_len,
len, (char*) field));
}
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index d309cf4c742..6cca3e21c79 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -94,8 +94,10 @@ row_sel_sec_rec_is_for_blob(
/*========================*/
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of
+ a character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of
+ a character, in bytes */
const byte* clust_field, /*!< in: the locally stored part of
the clustered index column, including
the BLOB pointer; the clustered
@@ -134,8 +136,7 @@ row_sel_sec_rec_is_for_blob(
len = btr_copy_externally_stored_field_prefix(buf, prefix_len,
zip_size,
- clust_field, clust_len,
- NULL);
+ clust_field, clust_len);
if (UNIV_UNLIKELY(len == 0)) {
/* The BLOB was being deleted as the server crashed.
@@ -146,7 +147,7 @@ row_sel_sec_rec_is_for_blob(
return(FALSE);
}
- len = dtype_get_at_most_n_mbchars(prtype, mbminmaxlen,
+ len = dtype_get_at_most_n_mbchars(prtype, mbminlen, mbmaxlen,
prefix_len, len, (const char*) buf);
return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
@@ -230,14 +231,14 @@ row_sel_sec_rec_is_for_clust_rec(
}
len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype, col->mbminlen, col->mbmaxlen,
ifield->prefix_len, len, (char*) clust_field);
if (rec_offs_nth_extern(clust_offs, clust_pos)
&& len < sec_len) {
if (!row_sel_sec_rec_is_for_blob(
col->mtype, col->prtype,
- col->mbminmaxlen,
+ col->mbminlen, col->mbmaxlen,
clust_field, clust_len,
sec_field, sec_len,
ifield->prefix_len,
@@ -454,7 +455,7 @@ row_sel_fetch_columns(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(index->table),
- field_no, &len, heap, NULL);
+ field_no, &len, heap);
/* data == NULL means that the
externally stored field was not
@@ -1401,7 +1402,7 @@ table_loop:
/* Open a cursor to index, or restore an open cursor position */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (consistent_read && plan->unique_search && !plan->pcur_is_open
&& !plan->must_get_clust
@@ -1441,7 +1442,7 @@ table_loop:
plan_reset_cursor(plan);
mtr_commit(&mtr);
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
}
if (search_latch_locked) {
@@ -2812,7 +2813,7 @@ row_sel_store_mysql_field_func(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(prebuilt->table),
- field_no, &len, heap, NULL);
+ field_no, &len, heap);
if (UNIV_UNLIKELY(!data)) {
/* The externally stored field was not written
@@ -3930,7 +3931,7 @@ row_search_for_mysql(
}
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/*-------------------------------------------------------------*/
/* PHASE 2: Try fast adaptive hash index search if possible */
@@ -4061,7 +4062,7 @@ release_search_latch_if_needed:
}
mtr_commit(&mtr);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
}
}
@@ -5137,7 +5138,7 @@ next_rec:
mtr_commit(&mtr);
mtr_has_extra_clust_latch = FALSE;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
if (sel_restore_position_for_mysql(&same_user_rec,
BTR_SEARCH_LEAF,
pcur, moves_up, &mtr)) {
@@ -5204,7 +5205,7 @@ lock_table_wait:
/* It was a lock wait, and it ended */
thr->lock_state = QUE_THR_LOCK_NOLOCK;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Table lock waited, go try to obtain table lock
again */
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index 4aa5cfdc4da..6c5e808cc38 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -299,7 +299,7 @@ row_undo_mod_clust(
pcur = &node->pcur;
index = btr_cur_get_index(btr_pcur_get_btr_cur(pcur));
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
online = dict_index_is_online_ddl(index);
if (online) {
@@ -328,7 +328,7 @@ row_undo_mod_clust(
/* We may have to modify tree structure: do a pessimistic
descent down the index tree */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
err = row_undo_mod_clust_low(
node, &offsets, &offsets_heap,
@@ -380,7 +380,7 @@ row_undo_mod_clust(
if (err == DB_SUCCESS && node->rec_type == TRX_UNDO_UPD_DEL_REC) {
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
/* It is not necessary to call row_log_table,
because the record is delete-marked and would thus
@@ -393,7 +393,7 @@ row_undo_mod_clust(
/* We may have to modify tree structure: do a
pessimistic descent down the index tree */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
err = row_undo_mod_remove_clust_low(node, thr, &mtr,
BTR_MODIFY_TREE);
@@ -440,7 +440,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
enum row_search_result search_result;
log_free_check();
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_TREE
&& index->space == IBUF_SPACE_ID
&& !dict_index_is_unique(index)) {
@@ -501,7 +501,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
which cannot be purged yet, requires its existence. If some requires,
we should delete mark the record. */
- mtr_start_trx(&mtr_vers, thr_get_trx(thr));
+ mtr_start(&mtr_vers);
success = btr_pcur_restore_position(BTR_SEARCH_LEAF, &(node->pcur),
&mtr_vers);
@@ -617,7 +617,7 @@ row_undo_mod_del_unmark_sec_and_undo_update(
ut_ad(trx->id);
log_free_check();
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_TREE
&& index->space == IBUF_SPACE_ID
&& !dict_index_is_unique(index)) {
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index ef51e2046ae..e2de47bf86a 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -259,7 +260,7 @@ row_upd_check_references_constraints(
DEBUG_SYNC_C("foreign_constraint_check_for_update");
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
if (trx->dict_operation_lock_mode == 0) {
got_s_lock = TRUE;
@@ -1152,7 +1153,7 @@ row_upd_ext_fetch(
byte* buf = static_cast<byte*>(mem_heap_alloc(heap, *len));
*len = btr_copy_externally_stored_field_prefix(
- buf, *len, zip_size, data, local_len, NULL);
+ buf, *len, zip_size, data, local_len);
/* We should never update records containing a half-deleted BLOB. */
ut_a(*len);
@@ -1204,7 +1205,7 @@ row_upd_index_replace_new_col_val(
}
len = dtype_get_at_most_n_mbchars(col->prtype,
- col->mbminmaxlen,
+ col->mbminlen, col->mbmaxlen,
field->prefix_len, len,
(const char*) data);
@@ -1852,7 +1853,7 @@ row_upd_sec_index_entry(
}
#endif /* UNIV_DEBUG */
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
if (*index->name == TEMP_INDEX_PREFIX) {
/* The index->online_status may change if the
@@ -2389,7 +2390,7 @@ row_upd_clust_rec(
/* We may have to modify the tree structure: do a pessimistic descent
down the index tree */
- mtr_start_trx(mtr, thr_get_trx(thr));
+ mtr_start(mtr);
/* NOTE: this transaction has an s-lock or x-lock on the record and
therefore other transactions cannot modify the record when we have no
@@ -2601,7 +2602,7 @@ row_upd_clust_step(
/* We have to restore the cursor to its position */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
/* If the restoration does not succeed, then the same
transaction has deleted the record on which the cursor was,
@@ -2655,7 +2656,7 @@ row_upd_clust_step(
mtr_commit(&mtr);
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur,
&mtr);
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 749ece33a06..cb003edfbdc 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -77,10 +77,6 @@ Created 10/8/1995 Heikki Tuuri
#include "fil0pagecompress.h"
#include "btr0scrub.h"
-#ifdef WITH_WSREP
-extern int wsrep_debug;
-extern int wsrep_trx_is_aborting(void *thd_ptr);
-#endif
/* The following is the maximum allowed duration of a lock wait. */
UNIV_INTERN ulong srv_fatal_semaphore_wait_threshold = DEFAULT_SRV_FATAL_SEMAPHORE_TIMEOUT;
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 5553de4814f..9e5e90128cb 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -584,32 +584,6 @@ trx_purge_rseg_get_next_history_log(
mutex_exit(&(rseg->mutex));
mtr_commit(&mtr);
-
- mutex_enter(&trx_sys->mutex);
-
- /* Add debug code to track history list corruption reported
- on the MySQL mailing list on Nov 9, 2004. The fut0lst.cc
- file-based list was corrupt. The prev node pointer was
- FIL_NULL, even though the list length was over 8 million nodes!
- We assume that purge truncates the history list in large
- size pieces, and if we here reach the head of the list, the
- list cannot be longer than 2000 000 undo logs now. */
-
- if (trx_sys->rseg_history_len > 2000000) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: purge reached the"
- " head of the history list,\n"
- "InnoDB: but its length is still"
- " reported as %lu! Make a detailed bug\n"
- "InnoDB: report, and submit it"
- " to https://jira.mariadb.org/\n",
- (ulong) trx_sys->rseg_history_len);
- ut_ad(0);
- }
-
- mutex_exit(&trx_sys->mutex);
-
return;
}
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index 10eadcb6d7e..cd5e51d4973 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -467,7 +467,7 @@ trx_undo_page_fetch_ext(
{
/* Fetch the BLOB. */
ulint ext_len = btr_copy_externally_stored_field_prefix(
- ext_buf, prefix_len, zip_size, field, *len, NULL);
+ ext_buf, prefix_len, zip_size, field, *len);
/* BLOBs should always be nonempty. */
ut_a(ext_len);
/* Append the BLOB pointer to the prefix. */
@@ -1076,6 +1076,7 @@ trx_undo_rec_get_partial_row(
used, as we do NOT copy the data in the
record! */
dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: updated columns */
dtuple_t** row, /*!< out, own: partial row */
ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
@@ -1103,6 +1104,13 @@ trx_undo_rec_get_partial_row(
->mtype = DATA_MISSING;
}
+ for (const upd_field_t* uf = update->fields, * const ue
+ = update->fields + update->n_fields;
+ uf != ue; uf++) {
+ ulint c = dict_index_get_nth_col(index, uf->field_no)->ind;
+ *dtuple_get_nth_field(*row, c) = uf->new_val;
+ }
+
end_ptr = ptr + mach_read_from_2(ptr);
ptr += 2;
@@ -1123,6 +1131,10 @@ trx_undo_rec_get_partial_row(
ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
dfield = dtuple_get_nth_field(*row, col_no);
+ ut_ad(dfield->type.mtype == DATA_MISSING
+ || dict_col_type_assert_equal(col, &dfield->type));
+ ut_ad(dfield->type.mtype == DATA_MISSING
+ || dfield->len == len);
dict_col_copy_type(
dict_table_get_nth_col(index->table, col_no),
dfield_get_type(dfield));
@@ -1255,7 +1267,7 @@ trx_undo_report_row_operation(
rseg = trx->rseg;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&trx->undo_mutex);
/* If the undo log is not assigned yet, assign one */
@@ -1331,7 +1343,7 @@ trx_undo_report_row_operation(
latches, such as SYNC_FSP and SYNC_FSP_PAGE. */
mtr_commit(&mtr);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&rseg->mutex);
trx_undo_free_last_page(trx, undo, &mtr);
@@ -1368,7 +1380,7 @@ trx_undo_report_row_operation(
/* We have to extend the undo log by one page */
ut_ad(++loop_count < 2);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* When we add a page to an undo log, this is analogous to
a pessimistic insert in a B-tree, and we must reserve the
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index 2c7287d44cf..e5c57aa21ce 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -739,7 +739,8 @@ trx_roll_must_shutdown()
mutex_enter(&recv_sys->mutex);
if (recv_sys->report(time)) {
- ulint n_trx = 0, n_rows = 0;
+ ulint n_trx = 0;
+ ulonglong n_rows = 0;
for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
t != NULL;
t = UT_LIST_GET_NEXT(trx_list, t)) {
@@ -753,9 +754,9 @@ trx_roll_must_shutdown()
}
ib_logf(IB_LOG_LEVEL_INFO,
"To roll back: " ULINTPF " transactions, "
- ULINTPF " rows", n_trx, n_rows);
+ "%llu rows", n_trx, n_rows);
sd_notifyf(0, "STATUS=To roll back: " ULINTPF " transactions, "
- ULINTPF " rows", n_trx, n_rows);
+ "%llu rows", n_trx, n_rows);
}
mutex_exit(&recv_sys->mutex);
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index 5638ccd17a6..d6bcd131a4f 100644
--- a/storage/innobase/trx/trx0undo.cc
+++ b/storage/innobase/trx/trx0undo.cc
@@ -1070,9 +1070,11 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end(
+trx_undo_truncate_end_func(
/*=======================*/
- trx_t* trx, /*!< in: transaction whose undo log it is */
+#ifdef UNIV_DEBUG
+ const trx_t* trx, /*!< in: transaction whose undo log it is */
+#endif /* UNIV_DEBUG */
trx_undo_t* undo, /*!< in: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
@@ -1087,7 +1089,7 @@ trx_undo_truncate_end(
ut_ad(mutex_own(&(trx->rseg->mutex)));
for (;;) {
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
trunc_here = NULL;
@@ -1774,7 +1776,7 @@ trx_undo_assign_undo(
ut_ad(mutex_own(&(trx->undo_mutex)));
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&rseg->mutex);
diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc
index 181e713cca9..2a430c9c422 100644
--- a/storage/innobase/ut/ut0ut.cc
+++ b/storage/innobase/ut/ut0ut.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 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
@@ -46,6 +46,9 @@ Created 5/11/1994 Heikki Tuuri
#endif /* UNIV_HOTBACKUP */
#ifdef __WIN__
+typedef VOID(WINAPI *time_fn)(LPFILETIME);
+static time_fn ut_get_system_time_as_file_time = GetSystemTimeAsFileTime;
+
/*****************************************************************//**
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
epoch starts from 1970/1/1. For selection of constant see:
@@ -71,7 +74,7 @@ ut_gettimeofday(
return(-1);
}
- GetSystemTimeAsFileTime(&ft);
+ ut_get_system_time_as_file_time(&ft);
tm = (ib_int64_t) ft.dwHighDateTime << 32;
tm |= ft.dwLowDateTime;
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 47f759e0c05..47b24e1030b 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2134,11 +2134,16 @@ void ha_maria::start_bulk_insert(ha_rows rows, uint flags)
safety net for now, we don't remove the test of
file->state->records, because there is uncertainty on what will
happen during repair if the two states disagree.
+
+ We also have to check in case of transactional tables that the
+ user has not used LOCK TABLE on the table twice.
*/
if ((file->state->records == 0) &&
(share->state.state.records == 0) && can_enable_indexes &&
(!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES) &&
- (file->lock.type == TL_WRITE || file->lock.type == TL_UNLOCK))
+ (file->lock.type == TL_WRITE || file->lock.type == TL_UNLOCK) &&
+ (!share->have_versioning || !share->now_transactional ||
+ file->used_tables->use_count == 1))
{
/**
@todo for a single-row INSERT SELECT, we will go into repair, which
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 57596558208..c4ec3cf2f9a 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -6166,7 +6166,7 @@ my_bool write_hook_for_undo_row_insert(enum translog_record_type type
/**
- @brief Upates "records" and calls the generic UNDO hook
+ @brief Updates "records" and calls the generic UNDO hook
@return Operation status, always 0 (success)
*/
@@ -6316,8 +6316,8 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
uchar *buff, *dir;
uint result;
MARIA_PINNED_PAGE page_link;
- enum pagecache_page_lock unlock_method;
- enum pagecache_page_pin unpin_method;
+ enum pagecache_page_lock lock_method;
+ enum pagecache_page_pin pin_method;
my_off_t end_of_page;
uint error;
DBUG_ENTER("_ma_apply_redo_insert_row_head_or_tail");
@@ -6345,8 +6345,8 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
fill it entirely with zeroes, then the REDO will put correct data on
it.
*/
- unlock_method= PAGECACHE_LOCK_WRITE;
- unpin_method= PAGECACHE_PIN;
+ lock_method= PAGECACHE_LOCK_WRITE;
+ pin_method= PAGECACHE_PIN;
DBUG_ASSERT(rownr == 0 && new_page);
if (rownr != 0 || !new_page)
@@ -6361,8 +6361,8 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
}
else
{
- unlock_method= PAGECACHE_LOCK_LEFT_WRITELOCKED;
- unpin_method= PAGECACHE_PIN_LEFT_PINNED;
+ lock_method= PAGECACHE_LOCK_LEFT_WRITELOCKED;
+ pin_method= PAGECACHE_PIN_LEFT_PINNED;
share->pagecache->readwrite_flags&= ~MY_WME;
buff= pagecache_read(share->pagecache, &info->dfile,
@@ -6463,11 +6463,11 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
this group, for this page, would be skipped) and unpin then.
*/
result= 0;
- if (unlock_method == PAGECACHE_LOCK_WRITE &&
+ if (lock_method == PAGECACHE_LOCK_WRITE &&
pagecache_write(share->pagecache,
&info->dfile, page, 0,
buff, PAGECACHE_PLAIN_PAGE,
- unlock_method, unpin_method,
+ lock_method, pin_method,
PAGECACHE_WRITE_DELAY, &page_link.link,
LSN_IMPOSSIBLE))
result= my_errno;
@@ -6488,7 +6488,7 @@ crashed_file:
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
err:
error= my_errno;
- if (unlock_method == PAGECACHE_LOCK_LEFT_WRITELOCKED)
+ if (lock_method == PAGECACHE_LOCK_LEFT_WRITELOCKED)
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index 4021fb8e161..2f77f6f87ec 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -224,17 +224,35 @@ my_bool _ma_write_keypage(MARIA_PAGE *page, enum pagecache_page_lock lock,
#endif
page_cleanup(share, page);
- res= pagecache_write(share->pagecache,
- &share->kfile,
- (pgcache_page_no_t) (page->pos / block_size),
- level, buff, share->page_type,
- lock,
- lock == PAGECACHE_LOCK_LEFT_WRITELOCKED ?
- PAGECACHE_PIN_LEFT_PINNED :
- (lock == PAGECACHE_LOCK_WRITE_UNLOCK ?
- PAGECACHE_UNPIN : PAGECACHE_PIN),
- PAGECACHE_WRITE_DELAY, &page_link.link,
- LSN_IMPOSSIBLE);
+ {
+ PAGECACHE_BLOCK_LINK **link;
+ enum pagecache_page_pin pin;
+ if (lock == PAGECACHE_LOCK_LEFT_WRITELOCKED)
+ {
+ pin= PAGECACHE_PIN_LEFT_PINNED;
+ link= &page_link.link;
+ }
+ else if (lock == PAGECACHE_LOCK_WRITE_UNLOCK)
+ {
+ pin= PAGECACHE_UNPIN;
+ /*
+ We unlock this page so link should be 0 to prevent it usage
+ even accidentally
+ */
+ link= NULL;
+ }
+ else
+ {
+ pin= PAGECACHE_PIN;
+ link= &page_link.link;
+ }
+ res= pagecache_write(share->pagecache,
+ &share->kfile,
+ (pgcache_page_no_t) (page->pos / block_size),
+ level, buff, share->page_type,
+ lock, pin, PAGECACHE_WRITE_DELAY, link,
+ LSN_IMPOSSIBLE);
+ }
if (lock == PAGECACHE_LOCK_WRITE)
{
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index 951850b16a4..0132dc95e5e 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -745,11 +745,11 @@ void _ma_kpointer(register MARIA_HA *info, register uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
@@ -881,13 +881,13 @@ void _ma_dpointer(MARIA_SHARE *share, uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 8: *buff++=0;
- /* fall trough */
+ /* fall through */
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c
index 88ce88b8f98..7404fe06641 100644
--- a/storage/maria/ma_state.c
+++ b/storage/maria/ma_state.c
@@ -58,6 +58,7 @@ my_bool _ma_setup_live_state(MARIA_HA *info)
MARIA_USED_TABLES *tables;
MARIA_STATE_HISTORY *history;
DBUG_ENTER("_ma_setup_live_state");
+ DBUG_PRINT("enter", ("info: %p", info));
DBUG_ASSERT(share->lock_key_trees);
@@ -110,6 +111,8 @@ my_bool _ma_setup_live_state(MARIA_HA *info)
end:
info->state_start= &tables->state_start;
info->state= &tables->state_current;
+ info->used_tables= tables;
+ tables->use_count++;
/*
Mark in transaction state if we are not using transid (versioning)
@@ -118,6 +121,7 @@ end:
*/
tables->state_current.no_transid|= !(info->row_flag & ROW_FLAG_TRANSID);
+ DBUG_PRINT("exit", ("tables: %p info->state: %p", tables, info->state));
DBUG_RETURN(0);
}
@@ -241,9 +245,10 @@ void _ma_reset_state(MARIA_HA *info)
DBUG_ENTER("_ma_reset_state");
/* Always true if share->now_transactional is set */
- if (history)
+ if (history && share->have_versioning)
{
MARIA_STATE_HISTORY *next;
+ DBUG_PRINT("info", ("resetting history"));
/* Set the current history to current state */
share->state_history->state= share->state.state;
@@ -255,7 +260,7 @@ void _ma_reset_state(MARIA_HA *info)
my_free(history);
}
share->state_history->next= 0;
- share->state_history->trid= 0; /* Visibile for all */
+ share->state_history->trid= 0; /* Visible for all */
}
DBUG_VOID_RETURN;
}
@@ -597,7 +602,7 @@ void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
SYNOPSIS
_ma_get_status()
- param Pointer to Myisam handler
+ param Pointer to Aria handler
concurrent_insert Set to 1 if we are going to do concurrent inserts
(THR_WRITE_CONCURRENT_INSERT was used)
*/
@@ -627,6 +632,8 @@ void _ma_block_get_status(void* param, my_bool concurrent_insert)
my_bool _ma_block_start_trans(void* param)
{
MARIA_HA *info=(MARIA_HA*) param;
+ DBUG_ENTER("_ma_block_start_trans");
+
if (info->s->lock_key_trees)
{
/*
@@ -634,7 +641,7 @@ my_bool _ma_block_start_trans(void* param)
out of memory conditions)
TODO: Fix this by having one extra state pre-allocated
*/
- return _ma_setup_live_state(info);
+ DBUG_RETURN(_ma_setup_live_state(info));
}
else
{
@@ -663,9 +670,9 @@ my_bool _ma_block_start_trans(void* param)
Assume for now that this doesn't fail (It can only fail in
out of memory conditions)
*/
- return maria_create_trn_hook(info) != 0;
+ DBUG_RETURN(maria_create_trn_hook(info) != 0);
}
- return 0;
+ DBUG_RETURN(0);
}
@@ -697,7 +704,7 @@ my_bool _ma_block_check_status(void *param __attribute__((unused)))
my_bool _ma_block_start_trans_no_versioning(void* param)
{
MARIA_HA *info=(MARIA_HA*) param;
- DBUG_ENTER("_ma_block_get_status_no_version");
+ DBUG_ENTER("_ma_block_start_trans_no_versioning");
DBUG_ASSERT(info->s->base.born_transactional && !info->s->lock_key_trees);
info->state->changed= 0; /* from _ma_reset_update_flag() */
@@ -722,6 +729,8 @@ my_bool _ma_block_start_trans_no_versioning(void* param)
void maria_versioning(MARIA_HA *info, my_bool versioning)
{
MARIA_SHARE *share= info->s;
+ DBUG_ENTER("maria_versioning");
+
/* For now, this is a hack */
if (share->have_versioning)
{
@@ -738,6 +747,7 @@ void maria_versioning(MARIA_HA *info, my_bool versioning)
info->state= &share->state.state; /* Change global values by default */
info->state_start= info->state; /* Initial values */
}
+ DBUG_VOID_RETURN;
}
diff --git a/storage/maria/ma_state.h b/storage/maria/ma_state.h
index 5ff6dc26337..a86aada94fd 100644
--- a/storage/maria/ma_state.h
+++ b/storage/maria/ma_state.h
@@ -34,6 +34,7 @@ typedef struct st_used_tables {
struct st_maria_share *share;
MARIA_STATUS_INFO state_current;
MARIA_STATUS_INFO state_start;
+ uint use_count;
} MARIA_USED_TABLES;
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 34ce530283c..4175a5be18c 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -340,7 +340,7 @@ err:
for (j=0 ; j < share->base.keys ; j++)
maria_flush_bulk_insert(info, j);
}
- info->errkey= (int) i;
+ info->errkey= i < share->base.keys ? (int) i : -1;
/*
We delete keys in the reverse order of insertion. This is the order that
a rollback would do and is important for CLR_ENDs generated by
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 3b93dda2bad..d57a429365a 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -600,6 +600,7 @@ struct st_maria_handler
struct st_ma_transaction *trn; /* Pointer to active transaction */
MARIA_STATUS_INFO *state, state_save;
MARIA_STATUS_INFO *state_start; /* State at start of transaction */
+ MARIA_USED_TABLES *used_tables;
MARIA_ROW cur_row; /* The active row that we just read */
MARIA_ROW new_row; /* Storage for a row during update */
MARIA_KEY last_key; /* Last found key */
@@ -1181,7 +1182,7 @@ extern ulonglong transid_get_packed(MARIA_SHARE *share, const uchar *from);
#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
void page_cleanup(MARIA_SHARE *share, MARIA_PAGE *page)
#else
-#define page_cleanup(A,B) while (0)
+#define page_cleanup(A,B) do { } while (0)
#endif
extern MARIA_KEY *_ma_make_key(MARIA_HA *info, MARIA_KEY *int_key, uint keynr,
diff --git a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c
index 39cff18a3ab..1ea31d228e1 100644
--- a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c
@@ -233,7 +233,7 @@ int main(int argc __attribute__((unused)), char *argv[])
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55
};
- uchar *long_buffer= malloc(LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2);
+ uchar *long_buffer;
char **default_argv;
PAGECACHE pagecache;
LSN lsn, lsn_base, first_lsn;
@@ -255,6 +255,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
#endif
+ long_buffer= malloc(LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2);
load_defaults("my", load_default_groups, &argc, &argv);
default_argv= argv;
get_options(&argc, &argv);
@@ -758,9 +759,12 @@ err:
if (maria_log_remove(maria_data_root))
exit(1);
+ free(long_buffer);
+
my_uuid_end();
my_free_open_file_info();
my_end(0);
+
return (MY_TEST(exit_status()));
}
diff --git a/storage/maria/unittest/ma_test_loghandler_nologs-t.c b/storage/maria/unittest/ma_test_loghandler_nologs-t.c
index a6ccfd754de..310345f0885 100644
--- a/storage/maria/unittest/ma_test_loghandler_nologs-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_nologs-t.c
@@ -191,6 +191,8 @@ int main(int argc __attribute__((unused)), char *argv[])
if (maria_log_remove(maria_data_root))
exit(1);
+ free(long_buffer);
+
my_uuid_end();
my_free_open_file_info();
my_end(0);
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index 1921926463e..4fd287c6038 100644
--- a/storage/myisam/mi_locking.c
+++ b/storage/myisam/mi_locking.c
@@ -1,5 +1,5 @@
-/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2009, 2018, 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
@@ -113,6 +113,8 @@ int mi_lock_database(MI_INFO *info, int lock_type)
share->changed=0;
if (myisam_flush)
{
+ if (share->file_map)
+ my_msync(info->dfile, share->file_map, share->mmaped_length, MS_SYNC);
if (mysql_file_sync(share->kfile, MYF(0)))
mark_crashed= error= my_errno;
if (mysql_file_sync(info->dfile, MYF(0)))
@@ -526,6 +528,8 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
#ifdef _WIN32
if (myisam_flush)
{
+ if (share->file_map)
+ my_msync(info->dfile, share->file_map, share->mmaped_length, MS_SYNC);
mysql_file_sync(share->kfile, 0);
mysql_file_sync(info->dfile, 0);
}
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index 60a34c641ad..92f28f4e32a 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -607,11 +607,11 @@ void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
@@ -728,13 +728,13 @@ void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos)
case 5: mi_int5store(buff,pos); break;
#else
case 8: *buff++=0;
- /* fall trough */
+ /* fall through */
case 7: *buff++=0;
- /* fall trough */
+ /* fall through */
case 6: *buff++=0;
- /* fall trough */
+ /* fall through */
case 5: *buff++=0;
- /* fall trough */
+ /* fall through */
#endif
case 4: mi_int4store(buff,pos); break;
case 3: mi_int3store(buff,pos); break;
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index f01c4aed449..7ea98728034 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -1,7 +1,9 @@
-SET(TOKUDB_VERSION 5.6.37-82.2)
+SET(TOKUDB_VERSION 5.6.38-83.0)
# PerconaFT only supports x86-64 and cmake-2.8.9+
IF(CMAKE_VERSION VERSION_LESS "2.8.9")
MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB")
+ELSEIF(NOT HAVE_DLOPEN)
+ MESSAGE(STATUS "dlopen is required by TokuDB")
ELSEIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR
CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64")
# tokudb requires F_NOCACHE or O_DIRECT, and designated initializers
diff --git a/storage/tokudb/PerconaFT/CMakeLists.txt b/storage/tokudb/PerconaFT/CMakeLists.txt
index d42525f1089..3973ec71b52 100644
--- a/storage/tokudb/PerconaFT/CMakeLists.txt
+++ b/storage/tokudb/PerconaFT/CMakeLists.txt
@@ -12,9 +12,14 @@ set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
# detect when we are being built as a subproject
if (DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
add_definitions( -DMYSQL_TOKUDB_ENGINE=1)
+ # Extended PFS instrumentation:
+ # -DTOKU_PFS_MUTEX_EXTENDED_CACHETABLEMMUTEX=1
+ if (WITH_PERFSCHEMA_STORAGE_ENGINE)
+ add_definitions(-DTOKU_MYSQL_WITH_PFS)
+ endif ()
+ include_directories(${CMAKE_SOURCE_DIR}/include)
if ((CMAKE_BUILD_TYPE MATCHES "Debug") AND
(CMAKE_CXX_FLAGS_DEBUG MATCHES " -DENABLED_DEBUG_SYNC"))
- include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/sql)
endif ()
endif ()
diff --git a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
index 0fa876f2bd8..95d6207edda 100644
--- a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
+++ b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc
@@ -445,14 +445,15 @@ static void print_db_key_range_struct (void) {
sort_and_dump_fields("db_key_range", false, NULL);
}
-static void print_db_lsn_struct (void) {
- field_counter=0;
- /* A dummy field to make sizeof(DB_LSN) equal in C and C++ */
- const char *extra[] = { "char dummy", NULL };
- sort_and_dump_fields("db_lsn", false, extra);
+static void print_db_lsn_struct(void) {
+ field_counter = 0;
+ // FT-692
+ STRUCT_SETUP(DB_LSN, file, "uint32_t %s");
+ STRUCT_SETUP(DB_LSN, offset, "uint32_t %s");
+ sort_and_dump_fields("db_lsn", false, NULL);
}
-static void print_dbt_struct (void) {
+static void print_dbt_struct(void) {
field_counter=0;
#if 0 && DB_VERSION_MAJOR==4 && DB_VERSION_MINOR==1
STRUCT_SETUP(DBT, app_private, "void*%s");
diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
index 0cd9a9c5941..385723aebc7 100644
--- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
+++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
@@ -53,7 +53,13 @@ macro(set_cflags_if_supported)
endforeach(flag)
endmacro(set_cflags_if_supported)
+if (NOT DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
+ set (OPTIONAL_CFLAGS "${OPTIONAL_CFLAGS} -Wmissing-format-attribute")
+endif()
+
## disable some warnings
+## missing-format-attribute causes warnings in some MySQL include files
+## if the library is built as a part of TokuDB MySQL storage engine
set_cflags_if_supported(
-Wno-missing-field-initializers
-Wstrict-null-sentinel
@@ -61,7 +67,7 @@ set_cflags_if_supported(
-Wswitch
-Wtrampolines
-Wlogical-op
- -Wmissing-format-attribute
+ ${OPTIONAL_CFLAGS}
-Wno-error=missing-format-attribute
-Wno-error=address-of-array-temporary
-Wno-error=tautological-constant-out-of-range-compare
@@ -143,8 +149,8 @@ set_cflags_if_supported(
-Wmissing-prototypes
-Wmissing-declarations
-Wpointer-arith
- -Wmissing-format-attribute
-Wshadow
+ ${OPTIONAL_CFLAGS}
## other flags to try:
#-Wunsafe-loop-optimizations
#-Wpointer-arith
diff --git a/storage/tokudb/PerconaFT/ft/cachetable/background_job_manager.cc b/storage/tokudb/PerconaFT/ft/cachetable/background_job_manager.cc
index 9119a49b081..c109185f973 100644
--- a/storage/tokudb/PerconaFT/ft/cachetable/background_job_manager.cc
+++ b/storage/tokudb/PerconaFT/ft/cachetable/background_job_manager.cc
@@ -42,6 +42,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "cachetable/background_job_manager.h"
+toku_instr_key *bjm_jobs_lock_mutex_key;
+toku_instr_key *bjm_jobs_wait_key;
+
struct background_job_manager_struct {
bool accepting_jobs;
uint32_t num_jobs;
@@ -49,10 +52,10 @@ struct background_job_manager_struct {
toku_mutex_t jobs_lock;
};
-void bjm_init(BACKGROUND_JOB_MANAGER* pbjm) {
+void bjm_init(BACKGROUND_JOB_MANAGER *pbjm) {
BACKGROUND_JOB_MANAGER XCALLOC(bjm);
- toku_mutex_init(&bjm->jobs_lock, 0);
- toku_cond_init(&bjm->jobs_wait, NULL);
+ toku_mutex_init(*bjm_jobs_lock_mutex_key, &bjm->jobs_lock, nullptr);
+ toku_cond_init(*bjm_jobs_wait_key, &bjm->jobs_wait, nullptr);
bjm->accepting_jobs = true;
bjm->num_jobs = 0;
*pbjm = bjm;
diff --git a/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc b/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
index 31aab932fd6..ae2bb2846e8 100644
--- a/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
+++ b/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
@@ -57,6 +57,25 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/status.h"
#include "util/context.h"
+toku_instr_key *cachetable_m_mutex_key;
+toku_instr_key *cachetable_ev_thread_lock_mutex_key;
+
+toku_instr_key *cachetable_m_list_lock_key;
+toku_instr_key *cachetable_m_pending_lock_expensive_key;
+toku_instr_key *cachetable_m_pending_lock_cheap_key;
+toku_instr_key *cachetable_m_lock_key;
+
+toku_instr_key *cachetable_value_key;
+toku_instr_key *cachetable_disk_nb_rwlock_key;
+
+toku_instr_key *cachetable_p_refcount_wait_key;
+toku_instr_key *cachetable_m_flow_control_cond_key;
+toku_instr_key *cachetable_m_ev_thread_cond_key;
+
+toku_instr_key *cachetable_disk_nb_mutex_key;
+toku_instr_key *log_internal_lock_mutex_key;
+toku_instr_key *eviction_thread_key;
+
///////////////////////////////////////////////////////////////////////////////////
// Engine status
//
@@ -779,18 +798,25 @@ void pair_init(PAIR p,
p->checkpoint_complete_callback = write_callback.checkpoint_complete_callback;
p->write_extraargs = write_callback.write_extraargs;
- p->count = 0; // <CER> Is zero the correct init value?
+ p->count = 0; // <CER> Is zero the correct init value?
p->refcount = 0;
p->num_waiting_on_refs = 0;
- toku_cond_init(&p->refcount_wait, NULL);
+ toku_cond_init(*cachetable_p_refcount_wait_key, &p->refcount_wait, nullptr);
p->checkpoint_pending = false;
p->mutex = list->get_mutex_for_pair(fullhash);
assert(p->mutex);
- p->value_rwlock.init(p->mutex);
- nb_mutex_init(&p->disk_nb_mutex);
+ p->value_rwlock.init(p->mutex
+#ifdef TOKU_MYSQL_WITH_PFS
+ ,
+ *cachetable_value_key
+#endif
+ );
+ nb_mutex_init(*cachetable_disk_nb_mutex_key,
+ *cachetable_disk_nb_rwlock_key,
+ &p->disk_nb_mutex);
- p->size_evicting_estimate = 0; // <CER> Is zero the correct init value?
+ p->size_evicting_estimate = 0; // <CER> Is zero the correct init value?
p->ev = ev;
p->list = list;
@@ -3229,16 +3255,26 @@ void pair_list::init() {
#if defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP)
pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
#else
- // TODO: need to figure out how to make writer-preferential rwlocks
- // happen on osx
+// TODO: need to figure out how to make writer-preferential rwlocks
+// happen on osx
#endif
- toku_pthread_rwlock_init(&m_list_lock, &attr);
- toku_pthread_rwlock_init(&m_pending_lock_expensive, &attr);
- toku_pthread_rwlock_init(&m_pending_lock_cheap, &attr);
+ toku_pthread_rwlock_init(*cachetable_m_list_lock_key, &m_list_lock, &attr);
+ toku_pthread_rwlock_init(*cachetable_m_pending_lock_expensive_key,
+ &m_pending_lock_expensive,
+ &attr);
+ toku_pthread_rwlock_init(
+ *cachetable_m_pending_lock_cheap_key, &m_pending_lock_cheap, &attr);
XCALLOC_N(m_table_size, m_table);
XCALLOC_N(m_num_locks, m_mutexes);
for (uint64_t i = 0; i < m_num_locks; i++) {
- toku_mutex_init(&m_mutexes[i].aligned_mutex, NULL);
+ toku_mutex_init(
+#ifdef TOKU_PFS_MUTEX_EXTENDED_CACHETABLEMMUTEX
+ *cachetable_m_mutex_key,
+#else
+ toku_uninstrumented,
+#endif
+ &m_mutexes[i].aligned_mutex,
+ nullptr);
}
}
@@ -3578,9 +3614,9 @@ ENSURE_POD(evictor);
// This is the function that runs eviction on its own thread.
//
static void *eviction_thread(void *evictor_v) {
- evictor* CAST_FROM_VOIDP(evictor, evictor_v);
+ evictor *CAST_FROM_VOIDP(evictor, evictor_v);
evictor->run_eviction_thread();
- return evictor_v;
+ return toku_pthread_done(evictor_v);
}
//
@@ -3629,11 +3665,14 @@ int evictor::init(long _size_limit, pair_list* _pl, cachefile_list* _cf_list, KI
m_pl = _pl;
m_cf_list = _cf_list;
- m_kibbutz = _kibbutz;
- toku_mutex_init(&m_ev_thread_lock, NULL);
- toku_cond_init(&m_flow_control_cond, NULL);
- toku_cond_init(&m_ev_thread_cond, NULL);
- m_num_sleepers = 0;
+ m_kibbutz = _kibbutz;
+ toku_mutex_init(
+ *cachetable_ev_thread_lock_mutex_key, &m_ev_thread_lock, nullptr);
+ toku_cond_init(
+ *cachetable_m_flow_control_cond_key, &m_flow_control_cond, nullptr);
+ toku_cond_init(
+ *cachetable_m_ev_thread_cond_key, &m_ev_thread_cond, nullptr);
+ m_num_sleepers = 0;
m_ev_thread_is_running = false;
m_period_in_seconds = eviction_period;
@@ -3641,11 +3680,12 @@ int evictor::init(long _size_limit, pair_list* _pl, cachefile_list* _cf_list, KI
int r = myinitstate_r(seed, m_random_statebuf, sizeof m_random_statebuf, &m_random_data);
assert_zero(r);
- // start the background thread
+ // start the background thread
m_run_thread = true;
m_num_eviction_thread_runs = 0;
m_ev_thread_init = false;
- r = toku_pthread_create(&m_ev_thread, NULL, eviction_thread, this);
+ r = toku_pthread_create(
+ *eviction_thread_key, &m_ev_thread, nullptr, eviction_thread, this);
if (r == 0) {
m_ev_thread_init = true;
}
@@ -4702,7 +4742,7 @@ static_assert(std::is_pod<cachefile_list>::value, "cachefile_list isn't POD");
void cachefile_list::init() {
m_next_filenum_to_use.fileid = 0;
m_next_hash_id_to_use = 0;
- toku_pthread_rwlock_init(&m_lock, NULL);
+ toku_pthread_rwlock_init(*cachetable_m_lock_key, &m_lock, nullptr);
m_active_filenum.create();
m_active_fileid.create();
m_stale_fileid.create();
diff --git a/storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc b/storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc
index 3223ab0a4ce..13ff5eff5af 100644
--- a/storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/cachetable/checkpoint.cc
@@ -86,8 +86,16 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/frwlock.h"
#include "util/status.h"
-void
-toku_checkpoint_get_status(CACHETABLE ct, CHECKPOINT_STATUS statp) {
+toku_instr_key *checkpoint_safe_mutex_key;
+toku_instr_key *checkpoint_safe_rwlock_key;
+toku_instr_key *multi_operation_lock_key;
+toku_instr_key *low_priority_multi_operation_lock_key;
+
+toku_instr_key *rwlock_cond_key;
+toku_instr_key *rwlock_wait_read_key;
+toku_instr_key *rwlock_wait_write_key;
+
+void toku_checkpoint_get_status(CACHETABLE ct, CHECKPOINT_STATUS statp) {
cp_status.init();
CP_STATUS_VAL(CP_PERIOD) = toku_get_checkpoint_period_unlocked(ct);
*statp = cp_status;
@@ -116,11 +124,14 @@ multi_operation_lock_init(void) {
#if defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP)
pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
#else
- // TODO: need to figure out how to make writer-preferential rwlocks
- // happen on osx
+// TODO: need to figure out how to make writer-preferential rwlocks
+// happen on osx
#endif
- toku_pthread_rwlock_init(&multi_operation_lock, &attr);
- toku_pthread_rwlock_init(&low_priority_multi_operation_lock, &attr);
+ toku_pthread_rwlock_init(
+ *multi_operation_lock_key, &multi_operation_lock, &attr);
+ toku_pthread_rwlock_init(*low_priority_multi_operation_lock_key,
+ &low_priority_multi_operation_lock,
+ &attr);
pthread_rwlockattr_destroy(&attr);
locked_mo = false;
}
@@ -145,10 +156,15 @@ multi_operation_checkpoint_unlock(void) {
toku_pthread_rwlock_wrunlock(&low_priority_multi_operation_lock);
}
-static void
-checkpoint_safe_lock_init(void) {
- toku_mutex_init(&checkpoint_safe_mutex, NULL);
- checkpoint_safe_lock.init(&checkpoint_safe_mutex);
+static void checkpoint_safe_lock_init(void) {
+ toku_mutex_init(
+ *checkpoint_safe_mutex_key, &checkpoint_safe_mutex, nullptr);
+ checkpoint_safe_lock.init(&checkpoint_safe_mutex
+#ifdef TOKU_MYSQL_WITH_PFS
+ ,
+ *checkpoint_safe_rwlock_key
+#endif
+ );
locked_cs = false;
}
diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.cc b/storage/tokudb/PerconaFT/ft/ft-ops.cc
index 07e244947e4..60885ed9f33 100644
--- a/storage/tokudb/PerconaFT/ft/ft-ops.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-ops.cc
@@ -186,9 +186,35 @@ basement nodes, bulk fetch, and partial fetch:
*/
static toku_mutex_t ft_open_close_lock;
-
-void
-toku_ft_get_status(FT_STATUS s) {
+static toku_instr_key *ft_open_close_lock_mutex_key;
+// FIXME: the instrumentation keys below are defined here even though they
+// belong to other modules, because they are registered here. If desired, they
+// can be moved to their proper modules and registration done there in a
+// one-time init function
+// locktree
+toku_instr_key *treenode_mutex_key;
+toku_instr_key *manager_mutex_key;
+toku_instr_key *manager_escalation_mutex_key;
+toku_instr_key *manager_escalator_mutex_key;
+// src
+toku_instr_key *db_txn_struct_i_txn_mutex_key;
+toku_instr_key *indexer_i_indexer_lock_mutex_key;
+toku_instr_key *indexer_i_indexer_estimate_lock_mutex_key;
+toku_instr_key *result_i_open_dbs_rwlock_key;
+// locktree
+toku_instr_key *lock_request_m_wait_cond_key;
+toku_instr_key *manager_m_escalator_done_key;
+toku_instr_key *locktree_request_info_mutex_key;
+toku_instr_key *locktree_request_info_retry_mutex_key;
+toku_instr_key *locktree_request_info_retry_cv_key;
+
+// this is a sample probe for custom instrumentation
+static toku_instr_key *fti_probe_1_key;
+
+// This is a sample probe for custom instrumentation
+toku_instr_probe *toku_instr_probe_1;
+
+void toku_ft_get_status(FT_STATUS s) {
ft_status.init();
*s = ft_status;
@@ -2643,11 +2669,14 @@ void toku_ft_set_direct_io (bool direct_io_on) {
use_direct_io = direct_io_on;
}
-static inline int ft_open_maybe_direct(const char *filename, int oflag, int mode) {
+static inline int ft_open_maybe_direct(const char *filename,
+ int oflag,
+ int mode) {
if (use_direct_io) {
- return toku_os_open_direct(filename, oflag, mode);
+ return toku_os_open_direct(
+ filename, oflag, mode, *tokudb_file_data_key);
} else {
- return toku_os_open(filename, oflag, mode);
+ return toku_os_open(filename, oflag, mode, *tokudb_file_data_key);
}
}
@@ -2721,7 +2750,7 @@ bool toku_create_subdirs_if_needed(const char *path) {
if (!subdir.get())
return true;
- if (toku_stat(subdir.get(), &stat) == -1) {
+ if (toku_stat(subdir.get(), &stat, toku_uninstrumented) == -1) {
if (ENOENT == get_error_errno())
subdir_exists = false;
else
@@ -2933,6 +2962,8 @@ ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only
CACHEFILE cf = NULL;
FT ft = NULL;
bool did_create = false;
+ bool was_already_open = false;
+
toku_ft_open_close_lock();
if (ft_h->did_set_flags) {
@@ -2944,7 +2975,6 @@ ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only
FILENUM reserved_filenum;
reserved_filenum = use_filenum;
fname_in_cwd = toku_cachetable_get_fname_in_cwd(cachetable, fname_in_env);
- bool was_already_open;
{
int fd = -1;
r = ft_open_file(fname_in_cwd, &fd);
@@ -4614,20 +4644,265 @@ int toku_dump_ft(FILE *f, FT_HANDLE ft_handle) {
return toku_dump_ftnode(f, ft_handle, root_key, 0, 0, 0);
}
+
+static void toku_pfs_keys_init(const char *toku_instr_group_name) {
+ kibbutz_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name, "kibbutz_mutex");
+ minicron_p_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "minicron_p_mutex");
+ queue_result_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "queue_result_mutex");
+ tpool_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "tpool_lock_mutex");
+ workset_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "workset_lock_mutex");
+ bjm_jobs_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "bjm_jobs_lock_mutex");
+ log_internal_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "log_internal_lock_mutex");
+ cachetable_ev_thread_lock_mutex_key =
+ new toku_instr_key(toku_instr_object_type::mutex,
+ toku_instr_group_name,
+ "cachetable_ev_thread_lock_mutex");
+ cachetable_disk_nb_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "cachetable_disk_nb_mutex");
+ safe_file_size_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "safe_file_size_lock_mutex");
+ cachetable_m_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "cachetable_m_mutex_key");
+ checkpoint_safe_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "checkpoint_safe_mutex");
+ ft_ref_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "ft_ref_lock_mutex");
+ ft_open_close_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "ft_open_close_lock_mutex");
+ loader_error_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "loader_error_mutex");
+ bfs_mutex_key =
+ new toku_instr_key(toku_instr_object_type::mutex, toku_instr_group_name,
+ "bfs_mutex");
+ loader_bl_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "loader_bl_mutex");
+ loader_fi_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "loader_fi_lock_mutex");
+ loader_out_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "loader_out_mutex");
+ result_output_condition_lock_mutex_key =
+ new toku_instr_key(toku_instr_object_type::mutex,
+ toku_instr_group_name,
+ "result_output_condition_lock_mutex");
+ block_table_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "block_table_mutex");
+ rollback_log_node_cache_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "rollback_log_node_cache_mutex");
+ txn_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name, "txn_lock_mutex");
+ txn_state_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "txn_state_lock_mutex");
+ txn_child_manager_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "txn_child_manager_mutex");
+ txn_manager_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "txn_manager_lock_mutex");
+ treenode_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name, "treenode_mutex");
+ locktree_request_info_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "locktree_request_info_mutex");
+ locktree_request_info_retry_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "locktree_request_info_retry_mutex_key");
+ manager_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name, "manager_mutex");
+ manager_escalation_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "manager_escalation_mutex");
+ db_txn_struct_i_txn_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "db_txn_struct_i_txn_mutex");
+ manager_escalator_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "manager_escalator_mutex");
+ indexer_i_indexer_lock_mutex_key = new toku_instr_key(
+ toku_instr_object_type::mutex, toku_instr_group_name,
+ "indexer_i_indexer_lock_mutex");
+ indexer_i_indexer_estimate_lock_mutex_key =
+ new toku_instr_key(toku_instr_object_type::mutex,
+ toku_instr_group_name,
+ "indexer_i_indexer_estimate_lock_mutex");
+
+ tokudb_file_data_key = new toku_instr_key(
+ toku_instr_object_type::file, toku_instr_group_name, "tokudb_data_file");
+ tokudb_file_load_key = new toku_instr_key(
+ toku_instr_object_type::file, toku_instr_group_name, "tokudb_load_file");
+ tokudb_file_tmp_key = new toku_instr_key(
+ toku_instr_object_type::file, toku_instr_group_name, "tokudb_tmp_file");
+ tokudb_file_log_key = new toku_instr_key(
+ toku_instr_object_type::file, toku_instr_group_name, "tokudb_log_file");
+
+ fti_probe_1_key =
+ new toku_instr_key(toku_instr_object_type::mutex, toku_instr_group_name,
+ "fti_probe_1");
+
+ extractor_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name,
+ "extractor_thread");
+ fractal_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name, "fractal_thread");
+ io_thread_key =
+ new toku_instr_key(toku_instr_object_type::thread, toku_instr_group_name,
+ "io_thread");
+ eviction_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name,
+ "eviction_thread");
+ kibbutz_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name, "kibbutz_thread");
+ minicron_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name,
+ "minicron_thread");
+ tp_internal_thread_key = new toku_instr_key(
+ toku_instr_object_type::thread, toku_instr_group_name,
+ "tp_internal_thread");
+
+ result_state_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "result_state_cond");
+ bjm_jobs_wait_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name, "bjm_jobs_wait");
+ cachetable_p_refcount_wait_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "cachetable_p_refcount_wait");
+ cachetable_m_flow_control_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "cachetable_m_flow_control_cond");
+ cachetable_m_ev_thread_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "cachetable_m_ev_thread_cond");
+ bfs_cond_key =
+ new toku_instr_key(toku_instr_object_type::cond, toku_instr_group_name,
+ "bfs_cond");
+ result_output_condition_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "result_output_condition");
+ manager_m_escalator_done_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "manager_m_escalator_done");
+ lock_request_m_wait_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "lock_request_m_wait_cond");
+ queue_result_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "queue_result_cond");
+ ws_worker_wait_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name, "ws_worker_wait");
+ rwlock_wait_read_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name, "rwlock_wait_read");
+ rwlock_wait_write_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "rwlock_wait_write");
+ rwlock_cond_key =
+ new toku_instr_key(toku_instr_object_type::cond, toku_instr_group_name,
+ "rwlock_cond");
+ tp_thread_wait_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name, "tp_thread_wait");
+ tp_pool_wait_free_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "tp_pool_wait_free");
+ frwlock_m_wait_read_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "frwlock_m_wait_read");
+ kibbutz_k_cond_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name, "kibbutz_k_cond");
+ minicron_p_condvar_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "minicron_p_condvar");
+ locktree_request_info_retry_cv_key = new toku_instr_key(
+ toku_instr_object_type::cond, toku_instr_group_name,
+ "locktree_request_info_retry_cv_key");
+
+ multi_operation_lock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "multi_operation_lock");
+ low_priority_multi_operation_lock_key =
+ new toku_instr_key(toku_instr_object_type::rwlock,
+ toku_instr_group_name,
+ "low_priority_multi_operation_lock");
+ cachetable_m_list_lock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "cachetable_m_list_lock");
+ cachetable_m_pending_lock_expensive_key =
+ new toku_instr_key(toku_instr_object_type::rwlock,
+ toku_instr_group_name,
+ "cachetable_m_pending_lock_expensive");
+ cachetable_m_pending_lock_cheap_key =
+ new toku_instr_key(toku_instr_object_type::rwlock,
+ toku_instr_group_name,
+ "cachetable_m_pending_lock_cheap");
+ cachetable_m_lock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "cachetable_m_lock");
+ result_i_open_dbs_rwlock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "result_i_open_dbs_rwlock");
+ checkpoint_safe_rwlock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "checkpoint_safe_rwlock");
+ cachetable_value_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "cachetable_value");
+ safe_file_size_lock_rwlock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "safe_file_size_lock_rwlock");
+ cachetable_disk_nb_rwlock_key = new toku_instr_key(
+ toku_instr_object_type::rwlock, toku_instr_group_name,
+ "cachetable_disk_nb_rwlock");
+
+ toku_instr_probe_1 = new toku_instr_probe(*fti_probe_1_key);
+}
+
int toku_ft_layer_init(void) {
int r = 0;
- //Portability must be initialized first
+
+ // Portability must be initialized first
r = toku_portability_init();
- if (r) { goto exit; }
+ if (r) {
+ goto exit;
+ }
+
+ toku_pfs_keys_init("fti");
+
r = db_env_set_toku_product_name("tokudb");
- if (r) { goto exit; }
+ if (r) {
+ goto exit;
+ }
partitioned_counters_init();
toku_status_init();
toku_context_status_init();
toku_checkpoint_init();
toku_ft_serialize_layer_init();
- toku_mutex_init(&ft_open_close_lock, NULL);
+ toku_mutex_init(
+ *ft_open_close_lock_mutex_key, &ft_open_close_lock, nullptr);
toku_scoped_malloc_init();
exit:
return r;
@@ -4641,7 +4916,10 @@ void toku_ft_layer_destroy(void) {
toku_status_destroy();
partitioned_counters_destroy();
toku_scoped_malloc_destroy();
- //Portability must be cleaned up last
+
+ delete toku_instr_probe_1;
+
+ // Portability must be cleaned up last
toku_portability_destroy();
}
diff --git a/storage/tokudb/PerconaFT/ft/ft.cc b/storage/tokudb/PerconaFT/ft/ft.cc
index 700e532d5cf..454bf11794f 100644
--- a/storage/tokudb/PerconaFT/ft/ft.cc
+++ b/storage/tokudb/PerconaFT/ft/ft.cc
@@ -50,9 +50,10 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <toku_assert.h>
#include <portability/toku_atomic.h>
-void
-toku_reset_root_xid_that_created(FT ft, TXNID new_root_xid_that_created) {
- // Reset the root_xid_that_created field to the given value.
+toku_instr_key *ft_ref_lock_mutex_key;
+
+void toku_reset_root_xid_that_created(FT ft, TXNID new_root_xid_that_created) {
+ // Reset the root_xid_that_created field to the given value.
// This redefines which xid created the dictionary.
// hold lock around setting and clearing of dirty bit
@@ -100,15 +101,11 @@ toku_ft_free (FT ft) {
toku_free(ft);
}
-void
-toku_ft_init_reflock(FT ft) {
- toku_mutex_init(&ft->ft_ref_lock, NULL);
+void toku_ft_init_reflock(FT ft) {
+ toku_mutex_init(*ft_ref_lock_mutex_key, &ft->ft_ref_lock, nullptr);
}
-void
-toku_ft_destroy_reflock(FT ft) {
- toku_mutex_destroy(&ft->ft_ref_lock);
-}
+void toku_ft_destroy_reflock(FT ft) { toku_mutex_destroy(&ft->ft_ref_lock); }
void
toku_ft_grab_reflock(FT ft) {
diff --git a/storage/tokudb/PerconaFT/ft/loader/callbacks.cc b/storage/tokudb/PerconaFT/ft/loader/callbacks.cc
index 6a520dba3a3..ac69fb7e789 100644
--- a/storage/tokudb/PerconaFT/ft/loader/callbacks.cc
+++ b/storage/tokudb/PerconaFT/ft/loader/callbacks.cc
@@ -45,6 +45,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "loader/loader-internal.h"
#include "util/dbt.h"
+toku_instr_key *loader_error_mutex_key;
+
static void error_callback_lock(ft_loader_error_callback loader_error) {
toku_mutex_lock(&loader_error->mutex);
}
@@ -57,10 +59,10 @@ void ft_loader_init_error_callback(ft_loader_error_callback loader_error) {
memset(loader_error, 0, sizeof *loader_error);
toku_init_dbt(&loader_error->key);
toku_init_dbt(&loader_error->val);
- toku_mutex_init(&loader_error->mutex, NULL);
+ toku_mutex_init(*loader_error_mutex_key, &loader_error->mutex, nullptr);
}
-void ft_loader_destroy_error_callback(ft_loader_error_callback loader_error) {
+void ft_loader_destroy_error_callback(ft_loader_error_callback loader_error) {
toku_mutex_destroy(&loader_error->mutex);
toku_destroy_dbt(&loader_error->key);
toku_destroy_dbt(&loader_error->val);
diff --git a/storage/tokudb/PerconaFT/ft/loader/dbufio.cc b/storage/tokudb/PerconaFT/ft/loader/dbufio.cc
index 28d8d49ba9f..9ff712bcbae 100644
--- a/storage/tokudb/PerconaFT/ft/loader/dbufio.cc
+++ b/storage/tokudb/PerconaFT/ft/loader/dbufio.cc
@@ -48,6 +48,10 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "loader/dbufio.h"
#include "loader/loader-internal.h"
+toku_instr_key *bfs_mutex_key;
+toku_instr_key *bfs_cond_key;
+toku_instr_key *io_thread_key;
+
struct dbufio_file {
// i/o thread owns these
int fd;
@@ -275,39 +279,44 @@ static void* io_thread (void *v)
toku_mutex_lock(&bfs->mutex);
//printf("%s:%d Locked\n", __FILE__, __LINE__);
while (1) {
+ if (paniced(bfs)) {
+ toku_mutex_unlock(&bfs->mutex); // ignore any error
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
+ }
+ // printf("n_not_done=%d\n", bfs->n_not_done);
+ if (bfs->n_not_done == 0) {
+ // all done (meaning we stored EOF (or another error) in
+ // error_code[0] for the file.
+ // printf("unlocked\n");
+ toku_mutex_unlock(&bfs->mutex);
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
+ }
- if (paniced(bfs)) {
- toku_mutex_unlock(&bfs->mutex); // ignore any error
- return 0;
- }
- //printf("n_not_done=%d\n", bfs->n_not_done);
- if (bfs->n_not_done==0) {
- // all done (meaning we stored EOF (or another error) in error_code[0] for the file.
- //printf("unlocked\n");
- toku_mutex_unlock(&bfs->mutex);
- return 0;
- }
-
- struct dbufio_file *dbf = bfs->head;
- if (dbf==NULL) {
- // No I/O needs to be done yet.
- // Wait until something happens that will wake us up.
- toku_cond_wait(&bfs->cond, &bfs->mutex);
- if (paniced(bfs)) {
- toku_mutex_unlock(&bfs->mutex); // ignore any error
- return 0;
- }
- // Have the lock so go around.
- } else {
- // Some I/O needs to be done.
- //printf("%s:%d Need I/O\n", __FILE__, __LINE__);
- assert(dbf->second_buf_ready == false);
- assert(!dbf->io_done);
- bfs->head = dbf->next;
- if (bfs->head==NULL) bfs->tail=NULL;
-
- // Unlock the mutex now that we have ownership of dbf to allow consumers to get the mutex and perform swaps. They won't swap
- // this buffer because second_buf_ready is false.
+ struct dbufio_file *dbf = bfs->head;
+ if (dbf == NULL) {
+ // No I/O needs to be done yet.
+ // Wait until something happens that will wake us up.
+ toku_cond_wait(&bfs->cond, &bfs->mutex);
+ if (paniced(bfs)) {
+ toku_mutex_unlock(&bfs->mutex); // ignore any error
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
+ }
+ // Have the lock so go around.
+ } else {
+ // Some I/O needs to be done.
+ // printf("%s:%d Need I/O\n", __FILE__, __LINE__);
+ assert(dbf->second_buf_ready == false);
+ assert(!dbf->io_done);
+ bfs->head = dbf->next;
+ if (bfs->head == NULL)
+ bfs->tail = NULL;
+
+ // Unlock the mutex now that we have ownership of dbf to allow
+ // consumers to get the mutex and perform swaps. They won't swap
+ // this buffer because second_buf_ready is false.
toku_mutex_unlock(&bfs->mutex);
//printf("%s:%d Doing read fd=%d\n", __FILE__, __LINE__, dbf->fd);
{
@@ -338,14 +347,16 @@ static void* io_thread (void *v)
//printf("%s:%d locking mutex again=%ld\n", __FILE__, __LINE__, readcode);
{
- toku_mutex_lock(&bfs->mutex);
- if (paniced(bfs)) {
- toku_mutex_unlock(&bfs->mutex); // ignore any error
- return 0;
- }
- }
- // Now that we have the mutex, we can decrement n_not_done (if applicable) and set second_buf_ready
- if (readcode<=0) {
+ toku_mutex_lock(&bfs->mutex);
+ if (paniced(bfs)) {
+ toku_mutex_unlock(&bfs->mutex); // ignore any error
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
+ }
+ }
+ // Now that we have the mutex, we can decrement n_not_done (if
+ // applicable) and set second_buf_ready
+ if (readcode<=0) {
bfs->n_not_done--;
}
//printf("%s:%d n_not_done=%d\n", __FILE__, __LINE__, bfs->n_not_done);
@@ -376,34 +387,36 @@ int create_dbufio_fileset (DBUFIO_FILESET *bfsp, int N, int fds[/*N*/], size_t b
}
}
}
- //printf("%s:%d here\n", __FILE__, __LINE__);
- if (result==0) {
- toku_mutex_init(&bfs->mutex, NULL);
- mutex_inited = true;
+ // printf("%s:%d here\n", __FILE__, __LINE__);
+ if (result == 0) {
+ toku_mutex_init(*bfs_mutex_key, &bfs->mutex, nullptr);
+ mutex_inited = true;
}
- if (result==0) {
- toku_cond_init(&bfs->cond, NULL);
- cond_inited = true;
+ if (result == 0) {
+ toku_cond_init(*bfs_cond_key, &bfs->cond, nullptr);
+ cond_inited = true;
}
- if (result==0) {
- bfs->N = N;
- bfs->n_not_done = N;
- bfs->head = bfs->tail = NULL;
- for (int i=0; i<N; i++) {
- bfs->files[i].fd = fds[i];
- bfs->files[i].offset_in_buf = 0;
- bfs->files[i].offset_in_uncompressed_file = 0;
- bfs->files[i].next = NULL;
- bfs->files[i].second_buf_ready = false;
- for (int j=0; j<2; j++) {
- if (result==0) {
- MALLOC_N(bufsize, bfs->files[i].buf[j]);
- if (bfs->files[i].buf[j]==NULL) { result=get_error_errno(); }
- }
- bfs->files[i].n_in_buf[j] = 0;
- bfs->files[i].error_code[j] = 0;
- }
- bfs->files[i].io_done = false;
+ if (result == 0) {
+ bfs->N = N;
+ bfs->n_not_done = N;
+ bfs->head = bfs->tail = NULL;
+ for (int i = 0; i < N; i++) {
+ bfs->files[i].fd = fds[i];
+ bfs->files[i].offset_in_buf = 0;
+ bfs->files[i].offset_in_uncompressed_file = 0;
+ bfs->files[i].next = NULL;
+ bfs->files[i].second_buf_ready = false;
+ for (int j = 0; j < 2; j++) {
+ if (result == 0) {
+ MALLOC_N(bufsize, bfs->files[i].buf[j]);
+ if (bfs->files[i].buf[j] == NULL) {
+ result = get_error_errno();
+ }
+ }
+ bfs->files[i].n_in_buf[j] = 0;
+ bfs->files[i].error_code[j] = 0;
+ }
+ bfs->files[i].io_done = false;
ssize_t r;
if (bfs->compressed) {
r = dbf_read_compressed(&bfs->files[i], bfs->files[i].buf[0], bufsize);
@@ -430,13 +443,21 @@ int create_dbufio_fileset (DBUFIO_FILESET *bfsp, int N, int fds[/*N*/], size_t b
bfs->panic = false;
bfs->panic_errno = 0;
}
- //printf("Creating IO thread\n");
- if (result==0) {
- result = toku_pthread_create(&bfs->iothread, NULL, io_thread, (void*)bfs);
+ // printf("Creating IO thread\n");
+ if (result == 0) {
+ result = toku_pthread_create(*io_thread_key,
+ &bfs->iothread,
+ nullptr,
+ io_thread,
+ static_cast<void *>(bfs));
+ }
+ if (result == 0) {
+ *bfsp = bfs;
+ return 0;
}
- if (result==0) { *bfsp = bfs; return 0; }
// Now undo everything.
- // If we got here, there is no thread (either result was zero before the thread was created, or else the thread creation itself failed.
+ // If we got here, there is no thread (either result was zero before the
+ // thread was created, or else the thread creation itself failed.
if (bfs) {
if (bfs->files) {
// the files were allocated, so we have to free all the bufs.
diff --git a/storage/tokudb/PerconaFT/ft/loader/loader-internal.h b/storage/tokudb/PerconaFT/ft/loader/loader-internal.h
index 1aa2c203831..6f7b0147b21 100644
--- a/storage/tokudb/PerconaFT/ft/loader/loader-internal.h
+++ b/storage/tokudb/PerconaFT/ft/loader/loader-internal.h
@@ -64,10 +64,10 @@ enum {
/* These structures maintain a collection of all the open temporary files used by the loader. */
struct file_info {
bool is_open;
- bool is_extant; // if true, the file must be unlinked.
+ bool is_extant; // if true, the file must be unlinked.
char *fname;
- FILE *file;
- uint64_t n_rows; // how many rows were written into that file
+ TOKU_FILE *file;
+ uint64_t n_rows; // how many rows were written into that file
size_t buffer_size;
void *buffer;
};
@@ -80,11 +80,11 @@ struct file_infos {
};
typedef struct fidx { int idx; } FIDX;
static const FIDX FIDX_NULL __attribute__((__unused__)) = {-1};
-static int fidx_is_null (const FIDX f) __attribute__((__unused__));
-static int fidx_is_null (const FIDX f) { return f.idx==-1; }
-FILE *toku_bl_fidx2file (FTLOADER bl, FIDX i);
+static int fidx_is_null(const FIDX f) __attribute__((__unused__));
+static int fidx_is_null(const FIDX f) { return f.idx == -1; }
+TOKU_FILE *toku_bl_fidx2file(FTLOADER bl, FIDX i);
-int ft_loader_open_temp_file (FTLOADER bl, FIDX*file_idx);
+int ft_loader_open_temp_file(FTLOADER bl, FIDX *file_idx);
/* These data structures are used for manipulating a collection of rows in main memory. */
struct row {
@@ -100,11 +100,17 @@ struct rowset {
};
int init_rowset (struct rowset *rows, uint64_t memory_budget);
-void destroy_rowset (struct rowset *rows);
-int add_row (struct rowset *rows, DBT *key, DBT *val);
-
-int loader_write_row(DBT *key, DBT *val, FIDX data, FILE*, uint64_t *dataoff, struct wbuf *wb, FTLOADER bl);
-int loader_read_row (FILE *f, DBT *key, DBT *val);
+void destroy_rowset(struct rowset *rows);
+int add_row(struct rowset *rows, DBT *key, DBT *val);
+
+int loader_write_row(DBT *key,
+ DBT *val,
+ FIDX data,
+ TOKU_FILE *,
+ uint64_t *dataoff,
+ struct wbuf *wb,
+ FTLOADER bl);
+int loader_read_row(TOKU_FILE *f, DBT *key, DBT *val);
struct merge_fileset {
bool have_sorted_output; // Is there an previous key?
@@ -195,12 +201,13 @@ struct ft_loader_s {
bool did_reserve_memory;
bool compress_intermediates;
bool allow_puts;
- uint64_t reserved_memory; // how much memory are we allowed to use?
+ uint64_t reserved_memory; // how much memory are we allowed to use?
- /* To make it easier to recover from errors, we don't use FILE*, instead we use an index into the file_infos. */
+ /* To make it easier to recover from errors, we don't use TOKU_FILE*,
+ * instead we use an index into the file_infos. */
struct file_infos file_infos;
-#define PROGRESS_MAX (1<<16)
+#define PROGRESS_MAX (1 << 16)
int progress; // Progress runs from 0 to PROGRESS_MAX. When we call the poll function we convert to a float from 0.0 to 1.0
// We use an integer so that we can add to the progress using a fetch-and-add instruction.
diff --git a/storage/tokudb/PerconaFT/ft/loader/loader.cc b/storage/tokudb/PerconaFT/ft/loader/loader.cc
index 528c86a8f79..9528af95627 100644
--- a/storage/tokudb/PerconaFT/ft/loader/loader.cc
+++ b/storage/tokudb/PerconaFT/ft/loader/loader.cc
@@ -62,21 +62,17 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/x1764.h"
-static size_t (*os_fwrite_fun)(const void *,size_t,size_t,FILE*)=NULL;
-void ft_loader_set_os_fwrite (size_t (*fwrite_fun)(const void*,size_t,size_t,FILE*)) {
- os_fwrite_fun=fwrite_fun;
-}
+toku_instr_key *loader_bl_mutex_key;
+toku_instr_key *loader_fi_lock_mutex_key;
+toku_instr_key *loader_out_mutex_key;
-static size_t do_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) {
- if (os_fwrite_fun) {
- return os_fwrite_fun(ptr, size, nmemb, stream);
- } else {
- return fwrite(ptr, size, nmemb, stream);
- }
-}
+toku_instr_key *extractor_thread_key;
+toku_instr_key *fractal_thread_key;
+toku_instr_key *tokudb_file_tmp_key;
+toku_instr_key *tokudb_file_load_key;
-// 1024 is the right size_factor for production.
+// 1024 is the right size_factor for production.
// Different values for these sizes may be used for testing.
static uint32_t size_factor = 1024;
static uint32_t default_loader_nodesize = FT_DEFAULT_NODE_SIZE;
@@ -98,7 +94,7 @@ toku_ft_loader_get_rowset_budget_for_testing (void)
void ft_loader_lock_init(FTLOADER bl) {
invariant(!bl->mutex_init);
- toku_mutex_init(&bl->mutex, NULL);
+ toku_mutex_init(*loader_bl_mutex_key, &bl->mutex, nullptr);
bl->mutex_init = true;
}
@@ -130,7 +126,10 @@ static int add_big_buffer(struct file_info *file) {
newbuffer = true;
}
if (result == 0) {
- int r = setvbuf(file->file, (char *) file->buffer, _IOFBF, file->buffer_size);
+ int r = setvbuf(file->file->file,
+ static_cast<char *>(file->buffer),
+ _IOFBF,
+ file->buffer_size);
if (r != 0) {
result = get_error_errno();
if (newbuffer) {
@@ -149,9 +148,9 @@ static void cleanup_big_buffer(struct file_info *file) {
}
}
-int ft_loader_init_file_infos (struct file_infos *fi) {
+int ft_loader_init_file_infos(struct file_infos *fi) {
int result = 0;
- toku_mutex_init(&fi->lock, NULL);
+ toku_mutex_init(*loader_fi_lock_mutex_key, &fi->lock, nullptr);
fi->n_files = 0;
fi->n_files_limit = 1;
fi->n_files_open = 0;
@@ -195,11 +194,10 @@ void ft_loader_fi_destroy (struct file_infos *fi, bool is_error)
fi->file_infos = NULL;
}
-static int open_file_add (struct file_infos *fi,
- FILE *file,
- char *fname,
- /* out */ FIDX *idx)
-{
+static int open_file_add(struct file_infos *fi,
+ TOKU_FILE *file,
+ char *fname,
+ /* out */ FIDX *idx) {
int result = 0;
toku_mutex_lock(&fi->lock);
if (fi->n_files >= fi->n_files_limit) {
@@ -229,11 +227,12 @@ int ft_loader_fi_reopen (struct file_infos *fi, FIDX idx, const char *mode) {
int result = 0;
toku_mutex_lock(&fi->lock);
int i = idx.idx;
- invariant(i>=0 && i<fi->n_files);
+ invariant(i >= 0 && i < fi->n_files);
invariant(!fi->file_infos[i].is_open);
invariant(fi->file_infos[i].is_extant);
- fi->file_infos[i].file = toku_os_fopen(fi->file_infos[i].fname, mode);
- if (fi->file_infos[i].file == NULL) {
+ fi->file_infos[i].file =
+ toku_os_fopen(fi->file_infos[i].fname, mode, *tokudb_file_load_key);
+ if (fi->file_infos[i].file == NULL) {
result = get_error_errno();
} else {
fi->file_infos[i].is_open = true;
@@ -306,20 +305,20 @@ int ft_loader_open_temp_file (FTLOADER bl, FIDX *file_idx)
*/
{
int result = 0;
- if (result) // debug hack
+ if (result) // debug hack
return result;
- FILE *f = NULL;
+ TOKU_FILE *f = NULL;
int fd = -1;
- char *fname = toku_strdup(bl->temp_file_template);
+ char *fname = toku_strdup(bl->temp_file_template);
if (fname == NULL)
result = get_error_errno();
else {
fd = mkstemp(fname);
- if (fd < 0) {
+ if (fd < 0) {
result = get_error_errno();
} else {
- f = toku_os_fdopen(fd, "r+");
- if (f == NULL)
+ f = toku_os_fdopen(fd, "r+", fname, *tokudb_file_tmp_key);
+ if (f->file == nullptr)
result = get_error_errno();
else
result = open_file_add(&bl->file_infos, f, fname, file_idx);
@@ -338,7 +337,7 @@ int ft_loader_open_temp_file (FTLOADER bl, FIDX *file_idx)
return result;
}
-void toku_ft_loader_internal_destroy (FTLOADER bl, bool is_error) {
+void toku_ft_loader_internal_destroy(FTLOADER bl, bool is_error) {
ft_loader_lock_destroy(bl);
// These frees rely on the fact that if you free a NULL pointer then nothing bad happens.
@@ -634,12 +633,16 @@ int toku_ft_loader_open (FTLOADER *blp, /* out */
allow_puts);
if (r!=0) result = r;
}
- if (result==0 && allow_puts) {
+ if (result == 0 && allow_puts) {
FTLOADER bl = *blp;
- int r = toku_pthread_create(&bl->extractor_thread, NULL, extractor_thread, (void*)bl);
- if (r==0) {
+ int r = toku_pthread_create(*extractor_thread_key,
+ &bl->extractor_thread,
+ nullptr,
+ extractor_thread,
+ static_cast<void *>(bl));
+ if (r == 0) {
bl->extractor_live = true;
- } else {
+ } else {
result = r;
(void) toku_ft_loader_internal_destroy(bl, true);
}
@@ -658,17 +661,17 @@ static void ft_loader_set_panic(FTLOADER bl, int error, bool callback, int which
}
// One of the tests uses this.
-FILE *toku_bl_fidx2file (FTLOADER bl, FIDX i) {
+TOKU_FILE *toku_bl_fidx2file(FTLOADER bl, FIDX i) {
toku_mutex_lock(&bl->file_infos.lock);
- invariant(i.idx >=0 && i.idx < bl->file_infos.n_files);
+ invariant(i.idx >= 0 && i.idx < bl->file_infos.n_files);
invariant(bl->file_infos.file_infos[i.idx].is_open);
- FILE *result=bl->file_infos.file_infos[i.idx].file;
+ TOKU_FILE *result = bl->file_infos.file_infos[i.idx].file;
toku_mutex_unlock(&bl->file_infos.lock);
return result;
}
-static int bl_finish_compressed_write(FILE *stream, struct wbuf *wb) {
- int r;
+static int bl_finish_compressed_write(TOKU_FILE *stream, struct wbuf *wb) {
+ int r = 0;
char *compressed_buf = NULL;
const size_t data_size = wb->ndone;
invariant(data_size > 0);
@@ -719,31 +722,23 @@ static int bl_finish_compressed_write(FILE *stream, struct wbuf *wb) {
// Mark as written
wb->ndone = 0;
- size_t size_to_write = total_size + 4; // Includes writing total_size
+ size_t size_to_write = total_size + 4; // Includes writing total_size
+
+ r = toku_os_fwrite(compressed_buf, 1, size_to_write, stream);
- {
- size_t written = do_fwrite(compressed_buf, 1, size_to_write, stream);
- if (written!=size_to_write) {
- if (os_fwrite_fun) // if using hook to induce artificial errors (for testing) ...
- r = get_maybe_error_errno(); // ... then there is no error in the stream, but there is one in errno
- else
- r = ferror(stream);
- invariant(r!=0);
- goto exit;
- }
- }
- r = 0;
-exit:
if (compressed_buf) {
toku_free(compressed_buf);
}
return r;
}
-static int bl_compressed_write(void *ptr, size_t nbytes, FILE *stream, struct wbuf *wb) {
+static int bl_compressed_write(void *ptr,
+ size_t nbytes,
+ TOKU_FILE *stream,
+ struct wbuf *wb) {
invariant(wb->size <= MAX_UNCOMPRESSED_BUF);
size_t bytes_left = nbytes;
- char *buf = (char*)ptr;
+ char *buf = (char *)ptr;
while (bytes_left > 0) {
size_t bytes_to_copy = bytes_left;
@@ -766,29 +761,28 @@ static int bl_compressed_write(void *ptr, size_t nbytes, FILE *stream, struct wb
return 0;
}
-static int bl_fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream, struct wbuf *wb, FTLOADER bl)
-/* Effect: this is a wrapper for fwrite that returns 0 on success, otherwise returns an error number.
+static int bl_fwrite(void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ struct wbuf *wb,
+ FTLOADER bl)
+/* Effect: this is a wrapper for fwrite that returns 0 on success, otherwise
+ * returns an error number.
* Arguments:
* ptr the data to be writen.
* size the amount of data to be written.
* nmemb the number of units of size to be written.
* stream write the data here.
- * wb where to write uncompressed data (if we're compressing) or ignore if NULL
- * bl passed so we can panic the ft_loader if something goes wrong (recording the error number).
+ * wb where to write uncompressed data (if we're compressing) or ignore if
+ * NULL
+ * bl passed so we can panic the ft_loader if something goes wrong
+ * (recording the error number).
* Return value: 0 on success, an error number otherwise.
*/
{
if (!bl->compress_intermediates || !wb) {
- size_t r = do_fwrite(ptr, size, nmemb, stream);
- if (r!=nmemb) {
- int e;
- if (os_fwrite_fun) // if using hook to induce artificial errors (for testing) ...
- e = get_maybe_error_errno(); // ... then there is no error in the stream, but there is one in errno
- else
- e = ferror(stream);
- invariant(e!=0);
- return e;
- }
+ return toku_os_fwrite(ptr, size, nmemb, stream);
} else {
size_t num_bytes = size * nmemb;
int r = bl_compressed_write(ptr, num_bytes, stream, wb);
@@ -799,8 +793,9 @@ static int bl_fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream, struct
return 0;
}
-static int bl_fread (void *ptr, size_t size, size_t nmemb, FILE *stream)
-/* Effect: this is a wrapper for fread that returns 0 on success, otherwise returns an error number.
+static int bl_fread(void *ptr, size_t size, size_t nmemb, TOKU_FILE *stream)
+/* Effect: this is a wrapper for fread that returns 0 on success, otherwise
+ * returns an error number.
* Arguments:
* ptr read data into here.
* size size of data element to be read.
@@ -809,24 +804,14 @@ static int bl_fread (void *ptr, size_t size, size_t nmemb, FILE *stream)
* Return value: 0 on success, an error number otherwise.
*/
{
- size_t r = fread(ptr, size, nmemb, stream);
- if (r==0) {
- if (feof(stream)) return EOF;
- else {
- do_error: ;
- int e = ferror(stream);
- // r == 0 && !feof && e == 0, how does this happen? invariant(e!=0);
- return e;
- }
- } else if (r<nmemb) {
- goto do_error;
- } else {
- return 0;
- }
+ return toku_os_fread(ptr, size, nmemb, stream);
}
-static int bl_write_dbt (DBT *dbt, FILE* datafile, uint64_t *dataoff, struct wbuf *wb, FTLOADER bl)
-{
+static int bl_write_dbt(DBT *dbt,
+ TOKU_FILE *datafile,
+ uint64_t *dataoff,
+ struct wbuf *wb,
+ FTLOADER bl) {
int r;
int dlen = dbt->size;
if ((r=bl_fwrite(&dlen, sizeof(dlen), 1, datafile, wb, bl))) return r;
@@ -836,8 +821,7 @@ static int bl_write_dbt (DBT *dbt, FILE* datafile, uint64_t *dataoff, struct wbu
return 0;
}
-static int bl_read_dbt (/*in*/DBT *dbt, FILE *stream)
-{
+static int bl_read_dbt(/*in*/ DBT *dbt, TOKU_FILE *stream) {
int len;
{
int r;
@@ -891,13 +875,20 @@ static int bl_read_dbt_from_dbufio (/*in*/DBT *dbt, DBUFIO_FILESET bfs, int file
return result;
}
-
-int loader_write_row(DBT *key, DBT *val, FIDX data, FILE *dataf, uint64_t *dataoff, struct wbuf *wb, FTLOADER bl)
-/* Effect: Given a key and a val (both DBTs), write them to a file. Increment *dataoff so that it's up to date.
+int loader_write_row(DBT *key,
+ DBT *val,
+ FIDX data,
+ TOKU_FILE *dataf,
+ uint64_t *dataoff,
+ struct wbuf *wb,
+ FTLOADER bl)
+/* Effect: Given a key and a val (both DBTs), write them to a file. Increment
+ * *dataoff so that it's up to date.
* Arguments:
* key, val write these.
* data the file to write them to
- * dataoff a pointer to a counter that keeps track of the amount of data written so far.
+ * dataoff a pointer to a counter that keeps track of the amount of data
+ * written so far.
* wb a pointer (possibly NULL) to buffer uncompressed output
* bl the ft_loader (passed so we can panic if needed).
* Return value: 0 on success, an error number otherwise.
@@ -915,8 +906,9 @@ int loader_write_row(DBT *key, DBT *val, FIDX data, FILE *dataf, uint64_t *datao
return 0;
}
-int loader_read_row (FILE *f, DBT *key, DBT *val)
-/* Effect: Read a key value pair from a file. The DBTs must have DB_DBT_REALLOC set.
+int loader_read_row(TOKU_FILE *f, DBT *key, DBT *val)
+/* Effect: Read a key value pair from a file. The DBTs must have DB_DBT_REALLOC
+ * set.
* Arguments:
* f where to read it from.
* key, val read it into these.
@@ -1086,7 +1078,7 @@ static void* extractor_thread (void *blv) {
FTLOADER bl = (FTLOADER)blv;
int r = 0;
while (1) {
- void *item;
+ void *item = nullptr;
{
int rq = toku_queue_deq(bl->primary_rowset_queue, &item, NULL, NULL);
if (rq==EOF) break;
@@ -1107,14 +1099,14 @@ static void* extractor_thread (void *blv) {
//printf("%s:%d extractor finishing\n", __FILE__, __LINE__);
if (r == 0) {
r = finish_primary_rows(bl);
- if (r)
+ if (r)
ft_loader_set_panic(bl, r, false, 0, nullptr, nullptr);
-
}
- return NULL;
+ toku_instr_delete_current_thread();
+ return nullptr;
}
-static void enqueue_for_extraction (FTLOADER bl) {
+static void enqueue_for_extraction(FTLOADER bl) {
//printf("%s:%d enqueing %ld items\n", __FILE__, __LINE__, bl->primary_rowset.n_rows);
struct rowset *XMALLOC(enqueue_me);
*enqueue_me = bl->primary_rowset;
@@ -1625,11 +1617,12 @@ static int write_rowset_to_file (FTLOADER bl, FIDX sfile, const struct rowset ro
struct wbuf wb;
wbuf_init(&wb, uncompressed_buffer, MAX_UNCOMPRESSED_BUF);
- FILE *sstream = toku_bl_fidx2file(bl, sfile);
- for (size_t i=0; i<rows.n_rows; i++) {
- DBT skey = make_dbt(rows.data + rows.rows[i].off, rows.rows[i].klen);
- DBT sval = make_dbt(rows.data + rows.rows[i].off + rows.rows[i].klen, rows.rows[i].vlen);
-
+ TOKU_FILE *sstream = toku_bl_fidx2file(bl, sfile);
+ for (size_t i = 0; i < rows.n_rows; i++) {
+ DBT skey = make_dbt(rows.data + rows.rows[i].off, rows.rows[i].klen);
+ DBT sval = make_dbt(rows.data + rows.rows[i].off + rows.rows[i].klen,
+ rows.rows[i].vlen);
+
uint64_t soffset=0; // don't really need this.
r = loader_write_row(&skey, &sval, sfile, sstream, &soffset, &wb, bl);
if (r != 0) {
@@ -1726,14 +1719,30 @@ int ft_loader_sort_and_write_rows (struct rowset *rows, struct merge_fileset *fs
return sort_and_write_rows (*rows, fs, bl, which_db, dest_db, compare);
}
-int toku_merge_some_files_using_dbufio (const bool to_q, FIDX dest_data, QUEUE q, int n_sources, DBUFIO_FILESET bfs, FIDX srcs_fidxs[/*n_sources*/], FTLOADER bl, int which_db, DB *dest_db, ft_compare_func compare, int progress_allocation)
-/* Effect: Given an array of FILE*'s each containing sorted, merge the data and write it to an output. All the files remain open after the merge.
- * This merge is performed in one pass, so don't pass too many files in. If you need a tree of merges do it elsewhere.
- * If TO_Q is true then we write rowsets into queue Q. Otherwise we write into dest_data.
- * Modifies: May modify the arrays of files (but if modified, it must be a permutation so the caller can use that array to close everything.)
- * Requires: The number of sources is at least one, and each of the input files must have at least one row in it.
+int toku_merge_some_files_using_dbufio(const bool to_q,
+ FIDX dest_data,
+ QUEUE q,
+ int n_sources,
+ DBUFIO_FILESET bfs,
+ FIDX srcs_fidxs[/*n_sources*/],
+ FTLOADER bl,
+ int which_db,
+ DB *dest_db,
+ ft_compare_func compare,
+ int progress_allocation)
+/* Effect: Given an array of FILE*'s each containing sorted, merge the data and
+ * write it to an output. All the files remain open after the merge.
+ * This merge is performed in one pass, so don't pass too many files in. If
+ * you need a tree of merges do it elsewhere.
+ * If TO_Q is true then we write rowsets into queue Q. Otherwise we write
+ * into dest_data.
+ * Modifies: May modify the arrays of files (but if modified, it must be a
+ * permutation so the caller can use that array to close everything.)
+ * Requires: The number of sources is at least one, and each of the input files
+ * must have at least one row in it.
* Arguments:
- * to_q boolean indicating that output is queue (true) or a file (false)
+ * to_q boolean indicating that output is queue (true) or a file
+ * (false)
* dest_data where to write the sorted data
* q where to write the sorted data
* n_sources how many source files.
@@ -1746,9 +1755,10 @@ int toku_merge_some_files_using_dbufio (const bool to_q, FIDX dest_data, QUEUE q
{
int result = 0;
- FILE *dest_stream = to_q ? NULL : toku_bl_fidx2file(bl, dest_data);
+ TOKU_FILE *dest_stream = to_q ? nullptr : toku_bl_fidx2file(bl, dest_data);
- //printf(" merge_some_files progress=%d fin at %d\n", bl->progress, bl->progress+progress_allocation);
+ // printf(" merge_some_files progress=%d fin at %d\n", bl->progress,
+ // bl->progress+progress_allocation);
DBT keys[n_sources];
DBT vals[n_sources];
uint64_t dataoff[n_sources];
@@ -1942,12 +1952,18 @@ static int merge_some_files (const bool to_q, FIDX dest_data, QUEUE q, int n_sou
int result = 0;
DBUFIO_FILESET bfs = NULL;
int *MALLOC_N(n_sources, fds);
- if (fds==NULL) result=get_error_errno();
- if (result==0) {
- for (int i=0; i<n_sources; i++) {
- int r = fileno(toku_bl_fidx2file(bl, srcs_fidxs[i])); // we rely on the fact that when the files are closed, the fd is also closed.
- if (r==-1) {
- result=get_error_errno();
+ if (fds == NULL)
+ result = get_error_errno();
+ if (result == 0) {
+ for (int i = 0; i < n_sources; i++) {
+ int r = fileno(
+ toku_bl_fidx2file(bl, srcs_fidxs[i])->file); // we rely on the
+ // fact that when
+ // the files are
+ // closed, the fd
+ // is also closed.
+ if (r == -1) {
+ result = get_error_errno();
break;
}
fds[i] = r;
@@ -2177,7 +2193,7 @@ static inline void dbout_init(struct dbout *out, FT ft) {
out->current_off = 0;
out->n_translations = out->n_translations_limit = 0;
out->translation = NULL;
- toku_mutex_init(&out->mutex, NULL);
+ toku_mutex_init(*loader_out_mutex_key, &out->mutex, nullptr);
out->ft = ft;
}
@@ -2417,7 +2433,7 @@ static int toku_loader_write_ft_from_q (FTLOADER bl,
assert_zero(r);
return result;
}
- FILE *pivots_stream = toku_bl_fidx2file(bl, pivots_file);
+ TOKU_FILE *pivots_stream = toku_bl_fidx2file(bl, pivots_file);
TXNID root_xid_that_created = TXNID_NONE;
if (bl->root_xids_that_created)
@@ -2704,21 +2720,35 @@ int toku_loader_write_ft_from_q_in_C (FTLOADER bl,
static void* fractal_thread (void *ftav) {
struct fractal_thread_args *fta = (struct fractal_thread_args *)ftav;
- int r = toku_loader_write_ft_from_q (fta->bl, fta->descriptor, fta->fd, fta->progress_allocation, fta->q, fta->total_disksize_estimate, fta->which_db, fta->target_nodesize, fta->target_basementnodesize, fta->target_compression_method, fta->target_fanout);
+ int r = toku_loader_write_ft_from_q(fta->bl,
+ fta->descriptor,
+ fta->fd,
+ fta->progress_allocation,
+ fta->q,
+ fta->total_disksize_estimate,
+ fta->which_db,
+ fta->target_nodesize,
+ fta->target_basementnodesize,
+ fta->target_compression_method,
+ fta->target_fanout);
fta->errno_result = r;
- return NULL;
-}
-
-static int loader_do_i (FTLOADER bl,
- int which_db,
- DB *dest_db,
- ft_compare_func compare,
- const DESCRIPTOR descriptor,
- const char *new_fname,
- int progress_allocation // how much progress do I need to add into bl->progress by the end..
- )
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
+}
+
+static int loader_do_i(FTLOADER bl,
+ int which_db,
+ DB *dest_db,
+ ft_compare_func compare,
+ const DESCRIPTOR descriptor,
+ const char *new_fname,
+ int progress_allocation // how much progress do I need
+ // to add into bl->progress by
+ // the end..
+ )
/* Effect: Handle the file creating for one particular DB in the bulk loader. */
-/* Requires: The data is fully extracted, so we can do merges out of files and write the ft file. */
+/* Requires: The data is fully extracted, so we can do merges out of files and
+ write the ft file. */
{
//printf("doing i use %d progress=%d fin at %d\n", progress_allocation, bl->progress, bl->progress+progress_allocation);
struct merge_fileset *fs = &(bl->fs[which_db]);
@@ -2729,10 +2759,14 @@ static int loader_do_i (FTLOADER bl,
if (r) goto error;
{
- mode_t mode = S_IRUSR+S_IWUSR + S_IRGRP+S_IWGRP;
- int fd = toku_os_open(new_fname, O_RDWR| O_CREAT | O_BINARY, mode); // #2621
+ mode_t mode = S_IRUSR + S_IWUSR + S_IRGRP + S_IWGRP;
+ int fd = toku_os_open(new_fname,
+ O_RDWR | O_CREAT | O_BINARY,
+ mode,
+ *tokudb_file_load_key); // #2621
if (fd < 0) {
- r = get_error_errno(); goto error;
+ r = get_error_errno();
+ goto error;
}
uint32_t target_nodesize, target_basementnodesize, target_fanout;
@@ -2752,24 +2786,27 @@ static int loader_do_i (FTLOADER bl,
progress_allocation -= allocation_for_merge;
// This structure must stay live until the join below.
- struct fractal_thread_args fta = {
- bl,
- descriptor,
- fd,
- progress_allocation,
- bl->fractal_queues[which_db],
- bl->extracted_datasizes[which_db],
- 0,
- which_db,
- target_nodesize,
- target_basementnodesize,
- target_compression_method,
- target_fanout
- };
-
- r = toku_pthread_create(bl->fractal_threads+which_db, NULL, fractal_thread, (void*)&fta);
+ struct fractal_thread_args fta = {bl,
+ descriptor,
+ fd,
+ progress_allocation,
+ bl->fractal_queues[which_db],
+ bl->extracted_datasizes[which_db],
+ 0,
+ which_db,
+ target_nodesize,
+ target_basementnodesize,
+ target_compression_method,
+ target_fanout};
+
+ r = toku_pthread_create(*fractal_thread_key,
+ bl->fractal_threads + which_db,
+ nullptr,
+ fractal_thread,
+ static_cast<void *>(&fta));
if (r) {
- int r2 __attribute__((__unused__)) = toku_queue_destroy(bl->fractal_queues[which_db]);
+ int r2 __attribute__((__unused__)) =
+ toku_queue_destroy(bl->fractal_queues[which_db]);
// ignore r2, since we already have an error
bl->fractal_queues[which_db] = nullptr;
goto error;
@@ -3106,7 +3143,7 @@ static int read_some_pivots (FIDX pivots_file, int n_to_read, FTLOADER bl,
for (int i = 0; i < n_to_read; i++)
pivots[i] = zero_dbt;
- FILE *pivots_stream = toku_bl_fidx2file(bl, pivots_file);
+ TOKU_FILE *pivots_stream = toku_bl_fidx2file(bl, pivots_file);
int result = 0;
for (int i = 0; i < n_to_read; i++) {
@@ -3158,8 +3195,9 @@ static int setup_nonleaf_block (int n_children,
}
if (result == 0) {
- FILE *next_pivots_stream = toku_bl_fidx2file(bl, next_pivots_file);
- int r = bl_write_dbt(&pivots[n_children-1], next_pivots_stream, NULL, nullptr, bl);
+ TOKU_FILE *next_pivots_stream = toku_bl_fidx2file(bl, next_pivots_file);
+ int r = bl_write_dbt(
+ &pivots[n_children - 1], next_pivots_stream, NULL, nullptr, bl);
if (r)
result = r;
}
@@ -3274,8 +3312,11 @@ static int write_nonleaves (FTLOADER bl, FIDX pivots_fidx, struct dbout *out, st
// 2) We put the 15 pivots and 16 blocks into an non-leaf node.
// 3) We put the 16th pivot into the next pivots file.
{
- int r = fseek(toku_bl_fidx2file(bl, pivots_fidx), 0, SEEK_SET);
- if (r!=0) { return get_error_errno(); }
+ int r =
+ fseek(toku_bl_fidx2file(bl, pivots_fidx)->file, 0, SEEK_SET);
+ if (r != 0) {
+ return get_error_errno();
+ }
}
FIDX next_pivots_file;
@@ -3295,7 +3336,7 @@ static int write_nonleaves (FTLOADER bl, FIDX pivots_fidx, struct dbout *out, st
while (sts->n_subtrees - n_subtrees_used >= n_per_block*2) {
// grab the first N_PER_BLOCK and build a node.
DBT *pivots;
- int64_t blocknum_of_new_node;
+ int64_t blocknum_of_new_node = 0;
struct subtree_info *subtree_info;
int r = setup_nonleaf_block (n_per_block,
sts, pivots_fidx, n_subtrees_used,
diff --git a/storage/tokudb/PerconaFT/ft/loader/loader.h b/storage/tokudb/PerconaFT/ft/loader/loader.h
index 9c1bdab1ee2..cea2e8dfda2 100644
--- a/storage/tokudb/PerconaFT/ft/loader/loader.h
+++ b/storage/tokudb/PerconaFT/ft/loader/loader.h
@@ -38,6 +38,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#pragma once
+#include "toku_portability.h"
#include "ft/txn/txn.h"
#include "ft/cachetable/cachetable.h"
#include "ft/comparator.h"
@@ -77,8 +78,6 @@ int toku_ft_loader_abort(FTLOADER bl,
bool is_error);
// For test purposes only
-void toku_ft_loader_set_size_factor (uint32_t factor);
-
-void ft_loader_set_os_fwrite (size_t (*fwrite_fun)(const void*,size_t,size_t,FILE*));
+void toku_ft_loader_set_size_factor(uint32_t factor);
size_t ft_loader_leafentry_size(size_t key_size, size_t val_size, TXNID xid);
diff --git a/storage/tokudb/PerconaFT/ft/logger/log-internal.h b/storage/tokudb/PerconaFT/ft/logger/log-internal.h
index bee74fac346..be19e1342cd 100644
--- a/storage/tokudb/PerconaFT/ft/logger/log-internal.h
+++ b/storage/tokudb/PerconaFT/ft/logger/log-internal.h
@@ -70,11 +70,11 @@ struct mylock {
};
static inline void ml_init(struct mylock *l) {
- toku_mutex_init(&l->lock, 0);
-}
-static inline void ml_lock(struct mylock *l) {
- toku_mutex_lock(&l->lock);
+ toku_mutex_init(*log_internal_lock_mutex_key, &l->lock, nullptr);
}
+// TODO: source location info might have be to be pulled up one caller
+// to be useful
+static inline void ml_lock(struct mylock *l) { toku_mutex_lock(&l->lock); }
static inline void ml_unlock(struct mylock *l) {
toku_mutex_unlock(&l->lock);
}
diff --git a/storage/tokudb/PerconaFT/ft/logger/logcursor.cc b/storage/tokudb/PerconaFT/ft/logger/logcursor.cc
index f13419ae43e..494d3b1d531 100644
--- a/storage/tokudb/PerconaFT/ft/logger/logcursor.cc
+++ b/storage/tokudb/PerconaFT/ft/logger/logcursor.cc
@@ -85,10 +85,10 @@ static int lc_close_cur_logfile(TOKULOGCURSOR lc) {
}
static toku_off_t lc_file_len(const char *name) {
- toku_struct_stat buf;
- int r = toku_stat(name, &buf);
- assert(r == 0);
- return buf.st_size;
+ toku_struct_stat buf;
+ int r = toku_stat(name, &buf, *tokudb_file_data_key);
+ assert(r == 0);
+ return buf.st_size;
}
// Cat the file and throw away the contents. This brings the file into the file system cache
diff --git a/storage/tokudb/PerconaFT/ft/logger/logger.cc b/storage/tokudb/PerconaFT/ft/logger/logger.cc
index eacec9cb83f..3f13fe10feb 100644
--- a/storage/tokudb/PerconaFT/ft/logger/logger.cc
+++ b/storage/tokudb/PerconaFT/ft/logger/logger.cc
@@ -49,11 +49,17 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/status.h"
-static const int log_format_version=TOKU_LOG_VERSION;
+static const int log_format_version = TOKU_LOG_VERSION;
-static int open_logfile (TOKULOGGER logger);
-static void logger_write_buffer (TOKULOGGER logger, LSN *fsynced_lsn);
-static void delete_logfile(TOKULOGGER logger, long long index, uint32_t version);
+toku_instr_key *result_output_condition_lock_mutex_key;
+toku_instr_key *result_output_condition_key;
+toku_instr_key *tokudb_file_log_key;
+
+static int open_logfile(TOKULOGGER logger);
+static void logger_write_buffer(TOKULOGGER logger, LSN *fsynced_lsn);
+static void delete_logfile(TOKULOGGER logger,
+ long long index,
+ uint32_t version);
static void grab_output(TOKULOGGER logger, LSN *fsynced_lsn);
static void release_output(TOKULOGGER logger, LSN fsynced_lsn);
@@ -131,10 +137,13 @@ int toku_logger_create (TOKULOGGER *resultp) {
// n_in_file is uninitialized
result->write_block_size = FT_DEFAULT_NODE_SIZE; // default logging size is the same as the default ft block size
toku_logfilemgr_create(&result->logfilemgr);
- *resultp=result;
+ *resultp = result;
ml_init(&result->input_lock);
- toku_mutex_init(&result->output_condition_lock, NULL);
- toku_cond_init(&result->output_condition, NULL);
+ toku_mutex_init(*result_output_condition_lock_mutex_key,
+ &result->output_condition_lock,
+ nullptr);
+ toku_cond_init(
+ *result_output_condition_key, &result->output_condition, nullptr);
result->rollback_cachefile = NULL;
result->output_is_available = true;
toku_txn_manager_init(&result->txn_manager);
@@ -300,10 +309,10 @@ int toku_logger_close(TOKULOGGER *loggerp) {
grab_output(logger, &fsynced_lsn);
logger_write_buffer(logger, &fsynced_lsn);
if (logger->fd!=-1) {
- if ( logger->write_log_files ) {
+ if (logger->write_log_files) {
toku_file_fsync_without_accounting(logger->fd);
}
- r = close(logger->fd);
+ r = toku_os_close(logger->fd);
assert(r == 0);
}
r = close_logdir(logger);
@@ -345,9 +354,13 @@ static int close_and_open_logfile (TOKULOGGER logger, LSN *fsynced_lsn)
if (logger->write_log_files) {
toku_file_fsync_without_accounting(logger->fd);
*fsynced_lsn = logger->written_lsn;
- toku_logfilemgr_update_last_lsn(logger->logfilemgr, logger->written_lsn); // fixes t:2294
+ toku_logfilemgr_update_last_lsn(logger->logfilemgr,
+ logger->written_lsn); // fixes t:2294
}
- r = close(logger->fd); if (r!=0) return get_error_errno();
+ r = toku_os_close(logger->fd);
+
+ if (r != 0)
+ return get_error_errno();
return open_logfile(logger);
}
@@ -677,18 +690,28 @@ static int open_logfile (TOKULOGGER logger)
{
int fnamelen = strlen(logger->directory)+50;
char fname[fnamelen];
- snprintf(fname, fnamelen, "%s/log%012lld.tokulog%d", logger->directory, logger->next_log_file_number, TOKU_LOG_VERSION);
+ snprintf(fname,
+ fnamelen,
+ "%s/log%012lld.tokulog%d",
+ logger->directory,
+ logger->next_log_file_number,
+ TOKU_LOG_VERSION);
long long index = logger->next_log_file_number;
if (logger->write_log_files) {
- logger->fd = open(fname, O_CREAT+O_WRONLY+O_TRUNC+O_EXCL+O_BINARY, S_IRUSR+S_IWUSR);
- if (logger->fd==-1) {
+ logger->fd =
+ toku_os_open(fname,
+ O_CREAT + O_WRONLY + O_TRUNC + O_EXCL + O_BINARY,
+ S_IRUSR + S_IWUSR,
+ *tokudb_file_log_key);
+ if (logger->fd == -1) {
return get_error_errno();
}
fsync_logdir(logger);
logger->next_log_file_number++;
} else {
- logger->fd = open(DEV_NULL_FILE, O_WRONLY+O_BINARY);
- if (logger->fd==-1) {
+ logger->fd = toku_os_open(
+ DEV_NULL_FILE, O_WRONLY + O_BINARY, S_IWUSR, *tokudb_file_log_key);
+ if (logger->fd == -1) {
return get_error_errno();
}
}
@@ -834,10 +857,11 @@ int toku_logger_restart(TOKULOGGER logger, LSN lastlsn)
logger_write_buffer(logger, &fsynced_lsn);
// close the log file
- if ( logger->write_log_files) { // fsyncs don't work to /dev/null
+ if (logger->write_log_files) { // fsyncs don't work to /dev/null
toku_file_fsync_without_accounting(logger->fd);
}
- r = close(logger->fd); assert(r == 0);
+ r = toku_os_close(logger->fd);
+ assert(r == 0);
logger->fd = -1;
// reset the LSN's to the lastlsn when the logger was opened
@@ -1237,11 +1261,13 @@ void toku_txnid2txn(TOKULOGGER logger, TXNID_PAIR txnid, TOKUTXN *result) {
}
// Find the earliest LSN in a log. No locks are needed.
-static int peek_at_log (TOKULOGGER logger, char* filename, LSN *first_lsn) {
- int fd = open(filename, O_RDONLY+O_BINARY);
- if (fd<0) {
+static int peek_at_log(TOKULOGGER logger, char *filename, LSN *first_lsn) {
+ int fd = toku_os_open(
+ filename, O_RDONLY + O_BINARY, S_IRUSR, *tokudb_file_log_key);
+ if (fd < 0) {
int er = get_error_errno();
- if (logger->write_log_files) printf("couldn't open: %s\n", strerror(er));
+ if (logger->write_log_files)
+ printf("couldn't open: %s\n", strerror(er));
return er;
}
enum { SKIP = 12+1+4 }; // read the 12 byte header, the first message, and the first len
@@ -1258,10 +1284,13 @@ static int peek_at_log (TOKULOGGER logger, char* filename, LSN *first_lsn) {
lsn = rbuf_ulonglong(&rb);
}
- r=close(fd);
- if (r!=0) { return 0; }
+ r = toku_os_close(fd);
+
+ if (r != 0) {
+ return 0;
+ }
- first_lsn->lsn=lsn;
+ first_lsn->lsn = lsn;
return 0;
}
diff --git a/storage/tokudb/PerconaFT/ft/logger/recover.cc b/storage/tokudb/PerconaFT/ft/logger/recover.cc
index 9eaa56bdc53..9a9a1214ecb 100644
--- a/storage/tokudb/PerconaFT/ft/logger/recover.cc
+++ b/storage/tokudb/PerconaFT/ft/logger/recover.cc
@@ -954,14 +954,14 @@ static int toku_recover_frename(struct logtype_frename *l, RECOVER_ENV renv) {
std::unique_ptr<char[], decltype(&toku_free)> new_iname_full(
toku_construct_full_name(2, data_dir, l->new_iname.data), &toku_free);
- if (toku_stat(old_iname_full.get(), &stat) == -1) {
+ if (toku_stat(old_iname_full.get(), &stat, toku_uninstrumented) == -1) {
if (ENOENT == errno)
old_exist = false;
else
return 1;
}
- if (toku_stat(new_iname_full.get(), &stat) == -1) {
+ if (toku_stat(new_iname_full.get(), &stat, toku_uninstrumented) == -1) {
if (ENOENT == errno)
new_exist = false;
else
@@ -980,7 +980,7 @@ static int toku_recover_frename(struct logtype_frename *l, RECOVER_ENV renv) {
// 'stalled cachefiles' container the new file is removed
// and the old file is renamed.
if (old_exist && new_exist &&
- (toku_os_unlink(new_iname_full.get()) == -1 ||
+ (toku_os_delete(new_iname_full.get()) == -1 ||
toku_os_rename(old_iname_full.get(), new_iname_full.get()) == -1 ||
toku_fsync_directory(old_iname_full.get()) == -1 ||
toku_fsync_directory(new_iname_full.get()) == -1))
@@ -1473,9 +1473,13 @@ static int do_recovery(RECOVER_ENV renv, const char *env_dir, const char *log_di
{
toku_struct_stat buf;
- if (toku_stat(env_dir, &buf)!=0) {
+ if (toku_stat(env_dir, &buf, toku_uninstrumented)) {
rr = get_error_errno();
- fprintf(stderr, "%.24s PerconaFT recovery error: directory does not exist: %s\n", ctime(&tnow), env_dir);
+ fprintf(stderr,
+ "%.24s PerconaFT recovery error: directory does not exist: "
+ "%s\n",
+ ctime(&tnow),
+ env_dir);
goto errorexit;
} else if (!S_ISDIR(buf.st_mode)) {
fprintf(stderr, "%.24s PerconaFT recovery error: this file is supposed to be a directory, but is not: %s\n", ctime(&tnow), env_dir);
diff --git a/storage/tokudb/PerconaFT/ft/serialize/block_allocator.cc b/storage/tokudb/PerconaFT/ft/serialize/block_allocator.cc
index 19811373d16..29f6daa293a 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/block_allocator.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/block_allocator.cc
@@ -40,6 +40,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <string.h>
+#include "toku_portability.h"
#include "portability/memory.h"
#include "portability/toku_assert.h"
#include "portability/toku_stdint.h"
diff --git a/storage/tokudb/PerconaFT/ft/serialize/block_table.cc b/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
index d2532134d96..56d51f56915 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
@@ -54,6 +54,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/nb_mutex.h"
#include "util/scoped_malloc.h"
+
+toku_instr_key *block_table_mutex_key;
+toku_instr_key *safe_file_size_lock_mutex_key;
+toku_instr_key *safe_file_size_lock_rwlock_key;
+
// indicates the end of a freelist
static const BLOCKNUM freelist_null = {-1};
@@ -99,8 +104,10 @@ void block_table::_create_internal() {
memset(&_checkpointed, 0, sizeof(struct translation));
memset(&_mutex, 0, sizeof(_mutex));
_bt_block_allocator = new BlockAllocator();
- toku_mutex_init(&_mutex, nullptr);
- nb_mutex_init(&_safe_file_size_lock);
+ toku_mutex_init(*block_table_mutex_key, &_mutex, nullptr);
+ nb_mutex_init(*safe_file_size_lock_mutex_key,
+ *safe_file_size_lock_rwlock_key,
+ &_safe_file_size_lock);
}
// Fill in the checkpointed translation from buffer, and copy checkpointed to
@@ -128,7 +135,7 @@ int block_table::create_from_buffer(
_copy_translation(&_current, &_checkpointed, TRANSLATION_CURRENT);
// Determine the file size
- int64_t file_size;
+ int64_t file_size = 0;
r = toku_os_get_file_size(fd, &file_size);
lazy_assert_zero(r);
invariant(file_size >= 0);
diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
index fcab9fc675e..b24d72a5dff 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
@@ -417,8 +417,10 @@ static size_t serialize_ft_min_size(uint32_t version) {
switch (version) {
case FT_LAYOUT_VERSION_29:
size += sizeof(uint64_t); // logrows in ft
+ // fallthrough
case FT_LAYOUT_VERSION_28:
size += sizeof(uint32_t); // fanout in ft
+ // fallthrough
case FT_LAYOUT_VERSION_27:
case FT_LAYOUT_VERSION_26:
case FT_LAYOUT_VERSION_25:
@@ -427,10 +429,12 @@ static size_t serialize_ft_min_size(uint32_t version) {
case FT_LAYOUT_VERSION_22:
case FT_LAYOUT_VERSION_21:
size += sizeof(MSN); // max_msn_in_ft
+ // fallthrough
case FT_LAYOUT_VERSION_20:
case FT_LAYOUT_VERSION_19:
size += 1; // compression method
size += sizeof(MSN); // highest_unused_msn_for_upgrade
+ // fallthrough
case FT_LAYOUT_VERSION_18:
size += sizeof(uint64_t); // time_of_last_optimize_begin
size += sizeof(uint64_t); // time_of_last_optimize_end
@@ -438,9 +442,11 @@ static size_t serialize_ft_min_size(uint32_t version) {
size += sizeof(MSN); // msn_at_start_of_last_completed_optimize
size -= 8; // removed num_blocks_to_upgrade_14
size -= 8; // removed num_blocks_to_upgrade_13
+ // fallthrough
case FT_LAYOUT_VERSION_17:
size += 16;
invariant(sizeof(STAT64INFO_S) == 16);
+ // fallthrough
case FT_LAYOUT_VERSION_16:
case FT_LAYOUT_VERSION_15:
size += 4; // basement node size
@@ -448,8 +454,10 @@ static size_t serialize_ft_min_size(uint32_t version) {
// num_blocks_to_upgrade, now one int each for upgrade
// from 13, 14
size += 8; // time of last verification
+ // fallthrough
case FT_LAYOUT_VERSION_14:
size += 8; // TXNID that created
+ // fallthrough
case FT_LAYOUT_VERSION_13:
size += (4 // build_id
+
@@ -459,7 +467,7 @@ static size_t serialize_ft_min_size(uint32_t version) {
+
8 // time_of_last_modification
);
- // fall through
+ // fallthrough
case FT_LAYOUT_VERSION_12:
size += (+8 // "tokudata"
+
diff --git a/storage/tokudb/PerconaFT/ft/serialize/sub_block.cc b/storage/tokudb/PerconaFT/ft/serialize/sub_block.cc
index c967d4b4c1c..6dc1f82844a 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/sub_block.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/sub_block.cc
@@ -51,6 +51,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/threadpool.h"
#include "util/x1764.h"
+toku_instr_key *workset_lock_mutex_key;
+toku_instr_key *ws_worker_wait_key;
+
SUB_BLOCK sub_block_creat(void) {
SUB_BLOCK XMALLOC(sb);
sub_block_init(sb);
diff --git a/storage/tokudb/PerconaFT/ft/serialize/workset.h b/storage/tokudb/PerconaFT/ft/serialize/workset.h
index 073741fccb1..295eb73cec9 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/workset.h
+++ b/storage/tokudb/PerconaFT/ft/serialize/workset.h
@@ -41,6 +41,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <toku_list.h>
#include <toku_pthread.h>
+extern toku_instr_key *ws_worker_wait_key;
+
// The work struct is the base class for work to be done by some threads
struct work {
struct toku_list next;
@@ -54,16 +56,14 @@ struct workset {
toku_cond_t worker_wait; // a condition variable used to wait for all of the worker to release their reference on the workset
};
-static inline void
-workset_init(struct workset *ws) {
- toku_mutex_init(&ws->lock, NULL);
+static inline void workset_init(struct workset *ws) {
+ toku_mutex_init(*workset_lock_mutex_key, &ws->lock, nullptr);
toku_list_init(&ws->worklist);
- ws->refs = 1; // the calling thread gets a reference
- toku_cond_init(&ws->worker_wait, NULL);
+ ws->refs = 1; // the calling thread gets a reference
+ toku_cond_init(*ws_worker_wait_key, &ws->worker_wait, nullptr);
}
-static inline void
-workset_destroy(struct workset *ws) {
+static inline void workset_destroy(struct workset *ws) {
invariant(toku_list_empty(&ws->worklist));
toku_cond_destroy(&ws->worker_wait);
toku_mutex_destroy(&ws->lock);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-4357.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-4357.cc
index 8bbda295462..0af5c8185a9 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-4357.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-4357.cc
@@ -71,21 +71,26 @@ cachetable_test (void) {
void* v1;
long s1;
- r = toku_cachetable_get_and_pin(
- f1,
- make_blocknum(1),
- toku_cachetable_hash(f1, make_blocknum(1)),
- &v1,
- &s1,
- def_write_callback(NULL), def_fetch, def_pf_req_callback, def_pf_callback,
- true,
- NULL
- );
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ toku_cachetable_hash(f1, make_blocknum(1)),
+ &v1,
+ &s1,
+ def_write_callback(NULL),
+ def_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ true,
+ NULL);
toku_pthread_t pin_nonblocking_tid;
- r = toku_pthread_create(&pin_nonblocking_tid, NULL, pin_nonblocking, NULL);
- assert_zero(r);
+ r = toku_pthread_create(toku_uninstrumented,
+ &pin_nonblocking_tid,
+ nullptr,
+ pin_nonblocking,
+ nullptr);
+ assert_zero(r);
// sleep 3 seconds
- usleep(3*1024*1024);
+ usleep(3 * 1024 * 1024);
r = toku_test_cachetable_unpin_and_remove(f1, make_blocknum(1), NULL, NULL);
assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-4365.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-4365.cc
index 9c54c086f5b..7bee0b80770 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-4365.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-4365.cc
@@ -71,15 +71,16 @@ static void *put_same_key(void *arg) {
return arg;
}
-
toku_pthread_t put_tid;
-static void test_remove_key(CACHEKEY* UU(cachekey), bool UU(for_checkpoint), void* UU(extra)) {
- int r = toku_pthread_create(&put_tid, NULL, put_same_key, NULL);
- assert_zero(r);
+static void test_remove_key(CACHEKEY *UU(cachekey),
+ bool UU(for_checkpoint),
+ void *UU(extra)) {
+ int r = toku_pthread_create(
+ toku_uninstrumented, &put_tid, nullptr, put_same_key, nullptr);
+ assert_zero(r);
}
-
static void
cachetable_test (void) {
const int test_limit = 12;
@@ -92,21 +93,26 @@ cachetable_test (void) {
void* v1;
long s1;
- r = toku_cachetable_get_and_pin(
- f1,
- make_blocknum(1),
- toku_cachetable_hash(f1, make_blocknum(1)),
- &v1,
- &s1,
- def_write_callback(NULL), def_fetch, def_pf_req_callback, def_pf_callback,
- true,
- NULL
- );
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ toku_cachetable_hash(f1, make_blocknum(1)),
+ &v1,
+ &s1,
+ def_write_callback(nullptr),
+ def_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ true,
+ nullptr);
toku_pthread_t pin_nonblocking_tid;
- r = toku_pthread_create(&pin_nonblocking_tid, NULL, pin_nonblocking, NULL);
- assert_zero(r);
+ r = toku_pthread_create(toku_uninstrumented,
+ &pin_nonblocking_tid,
+ nullptr,
+ pin_nonblocking,
+ nullptr);
+ assert_zero(r);
// sleep 3 seconds
- usleep(3*1024*1024);
+ usleep(3 * 1024 * 1024);
r = toku_test_cachetable_unpin_and_remove(f1, make_blocknum(1), test_remove_key, NULL);
assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-5097.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-5097.cc
index c1b6e0a94f2..5ab0df88e08 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-5097.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-5097.cc
@@ -153,13 +153,16 @@ cachetable_test (void) {
assert(r == 0);
}
- // at this point, we have a dirty PAIR in the cachetable associated with cachefile f1
- // launch a thread that will put another PAIR in the cachetable, and get partial eviction started
+ // at this point, we have a dirty PAIR in the cachetable associated with
+ // cachefile f1
+ // launch a thread that will put another PAIR in the cachetable, and get
+ // partial eviction started
toku_pthread_t tid;
- r = toku_pthread_create(&tid, NULL, f2_pin, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, f2_pin, nullptr);
assert_zero(r);
- usleep(2*1024*1024);
+ usleep(2 * 1024 * 1024);
check_flush = true;
toku_cachefile_close(&f1, false, ZERO_LSN);
if (enable_partial_eviction)
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-5978-2.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-5978-2.cc
index b462d76eeee..0b5110ddd99 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-5978-2.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-5978-2.cc
@@ -114,14 +114,14 @@ unpin_two (void* UU(v)) {
);
assert_zero(r);
- // at this point, we have p1 pinned, want to start a thread to do an unpin_and_remove
- // on p1
- r = toku_pthread_create(
- &unpin_and_remove_tid,
- NULL,
- unpin_and_remove_one,
- NULL
- );
+ // at this point, we have p1 pinned, want to start a thread to do an
+ // unpin_and_remove
+ // on p1
+ r = toku_pthread_create(toku_uninstrumented,
+ &unpin_and_remove_tid,
+ nullptr,
+ unpin_and_remove_one,
+ nullptr);
assert_zero(r);
// sleep to give a chance for the unpin_and_remove to get going
usleep(512*1024);
@@ -173,9 +173,9 @@ cachetable_test (void) {
r = toku_cachetable_get_and_pin(f1, make_blocknum(2), 2, &v1, &s1, wc, fetch_two, def_pf_req_callback, def_pf_callback, true, NULL);
assert_zero(r);
-
toku_pthread_t tid1;
- r = toku_pthread_create(&tid1, NULL, repin_one, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid1, nullptr, repin_one, nullptr);
assert_zero(r);
void *ret;
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-5978.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-5978.cc
index ee68ab3ef0b..a4ff6c33e6a 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-5978.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-5978.cc
@@ -199,9 +199,11 @@ cachetable_test (void) {
toku_pthread_t tid1;
toku_pthread_t tid2;
- r = toku_pthread_create(&tid1, NULL, repin_one, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid1, nullptr, repin_one, nullptr);
assert_zero(r);
- r = toku_pthread_create(&tid2, NULL, repin_two, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid2, nullptr, repin_two, nullptr);
assert_zero(r);
// unpin 1 and 2 so tid1 and tid2 can make progress
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-checkpoint-pending.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-checkpoint-pending.cc
index 3dd3a15e2de..5e87fed740d 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-checkpoint-pending.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-checkpoint-pending.cc
@@ -158,14 +158,24 @@ static void checkpoint_pending(void) {
// the checkpoint should cause n writes, but since n <= the cachetable size,
// all items should be kept in the cachetable
- n_flush = n_write_me = n_keep_me = n_fetch = 0; expect_value = 42;
- //printf("E42\n");
+ n_flush = n_write_me = n_keep_me = n_fetch = 0;
+ expect_value = 42;
+ // printf("E42\n");
toku_pthread_t checkpoint_thread, update_thread;
- r = toku_pthread_create(&checkpoint_thread, NULL, do_checkpoint, NULL); assert(r==0);
- r = toku_pthread_create(&update_thread, NULL, do_update, NULL); assert(r==0);
- r = toku_pthread_join(checkpoint_thread, 0); assert(r==0);
- r = toku_pthread_join(update_thread, 0); assert(r==0);
-
+ r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_thread,
+ nullptr,
+ do_checkpoint,
+ nullptr);
+ assert(r == 0);
+ r = toku_pthread_create(
+ toku_uninstrumented, &update_thread, nullptr, do_update, nullptr);
+ assert(r == 0);
+ r = toku_pthread_join(checkpoint_thread, 0);
+ assert(r == 0);
+ r = toku_pthread_join(update_thread, 0);
+ assert(r == 0);
+
assert(n_flush == N && n_write_me == N && n_keep_me == N);
// after the checkpoint, all of the items should be 43
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-cleaner-thread-attrs-accumulate.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-cleaner-thread-attrs-accumulate.cc
index c1e7b373e83..dd6c674af24 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-cleaner-thread-attrs-accumulate.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-cleaner-thread-attrs-accumulate.cc
@@ -91,7 +91,7 @@ run_test (void) {
const int test_limit = 1000;
int r;
CACHETABLE ct;
- toku_mutex_init(&attr_mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &attr_mutex, nullptr);
toku_cachetable_create(&ct, test_limit, ZERO_LSN, nullptr);
const char *fname1 = TOKU_TEST_FILENAME;
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-clone-checkpoint.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-clone-checkpoint.cc
index 50bd20f492e..99d595b1ff1 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-clone-checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-clone-checkpoint.cc
@@ -112,14 +112,17 @@ cachetable_test (void) {
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
toku_cachetable_begin_checkpoint(cp, NULL);
-
clone_flush_started = false;
clone_flush_completed = false;
toku_pthread_t checkpoint_tid;
- r = toku_pthread_create(&checkpoint_tid, NULL, run_end_checkpoint, NULL);
- assert_zero(r);
+ r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ run_end_checkpoint,
+ nullptr);
+ assert_zero(r);
- usleep(1*1024*1024);
+ usleep(1 * 1024 * 1024);
r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-pin-checkpoint.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-pin-checkpoint.cc
index 8a270af0566..65b02aebaec 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-pin-checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-pin-checkpoint.cc
@@ -386,19 +386,28 @@ cachetable_test (void) {
run_test = true;
for (int i = 0; i < NUM_MOVER_THREADS; i++) {
- r = toku_pthread_create(&read_random_tid[i], NULL, read_random_numbers, NULL);
+ r = toku_pthread_create(toku_uninstrumented,
+ &read_random_tid[i],
+ nullptr,
+ read_random_numbers,
+ nullptr);
assert_zero(r);
}
for (int i = 0; i < NUM_MOVER_THREADS; i++) {
- r = toku_pthread_create(&move_tid[i], NULL, move_numbers, NULL);
+ r = toku_pthread_create(toku_uninstrumented,
+ &move_tid[i],
+ nullptr,
+ move_numbers,
+ nullptr);
assert_zero(r);
}
- r = toku_pthread_create(&checkpoint_tid, NULL, checkpoints, NULL);
- assert_zero(r);
- r = toku_pthread_create(&time_tid, NULL, test_time, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &checkpoint_tid, nullptr, checkpoints, nullptr);
+ assert_zero(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &time_tid, nullptr, test_time, nullptr);
assert_zero(r);
-
void *ret;
r = toku_pthread_join(time_tid, &ret);
assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-put-checkpoint.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-put-checkpoint.cc
index afc95471116..4cf1678449b 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-put-checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-put-checkpoint.cc
@@ -518,19 +518,28 @@ cachetable_test (void) {
run_test = true;
for (int i = 0; i < NUM_MOVER_THREADS; i++) {
- r = toku_pthread_create(&move_tid[i], NULL, move_numbers, NULL);
+ r = toku_pthread_create(toku_uninstrumented,
+ &move_tid[i],
+ nullptr,
+ move_numbers,
+ nullptr);
assert_zero(r);
}
for (int i = 0; i < NUM_MOVER_THREADS; i++) {
- r = toku_pthread_create(&merge_and_split_tid[i], NULL, merge_and_split, NULL);
+ r = toku_pthread_create(toku_uninstrumented,
+ &merge_and_split_tid[i],
+ nullptr,
+ merge_and_split,
+ nullptr);
assert_zero(r);
}
- r = toku_pthread_create(&checkpoint_tid, NULL, checkpoints, NULL);
- assert_zero(r);
- r = toku_pthread_create(&time_tid, NULL, test_time, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &checkpoint_tid, nullptr, checkpoints, nullptr);
+ assert_zero(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &time_tid, nullptr, test_time, nullptr);
assert_zero(r);
-
void *ret;
r = toku_pthread_join(time_tid, &ret);
assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-rwlock-test.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-rwlock-test.cc
index 9a62f99e1fa..6d8bc28026c 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-rwlock-test.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-rwlock-test.cc
@@ -40,24 +40,22 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
// test create and destroy
-static void
-test_create_destroy (void) {
- struct rwlock the_rwlock, *rwlock = &the_rwlock;
+static void test_create_destroy(void) {
+ struct st_rwlock the_rwlock, *rwlock = &the_rwlock;
- rwlock_init(rwlock);
+ rwlock_init(toku_uninstrumented, rwlock);
rwlock_destroy(rwlock);
}
// test read lock and unlock with no writers
-static void
-test_simple_read_lock (int n) {
- struct rwlock the_rwlock, *rwlock = &the_rwlock;
+static void test_simple_read_lock(int n) {
+ struct st_rwlock the_rwlock, *rwlock = &the_rwlock;
- rwlock_init(rwlock);
+ rwlock_init(toku_uninstrumented, rwlock);
assert(rwlock_readers(rwlock) == 0);
int i;
- for (i=1; i<=n; i++) {
+ for (i = 1; i <= n; i++) {
rwlock_read_lock(rwlock, 0);
assert(rwlock_readers(rwlock) == i);
assert(rwlock_users(rwlock) == i);
@@ -72,11 +70,10 @@ test_simple_read_lock (int n) {
// test write lock and unlock with no readers
-static void
-test_simple_write_lock (void) {
- struct rwlock the_rwlock, *rwlock = &the_rwlock;
+static void test_simple_write_lock(void) {
+ struct st_rwlock the_rwlock, *rwlock = &the_rwlock;
- rwlock_init(rwlock);
+ rwlock_init(toku_uninstrumented, rwlock);
assert(rwlock_users(rwlock) == 0);
rwlock_write_lock(rwlock, 0);
assert(rwlock_writers(rwlock) == 1);
@@ -88,19 +85,17 @@ test_simple_write_lock (void) {
struct rw_event {
int e;
- struct rwlock the_rwlock;
+ struct st_rwlock the_rwlock;
toku_mutex_t mutex;
};
-static void
-rw_event_init (struct rw_event *rwe) {
+static void rw_event_init(struct rw_event *rwe) {
rwe->e = 0;
- rwlock_init(&rwe->the_rwlock);
- toku_mutex_init(&rwe->mutex, 0);
+ rwlock_init(toku_uninstrumented, &rwe->the_rwlock);
+ toku_mutex_init(toku_uninstrumented, &rwe->mutex, nullptr);
}
-static void
-rw_event_destroy (struct rw_event *rwe) {
+static void rw_event_destroy(struct rw_event *rwe) {
rwlock_destroy(&rwe->the_rwlock);
toku_mutex_destroy(&rwe->mutex);
}
@@ -138,10 +133,12 @@ test_writer_priority (void) {
toku_mutex_unlock(&rwe->mutex);
toku_pthread_t tid;
- r = toku_pthread_create(&tid, 0, test_writer_priority_thread, rwe);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, 0, test_writer_priority_thread, rwe);
sleep(1);
toku_mutex_lock(&rwe->mutex);
- rwe->e++; assert(rwe->e == 2);
+ rwe->e++;
+ assert(rwe->e == 2);
toku_mutex_unlock(&rwe->mutex);
sleep(1);
@@ -196,10 +193,12 @@ test_single_writer (void) {
toku_mutex_unlock(&rwe->mutex);
toku_pthread_t tid;
- r = toku_pthread_create(&tid, 0, test_single_writer_thread, rwe);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, 0, test_single_writer_thread, rwe);
sleep(1);
toku_mutex_lock(&rwe->mutex);
- rwe->e++; assert(rwe->e == 2);
+ rwe->e++;
+ assert(rwe->e == 2);
assert(rwlock_writers(&rwe->the_rwlock) == 1);
assert(rwlock_users(&rwe->the_rwlock) == 2);
rwlock_write_unlock(&rwe->the_rwlock);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin-nonblocking.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin-nonblocking.cc
index 8fd8828737a..ebe05e50883 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin-nonblocking.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin-nonblocking.cc
@@ -111,9 +111,20 @@ run_test (void) {
toku_pthread_t fetch_tid;
fetch_called = false;
- r = toku_pthread_create(&fetch_tid, NULL, run_expensive_fetch, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &fetch_tid, nullptr, run_expensive_fetch, nullptr);
sleep(1);
- r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, sleep_fetch, def_pf_req_callback, def_pf_callback, false, NULL);
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ 1,
+ &v1,
+ &s1,
+ wc,
+ sleep_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ false,
+ NULL);
assert_zero(r);
assert(fetch_called);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
@@ -133,9 +144,20 @@ run_test (void) {
toku_pthread_t pf_tid;
pf_called = false;
- r = toku_pthread_create(&pf_tid, NULL, run_expensive_pf, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &pf_tid, nullptr, run_expensive_pf, nullptr);
sleep(1);
- r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, sleep_fetch, def_pf_req_callback, def_pf_callback, false, NULL);
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ 1,
+ &v1,
+ &s1,
+ wc,
+ sleep_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ false,
+ NULL);
assert_zero(r);
assert(pf_called);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin.cc
index 63ca871a459..dd5d59df002 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-read-pin.cc
@@ -117,9 +117,20 @@ run_test (void) {
toku_pthread_t fetch_tid;
fetch_called = false;
- r = toku_pthread_create(&fetch_tid, NULL, run_expensive_fetch, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &fetch_tid, nullptr, run_expensive_fetch, nullptr);
sleep(1);
- r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, sleep_fetch, def_pf_req_callback, def_pf_callback, false, NULL);
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ 1,
+ &v1,
+ &s1,
+ wc,
+ sleep_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ false,
+ NULL);
assert_zero(r);
assert(fetch_called);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
@@ -141,9 +152,20 @@ run_test (void) {
toku_pthread_t pf_tid;
pf_called = false;
- r = toku_pthread_create(&pf_tid, NULL, run_expensive_pf, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &pf_tid, nullptr, run_expensive_pf, nullptr);
sleep(1);
- r = toku_cachetable_get_and_pin(f1, make_blocknum(1), 1, &v1, &s1, wc, sleep_fetch, def_pf_req_callback, def_pf_callback, false, NULL);
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ 1,
+ &v1,
+ &s1,
+ wc,
+ sleep_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ false,
+ NULL);
assert_zero(r);
assert(pf_called);
r = toku_test_cachetable_unpin(f1, make_blocknum(1), 1, CACHETABLE_CLEAN, make_pair_attr(8));
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-test.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-test.cc
index e4bb5fb0aea..64f688c470d 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-test.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-test.cc
@@ -42,15 +42,13 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
// global data, especially between the test thread and the cachetable
// writeback threads
-toku_mutex_t test_mutex;
+toku_mutex_t test_mutex;
static inline void test_mutex_init(void) {
- toku_mutex_init(&test_mutex, 0);
+ toku_mutex_init(toku_uninstrumented, &test_mutex, nullptr);
}
-static inline void test_mutex_destroy(void) {
- toku_mutex_destroy(&test_mutex);
-}
+static inline void test_mutex_destroy(void) { toku_mutex_destroy(&test_mutex); }
static inline void test_mutex_lock(void) {
toku_mutex_lock(&test_mutex);
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-unpin-remove-and-checkpoint.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-unpin-remove-and-checkpoint.cc
index 11baa36e51b..0e44bf10349 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-unpin-remove-and-checkpoint.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-unpin-remove-and-checkpoint.cc
@@ -86,11 +86,22 @@ run_test (void) {
// now this should mark the pair for checkpoint
CHECKPOINTER cp = toku_cachetable_get_checkpointer(ct);
toku_cachetable_begin_checkpoint(cp, NULL);
- r = toku_cachetable_get_and_pin(f1, make_blocknum(1), toku_cachetable_hash(f1, make_blocknum(1)), &v1, &s1, wc, def_fetch, def_pf_req_callback, def_pf_callback, true, NULL);
+ r = toku_cachetable_get_and_pin(f1,
+ make_blocknum(1),
+ toku_cachetable_hash(f1, make_blocknum(1)),
+ &v1,
+ &s1,
+ wc,
+ def_fetch,
+ def_pf_req_callback,
+ def_pf_callback,
+ true,
+ NULL);
toku_pthread_t mytid;
- r = toku_pthread_create(&mytid, NULL, run_end_chkpt, NULL);
- assert(r==0);
+ r = toku_pthread_create(
+ toku_uninstrumented, &mytid, nullptr, run_end_chkpt, nullptr);
+ assert(r == 0);
// give checkpoint thread a chance to start waiting on lock
sleep(1);
diff --git a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-extractor-errors.cc b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-extractor-errors.cc
index 872b674c784..4bff52ceb1b 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-extractor-errors.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-extractor-errors.cc
@@ -141,7 +141,7 @@ static void test_extractor(int nrows, int nrowsets, bool expect_fail, const char
// setup error injection
toku_set_func_malloc(my_malloc);
toku_set_func_realloc(my_realloc);
- ft_loader_set_os_fwrite(bad_fwrite);
+ toku_set_func_fwrite(bad_fwrite);
toku_set_func_write(bad_write);
toku_set_func_pwrite(bad_pwrite);
ft_loader_set_poll_function(&loader->poll_callback, loader_poll_callback, NULL);
@@ -157,7 +157,7 @@ static void test_extractor(int nrows, int nrowsets, bool expect_fail, const char
toku_set_func_malloc(NULL);
toku_set_func_realloc(NULL);
- ft_loader_set_os_fwrite(NULL);
+ toku_set_func_fwrite(nullptr);
toku_set_func_write(NULL);
toku_set_func_pwrite(NULL);
diff --git a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-merge-files-dbufio.cc b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-merge-files-dbufio.cc
index d1aeff198ff..0b121316738 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-merge-files-dbufio.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-merge-files-dbufio.cc
@@ -393,13 +393,17 @@ static void test (const char *directory, bool is_error) {
toku_pthread_t consumer;
struct consumer_thunk cthunk = {q, 0};
{
- int r = toku_pthread_create(&consumer, NULL, consumer_thread, (void*)&cthunk);
- assert(r==0);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &consumer,
+ nullptr,
+ consumer_thread,
+ static_cast<void *>(&cthunk));
+ assert(r == 0);
}
toku_set_func_malloc_only(my_malloc);
toku_set_func_realloc_only(my_realloc);
- ft_loader_set_os_fwrite(bad_fwrite);
+ toku_set_func_fwrite(bad_fwrite);
toku_set_func_write(bad_write);
toku_set_func_pwrite(bad_pwrite);
toku_set_func_fdopen(bad_fdopen);
@@ -427,7 +431,7 @@ static void test (const char *directory, bool is_error) {
toku_set_func_malloc(NULL);
toku_set_func_realloc(NULL);
- ft_loader_set_os_fwrite(NULL);
+ toku_set_func_fwrite(nullptr);
toku_set_func_write(NULL);
toku_set_func_pwrite(NULL);
toku_set_func_fdopen(NULL);
diff --git a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-writer-errors.cc b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-writer-errors.cc
index 0784ca87a26..e4423319518 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ftloader-test-writer-errors.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ftloader-test-writer-errors.cc
@@ -154,7 +154,7 @@ static int write_dbfile (char *tf_template, int n, char *output_name, bool expec
toku_set_func_malloc_only(my_malloc);
toku_set_func_realloc_only(my_realloc);
- ft_loader_set_os_fwrite(bad_fwrite);
+ toku_set_func_fwrite(bad_fwrite);
toku_set_func_write(bad_write);
toku_set_func_pwrite(bad_pwrite);
ft_loader_set_error_function(&bl.error_callback, NULL, NULL);
@@ -164,7 +164,7 @@ static int write_dbfile (char *tf_template, int n, char *output_name, bool expec
toku_set_func_malloc_only(NULL);
toku_set_func_realloc_only(NULL);
- ft_loader_set_os_fwrite(NULL);
+ toku_set_func_fwrite(nullptr);
toku_set_func_write(NULL);
toku_set_func_pwrite(NULL);
diff --git a/storage/tokudb/PerconaFT/ft/tests/log-test4.cc b/storage/tokudb/PerconaFT/ft/tests/log-test4.cc
index a31181deb30..e0bbedb95bf 100644
--- a/storage/tokudb/PerconaFT/ft/tests/log-test4.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/log-test4.cc
@@ -63,11 +63,14 @@ test_main (int argc __attribute__((__unused__)),
r = toku_logger_close(&logger); assert(r == 0);
{
- toku_struct_stat statbuf;
- sprintf(logname, "%s/log000000000000.tokulog%d", TOKU_TEST_FILENAME, TOKU_LOG_VERSION);
- r = toku_stat(logname, &statbuf);
- assert(r==0);
- assert(statbuf.st_size==12+5);
+ toku_struct_stat statbuf;
+ sprintf(logname,
+ "%s/log000000000000.tokulog%d",
+ TOKU_TEST_FILENAME,
+ TOKU_LOG_VERSION);
+ r = toku_stat(logname, &statbuf, toku_uninstrumented);
+ assert(r == 0);
+ assert(statbuf.st_size == 12 + 5);
}
toku_os_recursive_delete(TOKU_TEST_FILENAME);
return 0;
diff --git a/storage/tokudb/PerconaFT/ft/tests/log-test5.cc b/storage/tokudb/PerconaFT/ft/tests/log-test5.cc
index d4e31af22dc..fed9467a4ae 100644
--- a/storage/tokudb/PerconaFT/ft/tests/log-test5.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/log-test5.cc
@@ -81,14 +81,14 @@ test_main (int argc __attribute__((__unused__)),
struct dirent *dirent;
while ((dirent=readdir(dir))) {
if (strncmp(dirent->d_name, "log", 3)!=0) continue;
- char fname[TOKU_PATH_MAX+1];
- toku_path_join(fname, 2, TOKU_TEST_FILENAME, dirent->d_name);
- toku_struct_stat statbuf;
- r = toku_stat(fname, &statbuf);
- assert(r==0);
- assert(statbuf.st_size<=LSIZE+10);
- }
- r = closedir(dir);
+ char fname[TOKU_PATH_MAX + 1];
+ toku_path_join(fname, 2, TOKU_TEST_FILENAME, dirent->d_name);
+ toku_struct_stat statbuf;
+ r = toku_stat(fname, &statbuf, toku_uninstrumented);
+ assert(r == 0);
+ assert(statbuf.st_size <= LSIZE + 10);
+ }
+ r = closedir(dir);
assert(r==0);
}
toku_os_recursive_delete(TOKU_TEST_FILENAME);
diff --git a/storage/tokudb/PerconaFT/ft/tests/log-test6.cc b/storage/tokudb/PerconaFT/ft/tests/log-test6.cc
index 4d17488c57c..0e8b94566df 100644
--- a/storage/tokudb/PerconaFT/ft/tests/log-test6.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/log-test6.cc
@@ -86,11 +86,14 @@ test_main (int argc __attribute__((__unused__)),
{
char logname[PATH_MAX];
- toku_struct_stat statbuf;
- sprintf(logname, "%s/log000000000000.tokulog%d", TOKU_TEST_FILENAME, TOKU_LOG_VERSION);
- r = toku_stat(logname, &statbuf);
- assert(r==0);
- assert(statbuf.st_size<=LSIZE);
+ toku_struct_stat statbuf;
+ sprintf(logname,
+ "%s/log000000000000.tokulog%d",
+ TOKU_TEST_FILENAME,
+ TOKU_LOG_VERSION);
+ r = toku_stat(logname, &statbuf, toku_uninstrumented);
+ assert(r == 0);
+ assert(statbuf.st_size <= LSIZE);
}
toku_os_recursive_delete(TOKU_TEST_FILENAME);
return 0;
diff --git a/storage/tokudb/PerconaFT/ft/tests/recovery-bad-last-entry.cc b/storage/tokudb/PerconaFT/ft/tests/recovery-bad-last-entry.cc
index 431ee4b5e50..a3c934d1f4b 100644
--- a/storage/tokudb/PerconaFT/ft/tests/recovery-bad-last-entry.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/recovery-bad-last-entry.cc
@@ -83,11 +83,16 @@ run_test(void) {
r = toku_dup2(devnul, fileno(stderr)); assert(r==fileno(stderr));
r = close(devnul); assert(r==0);
- char fname[TOKU_PATH_MAX+1];
- sprintf(fname, "%s/%s%d", TOKU_TEST_FILENAME, "log000000000000.tokulog", TOKU_LOG_VERSION);
-
- r = toku_stat(fname, &st); assert(r==0);
- if ( st.st_size - trim > magic_begin_end_checkpoint_sz ) {
+ char fname[TOKU_PATH_MAX + 1];
+ sprintf(fname,
+ "%s/%s%d",
+ TOKU_TEST_FILENAME,
+ "log000000000000.tokulog",
+ TOKU_LOG_VERSION);
+
+ r = toku_stat(fname, &st, toku_uninstrumented);
+ assert(r == 0);
+ if (st.st_size - trim > magic_begin_end_checkpoint_sz) {
r = truncate(fname, st.st_size - trim);
CKERR(r);
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-bjm.cc b/storage/tokudb/PerconaFT/ft/tests/test-bjm.cc
index 97e00c42b95..6afe5b9f7c4 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-bjm.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-bjm.cc
@@ -71,12 +71,16 @@ static void bjm_test(void) {
bjm_reset(bjm);
r = bjm_add_background_job(bjm);
- assert_zero(r);
- toku_pthread_t tid;
- r = toku_pthread_create(&tid, NULL, finish_bjm, NULL);
assert_zero(r);
- usleep(2*1024*1024);
- // should return non-zero because tid is waiting
+ toku_pthread_t tid;
+ r = toku_pthread_create(toku_uninstrumented,
+ &tid,
+ nullptr,
+ finish_bjm,
+ nullptr);
+ assert_zero(r);
+ usleep(2 * 1024 * 1024);
+ // should return non-zero because tid is waiting
// for background jobs to finish
r = bjm_add_background_job(bjm);
assert(r != 0);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
index 3e5d9bba817..06a26614885 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
@@ -113,10 +113,14 @@ static void flusher_callback(int state, void* extra) {
if ((state == flt_flush_before_child_pin && !after_child_pin) ||
(state == ft_flush_aflter_child_pin && after_child_pin)) {
checkpoint_called = true;
- int r = toku_pthread_create(&checkpoint_tid, NULL, do_checkpoint, NULL);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ do_checkpoint,
+ nullptr);
assert_zero(r);
while (!checkpoint_callback_called) {
- usleep(1*1024*1024);
+ usleep(1 * 1024 * 1024);
}
}
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
index cb316127ef7..1029dfef320 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
@@ -103,10 +103,14 @@ static void flusher_callback(int state, void* extra) {
}
if (state == desired_state) {
checkpoint_called = true;
- int r = toku_pthread_create(&checkpoint_tid, NULL, do_checkpoint, NULL);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ do_checkpoint,
+ nullptr);
assert_zero(r);
while (!checkpoint_callback_called) {
- usleep(1*1024*1024);
+ usleep(1 * 1024 * 1024);
}
}
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
index 5f8485ac4ec..208ebe3ca31 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
@@ -103,10 +103,14 @@ static void flusher_callback(int state, void* extra) {
}
if (state == desired_state) {
checkpoint_called = true;
- int r = toku_pthread_create(&checkpoint_tid, NULL, do_checkpoint, NULL);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ do_checkpoint,
+ nullptr);
assert_zero(r);
while (!checkpoint_callback_called) {
- usleep(1*1024*1024);
+ usleep(1 * 1024 * 1024);
}
}
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
index 70c3ba22a0c..2b29de409b1 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
@@ -113,10 +113,14 @@ static void flusher_callback(int state, void* extra) {
if ((state == flt_flush_before_split && !after_split) ||
(state == flt_flush_during_split && after_split)) {
checkpoint_called = true;
- int r = toku_pthread_create(&checkpoint_tid, NULL, do_checkpoint, NULL);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ do_checkpoint,
+ nullptr);
assert_zero(r);
while (!checkpoint_callback_called) {
- usleep(1*1024*1024);
+ usleep(1 * 1024 * 1024);
}
}
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test3681.cc b/storage/tokudb/PerconaFT/ft/tests/test3681.cc
index e5e24a88246..9e4a46e8dfe 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test3681.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test3681.cc
@@ -91,13 +91,35 @@ static void *startb (void *n) {
return NULL;
}
-static void test3681 (void) {
+static void test3681(void) {
setup();
- toku_pthread_t a,b;
- { int r; r = toku_pthread_create(&a, NULL, starta, NULL); assert(r==0); }
- { int r; r = toku_pthread_create(&b, NULL, startb, NULL); assert(r==0); }
- { int r; void *v; r = toku_pthread_join(a, &v); assert(r==0); assert(v==NULL); }
- { int r; void *v; r = toku_pthread_join(b, &v); assert(r==0); assert(v==NULL); }
+ toku_pthread_t a, b;
+ {
+ int r;
+ r = toku_pthread_create(
+ toku_uninstrumented, &a, nullptr, starta, nullptr);
+ assert(r == 0);
+ }
+ {
+ int r;
+ r = toku_pthread_create(
+ toku_uninstrumented, &b, nullptr, startb, nullptr);
+ assert(r == 0);
+ }
+ {
+ int r;
+ void *v;
+ r = toku_pthread_join(a, &v);
+ assert(r == 0);
+ assert(v == NULL);
+ }
+ {
+ int r;
+ void *v;
+ r = toku_pthread_join(b, &v);
+ assert(r == 0);
+ assert(v == NULL);
+ }
finish();
}
diff --git a/storage/tokudb/PerconaFT/ft/txn/roll.cc b/storage/tokudb/PerconaFT/ft/txn/roll.cc
index 97afd2f5bdb..7228de06f34 100644
--- a/storage/tokudb/PerconaFT/ft/txn/roll.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/roll.cc
@@ -195,14 +195,14 @@ int toku_rollback_frename(BYTESTRING old_iname,
toku_cachetable_get_fname_in_cwd(cachetable, new_iname.data),
&toku_free);
- if (toku_stat(old_iname_full.get(), &stat) == -1) {
+ if (toku_stat(old_iname_full.get(), &stat, toku_uninstrumented) == -1) {
if (ENOENT == errno)
old_exist = false;
else
return 1;
}
- if (toku_stat(new_iname_full.get(), &stat) == -1) {
+ if (toku_stat(new_iname_full.get(), &stat, toku_uninstrumented) == -1) {
if (ENOENT == errno || ENAMETOOLONG == errno)
new_exist = false;
else
@@ -220,7 +220,7 @@ int toku_rollback_frename(BYTESTRING old_iname,
// removed
// and the new file is renamed.
if (old_exist && new_exist &&
- (toku_os_unlink(old_iname_full.get()) == -1 ||
+ (toku_os_delete(old_iname_full.get()) == -1 ||
toku_os_rename(new_iname_full.get(), old_iname_full.get()) == -1 ||
toku_fsync_directory(new_iname_full.get()) == -1 ||
toku_fsync_directory(old_iname_full.get()) == -1))
diff --git a/storage/tokudb/PerconaFT/ft/txn/rollback_log_node_cache.cc b/storage/tokudb/PerconaFT/ft/txn/rollback_log_node_cache.cc
index 71b1e79277c..5e1ab746936 100644
--- a/storage/tokudb/PerconaFT/ft/txn/rollback_log_node_cache.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/rollback_log_node_cache.cc
@@ -41,7 +41,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "txn/rollback_log_node_cache.h"
-void rollback_log_node_cache::init (uint32_t max_num_avail_nodes) {
+toku_instr_key* rollback_log_node_cache_mutex_key;
+
+void rollback_log_node_cache::init(uint32_t max_num_avail_nodes) {
XMALLOC_N(max_num_avail_nodes, m_avail_blocknums);
m_max_num_avail = max_num_avail_nodes;
m_first = 0;
@@ -49,7 +51,7 @@ void rollback_log_node_cache::init (uint32_t max_num_avail_nodes) {
toku_pthread_mutexattr_t attr;
toku_mutexattr_init(&attr);
toku_mutexattr_settype(&attr, TOKU_MUTEX_ADAPTIVE);
- toku_mutex_init(&m_mutex, &attr);
+ toku_mutex_init(*rollback_log_node_cache_mutex_key, &m_mutex, &attr);
toku_mutexattr_destroy(&attr);
}
diff --git a/storage/tokudb/PerconaFT/ft/txn/txn.cc b/storage/tokudb/PerconaFT/ft/txn/txn.cc
index a3ce6beb7b0..7327cbd9d24 100644
--- a/storage/tokudb/PerconaFT/ft/txn/txn.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/txn.cc
@@ -45,8 +45,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "ft/txn/txn_manager.h"
#include "util/status.h"
-void
-toku_txn_get_status(TXN_STATUS s) {
+toku_instr_key *txn_lock_mutex_key;
+toku_instr_key *txn_state_lock_mutex_key;
+toku_instr_key *result_state_cond_key;
+
+void toku_txn_get_status(TXN_STATUS s) {
txn_status.init();
*s = txn_status;
}
@@ -225,74 +228,74 @@ static void toku_txn_create_txn (
static txn_child_manager tcm;
- struct tokutxn new_txn = {
- .txnid = {.parent_id64 = TXNID_NONE, .child_id64 = TXNID_NONE },
- .snapshot_txnid64 = TXNID_NONE,
- .snapshot_type = for_recovery ? TXN_SNAPSHOT_NONE : snapshot_type,
- .for_recovery = for_recovery,
- .logger = logger,
- .parent = parent_tokutxn,
- .child = NULL,
- .child_manager_s = tcm,
- .child_manager = NULL,
- .container_db_txn = container_db_txn,
- .live_root_txn_list = nullptr,
- .xids = NULL,
- .snapshot_next = NULL,
- .snapshot_prev = NULL,
- .begin_was_logged = false,
- .declared_read_only = read_only,
- .do_fsync = false,
- .force_fsync_on_commit = false,
- .do_fsync_lsn = ZERO_LSN,
- .xa_xid = {0, 0, 0, ""},
- .progress_poll_fun = NULL,
- .progress_poll_fun_extra = NULL,
-
- // You cannot initialize txn_lock a TOKU_MUTEX_INITIALIZER, because we
- // will initialize it in the code below, and it cannot already
- // be initialized at that point. Also, in general, you don't
- // get to use PTHREAD_MUTEX_INITALIZER (which is what is inside
- // TOKU_MUTEX_INITIALIZER) except in static variables, and this
- // is initializing an auto variable.
- //
- // And we cannot simply avoid initializing these fields
- // because, although it avoids -Wmissing-field-initializer
- // errors under gcc, it gets other errors about non-trivial
- // designated initializers not being supported.
-
- .txn_lock = ZERO_MUTEX_INITIALIZER, // Not TOKU_MUTEX_INITIALIZER
- .open_fts = open_fts,
- .roll_info = roll_info,
- .state_lock = ZERO_MUTEX_INITIALIZER, // Not TOKU_MUTEX_INITIALIZER
- .state_cond = ZERO_COND_INITIALIZER, // Not TOKU_COND_INITIALIZER
- .state = TOKUTXN_LIVE,
- .num_pin = 0,
- .client_id = 0,
- .client_extra = nullptr,
- .start_time = time(NULL),
- };
+struct tokutxn new_txn = {
+ .txnid = {.parent_id64 = TXNID_NONE, .child_id64 = TXNID_NONE },
+ .snapshot_txnid64 = TXNID_NONE,
+ .snapshot_type = for_recovery ? TXN_SNAPSHOT_NONE : snapshot_type,
+ .for_recovery = for_recovery,
+ .logger = logger,
+ .parent = parent_tokutxn,
+ .child = NULL,
+ .child_manager_s = tcm,
+ .child_manager = NULL,
+ .container_db_txn = container_db_txn,
+ .live_root_txn_list = nullptr,
+ .xids = NULL,
+ .snapshot_next = NULL,
+ .snapshot_prev = NULL,
+ .begin_was_logged = false,
+ .declared_read_only = read_only,
+ .do_fsync = false,
+ .force_fsync_on_commit = false,
+ .do_fsync_lsn = ZERO_LSN,
+ .xa_xid = {0, 0, 0, ""},
+ .progress_poll_fun = NULL,
+ .progress_poll_fun_extra = NULL,
+
+ // You cannot initialize txn_lock a TOKU_MUTEX_INITIALIZER, because we
+ // will initialize it in the code below, and it cannot already
+ // be initialized at that point. Also, in general, you don't
+ // get to use PTHREAD_MUTEX_INITALIZER (which is what is inside
+ // TOKU_MUTEX_INITIALIZER) except in static variables, and this
+ // is initializing an auto variable.
+ //
+ // And we cannot simply avoid initializing these fields
+ // because, although it avoids -Wmissing-field-initializer
+ // errors under gcc, it gets other errors about non-trivial
+ // designated initializers not being supported.
+
+ .txn_lock = ZERO_MUTEX_INITIALIZER, // Not TOKU_MUTEX_INITIALIZER
+ .open_fts = open_fts,
+ .roll_info = roll_info,
+ .state_lock = ZERO_MUTEX_INITIALIZER, // Not TOKU_MUTEX_INITIALIZER
+ .state_cond = ZERO_COND_INITIALIZER, // Not TOKU_COND_INITIALIZER
+ .state = TOKUTXN_LIVE,
+ .num_pin = 0,
+ .client_id = 0,
+ .client_extra = nullptr,
+ .start_time = time(NULL),
+};
- TOKUTXN result = NULL;
- XMEMDUP(result, &new_txn);
- invalidate_xa_xid(&result->xa_xid);
- if (parent_tokutxn == NULL) {
- result->child_manager = &result->child_manager_s;
- result->child_manager->init(result);
+TOKUTXN result = NULL;
+XMEMDUP(result, &new_txn);
+invalidate_xa_xid(&result->xa_xid);
+if (parent_tokutxn == NULL) {
+ result->child_manager = &result->child_manager_s;
+ result->child_manager->init(result);
}
else {
result->child_manager = parent_tokutxn->child_manager;
}
- toku_mutex_init(&result->txn_lock, nullptr);
+ toku_mutex_init(*txn_lock_mutex_key, &result->txn_lock, nullptr);
toku_pthread_mutexattr_t attr;
toku_mutexattr_init(&attr);
toku_mutexattr_settype(&attr, TOKU_MUTEX_ADAPTIVE);
- toku_mutex_init(&result->state_lock, &attr);
+ toku_mutex_init(*txn_state_lock_mutex_key, &result->state_lock, &attr);
toku_mutexattr_destroy(&attr);
- toku_cond_init(&result->state_cond, nullptr);
+ toku_cond_init(*result_state_cond_key, &result->state_cond, nullptr);
*tokutxn = result;
diff --git a/storage/tokudb/PerconaFT/ft/txn/txn_child_manager.cc b/storage/tokudb/PerconaFT/ft/txn/txn_child_manager.cc
index db110127c55..99a21331b0a 100644
--- a/storage/tokudb/PerconaFT/ft/txn/txn_child_manager.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/txn_child_manager.cc
@@ -39,6 +39,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "ft/logger/log-internal.h"
#include "ft/txn/txn_child_manager.h"
+toku_instr_key *txn_child_manager_mutex_key;
+
//
// initialized a txn_child_manager,
// when called, root->txnid.parent_id64 may not yet be set
@@ -53,7 +55,7 @@ void txn_child_manager::init(TOKUTXN root) {
toku_pthread_mutexattr_t attr;
toku_mutexattr_init(&attr);
toku_mutexattr_settype(&attr, TOKU_MUTEX_ADAPTIVE);
- toku_mutex_init(&m_mutex, &attr);
+ toku_mutex_init(*txn_child_manager_mutex_key, &m_mutex, &attr);
toku_mutexattr_destroy(&attr);
}
diff --git a/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc b/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc
index 88eca36a261..384a960b1f3 100644
--- a/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc
@@ -56,7 +56,10 @@ void set_test_txn_sync_callback(void (*cb) (pthread_t, void *), void *extra) {
}
bool garbage_collection_debug = false;
-static bool txn_records_snapshot(TXN_SNAPSHOT_TYPE snapshot_type, struct tokutxn *parent) {
+toku_instr_key *txn_manager_lock_mutex_key;
+
+static bool txn_records_snapshot(TXN_SNAPSHOT_TYPE snapshot_type,
+ struct tokutxn *parent) {
if (snapshot_type == TXN_COPIES_SNAPSHOT) {
return false;
}
@@ -248,9 +251,10 @@ verify_snapshot_system(TXN_MANAGER txn_manager UU()) {
live_root_txns_omt.destroy();
}
-void toku_txn_manager_init(TXN_MANAGER* txn_managerp) {
+void toku_txn_manager_init(TXN_MANAGER *txn_managerp) {
TXN_MANAGER XCALLOC(txn_manager);
- toku_mutex_init(&txn_manager->txn_manager_lock, NULL);
+ toku_mutex_init(
+ *txn_manager_lock_mutex_key, &txn_manager->txn_manager_lock, nullptr);
txn_manager->live_root_txns.create();
txn_manager->live_root_ids.create();
txn_manager->snapshot_head = NULL;
diff --git a/storage/tokudb/PerconaFT/locktree/lock_request.cc b/storage/tokudb/PerconaFT/locktree/lock_request.cc
index 0151b5bd466..c0829e3f4e1 100644
--- a/storage/tokudb/PerconaFT/locktree/lock_request.cc
+++ b/storage/tokudb/PerconaFT/locktree/lock_request.cc
@@ -62,7 +62,7 @@ void lock_request::create(void) {
m_state = state::UNINITIALIZED;
m_info = nullptr;
- toku_cond_init(&m_wait_cond, nullptr);
+ toku_cond_init(*lock_request_m_wait_cond_key, &m_wait_cond, nullptr);
m_start_test_callback = nullptr;
m_start_before_pending_test_callback = nullptr;
diff --git a/storage/tokudb/PerconaFT/locktree/locktree.cc b/storage/tokudb/PerconaFT/locktree/locktree.cc
index 2fbf078bdd6..069aae26f66 100644
--- a/storage/tokudb/PerconaFT/locktree/locktree.cc
+++ b/storage/tokudb/PerconaFT/locktree/locktree.cc
@@ -51,7 +51,6 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
// the locktree source file instead of the header.
#include "concurrent_tree.h"
-
namespace toku {
// A locktree represents the set of row locks owned by all transactions
@@ -87,12 +86,13 @@ void lt_lock_request_info::init(void) {
pending_lock_requests.create();
pending_is_empty = true;
ZERO_STRUCT(mutex);
- toku_mutex_init(&mutex, nullptr);
+ toku_mutex_init(*locktree_request_info_mutex_key, &mutex, nullptr);
retry_want = retry_done = 0;
ZERO_STRUCT(counters);
ZERO_STRUCT(retry_mutex);
- toku_mutex_init(&retry_mutex, nullptr);
- toku_cond_init(&retry_cv, nullptr);
+ toku_mutex_init(
+ *locktree_request_info_retry_mutex_key, &retry_mutex, nullptr);
+ toku_cond_init(*locktree_request_info_retry_cv_key, &retry_cv, nullptr);
running_retry = false;
TOKU_VALGRIND_HG_DISABLE_CHECKING(&pending_is_empty,
diff --git a/storage/tokudb/PerconaFT/locktree/manager.cc b/storage/tokudb/PerconaFT/locktree/manager.cc
index 91ff7c5a007..6bb5c77bf32 100644
--- a/storage/tokudb/PerconaFT/locktree/manager.cc
+++ b/storage/tokudb/PerconaFT/locktree/manager.cc
@@ -56,9 +56,8 @@ void locktree_manager::create(lt_create_cb create_cb, lt_destroy_cb destroy_cb,
m_lt_destroy_callback = destroy_cb;
m_lt_escalate_callback = escalate_cb;
m_lt_escalate_callback_extra = escalate_extra;
-
ZERO_STRUCT(m_mutex);
- toku_mutex_init(&m_mutex, nullptr);
+ toku_mutex_init(*manager_mutex_key, &m_mutex, nullptr);
ZERO_STRUCT(m_lt_counters);
@@ -346,7 +345,8 @@ int locktree_manager::check_current_lock_constraints(bool big_txn) {
void locktree_manager::escalator_init(void) {
ZERO_STRUCT(m_escalation_mutex);
- toku_mutex_init(&m_escalation_mutex, nullptr);
+ toku_mutex_init(
+ *manager_escalation_mutex_key, &m_escalation_mutex, nullptr);
m_escalation_count = 0;
m_escalation_time = 0;
m_wait_escalation_count = 0;
@@ -403,8 +403,8 @@ struct escalate_args {
void locktree_manager::locktree_escalator::create(void) {
ZERO_STRUCT(m_escalator_mutex);
- toku_mutex_init(&m_escalator_mutex, nullptr);
- toku_cond_init(&m_escalator_done, nullptr);
+ toku_mutex_init(*manager_escalator_mutex_key, &m_escalator_mutex, nullptr);
+ toku_cond_init(*manager_m_escalator_done_key, &m_escalator_done, nullptr);
m_escalator_running = false;
}
diff --git a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_1big7lt_1small.cc b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_1big7lt_1small.cc
index 6c143f963ba..32029b5bddd 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_1big7lt_1small.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_1big7lt_1small.cc
@@ -201,12 +201,14 @@ int main(int argc, const char *argv[]) {
locktree *small_lt = mgr.get_lt(dict_id, dbt_comparator, nullptr);
// create the worker threads
- struct big_arg big_arg = { &mgr, big_lt, n_big, 1000 };
- r = toku_pthread_create(&big_id, nullptr, big_f, &big_arg);
+ struct big_arg big_arg = {&mgr, big_lt, n_big, 1000};
+ r = toku_pthread_create(
+ toku_uninstrumented, &big_id, nullptr, big_f, &big_arg);
assert(r == 0);
- struct small_arg small_arg = { &mgr, small_lt, 2000, 0 };
- r = toku_pthread_create(&small_id, nullptr, small_f, &small_arg);
+ struct small_arg small_arg = {&mgr, small_lt, 2000, 0};
+ r = toku_pthread_create(
+ toku_uninstrumented, &small_id, nullptr, small_f, &small_arg);
assert(r == 0);
// wait for some escalations to occur
diff --git a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_1lt.cc b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_1lt.cc
index 17eb07060d4..ff59a7bdd5c 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_1lt.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_1lt.cc
@@ -169,8 +169,10 @@ int main(int argc, const char *argv[]) {
struct arg big_arg[n_big];
pthread_t big_ids[n_big];
for (int i = 0; i < n_big; i++) {
- big_arg[i] = { &mgr, lt[i % n_lt], (TXNID)(1000+i), i == 0 ? 1 : -1000000000 };
- r = toku_pthread_create(&big_ids[i], nullptr, big_f, &big_arg[i]);
+ big_arg[i] = {
+ &mgr, lt[i % n_lt], (TXNID)(1000 + i), i == 0 ? 1 : -1000000000};
+ r = toku_pthread_create(
+ toku_uninstrumented, &big_ids[i], nullptr, big_f, &big_arg[i]);
assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_2lt.cc b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_2lt.cc
index 4326e8fafc2..be1ddaba9d0 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_2lt.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_2big_2lt.cc
@@ -169,8 +169,10 @@ int main(int argc, const char *argv[]) {
struct arg big_arg[n_big];
pthread_t big_ids[n_big];
for (int i = 0; i < n_big; i++) {
- big_arg[i] = { &mgr, lt[i % n_lt], (TXNID)(1000+i), i == 0 ? 1 : -1000000000 };
- r = toku_pthread_create(&big_ids[i], nullptr, big_f, &big_arg[i]);
+ big_arg[i] = {
+ &mgr, lt[i % n_lt], (TXNID)(1000 + i), i == 0 ? 1 : -1000000000};
+ r = toku_pthread_create(
+ toku_uninstrumented, &big_ids[i], nullptr, big_f, &big_arg[i]);
assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_stalls.cc b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_stalls.cc
index d146d94e337..9dc9596a7ed 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_stalls.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/locktree_escalation_stalls.cc
@@ -182,9 +182,10 @@ int main(int argc, const char *argv[]) {
locktree *lt_1 = mgr.get_lt(dict_id_1, dbt_comparator, nullptr);
// create the worker threads
- struct arg big_arg = { &mgr, lt_0, 1000 };
+ struct arg big_arg = {&mgr, lt_0, 1000};
pthread_t big_id;
- r = toku_pthread_create(&big_id, nullptr, big_f, &big_arg);
+ r = toku_pthread_create(
+ toku_uninstrumented, &big_id, nullptr, big_f, &big_arg);
assert(r == 0);
const int n_small = 7;
@@ -192,8 +193,12 @@ int main(int argc, const char *argv[]) {
struct arg small_args[n_small];
for (int i = 0; i < n_small; i++) {
- small_args[i] = { &mgr, lt_1, (TXNID)(2000+i), i };
- r = toku_pthread_create(&small_ids[i], nullptr, small_f, &small_args[i]);
+ small_args[i] = {&mgr, lt_1, (TXNID)(2000 + i), i};
+ r = toku_pthread_create(toku_uninstrumented,
+ &small_ids[i],
+ nullptr,
+ small_f,
+ &small_args[i]);
assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/locktree/tests/manager_parallel_locktree_get_release.cc b/storage/tokudb/PerconaFT/locktree/tests/manager_parallel_locktree_get_release.cc
index ec9ef21583c..08ce63140a5 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/manager_parallel_locktree_get_release.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/manager_parallel_locktree_get_release.cc
@@ -71,7 +71,8 @@ void manager_unit_test::test_reference_release_lt(void) {
const int nthreads = 2;
pthread_t ids[nthreads];
for (int i = 0; i < nthreads; i++) {
- r = toku_pthread_create(&ids[i], nullptr, my_tester, &mgr);
+ r = toku_pthread_create(
+ toku_uninstrumented, &ids[i], nullptr, my_tester, &mgr);
assert(r == 0);
}
for (int i = 0; i < nthreads; i++) {
diff --git a/storage/tokudb/PerconaFT/locktree/treenode.cc b/storage/tokudb/PerconaFT/locktree/treenode.cc
index 4f43291fe76..cc3a4969643 100644
--- a/storage/tokudb/PerconaFT/locktree/treenode.cc
+++ b/storage/tokudb/PerconaFT/locktree/treenode.cc
@@ -38,9 +38,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <toku_race_tools.h>
-void treenode::mutex_lock(void) {
- toku_mutex_lock(&m_mutex);
-}
+// TODO: source location info might have to be pulled up one caller
+// to be useful
+void treenode::mutex_lock(void) { toku_mutex_lock(&m_mutex); }
void treenode::mutex_unlock(void) {
toku_mutex_unlock(&m_mutex);
@@ -58,7 +58,7 @@ void treenode::init(const comparator *cmp) {
toku_pthread_mutexattr_t attr;
toku_mutexattr_init(&attr);
toku_mutexattr_settype(&attr, TOKU_MUTEX_ADAPTIVE);
- toku_mutex_init(&m_mutex, &attr);
+ toku_mutex_init(*treenode_mutex_key, &m_mutex, &attr);
toku_mutexattr_destroy(&attr);
m_left_child.set(nullptr);
m_right_child.set(nullptr);
diff --git a/storage/tokudb/PerconaFT/portability/CMakeLists.txt b/storage/tokudb/PerconaFT/portability/CMakeLists.txt
index 4793db63cc1..e5576a5d463 100644
--- a/storage/tokudb/PerconaFT/portability/CMakeLists.txt
+++ b/storage/tokudb/PerconaFT/portability/CMakeLists.txt
@@ -8,6 +8,7 @@ set(tokuportability_srcs
portability
toku_assert
toku_crash
+ toku_instr_mysql
toku_path
toku_pthread
toku_time
@@ -53,6 +54,10 @@ if (NOT DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
DESTINATION ${INSTALL_LIBDIR}
COMPONENT tokukv_libs_shared
)
+else ()
+ set_property(SOURCE toku_pthread portability APPEND PROPERTY
+ COMPILE_DEFINITIONS MYSQL_TOKUDB_ENGINE=1 )
+ target_link_libraries(${LIBTOKUPORTABILITY} LINK_PRIVATE mysys)
endif ()
add_subdirectory(tests)
diff --git a/storage/tokudb/PerconaFT/portability/file.cc b/storage/tokudb/PerconaFT/portability/file.cc
index 0e3efc1a12a..485bfac8514 100644
--- a/storage/tokudb/PerconaFT/portability/file.cc
+++ b/storage/tokudb/PerconaFT/portability/file.cc
@@ -52,9 +52,12 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "toku_path.h"
#include <portability/toku_atomic.h>
+toku_instr_key *tokudb_file_data_key;
+
static int toku_assert_on_write_enospc = 0;
static const int toku_write_enospc_sleep = 1;
-static uint64_t toku_write_enospc_last_report; // timestamp of most recent report to error log
+static uint64_t toku_write_enospc_last_report; // timestamp of most recent
+ // report to error log
static time_t toku_write_enospc_last_time; // timestamp of most recent ENOSPC
static uint32_t toku_write_enospc_current; // number of threads currently blocked on ENOSPC
static uint64_t toku_write_enospc_total; // total number of times ENOSPC was returned from an attempt to write
@@ -142,11 +145,17 @@ static ssize_t (*t_full_pwrite)(int, const void *, size_t, off_t);
static FILE * (*t_fdopen)(int, const char *);
static FILE * (*t_fopen)(const char *, const char *);
static int (*t_open)(const char *, int, int);
-static int (*t_fclose)(FILE *);
+static int (*t_fclose)(FILE *);
static ssize_t (*t_read)(int, void *, size_t);
static ssize_t (*t_pread)(int, void *, size_t, off_t);
+static size_t (*os_fwrite_fun)(const void *, size_t, size_t, FILE *) = nullptr;
+
+void toku_set_func_fwrite(
+ size_t (*fwrite_fun)(const void *, size_t, size_t, FILE *)) {
+ os_fwrite_fun = fwrite_fun;
+}
-void toku_set_func_write (ssize_t (*write_fun)(int, const void *, size_t)) {
+void toku_set_func_write(ssize_t (*write_fun)(int, const void *, size_t)) {
t_write = write_fun;
}
@@ -186,9 +195,63 @@ void toku_set_func_pread (ssize_t (*pread_fun)(int, void *, size_t, off_t)) {
t_pread = pread_fun;
}
-void
-toku_os_full_write (int fd, const void *buf, size_t len) {
- const char *bp = (const char *) buf;
+int toku_os_delete_with_source_location(const char *name,
+ const char *src_file,
+ uint src_line) {
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_name_close_begin(io_annotation,
+ *tokudb_file_data_key,
+ toku_instr_file_op::file_delete,
+ name,
+ src_file,
+ src_line);
+ const int result = unlink(name);
+
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_close_end(io_annotation, result);
+
+ return result;
+}
+
+int toku_os_rename_with_source_location(const char *old_name,
+ const char *new_name,
+ const char *src_file,
+ uint src_line) {
+ int result;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_name_io_begin(io_annotation,
+ *tokudb_file_data_key,
+ toku_instr_file_op::file_rename,
+ new_name,
+ 0,
+ src_file,
+ src_line);
+
+ result = rename(old_name, new_name);
+ /* Regsiter the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, 0);
+
+ return result;
+}
+
+void toku_os_full_write_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line) {
+ const char *bp = (const char *)buf;
+ size_t bytes_written = len;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_write,
+ fd,
+ len,
+ src_file,
+ src_line);
+
while (len > 0) {
ssize_t r;
if (t_full_write) {
@@ -205,14 +268,30 @@ toku_os_full_write (int fd, const void *buf, size_t len) {
}
}
assert(len == 0);
+
+ /* Register the result value with the instrumentaion system */
+ toku_instr_file_io_end(io_annotation, bytes_written);
}
-int
-toku_os_write (int fd, const void *buf, size_t len) {
- const char *bp = (const char *) buf;
+int toku_os_write_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line) {
+ const char *bp = (const char *)buf;
int result = 0;
+ ssize_t r;
+
+ size_t bytes_written = len;
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_write,
+ fd,
+ len,
+ src_file,
+ src_line);
+
while (len > 0) {
- ssize_t r;
if (t_write) {
r = t_write(fd, bp, len);
} else {
@@ -222,17 +301,33 @@ toku_os_write (int fd, const void *buf, size_t len) {
result = errno;
break;
}
- len -= r;
- bp += r;
+ len -= r;
+ bp += r;
}
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, bytes_written - len);
+
return result;
}
-void
-toku_os_full_pwrite (int fd, const void *buf, size_t len, toku_off_t off) {
- assert(0==((long long)buf)%512);
- assert((len%512 == 0) && (off%512)==0); // to make pwrite work.
- const char *bp = (const char *) buf;
+void toku_os_full_pwrite_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line) {
+ assert(0 == ((long long)buf) % 512);
+ assert((len % 512 == 0) && (off % 512) == 0); // to make pwrite work.
+ const char *bp = (const char *)buf;
+
+ size_t bytes_written = len;
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_write,
+ fd,
+ len,
+ src_file,
+ src_line);
while (len > 0) {
ssize_t r;
if (t_full_pwrite) {
@@ -250,71 +345,209 @@ toku_os_full_pwrite (int fd, const void *buf, size_t len, toku_off_t off) {
}
}
assert(len == 0);
-}
-ssize_t
-toku_os_pwrite (int fd, const void *buf, size_t len, toku_off_t off) {
- assert(0==((long long)buf)%512); // these asserts are to ensure that direct I/O will work.
- assert(0==len %512);
- assert(0==off %512);
- const char *bp = (const char *) buf;
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, bytes_written);
+}
+
+ssize_t toku_os_pwrite_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line) {
+ assert(0 ==
+ ((long long)buf) %
+ 512); // these asserts are to ensure that direct I/O will work.
+ assert(0 == len % 512);
+ assert(0 == off % 512);
+ const char *bp = (const char *)buf;
ssize_t result = 0;
+ ssize_t r;
+
+ size_t bytes_written = len;
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_write,
+ fd,
+ len,
+ src_file,
+ src_line);
while (len > 0) {
- ssize_t r;
- if (t_pwrite) {
- r = t_pwrite(fd, bp, len, off);
- } else {
- r = pwrite(fd, bp, len, off);
- }
+ r = (t_pwrite) ? t_pwrite(fd, bp, len, off) : pwrite(fd, bp, len, off);
+
if (r < 0) {
result = errno;
break;
}
len -= r;
- bp += r;
- off += r;
+ bp += r;
+ off += r;
+ }
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, bytes_written - len);
+
+ return result;
+}
+
+int toku_os_fwrite_with_source_location(const void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line) {
+ int result = 0;
+ size_t bytes_written;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_stream_io_begin(io_annotation,
+ toku_instr_file_op::file_write,
+ *stream,
+ nmemb,
+ src_file,
+ src_line);
+
+ if (os_fwrite_fun) {
+ bytes_written = os_fwrite_fun(ptr, size, nmemb, stream->file);
+ } else {
+ bytes_written = fwrite(ptr, size, nmemb, stream->file);
+ }
+
+ if (bytes_written != nmemb) {
+ if (os_fwrite_fun) // if using hook to induce artificial errors (for
+ // testing) ...
+ result = get_maybe_error_errno(); // ... then there is no error in
+ // the stream, but there is one
+ // in errno
+ else
+ result = ferror(stream->file);
+ invariant(result != 0); // Should we assert here?
+ }
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, bytes_written);
+
+ return result;
+}
+
+int toku_os_fread_with_source_location(void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line) {
+ int result = 0;
+ size_t bytes_read;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_stream_io_begin(io_annotation,
+ toku_instr_file_op::file_read,
+ *stream,
+ nmemb,
+ src_file,
+ src_line);
+
+ if ((bytes_read = fread(ptr, size, nmemb, stream->file)) != nmemb) {
+ if ((feof(stream->file)))
+ result = EOF;
+ else
+ result = ferror(stream->file);
+ invariant(result != 0); // Should we assert here?
}
+ /* Register the result value with the instrumentation system */
+ toku_instr_file_io_end(io_annotation, bytes_read);
+
return result;
}
-FILE *
-toku_os_fdopen(int fildes, const char *mode) {
- FILE * rval;
- if (t_fdopen)
- rval = t_fdopen(fildes, mode);
- else
- rval = fdopen(fildes, mode);
+TOKU_FILE *toku_os_fdopen_with_source_location(int fildes,
+ const char *mode,
+ const char *filename,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line) {
+ TOKU_FILE *XMALLOC(rval);
+ if (FT_LIKELY(rval != nullptr)) {
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_open_begin(io_annotation,
+ instr_key,
+ toku_instr_file_op::file_stream_open,
+ filename,
+ src_file,
+ src_line);
+
+ rval->file = (t_fdopen) ? t_fdopen(fildes, mode) : fdopen(fildes, mode);
+ toku_instr_file_stream_open_end(io_annotation, *rval);
+
+ if (FT_UNLIKELY(rval->file == nullptr)) {
+ toku_free(rval);
+ rval = nullptr;
+ }
+ }
return rval;
}
-
-FILE *
-toku_os_fopen(const char *filename, const char *mode){
- FILE * rval;
- if (t_fopen)
- rval = t_fopen(filename, mode);
- else
- rval = fopen(filename, mode);
+TOKU_FILE *toku_os_fopen_with_source_location(const char *filename,
+ const char *mode,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line) {
+ TOKU_FILE *XMALLOC(rval);
+ if (FT_UNLIKELY(rval == nullptr))
+ return nullptr;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_open_begin(io_annotation,
+ instr_key,
+ toku_instr_file_op::file_stream_open,
+ filename,
+ src_file,
+ src_line);
+ rval->file = t_fopen ? t_fopen(filename, mode) : fopen(filename, mode);
+ /* Register the returning "file" value with the system */
+ toku_instr_file_stream_open_end(io_annotation, *rval);
+
+ if (FT_UNLIKELY(rval->file == nullptr)) {
+ toku_free(rval);
+ rval = nullptr;
+ }
return rval;
}
-int
-toku_os_open(const char *path, int oflag, int mode) {
- int rval;
+int toku_os_open_with_source_location(const char *path,
+ int oflag,
+ int mode,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line) {
+ int fd;
+ toku_io_instrumentation io_annotation;
+ /* register a file open or creation depending on "oflag" */
+ toku_instr_file_open_begin(
+ io_annotation,
+ instr_key,
+ ((oflag & O_CREAT) ? toku_instr_file_op::file_create
+ : toku_instr_file_op::file_open),
+ path,
+ src_file,
+ src_line);
if (t_open)
- rval = t_open(path, oflag, mode);
+ fd = t_open(path, oflag, mode);
else
- rval = open(path, oflag, mode);
- return rval;
+ fd = open(path, oflag, mode);
+
+ toku_instr_file_open_end(io_annotation, fd);
+ return fd;
}
-int
-toku_os_open_direct(const char *path, int oflag, int mode) {
+int toku_os_open_direct(const char *path,
+ int oflag,
+ int mode,
+ const toku_instr_key &instr_key) {
int rval;
#if defined(HAVE_O_DIRECT)
- rval = toku_os_open(path, oflag | O_DIRECT, mode);
+ rval = toku_os_open(path, oflag | O_DIRECT, mode, instr_key);
#elif defined(HAVE_F_NOCACHE)
- rval = toku_os_open(path, oflag, mode);
+ rval = toku_os_open(path, oflag, mode, instr_key);
if (rval >= 0) {
int r = fcntl(rval, F_NOCACHE, 1);
if (r == -1) {
@@ -327,63 +560,112 @@ toku_os_open_direct(const char *path, int oflag, int mode) {
return rval;
}
-int
-toku_os_fclose(FILE * stream) {
+int toku_os_fclose_with_source_location(TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line) {
int rval = -1;
- if (t_fclose)
- rval = t_fclose(stream);
- else { // if EINTR, retry until success
- while (rval != 0) {
- rval = fclose(stream);
- if (rval && (errno != EINTR))
- break;
- }
+ if (FT_LIKELY(stream != nullptr)) {
+ /* register a file stream close " */
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_stream_close_begin(
+ io_annotation,
+ toku_instr_file_op::file_stream_close,
+ *stream,
+ src_file,
+ src_line);
+
+ if (t_fclose)
+ rval = t_fclose(stream->file);
+ else { // if EINTR, retry until success
+ while (rval != 0) {
+ rval = fclose(stream->file);
+ if (rval && (errno != EINTR))
+ break;
+ }
+ }
+ /* Register the returning "rval" value with the system */
+ toku_instr_file_close_end(io_annotation, rval);
+ toku_free(stream);
+ stream = nullptr;
}
return rval;
}
-int
-toku_os_close(int fd) { // if EINTR, retry until success
+int toku_os_close_with_source_location(
+ int fd,
+ const char *src_file,
+ uint src_line) { // if EINTR, retry until success
+ /* register the file close */
int r = -1;
+
+ /* register a file descriptor close " */
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_fd_close_begin(
+ io_annotation, toku_instr_file_op::file_close, fd, src_file, src_line);
while (r != 0) {
- r = close(fd);
- if (r) {
- int rr = errno;
- if (rr!=EINTR) printf("rr=%d (%s)\n", rr, strerror(rr));
- assert(rr==EINTR);
- }
+ r = close(fd);
+ if (r) {
+ int rr = errno;
+ if (rr != EINTR)
+ printf("rr=%d (%s)\n", rr, strerror(rr));
+ assert(rr == EINTR);
+ }
}
- return r;
-}
-
-int toku_os_rename(const char *old_name, const char *new_name) {
- return rename(old_name, new_name);
-}
-int toku_os_unlink(const char *path) { return unlink(path); }
+ /* Regsiter the returning value with the system */
+ toku_instr_file_close_end(io_annotation, r);
-ssize_t
-toku_os_read(int fd, void *buf, size_t count) {
- ssize_t r;
- if (t_read)
- r = t_read(fd, buf, count);
- else
- r = read(fd, buf, count);
return r;
}
-ssize_t
-toku_os_pread (int fd, void *buf, size_t count, off_t offset) {
- assert(0==((long long)buf)%512);
- assert(0==count%512);
- assert(0==offset%512);
- ssize_t r;
+ssize_t toku_os_read_with_source_location(int fd,
+ void *buf,
+ size_t count,
+ const char *src_file,
+ uint src_line) {
+ ssize_t bytes_read;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_read,
+ fd,
+ count,
+ src_file,
+ src_line);
+
+ bytes_read = (t_read) ? t_read(fd, buf, count) : read(fd, buf, count);
+
+ toku_instr_file_io_end(io_annotation, bytes_read);
+
+ return bytes_read;
+}
+
+ssize_t inline_toku_os_pread_with_source_location(int fd,
+ void *buf,
+ size_t count,
+ off_t offset,
+ const char *src_file,
+ uint src_line) {
+ assert(0 == ((long long)buf) % 512);
+ assert(0 == count % 512);
+ assert(0 == offset % 512);
+ ssize_t bytes_read;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_read,
+ fd,
+ count,
+ src_file,
+ src_line);
if (t_pread) {
- r = t_pread(fd, buf, count, offset);
+ bytes_read = t_pread(fd, buf, count, offset);
} else {
- r = pread(fd, buf, count, offset);
+ bytes_read = pread(fd, buf, count, offset);
}
- return r;
+ toku_instr_file_io_end(io_annotation, bytes_read);
+
+ return bytes_read;
}
void toku_os_recursive_delete(const char *path) {
@@ -411,13 +693,24 @@ void toku_set_func_fsync(int (*fsync_function)(int)) {
}
// keep trying if fsync fails because of EINTR
-static void file_fsync_internal (int fd) {
+void file_fsync_internal_with_source_location(int fd,
+ const char *src_file,
+ uint src_line) {
uint64_t tstart = toku_current_time_microsec();
int r = -1;
uint64_t eintr_count = 0;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_sync,
+ fd,
+ 0,
+ src_file,
+ src_line);
+
while (r != 0) {
- if (t_fsync) {
- r = t_fsync(fd);
+ if (t_fsync) {
+ r = t_fsync(fd);
} else {
r = fsync(fd);
}
@@ -429,6 +722,9 @@ static void file_fsync_internal (int fd) {
toku_sync_fetch_and_add(&toku_fsync_count, 1);
uint64_t duration = toku_current_time_microsec() - tstart;
toku_sync_fetch_and_add(&toku_fsync_time, duration);
+
+ toku_instr_file_io_end(io_annotation, 0);
+
if (duration >= toku_long_fsync_threshold) {
toku_sync_fetch_and_add(&toku_long_fsync_count, 1);
toku_sync_fetch_and_add(&toku_long_fsync_time, duration);
diff --git a/storage/tokudb/PerconaFT/portability/memory.cc b/storage/tokudb/PerconaFT/portability/memory.cc
index 5430ff84b70..9594158cf38 100644
--- a/storage/tokudb/PerconaFT/portability/memory.cc
+++ b/storage/tokudb/PerconaFT/portability/memory.cc
@@ -104,7 +104,13 @@ toku_memory_startup(void) {
size_t lg_chunk; // log2 of the mmap threshold
size_t lg_chunk_length = sizeof lg_chunk;
result = mallctl_f("opt.lg_chunk", &lg_chunk, &lg_chunk_length, NULL, 0);
- if (result == 0)
+ if (result)
+ {
+ status.mmap_threshold = 1 << 21; // Default value.
+ // Incompatible jemalloc change.
+ result = 0;
+ }
+ else
status.mmap_threshold = 1 << lg_chunk;
}
}
diff --git a/storage/tokudb/PerconaFT/portability/portability.cc b/storage/tokudb/PerconaFT/portability/portability.cc
index 19f445a85d7..dfa5153cc66 100644
--- a/storage/tokudb/PerconaFT/portability/portability.cc
+++ b/storage/tokudb/PerconaFT/portability/portability.cc
@@ -79,6 +79,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "toku_os.h"
#include "toku_time.h"
#include "memory.h"
+
+#include "toku_instrumentation.h"
+
#include <portability/toku_atomic.h>
#include <util/partitioned_counter.h>
@@ -172,13 +175,26 @@ toku_os_get_phys_memory_size(void) {
#endif
}
-int
-toku_os_get_file_size(int fildes, int64_t *fsize) {
+int toku_os_get_file_size_with_source_location(int fildes,
+ int64_t *fsize,
+ const char *src_file,
+ uint src_line) {
toku_struct_stat sbuf;
+
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_stat,
+ fildes,
+ 0,
+ src_file,
+ src_line);
+
int r = fstat(fildes, &sbuf);
- if (r==0) {
+ if (r == 0) {
*fsize = sbuf.st_size;
}
+ toku_instr_file_io_end(io_annotation, 0);
+
return r;
}
@@ -272,15 +288,39 @@ toku_os_get_max_process_data_size(uint64_t *maxdata) {
return r;
}
-int
-toku_stat(const char *name, toku_struct_stat *buf) {
+int toku_stat_with_source_location(const char *name,
+ toku_struct_stat *buf,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line) {
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_name_io_begin(io_annotation,
+ instr_key,
+ toku_instr_file_op::file_stat,
+ name,
+ 0,
+ src_file,
+ src_line);
int r = stat(name, buf);
+
+ toku_instr_file_io_end(io_annotation, 0);
return r;
}
-int
-toku_fstat(int fd, toku_struct_stat *buf) {
+int toku_os_fstat_with_source_location(int fd,
+ toku_struct_stat *buf,
+ const char *src_file,
+ uint src_line) {
+ toku_io_instrumentation io_annotation;
+ toku_instr_file_io_begin(io_annotation,
+ toku_instr_file_op::file_stat,
+ fd,
+ 0,
+ src_file,
+ src_line);
+
int r = fstat(fd, buf);
+ toku_instr_file_io_end(io_annotation, 0);
return r;
}
@@ -427,5 +467,9 @@ void __attribute__((constructor)) toku_portability_helgrind_ignore(void);
void
toku_portability_helgrind_ignore(void) {
TOKU_VALGRIND_HG_DISABLE_CHECKING(&toku_cached_hz, sizeof toku_cached_hz);
- TOKU_VALGRIND_HG_DISABLE_CHECKING(&toku_cached_pagesize, sizeof toku_cached_pagesize);
+ TOKU_VALGRIND_HG_DISABLE_CHECKING(&toku_cached_pagesize,
+ sizeof toku_cached_pagesize);
}
+
+static const pfs_key_t pfs_not_instrumented = 0xFFFFFFFF;
+toku_instr_key toku_uninstrumented(pfs_not_instrumented);
diff --git a/storage/tokudb/PerconaFT/portability/tests/rwlock_condvar.h b/storage/tokudb/PerconaFT/portability/tests/rwlock_condvar.h
index 92f2fb354f7..d1ebc81e1dc 100644
--- a/storage/tokudb/PerconaFT/portability/tests/rwlock_condvar.h
+++ b/storage/tokudb/PerconaFT/portability/tests/rwlock_condvar.h
@@ -107,10 +107,10 @@ get_waitstate(void)
#endif
int toku_cv_fair_rwlock_init (toku_cv_fair_rwlock_t *rwlock) {
- rwlock->state=0;
+ rwlock->state = 0;
rwlock->waiters_head = NULL;
rwlock->waiters_tail = NULL;
- toku_mutex_init(&rwlock->mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &rwlock->mutex, nullptr);
return 0;
}
diff --git a/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rdlock.cc b/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rdlock.cc
index 364bd7d3766..62aa5205f3c 100644
--- a/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rdlock.cc
+++ b/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rdlock.cc
@@ -48,7 +48,7 @@ int test_main(int argc __attribute__((__unused__)), char *const argv[] __attribu
toku_pthread_rwlock_t rwlock;
ZERO_STRUCT(rwlock);
- toku_pthread_rwlock_init(&rwlock, NULL);
+ toku_pthread_rwlock_init(toku_uninstrumented, &rwlock, nullptr);
toku_pthread_rwlock_rdlock(&rwlock);
toku_pthread_rwlock_rdlock(&rwlock);
toku_pthread_rwlock_rdunlock(&rwlock);
diff --git a/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rwr.cc b/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rwr.cc
index 3ca9e06bff7..92b30421ba9 100644
--- a/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rwr.cc
+++ b/storage/tokudb/PerconaFT/portability/tests/test-pthread-rwlock-rwr.cc
@@ -71,13 +71,19 @@ int test_main(int argc , char *const argv[] ) {
toku_pthread_t tid;
void *retptr;
- toku_pthread_rwlock_init(&rwlock, NULL);
- state = 37; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
+ toku_pthread_rwlock_init(toku_uninstrumented, &rwlock, nullptr);
+ state = 37;
+ if (verbose)
+ printf("%s:%d\n", __FUNCTION__, __LINE__);
toku_pthread_rwlock_rdlock(&rwlock);
- r = toku_pthread_create(&tid, NULL, f, &rwlock); assert(r == 0);
+ r = toku_pthread_create(toku_uninstrumented, &tid, nullptr, f, &rwlock);
+ assert(r == 0);
- assert(state==37); state = 42; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
+ assert(state == 37);
+ state = 42;
+ if (verbose)
+ printf("%s:%d\n", __FUNCTION__, __LINE__);
sleep(4);
assert(state==16); state = 44; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
toku_pthread_rwlock_rdlock(&rwlock);
diff --git a/storage/tokudb/PerconaFT/portability/tests/test-stat.cc b/storage/tokudb/PerconaFT/portability/tests/test-stat.cc
index 494a17bd074..57201764afb 100644
--- a/storage/tokudb/PerconaFT/portability/tests/test-stat.cc
+++ b/storage/tokudb/PerconaFT/portability/tests/test-stat.cc
@@ -47,10 +47,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
static void test_stat(const char *dirname, int result, int ex_errno) {
int r;
toku_struct_stat buf;
- r = toku_stat(dirname, &buf);
- //printf("stat %s %d %d\n", dirname, r, errno); fflush(stdout);
- assert(r==result);
- if (r!=0) assert(get_maybe_error_errno() == ex_errno);
+ r = toku_stat(dirname, &buf, toku_uninstrumented);
+ // printf("stat %s %d %d\n", dirname, r, errno); fflush(stdout);
+ assert(r == result);
+ if (r != 0)
+ assert(get_maybe_error_errno() == ex_errno);
}
int main(void) {
diff --git a/storage/tokudb/PerconaFT/portability/tests/test-toku-malloc.cc b/storage/tokudb/PerconaFT/portability/tests/test-toku-malloc.cc
index 1e1c7533c15..0d99b36b51a 100644
--- a/storage/tokudb/PerconaFT/portability/tests/test-toku-malloc.cc
+++ b/storage/tokudb/PerconaFT/portability/tests/test-toku-malloc.cc
@@ -53,10 +53,12 @@ int main(void) {
int i;
const int max_threads = 2;
toku_pthread_t tids[max_threads];
- for (i=0; i<max_threads; i++) {
- r = toku_pthread_create(&tids[i], NULL, f, 0); assert(r == 0);
+ for (i = 0; i < max_threads; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, f, nullptr);
+ assert(r == 0);
}
- for (i=0; i<max_threads; i++) {
+ for (i = 0; i < max_threads; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/portability/toku_assert.h b/storage/tokudb/PerconaFT/portability/toku_assert.h
index 26a71cede7d..b0a7be3287b 100644
--- a/storage/tokudb/PerconaFT/portability/toku_assert.h
+++ b/storage/tokudb/PerconaFT/portability/toku_assert.h
@@ -53,13 +53,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#error NDEBUG should not be set
#endif
-static inline int get_error_errno(void);
+inline int get_error_errno(void);
-static inline int
-get_maybe_error_errno(void)
-{
- return errno;
-}
+static inline int get_maybe_error_errno(void) { return errno; }
static inline void
set_errno(int new_errno)
@@ -139,12 +135,10 @@ void db_env_do_backtrace(FILE *outf);
#define paranoid_invariant(a) ((void) 0)
#define paranoid_invariant_null(a) ((void) 0)
#define paranoid_invariant_notnull(a) ((void) 0)
-#define paranoid_invariant_zero(a) ((void) 0)
+#define paranoid_invariant_zero(a) ((void)0)
#endif
-static inline int
-get_error_errno(void)
-{
+inline int get_error_errno(void) {
invariant(errno);
return errno;
}
diff --git a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc
new file mode 100644
index 00000000000..b7b4c0ab233
--- /dev/null
+++ b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc
@@ -0,0 +1,365 @@
+#ifdef MYSQL_TOKUDB_ENGINE
+#include "toku_portability.h"
+#include "toku_pthread.h"
+
+toku_instr_probe_pfs::toku_instr_probe_pfs(const toku_instr_key &key)
+ : mutex(new toku_mutex_t) {
+ toku_mutex_init(key, mutex.get(), nullptr);
+}
+
+toku_instr_probe_pfs::~toku_instr_probe_pfs() {
+ toku_mutex_destroy(mutex.get());
+}
+
+// Thread instrumentation
+
+int toku_pthread_create(const toku_instr_key &key,
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void *),
+ void *arg) {
+#if (MYSQL_VERSION_MAJOR >= 5) && (MYSQL_VERSION_MINOR >= 7)
+ return PSI_THREAD_CALL(spawn_thread)(
+ key.id(), reinterpret_cast<my_thread_handle *>(thread),
+ attr, start_routine, arg);
+#else
+ return PSI_THREAD_CALL(spawn_thread)(
+ key.id(), thread, attr, start_routine, arg);
+#endif
+}
+
+void toku_instr_register_current_thread(const toku_instr_key &key) {
+ struct PSI_thread *psi_thread =
+ PSI_THREAD_CALL(new_thread)(key.id(), nullptr, 0);
+ PSI_THREAD_CALL(set_thread)(psi_thread);
+}
+
+void toku_instr_delete_current_thread() {
+ PSI_THREAD_CALL(delete_current_thread)();
+}
+
+// I/O instrumentation
+
+void toku_instr_file_open_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker =
+ PSI_FILE_CALL(get_thread_file_name_locker)(
+ &io_instr.state, key.id(), static_cast<PSI_file_operation>(op),
+ name, io_instr.locker);
+ if (io_instr.locker != nullptr) {
+ PSI_FILE_CALL(start_file_open_wait)
+ (io_instr.locker, src_file, src_line);
+ }
+}
+
+void toku_instr_file_stream_open_end(toku_io_instrumentation &io_instr,
+ TOKU_FILE &file) {
+ file.key = nullptr;
+ if (FT_LIKELY(io_instr.locker)) {
+ file.key =
+ PSI_FILE_CALL(end_file_open_wait)(io_instr.locker, file.file);
+ }
+}
+
+void toku_instr_file_open_end(toku_io_instrumentation &io_instr, int fd) {
+ if (FT_LIKELY(io_instr.locker))
+ PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)
+ (io_instr.locker, fd);
+}
+
+void toku_instr_file_name_close_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker =
+ PSI_FILE_CALL(get_thread_file_name_locker)(
+ &io_instr.state, key.id(), static_cast<PSI_file_operation>(op),
+ name,
+ io_instr.locker);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_close_wait)
+ (io_instr.locker, src_file, src_line);
+ }
+}
+
+void toku_instr_file_stream_close_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ const TOKU_FILE &file,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker = nullptr;
+ if (FT_LIKELY(file.key)) {
+ io_instr.locker = PSI_FILE_CALL(get_thread_file_stream_locker)(
+ &io_instr.state, file.key, (PSI_file_operation)op);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_close_wait)
+ (io_instr.locker, src_file, src_line);
+ }
+ }
+}
+
+void toku_instr_file_fd_close_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ int fd,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
+ &io_instr.state, fd, (PSI_file_operation)op);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_close_wait)
+ (io_instr.locker, src_file, src_line);
+ }
+}
+
+void toku_instr_file_close_end(const toku_io_instrumentation &io_instr,
+ int result) {
+ if (FT_LIKELY(io_instr.locker))
+ PSI_FILE_CALL(end_file_close_wait)
+ (io_instr.locker, result);
+}
+
+void toku_instr_file_io_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ int fd,
+ ssize_t count,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker = PSI_FILE_CALL(get_thread_file_descriptor_locker)(
+ &io_instr.state, fd, (PSI_file_operation)op);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_wait)
+ (io_instr.locker, count, src_file, src_line);
+ }
+}
+
+void toku_instr_file_name_io_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ ssize_t count,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker =
+ PSI_FILE_CALL(get_thread_file_name_locker)(&io_instr.state,
+ key.id(),
+ (PSI_file_operation)op,
+ name,
+ &io_instr.locker);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_wait)
+ (io_instr.locker, count, src_file, src_line);
+ }
+}
+
+void toku_instr_file_stream_io_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ const TOKU_FILE &file,
+ ssize_t count,
+ const char *src_file,
+ int src_line) {
+ io_instr.locker = nullptr;
+ if (FT_LIKELY(file.key)) {
+ io_instr.locker = PSI_FILE_CALL(get_thread_file_stream_locker)(
+ &io_instr.state, file.key, (PSI_file_operation)op);
+ if (FT_LIKELY(io_instr.locker)) {
+ PSI_FILE_CALL(start_file_wait)
+ (io_instr.locker, count, src_file, src_line);
+ }
+ }
+}
+
+void toku_instr_file_io_end(toku_io_instrumentation &io_instr, ssize_t count) {
+ if (FT_LIKELY(io_instr.locker))
+ PSI_FILE_CALL(end_file_wait)
+ (io_instr.locker, count);
+}
+
+// Mutex instrumentation
+
+void toku_instr_mutex_init(const toku_instr_key &key, toku_mutex_t &mutex) {
+ mutex.psi_mutex = PSI_MUTEX_CALL(init_mutex)(key.id(), &mutex.pmutex);
+#if TOKU_PTHREAD_DEBUG
+ mutex.instr_key_id = key.id();
+#endif
+}
+
+void toku_instr_mutex_destroy(PSI_mutex *&mutex_instr) {
+ if (mutex_instr != nullptr) {
+ PSI_MUTEX_CALL(destroy_mutex)(mutex_instr);
+ mutex_instr = nullptr;
+ }
+}
+
+void toku_instr_mutex_lock_start(toku_mutex_instrumentation &mutex_instr,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line) {
+ mutex_instr.locker = nullptr;
+ if (mutex.psi_mutex) {
+ mutex_instr.locker =
+ PSI_MUTEX_CALL(start_mutex_wait)(&mutex_instr.state,
+ mutex.psi_mutex,
+ PSI_MUTEX_LOCK,
+ src_file,
+ src_line);
+ }
+}
+
+void toku_instr_mutex_trylock_start(toku_mutex_instrumentation &mutex_instr,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line) {
+ mutex_instr.locker = nullptr;
+ if (mutex.psi_mutex) {
+ mutex_instr.locker =
+ PSI_MUTEX_CALL(start_mutex_wait)(&mutex_instr.state,
+ mutex.psi_mutex,
+ PSI_MUTEX_TRYLOCK,
+ src_file,
+ src_line);
+ }
+}
+
+void toku_instr_mutex_lock_end(toku_mutex_instrumentation &mutex_instr,
+ int pthread_mutex_lock_result) {
+ if (mutex_instr.locker)
+ PSI_MUTEX_CALL(end_mutex_wait)
+ (mutex_instr.locker, pthread_mutex_lock_result);
+}
+
+void toku_instr_mutex_unlock(PSI_mutex *mutex_instr) {
+ if (mutex_instr)
+ PSI_MUTEX_CALL(unlock_mutex)(mutex_instr);
+}
+
+// Condvar instrumentation
+
+void toku_instr_cond_init(const toku_instr_key &key, toku_cond_t &cond) {
+ cond.psi_cond = PSI_COND_CALL(init_cond)(key.id(), &cond.pcond);
+#if TOKU_PTHREAD_DEBUG
+ cond.instr_key_id = key.id();
+#endif
+}
+
+void toku_instr_cond_destroy(PSI_cond *&cond_instr) {
+ if (cond_instr != nullptr) {
+ PSI_COND_CALL(destroy_cond)(cond_instr);
+ cond_instr = nullptr;
+ }
+}
+
+void toku_instr_cond_wait_start(toku_cond_instrumentation &cond_instr,
+ toku_instr_cond_op op,
+ toku_cond_t &cond,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line) {
+ cond_instr.locker = nullptr;
+ if (cond.psi_cond) {
+ /* Instrumentation start */
+ cond_instr.locker =
+ PSI_COND_CALL(start_cond_wait)(&cond_instr.state,
+ cond.psi_cond,
+ mutex.psi_mutex,
+ (PSI_cond_operation)op,
+ src_file,
+ src_line);
+ }
+}
+
+void toku_instr_cond_wait_end(toku_cond_instrumentation &cond_instr,
+ int pthread_cond_wait_result) {
+ if (cond_instr.locker)
+ PSI_COND_CALL(end_cond_wait)
+ (cond_instr.locker, pthread_cond_wait_result);
+}
+
+void toku_instr_cond_signal(const toku_cond_t &cond) {
+ if (cond.psi_cond)
+ PSI_COND_CALL(signal_cond)(cond.psi_cond);
+}
+
+void toku_instr_cond_broadcast(const toku_cond_t &cond) {
+ if (cond.psi_cond)
+ PSI_COND_CALL(broadcast_cond)(cond.psi_cond);
+}
+
+// rwlock instrumentation
+
+void toku_instr_rwlock_init(const toku_instr_key &key,
+ toku_pthread_rwlock_t &rwlock) {
+ rwlock.psi_rwlock = PSI_RWLOCK_CALL(init_rwlock)(key.id(), &rwlock.rwlock);
+#if TOKU_PTHREAD_DEBUG
+ rwlock.instr_key_id = key.id();
+#endif
+}
+
+void toku_instr_rwlock_destroy(PSI_rwlock *&rwlock_instr) {
+ if (rwlock_instr != nullptr) {
+ PSI_RWLOCK_CALL(destroy_rwlock)(rwlock_instr);
+ rwlock_instr = nullptr;
+ }
+}
+
+void toku_instr_rwlock_rdlock_wait_start(
+ toku_rwlock_instrumentation &rwlock_instr,
+ toku_pthread_rwlock_t &rwlock,
+ const char *src_file,
+ int src_line) {
+ rwlock_instr.locker = nullptr;
+ if (rwlock.psi_rwlock) {
+ /* Instrumentation start */
+ rwlock_instr.locker =
+ PSI_RWLOCK_CALL(start_rwlock_rdwait)(&rwlock_instr.state,
+ rwlock.psi_rwlock,
+ PSI_RWLOCK_READLOCK,
+ src_file,
+ src_line);
+ }
+}
+
+void toku_instr_rwlock_wrlock_wait_start(
+ toku_rwlock_instrumentation &rwlock_instr,
+ toku_pthread_rwlock_t &rwlock,
+ const char *src_file,
+ int src_line) {
+ rwlock_instr.locker = nullptr;
+ if (rwlock.psi_rwlock) {
+ /* Instrumentation start */
+ rwlock_instr.locker =
+ PSI_RWLOCK_CALL(start_rwlock_wrwait)(&rwlock_instr.state,
+ rwlock.psi_rwlock,
+ PSI_RWLOCK_WRITELOCK,
+ src_file,
+ src_line);
+ }
+}
+
+void toku_instr_rwlock_rdlock_wait_end(
+ toku_rwlock_instrumentation &rwlock_instr,
+ int pthread_rwlock_wait_result) {
+ if (rwlock_instr.locker)
+ PSI_RWLOCK_CALL(end_rwlock_rdwait)
+ (rwlock_instr.locker, pthread_rwlock_wait_result);
+}
+
+void toku_instr_rwlock_wrlock_wait_end(
+ toku_rwlock_instrumentation &rwlock_instr,
+ int pthread_rwlock_wait_result) {
+ if (rwlock_instr.locker)
+ PSI_RWLOCK_CALL(end_rwlock_wrwait)
+ (rwlock_instr.locker, pthread_rwlock_wait_result);
+}
+
+void toku_instr_rwlock_unlock(toku_pthread_rwlock_t &rwlock) {
+ if (rwlock.psi_rwlock)
+ PSI_RWLOCK_CALL(unlock_rwlock)(rwlock.psi_rwlock);
+}
+
+#endif // MYSQL_TOKUDB_ENGINE
diff --git a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h
new file mode 100644
index 00000000000..d6b0ed35ce9
--- /dev/null
+++ b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.h
@@ -0,0 +1,249 @@
+#ifdef TOKU_INSTR_MYSQL_H
+// This file can be included only from toku_instumentation.h because
+// it replaces the defintitions for the case if MySQL PFS is available
+#error "toku_instr_mysql.h can be included only once"
+#else // TOKU_INSTR_MYSQL_H
+#define TOKU_INSTR_MYSQL_H
+
+#include <memory>
+
+// As these macros are defined in my_global.h
+// and they are also defined in command line
+// undefine them here to avoid compilation errors.
+#undef __STDC_FORMAT_MACROS
+#undef __STDC_LIMIT_MACROS
+#include <mysql/psi/mysql_file.h> // PSI_file
+#include <mysql/psi/mysql_thread.h> // PSI_mutex
+
+#ifndef HAVE_PSI_MUTEX_INTERFACE
+#error HAVE_PSI_MUTEX_INTERFACE required
+#endif
+#ifndef HAVE_PSI_RWLOCK_INTERFACE
+#error HAVE_PSI_RWLOCK_INTERFACE required
+#endif
+#ifndef HAVE_PSI_THREAD_INTERFACE
+#error HAVE_PSI_THREAD_INTERFACE required
+#endif
+
+// Instrumentation keys
+
+class toku_instr_key {
+ private:
+ pfs_key_t m_id;
+
+ public:
+ toku_instr_key(toku_instr_object_type type,
+ const char *group,
+ const char *name) {
+ switch (type) {
+ case toku_instr_object_type::mutex: {
+ PSI_mutex_info mutex_info{&m_id, name, 0};
+ mysql_mutex_register(group, &mutex_info, 1);
+ } break;
+ case toku_instr_object_type::rwlock: {
+ PSI_rwlock_info rwlock_info{&m_id, name, 0};
+ mysql_rwlock_register(group, &rwlock_info, 1);
+ } break;
+ case toku_instr_object_type::cond: {
+ PSI_cond_info cond_info{&m_id, name, 0};
+ mysql_cond_register(group, &cond_info, 1);
+ } break;
+ case toku_instr_object_type::thread: {
+ PSI_thread_info thread_info{&m_id, name, 0};
+ mysql_thread_register(group, &thread_info, 1);
+ } break;
+ case toku_instr_object_type::file: {
+ PSI_file_info file_info{&m_id, name, 0};
+ mysql_file_register(group, &file_info, 1);
+ } break;
+ }
+ }
+
+ explicit toku_instr_key(pfs_key_t key_id) : m_id(key_id) {}
+
+ pfs_key_t id() const { return m_id; }
+};
+
+// Thread instrumentation
+int toku_pthread_create(const toku_instr_key &key,
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void *),
+ void *arg);
+void toku_instr_register_current_thread(const toku_instr_key &key);
+void toku_instr_delete_current_thread();
+
+// I/O instrumentation
+
+enum class toku_instr_file_op {
+ file_stream_open = PSI_FILE_STREAM_OPEN,
+ file_create = PSI_FILE_CREATE,
+ file_open = PSI_FILE_OPEN,
+ file_delete = PSI_FILE_DELETE,
+ file_rename = PSI_FILE_RENAME,
+ file_read = PSI_FILE_READ,
+ file_write = PSI_FILE_WRITE,
+ file_sync = PSI_FILE_SYNC,
+ file_stream_close = PSI_FILE_STREAM_CLOSE,
+ file_close = PSI_FILE_CLOSE,
+ file_stat = PSI_FILE_STAT
+};
+
+struct toku_io_instrumentation {
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+
+ toku_io_instrumentation() : locker(nullptr) {}
+};
+
+void toku_instr_file_open_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_stream_open_end(toku_io_instrumentation &io_instr,
+ TOKU_FILE &file);
+void toku_instr_file_open_end(toku_io_instrumentation &io_instr, int fd);
+void toku_instr_file_name_close_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_stream_close_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ const TOKU_FILE &file,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_fd_close_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ int fd,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_close_end(const toku_io_instrumentation &io_instr,
+ int result);
+void toku_instr_file_io_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ int fd,
+ ssize_t count,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_name_io_begin(toku_io_instrumentation &io_instr,
+ const toku_instr_key &key,
+ toku_instr_file_op op,
+ const char *name,
+ ssize_t count,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_stream_io_begin(toku_io_instrumentation &io_instr,
+ toku_instr_file_op op,
+ const TOKU_FILE &file,
+ ssize_t count,
+ const char *src_file,
+ int src_line);
+void toku_instr_file_io_end(toku_io_instrumentation &io_instr, ssize_t count);
+
+// Mutex instrumentation
+
+struct toku_mutex_instrumentation {
+ struct PSI_mutex_locker *locker;
+ PSI_mutex_locker_state state;
+
+ toku_mutex_instrumentation() : locker(nullptr) {}
+};
+
+void toku_instr_mutex_init(const toku_instr_key &key, toku_mutex_t &mutex);
+void toku_instr_mutex_destroy(PSI_mutex *&mutex_instr);
+void toku_instr_mutex_lock_start(toku_mutex_instrumentation &mutex_instr,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line);
+void toku_instr_mutex_trylock_start(toku_mutex_instrumentation &mutex_instr,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line);
+void toku_instr_mutex_lock_end(toku_mutex_instrumentation &mutex_instr,
+ int pthread_mutex_lock_result);
+void toku_instr_mutex_unlock(PSI_mutex *mutex_instr);
+
+// Instrumentation probes
+
+class toku_instr_probe_pfs {
+ private:
+ std::unique_ptr<toku_mutex_t> mutex;
+ toku_mutex_instrumentation mutex_instr;
+
+ public:
+ explicit toku_instr_probe_pfs(const toku_instr_key &key);
+
+ ~toku_instr_probe_pfs();
+
+ void start_with_source_location(const char *src_file, int src_line) {
+ mutex_instr.locker = nullptr;
+ toku_instr_mutex_lock_start(mutex_instr, *mutex, src_file, src_line);
+ }
+
+ void stop() { toku_instr_mutex_lock_end(mutex_instr, 0); }
+};
+
+typedef toku_instr_probe_pfs toku_instr_probe;
+
+// Condvar instrumentation
+
+struct toku_cond_instrumentation {
+ struct PSI_cond_locker *locker;
+ PSI_cond_locker_state state;
+
+ toku_cond_instrumentation() : locker(nullptr) {}
+};
+
+enum class toku_instr_cond_op {
+ cond_wait = PSI_COND_WAIT,
+ cond_timedwait = PSI_COND_TIMEDWAIT,
+};
+
+void toku_instr_cond_init(const toku_instr_key &key, toku_cond_t &cond);
+void toku_instr_cond_destroy(PSI_cond *&cond_instr);
+void toku_instr_cond_wait_start(toku_cond_instrumentation &cond_instr,
+ toku_instr_cond_op op,
+ toku_cond_t &cond,
+ toku_mutex_t &mutex,
+ const char *src_file,
+ int src_line);
+void toku_instr_cond_wait_end(toku_cond_instrumentation &cond_instr,
+ int pthread_cond_wait_result);
+void toku_instr_cond_signal(const toku_cond_t &cond);
+void toku_instr_cond_broadcast(const toku_cond_t &cond);
+
+// rwlock instrumentation
+
+struct toku_rwlock_instrumentation {
+ struct PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+
+ toku_rwlock_instrumentation() : locker(nullptr) { }
+};
+
+void toku_instr_rwlock_init(const toku_instr_key &key,
+ toku_pthread_rwlock_t &rwlock);
+void toku_instr_rwlock_destroy(PSI_rwlock *&rwlock_instr);
+void toku_instr_rwlock_rdlock_wait_start(
+ toku_rwlock_instrumentation &rwlock_instr,
+ toku_pthread_rwlock_t &rwlock,
+ const char *src_file,
+ int src_line);
+void toku_instr_rwlock_wrlock_wait_start(
+ toku_rwlock_instrumentation &rwlock_instr,
+ toku_pthread_rwlock_t &rwlock,
+ const char *src_file,
+ int src_line);
+void toku_instr_rwlock_rdlock_wait_end(
+ toku_rwlock_instrumentation &rwlock_instr,
+ int pthread_rwlock_wait_result);
+void toku_instr_rwlock_wrlock_wait_end(
+ toku_rwlock_instrumentation &rwlock_instr,
+ int pthread_rwlock_wait_result);
+void toku_instr_rwlock_unlock(toku_pthread_rwlock_t &rwlock);
+
+#endif // TOKU_INSTR_MYSQL_H
diff --git a/storage/tokudb/PerconaFT/portability/toku_instrumentation.h b/storage/tokudb/PerconaFT/portability/toku_instrumentation.h
new file mode 100644
index 00000000000..8c9390edc0a
--- /dev/null
+++ b/storage/tokudb/PerconaFT/portability/toku_instrumentation.h
@@ -0,0 +1,339 @@
+#pragma once
+
+#include <stdio.h> // FILE
+
+// Performance instrumentation object identifier type
+typedef unsigned int pfs_key_t;
+
+enum class toku_instr_object_type { mutex, rwlock, cond, thread, file };
+
+struct PSI_file;
+
+struct TOKU_FILE {
+ /** The real file. */
+ FILE *file;
+ struct PSI_file *key;
+ TOKU_FILE() : file(nullptr), key(nullptr) {}
+};
+
+struct PSI_mutex;
+struct PSI_cond;
+struct PSI_rwlock;
+
+struct toku_mutex_t;
+struct toku_cond_t;
+struct toku_pthread_rwlock_t;
+
+class toku_instr_key;
+
+class toku_instr_probe_empty {
+ public:
+ explicit toku_instr_probe_empty(UU(const toku_instr_key &key)) {}
+
+ void start_with_source_location(UU(const char *src_file),
+ UU(int src_line)) {}
+
+ void stop() {}
+};
+
+#define TOKU_PROBE_START(p) p->start_with_source_location(__FILE__, __LINE__)
+#define TOKU_PROBE_STOP(p) p->stop
+
+extern toku_instr_key toku_uninstrumented;
+
+#ifndef MYSQL_TOKUDB_ENGINE
+
+#include <pthread.h>
+
+class toku_instr_key {
+ public:
+ toku_instr_key(UU(toku_instr_object_type type),
+ UU(const char *group),
+ UU(const char *name)) {}
+
+ explicit toku_instr_key(UU(pfs_key_t key_id)) {}
+};
+
+typedef toku_instr_probe_empty toku_instr_probe;
+
+enum class toku_instr_file_op {
+ file_stream_open,
+ file_create,
+ file_open,
+ file_delete,
+ file_rename,
+ file_read,
+ file_write,
+ file_sync,
+ file_stream_close,
+ file_close,
+ file_stat
+};
+
+struct PSI_file {};
+struct PSI_mutex {};
+
+struct toku_io_instrumentation {};
+
+inline int toku_pthread_create(UU(const toku_instr_key &key),
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void *),
+ void *arg) {
+ return pthread_create(thread, attr, start_routine, arg);
+}
+
+inline void toku_instr_register_current_thread() {}
+
+inline void toku_instr_delete_current_thread() {}
+
+// Instrument file creation, opening, closing, and renaming
+inline void toku_instr_file_open_begin(UU(toku_io_instrumentation &io_instr),
+ UU(const toku_instr_key &key),
+ UU(toku_instr_file_op op),
+ UU(const char *name),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_stream_open_end(
+ UU(toku_io_instrumentation &io_instr),
+ UU(TOKU_FILE &file)) {}
+
+inline void toku_instr_file_open_end(UU(toku_io_instrumentation &io_instr),
+ UU(int fd)) {}
+
+inline void toku_instr_file_name_close_begin(
+ UU(toku_io_instrumentation &io_instr),
+ UU(const toku_instr_key &key),
+ UU(toku_instr_file_op op),
+ UU(const char *name),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_stream_close_begin(
+ UU(toku_io_instrumentation &io_instr),
+ UU(toku_instr_file_op op),
+ UU(TOKU_FILE &file),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_fd_close_begin(
+ UU(toku_io_instrumentation &io_instr),
+ UU(toku_instr_file_op op),
+ UU(int fd),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_close_end(UU(toku_io_instrumentation &io_instr),
+ UU(int result)) {}
+
+inline void toku_instr_file_io_begin(UU(toku_io_instrumentation &io_instr),
+ UU(toku_instr_file_op op),
+ UU(int fd),
+ UU(unsigned int count),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_name_io_begin(UU(toku_io_instrumentation &io_instr),
+ UU(const toku_instr_key &key),
+ UU(toku_instr_file_op op),
+ UU(const char *name),
+ UU(unsigned int count),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_stream_io_begin(
+ UU(toku_io_instrumentation &io_instr),
+ UU(toku_instr_file_op op),
+ UU(TOKU_FILE &file),
+ UU(unsigned int count),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_file_io_end(UU(toku_io_instrumentation &io_instr),
+ UU(unsigned int count)) {}
+
+struct toku_mutex_t;
+
+struct toku_mutex_instrumentation {};
+
+inline PSI_mutex *toku_instr_mutex_init(UU(const toku_instr_key &key),
+ UU(toku_mutex_t &mutex)) {
+ return nullptr;
+}
+
+inline void toku_instr_mutex_destroy(UU(PSI_mutex *&mutex_instr)) {}
+
+inline void toku_instr_mutex_lock_start(
+ UU(toku_mutex_instrumentation &mutex_instr),
+ UU(toku_mutex_t &mutex),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_mutex_trylock_start(
+ UU(toku_mutex_instrumentation &mutex_instr),
+ UU(toku_mutex_t &mutex),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_mutex_lock_end(
+ UU(toku_mutex_instrumentation &mutex_instr),
+ UU(int pthread_mutex_lock_result)) {}
+
+inline void toku_instr_mutex_unlock(UU(PSI_mutex *mutex_instr)) {}
+
+struct toku_cond_instrumentation {};
+
+enum class toku_instr_cond_op {
+ cond_wait,
+ cond_timedwait,
+};
+
+inline PSI_cond *toku_instr_cond_init(UU(const toku_instr_key &key),
+ UU(toku_cond_t &cond)) {
+ return nullptr;
+}
+
+inline void toku_instr_cond_destroy(UU(PSI_cond *&cond_instr)) {}
+
+inline void toku_instr_cond_wait_start(
+ UU(toku_cond_instrumentation &cond_instr),
+ UU(toku_instr_cond_op op),
+ UU(toku_cond_t &cond),
+ UU(toku_mutex_t &mutex),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_cond_wait_end(UU(toku_cond_instrumentation &cond_instr),
+ UU(int pthread_cond_wait_result)) {}
+
+inline void toku_instr_cond_signal(UU(toku_cond_t &cond)) {}
+
+inline void toku_instr_cond_broadcast(UU(toku_cond_t &cond)) {}
+
+// rwlock instrumentation
+struct toku_rwlock_instrumentation {};
+
+inline PSI_rwlock *toku_instr_rwlock_init(UU(const toku_instr_key &key),
+ UU(toku_pthread_rwlock_t &rwlock)) {
+ return nullptr;
+}
+
+inline void toku_instr_rwlock_destroy(UU(PSI_rwlock *&rwlock_instr)) {}
+
+inline void toku_instr_rwlock_rdlock_wait_start(
+ UU(toku_rwlock_instrumentation &rwlock_instr),
+ UU(toku_pthread_rwlock_t &rwlock),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_rwlock_wrlock_wait_start(
+ UU(toku_rwlock_instrumentation &rwlock_instr),
+ UU(toku_pthread_rwlock_t &rwlock),
+ UU(const char *src_file),
+ UU(int src_line)) {}
+
+inline void toku_instr_rwlock_rdlock_wait_end(
+ UU(toku_rwlock_instrumentation &rwlock_instr),
+ UU(int pthread_rwlock_wait_result)) {}
+
+inline void toku_instr_rwlock_wrlock_wait_end(
+ UU(toku_rwlock_instrumentation &rwlock_instr),
+ UU(int pthread_rwlock_wait_result)) {}
+
+inline void toku_instr_rwlock_unlock(UU(toku_pthread_rwlock_t &rwlock)) {}
+
+#else // MYSQL_TOKUDB_ENGINE
+// There can be not only mysql but also mongodb or any other PFS stuff
+#include <toku_instr_mysql.h>
+#endif // MYSQL_TOKUDB_ENGINE
+
+extern toku_instr_key toku_uninstrumented;
+
+extern toku_instr_probe *toku_instr_probe_1;
+
+// threads
+extern toku_instr_key *extractor_thread_key;
+extern toku_instr_key *fractal_thread_key;
+extern toku_instr_key *io_thread_key;
+extern toku_instr_key *eviction_thread_key;
+extern toku_instr_key *kibbutz_thread_key;
+extern toku_instr_key *minicron_thread_key;
+extern toku_instr_key *tp_internal_thread_key;
+
+// Files
+extern toku_instr_key *tokudb_file_data_key;
+extern toku_instr_key *tokudb_file_load_key;
+extern toku_instr_key *tokudb_file_tmp_key;
+extern toku_instr_key *tokudb_file_log_key;
+
+// Mutexes
+extern toku_instr_key *kibbutz_mutex_key;
+extern toku_instr_key *minicron_p_mutex_key;
+extern toku_instr_key *queue_result_mutex_key;
+extern toku_instr_key *tpool_lock_mutex_key;
+extern toku_instr_key *workset_lock_mutex_key;
+extern toku_instr_key *bjm_jobs_lock_mutex_key;
+extern toku_instr_key *log_internal_lock_mutex_key;
+extern toku_instr_key *cachetable_ev_thread_lock_mutex_key;
+extern toku_instr_key *cachetable_disk_nb_mutex_key;
+extern toku_instr_key *cachetable_m_mutex_key;
+extern toku_instr_key *safe_file_size_lock_mutex_key;
+extern toku_instr_key *checkpoint_safe_mutex_key;
+extern toku_instr_key *ft_ref_lock_mutex_key;
+extern toku_instr_key *loader_error_mutex_key;
+extern toku_instr_key *bfs_mutex_key;
+extern toku_instr_key *loader_bl_mutex_key;
+extern toku_instr_key *loader_fi_lock_mutex_key;
+extern toku_instr_key *loader_out_mutex_key;
+extern toku_instr_key *result_output_condition_lock_mutex_key;
+extern toku_instr_key *block_table_mutex_key;
+extern toku_instr_key *rollback_log_node_cache_mutex_key;
+extern toku_instr_key *txn_lock_mutex_key;
+extern toku_instr_key *txn_state_lock_mutex_key;
+extern toku_instr_key *txn_child_manager_mutex_key;
+extern toku_instr_key *txn_manager_lock_mutex_key;
+extern toku_instr_key *treenode_mutex_key;
+extern toku_instr_key *manager_mutex_key;
+extern toku_instr_key *manager_escalation_mutex_key;
+extern toku_instr_key *manager_escalator_mutex_key;
+extern toku_instr_key *db_txn_struct_i_txn_mutex_key;
+extern toku_instr_key *indexer_i_indexer_lock_mutex_key;
+extern toku_instr_key *indexer_i_indexer_estimate_lock_mutex_key;
+extern toku_instr_key *locktree_request_info_mutex_key;
+extern toku_instr_key *locktree_request_info_retry_mutex_key;
+
+// condition vars
+extern toku_instr_key *result_state_cond_key;
+extern toku_instr_key *bjm_jobs_wait_key;
+extern toku_instr_key *cachetable_p_refcount_wait_key;
+extern toku_instr_key *cachetable_m_flow_control_cond_key;
+extern toku_instr_key *cachetable_m_ev_thread_cond_key;
+extern toku_instr_key *bfs_cond_key;
+extern toku_instr_key *result_output_condition_key;
+extern toku_instr_key *manager_m_escalator_done_key;
+extern toku_instr_key *lock_request_m_wait_cond_key;
+extern toku_instr_key *queue_result_cond_key;
+extern toku_instr_key *ws_worker_wait_key;
+extern toku_instr_key *rwlock_wait_read_key;
+extern toku_instr_key *rwlock_wait_write_key;
+extern toku_instr_key *rwlock_cond_key;
+extern toku_instr_key *tp_thread_wait_key;
+extern toku_instr_key *tp_pool_wait_free_key;
+extern toku_instr_key *frwlock_m_wait_read_key;
+extern toku_instr_key *kibbutz_k_cond_key;
+extern toku_instr_key *minicron_p_condvar_key;
+extern toku_instr_key *locktree_request_info_retry_cv_key;
+
+// rwlocks
+extern toku_instr_key *multi_operation_lock_key;
+extern toku_instr_key *low_priority_multi_operation_lock_key;
+extern toku_instr_key *cachetable_m_list_lock_key;
+extern toku_instr_key *cachetable_m_pending_lock_expensive_key;
+extern toku_instr_key *cachetable_m_pending_lock_cheap_key;
+extern toku_instr_key *cachetable_m_lock_key;
+extern toku_instr_key *result_i_open_dbs_rwlock_key;
+extern toku_instr_key *checkpoint_safe_rwlock_key;
+extern toku_instr_key *cachetable_value_key;
+extern toku_instr_key *safe_file_size_lock_rwlock_key;
+extern toku_instr_key *cachetable_disk_nb_rwlock_key;
diff --git a/storage/tokudb/PerconaFT/portability/toku_os.h b/storage/tokudb/PerconaFT/portability/toku_os.h
index 3a0e7376971..d7cfcfefb9a 100644
--- a/storage/tokudb/PerconaFT/portability/toku_os.h
+++ b/storage/tokudb/PerconaFT/portability/toku_os.h
@@ -116,12 +116,10 @@ int toku_fsync_dir_by_name_without_accounting(const char *dir_name);
// *free_size is set to the bytes of free space in the file system
// *total_size is set to the total bytes in the file system
// Return 0 on success, otherwise an error number
-int toku_get_filesystem_sizes(const char *path, uint64_t *avail_size, uint64_t *free_size, uint64_t *total_size);
-
-// Portable linux 'stat'
-int toku_stat(const char *name, toku_struct_stat *statbuf) __attribute__((__visibility__("default")));
-// Portable linux 'fstat'
-int toku_fstat(int fd, toku_struct_stat *statbuf) __attribute__((__visibility__("default")));
+int toku_get_filesystem_sizes(const char *path,
+ uint64_t *avail_size,
+ uint64_t *free_size,
+ uint64_t *total_size);
// Portable linux 'dup2'
int toku_dup2(int fd, int fd2) __attribute__((__visibility__("default")));
diff --git a/storage/tokudb/PerconaFT/portability/toku_portability.h b/storage/tokudb/PerconaFT/portability/toku_portability.h
index 28ea8014f53..1096467a35d 100644
--- a/storage/tokudb/PerconaFT/portability/toku_portability.h
+++ b/storage/tokudb/PerconaFT/portability/toku_portability.h
@@ -125,6 +125,33 @@ typedef int64_t toku_off_t;
#define UU(x) x __attribute__((__unused__))
+// Branch prediction macros.
+// If supported by the compiler, will hint in inctruction caching for likely
+// branching. Should only be used where there is a very good idea of the correct
+// branch heuristics as determined by profiling. Mostly copied from InnoDB.
+// Use:
+// "if (FT_LIKELY(x))" where the chances of "x" evaluating true are higher
+// "if (FT_UNLIKELY(x))" where the chances of "x" evaluating false are higher
+#if defined(__GNUC__) && (__GNUC__ > 2) && !defined(__INTEL_COMPILER)
+
+// Tell the compiler that 'expr' probably evaluates to 'constant'.
+#define FT_EXPECT(expr, constant) __builtin_expect(expr, constant)
+
+#else
+
+#warning "No FT branch prediction operations in use!"
+#define FT_EXPECT(expr, constant) (expr)
+
+#endif // defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
+
+// Tell the compiler that cond is likely to hold
+#define FT_LIKELY(cond) FT_EXPECT(bool(cond), true)
+
+// Tell the compiler that cond is unlikely to hold
+#define FT_UNLIKELY(cond) FT_EXPECT(bool(cond), false)
+
+#include "toku_instrumentation.h"
+
#if defined(__cplusplus)
extern "C" {
#endif
@@ -240,28 +267,272 @@ void toku_os_full_write (int fd, const void *buf, size_t len) __attribute__((__v
// os_write returns 0 on success, otherwise an errno.
ssize_t toku_os_pwrite (int fd, const void *buf, size_t len, toku_off_t off) __attribute__((__visibility__("default")));
-int toku_os_write (int fd, const void *buf, size_t len) __attribute__((__visibility__("default")));
+int toku_os_write(int fd, const void *buf, size_t len)
+ __attribute__((__visibility__("default")));
// wrappers around file system calls
-FILE * toku_os_fdopen(int fildes, const char *mode);
-FILE * toku_os_fopen(const char *filename, const char *mode);
-int toku_os_open(const char *path, int oflag, int mode);
-int toku_os_open_direct(const char *path, int oflag, int mode);
-int toku_os_close(int fd);
-int toku_os_fclose(FILE * stream);
-int toku_os_rename(const char *old_name, const char *new_name);
-int toku_os_unlink(const char *path);
-ssize_t toku_os_read(int fd, void *buf, size_t count);
-ssize_t toku_os_pread(int fd, void *buf, size_t count, off_t offset);
void toku_os_recursive_delete(const char *path);
+TOKU_FILE *toku_os_fdopen_with_source_location(int fildes,
+ const char *mode,
+ const char *filename,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line);
+#define toku_os_fdopen(FD, M, FN, K) \
+ toku_os_fdopen_with_source_location(FD, M, FN, K, __FILE__, __LINE__)
+
+TOKU_FILE *toku_os_fopen_with_source_location(const char *filename,
+ const char *mode,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line);
+#define toku_os_fopen(F, M, K) \
+ toku_os_fopen_with_source_location(F, M, K, __FILE__, __LINE__)
+
+int toku_os_open_with_source_location(const char *path,
+ int oflag,
+ int mode,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line);
+#define toku_os_open(FD, F, M, K) \
+ toku_os_open_with_source_location(FD, F, M, K, __FILE__, __LINE__)
+
+int toku_os_open_direct(const char *path,
+ int oflag,
+ int mode,
+ const toku_instr_key &instr_key);
+
+int toku_os_delete_with_source_location(const char *name,
+ const char *src_file,
+ uint src_line);
+#define toku_os_delete(FN) \
+ toku_os_delete_with_source_location(FN, __FILE__, __LINE__)
+
+int toku_os_rename_with_source_location(const char *old_name,
+ const char *new_name,
+ const char *src_file,
+ uint src_line);
+#define toku_os_rename(old_name, new_name) \
+ toku_os_rename_with_source_location(old_name, new_name, __FILE__, __LINE__)
+
+void toku_os_full_write_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line);
+#define toku_os_full_write(FD, B, L) \
+ toku_os_full_write_with_source_location(FD, B, L, __FILE__, __LINE__)
+
+int toku_os_write_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line);
+#define toku_os_write(FD, B, L) \
+ toku_os_write_with_source_location(FD, B, L, __FILE__, __LINE__)
+
+void toku_os_full_pwrite_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line);
+#define toku_os_full_pwrite(FD, B, L, O) \
+ toku_os_full_pwrite_with_source_location(FD, B, L, O, __FILE__, __LINE__)
+
+ssize_t toku_os_pwrite_with_source_location(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line);
+
+#define toku_os_pwrite(FD, B, L, O) \
+ toku_os_pwrite_with_source_location(FD, B, L, O, __FILE__, __LINE__)
+
+int toku_os_fwrite_with_source_location(const void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+
+#define toku_os_fwrite(P, S, N, FS) \
+ toku_os_fwrite_with_source_location(P, S, N, FS, __FILE__, __LINE__)
+
+int toku_os_fread_with_source_location(void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+#define toku_os_fread(P, S, N, FS) \
+ toku_os_fread_with_source_location(P, S, N, FS, __FILE__, __LINE__)
+
+TOKU_FILE *toku_os_fopen_with_source_location(const char *filename,
+ const char *mode,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line);
+
+int toku_os_fclose_with_source_location(TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+
+#define toku_os_fclose(FS) \
+ toku_os_fclose_with_source_location(FS, __FILE__, __LINE__)
+
+int toku_os_close_with_source_location(int fd,
+ const char *src_file,
+ uint src_line);
+#define toku_os_close(FD) \
+ toku_os_close_with_source_location(FD, __FILE__, __LINE__)
+
+ssize_t toku_os_read_with_source_location(int fd,
+ void *buf,
+ size_t count,
+ const char *src_file,
+ uint src_line);
+
+#define toku_os_read(FD, B, C) \
+ toku_os_read_with_source_location(FD, B, C, __FILE__, __LINE__);
+
+ssize_t inline_toku_os_pread_with_source_location(int fd,
+ void *buf,
+ size_t count,
+ off_t offset,
+ const char *src_file,
+ uint src_line);
+#define toku_os_pread(FD, B, C, O) \
+ inline_toku_os_pread_with_source_location(FD, B, C, O, __FILE__, __LINE__);
+
+void file_fsync_internal_with_source_location(int fd,
+ const char *src_file,
+ uint src_line);
+
+#define file_fsync_internal(FD) \
+ file_fsync_internal_with_source_location(FD, __FILE__, __LINE__);
+
+int toku_os_get_file_size_with_source_location(int fildes,
+ int64_t *fsize,
+ const char *src_file,
+ uint src_line);
+
+#define toku_os_get_file_size(D, S) \
+ toku_os_get_file_size_with_source_location(D, S, __FILE__, __LINE__)
+
+// TODO: should this prototype be moved to toku_os.h?
+int toku_stat_with_source_location(const char *name,
+ toku_struct_stat *buf,
+ const toku_instr_key &instr_key,
+ const char *src_file,
+ uint src_line)
+ __attribute__((__visibility__("default")));
+
+#define toku_stat(N, B, K) \
+ toku_stat_with_source_location(N, B, K, __FILE__, __LINE__)
+
+int toku_os_fstat_with_source_location(int fd,
+ toku_struct_stat *buf,
+ const char *src_file,
+ uint src_line)
+ __attribute__((__visibility__("default")));
+
+#define toku_os_fstat(FD, B) \
+ toku_os_fstat_with_source_location(FD, B, __FILE__, __LINE__)
+
+#ifdef HAVE_PSI_FILE_INTERFACE2
+int inline_toku_os_close(int fd, const char *src_file, uint src_line);
+int inline_toku_os_fclose(TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+ssize_t inline_toku_os_read(int fd,
+ void *buf,
+ size_t count,
+ const char *src_file,
+ uint src_line);
+ssize_t inline_toku_os_pread(int fd,
+ void *buf,
+ size_t count,
+ off_t offset,
+ const char *src_file,
+ uint src_line);
+int inline_toku_os_fwrite(const void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+int inline_toku_os_fread(void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream,
+ const char *src_file,
+ uint src_line);
+int inline_toku_os_write(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line);
+ssize_t inline_toku_os_pwrite(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line);
+void inline_toku_os_full_write(int fd,
+ const void *buf,
+ size_t len,
+ const char *src_file,
+ uint src_line);
+void inline_toku_os_full_pwrite(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off,
+ const char *src_file,
+ uint src_line);
+int inline_toku_os_delete(const char *name,
+ const char *srv_file,
+ uint src_line);
+//#else
+int inline_toku_os_close(int fd);
+int inline_toku_os_fclose(TOKU_FILE *stream);
+ssize_t inline_toku_os_read(int fd, void *buf, size_t count);
+ssize_t inline_toku_os_pread(int fd, void *buf, size_t count, off_t offset);
+int inline_toku_os_fwrite(const void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream);
+int inline_toku_os_fread(void *ptr,
+ size_t size,
+ size_t nmemb,
+ TOKU_FILE *stream);
+int inline_toku_os_write(int fd, const void *buf, size_t len);
+ssize_t inline_toku_os_pwrite(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off);
+void inline_toku_os_full_write(int fd, const void *buf, size_t len);
+void inline_toku_os_full_pwrite(int fd,
+ const void *buf,
+ size_t len,
+ toku_off_t off);
+int inline_toku_os_delete(const char *name);
+#endif
+
// wrapper around fsync
-void toku_file_fsync_without_accounting(int fd);
void toku_file_fsync(int fd);
int toku_fsync_directory(const char *fname);
+void toku_file_fsync_without_accounting(int fd);
// get the number of fsync calls and the fsync times (total)
-void toku_get_fsync_times(uint64_t *fsync_count, uint64_t *fsync_time, uint64_t *long_fsync_threshold, uint64_t *long_fsync_count, uint64_t *long_fsync_time);
+void toku_get_fsync_times(uint64_t *fsync_count,
+ uint64_t *fsync_time,
+ uint64_t *long_fsync_threshold,
+ uint64_t *long_fsync_count,
+ uint64_t *long_fsync_time);
void toku_set_func_fsync (int (*fsync_function)(int));
void toku_set_func_pwrite (ssize_t (*)(int, const void *, size_t, toku_off_t));
@@ -271,9 +542,11 @@ void toku_set_func_full_write (ssize_t (*)(int, const void *, size_t));
void toku_set_func_fdopen (FILE * (*)(int, const char *));
void toku_set_func_fopen (FILE * (*)(const char *, const char *));
void toku_set_func_open (int (*)(const char *, int, int));
-void toku_set_func_fclose(int (*)(FILE*));
+void toku_set_func_fclose(int (*)(FILE *));
void toku_set_func_read(ssize_t (*)(int, void *, size_t));
-void toku_set_func_pread (ssize_t (*)(int, void *, size_t, off_t));
+void toku_set_func_pread(ssize_t (*)(int, void *, size_t, off_t));
+void toku_set_func_fwrite(
+ size_t (*fwrite_fun)(const void *, size_t, size_t, FILE *));
int toku_portability_init(void);
void toku_portability_destroy(void);
@@ -283,28 +556,3 @@ void toku_portability_destroy(void);
static inline uint64_t roundup_to_multiple(uint64_t alignment, uint64_t v) {
return (v + alignment - 1) & ~(alignment - 1);
}
-
-// Branch prediction macros.
-// If supported by the compiler, will hint in inctruction caching for likely
-// branching. Should only be used where there is a very good idea of the correct
-// branch heuristics as determined by profiling. Mostly copied from InnoDB.
-// Use:
-// "if (FT_LIKELY(x))" where the chances of "x" evaluating true are higher
-// "if (FT_UNLIKELY(x))" where the chances of "x" evaluating false are higher
-#if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
-
-// Tell the compiler that 'expr' probably evaluates to 'constant'.
-#define FT_EXPECT(expr,constant) __builtin_expect(expr, constant)
-
-#else
-
-#warning "No FT branch prediction operations in use!"
-#define FT_EXPECT(expr,constant) (expr)
-
-#endif // defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
-
-// Tell the compiler that cond is likely to hold
-#define FT_LIKELY(cond) FT_EXPECT(cond, 1)
-
-// Tell the compiler that cond is unlikely to hold
-#define FT_UNLIKELY(cond) FT_EXPECT(cond, 0)
diff --git a/storage/tokudb/PerconaFT/portability/toku_pthread.h b/storage/tokudb/PerconaFT/portability/toku_pthread.h
index 84c27736201..44de01244d2 100644
--- a/storage/tokudb/PerconaFT/portability/toku_pthread.h
+++ b/storage/tokudb/PerconaFT/portability/toku_pthread.h
@@ -42,31 +42,62 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <time.h>
#include <stdint.h>
+#include "toku_portability.h"
#include "toku_assert.h"
+// TODO: some things moved toku_instrumentation.h, not necessarily the best
+// place
typedef pthread_attr_t toku_pthread_attr_t;
typedef pthread_t toku_pthread_t;
-typedef pthread_mutexattr_t toku_pthread_mutexattr_t;
typedef pthread_mutex_t toku_pthread_mutex_t;
typedef pthread_condattr_t toku_pthread_condattr_t;
typedef pthread_cond_t toku_pthread_cond_t;
-typedef pthread_rwlock_t toku_pthread_rwlock_t;
-typedef pthread_rwlockattr_t toku_pthread_rwlockattr_t;
+typedef pthread_rwlockattr_t toku_pthread_rwlockattr_t;
typedef pthread_key_t toku_pthread_key_t;
typedef struct timespec toku_timespec_t;
-#ifndef TOKU_PTHREAD_DEBUG
-# define TOKU_PTHREAD_DEBUG 0
-#endif
+// TODO: break this include loop
+#include <pthread.h>
+typedef pthread_mutexattr_t toku_pthread_mutexattr_t;
-typedef struct toku_mutex {
+struct toku_mutex_t {
pthread_mutex_t pmutex;
+ struct PSI_mutex
+ *psi_mutex; /* The performance schema instrumentation hook */
#if TOKU_PTHREAD_DEBUG
- pthread_t owner; // = pthread_self(); // for debugging
+ pthread_t owner; // = pthread_self(); // for debugging
bool locked;
bool valid;
+ pfs_key_t instr_key_id;
+#endif
+};
+
+struct toku_cond_t {
+ pthread_cond_t pcond;
+ struct PSI_cond *psi_cond;
+#if TOKU_PTHREAD_DEBUG
+ pfs_key_t instr_key_id;
+#endif
+};
+
+#ifdef TOKU_PTHREAD_DEBUG
+#define TOKU_COND_INITIALIZER \
+ { \
+ .pcond = PTHREAD_COND_INITIALIZER, .psi_cond = nullptr, \
+ .instr_key_id = 0 \
+ }
+#else
+#define TOKU_COND_INITIALIZER \
+ { .pcond = PTHREAD_COND_INITIALIZER, .psi_cond = nullptr }
#endif
-} toku_mutex_t;
+
+struct toku_pthread_rwlock_t {
+ pthread_rwlock_t rwlock;
+ struct PSI_rwlock *psi_rwlock;
+#if TOKU_PTHREAD_DEBUG
+ pfs_key_t instr_key_id;
+#endif
+};
typedef struct toku_mutex_aligned {
toku_mutex_t aligned_mutex __attribute__((__aligned__(64)));
@@ -83,45 +114,68 @@ typedef struct toku_mutex_aligned {
// In general it will be a lot of busy work to make this codebase compile
// cleanly with -Wmissing-field-initializers
-# define ZERO_MUTEX_INITIALIZER {}
+#define ZERO_MUTEX_INITIALIZER \
+ {}
#if TOKU_PTHREAD_DEBUG
-# define TOKU_MUTEX_INITIALIZER { .pmutex = PTHREAD_MUTEX_INITIALIZER, .owner = 0, .locked = false, .valid = true }
+#define TOKU_MUTEX_INITIALIZER \
+ { \
+ .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr, .owner = 0, \
+ .locked = false, .valid = true, .instr_key_id = 0 \
+ }
#else
-# define TOKU_MUTEX_INITIALIZER { .pmutex = PTHREAD_MUTEX_INITIALIZER }
+#define TOKU_MUTEX_INITIALIZER \
+ { .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr }
#endif
// Darwin doesn't provide adaptive mutexes
#if defined(__APPLE__)
-# define TOKU_MUTEX_ADAPTIVE PTHREAD_MUTEX_DEFAULT
-# if TOKU_PTHREAD_DEBUG
-# define TOKU_ADAPTIVE_MUTEX_INITIALIZER { .pmutex = PTHREAD_MUTEX_INITIALIZER, .owner = 0, .locked = false, .valid = true }
-# else
-# define TOKU_ADAPTIVE_MUTEX_INITIALIZER { .pmutex = PTHREAD_MUTEX_INITIALIZER }
-# endif
-#else // __FreeBSD__, __linux__, at least
-# define TOKU_MUTEX_ADAPTIVE PTHREAD_MUTEX_ADAPTIVE_NP
-# if TOKU_PTHREAD_DEBUG
-# define TOKU_ADAPTIVE_MUTEX_INITIALIZER { .pmutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, .owner = 0, .locked = false, .valid = true }
-# else
-# define TOKU_ADAPTIVE_MUTEX_INITIALIZER { .pmutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP }
-# endif
+#define TOKU_MUTEX_ADAPTIVE PTHREAD_MUTEX_DEFAULT
+#if TOKU_PTHREAD_DEBUG
+#define TOKU_ADAPTIVE_MUTEX_INITIALIZER \
+ { \
+ .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr, .owner = 0, \
+ .locked = false, .valid = true, .instr_key_id = 0 \
+ }
+#else
+#define TOKU_ADAPTIVE_MUTEX_INITIALIZER \
+ { .pmutex = PTHREAD_MUTEX_INITIALIZER, .psi_mutex = nullptr }
#endif
-
-static inline void
-toku_mutex_init(toku_mutex_t *mutex, const toku_pthread_mutexattr_t *attr) {
- int r = pthread_mutex_init(&mutex->pmutex, attr);
- assert_zero(r);
+#else // __FreeBSD__, __linux__, at least
+#define TOKU_MUTEX_ADAPTIVE PTHREAD_MUTEX_ADAPTIVE_NP
#if TOKU_PTHREAD_DEBUG
- mutex->locked = false;
- invariant(!mutex->valid);
- mutex->valid = true;
- mutex->owner = 0;
+#define TOKU_ADAPTIVE_MUTEX_INITIALIZER \
+ { \
+ .pmutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, .psi_mutex = nullptr, \
+ .owner = 0, .locked = false, .valid = true, .instr_key_id = 0 \
+ }
+#else
+#define TOKU_ADAPTIVE_MUTEX_INITIALIZER \
+ { .pmutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, .psi_mutex = nullptr }
+#endif
#endif
-}
-static inline void
-toku_mutexattr_init(toku_pthread_mutexattr_t *attr) {
+// Different OSes implement mutexes as different amounts of nested structs.
+// C++ will fill out all missing values with zeroes if you provide at least one
+// zero, but it needs the right amount of nesting.
+#if defined(__FreeBSD__)
+#define ZERO_COND_INITIALIZER \
+ { 0 }
+#elif defined(__APPLE__)
+#define ZERO_COND_INITIALIZER \
+ { \
+ { 0 } \
+ }
+#else // __linux__, at least
+#define ZERO_COND_INITIALIZER \
+ { \
+ { \
+ { 0 } \
+ } \
+ }
+#endif
+
+static inline void toku_mutexattr_init(toku_pthread_mutexattr_t *attr) {
int r = pthread_mutexattr_init(attr);
assert_zero(r);
}
@@ -138,61 +192,8 @@ toku_mutexattr_destroy(toku_pthread_mutexattr_t *attr) {
assert_zero(r);
}
-static inline void
-toku_mutex_destroy(toku_mutex_t *mutex) {
#if TOKU_PTHREAD_DEBUG
- invariant(mutex->valid);
- mutex->valid = false;
- invariant(!mutex->locked);
-#endif
- int r = pthread_mutex_destroy(&mutex->pmutex);
- assert_zero(r);
-}
-
-static inline void
-toku_mutex_lock(toku_mutex_t *mutex) {
- int r = pthread_mutex_lock(&mutex->pmutex);
- assert_zero(r);
-#if TOKU_PTHREAD_DEBUG
- invariant(mutex->valid);
- invariant(!mutex->locked);
- invariant(mutex->owner == 0);
- mutex->locked = true;
- mutex->owner = pthread_self();
-#endif
-}
-
-static inline int
-toku_mutex_trylock(toku_mutex_t *mutex) {
- int r = pthread_mutex_trylock(&mutex->pmutex);
-#if TOKU_PTHREAD_DEBUG
- if (r == 0) {
- invariant(mutex->valid);
- invariant(!mutex->locked);
- invariant(mutex->owner == 0);
- mutex->locked = true;
- mutex->owner = pthread_self();
- }
-#endif
- return r;
-}
-
-static inline void
-toku_mutex_unlock(toku_mutex_t *mutex) {
-#if TOKU_PTHREAD_DEBUG
- invariant(mutex->owner == pthread_self());
- invariant(mutex->valid);
- invariant(mutex->locked);
- mutex->locked = false;
- mutex->owner = 0;
-#endif
- int r = pthread_mutex_unlock(&mutex->pmutex);
- assert_zero(r);
-}
-
-#if TOKU_PTHREAD_DEBUG
-static inline void
-toku_mutex_assert_locked(const toku_mutex_t *mutex) {
+static inline void toku_mutex_assert_locked(const toku_mutex_t *mutex) {
invariant(mutex->locked);
invariant(mutex->owner == pthread_self());
}
@@ -217,40 +218,123 @@ toku_mutex_assert_unlocked(toku_mutex_t *mutex) {
invariant(!mutex->locked);
}
#else
-static inline void
-toku_mutex_assert_unlocked(toku_mutex_t *mutex __attribute__((unused))) {
+static inline void toku_mutex_assert_unlocked(toku_mutex_t *mutex
+ __attribute__((unused))) {}
+#endif
+
+#define toku_mutex_lock(M) \
+ toku_mutex_lock_with_source_location(M, __FILE__, __LINE__)
+
+static inline void toku_cond_init(toku_cond_t *cond,
+ const toku_pthread_condattr_t *attr) {
+ int r = pthread_cond_init(&cond->pcond, attr);
+ assert_zero(r);
+}
+
+#define toku_mutex_trylock(M) \
+ toku_mutex_trylock_with_source_location(M, __FILE__, __LINE__)
+
+inline void toku_mutex_unlock(toku_mutex_t *mutex) {
+#if TOKU_PTHREAD_DEBUG
+ invariant(mutex->owner == pthread_self());
+ invariant(mutex->valid);
+ invariant(mutex->locked);
+ mutex->locked = false;
+ mutex->owner = 0;
+#endif
+ toku_instr_mutex_unlock(mutex->psi_mutex);
+ int r = pthread_mutex_unlock(&mutex->pmutex);
+ assert_zero(r);
}
+
+inline void toku_mutex_lock_with_source_location(toku_mutex_t *mutex,
+ const char *src_file,
+ int src_line) {
+
+ toku_mutex_instrumentation mutex_instr;
+ toku_instr_mutex_lock_start(mutex_instr, *mutex, src_file, src_line);
+
+ const int r = pthread_mutex_lock(&mutex->pmutex);
+ toku_instr_mutex_lock_end(mutex_instr, r);
+
+ assert_zero(r);
+#if TOKU_PTHREAD_DEBUG
+ invariant(mutex->valid);
+ invariant(!mutex->locked);
+ invariant(mutex->owner == 0);
+ mutex->locked = true;
+ mutex->owner = pthread_self();
#endif
+}
-typedef struct toku_cond {
- pthread_cond_t pcond;
-} toku_cond_t;
+inline int toku_mutex_trylock_with_source_location(toku_mutex_t *mutex,
+ const char *src_file,
+ int src_line) {
-// Same considerations as for ZERO_MUTEX_INITIALIZER apply
-#define ZERO_COND_INITIALIZER {}
+ toku_mutex_instrumentation mutex_instr;
+ toku_instr_mutex_trylock_start(mutex_instr, *mutex, src_file, src_line);
-#define TOKU_COND_INITIALIZER {PTHREAD_COND_INITIALIZER}
+ const int r = pthread_mutex_lock(&mutex->pmutex);
+ toku_instr_mutex_lock_end(mutex_instr, r);
-static inline void
-toku_cond_init(toku_cond_t *cond, const toku_pthread_condattr_t *attr) {
+#if TOKU_PTHREAD_DEBUG
+ if (r == 0) {
+ invariant(mutex->valid);
+ invariant(!mutex->locked);
+ invariant(mutex->owner == 0);
+ mutex->locked = true;
+ mutex->owner = pthread_self();
+ }
+#endif
+ return r;
+}
+
+#define toku_cond_wait(C, M) \
+ toku_cond_wait_with_source_location(C, M, __FILE__, __LINE__)
+
+#define toku_cond_timedwait(C, M, W) \
+ toku_cond_timedwait_with_source_location(C, M, W, __FILE__, __LINE__)
+
+inline void toku_cond_init(const toku_instr_key &key,
+ toku_cond_t *cond,
+ const pthread_condattr_t *attr) {
+ toku_instr_cond_init(key, *cond);
int r = pthread_cond_init(&cond->pcond, attr);
assert_zero(r);
}
-static inline void
-toku_cond_destroy(toku_cond_t *cond) {
+inline void toku_cond_destroy(toku_cond_t *cond) {
+ toku_instr_cond_destroy(cond->psi_cond);
int r = pthread_cond_destroy(&cond->pcond);
assert_zero(r);
}
-static inline void
-toku_cond_wait(toku_cond_t *cond, toku_mutex_t *mutex) {
+inline void toku_cond_wait_with_source_location(toku_cond_t *cond,
+ toku_mutex_t *mutex,
+ const char *src_file,
+ uint src_line) {
+
#if TOKU_PTHREAD_DEBUG
invariant(mutex->locked);
mutex->locked = false;
mutex->owner = 0;
#endif
- int r = pthread_cond_wait(&cond->pcond, &mutex->pmutex);
+
+ /* Instrumentation start */
+ toku_cond_instrumentation cond_instr;
+ toku_instr_cond_wait_start(cond_instr,
+ toku_instr_cond_op::cond_wait,
+ *cond,
+ *mutex,
+ src_file,
+ src_line);
+
+ /* Instrumented code */
+ const int r = pthread_cond_wait(&cond->pcond, &mutex->pmutex);
+
+ /* Instrumentation end */
+ toku_instr_cond_wait_end(cond_instr, r);
+
assert_zero(r);
#if TOKU_PTHREAD_DEBUG
invariant(!mutex->locked);
@@ -259,14 +343,33 @@ toku_cond_wait(toku_cond_t *cond, toku_mutex_t *mutex) {
#endif
}
-static inline int
-toku_cond_timedwait(toku_cond_t *cond, toku_mutex_t *mutex, toku_timespec_t *wakeup_at) {
+inline int toku_cond_timedwait_with_source_location(toku_cond_t *cond,
+ toku_mutex_t *mutex,
+ toku_timespec_t *wakeup_at,
+ const char *src_file,
+ uint src_line) {
#if TOKU_PTHREAD_DEBUG
invariant(mutex->locked);
mutex->locked = false;
mutex->owner = 0;
#endif
- int r = pthread_cond_timedwait(&cond->pcond, &mutex->pmutex, wakeup_at);
+
+ /* Instrumentation start */
+ toku_cond_instrumentation cond_instr;
+ toku_instr_cond_wait_start(cond_instr,
+ toku_instr_cond_op::cond_timedwait,
+ *cond,
+ *mutex,
+ src_file,
+ src_line);
+
+ /* Instrumented code */
+ const int r = pthread_cond_timedwait(
+ &cond->pcond, &mutex->pmutex, wakeup_at);
+
+ /* Instrumentation end */
+ toku_instr_cond_wait_end(cond_instr, r);
+
#if TOKU_PTHREAD_DEBUG
invariant(!mutex->locked);
mutex->locked = true;
@@ -275,69 +378,116 @@ toku_cond_timedwait(toku_cond_t *cond, toku_mutex_t *mutex, toku_timespec_t *wak
return r;
}
-static inline void
-toku_cond_signal(toku_cond_t *cond) {
- int r = pthread_cond_signal(&cond->pcond);
+inline void toku_cond_signal(toku_cond_t *cond) {
+ toku_instr_cond_signal(*cond);
+ const int r = pthread_cond_signal(&cond->pcond);
assert_zero(r);
}
-static inline void
-toku_cond_broadcast(toku_cond_t *cond) {
- int r =pthread_cond_broadcast(&cond->pcond);
+inline void toku_cond_broadcast(toku_cond_t *cond) {
+ toku_instr_cond_broadcast(*cond);
+ const int r = pthread_cond_broadcast(&cond->pcond);
assert_zero(r);
}
-int
-toku_pthread_yield(void) __attribute__((__visibility__("default")));
-
-static inline toku_pthread_t
-toku_pthread_self(void) {
- return pthread_self();
+inline void toku_mutex_init(const toku_instr_key &key,
+ toku_mutex_t *mutex,
+ const toku_pthread_mutexattr_t *attr) {
+#if TOKU_PTHREAD_DEBUG
+ mutex->valid = true;
+#endif
+ toku_instr_mutex_init(key, *mutex);
+ const int r = pthread_mutex_init(&mutex->pmutex, attr);
+ assert_zero(r);
+#if TOKU_PTHREAD_DEBUG
+ mutex->locked = false;
+ invariant(mutex->valid);
+ mutex->valid = true;
+ mutex->owner = 0;
+#endif
}
-static inline void
-toku_pthread_rwlock_init(toku_pthread_rwlock_t *__restrict rwlock, const toku_pthread_rwlockattr_t *__restrict attr) {
- int r = pthread_rwlock_init(rwlock, attr);
+inline void toku_mutex_destroy(toku_mutex_t *mutex) {
+#if TOKU_PTHREAD_DEBUG
+ invariant(mutex->valid);
+ mutex->valid = false;
+ invariant(!mutex->locked);
+#endif
+ toku_instr_mutex_destroy(mutex->psi_mutex);
+ int r = pthread_mutex_destroy(&mutex->pmutex);
assert_zero(r);
}
-static inline void
-toku_pthread_rwlock_destroy(toku_pthread_rwlock_t *rwlock) {
- int r = pthread_rwlock_destroy(rwlock);
+#define toku_pthread_rwlock_rdlock(RW) \
+ toku_pthread_rwlock_rdlock_with_source_location(RW, __FILE__, __LINE__)
+
+#define toku_pthread_rwlock_wrlock(RW) \
+ toku_pthread_rwlock_wrlock_with_source_location(RW, __FILE__, __LINE__)
+
+inline void toku_pthread_rwlock_init(
+ const toku_instr_key &key,
+ toku_pthread_rwlock_t *__restrict rwlock,
+ const toku_pthread_rwlockattr_t *__restrict attr) {
+ toku_instr_rwlock_init(key, *rwlock);
+ int r = pthread_rwlock_init(&rwlock->rwlock, attr);
assert_zero(r);
}
-static inline void
-toku_pthread_rwlock_rdlock(toku_pthread_rwlock_t *rwlock) {
- int r = pthread_rwlock_rdlock(rwlock);
+inline void toku_pthread_rwlock_destroy(toku_pthread_rwlock_t *rwlock) {
+ toku_instr_rwlock_destroy(rwlock->psi_rwlock);
+ int r = pthread_rwlock_destroy(&rwlock->rwlock);
assert_zero(r);
}
-static inline void
-toku_pthread_rwlock_rdunlock(toku_pthread_rwlock_t *rwlock) {
- int r = pthread_rwlock_unlock(rwlock);
+inline void toku_pthread_rwlock_rdlock_with_source_location(
+ toku_pthread_rwlock_t *rwlock,
+ const char *src_file,
+ uint src_line) {
+
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ toku_instr_rwlock_rdlock_wait_start(
+ rwlock_instr, *rwlock, src_file, src_line);
+ /* Instrumented code */
+ const int r = pthread_rwlock_rdlock(&rwlock->rwlock);
+
+ /* Instrumentation end */
+ toku_instr_rwlock_rdlock_wait_end(rwlock_instr, r);
+
assert_zero(r);
}
-static inline void
-toku_pthread_rwlock_wrlock(toku_pthread_rwlock_t *rwlock) {
- int r = pthread_rwlock_wrlock(rwlock);
+inline void toku_pthread_rwlock_wrlock_with_source_location(
+ toku_pthread_rwlock_t *rwlock,
+ const char *src_file,
+ uint src_line) {
+
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ toku_instr_rwlock_wrlock_wait_start(
+ rwlock_instr, *rwlock, src_file, src_line);
+ /* Instrumented code */
+ const int r = pthread_rwlock_wrlock(&rwlock->rwlock);
+
+ /* Instrumentation end */
+ toku_instr_rwlock_wrlock_wait_end(rwlock_instr, r);
+
assert_zero(r);
}
-static inline void
-toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) {
- int r = pthread_rwlock_unlock(rwlock);
+inline void toku_pthread_rwlock_rdunlock(toku_pthread_rwlock_t *rwlock) {
+ toku_instr_rwlock_unlock(*rwlock);
+ const int r = pthread_rwlock_unlock(&rwlock->rwlock);
assert_zero(r);
}
-static inline int
-toku_pthread_create(toku_pthread_t *thread, const toku_pthread_attr_t *attr, void *(*start_function)(void *), void *arg) {
- return pthread_create(thread, attr, start_function, arg);
+inline void toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) {
+ toku_instr_rwlock_unlock(*rwlock);
+ const int r = pthread_rwlock_unlock(&rwlock->rwlock);
+ assert_zero(r);
}
-static inline int
-toku_pthread_join(toku_pthread_t thread, void **value_ptr) {
+static inline int toku_pthread_join(toku_pthread_t thread, void **value_ptr) {
return pthread_join(thread, value_ptr);
}
@@ -361,7 +511,15 @@ toku_pthread_getspecific(toku_pthread_key_t key) {
return pthread_getspecific(key);
}
-static inline int
-toku_pthread_setspecific(toku_pthread_key_t key, void *data) {
+static inline int toku_pthread_setspecific(toku_pthread_key_t key, void *data) {
return pthread_setspecific(key, data);
}
+
+int toku_pthread_yield(void) __attribute__((__visibility__("default")));
+
+static inline toku_pthread_t toku_pthread_self(void) { return pthread_self(); }
+
+static inline void *toku_pthread_done(void *exit_value) {
+ toku_instr_delete_current_thread();
+ pthread_exit(exit_value);
+}
diff --git a/storage/tokudb/PerconaFT/src/indexer-undo-do.cc b/storage/tokudb/PerconaFT/src/indexer-undo-do.cc
index 4c7f5336161..cc86402751b 100644
--- a/storage/tokudb/PerconaFT/src/indexer-undo-do.cc
+++ b/storage/tokudb/PerconaFT/src/indexer-undo-do.cc
@@ -571,6 +571,7 @@ indexer_ft_delete_committed(DB_INDEXER *indexer, DB *hotdb, DBT *hotkey, XIDS xi
oldest_referenced_xid_estimate,
true);
toku_ft_send_delete(db_struct_i(hotdb)->ft_handle, hotkey, xids, &gc_info);
+ toku_ft_adjust_logical_row_count(db_struct_i(hotdb)->ft_handle->ft, -1);
}
}
return result;
@@ -616,6 +617,7 @@ indexer_ft_insert_committed(DB_INDEXER *indexer, DB *hotdb, DBT *hotkey, DBT *ho
oldest_referenced_xid_estimate,
true);
toku_ft_send_insert(db_struct_i(hotdb)->ft_handle, hotkey, hotval, xids, FT_INSERT, &gc_info);
+ toku_ft_adjust_logical_row_count(db_struct_i(hotdb)->ft_handle->ft, 1);
}
}
return result;
diff --git a/storage/tokudb/PerconaFT/src/indexer.cc b/storage/tokudb/PerconaFT/src/indexer.cc
index b475b08beb5..044ffac917c 100644
--- a/storage/tokudb/PerconaFT/src/indexer.cc
+++ b/storage/tokudb/PerconaFT/src/indexer.cc
@@ -253,16 +253,21 @@ toku_indexer_create_indexer(DB_ENV *env,
indexer->set_error_callback = toku_indexer_set_error_callback;
indexer->set_poll_function = toku_indexer_set_poll_function;
indexer->build = build_index;
- indexer->close = close_indexer;
- indexer->abort = abort_indexer;
-
- toku_mutex_init(&indexer->i->indexer_lock, NULL);
- toku_mutex_init(&indexer->i->indexer_estimate_lock, NULL);
+ indexer->close = close_indexer;
+ indexer->abort = abort_indexer;
+
+ toku_mutex_init(
+ *indexer_i_indexer_lock_mutex_key, &indexer->i->indexer_lock, nullptr);
+ toku_mutex_init(*indexer_i_indexer_estimate_lock_mutex_key,
+ &indexer->i->indexer_estimate_lock,
+ nullptr);
toku_init_dbt(&indexer->i->position_estimate);
//
- // create and close a dummy loader to get redirection going for the hot indexer
- // This way, if the hot index aborts, but other transactions have references to the
+ // create and close a dummy loader to get redirection going for the hot
+ // indexer
+ // This way, if the hot index aborts, but other transactions have references
+ // to the
// underlying FT, then those transactions can do dummy operations on the FT
// while the DB gets redirected back to an empty dictionary
//
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-first-empty.cc b/storage/tokudb/PerconaFT/src/tests/blocking-first-empty.cc
index d9d865254f1..3b53911e614 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-first-empty.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-first-empty.cc
@@ -99,12 +99,14 @@ static void *blocking_first_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_first_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_first_thread, &a); assert(r == 0);
+ struct blocking_first_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_first_thread, &a);
+ assert(r == 0);
}
blocking_first(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-first.cc b/storage/tokudb/PerconaFT/src/tests/blocking-first.cc
index 9f3f8f4eb6a..c104eabd6c3 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-first.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-first.cc
@@ -116,12 +116,14 @@ static void *blocking_first_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_first_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_first_thread, &a); assert(r == 0);
+ struct blocking_first_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_first_thread, &a);
+ assert(r == 0);
}
blocking_first(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-last.cc b/storage/tokudb/PerconaFT/src/tests/blocking-last.cc
index a62d83eb46f..3a702e3f115 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-last.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-last.cc
@@ -116,12 +116,14 @@ static void *blocking_last_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_last_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_last_thread, &a); assert(r == 0);
+ struct blocking_last_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_last_thread, &a);
+ assert(r == 0);
}
blocking_last(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-next-prev-deadlock.cc b/storage/tokudb/PerconaFT/src/tests/blocking-next-prev-deadlock.cc
index bd5697ba526..781708cc627 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-next-prev-deadlock.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-next-prev-deadlock.cc
@@ -181,12 +181,14 @@ static void *blocking_next_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_next_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_next_thread, &a); assert(r == 0);
+ struct blocking_next_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_next_thread, &a);
+ assert(r == 0);
}
blocking_prev(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-next-prev.cc b/storage/tokudb/PerconaFT/src/tests/blocking-next-prev.cc
index 729473bb7cf..aa179e88d76 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-next-prev.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-next-prev.cc
@@ -188,12 +188,14 @@ static void *blocking_next_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_next_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_next_thread, &a); assert(r == 0);
+ struct blocking_next_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_next_thread, &a);
+ assert(r == 0);
}
blocking_prev(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-prelock-range.cc b/storage/tokudb/PerconaFT/src/tests/blocking-prelock-range.cc
index 8821b39aa8a..38875a2f8ec 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-prelock-range.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-prelock-range.cc
@@ -140,12 +140,17 @@ int test_main(int argc, char * const argv[]) {
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
toku_pthread_t tids[nthreads];
- struct blocking_range_lock_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_range_lock_thread, &a); assert(r == 0);
+ struct blocking_range_lock_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(toku_uninstrumented,
+ &tids[i],
+ nullptr,
+ blocking_range_lock_thread,
+ &a);
+ assert(r == 0);
}
blocking_range_lock(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-put-timeout.cc b/storage/tokudb/PerconaFT/src/tests/blocking-put-timeout.cc
index a31e173fd83..bf4a8a24f47 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-put-timeout.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-put-timeout.cc
@@ -57,8 +57,8 @@ struct test_seq {
static void test_seq_init(struct test_seq *seq) {
seq->state = 0;
- toku_mutex_init(&seq->lock, NULL);
- toku_cond_init(&seq->cv, NULL);
+ toku_mutex_init(toku_uninstrumented, &seq->lock, nullptr);
+ toku_cond_init(toku_uninstrumented, &seq->cv, nullptr);
}
static void test_seq_destroy(struct test_seq *seq) {
@@ -172,13 +172,18 @@ int test_main(int argc, char * const argv[]) {
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
// run test
- struct test_seq seq; ZERO_STRUCT(seq); test_seq_init(&seq);
+ struct test_seq seq;
+ ZERO_STRUCT(seq);
+ test_seq_init(&seq);
toku_pthread_t t_a_id;
- struct t_a_args t_a_args = { db_env, db, &seq };
- r = toku_pthread_create(&t_a_id, NULL, t_a_thread, &t_a_args); assert(r == 0);
+ struct t_a_args t_a_args = {db_env, db, &seq};
+ r = toku_pthread_create(
+ toku_uninstrumented, &t_a_id, nullptr, t_a_thread, &t_a_args);
+ assert(r == 0);
t_b(db_env, db, &seq);
void *ret;
- r = toku_pthread_join(t_a_id, &ret); assert(r == 0);
+ r = toku_pthread_join(t_a_id, &ret);
+ assert(r == 0);
test_seq_destroy(&seq);
// close env
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-put-wakeup.cc b/storage/tokudb/PerconaFT/src/tests/blocking-put-wakeup.cc
index 615cdb5d17c..dba7962de35 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-put-wakeup.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-put-wakeup.cc
@@ -58,8 +58,8 @@ struct test_seq {
static void test_seq_init(struct test_seq *seq) {
seq->state = 0;
- toku_mutex_init(&seq->lock, NULL);
- toku_cond_init(&seq->cv, NULL);
+ toku_mutex_init(toku_uninstrumented, &seq->lock, nullptr);
+ toku_cond_init(toku_uninstrumented, &seq->cv, nullptr);
}
static void test_seq_destroy(struct test_seq *seq) {
@@ -167,13 +167,18 @@ int test_main(int argc, char * const argv[]) {
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
// run test
- struct test_seq seq; ZERO_STRUCT(seq); test_seq_init(&seq);
+ struct test_seq seq;
+ ZERO_STRUCT(seq);
+ test_seq_init(&seq);
toku_pthread_t t_a_id;
- struct t_a_args t_a_args = { db_env, db, &seq };
- r = toku_pthread_create(&t_a_id, NULL, t_a_thread, &t_a_args); assert(r == 0);
+ struct t_a_args t_a_args = {db_env, db, &seq};
+ r = toku_pthread_create(
+ toku_uninstrumented, &t_a_id, nullptr, t_a_thread, &t_a_args);
+ assert(r == 0);
t_b(db_env, db, &seq);
void *ret;
- r = toku_pthread_join(t_a_id, &ret); assert(r == 0);
+ r = toku_pthread_join(t_a_id, &ret);
+ assert(r == 0);
test_seq_destroy(&seq);
// close env
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-put.cc b/storage/tokudb/PerconaFT/src/tests/blocking-put.cc
index 0fa56325007..95481062483 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-put.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-put.cc
@@ -139,12 +139,14 @@ int test_main(int argc, char * const argv[]) {
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
toku_pthread_t tids[nthreads];
- struct blocking_put_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_put_thread, &a); assert(r == 0);
+ struct blocking_put_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_put_thread, &a);
+ assert(r == 0);
}
blocking_put(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-0.cc b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-0.cc
index a0e03ab3293..7c2e7b0fb26 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-0.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-0.cc
@@ -126,12 +126,15 @@ static void *blocking_set_range_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime, uint64_t the_key) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_set_range_args a = { db_env, db, nrows, sleeptime, the_key };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_set_range_thread, &a); assert(r == 0);
+ struct blocking_set_range_args a = {db_env, db, nrows, sleeptime, the_key};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr,
+ blocking_set_range_thread, &a);
+ assert(r == 0);
}
blocking_set_range(db_env, db, nrows, sleeptime, the_key);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-n.cc b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-n.cc
index 056d74dbdd2..54a5846eb5e 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-n.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-n.cc
@@ -121,12 +121,15 @@ static void *blocking_set_range_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime, uint64_t the_key) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_set_range_args a = { db_env, db, nrows, sleeptime, the_key };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_set_range_thread, &a); assert(r == 0);
+ struct blocking_set_range_args a = {db_env, db, nrows, sleeptime, the_key};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr,
+ blocking_set_range_thread, &a);
+ assert(r == 0);
}
blocking_set_range(db_env, db, nrows, sleeptime, the_key);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-reverse-0.cc b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-reverse-0.cc
index 1e7fca85bff..59e582547bf 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-set-range-reverse-0.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-set-range-reverse-0.cc
@@ -126,12 +126,15 @@ static void *blocking_set_range_thread(void *arg) {
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime, uint64_t the_key) {
int r;
toku_pthread_t tids[nthreads];
- struct blocking_set_range_args a = { db_env, db, nrows, sleeptime, the_key };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_set_range_thread, &a); assert(r == 0);
+ struct blocking_set_range_args a = {db_env, db, nrows, sleeptime, the_key};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr,
+ blocking_set_range_thread, &a);
+ assert(r == 0);
}
blocking_set_range(db_env, db, nrows, sleeptime, the_key);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-set.cc b/storage/tokudb/PerconaFT/src/tests/blocking-set.cc
index ba64989842a..aa433c87be1 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-set.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-set.cc
@@ -182,12 +182,14 @@ int test_main(int argc, char * const argv[]) {
populate(db_env, db, nrows);
toku_pthread_t tids[nthreads];
- struct blocking_set_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_set_thread, &a); assert(r == 0);
+ struct blocking_set_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, blocking_set_thread, &a);
+ assert(r == 0);
}
blocking_set(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/blocking-table-lock.cc b/storage/tokudb/PerconaFT/src/tests/blocking-table-lock.cc
index 9ae33c56621..0953a4e80de 100644
--- a/storage/tokudb/PerconaFT/src/tests/blocking-table-lock.cc
+++ b/storage/tokudb/PerconaFT/src/tests/blocking-table-lock.cc
@@ -133,12 +133,17 @@ int test_main(int argc, char * const argv[]) {
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
toku_pthread_t tids[nthreads];
- struct blocking_table_lock_args a = { db_env, db, nrows, sleeptime };
- for (int i = 0; i < nthreads-1; i++) {
- r = toku_pthread_create(&tids[i], NULL, blocking_table_lock_thread, &a); assert(r == 0);
+ struct blocking_table_lock_args a = {db_env, db, nrows, sleeptime};
+ for (int i = 0; i < nthreads - 1; i++) {
+ r = toku_pthread_create(toku_uninstrumented,
+ &tids[i],
+ nullptr,
+ blocking_table_lock_thread,
+ &a);
+ assert(r == 0);
}
blocking_table_lock(db_env, db, nrows, sleeptime);
- for (int i = 0; i < nthreads-1; i++) {
+ for (int i = 0; i < nthreads - 1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/checkpoint_fairness.cc b/storage/tokudb/PerconaFT/src/tests/checkpoint_fairness.cc
index be82f8c352f..f62dfbc76d3 100644
--- a/storage/tokudb/PerconaFT/src/tests/checkpoint_fairness.cc
+++ b/storage/tokudb/PerconaFT/src/tests/checkpoint_fairness.cc
@@ -113,10 +113,14 @@ int test_main(int argc, char * const argv[]) {
{ int chk_r = db->open(db, NULL, "db", NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT, 0666); CKERR(chk_r); }
pthread_t thds[n_threads];
- int ids[n_threads];
- for (int i=0; i<n_threads; i++) {
- ids[i]=i;
- { int chk_r = toku_pthread_create(&thds[i], NULL, start_txns, &ids[i]); CKERR(chk_r); }
+ int ids[n_threads];
+ for (int i = 0; i < n_threads; i++) {
+ ids[i] = i;
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &thds[i], nullptr, start_txns, &ids[i]);
+ CKERR(chk_r);
+ }
}
start_checkpoints();
diff --git a/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc b/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc
index 221471a8045..135a9843ce4 100644
--- a/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc
+++ b/storage/tokudb/PerconaFT/src/tests/checkpoint_stress.cc
@@ -271,24 +271,29 @@ run_test (int iter, int die) {
}
// take checkpoint (all dictionaries)
- snapshot(NULL, 1);
+ snapshot(NULL, 1);
if (die) {
- // separate thread will perform random acts on other dictionaries (not 0)
- int r = toku_pthread_create(&thread, 0, random_acts, (void *) dictionaries);
- CKERR(r);
- // this thead will scribble over dictionary 0 before crash to verify that
- // post-checkpoint inserts are not in the database
- DB* db = dictionaries[0].db;
- if (iter & 1)
- scribble(db, iter);
- else
- thin_out(db, iter);
- uint32_t delay = myrandom();
- delay &= 0xFFF; // select lower 12 bits, shifted up 8 for random number ...
- delay = delay << 8; // ... uniformly distributed between 0 and 1M ...
- usleep(delay); // ... to sleep up to one second (1M usec)
- drop_dead();
+ // separate thread will perform random acts on other dictionaries (not
+ // 0)
+ int r = toku_pthread_create(
+ toku_uninstrumented, &thread, nullptr,
+ random_acts, static_cast<void*>(dictionaries));
+ CKERR(r);
+ // this thead will scribble over dictionary 0 before crash to verify
+ // that
+ // post-checkpoint inserts are not in the database
+ DB* db = dictionaries[0].db;
+ if (iter & 1)
+ scribble(db, iter);
+ else
+ thin_out(db, iter);
+ uint32_t delay = myrandom();
+ delay &=
+ 0xFFF; // select lower 12 bits, shifted up 8 for random number ...
+ delay = delay << 8; // ... uniformly distributed between 0 and 1M ...
+ usleep(delay); // ... to sleep up to one second (1M usec)
+ drop_dead();
}
else {
for (i = 0; i < NUM_DICTIONARIES; i++) {
diff --git a/storage/tokudb/PerconaFT/src/tests/db-put-simple-deadlock-threads.cc b/storage/tokudb/PerconaFT/src/tests/db-put-simple-deadlock-threads.cc
index ada46bd7516..e5bcc6af7bb 100644
--- a/storage/tokudb/PerconaFT/src/tests/db-put-simple-deadlock-threads.cc
+++ b/storage/tokudb/PerconaFT/src/tests/db-put-simple-deadlock-threads.cc
@@ -57,8 +57,8 @@ struct test_seq {
static void test_seq_init(struct test_seq *seq) {
seq->state = 0;
- toku_mutex_init(&seq->lock, NULL);
- toku_cond_init(&seq->cv, NULL);
+ toku_mutex_init(toku_uninstrumented, &seq->lock, nullptr);
+ toku_cond_init(toku_uninstrumented, &seq->cv, nullptr);
}
static void test_seq_destroy(struct test_seq *seq) {
@@ -146,8 +146,9 @@ static void simple_deadlock(DB_ENV *db_env, DB *db, int do_txn, int n) {
struct test_seq test_seq; ZERO_STRUCT(test_seq); test_seq_init(&test_seq);
toku_pthread_t tid;
- struct run_txn_b_arg arg = { &test_seq, txn_b, db, n};
- r = toku_pthread_create(&tid, NULL, run_txn_b, &arg);
+ struct run_txn_b_arg arg = {&test_seq, txn_b, db, n};
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, run_txn_b, &arg);
test_seq_sleep(&test_seq, 0);
insert_row(db, txn_a, htonl(0), 0, 0);
diff --git a/storage/tokudb/PerconaFT/src/tests/db-put-simple-lockwait.cc b/storage/tokudb/PerconaFT/src/tests/db-put-simple-lockwait.cc
index 365ea39eced..0fbe851532e 100644
--- a/storage/tokudb/PerconaFT/src/tests/db-put-simple-lockwait.cc
+++ b/storage/tokudb/PerconaFT/src/tests/db-put-simple-lockwait.cc
@@ -95,10 +95,11 @@ static void simple_lockwait(DB_ENV *db_env, DB *db, int do_txn, int nrows, int n
insert_row(db, txns[0], htonl(0), 0, 0);
toku_pthread_t tids[ntxns];
- for (int i = 1 ; i < ntxns; i++) {
+ for (int i = 1; i < ntxns; i++) {
struct insert_one_arg *XMALLOC(arg);
- *arg = (struct insert_one_arg) { txns[i], db};
- r = toku_pthread_create(&tids[i], NULL, insert_one, arg);
+ *arg = (struct insert_one_arg){txns[i], db};
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, insert_one, arg);
}
sleep(10);
diff --git a/storage/tokudb/PerconaFT/src/tests/db-put-update-deadlock.cc b/storage/tokudb/PerconaFT/src/tests/db-put-update-deadlock.cc
index 3660f11d1bd..7a968058d7f 100644
--- a/storage/tokudb/PerconaFT/src/tests/db-put-update-deadlock.cc
+++ b/storage/tokudb/PerconaFT/src/tests/db-put-update-deadlock.cc
@@ -128,10 +128,12 @@ static void update_deadlock(DB_ENV *db_env, DB *db, int do_txn, int nrows, int n
// get write locks
toku_pthread_t tids[ntxns];
- for (int i = 0 ; i < ntxns; i++) {
+ for (int i = 0; i < ntxns; i++) {
struct write_one_arg *XMALLOC(arg);
- *arg = (struct write_one_arg) { txns[i], db, (int) htonl((i + 1) % ntxns), 0};
- r = toku_pthread_create(&tids[i], NULL, write_one_f, arg);
+ *arg =
+ (struct write_one_arg){txns[i], db, (int)htonl((i + 1) % ntxns), 0};
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, write_one_f, arg);
}
#else
// get read locks
@@ -141,10 +143,11 @@ static void update_deadlock(DB_ENV *db_env, DB *db, int do_txn, int nrows, int n
// get write locks
toku_pthread_t tids[ntxns];
- for (int i = 0 ; i < ntxns; i++) {
+ for (int i = 0; i < ntxns; i++) {
struct write_one_arg *XMALLOC(arg);
- *arg = (struct write_one_arg) { txns[i], db, (int) htonl(0), 0};
- r = toku_pthread_create(&tids[i], NULL, write_one_f, arg);
+ *arg = (struct write_one_arg){txns[i], db, (int)htonl(0), 0};
+ r = toku_pthread_create(
+ toku_uninstrumented, &tids[i], nullptr, write_one_f, arg);
}
#endif
diff --git a/storage/tokudb/PerconaFT/src/tests/filesize.cc b/storage/tokudb/PerconaFT/src/tests/filesize.cc
index 6ab22245e68..9dfeea131c6 100644
--- a/storage/tokudb/PerconaFT/src/tests/filesize.cc
+++ b/storage/tokudb/PerconaFT/src/tests/filesize.cc
@@ -170,11 +170,9 @@ get_file_pathname(void) {
if (verbose) printf("path = %s\n", path);
}
-
-static int
-getsizeM(void) {
+static int getsizeM(void) {
toku_struct_stat buf;
- int r = toku_stat(path, &buf);
+ int r = toku_stat(path, &buf, toku_uninstrumented);
CKERR(r);
int sizeM = (int)buf.st_size >> 20;
check_fragmentation();
diff --git a/storage/tokudb/PerconaFT/src/tests/hotindexer-bw.cc b/storage/tokudb/PerconaFT/src/tests/hotindexer-bw.cc
index 82471f30e45..5336bc3329f 100644
--- a/storage/tokudb/PerconaFT/src/tests/hotindexer-bw.cc
+++ b/storage/tokudb/PerconaFT/src/tests/hotindexer-bw.cc
@@ -302,12 +302,19 @@ static void test_indexer(DB *src, DB **dbs)
CKERR(r);
toku_mutex_unlock(&put_lock);
- // start threads doing additional inserts - no lock issues since indexer already created
- r = toku_pthread_create(&client_threads[0], 0, client, (void *)&client_specs[0]); CKERR(r);
-// r = toku_pthread_create(&client_threads[1], 0, client, (void *)&client_specs[1]); CKERR(r);
+ // start threads doing additional inserts - no lock issues since indexer
+ // already created
+ r = toku_pthread_create(toku_uninstrumented,
+ &client_threads[0],
+ nullptr,
+ client,
+ static_cast<void *>(&client_specs[0]));
+ CKERR(r);
+ // r = toku_pthread_create(toku_uninstrumented, &client_threads[1], 0,
+ // client, (void *)&client_specs[1]); CKERR(r);
struct timeval start, now;
- if ( verbose ) {
+ if (verbose) {
printf("test_indexer build\n");
gettimeofday(&start,0);
}
@@ -342,14 +349,13 @@ static void test_indexer(DB *src, DB **dbs)
if ( verbose ) printf("test_indexer done\n");
}
-
-static void run_test(void)
-{
+static void run_test(void) {
int r;
- toku_mutex_init(&put_lock, NULL);
+ toku_mutex_init(toku_uninstrumented, &put_lock, nullptr);
toku_os_recursive_delete(TOKU_TEST_FILENAME);
- r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
- char logname[TOKU_PATH_MAX+1];
+ r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU + S_IRWXG + S_IRWXO);
+ CKERR(r);
+ char logname[TOKU_PATH_MAX + 1];
r = toku_os_mkdir(toku_path_join(logname, 2, TOKU_TEST_FILENAME, "log"), S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
r = db_env_create(&env, 0); CKERR(r);
diff --git a/storage/tokudb/PerconaFT/src/tests/hotindexer-multiclient.cc b/storage/tokudb/PerconaFT/src/tests/hotindexer-multiclient.cc
index eefc621f80a..004a19eccec 100644
--- a/storage/tokudb/PerconaFT/src/tests/hotindexer-multiclient.cc
+++ b/storage/tokudb/PerconaFT/src/tests/hotindexer-multiclient.cc
@@ -303,13 +303,25 @@ static void test_indexer(DB *src, DB **dbs)
r = indexer->set_poll_function(indexer, poll_print, NULL);
CKERR(r);
- // start threads doing additional inserts - no lock issues since indexer already created
- r = toku_pthread_create(&client_threads[0], 0, client, (void *)&client_specs[0]); CKERR(r);
- r = toku_pthread_create(&client_threads[1], 0, client, (void *)&client_specs[1]); CKERR(r);
-// r = toku_pthread_create(&client_threads[2], 0, client, (void *)&client_specs[2]); CKERR(r);
+ // start threads doing additional inserts - no lock issues since indexer
+ // already created
+ r = toku_pthread_create(toku_uninstrumented,
+ &client_threads[0],
+ nullptr,
+ client,
+ static_cast<void *>(&client_specs[0]));
+ CKERR(r);
+ r = toku_pthread_create(toku_uninstrumented,
+ &client_threads[1],
+ nullptr,
+ client,
+ static_cast<void *>(&client_specs[1]));
+ CKERR(r);
+ // r = toku_pthread_create(toku_uninstrumented, &client_threads[2], 0,
+ // client, (void *)&client_specs[2]); CKERR(r);
struct timeval start, now;
- if ( verbose ) {
+ if (verbose) {
printf("test_indexer build\n");
gettimeofday(&start,0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/hotindexer-put-abort.cc b/storage/tokudb/PerconaFT/src/tests/hotindexer-put-abort.cc
index 27501291b15..f4dd9c53ed5 100644
--- a/storage/tokudb/PerconaFT/src/tests/hotindexer-put-abort.cc
+++ b/storage/tokudb/PerconaFT/src/tests/hotindexer-put-abort.cc
@@ -142,11 +142,14 @@ run_test(void) {
}
// run the indexer
- struct indexer_arg indexer_arg = { env, src_db, 1, &dest_db };
+ struct indexer_arg indexer_arg = {env, src_db, 1, &dest_db};
toku_pthread_t pid;
- r = toku_pthread_create(&pid, NULL, indexer_thread, &indexer_arg); assert_zero(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &pid, nullptr, indexer_thread, &indexer_arg);
+ assert_zero(r);
- r = txn->abort(txn); assert_zero(r);
+ r = txn->abort(txn);
+ assert_zero(r);
void *ret;
r = toku_pthread_join(pid, &ret); assert_zero(r);
diff --git a/storage/tokudb/PerconaFT/src/tests/hotindexer-put-commit.cc b/storage/tokudb/PerconaFT/src/tests/hotindexer-put-commit.cc
index 59b40037125..99c9bf301cc 100644
--- a/storage/tokudb/PerconaFT/src/tests/hotindexer-put-commit.cc
+++ b/storage/tokudb/PerconaFT/src/tests/hotindexer-put-commit.cc
@@ -166,12 +166,16 @@ run_test(void) {
}
// run the indexer
- struct indexer_arg indexer_arg = { env, src_db, 1, &dest_db };
+ struct indexer_arg indexer_arg = {env, src_db, 1, &dest_db};
toku_pthread_t pid;
- r = toku_pthread_create(&pid, NULL, indexer_thread, &indexer_arg); assert_zero(r);
-
- if (verbose) fprintf(stderr, "commit start\n");
- r = txn->commit(txn, 0); assert_zero(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &pid, nullptr, indexer_thread, &indexer_arg);
+ assert_zero(r);
+
+ if (verbose)
+ fprintf(stderr, "commit start\n");
+ r = txn->commit(txn, 0);
+ assert_zero(r);
if (verbose) fprintf(stderr, "commit end\n");
void *ret;
diff --git a/storage/tokudb/PerconaFT/src/tests/hotindexer-with-queries.cc b/storage/tokudb/PerconaFT/src/tests/hotindexer-with-queries.cc
index a0be49c1617..2bc60142f3c 100644
--- a/storage/tokudb/PerconaFT/src/tests/hotindexer-with-queries.cc
+++ b/storage/tokudb/PerconaFT/src/tests/hotindexer-with-queries.cc
@@ -114,10 +114,12 @@ static void query_only(DB *src)
client_init();
// start thread doing query
- r = toku_pthread_create(client_thread, 0, client, (void *)src);
+ r = toku_pthread_create(
+ toku_uninstrumented, client_thread, nullptr,
+ client, static_cast<void *>(src));
CKERR(r);
- r = toku_pthread_join(*client_thread, &t0);
+ r = toku_pthread_join(*client_thread, &t0);
CKERR(r);
client_cleanup();
@@ -150,10 +152,13 @@ static void test_indexer(DB *src, DB **dbs)
CKERR(r);
// start thread doing query
- r = toku_pthread_create(client_thread, 0, client, (void *)src); CKERR(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, client_thread, nullptr,
+ client, static_cast<void *>(src));
+ CKERR(r);
struct timeval start, now;
- if ( verbose ) {
+ if (verbose) {
printf("test_indexer build\n");
gettimeofday(&start,0);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/locktree_escalation_stalls.cc b/storage/tokudb/PerconaFT/src/tests/locktree_escalation_stalls.cc
index b4874472bcb..e6c1b18b2b6 100644
--- a/storage/tokudb/PerconaFT/src/tests/locktree_escalation_stalls.cc
+++ b/storage/tokudb/PerconaFT/src/tests/locktree_escalation_stalls.cc
@@ -191,17 +191,22 @@ static void run_test(uint64_t max_i, int n_small) {
env, big_db, max_i, big_test,
};
toku_pthread_t big_id;
- r = toku_pthread_create(&big_id, NULL, test_f, &big_test_args);
+ r = toku_pthread_create(
+ toku_uninstrumented, &big_id, nullptr, test_f, &big_test_args);
assert(r == 0);
struct test_args small_test_args[n_small];
toku_pthread_t small_id[n_small];
for (int i = 0; i < n_small; i++) {
- small_test_args[i] = { env, small_db, max_i, small_test };
- r = toku_pthread_create(&small_id[i], NULL, test_f, &small_test_args[i]);
+ small_test_args[i] = {env, small_db, max_i, small_test};
+ r = toku_pthread_create(toku_uninstrumented,
+ &small_id[i],
+ nullptr,
+ test_f,
+ &small_test_args[i]);
assert(r == 0);
}
-
+
void *big_ret;
r = toku_pthread_join(big_id, &big_ret);
assert(r == 0);
diff --git a/storage/tokudb/PerconaFT/src/tests/recover-test_crash_in_flusher_thread.h b/storage/tokudb/PerconaFT/src/tests/recover-test_crash_in_flusher_thread.h
index 0ed68207ed4..5c10d0cb712 100644
--- a/storage/tokudb/PerconaFT/src/tests/recover-test_crash_in_flusher_thread.h
+++ b/storage/tokudb/PerconaFT/src/tests/recover-test_crash_in_flusher_thread.h
@@ -70,13 +70,18 @@ static void *do_checkpoint_and_crash(void *arg) {
static void flt_callback(int flt_state, void* extra) {
cnt++;
if (verbose) printf("flt_state!! %d\n", flt_state);
- if (cnt > 0 && !starting_a_chkpt && flt_state == state_to_crash) {
- starting_a_chkpt = true;
- if (verbose) printf("flt_state %d\n", flt_state);
- int r = toku_pthread_create(&checkpoint_tid, NULL, do_checkpoint_and_crash, extra);
- assert(r==0);
- usleep(2*1000*1000);
- }
+ if (cnt > 0 && !starting_a_chkpt && flt_state == state_to_crash) {
+ starting_a_chkpt = true;
+ if (verbose)
+ printf("flt_state %d\n", flt_state);
+ int r = toku_pthread_create(toku_uninstrumented,
+ &checkpoint_tid,
+ nullptr,
+ do_checkpoint_and_crash,
+ extra);
+ assert(r == 0);
+ usleep(2 * 1000 * 1000);
+ }
}
diff --git a/storage/tokudb/PerconaFT/src/tests/recovery_stress.cc b/storage/tokudb/PerconaFT/src/tests/recovery_stress.cc
index b1f5f98a90a..1646030cc85 100644
--- a/storage/tokudb/PerconaFT/src/tests/recovery_stress.cc
+++ b/storage/tokudb/PerconaFT/src/tests/recovery_stress.cc
@@ -515,19 +515,8 @@ static void run_test (int iter) {
// if requesting crash, randomly do other non-committed acts, then "drop_dead"
if (iter > 0) {
- if (verbose) printf("dying\n");
-#if 0
- // separate thread will perform random acts on other dictionaries (not 0)
- r = toku_pthread_create(&thread, 0, random_acts, (void *) dictionaries);
- CKERR(r);
- // this thead will scribble over dictionary 0 before crash to verify that
- // post-checkpoint inserts are not in the database
- DB* db = dictionaries[0].db;
- if (iter & 1)
- scribble(db, iter);
- else
- thin_out(db, iter);
-#endif
+ if (verbose)
+ printf("dying\n");
uint32_t delay = myrandom();
delay &= 0xFFF; // select lower 12 bits, shifted up 8 for random number ...
delay = delay << 8; // ... uniformly distributed between 0 and 1M ...
diff --git a/storage/tokudb/PerconaFT/src/tests/stress_openclose.h b/storage/tokudb/PerconaFT/src/tests/stress_openclose.h
index 3f10bfe8aeb..3a55ca4486f 100644
--- a/storage/tokudb/PerconaFT/src/tests/stress_openclose.h
+++ b/storage/tokudb/PerconaFT/src/tests/stress_openclose.h
@@ -245,19 +245,16 @@ stress_table(DB_ENV *env, DB **dbp, struct cli_args *cli_args) {
// which they can choose a random db to either touch or query
XMALLOC_N(num_buckets, buckets);
for (int i = 0; i < num_buckets; i++) {
- struct db_bucket bucket = {
- .env = env,
- .db = dbp[i],
- .is_open = true
- };
+ struct db_bucket bucket = {.env = env, .db = dbp[i], .is_open = true};
buckets[i] = bucket;
- toku_mutex_init(&buckets[i].mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &buckets[i].mutex, nullptr);
}
// run all of the query and update workers. they may randomly open
// and close the dbs in each db_bucket to be some random dictionary,
// so when they're done we'll have to clean up the mess so this
// stress test can exit gracefully expecting db[i] = the ith db
- //verbose_printf("stressing %d tables using %d update threads, %d query threads\n",
+ // verbose_printf("stressing %d tables using %d update threads, %d query
+ // threads\n",
// num_buckets, update_threads, query_threads);
verbose_printf("stressing %d tables using %d update threads\n",
num_buckets, update_threads);
diff --git a/storage/tokudb/PerconaFT/src/tests/test3039.cc b/storage/tokudb/PerconaFT/src/tests/test3039.cc
index 54a2b3bf730..6c38fa13592 100644
--- a/storage/tokudb/PerconaFT/src/tests/test3039.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test3039.cc
@@ -184,30 +184,36 @@ void do_threads (unsigned long long N, int do_nonlocal) {
toku_pthread_t ths[2];
struct reader_thread_state rstates[2] = {{.elapsed_time = 0.0,
.n_did_read = 0,
- .n_to_read = (long long signed) N,
- .do_local = 1,
- .finish = 0},
+ .n_to_read = (long long signed)N,
+ .do_local = 1,
+ .finish = 0},
{.elapsed_time = 0.0,
.n_did_read = 0,
.n_to_read = -1,
- .do_local = 0,
- .finish = 0}};
+ .do_local = 0,
+ .finish = 0}};
int n_to_create = do_nonlocal ? 2 : 1;
- for (int i=0; i<n_to_create; i++) {
- int r = toku_pthread_create(&ths[i], 0, reader_thread, (void*)&rstates[i]);
- CKERR(r);
+ for (int i = 0; i < n_to_create; i++) {
+ int r = toku_pthread_create(toku_uninstrumented,
+ &ths[i],
+ nullptr,
+ reader_thread,
+ static_cast<void *>(&rstates[i]));
+ CKERR(r);
}
- for (int i=0; i<n_to_create; i++) {
- void *retval;
- int r = toku_pthread_join(ths[i], &retval);
- CKERR(r);
- assert(retval==0);
- if (verbose) {
- printf("%9s thread time = %8.2fs on %9lld reads (%.3f us/read)\n",
- (i==0 ? "local" : "nonlocal"),
- rstates[i].elapsed_time, rstates[i].n_did_read, rstates[i].elapsed_time/rstates[i].n_did_read * 1e6);
- }
- rstates[1].finish = 1;
+ for (int i = 0; i < n_to_create; i++) {
+ void *retval;
+ int r = toku_pthread_join(ths[i], &retval);
+ CKERR(r);
+ assert(retval == 0);
+ if (verbose) {
+ printf("%9s thread time = %8.2fs on %9lld reads (%.3f us/read)\n",
+ (i == 0 ? "local" : "nonlocal"),
+ rstates[i].elapsed_time,
+ rstates[i].n_did_read,
+ rstates[i].elapsed_time / rstates[i].n_did_read * 1e6);
+ }
+ rstates[1].finish = 1;
}
if (verbose && do_nonlocal) {
printf("total %9lld reads (%.3f us/read)\n",
diff --git a/storage/tokudb/PerconaFT/src/tests/test_1672532.cc b/storage/tokudb/PerconaFT/src/tests/test_1672532.cc
new file mode 100644
index 00000000000..721e7677824
--- /dev/null
+++ b/storage/tokudb/PerconaFT/src/tests/test_1672532.cc
@@ -0,0 +1,210 @@
+/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
+#ident "$Id$"
+/*======
+This file is part of PerconaFT.
+
+
+Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
+
+ PerconaFT is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2,
+ as published by the Free Software Foundation.
+
+ PerconaFT 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.
+
+ You should have received a copy of the GNU General Public License
+ along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
+
+----------------------------------------
+
+ PerconaFT is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License, version 3,
+ as published by the Free Software Foundation.
+
+ PerconaFT 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with PerconaFT. If not, see <http://www.gnu.org/licenses/>.
+======= */
+
+#ident \
+ "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
+
+#include "test.h"
+// to verify the DB_LOCKING_READ works to lock the read rows for snapshot
+// isolaton.
+// we create a db, then init a read transaction with repeatable-read isolation
+// and
+// locking read flag, then we start another transaction to grab the write lock.
+// DB_LOCKING_READ is defined here to just make the before and after tests work
+// (before
+// test did not have DB_LOCKING_READ flag).
+#if !defined(DB_LOCKING_READ)
+#define DB_LOCKING_READ 0
+#endif
+static int prelock_range(DBC *cursor, int left, int right) {
+ DBT key_left;
+ dbt_init(&key_left, &left, sizeof left);
+ DBT key_right;
+ dbt_init(&key_right, &right, sizeof right);
+ int r = cursor->c_set_bounds(cursor, &key_left, &key_right, true, 0);
+ return r;
+}
+
+static void test_read_write_range(DB_ENV *env,
+ DB *db,
+ uint32_t iso_flags,
+ int expect_r) {
+ int r;
+
+ DB_TXN *txn_a = NULL;
+ r = env->txn_begin(env, NULL, &txn_a, iso_flags);
+ assert_zero(r);
+ DB_TXN *txn_b = NULL;
+ r = env->txn_begin(env, NULL, &txn_b, iso_flags);
+ assert_zero(r);
+
+ DBC *cursor_a = NULL;
+ r = db->cursor(db, txn_a, &cursor_a, DB_LOCKING_READ);
+ assert_zero(r);
+ DBC *cursor_b = NULL;
+ r = db->cursor(db, txn_b, &cursor_b, DB_RMW);
+ assert_zero(r);
+
+ r = prelock_range(cursor_a, htonl(10), htonl(100));
+ assert_zero(r);
+ r = prelock_range(cursor_b, htonl(50), htonl(200));
+ assert(r == expect_r);
+
+ r = cursor_a->c_close(cursor_a);
+ assert_zero(r);
+ r = cursor_b->c_close(cursor_b);
+ assert_zero(r);
+
+ r = txn_a->commit(txn_a, 0);
+ assert_zero(r);
+ r = txn_b->commit(txn_b, 0);
+ assert_zero(r);
+}
+
+static void test_read_write_point(DB_ENV *env,
+ DB *db,
+ uint32_t iso_flags,
+ int expect_r) {
+ int r;
+
+ DB_TXN *txn1 = NULL;
+ r = env->txn_begin(env, NULL, &txn1, iso_flags);
+ assert_zero(r);
+
+ DB_TXN *txn2 = NULL;
+ r = env->txn_begin(env, NULL, &txn2, iso_flags);
+ assert_zero(r);
+
+ DBC *c1 = NULL;
+ r = db->cursor(db, txn1, &c1, DB_LOCKING_READ);
+ assert_zero(r);
+
+ DBC *c2 = NULL;
+ r = db->cursor(db, txn2, &c2, DB_RMW);
+ assert_zero(r);
+
+ int k = htonl(42);
+ DBT key;
+ dbt_init(&key, &k, sizeof k);
+ DBT val;
+ memset(&val, 0, sizeof val);
+ r = c1->c_get(c1, &key, &val, DB_SET);
+ assert_zero(r);
+
+ r = c2->c_get(c2, &key, &val, DB_SET);
+ assert(r == expect_r);
+
+ r = c1->c_close(c1);
+ assert_zero(r);
+ r = c2->c_close(c2);
+ assert_zero(r);
+
+ r = txn1->commit(txn1, 0);
+ assert_zero(r);
+ r = txn2->commit(txn2, 0);
+ assert_zero(r);
+}
+
+int test_main(int argc, char *const argv[]) {
+ int r;
+
+ const char *env_dir = TOKU_TEST_FILENAME;
+ const char *db_filename = "lockingreadtest";
+
+ parse_args(argc, argv);
+
+ char rm_cmd[strlen(env_dir) + strlen("rm -rf ") + 1];
+ snprintf(rm_cmd, sizeof(rm_cmd), "rm -rf %s", env_dir);
+ r = system(rm_cmd);
+ assert_zero(r);
+
+ r = toku_os_mkdir(env_dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+ assert_zero(r);
+
+ DB_ENV *env = NULL;
+ r = db_env_create(&env, 0);
+ assert_zero(r);
+ int env_open_flags = DB_CREATE | DB_PRIVATE | DB_INIT_MPOOL | DB_INIT_TXN |
+ DB_INIT_LOCK | DB_INIT_LOG;
+ r = env->open(
+ env, env_dir, env_open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ assert_zero(r);
+
+ // create the db
+ DB *db = NULL;
+ r = db_create(&db, env, 0);
+ assert_zero(r);
+ DB_TXN *create_txn = NULL;
+ r = env->txn_begin(env, NULL, &create_txn, 0);
+ assert_zero(r);
+ r = db->open(db,
+ create_txn,
+ db_filename,
+ NULL,
+ DB_BTREE,
+ DB_CREATE,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ assert_zero(r);
+ r = create_txn->commit(create_txn, 0);
+ assert_zero(r);
+
+ // add a record
+
+ DB_TXN *write_txn = NULL;
+ r = env->txn_begin(env, NULL, &write_txn, 0);
+ assert_zero(r);
+
+ int k = htonl(42);
+ int v = 42;
+ DBT key;
+ dbt_init(&key, &k, sizeof k);
+ DBT val;
+ dbt_init(&val, &v, sizeof v);
+ r = db->put(db, write_txn, &key, &val, DB_NOOVERWRITE);
+ assert_zero(r);
+ r = write_txn->commit(write_txn, 0);
+ assert_zero(r);
+
+ test_read_write_range(env, db, DB_TXN_SNAPSHOT, DB_LOCK_NOTGRANTED);
+ test_read_write_point(env, db, DB_TXN_SNAPSHOT, DB_LOCK_NOTGRANTED);
+
+ r = db->close(db, 0);
+ assert_zero(r);
+
+ r = env->close(env, 0);
+ assert_zero(r);
+ return 0;
+}
diff --git a/storage/tokudb/PerconaFT/src/tests/test_3645.cc b/storage/tokudb/PerconaFT/src/tests/test_3645.cc
index bb5566b032d..e1fa37bef54 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_3645.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_3645.cc
@@ -239,33 +239,61 @@ test_evictions (void) {
// make the forward fast scanner
myargs[0].fast = true;
myargs[0].fwd = true;
- { int chk_r = toku_pthread_create(&mytids[0], NULL, scan_db, &myargs[0]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[0], nullptr, scan_db, &myargs[0]);
+ CKERR(chk_r);
+ }
// make the forward slow scanner
myargs[1].fast = false;
myargs[1].fwd = true;
- { int chk_r = toku_pthread_create(&mytids[1], NULL, scan_db, &myargs[1]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[1], nullptr, scan_db, &myargs[1]);
+ CKERR(chk_r);
+ }
// make the backward fast scanner
myargs[2].fast = true;
myargs[2].fwd = false;
- { int chk_r = toku_pthread_create(&mytids[2], NULL, scan_db, &myargs[2]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[2], nullptr, scan_db, &myargs[2]);
+ CKERR(chk_r);
+ }
// make the backward slow scanner
myargs[3].fast = false;
myargs[3].fwd = false;
- { int chk_r = toku_pthread_create(&mytids[3], NULL, scan_db, &myargs[3]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[3], nullptr, scan_db, &myargs[3]);
+ CKERR(chk_r);
+ }
// make the guy that updates the db
- { int chk_r = toku_pthread_create(&mytids[4], NULL, update_db, &myargs[4]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[4], nullptr, update_db, &myargs[4]);
+ CKERR(chk_r);
+ }
// make the guy that does point queries
- { int chk_r = toku_pthread_create(&mytids[5], NULL, ptquery_db, &myargs[5]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[5], nullptr, ptquery_db, &myargs[5]);
+ CKERR(chk_r);
+ }
// make the guy that sleeps
- { int chk_r = toku_pthread_create(&mytids[6], NULL, test_time, NULL); CKERR(chk_r); }
-
- for (uint32_t i = 0; i < sizeof(myargs)/sizeof(myargs[0]); i++) {
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &mytids[6], nullptr, test_time, nullptr);
+ CKERR(chk_r);
+ }
+
+ for (uint32_t i = 0; i < sizeof(myargs) / sizeof(myargs[0]); i++) {
void *ret;
r = toku_pthread_join(mytids[i], &ret); assert_zero(r);
}
diff --git a/storage/tokudb/PerconaFT/src/tests/test_4015.cc b/storage/tokudb/PerconaFT/src/tests/test_4015.cc
index dc18242b489..1231e3b4bca 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_4015.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_4015.cc
@@ -151,10 +151,18 @@ int test_main(int argc, char * const argv[]) {
{ int chk_r = db->open(db, NULL, "db", NULL, DB_BTREE, DB_CREATE, 0666); CKERR(chk_r); }
DBT desc;
dbt_init(&desc, "foo", sizeof("foo"));
- IN_TXN_COMMIT(env, NULL, txn, 0,
- { int chk_r = db->change_descriptor(db, txn, &desc, DB_UPDATE_CMP_DESCRIPTOR); CKERR(chk_r); });
+ IN_TXN_COMMIT(env, NULL, txn, 0, {
+ int chk_r =
+ db->change_descriptor(db, txn, &desc, DB_UPDATE_CMP_DESCRIPTOR);
+ CKERR(chk_r);
+ });
pthread_t thd;
- { int chk_r = toku_pthread_create(&thd, NULL, startA, NULL); CKERR(chk_r); }
+ {
+ int chk_r =
+ toku_pthread_create(
+ toku_uninstrumented, &thd, nullptr, startA, nullptr);
+ CKERR(chk_r);
+ }
startB();
diff --git a/storage/tokudb/PerconaFT/src/tests/test_abort1.cc b/storage/tokudb/PerconaFT/src/tests/test_abort1.cc
index 55449610ffb..7b60364878b 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_abort1.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_abort1.cc
@@ -87,10 +87,12 @@ test_db_open_aborts (void) {
CKERR2(r, DB_NOTFOUND);
}
toku_struct_stat statbuf;
- char filename[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(filename, 2, TOKU_TEST_FILENAME, "foo.db"), &statbuf);
- assert(r!=0);
- assert(errno==ENOENT);
+ char filename[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(filename, 2, TOKU_TEST_FILENAME, "foo.db"),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r != 0);
+ assert(errno == ENOENT);
}
r=env->close(env, 0); assert(r==0);
@@ -153,10 +155,12 @@ test_db_put_aborts (void) {
CAST_FROM_VOIDP(filename, iname.data);
assert(filename);
}
- toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename), &statbuf);
- assert(r==0);
+ toku_struct_stat statbuf;
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == 0);
toku_free(filename);
}
// But the item should not be in it.
diff --git a/storage/tokudb/PerconaFT/src/tests/test_abort4.cc b/storage/tokudb/PerconaFT/src/tests/test_abort4.cc
index e67efb465b2..e797fc640d8 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_abort4.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_abort4.cc
@@ -160,10 +160,12 @@ verify_and_tear_down(int close_first) {
CAST_FROM_VOIDP(filename, iname.data);
assert(filename);
}
- toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename), &statbuf);
- assert(r==0);
+ toku_struct_stat statbuf;
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == 0);
toku_free(filename);
}
CKERR(r);
diff --git a/storage/tokudb/PerconaFT/src/tests/test_abort5.cc b/storage/tokudb/PerconaFT/src/tests/test_abort5.cc
index 728afcce1b9..d5d056d5126 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_abort5.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_abort5.cc
@@ -191,10 +191,12 @@ verify_and_tear_down(int close_first) {
CAST_FROM_VOIDP(filename, iname.data);
assert(filename);
}
- toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename), &statbuf);
- assert(r==0);
+ toku_struct_stat statbuf;
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == 0);
toku_free(filename);
}
if (close_first) {
diff --git a/storage/tokudb/PerconaFT/src/tests/test_forkjoin.cc b/storage/tokudb/PerconaFT/src/tests/test_forkjoin.cc
index 910cf46e513..766372a15c2 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_forkjoin.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_forkjoin.cc
@@ -48,12 +48,13 @@ f (void *arg) {
return arg;
}
-int
-test_main(int argc, char *const argv[]) {
+int test_main(int argc, char *const argv[]) {
parse_args(argc, argv);
toku_pthread_t t;
- int r = toku_pthread_create(&t, 0, f, 0); assert(r == 0);
+ int r = toku_pthread_create(toku_uninstrumented, &t, nullptr, f, nullptr);
+ assert(r == 0);
void *ret;
- r = toku_pthread_join(t, &ret); assert(r == 0);
+ r = toku_pthread_join(t, &ret);
+ assert(r == 0);
return 0;
}
diff --git a/storage/tokudb/PerconaFT/src/tests/test_groupcommit_count.cc b/storage/tokudb/PerconaFT/src/tests/test_groupcommit_count.cc
index 414ddd2b70a..35104c2a569 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_groupcommit_count.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_groupcommit_count.cc
@@ -87,12 +87,16 @@ test_groupcommit (int nthreads) {
int i;
toku_pthread_t threads[nthreads];
int whichthread[nthreads];
- for (i=0; i<nthreads; i++) {
- whichthread[i]=i;
- r=toku_pthread_create(&threads[i], 0, start_a_thread, &whichthread[i]);
+ for (i = 0; i < nthreads; i++) {
+ whichthread[i] = i;
+ r = toku_pthread_create(toku_uninstrumented,
+ &threads[i],
+ nullptr,
+ start_a_thread,
+ &whichthread[i]);
}
- for (i=0; i<nthreads; i++) {
- toku_pthread_join(threads[i], 0);
+ for (i = 0; i < nthreads; i++) {
+ toku_pthread_join(threads[i], 0);
}
r=db->close(db, 0); assert(r==0);
diff --git a/storage/tokudb/PerconaFT/src/tests/test_groupcommit_perf.cc b/storage/tokudb/PerconaFT/src/tests/test_groupcommit_perf.cc
index 94eaf2a01a9..6f872d10a32 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_groupcommit_perf.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_groupcommit_perf.cc
@@ -84,12 +84,16 @@ test_groupcommit (int nthreads) {
int i;
toku_pthread_t threads[nthreads];
int whichthread[nthreads];
- for (i=0; i<nthreads; i++) {
- whichthread[i]=i;
- r=toku_pthread_create(&threads[i], 0, start_a_thread, &whichthread[i]);
+ for (i = 0; i < nthreads; i++) {
+ whichthread[i] = i;
+ r = toku_pthread_create(toku_uninstrumented,
+ &threads[i],
+ nullptr,
+ start_a_thread,
+ &whichthread[i]);
}
- for (i=0; i<nthreads; i++) {
- toku_pthread_join(threads[i], 0);
+ for (i = 0; i < nthreads; i++) {
+ toku_pthread_join(threads[i], 0);
}
#if 0
r=env->txn_begin(env, 0, &tid, 0); CKERR(r);
diff --git a/storage/tokudb/PerconaFT/src/tests/test_iterate_pending_lock_requests.cc b/storage/tokudb/PerconaFT/src/tests/test_iterate_pending_lock_requests.cc
index f2bf0a2c756..66471a74af2 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_iterate_pending_lock_requests.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_iterate_pending_lock_requests.cc
@@ -112,12 +112,17 @@ int test_main(int UU(argc), char *const UU(argv[])) {
acquire_lock(txn1, magic_key);
acquire_lock_extra e1(txn2, magic_key);
- r = toku_pthread_create(&thread1, NULL, acquire_lock_thread, &e1); CKERR(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &thread1, nullptr, acquire_lock_thread, &e1);
+ CKERR(r);
acquire_lock_extra e2(txn3, magic_key);
- r = toku_pthread_create(&thread2, NULL, acquire_lock_thread, &e2); CKERR(r);
+ r = toku_pthread_create(
+ toku_uninstrumented, &thread2, nullptr, acquire_lock_thread, &e2);
+ CKERR(r);
sleep(1);
- r = env->iterate_pending_lock_requests(env, iterate_callback, NULL); CKERR(r);
+ r = env->iterate_pending_lock_requests(env, iterate_callback, NULL);
+ CKERR(r);
invariant(iterate_callback_called == 2);
void *v;
diff --git a/storage/tokudb/PerconaFT/src/tests/test_lock_timeout_callback.cc b/storage/tokudb/PerconaFT/src/tests/test_lock_timeout_callback.cc
index 75ea49ec858..571bae69916 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_lock_timeout_callback.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_lock_timeout_callback.cc
@@ -118,7 +118,8 @@ int test_main(int UU(argc), char *const UU(argv[])) {
acquire_lock(txn2, magic_key + 1);
toku_pthread_t thread;
acquire_lock_extra e(txn1, magic_key + 1);
- r = toku_pthread_create(&thread, NULL, acquire_lock_thread, &e);
+ r = toku_pthread_create(
+ toku_uninstrumented, &thread, nullptr, acquire_lock_thread, &e);
usleep(100000);
acquire_lock(txn2, magic_key);
invariant(callback_calls == 2);
diff --git a/storage/tokudb/PerconaFT/src/tests/test_log1.cc b/storage/tokudb/PerconaFT/src/tests/test_log1.cc
index 65fa1d830ef..5473a8e3d5e 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_log1.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_log1.cc
@@ -87,10 +87,12 @@ static void make_db (bool close_env) {
r=tid->commit(tid, 0); assert(r==0);
r=db->close(db, 0); assert(r==0);
{
- toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename), &statbuf);
- assert(r==0);
+ toku_struct_stat statbuf;
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == 0);
toku_free(filename);
}
if (close_env) {
diff --git a/storage/tokudb/PerconaFT/src/tests/test_log1_abort.cc b/storage/tokudb/PerconaFT/src/tests/test_log1_abort.cc
index 92c3657a154..c66409fb823 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_log1_abort.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_log1_abort.cc
@@ -80,11 +80,13 @@ test_main (int UU(argc), char UU(*const argv[])) {
r=env->close(env, 0);
assert(r==0);
{
- toku_struct_stat statbuf;
- char filename[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(filename, 2, TOKU_TEST_FILENAME, "foo.db"), &statbuf);
- assert(r==-1);
- assert(errno==ENOENT);
+ toku_struct_stat statbuf;
+ char filename[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(filename, 2, TOKU_TEST_FILENAME, "foo.db"),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == -1);
+ assert(errno == ENOENT);
}
return 0;
}
diff --git a/storage/tokudb/PerconaFT/src/tests/test_logmax.cc b/storage/tokudb/PerconaFT/src/tests/test_logmax.cc
index e5de0a5d906..133eb36ddb5 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_logmax.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_logmax.cc
@@ -50,14 +50,19 @@ check_logmax (int max) {
struct dirent *ent;
while ((ent=readdir(dir))) {
if ((ent->d_type==DT_REG || ent->d_type==DT_UNKNOWN) && strncmp(ent->d_name, "log", 3)==0) {
- // It is a "log*" file
- char full_fname[TOKU_PATH_MAX+1];
- toku_struct_stat sbuf;
- int r = toku_stat(toku_path_join(full_fname, 2, TOKU_TEST_FILENAME, ent->d_name), &sbuf);
- assert(r==0);
- if (verbose)
- printf("%s is of size %" PRId64 "\n", ent->d_name, (int64_t)sbuf.st_size);
- if (sbuf.st_size > max) any_too_big=1;
+ // It is a "log*" file
+ char full_fname[TOKU_PATH_MAX + 1];
+ toku_struct_stat sbuf;
+ int r = toku_stat(
+ toku_path_join(full_fname, 2, TOKU_TEST_FILENAME, ent->d_name),
+ &sbuf,
+ toku_uninstrumented);
+ assert(r == 0);
+ if (verbose)
+ printf("%s is of size %" PRId64 "\n",
+ ent->d_name,
+ (int64_t)sbuf.st_size);
+ if (sbuf.st_size > max) any_too_big=1;
}
}
assert(!any_too_big);
diff --git a/storage/tokudb/PerconaFT/src/tests/test_multiple_checkpoints_block_commit.cc b/storage/tokudb/PerconaFT/src/tests/test_multiple_checkpoints_block_commit.cc
index 66e9f4a5ec8..da53a7bfe11 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_multiple_checkpoints_block_commit.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_multiple_checkpoints_block_commit.cc
@@ -101,10 +101,17 @@ static void run_test(void) {
toku_pthread_t chkpt1_tid;
toku_pthread_t chkpt2_tid;
-
- { int chk_r = toku_pthread_create(&chkpt1_tid, NULL, run_checkpoint, NULL); CKERR(chk_r); }
- { int chk_r = toku_pthread_create(&chkpt2_tid, NULL, run_checkpoint, NULL); CKERR(chk_r); }
- usleep(2*1024*1024);
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &chkpt1_tid, nullptr, run_checkpoint, nullptr);
+ CKERR(chk_r);
+ }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &chkpt2_tid, nullptr, run_checkpoint, nullptr);
+ CKERR(chk_r);
+ }
+ usleep(2 * 1024 * 1024);
struct timeval tstart;
gettimeofday(&tstart, NULL);
DB_TXN *txn = NULL;
diff --git a/storage/tokudb/PerconaFT/src/tests/test_stress_hot_indexing.cc b/storage/tokudb/PerconaFT/src/tests/test_stress_hot_indexing.cc
index e0bf0d2ec6f..6395f591660 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_stress_hot_indexing.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_stress_hot_indexing.cc
@@ -312,12 +312,11 @@ stress_table(DB_ENV *env, DB **dbp, struct cli_args *cli_args) {
run_workers(myargs, num_threads, cli_args->num_seconds, false, cli_args);
}
-int
-test_main(int argc, char *const argv[]) {
+int test_main(int argc, char *const argv[]) {
gid_count = 0;
memset(hi_gid, 0, sizeof(hi_gid));
- toku_mutex_init(&hi_lock, NULL);
- toku_mutex_init(&fops_lock, NULL);
+ toku_mutex_init(toku_uninstrumented, &hi_lock, nullptr);
+ toku_mutex_init(toku_uninstrumented, &fops_lock, nullptr);
hot_db = NULL;
struct cli_args args = get_default_args();
// let's make default checkpointing period really slow
diff --git a/storage/tokudb/PerconaFT/src/tests/test_thread_insert.cc b/storage/tokudb/PerconaFT/src/tests/test_thread_insert.cc
index 0d5245e8f80..a266de638f1 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_thread_insert.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_thread_insert.cc
@@ -150,10 +150,13 @@ test_main(int argc, char *const argv[]) {
work[i].endno = n;
}
- if (verbose) printf("pid:%d\n", toku_os_getpid());
+ if (verbose)
+ printf("pid:%d\n", toku_os_getpid());
- for (i=1; i<nthreads; i++) {
- r = toku_pthread_create(&work[i].tid, 0, do_inserts, &work[i]); assert(r == 0);
+ for (i = 1; i < nthreads; i++) {
+ r = toku_pthread_create(
+ toku_uninstrumented, &work[i].tid, nullptr, do_inserts, &work[i]);
+ assert(r == 0);
}
work[0].do_exit = 0;
diff --git a/storage/tokudb/PerconaFT/src/tests/test_txn_abort7.cc b/storage/tokudb/PerconaFT/src/tests/test_txn_abort7.cc
index fb428f437b1..0a4463644b3 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_txn_abort7.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_txn_abort7.cc
@@ -79,10 +79,12 @@ test_abort_create (void) {
CAST_FROM_VOIDP(filename, iname.data);
assert(filename);
}
- toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename), &statbuf);
- assert(r==0);
+ toku_struct_stat statbuf;
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, filename),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r == 0);
toku_free(filename);
}
@@ -100,10 +102,13 @@ test_abort_create (void) {
CKERR2(r, DB_NOTFOUND);
}
toku_struct_stat statbuf;
- char fullfile[TOKU_PATH_MAX+1];
- r = toku_stat(toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, "test.db"), &statbuf);
- assert(r!=0);
- assert(errno==ENOENT);
+ char fullfile[TOKU_PATH_MAX + 1];
+ r = toku_stat(
+ toku_path_join(fullfile, 2, TOKU_TEST_FILENAME, "test.db"),
+ &statbuf,
+ toku_uninstrumented);
+ assert(r != 0);
+ assert(errno == ENOENT);
}
r = env->close(env, 0); assert(r == 0);
diff --git a/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h b/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
index f2bacceed9d..e232f327d10 100644
--- a/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
+++ b/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
@@ -469,11 +469,11 @@ static int get_commit_flags(struct cli_args *args) {
}
struct worker_extra {
- struct arg* thread_arg;
+ struct arg *thread_arg;
toku_mutex_t *operation_lock_mutex;
- struct rwlock *operation_lock;
+ struct st_rwlock *operation_lock;
uint64_t *counters;
- int64_t pad[4]; // pad to 64 bytes
+ int64_t pad[4]; // pad to 64 bytes
};
static void lock_worker_op(struct worker_extra* we) {
@@ -1772,11 +1772,12 @@ static int run_workers(
)
{
int r;
- const struct perf_formatter *perf_formatter = &perf_formatters[cli_args->perf_output_format];
+ const struct perf_formatter *perf_formatter =
+ &perf_formatters[cli_args->perf_output_format];
toku_mutex_t mutex = ZERO_MUTEX_INITIALIZER;
- toku_mutex_init(&mutex, nullptr);
- struct rwlock rwlock;
- rwlock_init(&rwlock);
+ toku_mutex_init(toku_uninstrumented, &mutex, nullptr);
+ struct st_rwlock rwlock;
+ rwlock_init(toku_uninstrumented, &rwlock);
toku_pthread_t tids[num_threads];
toku_pthread_t time_tid;
if (cli_args->print_performance) {
@@ -1798,15 +1799,26 @@ static int run_workers(
worker_extra[i].thread_arg = &thread_args[i];
worker_extra[i].operation_lock = &rwlock;
worker_extra[i].operation_lock_mutex = &mutex;
- XCALLOC_N((int) NUM_OPERATION_TYPES, worker_extra[i].counters);
+ XCALLOC_N((int)NUM_OPERATION_TYPES, worker_extra[i].counters);
TOKU_DRD_IGNORE_VAR(worker_extra[i].counters);
- { int chk_r = toku_pthread_create(&tids[i], nullptr, worker, &worker_extra[i]); CKERR(chk_r); }
+ {
+ int chk_r = toku_pthread_create(toku_uninstrumented,
+ &tids[i],
+ nullptr,
+ worker,
+ &worker_extra[i]);
+ CKERR(chk_r);
+ }
if (verbose)
- printf("%lu created\n", (unsigned long) tids[i]);
+ printf("%lu created\n", (unsigned long)tids[i]);
+ }
+ {
+ int chk_r = toku_pthread_create(
+ toku_uninstrumented, &time_tid, nullptr, test_time, &tte);
+ CKERR(chk_r);
}
- { int chk_r = toku_pthread_create(&time_tid, nullptr, test_time, &tte); CKERR(chk_r); }
if (verbose)
- printf("%lu created\n", (unsigned long) time_tid);
+ printf("%lu created\n", (unsigned long)time_tid);
void *ret;
r = toku_pthread_join(time_tid, &ret); assert_zero(r);
@@ -1817,17 +1829,22 @@ static int run_workers(
// threads (i.e. there is some runaway thread).
struct sleep_and_crash_extra sac_extra;
ZERO_STRUCT(sac_extra);
- toku_mutex_init(&sac_extra.mutex, nullptr);
- toku_cond_init(&sac_extra.cond, nullptr);
+ toku_mutex_init(toku_uninstrumented, &sac_extra.mutex, nullptr);
+ toku_cond_init(toku_uninstrumented, &sac_extra.cond, nullptr);
sac_extra.seconds = cli_args->join_timeout;
sac_extra.is_setup = false;
sac_extra.threads_have_joined = false;
toku_mutex_lock(&sac_extra.mutex);
toku_pthread_t sac_thread;
- r = toku_pthread_create(&sac_thread, nullptr, sleep_and_crash, &sac_extra);
+ r = toku_pthread_create(toku_uninstrumented,
+ &sac_thread,
+ nullptr,
+ sleep_and_crash,
+ &sac_extra);
assert_zero(r);
- // Wait for sleep_and_crash thread to get set up, spinning is ok, this should be quick.
+ // Wait for sleep_and_crash thread to get set up, spinning is ok, this
+ // should be quick.
while (!sac_extra.is_setup) {
toku_mutex_unlock(&sac_extra.mutex);
r = toku_pthread_yield();
diff --git a/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc b/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc
index 30cc16d73a7..469e78f492f 100644
--- a/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc
+++ b/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc
@@ -52,8 +52,8 @@ struct test_sync {
static void test_sync_init(struct test_sync *UU(sync)) {
#if TOKU_DEBUG_TXN_SYNC
sync->state = 0;
- toku_mutex_init(&sync->lock, NULL);
- toku_cond_init(&sync->cv, NULL);
+ toku_mutex_init(toku_uninstrumented, &sync->lock, nullptr);
+ toku_cond_init(toku_uninstrumented, &sync->cv, nullptr);
#endif
}
diff --git a/storage/tokudb/PerconaFT/src/ydb.cc b/storage/tokudb/PerconaFT/src/ydb.cc
index 1edfe9c81f9..41f48d4ec09 100644
--- a/storage/tokudb/PerconaFT/src/ydb.cc
+++ b/storage/tokudb/PerconaFT/src/ydb.cc
@@ -227,7 +227,7 @@ env_fs_poller(void *arg) {
int in_red; // set true to prevent certain operations (returning ENOSPC)
// get the fs sizes for the home dir
- uint64_t avail_size, total_size;
+ uint64_t avail_size = 0, total_size = 0;
r = toku_get_filesystem_sizes(env->i->dir, &avail_size, NULL, &total_size);
assert(r == 0);
in_yellow = (avail_size < 2 * env_fs_redzone(env, total_size));
@@ -643,7 +643,7 @@ static int validate_env(DB_ENV *env,
path = toku_construct_full_name(
2, env->i->dir, toku_product_name_strings.environmentdictionary);
assert(path);
- r = toku_stat(path, &buf);
+ r = toku_stat(path, &buf, toku_uninstrumented);
if (r == 0) {
expect_newenv = false; // persistent info exists
} else {
@@ -668,7 +668,7 @@ static int validate_env(DB_ENV *env,
path = toku_construct_full_name(
2, env->i->dir, toku_product_name_strings.rollback_cachefile);
assert(path);
- r = toku_stat(path, &buf);
+ r = toku_stat(path, &buf, toku_uninstrumented);
if (r == 0) {
if (expect_newenv) // rollback cachefile exists, but persistent env
// is missing
@@ -710,7 +710,7 @@ static int validate_env(DB_ENV *env,
path = toku_construct_full_name(
2, env->i->dir, toku_product_name_strings.fileopsdirectory);
assert(path);
- r = toku_stat(path, &buf);
+ r = toku_stat(path, &buf, toku_uninstrumented);
if (r == 0) {
if (expect_newenv) // fileops directory exists, but persistent env
// is missing
@@ -856,10 +856,11 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
// Verify that the home exists.
toku_struct_stat buf;
- r = toku_stat(home, &buf);
+ r = toku_stat(home, &buf, toku_uninstrumented);
if (r != 0) {
int e = get_error_errno();
- r = toku_ydb_do_error(env, e, "Error from toku_stat(\"%s\",...)\n", home);
+ r = toku_ydb_do_error(
+ env, e, "Error from toku_stat(\"%s\",...)\n", home);
goto cleanup;
}
unused_flags &= ~DB_PRIVATE;
@@ -875,13 +876,22 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
env->i->open_flags = flags;
env->i->open_mode = mode;
+ // Instrumentation probe start
+ TOKU_PROBE_START(toku_instr_probe_1);
+
env_setup_real_data_dir(env);
env_setup_real_log_dir(env);
env_setup_real_tmp_dir(env);
- r = toku_single_process_lock(env->i->dir, "environment", &env->i->envdir_lockfd);
- if (r!=0) goto cleanup;
- r = toku_single_process_lock(env->i->real_data_dir, "data", &env->i->datadir_lockfd);
+ // Instrumentation probe stop
+ toku_instr_probe_1->stop();
+
+ r = toku_single_process_lock(
+ env->i->dir, "environment", &env->i->envdir_lockfd);
+ if (r != 0)
+ goto cleanup;
+ r = toku_single_process_lock(
+ env->i->real_data_dir, "data", &env->i->datadir_lockfd);
if (r!=0) goto cleanup;
r = toku_single_process_lock(env->i->real_log_dir, "logs", &env->i->logdir_lockfd);
if (r!=0) goto cleanup;
@@ -2931,7 +2941,8 @@ toku_env_create(DB_ENV ** envp, uint32_t flags) {
result->i->open_dbs_by_dname->create();
XMALLOC(result->i->open_dbs_by_dict_id);
result->i->open_dbs_by_dict_id->create();
- toku_pthread_rwlock_init(&result->i->open_dbs_rwlock, NULL);
+ toku_pthread_rwlock_init(
+ *result_i_open_dbs_rwlock_key, &result->i->open_dbs_rwlock, nullptr);
*envp = result;
r = 0;
diff --git a/storage/tokudb/PerconaFT/src/ydb_db.cc b/storage/tokudb/PerconaFT/src/ydb_db.cc
index 100d1bfa20b..40c4a7f6577 100644
--- a/storage/tokudb/PerconaFT/src/ydb_db.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_db.cc
@@ -83,53 +83,56 @@ ydb_db_layer_get_status(YDB_DB_LAYER_STATUS statp) {
*statp = ydb_db_layer_status;
}
-void create_iname_hint(const char *dname, char *hint) {
+void create_iname_hint(DB_ENV *env, const char *dname, char *hint) {
//Requires: size of hint array must be > strlen(dname)
//Copy alphanumeric characters only.
//Replace strings of non-alphanumeric characters with a single underscore.
- bool underscored = false;
- while (*dname) {
- if (isalnum(*dname)) {
- char c = *dname++;
- *hint++ = c;
- underscored = false;
- }
- else {
- if (!underscored)
- *hint++ = '_';
- dname++;
- underscored = true;
+ if (env->get_dir_per_db(env) && !toku_os_is_absolute_name(dname)) {
+ assert(dname);
+ if (*dname == '.')
+ ++dname;
+ if (*dname == '/')
+ ++dname;
+ bool underscored = false;
+ bool dbdir_is_parsed = false;
+ // Do not change the first '/' because this is
+ // delimiter which splits name into database dir
+ // and table dir.
+ while (*dname) {
+ if (isalnum(*dname) || (*dname == '/' && !dbdir_is_parsed)) {
+ char c = *dname++;
+ *hint++ = c;
+ if (c == '/')
+ dbdir_is_parsed = true;
+ underscored = false;
+ } else if (!dbdir_is_parsed) {
+ char c = *dname++;
+ *hint++ = c;
+ } else {
+ if (!underscored)
+ *hint++ = '_';
+ dname++;
+ underscored = true;
+ }
}
- }
- *hint = '\0';
-}
-
-void create_iname_hint_for_dbdir(const char *dname, char *hint) {
- assert(dname);
- if (*dname == '.')
- ++dname;
- if (*dname == '/')
- ++dname;
- bool underscored = false;
- bool dbdir_is_parsed = false;
- // Do not change the first '/' because this is
- // delimiter which splits name into database dir
- // and table dir.
- while (*dname) {
- if (isalnum(*dname) || (*dname == '/' && !dbdir_is_parsed)) {
- char c = *dname++;
- *hint++ = c;
- if (c == '/')
- dbdir_is_parsed = true;
- underscored = false;
- } else {
- if (!underscored)
- *hint++ = '_';
- dname++;
- underscored = true;
+ *hint = '\0';
+ } else {
+ bool underscored = false;
+ while (*dname) {
+ if (isalnum(*dname)) {
+ char c = *dname++;
+ *hint++ = c;
+ underscored = false;
+ }
+ else {
+ if (!underscored)
+ *hint++ = '_';
+ dname++;
+ underscored = true;
+ }
}
+ *hint = '\0';
}
- *hint = '\0';
}
// n < 0 means to ignore mark and ignore n
@@ -187,10 +190,7 @@ std::unique_ptr<char[], decltype(&toku_free)> generate_iname_for_rename_or_open(
} else if (is_open)
id1 = toku_sync_fetch_and_add(&nontransactional_open_id, 1);
- if (env->get_dir_per_db(env) && !toku_os_is_absolute_name(dname))
- create_iname_hint_for_dbdir(dname, hint);
- else
- create_iname_hint(dname, hint);
+ create_iname_hint(env, dname, hint);
result.reset(create_iname(env, id1, id2, hint, NULL, -1));
@@ -1221,15 +1221,18 @@ load_inames(DB_ENV * env, DB_TXN * txn, int N, DB * dbs[/*N*/], const char * new
for (i = 0; i < N; i++) {
char * dname = dbs[i]->i->dname;
toku_fill_dbt(&dname_dbt, dname, strlen(dname)+1);
+
// now create new iname
char hint[strlen(dname) + 1];
- if (env->get_dir_per_db(env) && !toku_os_is_absolute_name(dname))
- create_iname_hint_for_dbdir(dname, hint);
- else
- create_iname_hint(dname, hint);
- const char *new_iname = create_iname(env, xid.parent_id64, xid.child_id64, hint, mark, i); // allocates memory for iname_in_env
+ create_iname_hint(env, dname, hint);
+
+ // allocates memory for iname_in_env
+ const char *new_iname =
+ create_iname(env, xid.parent_id64, xid.child_id64, hint, mark, i);
new_inames_in_env[i] = new_iname;
- toku_fill_dbt(&iname_dbt, new_iname, strlen(new_iname) + 1); // iname_in_env goes in directory
+
+ // iname_in_env goes in directory
+ toku_fill_dbt(&iname_dbt, new_iname, strlen(new_iname) + 1);
rval = toku_db_put(env->i->directory, txn, &dname_dbt, &iname_dbt, 0, true);
if (rval) break;
}
diff --git a/storage/tokudb/PerconaFT/src/ydb_db.h b/storage/tokudb/PerconaFT/src/ydb_db.h
index 8be28857c14..ab8fcd2a401 100644
--- a/storage/tokudb/PerconaFT/src/ydb_db.h
+++ b/storage/tokudb/PerconaFT/src/ydb_db.h
@@ -122,8 +122,7 @@ toku_db_destruct_autotxn(DB_TXN *txn, int r, bool changed) {
return r;
}
-void create_iname_hint_for_dbdir(const char *dname, char *hint);
-void create_iname_hint(const char *dname, char *hint);
+void create_iname_hint(DB_ENV *env, const char *dname, char *hint);
char *create_iname(DB_ENV *env,
uint64_t id1,
uint64_t id2,
diff --git a/storage/tokudb/PerconaFT/src/ydb_env_func.cc b/storage/tokudb/PerconaFT/src/ydb_env_func.cc
index 13c56fec6bf..b8f0a634116 100644
--- a/storage/tokudb/PerconaFT/src/ydb_env_func.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_env_func.cc
@@ -109,7 +109,7 @@ void db_env_set_func_pread (ssize_t (*fun)(int, void *, size_t, off_t)) {
}
void db_env_set_func_loader_fwrite (size_t (*fwrite_fun)(const void*,size_t,size_t,FILE*)) {
- ft_loader_set_os_fwrite(fwrite_fun);
+ toku_set_func_fwrite(fwrite_fun);
}
void db_env_set_func_malloc (void *(*f)(size_t)) {
diff --git a/storage/tokudb/PerconaFT/src/ydb_txn.cc b/storage/tokudb/PerconaFT/src/ydb_txn.cc
index 40b479055f2..dd5fb3b8f0c 100644
--- a/storage/tokudb/PerconaFT/src/ydb_txn.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_txn.cc
@@ -540,10 +540,12 @@ int toku_txn_begin(DB_ENV *env, DB_TXN * stxn, DB_TXN ** txn, uint32_t flags) {
db_txn_struct_i(result)->iso = child_isolation;
db_txn_struct_i(result)->lt_map.create_no_array();
- toku_mutex_init(&db_txn_struct_i(result)->txn_mutex, NULL);
+ toku_mutex_init(*db_txn_struct_i_txn_mutex_key,
+ &db_txn_struct_i(result)->txn_mutex,
+ nullptr);
TXN_SNAPSHOT_TYPE snapshot_type;
- switch(db_txn_struct_i(result)->iso){
+ switch (db_txn_struct_i(result)->iso) {
case(TOKU_ISO_SNAPSHOT):
{
snapshot_type = TXN_SNAPSHOT_ROOT;
@@ -603,7 +605,9 @@ void toku_keep_prepared_txn_callback (DB_ENV *env, TOKUTXN tokutxn) {
toku_txn_set_container_db_txn(tokutxn, result);
- toku_mutex_init(&db_txn_struct_i(result)->txn_mutex, NULL);
+ toku_mutex_init(*db_txn_struct_i_txn_mutex_key,
+ &db_txn_struct_i(result)->txn_mutex,
+ nullptr);
}
// Test-only function
diff --git a/storage/tokudb/PerconaFT/tools/CMakeLists.txt b/storage/tokudb/PerconaFT/tools/CMakeLists.txt
index e6540bf69be..af40a838b9a 100644
--- a/storage/tokudb/PerconaFT/tools/CMakeLists.txt
+++ b/storage/tokudb/PerconaFT/tools/CMakeLists.txt
@@ -12,6 +12,7 @@ foreach(tool ${tools})
(CMAKE_CXX_FLAGS_DEBUG MATCHES " -DENABLED_DEBUG_SYNC"))
target_link_libraries(${tool} sql)
endif()
+ target_link_libraries(${tool} mysqlclient)
endif ()
add_space_separated_property(TARGET ${tool} COMPILE_FLAGS -fvisibility=hidden)
diff --git a/storage/tokudb/PerconaFT/util/dbt.cc b/storage/tokudb/PerconaFT/util/dbt.cc
index 5bc1cb7446f..b6d2a584a45 100644
--- a/storage/tokudb/PerconaFT/util/dbt.cc
+++ b/storage/tokudb/PerconaFT/util/dbt.cc
@@ -199,7 +199,8 @@ int toku_dbt_set(uint32_t len, const void *val, DBT *d, struct simple_dbt *sdbt)
case (DB_DBT_MALLOC):
d->data = NULL;
d->ulen = 0;
- //Fall through to DB_DBT_REALLOC
+ // fallthrough
+ // to DB_DBT_REALLOC
case (DB_DBT_REALLOC):
if (d->ulen < len) {
d->ulen = len*2;
diff --git a/storage/tokudb/PerconaFT/util/fmutex.h b/storage/tokudb/PerconaFT/util/fmutex.h
index 9ff95978a16..fed1bc24a92 100644
--- a/storage/tokudb/PerconaFT/util/fmutex.h
+++ b/storage/tokudb/PerconaFT/util/fmutex.h
@@ -38,6 +38,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#pragma once
+extern toku_instr_key *fmutex_cond_key;
+
// fair mutex
struct fmutex {
pthread_mutex_t mutex;
@@ -98,8 +100,8 @@ void fmutex_lock(struct fmutex *fm) {
}
pthread_cond_t cond;
- pthread_cond_init(&cond, NULL);
- struct queue_item item = { .cond = &cond, .next = NULL };
+ pthread_cond_init(*fmutex_cond_key, &cond, nullptr);
+ struct queue_item item = {.cond = &cond, .next = NULL};
enq_item(fm, &item);
// Wait for our turn.
diff --git a/storage/tokudb/PerconaFT/util/frwlock.cc b/storage/tokudb/PerconaFT/util/frwlock.cc
index ce1e33e85d3..1f821fe5f54 100644
--- a/storage/tokudb/PerconaFT/util/frwlock.cc
+++ b/storage/tokudb/PerconaFT/util/frwlock.cc
@@ -41,271 +41,311 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include <util/context.h>
#include <util/frwlock.h>
+toku_instr_key *frwlock_m_wait_read_key;
+
namespace toku {
-static __thread int thread_local_tid = -1;
-static int get_local_tid() {
- if (thread_local_tid == -1) {
- thread_local_tid = toku_os_gettid();
- }
- return thread_local_tid;
-}
-
-void frwlock::init(toku_mutex_t *const mutex) {
- m_mutex = mutex;
-
- m_num_readers = 0;
- m_num_writers = 0;
- m_num_want_write = 0;
- m_num_want_read = 0;
- m_num_signaled_readers = 0;
- m_num_expensive_want_write = 0;
-
- toku_cond_init(&m_wait_read, nullptr);
- m_queue_item_read.cond = &m_wait_read;
- m_queue_item_read.next = nullptr;
- m_wait_read_is_in_queue = false;
- m_current_writer_expensive = false;
- m_read_wait_expensive = false;
- m_current_writer_tid = -1;
- m_blocking_writer_context_id = CTX_INVALID;
-
- m_wait_head = nullptr;
- m_wait_tail = nullptr;
-}
-
-void frwlock::deinit(void) {
- toku_cond_destroy(&m_wait_read);
-}
-
-bool frwlock::queue_is_empty(void) const {
- return m_wait_head == nullptr;
-}
-
-void frwlock::enq_item(queue_item *const item) {
- paranoid_invariant_null(item->next);
- if (m_wait_tail != nullptr) {
- m_wait_tail->next = item;
- } else {
- paranoid_invariant_null(m_wait_head);
- m_wait_head = item;
+ static __thread int thread_local_tid = -1;
+ static int get_local_tid() {
+ if (thread_local_tid == -1) {
+ thread_local_tid = toku_os_gettid();
+ }
+ return thread_local_tid;
}
- m_wait_tail = item;
-}
-
-toku_cond_t *frwlock::deq_item(void) {
- paranoid_invariant_notnull(m_wait_head);
- paranoid_invariant_notnull(m_wait_tail);
- queue_item *item = m_wait_head;
- m_wait_head = m_wait_head->next;
- if (m_wait_tail == item) {
+
+ void frwlock::init(toku_mutex_t *const mutex
+#if defined(TOKU_MYSQL_WITH_PFS)
+ ,
+ const toku_instr_key &rwlock_instr_key
+#endif
+ ) {
+ m_mutex = mutex;
+
+ m_num_readers = 0;
+ m_num_writers = 0;
+ m_num_want_write = 0;
+ m_num_want_read = 0;
+ m_num_signaled_readers = 0;
+ m_num_expensive_want_write = 0;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_init(rwlock_instr_key, &m_rwlock, nullptr);
+#endif
+ toku_cond_init(toku_uninstrumented, &m_wait_read, nullptr);
+ m_queue_item_read.cond = &m_wait_read;
+ m_queue_item_read.next = nullptr;
+ m_wait_read_is_in_queue = false;
+ m_current_writer_expensive = false;
+ m_read_wait_expensive = false;
+ m_current_writer_tid = -1;
+ m_blocking_writer_context_id = CTX_INVALID;
+
+ m_wait_head = nullptr;
m_wait_tail = nullptr;
}
- return item->cond;
-}
-
-// Prerequisite: Holds m_mutex.
-void frwlock::write_lock(bool expensive) {
- toku_mutex_assert_locked(m_mutex);
- if (this->try_write_lock(expensive)) {
- return;
+
+ void frwlock::deinit(void) {
+ toku_cond_destroy(&m_wait_read);
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_destroy(&m_rwlock);
+#endif
}
- toku_cond_t cond = TOKU_COND_INITIALIZER;
- queue_item item = { .cond = &cond, .next = nullptr };
- this->enq_item(&item);
+ bool frwlock::queue_is_empty(void) const { return m_wait_head == nullptr; }
- // Wait for our turn.
- ++m_num_want_write;
- if (expensive) {
- ++m_num_expensive_want_write;
- }
- if (m_num_writers == 0 && m_num_want_write == 1) {
- // We are the first to want a write lock. No new readers can get the lock.
- // Set our thread id and context for proper instrumentation.
- // see: toku_context_note_frwlock_contention()
- m_current_writer_tid = get_local_tid();
- m_blocking_writer_context_id = toku_thread_get_context()->get_id();
- }
- toku_cond_wait(&cond, m_mutex);
- toku_cond_destroy(&cond);
-
- // Now it's our turn.
- paranoid_invariant(m_num_want_write > 0);
- paranoid_invariant_zero(m_num_readers);
- paranoid_invariant_zero(m_num_writers);
- paranoid_invariant_zero(m_num_signaled_readers);
-
- // Not waiting anymore; grab the lock.
- --m_num_want_write;
- if (expensive) {
- --m_num_expensive_want_write;
+ void frwlock::enq_item(queue_item *const item) {
+ paranoid_invariant_null(item->next);
+ if (m_wait_tail != nullptr) {
+ m_wait_tail->next = item;
+ } else {
+ paranoid_invariant_null(m_wait_head);
+ m_wait_head = item;
+ }
+ m_wait_tail = item;
}
- m_num_writers = 1;
- m_current_writer_expensive = expensive;
- m_current_writer_tid = get_local_tid();
- m_blocking_writer_context_id = toku_thread_get_context()->get_id();
-}
-
-bool frwlock::try_write_lock(bool expensive) {
- toku_mutex_assert_locked(m_mutex);
- if (m_num_readers > 0 || m_num_writers > 0 || m_num_signaled_readers > 0 || m_num_want_write > 0) {
- return false;
+
+ toku_cond_t *frwlock::deq_item(void) {
+ paranoid_invariant_notnull(m_wait_head);
+ paranoid_invariant_notnull(m_wait_tail);
+ queue_item *item = m_wait_head;
+ m_wait_head = m_wait_head->next;
+ if (m_wait_tail == item) {
+ m_wait_tail = nullptr;
+ }
+ return item->cond;
}
- // No one holds the lock. Grant the write lock.
- paranoid_invariant_zero(m_num_want_write);
- paranoid_invariant_zero(m_num_want_read);
- m_num_writers = 1;
- m_current_writer_expensive = expensive;
- m_current_writer_tid = get_local_tid();
- m_blocking_writer_context_id = toku_thread_get_context()->get_id();
- return true;
-}
-
-void frwlock::read_lock(void) {
- toku_mutex_assert_locked(m_mutex);
- if (m_num_writers > 0 || m_num_want_write > 0) {
- if (!m_wait_read_is_in_queue) {
- // Throw the read cond_t onto the queue.
- paranoid_invariant(m_num_signaled_readers == m_num_want_read);
- m_queue_item_read.next = nullptr;
- this->enq_item(&m_queue_item_read);
- m_wait_read_is_in_queue = true;
- paranoid_invariant(!m_read_wait_expensive);
- m_read_wait_expensive = (
- m_current_writer_expensive ||
- (m_num_expensive_want_write > 0)
- );
+
+ // Prerequisite: Holds m_mutex.
+ void frwlock::write_lock(bool expensive) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ toku_instr_rwlock_wrlock_wait_start(
+ rwlock_instr, m_rwlock, __FILE__, __LINE__);
+#endif
+
+ toku_mutex_assert_locked(m_mutex);
+ if (this->try_write_lock(expensive)) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation end */
+ toku_instr_rwlock_wrlock_wait_end(rwlock_instr, 0);
+#endif
+ return;
}
- // Note this contention event in engine status.
- toku_context_note_frwlock_contention(
- toku_thread_get_context()->get_id(),
- m_blocking_writer_context_id
- );
+ toku_cond_t cond = TOKU_COND_INITIALIZER;
+ queue_item item = {.cond = &cond, .next = nullptr};
+ this->enq_item(&item);
// Wait for our turn.
- ++m_num_want_read;
- toku_cond_wait(&m_wait_read, m_mutex);
+ ++m_num_want_write;
+ if (expensive) {
+ ++m_num_expensive_want_write;
+ }
+ if (m_num_writers == 0 && m_num_want_write == 1) {
+ // We are the first to want a write lock. No new readers can get the
+ // lock.
+ // Set our thread id and context for proper instrumentation.
+ // see: toku_context_note_frwlock_contention()
+ m_current_writer_tid = get_local_tid();
+ m_blocking_writer_context_id = toku_thread_get_context()->get_id();
+ }
+ toku_cond_wait(&cond, m_mutex);
+ toku_cond_destroy(&cond);
// Now it's our turn.
+ paranoid_invariant(m_num_want_write > 0);
+ paranoid_invariant_zero(m_num_readers);
paranoid_invariant_zero(m_num_writers);
- paranoid_invariant(m_num_want_read > 0);
- paranoid_invariant(m_num_signaled_readers > 0);
+ paranoid_invariant_zero(m_num_signaled_readers);
// Not waiting anymore; grab the lock.
- --m_num_want_read;
- --m_num_signaled_readers;
+ --m_num_want_write;
+ if (expensive) {
+ --m_num_expensive_want_write;
+ }
+ m_num_writers = 1;
+ m_current_writer_expensive = expensive;
+ m_current_writer_tid = get_local_tid();
+ m_blocking_writer_context_id = toku_thread_get_context()->get_id();
+
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation end */
+ toku_instr_rwlock_wrlock_wait_end(rwlock_instr, 0);
+#endif
+ }
+
+ bool frwlock::try_write_lock(bool expensive) {
+ toku_mutex_assert_locked(m_mutex);
+ if (m_num_readers > 0 || m_num_writers > 0 ||
+ m_num_signaled_readers > 0 || m_num_want_write > 0) {
+ return false;
+ }
+ // No one holds the lock. Grant the write lock.
+ paranoid_invariant_zero(m_num_want_write);
+ paranoid_invariant_zero(m_num_want_read);
+ m_num_writers = 1;
+ m_current_writer_expensive = expensive;
+ m_current_writer_tid = get_local_tid();
+ m_blocking_writer_context_id = toku_thread_get_context()->get_id();
+ return true;
}
- ++m_num_readers;
-}
-bool frwlock::try_read_lock(void) {
- toku_mutex_assert_locked(m_mutex);
- if (m_num_writers > 0 || m_num_want_write > 0) {
- return false;
+ void frwlock::read_lock(void) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ toku_instr_rwlock_rdlock_wait_start(
+ rwlock_instr, m_rwlock, __FILE__, __LINE__);
+#endif
+ toku_mutex_assert_locked(m_mutex);
+ if (m_num_writers > 0 || m_num_want_write > 0) {
+ if (!m_wait_read_is_in_queue) {
+ // Throw the read cond_t onto the queue.
+ paranoid_invariant(m_num_signaled_readers == m_num_want_read);
+ m_queue_item_read.next = nullptr;
+ this->enq_item(&m_queue_item_read);
+ m_wait_read_is_in_queue = true;
+ paranoid_invariant(!m_read_wait_expensive);
+ m_read_wait_expensive = (m_current_writer_expensive ||
+ (m_num_expensive_want_write > 0));
+ }
+
+ // Note this contention event in engine status.
+ toku_context_note_frwlock_contention(
+ toku_thread_get_context()->get_id(),
+ m_blocking_writer_context_id);
+
+ // Wait for our turn.
+ ++m_num_want_read;
+ toku_cond_wait(&m_wait_read, m_mutex);
+
+ // Now it's our turn.
+ paranoid_invariant_zero(m_num_writers);
+ paranoid_invariant(m_num_want_read > 0);
+ paranoid_invariant(m_num_signaled_readers > 0);
+
+ // Not waiting anymore; grab the lock.
+ --m_num_want_read;
+ --m_num_signaled_readers;
+ }
+ ++m_num_readers;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation end */
+ toku_instr_rwlock_rdlock_wait_end(rwlock_instr, 0);
+#endif
}
- // No writer holds the lock.
- // No writers are waiting.
- // Grant the read lock.
- ++m_num_readers;
- return true;
-}
-
-void frwlock::maybe_signal_next_writer(void) {
- if (m_num_want_write > 0 && m_num_signaled_readers == 0 && m_num_readers == 0) {
- toku_cond_t *cond = this->deq_item();
- paranoid_invariant(cond != &m_wait_read);
- // Grant write lock to waiting writer.
- paranoid_invariant(m_num_want_write > 0);
- toku_cond_signal(cond);
+
+ bool frwlock::try_read_lock(void) {
+ toku_mutex_assert_locked(m_mutex);
+ if (m_num_writers > 0 || m_num_want_write > 0) {
+ return false;
+ }
+ // No writer holds the lock.
+ // No writers are waiting.
+ // Grant the read lock.
+ ++m_num_readers;
+ return true;
}
-}
-
-void frwlock::read_unlock(void) {
- toku_mutex_assert_locked(m_mutex);
- paranoid_invariant(m_num_writers == 0);
- paranoid_invariant(m_num_readers > 0);
- --m_num_readers;
- this->maybe_signal_next_writer();
-}
-
-bool frwlock::read_lock_is_expensive(void) {
- toku_mutex_assert_locked(m_mutex);
- if (m_wait_read_is_in_queue) {
- return m_read_wait_expensive;
+
+ void frwlock::maybe_signal_next_writer(void) {
+ if (m_num_want_write > 0 && m_num_signaled_readers == 0 &&
+ m_num_readers == 0) {
+ toku_cond_t *cond = this->deq_item();
+ paranoid_invariant(cond != &m_wait_read);
+ // Grant write lock to waiting writer.
+ paranoid_invariant(m_num_want_write > 0);
+ toku_cond_signal(cond);
+ }
+ }
+
+ void frwlock::read_unlock(void) {
+#ifdef TOKU_MYSQL_WITH_PFS
+ toku_instr_rwlock_unlock(m_rwlock);
+#endif
+ toku_mutex_assert_locked(m_mutex);
+ paranoid_invariant(m_num_writers == 0);
+ paranoid_invariant(m_num_readers > 0);
+ --m_num_readers;
+ this->maybe_signal_next_writer();
}
- else {
- return m_current_writer_expensive || (m_num_expensive_want_write > 0);
+
+ bool frwlock::read_lock_is_expensive(void) {
+ toku_mutex_assert_locked(m_mutex);
+ if (m_wait_read_is_in_queue) {
+ return m_read_wait_expensive;
+ } else {
+ return m_current_writer_expensive ||
+ (m_num_expensive_want_write > 0);
+ }
}
-}
+ void frwlock::maybe_signal_or_broadcast_next(void) {
+ paranoid_invariant(m_num_signaled_readers == 0);
-void frwlock::maybe_signal_or_broadcast_next(void) {
- paranoid_invariant(m_num_signaled_readers == 0);
+ if (this->queue_is_empty()) {
+ paranoid_invariant(m_num_want_write == 0);
+ paranoid_invariant(m_num_want_read == 0);
+ return;
+ }
+ toku_cond_t *cond = this->deq_item();
+ if (cond == &m_wait_read) {
+ // Grant read locks to all waiting readers
+ paranoid_invariant(m_wait_read_is_in_queue);
+ paranoid_invariant(m_num_want_read > 0);
+ m_num_signaled_readers = m_num_want_read;
+ m_wait_read_is_in_queue = false;
+ m_read_wait_expensive = false;
+ toku_cond_broadcast(cond);
+ } else {
+ // Grant write lock to waiting writer.
+ paranoid_invariant(m_num_want_write > 0);
+ toku_cond_signal(cond);
+ }
+ }
- if (this->queue_is_empty()) {
- paranoid_invariant(m_num_want_write == 0);
- paranoid_invariant(m_num_want_read == 0);
- return;
+ void frwlock::write_unlock(void) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_instr_rwlock_unlock(m_rwlock);
+#endif
+ toku_mutex_assert_locked(m_mutex);
+ paranoid_invariant(m_num_writers == 1);
+ m_num_writers = 0;
+ m_current_writer_expensive = false;
+ m_current_writer_tid = -1;
+ m_blocking_writer_context_id = CTX_INVALID;
+ this->maybe_signal_or_broadcast_next();
}
- toku_cond_t *cond = this->deq_item();
- if (cond == &m_wait_read) {
- // Grant read locks to all waiting readers
- paranoid_invariant(m_wait_read_is_in_queue);
- paranoid_invariant(m_num_want_read > 0);
- m_num_signaled_readers = m_num_want_read;
- m_wait_read_is_in_queue = false;
- m_read_wait_expensive = false;
- toku_cond_broadcast(cond);
+ bool frwlock::write_lock_is_expensive(void) {
+ toku_mutex_assert_locked(m_mutex);
+ return (m_num_expensive_want_write > 0) || (m_current_writer_expensive);
}
- else {
- // Grant write lock to waiting writer.
- paranoid_invariant(m_num_want_write > 0);
- toku_cond_signal(cond);
+
+ uint32_t frwlock::users(void) const {
+ toku_mutex_assert_locked(m_mutex);
+ return m_num_readers + m_num_writers + m_num_want_read +
+ m_num_want_write;
+ }
+ uint32_t frwlock::blocked_users(void) const {
+ toku_mutex_assert_locked(m_mutex);
+ return m_num_want_read + m_num_want_write;
+ }
+ uint32_t frwlock::writers(void) const {
+ // this is sometimes called as "assert(lock->writers())" when we
+ // assume we have the write lock. if that's the assumption, we may
+ // not own the mutex, so we don't assert_locked here
+ return m_num_writers;
+ }
+ uint32_t frwlock::blocked_writers(void) const {
+ toku_mutex_assert_locked(m_mutex);
+ return m_num_want_write;
+ }
+ uint32_t frwlock::readers(void) const {
+ toku_mutex_assert_locked(m_mutex);
+ return m_num_readers;
+ }
+ uint32_t frwlock::blocked_readers(void) const {
+ toku_mutex_assert_locked(m_mutex);
+ return m_num_want_read;
}
-}
-
-void frwlock::write_unlock(void) {
- toku_mutex_assert_locked(m_mutex);
- paranoid_invariant(m_num_writers == 1);
- m_num_writers = 0;
- m_current_writer_expensive = false;
- m_current_writer_tid = -1;
- m_blocking_writer_context_id = CTX_INVALID;
- this->maybe_signal_or_broadcast_next();
-}
-bool frwlock::write_lock_is_expensive(void) {
- toku_mutex_assert_locked(m_mutex);
- return (m_num_expensive_want_write > 0) || (m_current_writer_expensive);
-}
-
-
-uint32_t frwlock::users(void) const {
- toku_mutex_assert_locked(m_mutex);
- return m_num_readers + m_num_writers + m_num_want_read + m_num_want_write;
-}
-uint32_t frwlock::blocked_users(void) const {
- toku_mutex_assert_locked(m_mutex);
- return m_num_want_read + m_num_want_write;
-}
-uint32_t frwlock::writers(void) const {
- // this is sometimes called as "assert(lock->writers())" when we
- // assume we have the write lock. if that's the assumption, we may
- // not own the mutex, so we don't assert_locked here
- return m_num_writers;
-}
-uint32_t frwlock::blocked_writers(void) const {
- toku_mutex_assert_locked(m_mutex);
- return m_num_want_write;
-}
-uint32_t frwlock::readers(void) const {
- toku_mutex_assert_locked(m_mutex);
- return m_num_readers;
-}
-uint32_t frwlock::blocked_readers(void) const {
- toku_mutex_assert_locked(m_mutex);
- return m_num_want_read;
-}
} // namespace toku
diff --git a/storage/tokudb/PerconaFT/util/frwlock.h b/storage/tokudb/PerconaFT/util/frwlock.h
index 52b98a8d727..b02d95e545c 100644
--- a/storage/tokudb/PerconaFT/util/frwlock.h
+++ b/storage/tokudb/PerconaFT/util/frwlock.h
@@ -48,76 +48,82 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
namespace toku {
-class frwlock {
-public:
-
- void init(toku_mutex_t *const mutex);
- void deinit(void);
-
- void write_lock(bool expensive);
- bool try_write_lock(bool expensive);
- void write_unlock(void);
- // returns true if acquiring a write lock will be expensive
- bool write_lock_is_expensive(void);
-
- void read_lock(void);
- bool try_read_lock(void);
- void read_unlock(void);
- // returns true if acquiring a read lock will be expensive
- bool read_lock_is_expensive(void);
-
- uint32_t users(void) const;
- uint32_t blocked_users(void) const;
- uint32_t writers(void) const;
- uint32_t blocked_writers(void) const;
- uint32_t readers(void) const;
- uint32_t blocked_readers(void) const;
-
-private:
- struct queue_item {
- toku_cond_t *cond;
- struct queue_item *next;
+ class frwlock {
+ public:
+ void init(toku_mutex_t *const mutex
+#if defined(TOKU_MYSQL_WITH_PFS)
+ ,
+ const toku_instr_key &rwlock_instr_key
+#endif
+ );
+ void deinit(void);
+
+ void write_lock(bool expensive);
+ bool try_write_lock(bool expensive);
+ void write_unlock(void);
+ // returns true if acquiring a write lock will be expensive
+ bool write_lock_is_expensive(void);
+
+ void read_lock(void);
+ bool try_read_lock(void);
+ void read_unlock(void);
+ // returns true if acquiring a read lock will be expensive
+ bool read_lock_is_expensive(void);
+
+ uint32_t users(void) const;
+ uint32_t blocked_users(void) const;
+ uint32_t writers(void) const;
+ uint32_t blocked_writers(void) const;
+ uint32_t readers(void) const;
+ uint32_t blocked_readers(void) const;
+
+ private:
+ struct queue_item {
+ toku_cond_t *cond;
+ struct queue_item *next;
+ };
+
+ bool queue_is_empty(void) const;
+ void enq_item(queue_item *const item);
+ toku_cond_t *deq_item(void);
+ void maybe_signal_or_broadcast_next(void);
+ void maybe_signal_next_writer(void);
+
+ toku_mutex_t *m_mutex;
+
+ uint32_t m_num_readers;
+ uint32_t m_num_writers;
+ uint32_t m_num_want_write;
+ uint32_t m_num_want_read;
+ uint32_t m_num_signaled_readers;
+ // number of writers waiting that are expensive
+ // MUST be < m_num_want_write
+ uint32_t m_num_expensive_want_write;
+ // bool that states if the current writer is expensive
+ // if there is no current writer, then is false
+ bool m_current_writer_expensive;
+ // bool that states if waiting for a read
+ // is expensive
+ // if there are currently no waiting readers, then set to false
+ bool m_read_wait_expensive;
+ // thread-id of the current writer
+ int m_current_writer_tid;
+ // context id describing the context of the current writer blocking
+ // new readers (either because this writer holds the write lock or
+ // is the first to want the write lock).
+ context_id m_blocking_writer_context_id;
+ queue_item m_queue_item_read;
+ bool m_wait_read_is_in_queue;
+
+ toku_cond_t m_wait_read;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_t m_rwlock;
+#endif
+ queue_item *m_wait_head;
+ queue_item *m_wait_tail;
};
- bool queue_is_empty(void) const;
- void enq_item(queue_item *const item);
- toku_cond_t *deq_item(void);
- void maybe_signal_or_broadcast_next(void);
- void maybe_signal_next_writer(void);
-
- toku_mutex_t *m_mutex;
-
- uint32_t m_num_readers;
- uint32_t m_num_writers;
- uint32_t m_num_want_write;
- uint32_t m_num_want_read;
- uint32_t m_num_signaled_readers;
- // number of writers waiting that are expensive
- // MUST be < m_num_want_write
- uint32_t m_num_expensive_want_write;
- // bool that states if the current writer is expensive
- // if there is no current writer, then is false
- bool m_current_writer_expensive;
- // bool that states if waiting for a read
- // is expensive
- // if there are currently no waiting readers, then set to false
- bool m_read_wait_expensive;
- // thread-id of the current writer
- int m_current_writer_tid;
- // context id describing the context of the current writer blocking
- // new readers (either because this writer holds the write lock or
- // is the first to want the write lock).
- context_id m_blocking_writer_context_id;
-
- toku_cond_t m_wait_read;
- queue_item m_queue_item_read;
- bool m_wait_read_is_in_queue;
-
- queue_item *m_wait_head;
- queue_item *m_wait_tail;
-};
-
-ENSURE_POD(frwlock);
+ ENSURE_POD(frwlock);
} // namespace toku
diff --git a/storage/tokudb/PerconaFT/util/kibbutz.cc b/storage/tokudb/PerconaFT/util/kibbutz.cc
index 7fc24bae727..409bf6bdd7b 100644
--- a/storage/tokudb/PerconaFT/util/kibbutz.cc
+++ b/storage/tokudb/PerconaFT/util/kibbutz.cc
@@ -72,14 +72,18 @@ struct kibbutz {
uint64_t total_execution_time;
};
-static void *work_on_kibbutz (void *);
+static void *work_on_kibbutz(void *);
-int toku_kibbutz_create (int n_workers, KIBBUTZ *kb_ret) {
+toku_instr_key *kibbutz_mutex_key;
+toku_instr_key *kibbutz_k_cond_key;
+toku_instr_key *kibbutz_thread_key;
+
+int toku_kibbutz_create(int n_workers, KIBBUTZ *kb_ret) {
int r = 0;
*kb_ret = NULL;
KIBBUTZ XCALLOC(k);
- toku_mutex_init(&k->mutex, NULL);
- toku_cond_init(&k->cond, NULL);
+ toku_mutex_init(*kibbutz_mutex_key, &k->mutex, nullptr);
+ toku_cond_init(*kibbutz_k_cond_key, &k->cond, nullptr);
k->please_shutdown = false;
k->head = NULL;
k->tail = NULL;
@@ -93,7 +97,11 @@ int toku_kibbutz_create (int n_workers, KIBBUTZ *kb_ret) {
XMALLOC_N(n_workers, k->ids);
for (int i = 0; i < n_workers; i++) {
k->ids[i].k = k;
- r = toku_pthread_create(&k->workers[i], NULL, work_on_kibbutz, &k->ids[i]);
+ r = toku_pthread_create(*kibbutz_thread_key,
+ &k->workers[i],
+ nullptr,
+ work_on_kibbutz,
+ &k->ids[i]);
if (r != 0) {
k->n_workers = i;
toku_kibbutz_destroy(k);
@@ -153,10 +161,14 @@ static void *work_on_kibbutz (void *kidv) {
// if there's another item on k->head, then we'll just go grab it now, without waiting for a signal.
}
if (k->please_shutdown) {
- // Don't follow this unless the work is all done, so that when we set please_shutdown, all the work finishes before any threads quit.
- ksignal(k); // must wake up anyone else who is waiting, so they can shut down.
+ // Don't follow this unless the work is all done, so that when we
+ // set please_shutdown, all the work finishes before any threads
+ // quit.
+ ksignal(k); // must wake up anyone else who is waiting, so they can
+ // shut down.
kunlock(k);
- return NULL;
+ toku_instr_delete_current_thread();
+ return nullptr;
}
// There is no work to do and it's not time to shutdown, so wait.
kwait(k);
diff --git a/storage/tokudb/PerconaFT/util/minicron.cc b/storage/tokudb/PerconaFT/util/minicron.cc
index 737c6ef6a4f..c1412015be0 100644
--- a/storage/tokudb/PerconaFT/util/minicron.cc
+++ b/storage/tokudb/PerconaFT/util/minicron.cc
@@ -43,8 +43,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "portability/toku_assert.h"
#include "util/minicron.h"
-static void
-toku_gettime (toku_timespec_t *a) {
+toku_instr_key *minicron_p_mutex_key;
+toku_instr_key *minicron_p_condvar_key;
+toku_instr_key *minicron_thread_key;
+
+static void toku_gettime(toku_timespec_t *a) {
struct timeval tv;
gettimeofday(&tv, 0);
a->tv_sec = tv.tv_sec;
@@ -74,7 +77,8 @@ minicron_do (void *pv)
while (1) {
if (p->do_shutdown) {
toku_mutex_unlock(&p->mutex);
- return 0;
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
}
if (p->period_in_ms == 0) {
// if we aren't supposed to do it then just do an untimed wait.
@@ -104,7 +108,8 @@ minicron_do (void *pv)
// Now we woke up, and we should figure out what to do
if (p->do_shutdown) {
toku_mutex_unlock(&p->mutex);
- return 0;
+ toku_instr_delete_current_thread();
+ return toku_pthread_done(nullptr);
}
if (p->period_in_ms > 1000) {
toku_timespec_t now;
@@ -137,17 +142,17 @@ toku_minicron_setup(struct minicron *p, uint32_t period_in_ms, int(*f)(void *),
p->f = f;
p->arg = arg;
toku_gettime(&p->time_of_last_call_to_f);
- //printf("now=%.6f", p->time_of_last_call_to_f.tv_sec + p->time_of_last_call_to_f.tv_nsec*1e-9);
- p->period_in_ms = period_in_ms;
+ // printf("now=%.6f", p->time_of_last_call_to_f.tv_sec +
+ // p->time_of_last_call_to_f.tv_nsec*1e-9);
+ p->period_in_ms = period_in_ms;
p->do_shutdown = false;
- toku_mutex_init(&p->mutex, 0);
- toku_cond_init (&p->condvar, 0);
- return toku_pthread_create(&p->thread, 0, minicron_do, p);
+ toku_mutex_init(*minicron_p_mutex_key, &p->mutex, nullptr);
+ toku_cond_init(*minicron_p_condvar_key, &p->condvar, nullptr);
+ return toku_pthread_create(
+ *minicron_thread_key, &p->thread, nullptr, minicron_do, p);
}
-
-void
-toku_minicron_change_period(struct minicron *p, uint32_t new_period)
-{
+
+void toku_minicron_change_period(struct minicron *p, uint32_t new_period) {
toku_mutex_lock(&p->mutex);
p->period_in_ms = new_period;
toku_cond_signal(&p->condvar);
diff --git a/storage/tokudb/PerconaFT/util/nb_mutex.h b/storage/tokudb/PerconaFT/util/nb_mutex.h
index 3490c1b365c..d777961ad78 100644
--- a/storage/tokudb/PerconaFT/util/nb_mutex.h
+++ b/storage/tokudb/PerconaFT/util/nb_mutex.h
@@ -49,35 +49,67 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
// increase parallelism at the expense of single thread performance, we
// are experimenting with a single higher level lock.
+extern toku_instr_key *nb_mutex_key;
+
typedef struct nb_mutex *NB_MUTEX;
struct nb_mutex {
- struct rwlock lock;
+ struct st_rwlock lock;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_mutex_t toku_mutex;
+#endif
};
+#if defined(TOKU_MYSQL_WITH_PFS)
+#define nb_mutex_init(MK, RK, M) \
+ inline_nb_mutex_init(MK, RK, M)
+#else
+#define nb_mutex_init(MK, RK, M) inline_nb_mutex_init(M)
+#endif
+
// initialize an nb mutex
-static __attribute__((__unused__))
-void
-nb_mutex_init(NB_MUTEX nb_mutex) {
- rwlock_init(&nb_mutex->lock);
+inline void inline_nb_mutex_init(
+#if defined(TOKU_MYSQL_WITH_PFS)
+ const toku_instr_key &mutex_instr_key,
+ const toku_instr_key &rwlock_instr_key,
+#endif
+ NB_MUTEX nb_mutex) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_mutex_init(mutex_instr_key, &nb_mutex->toku_mutex, nullptr);
+#endif
+ rwlock_init(rwlock_instr_key, &nb_mutex->lock);
}
// destroy a read write lock
-static __attribute__((__unused__))
-void
-nb_mutex_destroy(NB_MUTEX nb_mutex) {
+inline void nb_mutex_destroy(NB_MUTEX nb_mutex) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_instr_mutex_destroy(nb_mutex->toku_mutex.psi_mutex);
+#endif
rwlock_destroy(&nb_mutex->lock);
}
// obtain a write lock
// expects: mutex is locked
-static inline void nb_mutex_lock(NB_MUTEX nb_mutex, toku_mutex_t *mutex) {
+inline void nb_mutex_lock(NB_MUTEX nb_mutex, toku_mutex_t *mutex) {
+#ifdef TOKU_MYSQL_WITH_PFS
+ toku_mutex_instrumentation mutex_instr;
+ toku_instr_mutex_lock_start(mutex_instr,
+ *mutex,
+ __FILE__,
+ __LINE__); // TODO: pull these to caller?
+#endif
rwlock_write_lock(&nb_mutex->lock, mutex);
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_instr_mutex_lock_end(mutex_instr, 0);
+#endif
}
// release a write lock
// expects: mutex is locked
-static inline void nb_mutex_unlock(NB_MUTEX nb_mutex) {
+inline void nb_mutex_unlock(NB_MUTEX nb_mutex) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_instr_mutex_unlock(nb_mutex->toku_mutex.psi_mutex);
+#endif
rwlock_write_unlock(&nb_mutex->lock);
}
diff --git a/storage/tokudb/PerconaFT/util/queue.cc b/storage/tokudb/PerconaFT/util/queue.cc
index 0716dfb2f59..39dfbbc699a 100644
--- a/storage/tokudb/PerconaFT/util/queue.cc
+++ b/storage/tokudb/PerconaFT/util/queue.cc
@@ -44,6 +44,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "memory.h"
#include <toku_pthread.h>
+toku_instr_key *queue_result_mutex_key;
+toku_instr_key *queue_result_cond_key;
+
struct qitem;
struct qitem {
@@ -81,11 +84,11 @@ int toku_queue_create (QUEUE *q, uint64_t weight_limit)
if (result==NULL) return get_error_errno();
result->contents_weight = 0;
result->weight_limit = weight_limit;
- result->head = NULL;
- result->tail = NULL;
- result->eof = false;
- toku_mutex_init(&result->mutex, NULL);
- toku_cond_init(&result->cond, NULL);
+ result->head = NULL;
+ result->tail = NULL;
+ result->eof = false;
+ toku_mutex_init(*queue_result_mutex_key, &result->mutex, nullptr);
+ toku_cond_init(*queue_result_cond_key, &result->cond, nullptr);
*q = result;
return 0;
}
diff --git a/storage/tokudb/PerconaFT/util/rwlock.h b/storage/tokudb/PerconaFT/util/rwlock.h
index 47f78df70d1..d9a13ba9014 100644
--- a/storage/tokudb/PerconaFT/util/rwlock.h
+++ b/storage/tokudb/PerconaFT/util/rwlock.h
@@ -39,6 +39,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#pragma once
#include <toku_assert.h>
+#include <toku_portability.h>
+#include <toku_instrumentation.h>
/* Readers/writers locks implementation
*
@@ -147,53 +149,81 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
// increase parallelism at the expense of single thread performance, we
// are experimenting with a single higher level lock.
-typedef struct rwlock *RWLOCK;
-struct rwlock {
- int reader; // the number of readers
- int want_read; // the number of blocked readers
+extern toku_instr_key *rwlock_cond_key;
+extern toku_instr_key *rwlock_wait_read_key;
+extern toku_instr_key *rwlock_wait_write_key;
+
+typedef struct st_rwlock *RWLOCK;
+struct st_rwlock {
+ int reader; // the number of readers
+ int want_read; // the number of blocked readers
toku_cond_t wait_read;
int writer; // the number of writers
int want_write; // the number of blocked writers
toku_cond_t wait_write;
- toku_cond_t* wait_users_go_to_zero;
+ toku_cond_t *wait_users_go_to_zero;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_t prwlock;
+#endif
};
// returns: the sum of the number of readers, pending readers, writers, and
// pending writers
static inline int rwlock_users(RWLOCK rwlock) {
- return rwlock->reader + rwlock->want_read + rwlock->writer + rwlock->want_write;
+ return rwlock->reader + rwlock->want_read + rwlock->writer +
+ rwlock->want_write;
}
-// initialize a read write lock
+#if defined(TOKU_MYSQL_WITH_PFS)
+#define rwlock_init(K, R) inline_rwlock_init(K, R)
+#else
+#define rwlock_init(K, R) inline_rwlock_init(R)
+#endif
-static __attribute__((__unused__))
-void
-rwlock_init(RWLOCK rwlock) {
+// initialize a read write lock
+static inline __attribute__((__unused__)) void inline_rwlock_init(
+#if defined(TOKU_MYSQL_WITH_PFS)
+ const toku_instr_key &rwlock_instr_key,
+#endif
+ RWLOCK rwlock) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_init(rwlock_instr_key, &rwlock->prwlock, nullptr);
+#endif
rwlock->reader = rwlock->want_read = 0;
- toku_cond_init(&rwlock->wait_read, 0);
rwlock->writer = rwlock->want_write = 0;
- toku_cond_init(&rwlock->wait_write, 0);
+ toku_cond_init(toku_uninstrumented, &rwlock->wait_read, nullptr);
+ toku_cond_init(toku_uninstrumented, &rwlock->wait_write, nullptr);
rwlock->wait_users_go_to_zero = NULL;
}
// destroy a read write lock
-static __attribute__((__unused__))
-void
-rwlock_destroy(RWLOCK rwlock) {
+static inline __attribute__((__unused__)) void rwlock_destroy(RWLOCK rwlock) {
paranoid_invariant(rwlock->reader == 0);
paranoid_invariant(rwlock->want_read == 0);
paranoid_invariant(rwlock->writer == 0);
paranoid_invariant(rwlock->want_write == 0);
toku_cond_destroy(&rwlock->wait_read);
toku_cond_destroy(&rwlock->wait_write);
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_pthread_rwlock_destroy(&rwlock->prwlock);
+#endif
}
// obtain a read lock
// expects: mutex is locked
static inline void rwlock_read_lock(RWLOCK rwlock, toku_mutex_t *mutex) {
+#ifdef TOKU_MYSQL_WITH_PFS
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ // TODO: pull location information up to caller
+ toku_instr_rwlock_rdlock_wait_start(
+ rwlock_instr, rwlock->prwlock, __FILE__, __LINE__);
+
+#endif
+
paranoid_invariant(!rwlock->wait_users_go_to_zero);
if (rwlock->writer || rwlock->want_write) {
rwlock->want_read++;
@@ -203,12 +233,19 @@ static inline void rwlock_read_lock(RWLOCK rwlock, toku_mutex_t *mutex) {
rwlock->want_read--;
}
rwlock->reader++;
+#ifdef TOKU_MYSQL_WITH_PFS
+ /* Instrumentation end */
+ toku_instr_rwlock_wrlock_wait_end(rwlock_instr, 0);
+#endif
}
// release a read lock
// expects: mutex is locked
static inline void rwlock_read_unlock(RWLOCK rwlock) {
+#ifdef TOKU_MYSQL_WITH_PFS
+ toku_instr_rwlock_unlock(rwlock->prwlock);
+#endif
paranoid_invariant(rwlock->reader > 0);
paranoid_invariant(rwlock->writer == 0);
rwlock->reader--;
@@ -224,6 +261,12 @@ static inline void rwlock_read_unlock(RWLOCK rwlock) {
// expects: mutex is locked
static inline void rwlock_write_lock(RWLOCK rwlock, toku_mutex_t *mutex) {
+#ifdef TOKU_MYSQL_WITH_PFS
+ /* Instrumentation start */
+ toku_rwlock_instrumentation rwlock_instr;
+ toku_instr_rwlock_wrlock_wait_start(
+ rwlock_instr, rwlock->prwlock, __FILE__, __LINE__);
+#endif
paranoid_invariant(!rwlock->wait_users_go_to_zero);
if (rwlock->reader || rwlock->writer) {
rwlock->want_write++;
@@ -233,12 +276,19 @@ static inline void rwlock_write_lock(RWLOCK rwlock, toku_mutex_t *mutex) {
rwlock->want_write--;
}
rwlock->writer++;
+#if defined(TOKU_MYSQL_WITH_PFS)
+ /* Instrumentation end */
+ toku_instr_rwlock_wrlock_wait_end(rwlock_instr, 0);
+#endif
}
// release a write lock
// expects: mutex is locked
static inline void rwlock_write_unlock(RWLOCK rwlock) {
+#if defined(TOKU_MYSQL_WITH_PFS)
+ toku_instr_rwlock_unlock(rwlock->prwlock);
+#endif
paranoid_invariant(rwlock->reader == 0);
paranoid_invariant(rwlock->writer == 1);
rwlock->writer--;
@@ -284,14 +334,10 @@ static inline int rwlock_read_will_block(RWLOCK rwlock) {
return (rwlock->writer > 0 || rwlock->want_write > 0);
}
-static inline void rwlock_wait_for_users(
- RWLOCK rwlock,
- toku_mutex_t *mutex
- )
-{
+static inline void rwlock_wait_for_users(RWLOCK rwlock, toku_mutex_t *mutex) {
paranoid_invariant(!rwlock->wait_users_go_to_zero);
toku_cond_t cond;
- toku_cond_init(&cond, NULL);
+ toku_cond_init(toku_uninstrumented, &cond, nullptr);
while (rwlock_users(rwlock) > 0) {
rwlock->wait_users_go_to_zero = &cond;
toku_cond_wait(&cond, mutex);
diff --git a/storage/tokudb/PerconaFT/util/tests/marked-omt-test.cc b/storage/tokudb/PerconaFT/util/tests/marked-omt-test.cc
index bce1b1a885b..7e60c711c66 100644
--- a/storage/tokudb/PerconaFT/util/tests/marked-omt-test.cc
+++ b/storage/tokudb/PerconaFT/util/tests/marked-omt-test.cc
@@ -156,7 +156,7 @@ int int_heaviside(const uint32_t &v, const uint32_t &target) {
struct stress_shared {
stress_omt *omt;
volatile bool running;
- struct rwlock lock;
+ struct st_rwlock lock;
toku_mutex_t mutex;
int num_marker_threads;
};
@@ -400,8 +400,8 @@ static void stress_test(int nelts) {
struct stress_shared extra;
ZERO_STRUCT(extra);
extra.omt = &omt;
- toku_mutex_init(&extra.mutex, NULL);
- rwlock_init(&extra.lock);
+ toku_mutex_init(toku_uninstrumented, &extra.mutex, nullptr);
+ rwlock_init(toku_uninstrumented, &extra.lock);
extra.running = true;
extra.num_marker_threads = num_marker_threads;
@@ -422,11 +422,19 @@ static void stress_test(int nelts) {
r = myinitstate_r(seed, reader.buf_write, 8, &reader.rand_write);
invariant_zero(r);
- toku_pthread_create(&marker_threads[i], NULL, stress_mark_worker, &reader);
+ toku_pthread_create(toku_uninstrumented,
+ &marker_threads[i],
+ nullptr,
+ stress_mark_worker,
+ &reader);
}
toku_pthread_t deleter_thread;
- toku_pthread_create(&deleter_thread, NULL, stress_delete_worker, &readers[0]);
+ toku_pthread_create(toku_uninstrumented,
+ &deleter_thread,
+ nullptr,
+ stress_delete_worker,
+ &readers[0]);
toku_pthread_join(deleter_thread, NULL);
for (int i = 0; i < num_marker_threads; ++i) {
diff --git a/storage/tokudb/PerconaFT/util/tests/minicron-test.cc b/storage/tokudb/PerconaFT/util/tests/minicron-test.cc
index a2ddbdeabdf..026ab7446d3 100644
--- a/storage/tokudb/PerconaFT/util/tests/minicron-test.cc
+++ b/storage/tokudb/PerconaFT/util/tests/minicron-test.cc
@@ -206,11 +206,12 @@ test_main (int argc, const char *argv[]) {
toku_pthread_t tests[N];
unsigned int i;
- for (i=0; i<N; i++) {
- int r=toku_pthread_create(tests+i, 0, testfuns[i], 0);
- assert(r==0);
+ for (i = 0; i < N; i++) {
+ int r = toku_pthread_create(
+ toku_uninstrumented, tests + i, nullptr, testfuns[i], nullptr);
+ assert(r == 0);
}
- for (i=0; i<N; i++) {
+ for (i = 0; i < N; i++) {
void *v;
int r=toku_pthread_join(tests[i], &v);
assert(r==0);
diff --git a/storage/tokudb/PerconaFT/util/tests/queue-test.cc b/storage/tokudb/PerconaFT/util/tests/queue-test.cc
index 433a0aca32a..f87e05bc664 100644
--- a/storage/tokudb/PerconaFT/util/tests/queue-test.cc
+++ b/storage/tokudb/PerconaFT/util/tests/queue-test.cc
@@ -87,9 +87,11 @@ static void queue_test_0 (uint64_t weight)
d_max_weight = 0;
QUEUE q;
int r;
- r = toku_queue_create(&q, weight); assert(r==0);
+ r = toku_queue_create(&q, weight);
+ assert(r == 0);
toku_pthread_t thread;
- r = toku_pthread_create(&thread, NULL, start_0, q); assert(r==0);
+ r = toku_pthread_create(toku_uninstrumented, &thread, nullptr, start_0, q);
+ assert(r == 0);
enq(q, 0L, weight);
enq(q, 1L, weight);
enq(q, 2L, weight);
diff --git a/storage/tokudb/PerconaFT/util/tests/rwlock_condvar.h b/storage/tokudb/PerconaFT/util/tests/rwlock_condvar.h
index 816b98af81c..b49c2780ff8 100644
--- a/storage/tokudb/PerconaFT/util/tests/rwlock_condvar.h
+++ b/storage/tokudb/PerconaFT/util/tests/rwlock_condvar.h
@@ -67,13 +67,13 @@ struct toku_cv_fair_rwlock_waiter_state {
static __thread struct toku_cv_fair_rwlock_waiter_state waitstate = {0, NULL, {PTHREAD_COND_INITIALIZER} };
void toku_cv_fair_rwlock_init (toku_cv_fair_rwlock_t *rwlock) {
- rwlock->state=0;
+ rwlock->state = 0;
rwlock->waiters_head = NULL;
rwlock->waiters_tail = NULL;
- toku_mutex_init(&rwlock->mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &rwlock->mutex, nullptr);
}
-void toku_cv_fair_rwlock_destroy (toku_cv_fair_rwlock_t *rwlock) {
+void toku_cv_fair_rwlock_destroy(toku_cv_fair_rwlock_t *rwlock) {
toku_mutex_destroy(&rwlock->mutex);
}
diff --git a/storage/tokudb/PerconaFT/util/tests/sm-basic.cc b/storage/tokudb/PerconaFT/util/tests/sm-basic.cc
index 80bc965fd31..0e5eb8364e2 100644
--- a/storage/tokudb/PerconaFT/util/tests/sm-basic.cc
+++ b/storage/tokudb/PerconaFT/util/tests/sm-basic.cc
@@ -64,7 +64,8 @@ int main(void) {
// run the test
toku_pthread_t tid;
int r;
- r = toku_pthread_create(&tid, NULL, sm_test_f, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, sm_test_f, nullptr);
assert_zero(r);
void *ret;
r = toku_pthread_join(tid, &ret);
diff --git a/storage/tokudb/PerconaFT/util/tests/sm-crash-double-free.cc b/storage/tokudb/PerconaFT/util/tests/sm-crash-double-free.cc
index c5d7e3e53a7..5aa3565510b 100644
--- a/storage/tokudb/PerconaFT/util/tests/sm-crash-double-free.cc
+++ b/storage/tokudb/PerconaFT/util/tests/sm-crash-double-free.cc
@@ -64,10 +64,12 @@ int main(void) {
toku_scoped_malloc_init();
toku_pthread_t tid;
int r;
- r = toku_pthread_create(&tid, NULL, sm_test_f, NULL);
+ r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, sm_test_f, nullptr);
assert_zero(r);
void *ret;
- while (state != 1) sleep(1);
+ while (state != 1)
+ sleep(1);
toku_scoped_malloc_destroy_set();
state = 2;
r = toku_pthread_join(tid, &ret);
diff --git a/storage/tokudb/PerconaFT/util/tests/test-frwlock-fair-writers.cc b/storage/tokudb/PerconaFT/util/tests/test-frwlock-fair-writers.cc
index 7fd4801fe11..9a625c32aeb 100644
--- a/storage/tokudb/PerconaFT/util/tests/test-frwlock-fair-writers.cc
+++ b/storage/tokudb/PerconaFT/util/tests/test-frwlock-fair-writers.cc
@@ -66,9 +66,9 @@ static void *t1_func(void *arg) {
int main(void) {
int r;
- toku_mutex_init(&rwlock_mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &rwlock_mutex, nullptr);
rwlock.init(&rwlock_mutex);
-
+
const int nthreads = 2;
pthread_t tids[nthreads];
for (int i = 0; i < nthreads; i++) {
diff --git a/storage/tokudb/PerconaFT/util/tests/test-rwlock-cheapness.cc b/storage/tokudb/PerconaFT/util/tests/test-rwlock-cheapness.cc
index 0075ddf9bcb..c0b43c2db1c 100644
--- a/storage/tokudb/PerconaFT/util/tests/test-rwlock-cheapness.cc
+++ b/storage/tokudb/PerconaFT/util/tests/test-rwlock-cheapness.cc
@@ -101,7 +101,8 @@ static void *do_read_wait(void *arg) {
static void launch_cheap_waiter(void) {
toku_pthread_t tid;
- int r = toku_pthread_create(&tid, NULL, do_cheap_wait, NULL);
+ int r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, do_cheap_wait, nullptr);
assert_zero(r);
toku_pthread_detach(tid);
sleep(1);
@@ -109,7 +110,8 @@ static void launch_cheap_waiter(void) {
static void launch_expensive_waiter(void) {
toku_pthread_t tid;
- int r = toku_pthread_create(&tid, NULL, do_expensive_wait, NULL);
+ int r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, do_expensive_wait, nullptr);
assert_zero(r);
toku_pthread_detach(tid);
sleep(1);
@@ -117,7 +119,8 @@ static void launch_expensive_waiter(void) {
static void launch_reader(void) {
toku_pthread_t tid;
- int r = toku_pthread_create(&tid, NULL, do_read_wait, NULL);
+ int r = toku_pthread_create(
+ toku_uninstrumented, &tid, nullptr, do_read_wait, nullptr);
assert_zero(r);
toku_pthread_detach(tid);
sleep(1);
@@ -132,7 +135,7 @@ static bool locks_are_expensive(void) {
}
static void test_write_cheapness(void) {
- toku_mutex_init(&mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &mutex, nullptr);
w.init(&mutex);
// single expensive write lock
diff --git a/storage/tokudb/PerconaFT/util/tests/test-rwlock.cc b/storage/tokudb/PerconaFT/util/tests/test-rwlock.cc
index 18ca1229f56..56dd3f6b480 100644
--- a/storage/tokudb/PerconaFT/util/tests/test-rwlock.cc
+++ b/storage/tokudb/PerconaFT/util/tests/test-rwlock.cc
@@ -245,14 +245,14 @@ static void util_rwlock_unlock (RWLOCK rwlock, toku_mutex_t *mutex) {
}
// Time the read lock that's in util/rwlock.h
-void time_util_rwlock (void) __attribute((__noinline__));
-void time_util_rwlock (void) {
- struct rwlock rwlock;
+void time_util_rwlock(void) __attribute((__noinline__));
+void time_util_rwlock(void) {
+ struct st_rwlock rwlock;
toku_mutex_t external_mutex;
- toku_mutex_init(&external_mutex, NULL);
- rwlock_init(&rwlock);
- struct timeval start,end;
-
+ toku_mutex_init(toku_uninstrumented, &external_mutex, nullptr);
+ rwlock_init(toku_uninstrumented, &rwlock);
+ struct timeval start, end;
+
util_rwlock_lock(&rwlock, &external_mutex);
util_rwlock_unlock(&rwlock, &external_mutex);
for (int t=0; t<T; t++) {
@@ -271,16 +271,17 @@ void time_util_rwlock (void) {
toku_mutex_destroy(&external_mutex);
}
-// Time the read lock that's in util/rwlock.h, assuming the mutex is already held.
-void time_util_prelocked_rwlock (void) __attribute__((__noinline__));
-void time_util_prelocked_rwlock (void) {
- struct rwlock rwlock;
+// Time the read lock that's in util/rwlock.h, assuming the mutex is already
+// held.
+void time_util_prelocked_rwlock(void) __attribute__((__noinline__));
+void time_util_prelocked_rwlock(void) {
+ struct st_rwlock rwlock;
toku_mutex_t external_mutex;
- toku_mutex_init(&external_mutex, NULL);
+ toku_mutex_init(toku_uninstrumented, &external_mutex, nullptr);
toku_mutex_lock(&external_mutex);
- rwlock_init(&rwlock);
- struct timeval start,end;
-
+ rwlock_init(toku_uninstrumented, &rwlock);
+ struct timeval start, end;
+
rwlock_read_lock(&rwlock, &external_mutex);
rwlock_read_unlock(&rwlock);
for (int t=0; t<T; t++) {
@@ -303,8 +304,8 @@ void time_util_prelocked_rwlock (void) {
void time_frwlock_prelocked(void) __attribute__((__noinline__));
void time_frwlock_prelocked(void) {
toku_mutex_t external_mutex;
- toku_mutex_init(&external_mutex, NULL);
- struct timeval start,end;
+ toku_mutex_init(toku_uninstrumented, &external_mutex, nullptr);
+ struct timeval start, end;
toku::frwlock x;
x.init(&external_mutex);
toku_mutex_lock(&external_mutex);
@@ -340,8 +341,8 @@ void time_frwlock_prelocked(void) {
void time_frwlock(void) __attribute__((__noinline__));
void time_frwlock(void) {
toku_mutex_t external_mutex;
- toku_mutex_init(&external_mutex, NULL);
- struct timeval start,end;
+ toku_mutex_init(toku_uninstrumented, &external_mutex, nullptr);
+ struct timeval start, end;
toku::frwlock x;
x.init(&external_mutex);
toku_mutex_lock(&external_mutex);
diff --git a/storage/tokudb/PerconaFT/util/tests/threadpool-test.cc b/storage/tokudb/PerconaFT/util/tests/threadpool-test.cc
index 3379507270d..83c142edc2d 100644
--- a/storage/tokudb/PerconaFT/util/tests/threadpool-test.cc
+++ b/storage/tokudb/PerconaFT/util/tests/threadpool-test.cc
@@ -67,10 +67,11 @@ struct my_threadpool {
static void
my_threadpool_init (struct my_threadpool *my_threadpool, int max_threads) {
int r;
- r = toku_thread_pool_create(&my_threadpool->threadpool, max_threads); assert(r == 0);
+ r = toku_thread_pool_create(&my_threadpool->threadpool, max_threads);
+ assert(r == 0);
assert(my_threadpool != 0);
- toku_mutex_init(&my_threadpool->mutex, 0);
- toku_cond_init(&my_threadpool->wait, 0);
+ toku_mutex_init(toku_uninstrumented, &my_threadpool->mutex, nullptr);
+ toku_cond_init(toku_uninstrumented, &my_threadpool->wait, nullptr);
my_threadpool->closed = 0;
my_threadpool->counter = 0;
}
diff --git a/storage/tokudb/PerconaFT/util/threadpool.cc b/storage/tokudb/PerconaFT/util/threadpool.cc
index 146cc63242a..6e0ccf05f93 100644
--- a/storage/tokudb/PerconaFT/util/threadpool.cc
+++ b/storage/tokudb/PerconaFT/util/threadpool.cc
@@ -48,6 +48,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "threadpool.h"
+toku_instr_key *tpool_lock_mutex_key;
+toku_instr_key *tp_thread_wait_key;
+toku_instr_key *tp_pool_wait_free_key;
+toku_instr_key *tp_internal_thread_key;
+
struct toku_thread {
struct toku_thread_pool *pool;
toku_pthread_t tid;
@@ -84,8 +89,12 @@ toku_thread_create(struct toku_thread_pool *pool, struct toku_thread **toku_thre
} else {
memset(thread, 0, sizeof *thread);
thread->pool = pool;
- toku_cond_init(&thread->wait, nullptr);
- r = toku_pthread_create(&thread->tid, nullptr, toku_thread_run_internal, thread);
+ toku_cond_init(*tp_thread_wait_key, &thread->wait, nullptr);
+ r = toku_pthread_create(*tp_internal_thread_key,
+ &thread->tid,
+ nullptr,
+ toku_thread_run_internal,
+ thread);
if (r) {
toku_cond_destroy(&thread->wait);
toku_free(thread);
@@ -105,11 +114,11 @@ toku_thread_run(struct toku_thread *thread, void *(*f)(void *arg), void *arg) {
toku_thread_pool_unlock(thread->pool);
}
-static void
-toku_thread_destroy(struct toku_thread *thread) {
+static void toku_thread_destroy(struct toku_thread *thread) {
int r;
void *ret;
- r = toku_pthread_join(thread->tid, &ret); invariant(r == 0 && ret == thread);
+ r = toku_pthread_join(thread->tid, &ret);
+ invariant(r == 0 && ret == thread);
struct toku_thread_pool *pool = thread->pool;
toku_thread_pool_lock(pool);
toku_list_remove(&thread->free_link);
@@ -147,20 +156,20 @@ toku_thread_run_internal(void *arg) {
thread->f = nullptr;
toku_list_push(&pool->free_threads, &thread->free_link);
}
- return arg;
-}
+ return toku_pthread_done(arg);
+}
-int
-toku_thread_pool_create(struct toku_thread_pool **pool_return, int max_threads) {
+int toku_thread_pool_create(struct toku_thread_pool **pool_return,
+ int max_threads) {
int r;
struct toku_thread_pool *CALLOC(pool);
if (pool == nullptr) {
r = get_error_errno();
} else {
- toku_mutex_init(&pool->lock, nullptr);
+ toku_mutex_init(*tpool_lock_mutex_key, &pool->lock, nullptr);
toku_list_init(&pool->free_threads);
toku_list_init(&pool->all_threads);
- toku_cond_init(&pool->wait_free, nullptr);
+ toku_cond_init(*tp_pool_wait_free_key, &pool->wait_free, nullptr);
pool->cur_threads = 0;
pool->max_threads = max_threads;
*pool_return = pool;
diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc
index 56bebf1c3ec..cdd4adb0947 100644
--- a/storage/tokudb/ha_tokudb.cc
+++ b/storage/tokudb/ha_tokudb.cc
@@ -31,6 +31,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "ha_tokudb.h"
#include "sql_db.h"
+pfs_key_t ha_tokudb_mutex_key;
+pfs_key_t num_DBs_lock_key;
#if TOKU_INCLUDE_EXTENDED_KEYS
static inline uint get_ext_key_parts(const KEY *key) {
@@ -187,13 +189,9 @@ const char* TOKUDB_SHARE::get_state_string(share_state_t state) {
void* TOKUDB_SHARE::operator new(size_t sz) {
return tokudb::memory::malloc(sz, MYF(MY_WME|MY_ZEROFILL|MY_FAE));
}
-void TOKUDB_SHARE::operator delete(void* p) {
- tokudb::memory::free(p);
-}
-TOKUDB_SHARE::TOKUDB_SHARE() :
- _num_DBs_lock(),
- _mutex() {
-}
+void TOKUDB_SHARE::operator delete(void* p) { tokudb::memory::free(p); }
+TOKUDB_SHARE::TOKUDB_SHARE()
+ : _num_DBs_lock(num_DBs_lock_key), _mutex(ha_tokudb_mutex_key) {}
void TOKUDB_SHARE::init(const char* table_name) {
_use_count = 0;
thr_lock_init(&_thr_lock);
@@ -228,20 +226,15 @@ void TOKUDB_SHARE::destroy() {
thr_lock_delete(&_thr_lock);
TOKUDB_SHARE_DBUG_VOID_RETURN();
}
-TOKUDB_SHARE* TOKUDB_SHARE::get_share(
- const char* table_name,
- TABLE_SHARE* table_share,
- THR_LOCK_DATA* data,
- bool create_new) {
-
- _open_tables_mutex.lock();
+TOKUDB_SHARE* TOKUDB_SHARE::get_share(const char* table_name,
+ TABLE_SHARE* table_share,
+ THR_LOCK_DATA* data,
+ bool create_new) {
+ mutex_t_lock(_open_tables_mutex);
int error = 0;
- uint length = (uint) strlen(table_name);
- TOKUDB_SHARE* share =
- (TOKUDB_SHARE*)my_hash_search(
- &_open_tables,
- (uchar*)table_name,
- length);
+ uint length = (uint)strlen(table_name);
+ TOKUDB_SHARE* share = (TOKUDB_SHARE*)my_hash_search(
+ &_open_tables, (uchar*)table_name, length);
TOKUDB_TRACE_FOR_FLAGS(
TOKUDB_DEBUG_SHARE,
@@ -276,28 +269,27 @@ TOKUDB_SHARE* TOKUDB_SHARE::get_share(
thr_lock_data_init(&(share->_thr_lock), data, NULL);
exit:
- _open_tables_mutex.unlock();
+ mutex_t_unlock(_open_tables_mutex);
return share;
}
void TOKUDB_SHARE::drop_share(TOKUDB_SHARE* share) {
- TOKUDB_TRACE_FOR_FLAGS(
- TOKUDB_DEBUG_SHARE,
- "share[%p]:file[%s]:state[%s]:use_count[%d]",
- share,
- share->_full_table_name.ptr(),
- get_state_string(share->_state),
- share->_use_count);
-
- _open_tables_mutex.lock();
+ TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_SHARE,
+ "share[%p]:file[%s]:state[%s]:use_count[%d]",
+ share,
+ share->_full_table_name.ptr(),
+ get_state_string(share->_state),
+ share->_use_count);
+
+ mutex_t_lock(_open_tables_mutex);
my_hash_delete(&_open_tables, (uchar*)share);
- _open_tables_mutex.unlock();
+ mutex_t_unlock(_open_tables_mutex);
}
TOKUDB_SHARE::share_state_t TOKUDB_SHARE::addref() {
TOKUDB_SHARE_TRACE_FOR_FLAGS((TOKUDB_DEBUG_ENTER & TOKUDB_DEBUG_SHARE),
- "file[%s]:state[%s]:use_count[%d]",
- _full_table_name.ptr(),
- get_state_string(_state),
- _use_count);
+ "file[%s]:state[%s]:use_count[%d]",
+ _full_table_name.ptr(),
+ get_state_string(_state),
+ _use_count);
lock();
_use_count++;
@@ -312,7 +304,7 @@ int TOKUDB_SHARE::release() {
int error, result = 0;
- _mutex.lock();
+ mutex_t_lock(_mutex);
assert_always(_use_count != 0);
_use_count--;
if (_use_count == 0 && _state == TOKUDB_SHARE::OPENED) {
@@ -356,7 +348,7 @@ int TOKUDB_SHARE::release() {
_state = TOKUDB_SHARE::CLOSED;
}
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
TOKUDB_SHARE_DBUG_RETURN(result);
}
@@ -1195,8 +1187,10 @@ static int generate_row_for_put(
ha_tokudb::ha_tokudb(handlerton * hton, TABLE_SHARE * table_arg):handler(hton, table_arg) {
TOKUDB_HANDLER_DBUG_ENTER("");
share = NULL;
- int_table_flags = HA_REC_NOT_IN_SEQ | HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_PRIMARY_KEY_IN_READ_INDEX | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
- HA_FILE_BASED | HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX | HA_CAN_WRITE_DURING_OPTIMIZE;
+ int_table_flags = HA_REC_NOT_IN_SEQ | HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS
+ | HA_PRIMARY_KEY_IN_READ_INDEX | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
+ | HA_FILE_BASED | HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX
+ | HA_CAN_WRITE_DURING_OPTIMIZE | HA_ONLINE_ANALYZE;
alloc_ptr = NULL;
rec_buff = NULL;
rec_update_buff = NULL;
@@ -3313,12 +3307,12 @@ void ha_tokudb::start_bulk_insert(ha_rows rows) {
delay_updating_ai_metadata = true;
ai_metadata_update_required = false;
abort_loader = false;
-
- share->_num_DBs_lock.lock_read();
+
+ rwlock_t_lock_read(share->_num_DBs_lock);
uint curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key);
num_DBs_locked_in_bulk = true;
lock_count = 0;
-
+
if ((rows == 0 || rows > 1) && share->try_table_lock) {
if (tokudb::sysvars::prelock_empty(thd) &&
may_table_be_empty(transaction) &&
@@ -4030,14 +4024,13 @@ int ha_tokudb::write_row(uchar * record) {
// grab reader lock on numDBs_lock
//
if (!num_DBs_locked_in_bulk) {
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
num_DBs_locked = true;
- }
- else {
+ } else {
lock_count++;
if (lock_count >= 2000) {
share->_num_DBs_lock.unlock();
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
lock_count = 0;
}
}
@@ -4208,7 +4201,7 @@ int ha_tokudb::update_row(const uchar * old_row, uchar * new_row) {
//
bool num_DBs_locked = false;
if (!num_DBs_locked_in_bulk) {
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
num_DBs_locked = true;
}
curr_num_DBs = share->num_DBs;
@@ -4350,7 +4343,7 @@ int ha_tokudb::delete_row(const uchar * record) {
//
bool num_DBs_locked = false;
if (!num_DBs_locked_in_bulk) {
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
num_DBs_locked = true;
}
curr_num_DBs = share->num_DBs;
@@ -4641,6 +4634,9 @@ int ha_tokudb::index_init(uint keynr, bool sorted) {
if (tokudb::sysvars::disable_prefetching(thd)) {
cursor_flags |= DBC_DISABLE_PREFETCHING;
}
+ if (lock.type == TL_READ_WITH_SHARED_LOCKS) {
+ cursor_flags |= DB_LOCKING_READ;
+ }
if ((error = share->key_file[keynr]->cursor(share->key_file[keynr],
transaction, &cursor,
cursor_flags))) {
@@ -6212,6 +6208,8 @@ int ha_tokudb::info(uint flag) {
}
if ((flag & HA_STATUS_CONST)) {
stats.max_data_file_length = 9223372036854775807ULL;
+ }
+ if (flag & (HA_STATUS_VARIABLE | HA_STATUS_CONST)) {
share->set_cardinality_counts_in_table(table);
}
@@ -6295,7 +6293,7 @@ int ha_tokudb::acquire_table_lock (DB_TXN* trans, TABLE_LOCK_TYPE lt) {
TOKUDB_HANDLER_DBUG_ENTER("%p %s", trans, lt == lock_read ? "r" : "w");
int error = ENOSYS;
if (!num_DBs_locked_in_bulk) {
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
}
uint curr_num_DBs = share->num_DBs;
if (lt == lock_read) {
@@ -6651,8 +6649,9 @@ THR_LOCK_DATA* *ha_tokudb::store_lock(
if (sql_command == SQLCOM_CREATE_INDEX &&
tokudb::sysvars::create_index_online(thd)) {
// hot indexing
- share->_num_DBs_lock.lock_read();
- if (share->num_DBs == (table->s->keys + tokudb_test(hidden_primary_key))) {
+ rwlock_t_lock_read(share->_num_DBs_lock);
+ if (share->num_DBs ==
+ (table->s->keys + tokudb_test(hidden_primary_key))) {
lock_type = TL_WRITE_ALLOW_WRITE;
}
share->_num_DBs_lock.unlock();
@@ -7225,10 +7224,28 @@ int ha_tokudb::create(
const tokudb::sysvars::row_format_t row_format =
(tokudb::sysvars::row_format_t)form->s->option_struct->row_format;
#else
- const tokudb::sysvars::row_format_t row_format =
- (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)
- ? row_type_to_row_format(create_info->row_type)
- : tokudb::sysvars::row_format(thd);
+ // TDB-76 : CREATE TABLE ... LIKE ... does not use source row_format on
+ // target table
+ // Original code would only use create_info->row_type if
+ // create_info->used_fields & HA_CREATE_USED_ROW_FORMAT was true. This
+ // would cause us to skip transferring the row_format for a table created
+ // via CREATE TABLE tn LIKE tn. We also take on more InnoDB like behavior
+ // and throw a warning if we get a row_format that we can't translate into
+ // a known TokuDB row_format.
+ tokudb::sysvars::row_format_t row_format =
+ tokudb::sysvars::row_format(thd);
+
+ if ((create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) ||
+ create_info->row_type != ROW_TYPE_DEFAULT) {
+ row_format = row_type_to_row_format(create_info->row_type);
+ if (row_format == tokudb::sysvars::SRV_ROW_FORMAT_DEFAULT &&
+ create_info->row_type != ROW_TYPE_DEFAULT) {
+ push_warning(thd,
+ Sql_condition::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "TokuDB: invalid ROW_FORMAT specifier.");
+ }
+ }
#endif
const toku_compression_method compression_method =
row_format_to_toku_compression_method(row_format);
@@ -8112,8 +8129,8 @@ int ha_tokudb::tokudb_add_index(
}
}
}
-
- share->_num_DBs_lock.lock_write();
+
+ rwlock_t_lock_write(share->_num_DBs_lock);
rw_lock_taken = true;
//
// open all the DB files and set the appropriate variables in share
@@ -8223,7 +8240,7 @@ int ha_tokudb::tokudb_add_index(
goto cleanup;
}
- share->_num_DBs_lock.lock_write();
+ rwlock_t_lock_write(share->_num_DBs_lock);
error = indexer->close(indexer);
share->_num_DBs_lock.unlock();
if (error) {
@@ -8457,7 +8474,7 @@ cleanup:
if (indexer != NULL) {
sprintf(status_msg, "aborting creation of indexes.");
thd_proc_info(thd, status_msg);
- share->_num_DBs_lock.lock_write();
+ rwlock_t_lock_write(share->_num_DBs_lock);
indexer->abort(indexer);
share->_num_DBs_lock.unlock();
}
@@ -8506,10 +8523,10 @@ void ha_tokudb::restore_add_index(
//
// need to restore num_DBs, and we have to do it before we close the dictionaries
- // so that there is not a window
+ // so that there is not a window
//
if (incremented_numDBs) {
- share->_num_DBs_lock.lock_write();
+ rwlock_t_lock_write(share->_num_DBs_lock);
share->num_DBs--;
}
if (modified_DBs) {
diff --git a/storage/tokudb/ha_tokudb.h b/storage/tokudb/ha_tokudb.h
index 3891e57738b..a2fd747bb92 100644
--- a/storage/tokudb/ha_tokudb.h
+++ b/storage/tokudb/ha_tokudb.h
@@ -318,18 +318,18 @@ inline int TOKUDB_SHARE::use_count() const {
}
inline void TOKUDB_SHARE::lock() const {
TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]",
- _full_table_name.ptr(),
- get_state_string(_state),
- _use_count);
- _mutex.lock();
+ _full_table_name.ptr(),
+ get_state_string(_state),
+ _use_count);
+ mutex_t_lock(_mutex);
TOKUDB_SHARE_DBUG_VOID_RETURN();
}
inline void TOKUDB_SHARE::unlock() const {
TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]",
- _full_table_name.ptr(),
- get_state_string(_state),
- _use_count);
- _mutex.unlock();
+ _full_table_name.ptr(),
+ get_state_string(_state),
+ _use_count);
+ mutex_t_unlock(_mutex);
TOKUDB_SHARE_DBUG_VOID_RETURN();
}
inline TOKUDB_SHARE::share_state_t TOKUDB_SHARE::state() const {
diff --git a/storage/tokudb/ha_tokudb_update.cc b/storage/tokudb/ha_tokudb_update.cc
index 23de81f3d8a..9fe5e729ec4 100644
--- a/storage/tokudb/ha_tokudb_update.cc
+++ b/storage/tokudb/ha_tokudb_update.cc
@@ -918,7 +918,7 @@ int ha_tokudb::send_update_message(
marshall_update(update_message, lhs_item, rhs_item, table, share);
}
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
// hot index in progress
if (share->num_DBs > table->s->keys + tokudb_test(hidden_primary_key)) {
@@ -1108,7 +1108,7 @@ int ha_tokudb::send_upsert_message(
marshall_update(update_message, lhs_item, rhs_item, table, share);
}
- share->_num_DBs_lock.lock_read();
+ rwlock_t_lock_read(share->_num_DBs_lock);
// hot index in progress
if (share->num_DBs > table->s->keys + tokudb_test(hidden_primary_key)) {
diff --git a/storage/tokudb/hatoku_cmp.cc b/storage/tokudb/hatoku_cmp.cc
index 13bc60e9d98..88ba83ea0ab 100644
--- a/storage/tokudb/hatoku_cmp.cc
+++ b/storage/tokudb/hatoku_cmp.cc
@@ -1984,6 +1984,7 @@ static uint32_t pack_desc_key_length_info(uchar* buf, KEY_AND_COL_INFO* kc_info,
case (toku_type_fixstring):
field_length = field->pack_length();
set_if_smaller(key_part_length, field_length);
+ // fallthrough
case (toku_type_varbinary):
case (toku_type_varstring):
case (toku_type_blob):
diff --git a/storage/tokudb/hatoku_defines.h b/storage/tokudb/hatoku_defines.h
index 1b33e0a53e4..360272969e5 100644
--- a/storage/tokudb/hatoku_defines.h
+++ b/storage/tokudb/hatoku_defines.h
@@ -168,6 +168,14 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#define HA_CAN_WRITE_DURING_OPTIMIZE 0
#endif
+#if !defined(HA_ONLINE_ANALYZE)
+#define HA_ONLINE_ANALYZE 0
+#endif
+
+#if !defined(MY_ATTRIBUTE)
+#define MY_ATTRIBUTE(A) __attribute__(A)
+#endif
+
#if !defined(HA_OPTION_CREATE_FROM_ENGINE)
#define HA_OPTION_CREATE_FROM_ENGINE 0
#endif
@@ -248,4 +256,22 @@ inline uint tokudb_uint3korr(const uchar *a) {
return uint3korr(b);
}
-#endif // _HATOKU_DEFINES_H
+typedef unsigned int pfs_key_t;
+
+#if defined(HAVE_PSI_MUTEX_INTERFACE)
+#define mutex_t_lock(M) M.lock(__FILE__, __LINE__)
+#define mutex_t_unlock(M) M.unlock(__FILE__, __LINE__)
+#else // HAVE_PSI_MUTEX_INTERFACE
+#define mutex_t_lock(M) M.lock()
+#define mutex_t_unlock(M) M.unlock()
+#endif // HAVE_PSI_MUTEX_INTERFACE
+
+#if defined(HAVE_PSI_RWLOCK_INTERFACE)
+#define rwlock_t_lock_read(M) M.lock_read(__FILE__, __LINE__)
+#define rwlock_t_lock_write(M) M.lock_write(__FILE__, __LINE__)
+#else // HAVE_PSI_RWLOCK_INTERFACE
+#define rwlock_t_lock_read(M) M.lock_read()
+#define rwlock_t_lock_write(M) M.lock_write()
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+
+#endif // _HATOKU_DEFINES_H
diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc
index 7b44044bd81..ac0976fb119 100644
--- a/storage/tokudb/hatoku_hton.cc
+++ b/storage/tokudb/hatoku_hton.cc
@@ -28,6 +28,17 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#define TOKU_METADB_NAME "tokudb_meta"
+static pfs_key_t tokudb_map_mutex_key;
+
+static PSI_mutex_info all_tokudb_mutexes[] = {
+ {&tokudb_map_mutex_key, "tokudb_map_mutex", 0},
+ {&ha_tokudb_mutex_key, "ha_tokudb_mutex", 0},
+};
+
+static PSI_rwlock_info all_tokudb_rwlocks[] = {
+ {&num_DBs_lock_key, "num_DBs_lock", 0},
+};
+
typedef struct savepoint_info {
DB_TXN* txn;
tokudb_trx_data* trx;
@@ -109,8 +120,8 @@ handlerton* tokudb_hton;
const char* ha_tokudb_ext = ".tokudb";
DB_ENV* db_env;
-#if TOKU_THDVAR_MEMALLOC_BUG
static tokudb::thread::mutex_t tokudb_map_mutex;
+#if TOKU_THDVAR_MEMALLOC_BUG
static TREE tokudb_map;
struct tokudb_map_pair {
THD* thd;
@@ -212,6 +223,10 @@ extern "C" {
// use constructor and destructor functions to create and destroy
// the lock before and after main(), respectively.
int tokudb_hton_initialized;
+
+// tokudb_hton_initialized_lock can not be instrumented as it must be
+// initialized before mysql_mutex_register() call to protect
+// some globals from race condition.
tokudb::thread::rwlock_t tokudb_hton_initialized_lock;
static SHOW_VAR *toku_global_status_variables = NULL;
@@ -267,10 +282,23 @@ static int tokudb_init_func(void *p) {
int r;
// 3938: lock the handlerton's initialized status flag for writing
- tokudb_hton_initialized_lock.lock_write();
+ rwlock_t_lock_write(tokudb_hton_initialized_lock);
+
+#ifdef HAVE_PSI_INTERFACE
+ /* Register TokuDB mutex keys with MySQL performance schema */
+ int count;
+
+ count = array_elements(all_tokudb_mutexes);
+ mysql_mutex_register("tokudb", all_tokudb_mutexes, count);
+
+ count = array_elements(all_tokudb_rwlocks);
+ mysql_rwlock_register("tokudb", all_tokudb_rwlocks, count);
+
+ tokudb_map_mutex.reinit(tokudb_map_mutex_key);
+#endif /* HAVE_PSI_INTERFACE */
db_env = NULL;
- tokudb_hton = (handlerton *) p;
+ tokudb_hton = (handlerton*)p;
if (tokudb::sysvars::check_jemalloc) {
typedef int (*mallctl_type)(
@@ -668,7 +696,7 @@ int tokudb_end(handlerton* hton, ha_panic_function type) {
// initialized. grab a writer lock for the duration of the
// call, so we can drop the flag and destroy the mutexes
// in isolation.
- tokudb_hton_initialized_lock.lock_write();
+ rwlock_t_lock_write(tokudb_hton_initialized_lock);
assert_always(tokudb_hton_initialized);
tokudb::background::destroy();
@@ -748,16 +776,16 @@ static int tokudb_close_connection(handlerton* hton, THD* thd) {
}
tokudb::memory::free(trx);
#if TOKU_THDVAR_MEMALLOC_BUG
- tokudb_map_mutex.lock();
- struct tokudb_map_pair key = { thd, NULL };
+ mutex_t_lock(tokudb_map_mutex);
+ struct tokudb_map_pair key = {thd, NULL};
struct tokudb_map_pair* found_key =
- (struct tokudb_map_pair*) tree_search(&tokudb_map, &key, NULL);
+ (struct tokudb_map_pair*)tree_search(&tokudb_map, &key, NULL);
if (found_key) {
tokudb::memory::free(found_key->last_lock_timeout);
tree_delete(&tokudb_map, found_key, sizeof(*found_key), NULL);
}
- tokudb_map_mutex.unlock();
+ mutex_t_unlock(tokudb_map_mutex);
#endif
return error;
}
@@ -1718,12 +1746,12 @@ static void tokudb_lock_timeout_callback(
tokudb::memory::strdup(log_str.c_ptr(), MY_FAE);
tokudb::sysvars::set_last_lock_timeout(thd, new_lock_timeout);
#if TOKU_THDVAR_MEMALLOC_BUG
- tokudb_map_mutex.lock();
- struct tokudb_map_pair old_key = { thd, old_lock_timeout };
+ mutex_t_lock(tokudb_map_mutex);
+ struct tokudb_map_pair old_key = {thd, old_lock_timeout};
tree_delete(&tokudb_map, &old_key, sizeof old_key, NULL);
- struct tokudb_map_pair new_key = { thd, new_lock_timeout };
+ struct tokudb_map_pair new_key = {thd, new_lock_timeout};
tree_insert(&tokudb_map, &new_key, sizeof new_key, NULL);
- tokudb_map_mutex.unlock();
+ mutex_t_unlock(tokudb_map_mutex);
#endif
tokudb::memory::free(old_lock_timeout);
}
diff --git a/storage/tokudb/hatoku_hton.h b/storage/tokudb/hatoku_hton.h
index d126ff4339f..80e13fa9b0c 100644
--- a/storage/tokudb/hatoku_hton.h
+++ b/storage/tokudb/hatoku_hton.h
@@ -39,6 +39,9 @@ extern handlerton* tokudb_hton;
extern DB_ENV* db_env;
+extern pfs_key_t ha_tokudb_mutex_key;
+extern pfs_key_t num_DBs_lock_key;
+
inline tokudb::sysvars::row_format_t toku_compression_method_to_row_format(
toku_compression_method method) {
@@ -180,9 +183,7 @@ inline bool tokudb_killed_thd_callback(void *extra, uint64_t deleted_rows) {
return thd_kill_level(thd) != 0;
}
-
extern HASH tokudb_open_tables;
-extern tokudb::thread::mutex_t tokudb_mutex;
extern const char* tokudb_hton_name;
extern int tokudb_hton_initialized;
extern tokudb::thread::rwlock_t tokudb_hton_initialized_lock;
diff --git a/storage/tokudb/mysql-test/tokudb/disabled.def b/storage/tokudb/mysql-test/tokudb/disabled.def
index ddefceb432e..7f354cd8ba6 100644
--- a/storage/tokudb/mysql-test/tokudb/disabled.def
+++ b/storage/tokudb/mysql-test/tokudb/disabled.def
@@ -29,3 +29,4 @@ cluster_key_part: engine options on partitioned tables
i_s_tokudb_lock_waits_released: unstable, race conditions
i_s_tokudb_locks_released: unstable, race conditions
row_format: n/a
+nonflushing_analyze_debug: Freezes in MariaDB 10.0
diff --git a/storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result b/storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result
index cfd7e38179c..981433fac91 100644
--- a/storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result
+++ b/storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result
@@ -1,7 +1,7 @@
-set global tokudb_cardinality_scale_percent = 10;
analyze table tt;
Table Op Msg_type Msg_text
test.tt analyze status OK
+set global tokudb_cardinality_scale_percent = 10;
show indexes from tt;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE
@@ -9,9 +9,6 @@ tt 1 b 1 b A 4000 NULL NULL YES BTREE
tt 1 c 1 c A 4000 NULL NULL YES BTREE
tt 1 d 1 d A 4000 NULL NULL YES BTREE
set global tokudb_cardinality_scale_percent = 50;
-analyze table tt;
-Table Op Msg_type Msg_text
-test.tt analyze status OK
show indexes from tt;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE
@@ -19,9 +16,6 @@ tt 1 b 1 b A 4000 NULL NULL YES BTREE
tt 1 c 1 c A 4000 NULL NULL YES BTREE
tt 1 d 1 d A 2000 NULL NULL YES BTREE
set global tokudb_cardinality_scale_percent = 100;
-analyze table tt;
-Table Op Msg_type Msg_text
-test.tt analyze status OK
show indexes from tt;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE
@@ -31,9 +25,6 @@ tt 1 d 1 d A 1000 NULL NULL YES BTREE
set global tokudb_cardinality_scale_percent = 200;
Warnings:
Warning 1292 Truncated incorrect tokudb_cardinality_scale_percent value: '200'
-analyze table tt;
-Table Op Msg_type Msg_text
-test.tt analyze status OK
show indexes from tt;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE
diff --git a/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-1.result b/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-1.result
new file mode 100644
index 00000000000..c9fcb5e2273
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-1.result
@@ -0,0 +1,13 @@
+create table t (a int primary key, b int) ENGINE=TokuDB;
+insert into t values (1,0);
+set session transaction isolation level repeatable read;
+begin;
+select * from t where a=1 lock in share mode;
+a b
+1 0
+set session transaction isolation level repeatable read;
+begin;
+update t set b=b+1 where a=1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+drop table t;
diff --git a/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-2.result b/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-2.result
new file mode 100644
index 00000000000..f1b214e514c
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/r/locking-read-repeatable-read-2.result
@@ -0,0 +1,17 @@
+create table t (a int primary key, b int) ENGINE=TokuDB;
+insert into t values (1,0);
+insert into t values (2,1);
+insert into t values (3,2);
+set session transaction isolation level repeatable read;
+begin;
+select * from t lock in share mode;
+a b
+1 0
+2 1
+3 2
+set session transaction isolation level repeatable read;
+begin;
+update t set b=b+1 where a=2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+drop table t;
diff --git a/storage/tokudb/mysql-test/tokudb/r/nonflushing_analyze_debug.result b/storage/tokudb/mysql-test/tokudb/r/nonflushing_analyze_debug.result
new file mode 100644
index 00000000000..e8f51edee04
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/r/nonflushing_analyze_debug.result
@@ -0,0 +1,19 @@
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=TokuDB;
+INSERT INTO t1 VALUES (1), (2), (3);
+SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan";
+SELECT * FROM t1;
+SET DEBUG_SYNC="now WAIT_FOR idx_scan_in_progress";
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+SELECT * FROM t1;
+a
+1
+2
+3
+SET DEBUG_SYNC="now SIGNAL finish_scan";
+a
+1
+2
+3
+DROP TABLE t1;
diff --git a/storage/tokudb/mysql-test/tokudb/r/row_format.result b/storage/tokudb/mysql-test/tokudb/r/row_format.result
index cb669148445..15d4f9fe12a 100644
--- a/storage/tokudb/mysql-test/tokudb/r/row_format.result
+++ b/storage/tokudb/mysql-test/tokudb/r/row_format.result
@@ -1,4 +1,6 @@
CREATE TABLE tokudb_row_format_test_1 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_DEFAULT;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
CREATE TABLE tokudb_row_format_test_2 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_FAST;
CREATE TABLE tokudb_row_format_test_3 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_SMALL;
CREATE TABLE tokudb_row_format_test_4 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_UNCOMPRESSED;
@@ -6,6 +8,41 @@ CREATE TABLE tokudb_row_format_test_5 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_ZL
CREATE TABLE tokudb_row_format_test_6 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_LZMA;
CREATE TABLE tokudb_row_format_test_7 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_QUICKLZ;
CREATE TABLE tokudb_row_format_test_8 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_SNAPPY;
+CREATE TABLE tdb76_1 LIKE tokudb_row_format_test_1;
+CREATE TABLE tdb76_2 LIKE tokudb_row_format_test_2;
+CREATE TABLE tdb76_3 LIKE tokudb_row_format_test_3;
+CREATE TABLE tdb76_4 LIKE tokudb_row_format_test_4;
+CREATE TABLE tdb76_5 LIKE tokudb_row_format_test_5;
+CREATE TABLE tdb76_6 LIKE tokudb_row_format_test_6;
+CREATE TABLE tdb76_7 LIKE tokudb_row_format_test_7;
+CREATE TABLE tdb76_8 LIKE tokudb_row_format_test_8;
+CREATE TABLE tdb76_compact(a INT) ENGINE=TokuDB ROW_FORMAT=COMPACT;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
+CREATE TABLE tdb76_redundant(a INT) ENGINE=TokuDB ROW_FORMAT=REDUNDANT;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
+CREATE TABLE tdb76_dynamic(a INT) ENGINE=TokuDB ROW_FORMAT=DYNAMIC;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
+CREATE TABLE tdb76_compressed(a INT) ENGINE=TokuDB ROW_FORMAT=COMPRESSED;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
+SELECT table_name, row_format, engine FROM information_schema.tables WHERE table_name like 'tdb76_%' ORDER BY table_name;
+table_name row_format engine
+tdb76_1 tokudb_zlib TokuDB
+tdb76_2 tokudb_quicklz TokuDB
+tdb76_3 tokudb_lzma TokuDB
+tdb76_4 tokudb_uncompressed TokuDB
+tdb76_5 tokudb_zlib TokuDB
+tdb76_6 tokudb_lzma TokuDB
+tdb76_7 tokudb_quicklz TokuDB
+tdb76_8 tokudb_snappy TokuDB
+tdb76_compact tokudb_zlib TokuDB
+tdb76_compressed tokudb_zlib TokuDB
+tdb76_dynamic tokudb_zlib TokuDB
+tdb76_redundant tokudb_zlib TokuDB
+DROP TABLE tdb76_1, tdb76_2, tdb76_3, tdb76_4, tdb76_5, tdb76_6, tdb76_7, tdb76_8, tdb76_compact, tdb76_redundant, tdb76_dynamic, tdb76_compressed;
SELECT table_name, row_format, engine FROM information_schema.tables WHERE table_name like 'tokudb_row_format_test%' ORDER BY table_name;
table_name row_format engine
tokudb_row_format_test_1 tokudb_zlib TokuDB
@@ -45,6 +82,8 @@ SELECT table_name, row_format, engine FROM information_schema.tables WHERE table
table_name row_format engine
tokudb_row_format_test_1 tokudb_lzma TokuDB
ALTER TABLE tokudb_row_format_test_1 ENGINE=TokuDB ROW_FORMAT=TOKUDB_DEFAULT;
+Warnings:
+Warning 1478 TokuDB: invalid ROW_FORMAT specifier.
SELECT table_name, row_format, engine FROM information_schema.tables WHERE table_name = 'tokudb_row_format_test_1';
table_name row_format engine
tokudb_row_format_test_1 tokudb_zlib TokuDB
diff --git a/storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test b/storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test
index 47f1eb37989..75c53611308 100644
--- a/storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test
+++ b/storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test
@@ -30,20 +30,18 @@ set session tokudb_analyze_throttle=0;
-- enable_query_log
-set global tokudb_cardinality_scale_percent = 10;
analyze table tt;
+
+set global tokudb_cardinality_scale_percent = 10;
show indexes from tt;
set global tokudb_cardinality_scale_percent = 50;
-analyze table tt;
show indexes from tt;
set global tokudb_cardinality_scale_percent = 100;
-analyze table tt;
show indexes from tt;
set global tokudb_cardinality_scale_percent = 200;
-analyze table tt;
show indexes from tt;
-- disable_query_log
diff --git a/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-1.test b/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-1.test
new file mode 100644
index 00000000000..c5ef0f0703e
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-1.test
@@ -0,0 +1,23 @@
+source include/have_tokudb.inc;
+source include/count_sessions.inc;
+create table t (a int primary key, b int) ENGINE=TokuDB;
+insert into t values (1,0);
+set session transaction isolation level repeatable read;
+begin;
+# t1 select in share mode
+select * from t where a=1 lock in share mode;
+# t2 update
+connect(conn1,localhost,root);
+set session transaction isolation level repeatable read;
+begin;
+# t2 select for update, should hang until t1 commits
+send update t set b=b+1 where a=1;
+--error ER_LOCK_WAIT_TIMEOUT
+reap;
+# t2 update
+connection default;
+commit;
+disconnect conn1;
+drop table t;
+
+source include/wait_until_count_sessions.inc;
diff --git a/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-2.test b/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-2.test
new file mode 100644
index 00000000000..20a4549c45f
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/t/locking-read-repeatable-read-2.test
@@ -0,0 +1,29 @@
+#the difference of this test from locking-read-repeatable-read-1
+#is that this test is on range query(gap lock) which actually
+#examines a different patch
+
+source include/have_tokudb.inc;
+source include/count_sessions.inc;
+create table t (a int primary key, b int) ENGINE=TokuDB;
+insert into t values (1,0);
+insert into t values (2,1);
+insert into t values (3,2);
+set session transaction isolation level repeatable read;
+begin;
+# t1 select in share mode
+select * from t lock in share mode;
+# t2 update
+connect(conn1,localhost,root);
+set session transaction isolation level repeatable read;
+begin;
+# t2 select for update, should hang until t1 commits
+send update t set b=b+1 where a=2;
+--error ER_LOCK_WAIT_TIMEOUT
+reap;
+# t2 update
+connection default;
+commit;
+disconnect conn1;
+drop table t;
+
+source include/wait_until_count_sessions.inc;
diff --git a/storage/tokudb/mysql-test/tokudb/t/nonflushing_analyze_debug.test b/storage/tokudb/mysql-test/tokudb/t/nonflushing_analyze_debug.test
new file mode 100644
index 00000000000..0c4c01b3dc0
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb/t/nonflushing_analyze_debug.test
@@ -0,0 +1,10 @@
+--source include/have_debug_sync.inc
+--source include/have_tokudb.inc
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=TokuDB;
+INSERT INTO t1 VALUES (1), (2), (3);
+
+--let $percona_nonflushing_analyze_table= t1
+--source include/percona_nonflushing_analyze_debug.inc
+
+DROP TABLE t1;
diff --git a/storage/tokudb/mysql-test/tokudb/t/row_format.test b/storage/tokudb/mysql-test/tokudb/t/row_format.test
index 6533f8c06be..9c5c6e6403e 100644
--- a/storage/tokudb/mysql-test/tokudb/t/row_format.test
+++ b/storage/tokudb/mysql-test/tokudb/t/row_format.test
@@ -12,6 +12,27 @@ CREATE TABLE tokudb_row_format_test_6 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_LZ
CREATE TABLE tokudb_row_format_test_7 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_QUICKLZ;
CREATE TABLE tokudb_row_format_test_8 (a INT) ENGINE=TokuDB ROW_FORMAT=TOKUDB_SNAPPY;
+# TDB-76 : CREATE TABLE ... LIKE ... does not use source row_format on target table
+CREATE TABLE tdb76_1 LIKE tokudb_row_format_test_1;
+CREATE TABLE tdb76_2 LIKE tokudb_row_format_test_2;
+CREATE TABLE tdb76_3 LIKE tokudb_row_format_test_3;
+CREATE TABLE tdb76_4 LIKE tokudb_row_format_test_4;
+CREATE TABLE tdb76_5 LIKE tokudb_row_format_test_5;
+CREATE TABLE tdb76_6 LIKE tokudb_row_format_test_6;
+CREATE TABLE tdb76_7 LIKE tokudb_row_format_test_7;
+CREATE TABLE tdb76_8 LIKE tokudb_row_format_test_8;
+
+CREATE TABLE tdb76_compact(a INT) ENGINE=TokuDB ROW_FORMAT=COMPACT;
+CREATE TABLE tdb76_redundant(a INT) ENGINE=TokuDB ROW_FORMAT=REDUNDANT;
+CREATE TABLE tdb76_dynamic(a INT) ENGINE=TokuDB ROW_FORMAT=DYNAMIC;
+CREATE TABLE tdb76_compressed(a INT) ENGINE=TokuDB ROW_FORMAT=COMPRESSED;
+
+SELECT table_name, row_format, engine FROM information_schema.tables WHERE table_name like 'tdb76_%' ORDER BY table_name;
+
+DROP TABLE tdb76_1, tdb76_2, tdb76_3, tdb76_4, tdb76_5, tdb76_6, tdb76_7, tdb76_8, tdb76_compact, tdb76_redundant, tdb76_dynamic, tdb76_compressed;
+
+
+
SELECT table_name, row_format, engine FROM information_schema.tables WHERE table_name like 'tokudb_row_format_test%' ORDER BY table_name;
ALTER TABLE tokudb_row_format_test_1 ENGINE=TokuDB ROW_FORMAT=TOKUDB_FAST;
diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result
index 5ba5da21789..caaa963c325 100644
--- a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result
+++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result
@@ -17,5 +17,5 @@ test.t analyze status OK
show indexes from t;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
t 0 PRIMARY 1 id A 7 NULL NULL BTREE
-t 1 x 1 x A 3 NULL NULL YES BTREE
+t 1 x 1 x A 7 NULL NULL YES BTREE
drop table t;
diff --git a/storage/tokudb/mysql-test/tokudb_parts/disabled.def b/storage/tokudb/mysql-test/tokudb_parts/disabled.def
index 3252a463176..17a8ddcc12e 100644
--- a/storage/tokudb/mysql-test/tokudb_parts/disabled.def
+++ b/storage/tokudb/mysql-test/tokudb_parts/disabled.def
@@ -7,3 +7,4 @@ partition_max_sub_parts_key_list_tokudb: 5.6 test not merged yet
partition_max_sub_parts_key_range_tokudb: 5.6 test not merged yet
partition_max_sub_parts_list_tokudb: 5.6 test not merged yet
partition_max_sub_parts_range_tokudb: 5.6 test not merged yet
+nonflushing_analyze_debug: Freezes in MariaDB 10.0
diff --git a/storage/tokudb/mysql-test/tokudb_parts/r/nonflushing_analyze_debug.result b/storage/tokudb/mysql-test/tokudb_parts/r/nonflushing_analyze_debug.result
new file mode 100644
index 00000000000..5a7bfb369df
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_parts/r/nonflushing_analyze_debug.result
@@ -0,0 +1,50 @@
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=TokuDB
+PARTITION BY RANGE (a) (
+PARTITION p0 VALUES LESS THAN (3),
+PARTITION p1 VALUES LESS THAN (10));
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan";
+SELECT * FROM t1;
+SET DEBUG_SYNC="now WAIT_FOR idx_scan_in_progress";
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+SELECT * FROM t1;
+a
+1
+2
+3
+4
+SET DEBUG_SYNC="now SIGNAL finish_scan";
+a
+1
+2
+3
+4
+DROP TABLE t1;
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=TokuDB
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH (A)
+SUBPARTITIONS 2 (
+PARTITION p0 VALUES LESS THAN (3),
+PARTITION p1 VALUES LESS THAN (10));
+INSERT INTO t2 VALUES (1), (2), (3), (4);
+SET DEBUG_SYNC="handler_ha_index_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan";
+SELECT * FROM t2;
+SET DEBUG_SYNC="now WAIT_FOR idx_scan_in_progress";
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+SELECT * FROM t2;
+a
+2
+1
+4
+3
+SET DEBUG_SYNC="now SIGNAL finish_scan";
+a
+2
+1
+4
+3
+DROP TABLE t2;
diff --git a/storage/tokudb/mysql-test/tokudb_parts/t/nonflushing_analyze_debug.test b/storage/tokudb/mysql-test/tokudb_parts/t/nonflushing_analyze_debug.test
new file mode 100644
index 00000000000..c99206acfe3
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_parts/t/nonflushing_analyze_debug.test
@@ -0,0 +1,29 @@
+--source include/have_debug_sync.inc
+--source include/have_tokudb.inc
+--source include/have_partition.inc
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=TokuDB
+ PARTITION BY RANGE (a) (
+ PARTITION p0 VALUES LESS THAN (3),
+ PARTITION p1 VALUES LESS THAN (10));
+
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+
+--let $percona_nonflushing_analyze_table= t1
+--source include/percona_nonflushing_analyze_debug.inc
+
+DROP TABLE t1;
+
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=TokuDB
+ PARTITION BY RANGE (a)
+ SUBPARTITION BY HASH (A)
+ SUBPARTITIONS 2 (
+ PARTITION p0 VALUES LESS THAN (3),
+ PARTITION p1 VALUES LESS THAN (10));
+
+INSERT INTO t2 VALUES (1), (2), (3), (4);
+
+--let $percona_nonflushing_analyze_table= t2
+--source include/percona_nonflushing_analyze_debug.inc
+
+DROP TABLE t2;
diff --git a/storage/tokudb/mysql-test/tokudb_perfschema/r/crash_tokudb.result b/storage/tokudb/mysql-test/tokudb_perfschema/r/crash_tokudb.result
new file mode 100644
index 00000000000..189d6bef14e
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_perfschema/r/crash_tokudb.result
@@ -0,0 +1,30 @@
+SELECT COUNT(*) > 0 FROM performance_schema.setup_consumers
+WHERE ENABLED = "NO";
+COUNT(*) > 0
+0
+SELECT COUNT(*) > 0 FROM performance_schema.setup_instruments
+WHERE NAME LIKE "%/fti/%" AND (ENABLED = 'NO' OR TIMED = "NO");
+COUNT(*) > 0
+0
+CREATE TABLE t(a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE=TokuDB;
+INSERT INTO t (b) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+(1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+INSERT INTO t (b) SELECT b FROM t;
+UPDATE t SET b = 11 WHERE b = 10;
+DELETE FROM t WHERE b = 1;
+ALTER TABLE t ADD COLUMN c CHAR(10) default NULL;
+TRUNCATE TABLE t;
+RENAME TABLE t TO t1;
+RENAME TABLE t1 TO t;
+SELECT COUNT(*) > 0 FROM t;
+COUNT(*) > 0
+0
+DROP TABLE t;
diff --git a/storage/tokudb/mysql-test/tokudb_perfschema/r/start_server_tokudb.result b/storage/tokudb/mysql-test/tokudb_perfschema/r/start_server_tokudb.result
new file mode 100644
index 00000000000..2e220916ec3
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_perfschema/r/start_server_tokudb.result
@@ -0,0 +1,114 @@
+show databases;
+Database
+information_schema
+mtr
+mysql
+performance_schema
+test
+select count(*) from performance_schema.performance_timers;
+count(*)
+5
+select count(*) from performance_schema.setup_consumers;
+count(*)
+12
+select count(*) > 3 from performance_schema.setup_instruments;
+count(*) > 3
+1
+select count(*) from performance_schema.setup_timers;
+count(*)
+4
+select * from performance_schema.accounts;
+select * from performance_schema.cond_instances;
+select * from performance_schema.events_stages_current;
+select * from performance_schema.events_stages_history;
+select * from performance_schema.events_stages_history_long;
+select * from performance_schema.events_stages_summary_by_account_by_event_name;
+select * from performance_schema.events_stages_summary_by_host_by_event_name;
+select * from performance_schema.events_stages_summary_by_thread_by_event_name;
+select * from performance_schema.events_stages_summary_by_user_by_event_name;
+select * from performance_schema.events_stages_summary_global_by_event_name;
+select * from performance_schema.events_statements_current;
+select * from performance_schema.events_statements_history;
+select * from performance_schema.events_statements_history_long;
+select * from performance_schema.events_statements_summary_by_account_by_event_name;
+select * from performance_schema.events_statements_summary_by_digest;
+select * from performance_schema.events_statements_summary_by_host_by_event_name;
+select * from performance_schema.events_statements_summary_by_thread_by_event_name;
+select * from performance_schema.events_statements_summary_by_user_by_event_name;
+select * from performance_schema.events_statements_summary_global_by_event_name;
+select * from performance_schema.events_waits_current;
+select * from performance_schema.events_waits_history;
+select * from performance_schema.events_waits_history_long;
+select * from performance_schema.events_waits_summary_by_account_by_event_name;
+select * from performance_schema.events_waits_summary_by_host_by_event_name;
+select * from performance_schema.events_waits_summary_by_instance;
+select * from performance_schema.events_waits_summary_by_thread_by_event_name;
+select * from performance_schema.events_waits_summary_by_user_by_event_name;
+select * from performance_schema.events_waits_summary_global_by_event_name;
+select * from performance_schema.file_instances;
+select * from performance_schema.file_summary_by_event_name;
+select * from performance_schema.file_summary_by_instance;
+select * from performance_schema.host_cache;
+select * from performance_schema.hosts;
+select * from performance_schema.mutex_instances;
+select * from performance_schema.objects_summary_global_by_type;
+select * from performance_schema.performance_timers;
+select * from performance_schema.rwlock_instances;
+select * from performance_schema.session_account_connect_attrs;
+select * from performance_schema.session_connect_attrs;
+select * from performance_schema.setup_actors;
+select * from performance_schema.setup_consumers;
+select * from performance_schema.setup_instruments;
+select * from performance_schema.setup_objects;
+select * from performance_schema.setup_timers;
+select * from performance_schema.socket_instances;
+select * from performance_schema.socket_summary_by_instance;
+select * from performance_schema.socket_summary_by_event_name;
+select * from performance_schema.table_io_waits_summary_by_index_usage;
+select * from performance_schema.table_io_waits_summary_by_table;
+select * from performance_schema.table_lock_waits_summary_by_table;
+select * from performance_schema.threads;
+select * from performance_schema.users;
+show variables where
+`Variable_name` != "performance_schema_max_statement_classes" and
+`Variable_name` like "performance_schema%";
+Variable_name Value
+performance_schema ON
+performance_schema_accounts_size 100
+performance_schema_digests_size 200
+performance_schema_events_stages_history_long_size 1000
+performance_schema_events_stages_history_size 10
+performance_schema_events_statements_history_long_size 1000
+performance_schema_events_statements_history_size 10
+performance_schema_events_waits_history_long_size 10000
+performance_schema_events_waits_history_size 10
+performance_schema_hosts_size 100
+performance_schema_max_cond_classes 80
+performance_schema_max_cond_instances 1000
+performance_schema_max_digest_length 1024
+performance_schema_max_file_classes 50
+performance_schema_max_file_handles 32768
+performance_schema_max_file_instances 10000
+performance_schema_max_mutex_classes 200
+performance_schema_max_mutex_instances 5000
+performance_schema_max_rwlock_classes 40
+performance_schema_max_rwlock_instances 5000
+performance_schema_max_socket_classes 10
+performance_schema_max_socket_instances 1000
+performance_schema_max_stage_classes 150
+performance_schema_max_table_handles 1000
+performance_schema_max_table_instances 500
+performance_schema_max_thread_classes 50
+performance_schema_max_thread_instances 200
+performance_schema_session_connect_attrs_size 2048
+performance_schema_setup_actors_size 100
+performance_schema_setup_objects_size 100
+performance_schema_users_size 100
+show engine PERFORMANCE_SCHEMA status;
+show status like "performance_schema%";
+SELECT COUNT(NAME) > 0 FROM performance_schema.setup_instruments WHERE NAME LIKE "%/fti/%";
+COUNT(NAME) > 0
+1
+SELECT COUNT(NAME) > 0 FROM performance_schema.threads WHERE NAME LIKE "%kibbutz%";
+COUNT(NAME) > 0
+1
diff --git a/storage/tokudb/mysql-test/tokudb_perfschema/t/crash_tokudb.test b/storage/tokudb/mysql-test/tokudb_perfschema/t/crash_tokudb.test
new file mode 100644
index 00000000000..31757a20259
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_perfschema/t/crash_tokudb.test
@@ -0,0 +1,36 @@
+# TokuDB PFS crash test:
+# Make sure FTI instrumentation is on, execute base DDL, DML queries
+# and make sure there is no crash.
+
+--source include/not_embedded.inc
+--source include/have_perfschema.inc
+--source include/have_tokudb.inc
+
+SELECT COUNT(*) > 0 FROM performance_schema.setup_consumers
+ WHERE ENABLED = "NO";
+SELECT COUNT(*) > 0 FROM performance_schema.setup_instruments
+ WHERE NAME LIKE "%/fti/%" AND (ENABLED = 'NO' OR TIMED = "NO");
+
+CREATE TABLE t(a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE=TokuDB;
+INSERT INTO t (b) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+INSERT INTO t (b) SELECT b FROM t;
+
+UPDATE t SET b = 11 WHERE b = 10;
+DELETE FROM t WHERE b = 1;
+
+ALTER TABLE t ADD COLUMN c CHAR(10) default NULL;
+TRUNCATE TABLE t;
+RENAME TABLE t TO t1;
+RENAME TABLE t1 TO t;
+
+SELECT COUNT(*) > 0 FROM t;
+DROP TABLE t;
diff --git a/storage/tokudb/mysql-test/tokudb_perfschema/t/start_server_tokudb.test b/storage/tokudb/mysql-test/tokudb_perfschema/t/start_server_tokudb.test
new file mode 100644
index 00000000000..4034fba0549
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_perfschema/t/start_server_tokudb.test
@@ -0,0 +1,10 @@
+# Tests for PERFORMANCE_SCHEMA
+
+--source include/not_embedded.inc
+--source include/have_perfschema.inc
+--source include/have_tokudb.inc
+
+--source ../../perfschema/include/start_server_common.inc
+
+SELECT COUNT(NAME) > 0 FROM performance_schema.setup_instruments WHERE NAME LIKE "%/fti/%";
+SELECT COUNT(NAME) > 0 FROM performance_schema.threads WHERE NAME LIKE "%kibbutz%";
diff --git a/storage/tokudb/mysql-test/tokudb_perfschema/t/suite.opt b/storage/tokudb/mysql-test/tokudb_perfschema/t/suite.opt
new file mode 100644
index 00000000000..6d826fe91d1
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_perfschema/t/suite.opt
@@ -0,0 +1 @@
+--loose-enable-performance-schema $TOKUDB_OPT $TOKUDB_LOAD_ADD --loose-tokudb-check-jemalloc=0 --loose-tokudb-cache-size=512M --loose-tokudb-block-size=1M
diff --git a/storage/tokudb/tokudb_background.cc b/storage/tokudb/tokudb_background.cc
index e019e41c788..13e0e9321cc 100644
--- a/storage/tokudb/tokudb_background.cc
+++ b/storage/tokudb/tokudb_background.cc
@@ -66,13 +66,13 @@ void job_manager_t::destroy() {
_sem.set_interrupt();
while (_background_jobs.size()) {
- _mutex.lock();
+ mutex_t_lock(_mutex);
job_t* job = _background_jobs.front();
if (!job->cancelled())
cancel(job);
_background_jobs.pop_front();
delete job;
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
}
void* result;
@@ -83,7 +83,7 @@ bool job_manager_t::run_job(job_t* newjob, bool background) {
bool ret = false;
const char* jobkey = newjob->key();
- _mutex.lock();
+ mutex_t_lock(_mutex);
assert_always(!_shutdown);
for (jobs_t::iterator it = _background_jobs.begin();
@@ -138,15 +138,16 @@ bool job_manager_t::run_job(job_t* newjob, bool background) {
}
cleanup:
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
return ret;
}
bool job_manager_t::cancel_job(const char* key) {
bool ret = false;
- _mutex.lock();
+ mutex_t_lock(_mutex);
for (jobs_t::iterator it = _background_jobs.begin();
- it != _background_jobs.end(); it++) {
+ it != _background_jobs.end();
+ it++) {
job_t* job = *it;
if (!job->cancelled() && strcmp(job->key(), key) == 0) {
@@ -155,12 +156,11 @@ bool job_manager_t::cancel_job(const char* key) {
}
}
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
return ret;
}
void job_manager_t::iterate_jobs(pfn_iterate_t callback, void* extra) const {
-
- _mutex.lock();
+ mutex_t_lock(_mutex);
for (jobs_t::const_iterator it = _background_jobs.begin();
it != _background_jobs.end();
@@ -171,7 +171,7 @@ void job_manager_t::iterate_jobs(pfn_iterate_t callback, void* extra) const {
}
}
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
}
void* job_manager_t::thread_func(void* v) {
return ((tokudb::background::job_manager_t*)v)->real_thread_func();
@@ -189,14 +189,14 @@ void* job_manager_t::real_thread_func() {
tokudb::time::sleep_microsec(250000);
continue;
}
-#endif // TOKUDB_DEBUG
+#endif // TOKUDB_DEBUG
- _mutex.lock();
+ mutex_t_lock(_mutex);
assert_debug(_background_jobs.size() > 0);
job_t* job = _background_jobs.front();
run(job);
_background_jobs.pop_front();
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
delete job;
}
}
@@ -205,11 +205,11 @@ void* job_manager_t::real_thread_func() {
void job_manager_t::run(job_t* job) {
assert_debug(_mutex.is_owned_by_me());
if (!job->cancelled()) {
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
// do job
job->run();
// done job
- _mutex.lock();
+ mutex_t_lock(_mutex);
}
if (!job->cancelled()) {
job->destroy();
diff --git a/storage/tokudb/tokudb_background.h b/storage/tokudb/tokudb_background.h
index 29991ab325d..bf5eb97a619 100644
--- a/storage/tokudb/tokudb_background.h
+++ b/storage/tokudb/tokudb_background.h
@@ -174,11 +174,11 @@ bool destroy();
inline void job_manager_t::lock() {
assert_debug(!_mutex.is_owned_by_me());
- _mutex.lock();
+ mutex_t_lock(_mutex);
}
inline void job_manager_t::unlock() {
assert_debug(_mutex.is_owned_by_me());
- _mutex.unlock();
+ mutex_t_unlock(_mutex);
}
inline void job_manager_t::job_t::run() {
diff --git a/storage/tokudb/tokudb_information_schema.cc b/storage/tokudb/tokudb_information_schema.cc
index 5cd0609ac74..bb263d5f960 100644
--- a/storage/tokudb/tokudb_information_schema.cc
+++ b/storage/tokudb/tokudb_information_schema.cc
@@ -99,7 +99,7 @@ int trx_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) {
TOKUDB_DBUG_ENTER("");
int error;
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -234,7 +234,7 @@ int lock_waits_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) {
TOKUDB_DBUG_ENTER("");
int error;
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -377,7 +377,7 @@ int locks_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) {
TOKUDB_DBUG_ENTER("");
int error;
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -521,7 +521,7 @@ int file_map_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) {
int error;
TABLE* table = tables->table;
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -728,7 +728,7 @@ int fractal_tree_info_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) {
// 3938: Get a read lock on the status flag, since we must
// read it before safely proceeding
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -1025,7 +1025,7 @@ int fractal_tree_block_map_fill_table(
// 3938: Get a read lock on the status flag, since we must
// read it before safely proceeding
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
@@ -1162,7 +1162,7 @@ int background_job_status_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) {
int error;
TABLE* table = tables->table;
- tokudb_hton_initialized_lock.lock_read();
+ rwlock_t_lock_read(tokudb_hton_initialized_lock);
if (!tokudb_hton_initialized) {
error = ER_PLUGIN_IS_NOT_LOADED;
diff --git a/storage/tokudb/tokudb_thread.cc b/storage/tokudb/tokudb_thread.cc
index f27e803a065..6fc1191975d 100644
--- a/storage/tokudb/tokudb_thread.cc
+++ b/storage/tokudb/tokudb_thread.cc
@@ -29,6 +29,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
namespace tokudb {
namespace thread {
+const pfs_key_t pfs_not_instrumented = 0xFFFFFFFF;
pthread_t mutex_t::_null_owner = 0;
} // namespace thread
diff --git a/storage/tokudb/tokudb_thread.h b/storage/tokudb/tokudb_thread.h
index dcb1fd6ec63..dec58f3fd35 100644
--- a/storage/tokudb/tokudb_thread.h
+++ b/storage/tokudb/tokudb_thread.h
@@ -34,95 +34,68 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
namespace tokudb {
namespace thread {
-#if (defined(__MACH__) || defined(__APPLE__)) && _POSIX_TIMERS <= 0
-
-#define _x_min(a, b) ((a) < (b) ? (a) : (b))
-
-#define timed_lock_define(timed_func_name, lock_type_name, lock_func_name) \
-inline int timed_func_name(lock_type_name *mutex, \
- const struct timespec *abs_timeout) { \
- int pthread_rc; \
- struct timespec remaining, slept, ts; \
- static const int sleep_step = 1000000; \
- \
- remaining = *abs_timeout; \
- while ((pthread_rc = lock_func_name(mutex)) == EBUSY) { \
- ts.tv_sec = 0; \
- ts.tv_nsec = (remaining.tv_sec > 0 ? \
- sleep_step : \
- _x_min(remaining.tv_nsec,sleep_step)); \
- nanosleep(&ts, &slept); \
- ts.tv_nsec -= slept.tv_nsec; \
- if (ts.tv_nsec <= remaining.tv_nsec) { \
- remaining.tv_nsec -= ts.tv_nsec; \
- } else { \
- remaining.tv_sec--; \
- remaining.tv_nsec = \
- (sleep_step - (ts.tv_nsec - remaining.tv_nsec)); \
- } \
- if (remaining.tv_sec < 0 || \
- (!remaining.tv_sec && remaining.tv_nsec <= 0)) { \
- return ETIMEDOUT; \
- } \
- } \
- \
- return pthread_rc; \
-}
-
-timed_lock_define(pthread_mutex_timedlock,
- pthread_mutex_t,
- pthread_mutex_trylock);
-
-timed_lock_define(pthread_rwlock_timedrdlock,
- pthread_rwlock_t,
- pthread_rwlock_tryrdlock);
-
-timed_lock_define(pthread_rwlock_timedwrlock,
- pthread_rwlock_t,
- pthread_rwlock_trywrlock);
-
-#endif //(defined(__MACH__) || defined(__APPLE__)) && _POSIX_TIMERS <= 0
+extern const pfs_key_t pfs_not_instrumented;
uint my_tid(void);
// Your basic mutex
class mutex_t {
public:
- mutex_t(void);
+ explicit mutex_t(pfs_key_t key);
+ mutex_t(void) : mutex_t(pfs_not_instrumented) {}
~mutex_t(void);
- void lock(void);
- int lock(ulonglong microseconds);
- void unlock(void);
+ void reinit(pfs_key_t key);
+ void lock(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_MUTEX_INTERFACE
+ );
+ void unlock(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_MUTEX_INTERFACE
+ );
#ifdef TOKUDB_DEBUG
bool is_owned_by_me(void) const;
#endif
private:
static pthread_t _null_owner;
- pthread_mutex_t _mutex;
+ mysql_mutex_t _mutex;
#ifdef TOKUDB_DEBUG
- uint _owners;
- pthread_t _owner;
+ uint _owners;
+ pthread_t _owner;
#endif
};
// Simple read write lock
class rwlock_t {
public:
- rwlock_t(void);
+ explicit rwlock_t(pfs_key_t key);
+ rwlock_t(void) : rwlock_t(pfs_not_instrumented) {}
~rwlock_t(void);
- void lock_read(void);
- int lock_read(ulonglong microseconds);
- void lock_write(void);
- int lock_write(ulonglong microseconds);
+ void lock_read(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ );
+ void lock_write(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ );
void unlock(void);
private:
rwlock_t(const rwlock_t&);
rwlock_t& operator=(const rwlock_t&);
- pthread_rwlock_t _rwlock;
+ mysql_rwlock_t _rwlock;
};
// Simple event signal/wait class
@@ -224,57 +197,76 @@ private:
pthread_t _thread;
};
+inline uint my_tid(void) { return (uint)toku_os_gettid(); }
-inline uint my_tid(void) {
- return (uint)toku_os_gettid();
-}
-
-
-inline mutex_t::mutex_t(void) {
- #ifdef TOKUDB_DEBUG
- _owners = 0;
- _owner = _null_owner;
- #endif
- int r = pthread_mutex_init(&_mutex, MY_MUTEX_INIT_FAST);
+inline mutex_t::mutex_t(pfs_key_t key) {
+#ifdef TOKUDB_DEBUG
+ _owners = 0;
+ _owner = _null_owner;
+#endif
+ int r MY_ATTRIBUTE((unused)) = mysql_mutex_init(key, &_mutex, MY_MUTEX_INIT_FAST);
assert_debug(r == 0);
}
inline mutex_t::~mutex_t(void) {
- #ifdef TOKUDB_DEBUG
- assert_debug(_owners == 0);
- #endif
- int r = pthread_mutex_destroy(&_mutex);
+#ifdef TOKUDB_DEBUG
+ assert_debug(_owners == 0);
+#endif
+ int r MY_ATTRIBUTE((unused)) = mysql_mutex_destroy(&_mutex);
assert_debug(r == 0);
}
-inline void mutex_t::lock(void) {
- assert_debug(is_owned_by_me() == false);
- int r = pthread_mutex_lock(&_mutex);
+inline void mutex_t::reinit(pfs_key_t key) {
+#ifdef TOKUDB_DEBUG
+ assert_debug(_owners == 0);
+#endif
+ int r MY_ATTRIBUTE((unused));
+ r = mysql_mutex_destroy(&_mutex);
+ assert_debug(r == 0);
+ r = mysql_mutex_init(key, &_mutex, MY_MUTEX_INIT_FAST);
assert_debug(r == 0);
- #ifdef TOKUDB_DEBUG
- _owners++;
- _owner = pthread_self();
- #endif
}
-inline int mutex_t::lock(ulonglong microseconds) {
+inline void mutex_t::lock(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_MUTEX_INTERFACE
+ ) {
assert_debug(is_owned_by_me() == false);
- timespec waittime = time::offset_timespec(microseconds);
- int r = pthread_mutex_timedlock(&_mutex, &waittime);
- #ifdef TOKUDB_DEBUG
- if (r == 0) {
- _owners++;
- _owner = pthread_self();
- }
- #endif
- assert_debug(r == 0 || r == ETIMEDOUT);
- return r;
+ int r MY_ATTRIBUTE((unused)) = inline_mysql_mutex_lock(&_mutex
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ ,
+ src_file,
+ src_line
+#endif // HAVE_PSI_MUTEX_INTERFACE
+ );
+ assert_debug(r == 0);
+#ifdef TOKUDB_DEBUG
+ _owners++;
+ _owner = pthread_self();
+#endif
}
-inline void mutex_t::unlock(void) {
- #ifdef TOKUDB_DEBUG
- assert_debug(_owners > 0);
- assert_debug(is_owned_by_me());
- _owners--;
- _owner = _null_owner;
- #endif
- int r = pthread_mutex_unlock(&_mutex);
+inline void mutex_t::unlock(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_MUTEX_INTERFACE
+ ) {
+#ifndef SAFE_MUTEX
+ (void)(src_file);
+ (void)(src_line);
+#endif // SAFE_MUTEX
+#ifdef TOKUDB_DEBUG
+ assert_debug(_owners > 0);
+ assert_debug(is_owned_by_me());
+ _owners--;
+ _owner = _null_owner;
+#endif
+ int r MY_ATTRIBUTE((unused)) = inline_mysql_mutex_unlock(&_mutex
+#ifdef SAFE_MUTEX
+ ,
+ src_file,
+ src_line
+#endif // SAFE_MUTEX
+ );
assert_debug(r == 0);
}
#ifdef TOKUDB_DEBUG
@@ -283,44 +275,28 @@ inline bool mutex_t::is_owned_by_me(void) const {
}
#endif
-
-inline rwlock_t::rwlock_t(void) {
- int r = pthread_rwlock_init(&_rwlock, NULL);
+inline rwlock_t::rwlock_t(pfs_key_t key) {
+ int r MY_ATTRIBUTE((unused)) = mysql_rwlock_init(key, &_rwlock);
assert_debug(r == 0);
}
inline rwlock_t::~rwlock_t(void) {
- int r = pthread_rwlock_destroy(&_rwlock);
- assert_debug(r == 0);
-}
-inline void rwlock_t::lock_read(void) {
- int r;
- while ((r = pthread_rwlock_rdlock(&_rwlock)) != 0) {
- if (r == EBUSY || r == EAGAIN) {
- time::sleep_microsec(1000);
- continue;
- }
- break;
- }
- assert_debug(r == 0);
-}
-inline int rwlock_t::lock_read(ulonglong microseconds) {
- int r;
- timespec waittime = time::offset_timespec(microseconds);
- while ((r = pthread_rwlock_timedrdlock(&_rwlock, &waittime)) != 0) {
- if (r == EBUSY || r == EAGAIN) {
- time::sleep_microsec(1000);
- continue;
- } else if (r == ETIMEDOUT) {
- return ETIMEDOUT;
- }
- break;
- }
+ int r MY_ATTRIBUTE((unused)) = mysql_rwlock_destroy(&_rwlock);
assert_debug(r == 0);
- return r;
}
-inline void rwlock_t::lock_write(void) {
+inline void rwlock_t::lock_read(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ ) {
int r;
- while ((r = pthread_rwlock_wrlock(&_rwlock)) != 0) {
+ while ((r = inline_mysql_rwlock_rdlock(&_rwlock
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ ,
+ src_file,
+ src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ )) != 0) {
if (r == EBUSY || r == EAGAIN) {
time::sleep_microsec(1000);
continue;
@@ -329,27 +305,33 @@ inline void rwlock_t::lock_write(void) {
}
assert_debug(r == 0);
}
-inline int rwlock_t::lock_write(ulonglong microseconds) {
+inline void rwlock_t::lock_write(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ const char* src_file,
+ uint src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ ) {
int r;
- timespec waittime = time::offset_timespec(microseconds);
- while ((r = pthread_rwlock_timedwrlock(&_rwlock, &waittime)) != 0) {
+ while ((r = inline_mysql_rwlock_wrlock(&_rwlock
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ ,
+ src_file,
+ src_line
+#endif // HAVE_PSI_RWLOCK_INTERFACE
+ )) != 0) {
if (r == EBUSY || r == EAGAIN) {
time::sleep_microsec(1000);
continue;
- } else if (r == ETIMEDOUT) {
- return ETIMEDOUT;
}
break;
}
assert_debug(r == 0);
- return r;
}
inline void rwlock_t::unlock(void) {
- int r = pthread_rwlock_unlock(&_rwlock);
+ int r MY_ATTRIBUTE((unused)) = mysql_rwlock_unlock(&_rwlock);
assert_debug(r == 0);
}
-inline rwlock_t::rwlock_t(const rwlock_t&) {
-}
+inline rwlock_t::rwlock_t(const rwlock_t&) {}
inline rwlock_t& rwlock_t::operator=(const rwlock_t&) {
return *this;
}
@@ -358,7 +340,7 @@ inline rwlock_t& rwlock_t::operator=(const rwlock_t&) {
inline event_t::event_t(bool create_signalled, bool manual_reset) :
_manual_reset(manual_reset) {
- int r = pthread_mutex_init(&_mutex, NULL);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_init(&_mutex, NULL);
assert_debug(r == 0);
r = pthread_cond_init(&_cond, NULL);
assert_debug(r == 0);
@@ -370,13 +352,13 @@ inline event_t::event_t(bool create_signalled, bool manual_reset) :
_pulsed = false;
}
inline event_t::~event_t(void) {
- int r = pthread_mutex_destroy(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_destroy(&_mutex);
assert_debug(r == 0);
r = pthread_cond_destroy(&_cond);
assert_debug(r == 0);
}
inline void event_t::wait(void) {
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
while (_signalled == false && _pulsed == false) {
r = pthread_cond_wait(&_cond, &_mutex);
@@ -413,7 +395,7 @@ inline int event_t::wait(ulonglong microseconds) {
return 0;
}
inline void event_t::signal(void) {
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_signalled = true;
if (_manual_reset) {
@@ -427,7 +409,7 @@ inline void event_t::signal(void) {
assert_debug(r == 0);
}
inline void event_t::pulse(void) {
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_pulsed = true;
r = pthread_cond_signal(&_cond);
@@ -437,7 +419,7 @@ inline void event_t::pulse(void) {
}
inline bool event_t::signalled(void) {
bool ret = false;
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
ret = _signalled;
r = pthread_mutex_unlock(&_mutex);
@@ -445,7 +427,7 @@ inline bool event_t::signalled(void) {
return ret;
}
inline void event_t::reset(void) {
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_signalled = false;
_pulsed = false;
@@ -467,21 +449,21 @@ inline semaphore_t::semaphore_t(
_initial_count(initial_count),
_max_count(max_count) {
- int r = pthread_mutex_init(&_mutex, NULL);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_init(&_mutex, NULL);
assert_debug(r == 0);
r = pthread_cond_init(&_cond, NULL);
assert_debug(r == 0);
_signalled = _initial_count;
}
inline semaphore_t::~semaphore_t(void) {
- int r = pthread_mutex_destroy(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_destroy(&_mutex);
assert_debug(r == 0);
r = pthread_cond_destroy(&_cond);
assert_debug(r == 0);
}
inline semaphore_t::E_WAIT semaphore_t::wait(void) {
E_WAIT ret;
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
while (_signalled == 0 && _interrupted == false) {
r = pthread_cond_wait(&_cond, &_mutex);
@@ -524,7 +506,7 @@ inline semaphore_t::E_WAIT semaphore_t::wait(ulonglong microseconds) {
}
inline bool semaphore_t::signal(void) {
bool ret = false;
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
if (_signalled < _max_count) {
_signalled++;
@@ -538,7 +520,7 @@ inline bool semaphore_t::signal(void) {
}
inline int semaphore_t::signalled(void) {
int ret = 0;
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
ret = _signalled;
r = pthread_mutex_unlock(&_mutex);
@@ -546,7 +528,7 @@ inline int semaphore_t::signalled(void) {
return ret;
}
inline void semaphore_t::reset(void) {
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_signalled = 0;
r = pthread_mutex_unlock(&_mutex);
@@ -554,7 +536,7 @@ inline void semaphore_t::reset(void) {
return;
}
inline void semaphore_t::set_interrupt(void) {
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_interrupted = true;
r = pthread_cond_broadcast(&_cond);
@@ -563,7 +545,7 @@ inline void semaphore_t::set_interrupt(void) {
assert_debug(r == 0);
}
inline void semaphore_t::clear_interrupt(void) {
- int r = pthread_mutex_lock(&_mutex);
+ int r MY_ATTRIBUTE((unused)) = pthread_mutex_lock(&_mutex);
assert_debug(r == 0);
_interrupted = false;
r = pthread_mutex_unlock(&_mutex);
diff --git a/storage/xtradb/api/api0api.cc b/storage/xtradb/api/api0api.cc
index 1abb0b2bdd1..55ed555ed48 100644
--- a/storage/xtradb/api/api0api.cc
+++ b/storage/xtradb/api/api0api.cc
@@ -398,7 +398,7 @@ ib_read_tuple(
data = btr_rec_copy_externally_stored_field(
copy, offsets, zip_size, i, &len,
- tuple->heap, NULL);
+ tuple->heap);
ut_a(len != UNIV_SQL_NULL);
}
diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc
index f22871deb32..e29d9091f8e 100644
--- a/storage/xtradb/btr/btr0cur.cc
+++ b/storage/xtradb/btr/btr0cur.cc
@@ -3991,7 +3991,6 @@ static const ib_int64_t rows_in_range_arbitrary_ret_val = 10;
@param[in] mode1 search mode for range start
@param[in] tuple2 range end, may also be empty tuple
@param[in] mode2 search mode for range end
-@param[in] trx trx
@param[in] nth_attempt if the tree gets modified too much while
we are trying to analyze it, then we will retry (this function will call
itself, incrementing this parameter)
@@ -4008,7 +4007,6 @@ btr_estimate_n_rows_in_range_low(
ulint mode1,
const dtuple_t* tuple2,
ulint mode2,
- trx_t* trx,
unsigned nth_attempt)
{
btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS];
@@ -4027,7 +4025,7 @@ btr_estimate_n_rows_in_range_low(
table_n_rows = dict_table_get_n_rows(index->table);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
cursor.path_arr = path1;
@@ -4049,7 +4047,7 @@ btr_estimate_n_rows_in_range_low(
return (0);
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
#ifdef UNIV_DEBUG
if (!strcmp(index->name, "iC")) {
@@ -4144,7 +4142,7 @@ 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,
+ tuple2, mode2,
nth_attempt + 1);
return(ret);
@@ -4205,7 +4203,6 @@ btr_estimate_n_rows_in_range_low(
@param[in] mode1 search mode for range start
@param[in] tuple2 range end, may also be empty tuple
@param[in] mode2 search mode for range end
-@param[in] trx trx
@return estimated number of rows */
ib_int64_t
btr_estimate_n_rows_in_range(
@@ -4213,11 +4210,10 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1,
ulint mode1,
const dtuple_t* tuple2,
- ulint mode2,
- trx_t* trx)
+ ulint mode2)
{
const ib_int64_t ret = btr_estimate_n_rows_in_range_low(
- index, tuple1, mode1, tuple2, mode2, trx,
+ index, tuple1, mode1, tuple2, mode2,
1 /* first attempt */);
return(ret);
@@ -5757,8 +5753,7 @@ btr_copy_blob_prefix(
ulint len, /*!< in: length of buf, in bytes */
ulint space_id,/*!< in: space id of the BLOB pages */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset, /*!< in: offset on the first BLOB page */
- trx_t* trx) /*!< in: transaction handle */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
ulint copied_len = 0;
@@ -5770,7 +5765,7 @@ btr_copy_blob_prefix(
ulint part_len;
ulint copy_len;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
block = buf_page_get(space_id, 0, page_no, RW_S_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
@@ -5973,8 +5968,7 @@ btr_copy_externally_stored_field_prefix_low(
zero for uncompressed BLOBs */
ulint space_id,/*!< in: space id of the first BLOB page */
ulint page_no,/*!< in: page number of the first BLOB page */
- ulint offset, /*!< in: offset on the first BLOB page */
- trx_t* trx) /*!< in: transaction handle */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
if (UNIV_UNLIKELY(len == 0)) {
return(0);
@@ -5985,7 +5979,7 @@ btr_copy_externally_stored_field_prefix_low(
space_id, page_no, offset));
} else {
return(btr_copy_blob_prefix(buf, len, space_id,
- page_no, offset, trx));
+ page_no, offset));
}
}
@@ -6006,8 +6000,7 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len,/*!< in: length of data, in bytes */
- trx_t* trx) /*!< in: transaction handle */
+ ulint local_len)/*!< in: length of data, in bytes */
{
ulint space_id;
ulint page_no;
@@ -6046,7 +6039,7 @@ btr_copy_externally_stored_field_prefix(
len - local_len,
zip_size,
space_id, page_no,
- offset, trx));
+ offset));
}
/*******************************************************************//**
@@ -6065,8 +6058,7 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx) /*!< in: transaction handle */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint space_id;
ulint page_no;
@@ -6097,8 +6089,7 @@ btr_copy_externally_stored_field(
extern_len,
zip_size,
space_id,
- page_no, offset,
- trx);
+ page_no, offset);
return(buf);
}
@@ -6117,8 +6108,7 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx) /*!< in: transaction handle */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint local_len;
const byte* data;
@@ -6149,7 +6139,6 @@ btr_rec_copy_externally_stored_field(
}
return(btr_copy_externally_stored_field(len, data,
- zip_size, local_len, heap,
- trx));
+ zip_size, local_len, heap));
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/btr/btr0pcur.cc b/storage/xtradb/btr/btr0pcur.cc
index 0b970e1cf49..06166e1aa16 100644
--- a/storage/xtradb/btr/btr0pcur.cc
+++ b/storage/xtradb/btr/btr0pcur.cc
@@ -33,6 +33,7 @@ Created 2/23/1996 Heikki Tuuri
#include "rem0cmp.h"
#include "trx0trx.h"
#include "srv0srv.h"
+
/**************************************************************//**
Allocates memory for a persistent cursor object and initializes the cursor.
@return own: persistent cursor */
@@ -511,7 +512,7 @@ btr_pcur_move_backward_from_page(
mtr_commit(mtr);
- mtr_start_trx(mtr, mtr->trx);
+ mtr_start(mtr);
btr_pcur_restore_position(latch_mode2, cursor, mtr);
diff --git a/storage/xtradb/buf/buf0buddy.cc b/storage/xtradb/buf/buf0buddy.cc
index 2ee39c6c992..1c50e71e687 100644
--- a/storage/xtradb/buf/buf0buddy.cc
+++ b/storage/xtradb/buf/buf0buddy.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -667,7 +668,7 @@ buf_buddy_free_low(
ut_ad(buf_pool->buddy_stat[i].used > 0);
buf_pool->buddy_stat[i].used--;
recombine:
- UNIV_MEM_ASSERT_AND_ALLOC(buf, BUF_BUDDY_LOW << i);
+ UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i);
if (i == BUF_BUDDY_SIZES) {
mutex_exit(&buf_pool->zip_free_mutex);
diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc
index c71d45009e4..7bf423ed740 100644
--- a/storage/xtradb/buf/buf0lru.cc
+++ b/storage/xtradb/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -87,6 +87,10 @@ buffer pools. */
frames in the buffer pool, we set this to TRUE */
static ibool buf_lru_switched_on_innodb_mon = FALSE;
+/** True if diagnostic message about difficult to find free blocks
+in the buffer bool has already printed. */
+static bool buf_lru_free_blocks_error_printed;
+
/******************************************************************//**
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics,
@@ -1080,68 +1084,39 @@ buf_LRU_check_size_of_non_data_objects(
}
/** Diagnose failure to get a free page and request InnoDB monitor output in
-the error log if more than two seconds have been spent already.
+the error log if it has not yet printed.
@param[in] n_iterations how many buf_LRU_get_free_page iterations
already completed
-@param[in] started_ms timestamp in ms of when the attempt to get the
- free page started
@param[in] flush_failures how many times single-page flush, if allowed,
has failed
-@param[out] mon_value_was previous srv_print_innodb_monitor value
-@param[out] started_monitor whether InnoDB monitor print has been requested
*/
static
void
-buf_LRU_handle_lack_of_free_blocks(ulint n_iterations, ulint started_ms,
- ulint flush_failures,
- ibool *mon_value_was,
- ibool *started_monitor)
+buf_LRU_handle_lack_of_free_blocks(
+ ulint n_iterations,
+ ulint flush_failures)
{
- static ulint last_printout_ms = 0;
-
- /* Legacy algorithm started warning after at least 2 seconds, we
- emulate this. */
- const ulint current_ms = ut_time_ms();
-
- if ((current_ms > started_ms + 2000)
- && (current_ms > last_printout_ms + 2000)) {
-
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: difficult to find free blocks in\n"
- "InnoDB: the buffer pool (%lu search iterations)!\n"
- "InnoDB: %lu failed attempts to flush a page!"
- " Consider\n"
- "InnoDB: increasing the buffer pool size.\n"
- "InnoDB: It is also possible that"
- " in your Unix version\n"
- "InnoDB: fsync is very slow, or"
- " completely frozen inside\n"
- "InnoDB: the OS kernel. Then upgrading to"
- " a newer version\n"
- "InnoDB: of your operating system may help."
- " Look at the\n"
- "InnoDB: number of fsyncs in diagnostic info below.\n"
- "InnoDB: Pending flushes (fsync) log: %lu;"
- " buffer pool: %lu\n"
- "InnoDB: %lu OS file reads, %lu OS file writes,"
- " %lu OS fsyncs\n"
- "InnoDB: Starting InnoDB Monitor to print further\n"
- "InnoDB: diagnostics to the standard output.\n",
- (ulong) n_iterations,
- (ulong) flush_failures,
- (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);
-
- last_printout_ms = current_ms;
- *mon_value_was = srv_print_innodb_monitor;
- *started_monitor = TRUE;
- srv_print_innodb_monitor = TRUE;
- os_event_set(lock_sys->timeout_event);
+ if (n_iterations > 20 && !buf_lru_free_blocks_error_printed) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Difficult to find free blocks in"
+ " the buffer pool (" ULINTPF " search iterations)! "
+ ULINTPF " failed attempts to flush a page!",
+ n_iterations, flush_failures);
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Consider increasing the buffer pool size.");
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Pending flushes (fsync) log: " ULINTPF
+ " buffer pool: " ULINTPF
+ " OS file reads: " ULINTPF " OS file writes: "
+ ULINTPF " OS fsyncs: " ULINTPF "",
+ fil_n_pending_log_flushes,
+ fil_n_pending_tablespace_flushes,
+ os_n_file_reads,
+ os_n_file_writes,
+ os_n_fsyncs);
+
+ buf_lru_free_blocks_error_printed = true;
}
-
}
/** The maximum allowed backoff sleep time duration, microseconds */
@@ -1189,9 +1164,6 @@ buf_LRU_get_free_block(
ibool freed = FALSE;
ulint n_iterations = 0;
ulint flush_failures = 0;
- ibool mon_value_was = FALSE;
- ibool started_monitor = FALSE;
- ulint started_ms = 0;
ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
@@ -1199,42 +1171,20 @@ buf_LRU_get_free_block(
loop:
buf_LRU_check_size_of_non_data_objects(buf_pool);
- /* If there is a block in the free list, take it */
- if (DBUG_EVALUATE_IF("simulate_lack_of_pages", true, false)) {
-
- block = NULL;
-
- if (srv_debug_monitor_printed)
- DBUG_SET("-d,simulate_lack_of_pages");
-
- } else if (DBUG_EVALUATE_IF("simulate_recovery_lack_of_pages",
- recv_recovery_on, false)) {
-
- block = NULL;
-
- if (srv_debug_monitor_printed)
- DBUG_SUICIDE();
- } else {
+ DBUG_EXECUTE_IF("ib_lru_force_no_free_page",
+ if (!buf_lru_free_blocks_error_printed) {
+ n_iterations = 21;
+ goto not_found;});
- block = buf_LRU_get_free_only(buf_pool);
- }
+ block = buf_LRU_get_free_only(buf_pool);
if (block) {
ut_ad(buf_pool_from_block(block) == buf_pool);
memset(&block->page.zip, 0, sizeof block->page.zip);
-
- if (started_monitor) {
- srv_print_innodb_monitor =
- static_cast<my_bool>(mon_value_was);
- }
-
return(block);
}
- if (!started_ms)
- started_ms = ut_time_ms();
-
if (srv_empty_free_list_algorithm == SRV_EMPTY_FREE_LIST_BACKOFF
&& buf_lru_manager_is_active
&& (srv_shutdown_state == SRV_SHUTDOWN_NONE
@@ -1272,10 +1222,7 @@ loop:
: FREE_LIST_BACKOFF_LOW_PRIO_DIVIDER));
}
- buf_LRU_handle_lack_of_free_blocks(n_iterations, started_ms,
- flush_failures,
- &mon_value_was,
- &started_monitor);
+ buf_LRU_handle_lack_of_free_blocks(n_iterations, flush_failures);
n_iterations++;
@@ -1314,13 +1261,8 @@ loop:
mutex_exit(&buf_pool->flush_state_mutex);
- if (DBUG_EVALUATE_IF("simulate_recovery_lack_of_pages", true, false)
- || DBUG_EVALUATE_IF("simulate_lack_of_pages", true, false)) {
-
- buf_pool->try_LRU_scan = false;
- }
-
freed = FALSE;
+
if (buf_pool->try_LRU_scan || n_iterations > 0) {
/* If no block was in the free list, search from the
@@ -1345,9 +1287,11 @@ loop:
}
- buf_LRU_handle_lack_of_free_blocks(n_iterations, started_ms,
- flush_failures, &mon_value_was,
- &started_monitor);
+#ifndef DBUG_OFF
+not_found:
+#endif
+
+ buf_LRU_handle_lack_of_free_blocks(n_iterations, flush_failures);
/* If we have scanned the whole LRU and still are unable to
find a free block then we should sleep here to let the
@@ -2126,7 +2070,7 @@ buf_LRU_block_free_non_file_page(
ut_d(block->page.in_free_list = TRUE);
mutex_exit(&buf_pool->free_list_mutex);
- UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
+ UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE);
}
/******************************************************************//**
diff --git a/storage/xtradb/buf/buf0rea.cc b/storage/xtradb/buf/buf0rea.cc
index 76b71550710..43e678ed7d4 100644
--- a/storage/xtradb/buf/buf0rea.cc
+++ b/storage/xtradb/buf/buf0rea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -124,7 +124,12 @@ not exist or is being dropped
use to stop dangling page reads from a tablespace
which we have DISCARDed + IMPORTed back
@param[in] offset page number
-@param[in] trx transaction
+@param[in,out] trx transaction
+@param[in] should_buffer whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests
@return 1 if read request is issued. 0 if it is not */
static
ulint
@@ -137,7 +142,8 @@ buf_read_page_low(
ibool unzip,
ib_int64_t tablespace_version,
ulint offset,
- trx_t* trx = NULL)
+ trx_t* trx = NULL,
+ bool should_buffer = false)
{
buf_page_t* bpage;
ulint wake_later;
@@ -240,17 +246,18 @@ not_to_recover:
}
if (zip_size) {
- *err = _fil_io(OS_FILE_READ | wake_later
- | ignore_nonexistent_pages,
- sync, space, zip_size, offset, 0, zip_size,
- frame, bpage, 0, trx);
+ *err = fil_io(OS_FILE_READ | wake_later
+ | ignore_nonexistent_pages,
+ sync, space, zip_size, offset, 0, zip_size,
+ frame, bpage, 0, trx, should_buffer);
} else {
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
- *err = _fil_io(OS_FILE_READ | wake_later
+ *err = fil_io(OS_FILE_READ | wake_later
| ignore_nonexistent_pages,
sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
- frame, bpage, &bpage->write_size, trx);
+ frame, bpage, &bpage->write_size,
+ trx, should_buffer);
}
if (sync) {
@@ -848,7 +855,7 @@ buf_read_ahead_linear(
&err, false,
ibuf_mode,
space, zip_size, FALSE, tablespace_version,
- i, trx);
+ i, trx, true);
switch(err) {
case DB_SUCCESS:
@@ -876,6 +883,7 @@ buf_read_ahead_linear(
}
}
}
+ os_aio_dispatch_read_array_submit();
/* In simulated aio we wake the aio handler threads only after
queuing all aio requests, in native aio the following call does
@@ -952,7 +960,7 @@ buf_read_ibuf_merge_pages(
buf_read_page_low(&err, sync && (i + 1 == n_stored),
BUF_READ_ANY_PAGE, space_ids[i],
zip_size, TRUE, space_versions[i],
- page_nos[i], NULL);
+ page_nos[i]);
switch(err) {
case DB_SUCCESS:
@@ -1100,13 +1108,12 @@ not_to_recover:
if ((i + 1 == n_stored) && sync) {
buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space,
zip_size, TRUE, tablespace_version,
- page_nos[i], NULL);
+ page_nos[i]);
} else {
buf_read_page_low(&err, false, BUF_READ_ANY_PAGE
| OS_AIO_SIMULATED_WAKE_LATER,
space, zip_size, TRUE,
- tablespace_version, page_nos[i],
- NULL);
+ tablespace_version, page_nos[i]);
}
if (err == DB_DECRYPTION_FAILED) {
diff --git a/storage/xtradb/data/data0type.cc b/storage/xtradb/data/data0type.cc
index 0b9e08544a5..34ca399f9b2 100644
--- a/storage/xtradb/data/data0type.cc
+++ b/storage/xtradb/data/data0type.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -49,8 +50,10 @@ ulint
dtype_get_at_most_n_mbchars(
/*========================*/
ulint prtype, /*!< in: precise type */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of
+ a multi-byte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of
+ a multi-byte character, in bytes */
ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
@@ -58,9 +61,6 @@ dtype_get_at_most_n_mbchars(
const char* str) /*!< in: the string whose prefix
length is being determined */
{
- ulint mbminlen = DATA_MBMINLEN(mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen);
-
ut_a(data_len != UNIV_SQL_NULL);
ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen));
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index 5af3a635a96..9257321c7ef 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -3409,6 +3409,7 @@ dict_foreign_find_index(
if (types_idx != index
&& !(index->type & DICT_FTS)
&& !index->to_be_dropped
+ && !dict_index_is_online_ddl(index)
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
index, types_idx,
diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc
index 125d7d78a1f..cf27caf6c28 100644
--- a/storage/xtradb/dict/dict0mem.cc
+++ b/storage/xtradb/dict/dict0mem.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -533,7 +533,8 @@ dict_mem_fill_column_struct(
column->len = (unsigned int) col_len;
#ifndef UNIV_HOTBACKUP
dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
- dict_col_set_mbminmaxlen(column, mbminlen, mbmaxlen);
+ column->mbminlen = mbminlen;
+ column->mbmaxlen = mbmaxlen;
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/xtradb/dict/dict0stats_bg.cc b/storage/xtradb/dict/dict0stats_bg.cc
index e166e7df72a..884f62103f5 100644
--- a/storage/xtradb/dict/dict0stats_bg.cc
+++ b/storage/xtradb/dict/dict0stats_bg.cc
@@ -337,7 +337,7 @@ dict_stats_wait_bg_to_stop_using_table(
unlocking/locking the data dict */
{
while (!dict_stats_stop_bg(table)) {
- DICT_STATS_BG_YIELD(trx);
+ DICT_BG_YIELD(trx);
}
}
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 9023b4446b5..96902cd77ec 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2014, 2018, 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
@@ -2125,7 +2125,7 @@ fil_write_flushed_lsn(
{
byte* buf1;
byte* buf;
- dberr_t err;
+ dberr_t err = DB_TABLESPACE_NOT_FOUND;
buf1 = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
buf = static_cast<byte*>(ut_align(buf1, UNIV_PAGE_SIZE));
@@ -4967,6 +4967,11 @@ will_not_choose:
return;
}
+ /* In mariabackup lets not crash. */
+ if (IS_XTRABACKUP()) {
+ return;
+ }
+
abort();
}
@@ -6056,7 +6061,7 @@ Reads or writes data. This operation is asynchronous (aio).
i/o on a tablespace which does not exist */
UNIV_INTERN
dberr_t
-_fil_io(
+fil_io(
/*===*/
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
@@ -6088,7 +6093,12 @@ _fil_io(
operation for this page and if
initialized we do not trim again if
actual page size does not decrease. */
- trx_t* trx)
+ trx_t* trx,
+ bool should_buffer) /*!< in: whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
{
ulint mode;
fil_space_t* space;
@@ -6308,8 +6318,8 @@ _fil_io(
/* Queue the aio request */
ret = os_aio(type, is_log, mode | wake_later, name, node->handle, buf,
- offset, len, zip_size ? zip_size : UNIV_PAGE_SIZE, node,
- message, space_id, trx, write_size);
+ offset, len, zip_size ? zip_size : UNIV_PAGE_SIZE, node,
+ message, space_id, trx, write_size, should_buffer);
#else
/* In mysqlbackup do normal i/o, not aio */
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 88b5ad97277..98aaf610f2a 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -26,6 +26,7 @@ Full Text Search interface
#include "row0mysql.h"
#include "row0upd.h"
#include "dict0types.h"
+#include "dict0stats_bg.h"
#include "row0sel.h"
#include "fts0fts.h"
@@ -868,18 +869,37 @@ fts_drop_index(
err = fts_drop_index_tables(trx, index);
- fts_free(table);
-
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry){
+ fts_free(table);
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
return(err);
}
- current_doc_id = table->fts->cache->next_doc_id;
- first_doc_id = table->fts->cache->first_doc_id;
- fts_cache_clear(table->fts->cache);
- fts_cache_destroy(table->fts->cache);
- table->fts->cache = fts_cache_create(table);
- table->fts->cache->next_doc_id = current_doc_id;
- table->fts->cache->first_doc_id = first_doc_id;
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry){
+ current_doc_id = table->fts->cache->next_doc_id;
+ first_doc_id = table->fts->cache->first_doc_id;
+ fts_cache_clear(table->fts->cache);
+ fts_cache_destroy(table->fts->cache);
+ table->fts->cache = fts_cache_create(table);
+ table->fts->cache->next_doc_id = current_doc_id;
+ table->fts->cache->first_doc_id = first_doc_id;
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
} else {
fts_cache_t* cache = table->fts->cache;
fts_index_cache_t* index_cache;
@@ -889,9 +909,17 @@ fts_drop_index(
index_cache = fts_find_index_cache(cache, index);
if (index_cache != NULL) {
- if (index_cache->words) {
- fts_words_free(index_cache->words);
- rbt_free(index_cache->words);
+ for(;;) {
+ bool retry = false;
+ if (index->index_fts_syncing) {
+ retry = true;
+ }
+ if (!retry && index_cache->words) {
+ fts_words_free(index_cache->words);
+ rbt_free(index_cache->words);
+ break;
+ }
+ DICT_BG_YIELD(trx);
}
ib_vector_remove(cache->indexes, *(void**) index_cache);
@@ -1973,7 +2001,7 @@ fts_create_one_index_table(
? DATA_VARCHAR : DATA_VARMYSQL,
field->col->prtype,
FTS_MAX_WORD_LEN_IN_CHAR
- * DATA_MBMAXLEN(field->col->mbminmaxlen));
+ * field->col->mbmaxlen);
dict_mem_table_add_col(new_table, heap, "first_doc_id", DATA_INT,
DATA_NOT_NULL | DATA_UNSIGNED,
@@ -3333,8 +3361,7 @@ fts_fetch_doc_from_rec(
dict_table_zip_size(table),
clust_pos, &doc->text.f_len,
static_cast<mem_heap_t*>(
- doc->self_heap->arg),
- NULL);
+ doc->self_heap->arg));
} else {
doc->text.f_str = (byte*) rec_get_nth_field(
clust_rec, offsets, clust_pos,
@@ -4568,10 +4595,16 @@ begin_sync:
index_cache = static_cast<fts_index_cache_t*>(
ib_vector_get(cache->indexes, i));
- if (index_cache->index->to_be_dropped) {
+ if (index_cache->index->to_be_dropped
+ || index_cache->index->table->to_be_dropped) {
continue;
}
+ index_cache->index->index_fts_syncing = true;
+ DBUG_EXECUTE_IF("fts_instrument_sync_sleep_drop_waits",
+ os_thread_sleep(10000000);
+ );
+
error = fts_sync_index(sync, index_cache);
if (error != DB_SUCCESS && !sync->interrupted) {
@@ -4604,11 +4637,33 @@ begin_sync:
end_sync:
if (error == DB_SUCCESS && !sync->interrupted) {
error = fts_sync_commit(sync);
+ if (error == DB_SUCCESS) {
+ for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
+ fts_index_cache_t* index_cache;
+ index_cache = static_cast<fts_index_cache_t*>(
+ ib_vector_get(cache->indexes, i));
+ if (index_cache->index->index_fts_syncing) {
+ index_cache->index->index_fts_syncing
+ = false;
+ }
+ }
+ }
} else {
fts_sync_rollback(sync);
}
rw_lock_x_lock(&cache->lock);
+ /* Clear fts syncing flags of any indexes incase sync is
+ interrupeted */
+ for (i = 0; i < ib_vector_size(cache->indexes); ++i) {
+ fts_index_cache_t* index_cache;
+ index_cache = static_cast<fts_index_cache_t*>(
+ ib_vector_get(cache->indexes, i));
+ if (index_cache->index->index_fts_syncing == true) {
+ index_cache->index->index_fts_syncing = false;
+ }
+ }
+
sync->interrupted = false;
sync->in_progress = false;
os_event_set(sync->event);
@@ -7535,8 +7590,7 @@ fts_init_recover_doc(
&doc.text.f_len,
static_cast<byte*>(dfield_get_data(dfield)),
zip_size, len,
- static_cast<mem_heap_t*>(doc.self_heap->arg),
- NULL);
+ static_cast<mem_heap_t*>(doc.self_heap->arg));
} else {
doc.text.f_str = static_cast<byte*>(
dfield_get_data(dfield));
diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc
index cb30122adcb..d9f96948000 100644
--- a/storage/xtradb/fts/fts0opt.cc
+++ b/storage/xtradb/fts/fts0opt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, MariaDB Corporation. All Rights reserved.
This program is free software; you can redistribute it and/or modify it under
@@ -2971,13 +2971,6 @@ fts_optimize_sync_table(
{
dict_table_t* table = NULL;
- /* Prevent DROP INDEX etc. from running when we are syncing
- cache in background. */
- if (!rw_lock_s_lock_nowait(&dict_operation_lock, __FILE__, __LINE__)) {
- /* Exit when fail to get dict operation lock. */
- return;
- }
-
table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (table) {
@@ -2987,8 +2980,6 @@ fts_optimize_sync_table(
dict_table_close(table, FALSE, FALSE);
}
-
- rw_lock_s_unlock(&dict_operation_lock);
}
/**********************************************************************//**
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index 358d979fff6..0b0aecaeaa2 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2007, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -1937,8 +1937,7 @@ fts_query_fetch_document(
if (dfield_is_ext(dfield)) {
data = btr_copy_externally_stored_field(
&cur_len, data, phrase->zip_size,
- dfield_get_len(dfield), phrase->heap,
- NULL);
+ dfield_get_len(dfield), phrase->heap);
} else {
cur_len = dfield_get_len(dfield);
}
@@ -3656,6 +3655,7 @@ fts_query_free(
if (query->intersection) {
fts_query_free_doc_ids(query, query->intersection);
+ query->intersection = NULL;
}
if (query->doc_ids) {
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 37755cb9078..65ac41c26de 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1289,6 +1289,8 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_sec_rec_cluster_reads, SHOW_LONG},
{"secondary_index_triggered_cluster_reads_avoided",
(char*) &export_vars.innodb_sec_rec_cluster_reads_avoided, SHOW_LONG},
+ {"buffered_aio_submitted",
+ (char*) &export_vars.innodb_buffered_aio_submitted, SHOW_LONG},
/* Encryption */
{"encryption_rotation_pages_read_from_cache",
@@ -12321,6 +12323,7 @@ index_bad:
case ROW_TYPE_DEFAULT:
/* If we fell through, set row format to Compact. */
row_format = ROW_TYPE_COMPACT;
+ /* fall through */
case ROW_TYPE_COMPACT:
break;
}
@@ -13710,7 +13713,7 @@ ha_innobase::records_in_range(
n_rows = btr_estimate_n_rows_in_range(index, range_start,
mode1, range_end,
- mode2, prebuilt->trx);
+ mode2);
} else {
n_rows = HA_POS_ERROR;
@@ -21081,6 +21084,13 @@ static MYSQL_SYSVAR_BOOL(print_all_deadlocks, srv_print_all_deadlocks,
"Print all deadlocks to MySQL error log (off by default)",
NULL, NULL, FALSE);
+static MYSQL_SYSVAR_BOOL(
+ print_lock_wait_timeout_info,
+ srv_print_lock_wait_timeout_info,
+ PLUGIN_VAR_OPCMDARG,
+ "Print lock wait timeout info to MySQL error log (off by default)",
+ NULL, NULL, FALSE);
+
static MYSQL_SYSVAR_ULONG(compression_failure_threshold_pct,
zip_failure_threshold_pct, PLUGIN_VAR_OPCMDARG,
"If the compression failure rate of a table is greater than this number"
@@ -21539,6 +21549,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(foreground_preflush),
MYSQL_SYSVAR(empty_free_list_algorithm),
MYSQL_SYSVAR(print_all_deadlocks),
+ MYSQL_SYSVAR(print_lock_wait_timeout_info),
MYSQL_SYSVAR(cmp_per_index_enabled),
MYSQL_SYSVAR(undo_logs),
MYSQL_SYSVAR(rollback_segments),
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index b2f0d301815..2a2c466fd4f 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2013, 2018, MariaDB Corporation. 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
@@ -1200,8 +1200,7 @@ innobase_col_to_mysql(
#ifdef UNIV_DEBUG
case DATA_MYSQL:
ut_ad(flen >= len);
- ut_ad(DATA_MBMAXLEN(col->mbminmaxlen)
- >= DATA_MBMINLEN(col->mbminmaxlen));
+ ut_ad(col->mbmaxlen >= col->mbminlen);
memcpy(dest, data, len);
break;
@@ -5917,7 +5916,47 @@ ha_innobase::commit_inplace_alter_table(
break;
}
- DICT_STATS_BG_YIELD(trx);
+ DICT_BG_YIELD(trx);
+ }
+
+ /* Make a concurrent Drop fts Index to wait until sync of that
+ fts index is happening in the background */
+ for (;;) {
+ bool retry = false;
+
+ for (inplace_alter_handler_ctx** pctx = ctx_array;
+ *pctx; pctx++) {
+ int count =0;
+ ha_innobase_inplace_ctx* ctx
+ = static_cast<ha_innobase_inplace_ctx*>(*pctx);
+ DBUG_ASSERT(new_clustered == ctx->need_rebuild());
+
+ if (dict_fts_index_syncing(ctx->old_table)) {
+ count++;
+ if (count == 100) {
+ fprintf(stderr,
+ "Drop index waiting for background sync"
+ "to finish\n");
+ }
+ retry = true;
+ }
+
+ if (new_clustered && dict_fts_index_syncing(ctx->new_table)) {
+ count++;
+ if (count == 100) {
+ fprintf(stderr,
+ "Drop index waiting for background sync"
+ "to finish\n");
+ }
+ retry = true;
+ }
+ }
+
+ if (!retry) {
+ break;
+ }
+
+ DICT_BG_YIELD(trx);
}
/* Apply the changes to the data dictionary tables, for all
@@ -6233,8 +6272,13 @@ foreign_fail:
ut_d(dict_table_check_for_dup_indexes(
ctx->new_table, CHECK_ABORTED_OK));
- ut_a(fts_check_cached_index(ctx->new_table));
+#ifdef UNIV_DEBUG
+ if (!(ctx->new_table->fts != NULL
+ && ctx->new_table->fts->cache->sync->in_progress)) {
+ ut_a(fts_check_cached_index(ctx->new_table));
+ }
+#endif
if (new_clustered) {
/* Since the table has been rebuilt, we remove
all persistent statistics corresponding to the
diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc
index 6925cd3abb5..b169916c34e 100644
--- a/storage/xtradb/ibuf/ibuf0ibuf.cc
+++ b/storage/xtradb/ibuf/ibuf0ibuf.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -4645,7 +4645,7 @@ ibuf_merge_or_delete_for_page(
function. When the counter is > 0, that prevents tablespace
from being dropped. */
- space = fil_space_acquire(space_id);
+ space = fil_space_acquire_silent(space_id);
if (UNIV_UNLIKELY(!space)) {
/* Do not try to read the bitmap page from space;
diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h
index e478b33bf8e..1b0632e2120 100644
--- a/storage/xtradb/include/btr0cur.h
+++ b/storage/xtradb/include/btr0cur.h
@@ -568,8 +568,7 @@ btr_estimate_n_rows_in_range(
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
ulint mode1, /*!< in: search mode for range start */
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
- ulint mode2, /*!< in: search mode for range end */
- trx_t* trx); /*!< in: trx */
+ ulint mode2); /*!< in: search mode for range end */
/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where 1 <= n <= dict_index_get_n_unique(index).
@@ -704,8 +703,7 @@ btr_copy_externally_stored_field_prefix(
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len,/*!< in: length of data, in bytes */
- trx_t* trx); /*!< in: transaction handle */
+ ulint local_len);/*!< in: length of data, in bytes */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap. The
clustered index record must be protected by a lock or a page latch.
@@ -722,8 +720,7 @@ btr_copy_externally_stored_field(
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint local_len,/*!< in: length of data */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx); /*!< in: transaction handle */
+ mem_heap_t* heap); /*!< in: mem heap */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap.
@return the field copied to heap, or NULL if the field is incomplete */
@@ -738,8 +735,7 @@ btr_rec_copy_externally_stored_field(
zero for uncompressed BLOBs */
ulint no, /*!< in: field number */
ulint* len, /*!< out: length of the field */
- mem_heap_t* heap, /*!< in: mem heap */
- trx_t* trx); /*!< in: transaction handle */
+ mem_heap_t* heap); /*!< in: mem heap */
/*******************************************************************//**
Flags the data tuple fields that are marked as extern storage in the
update vector. We use this function to remember which fields we must
diff --git a/storage/xtradb/include/data0type.h b/storage/xtradb/include/data0type.h
index df6b6a41c11..f3ecab5a3ba 100644
--- a/storage/xtradb/include/data0type.h
+++ b/storage/xtradb/include/data0type.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -182,18 +182,7 @@ store the charset-collation number; one byte is left unused, though */
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
/* Maximum multi-byte character length in bytes, plus 1 */
-#define DATA_MBMAX 5
-
-/* Pack mbminlen, mbmaxlen to mbminmaxlen. */
-#define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \
- ((mbmaxlen) * DATA_MBMAX + (mbminlen))
-/* Get mbminlen from mbminmaxlen. Cast the result of UNIV_EXPECT to ulint
-because in GCC it returns a long. */
-#define DATA_MBMINLEN(mbminmaxlen) ((ulint) \
- UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \
- 1))
-/* Get mbmaxlen from mbminmaxlen. */
-#define DATA_MBMAXLEN(mbminmaxlen) ((ulint) ((mbminmaxlen) / DATA_MBMAX))
+#define DATA_MBMAX 8
/* We now support 15 bits (up to 32767) collation number */
#define MAX_CHAR_COLL_NUM 32767
@@ -220,8 +209,10 @@ ulint
dtype_get_at_most_n_mbchars(
/*========================*/
ulint prtype, /*!< in: precise type */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of
+ a multi-byte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of
+ a multi-byte character, in bytes */
ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
@@ -366,19 +357,6 @@ dtype_get_mbmaxlen(
/*===============*/
const dtype_t* type); /*!< in: type */
/*********************************************************************//**
-Sets the minimum and maximum length of a character, in bytes. */
-UNIV_INLINE
-void
-dtype_set_mbminmaxlen(
-/*==================*/
- dtype_t* type, /*!< in/out: type */
- ulint mbminlen, /*!< in: minimum length of a char,
- in bytes, or 0 if this is not
- a character type */
- ulint mbmaxlen); /*!< in: maximum length of a char,
- in bytes, or 0 if this is not
- a character type */
-/*********************************************************************//**
Gets the padding character code for the type.
@return padding character code, or ULINT_UNDEFINED if no padding specified */
UNIV_INLINE
@@ -398,7 +376,9 @@ dtype_get_fixed_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of a
+ ulint mbminlen, /*!< in: minimum length of a
+ multibyte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of a
multibyte character, in bytes */
ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
#ifndef UNIV_HOTBACKUP
@@ -412,8 +392,8 @@ dtype_get_min_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen); /*!< in: minimum and maximum length of a
- multibyte character */
+ ulint mbminlen, /*!< in: minimum length of a character */
+ ulint mbmaxlen); /*!< in: maximum length of a character */
/***********************************************************************//**
Returns the maximum size of a data type. Note: types in system tables may be
incomplete and return incorrect information.
@@ -530,11 +510,10 @@ struct dtype_t{
the string, MySQL uses 1 or 2
bytes to store the string length) */
#ifndef UNIV_HOTBACKUP
- unsigned mbminmaxlen:5; /*!< minimum and maximum length of a
- character, in bytes;
- DATA_MBMINMAXLEN(mbminlen,mbmaxlen);
- mbminlen=DATA_MBMINLEN(mbminmaxlen);
- mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */
+ unsigned mbminlen:3; /*!< minimum length of a character,
+ in bytes */
+ unsigned mbmaxlen:3; /*!< maximum length of a character,
+ in bytes */
#endif /* !UNIV_HOTBACKUP */
};
diff --git a/storage/xtradb/include/data0type.ic b/storage/xtradb/include/data0type.ic
index ff72f6ed20f..96b001e197e 100644
--- a/storage/xtradb/include/data0type.ic
+++ b/storage/xtradb/include/data0type.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -105,27 +105,6 @@ dtype_get_mblen(
}
/*********************************************************************//**
-Sets the minimum and maximum length of a character, in bytes. */
-UNIV_INLINE
-void
-dtype_set_mbminmaxlen(
-/*==================*/
- dtype_t* type, /*!< in/out: type */
- ulint mbminlen, /*!< in: minimum length of a char,
- in bytes, or 0 if this is not
- a character type */
- ulint mbmaxlen) /*!< in: maximum length of a char,
- in bytes, or 0 if this is not
- a character type */
-{
- ut_ad(mbminlen < DATA_MBMAX);
- ut_ad(mbmaxlen < DATA_MBMAX);
- ut_ad(mbminlen <= mbmaxlen);
-
- type->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen);
-}
-
-/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
@@ -137,7 +116,8 @@ dtype_set_mblen(
ulint mbmaxlen;
dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen);
- dtype_set_mbminmaxlen(type, mbminlen, mbmaxlen);
+ type->mbminlen = mbminlen;
+ type->mbmaxlen = mbmaxlen;
ut_ad(dtype_validate(type));
}
@@ -233,8 +213,7 @@ dtype_get_mbminlen(
/*===============*/
const dtype_t* type) /*!< in: type */
{
- ut_ad(type);
- return(DATA_MBMINLEN(type->mbminmaxlen));
+ return type->mbminlen;
}
/*********************************************************************//**
Gets the maximum length of a character, in bytes.
@@ -246,8 +225,7 @@ dtype_get_mbmaxlen(
/*===============*/
const dtype_t* type) /*!< in: type */
{
- ut_ad(type);
- return(DATA_MBMAXLEN(type->mbminmaxlen));
+ return type->mbmaxlen;
}
/*********************************************************************//**
@@ -523,8 +501,10 @@ dtype_get_fixed_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multibyte character, in bytes */
+ ulint mbminlen, /*!< in: minimum length of a
+ multibyte character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of a
+ multibyte character, in bytes */
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
switch (mtype) {
@@ -565,11 +545,10 @@ dtype_get_fixed_size_low(
dtype_get_charset_coll(prtype),
&i_mbminlen, &i_mbmaxlen);
- ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen)
- == mbminmaxlen);
+ ut_ad(i_mbminlen == mbminlen);
+ ut_ad(i_mbmaxlen == mbmaxlen);
#endif /* UNIV_DEBUG */
- if (DATA_MBMINLEN(mbminmaxlen)
- == DATA_MBMAXLEN(mbminmaxlen)) {
+ if (mbminlen == mbmaxlen) {
return(len);
}
}
@@ -602,8 +581,8 @@ dtype_get_min_size_low(
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
ulint len, /*!< in: length */
- ulint mbminmaxlen) /*!< in: minimum and maximum length of a
- multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of a character */
+ ulint mbmaxlen) /*!< in: maximum length of a character */
{
switch (mtype) {
case DATA_SYS:
@@ -633,9 +612,6 @@ dtype_get_min_size_low(
if (prtype & DATA_BINARY_TYPE) {
return(len);
} else {
- ulint mbminlen = DATA_MBMINLEN(mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen);
-
if (mbminlen == mbmaxlen) {
return(len);
}
@@ -706,9 +682,9 @@ dtype_get_sql_null_size(
{
#ifndef UNIV_HOTBACKUP
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- type->mbminmaxlen, comp));
+ type->mbminlen, type->mbmaxlen, comp));
#else /* !UNIV_HOTBACKUP */
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- 0, 0));
+ 0, 0, 0));
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index dda8f4d2714..241ed89e36b 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -197,18 +197,6 @@ dict_col_get_mbmaxlen(
const dict_col_t* col) /*!< in: column */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/*********************************************************************//**
-Sets the minimum and maximum number of bytes per character. */
-UNIV_INLINE
-void
-dict_col_set_mbminmaxlen(
-/*=====================*/
- dict_col_t* col, /*!< in/out: column */
- ulint mbminlen, /*!< in: minimum multi-byte
- character size, in bytes */
- ulint mbmaxlen) /*!< in: minimum multi-byte
- character size, in bytes */
- MY_ATTRIBUTE((nonnull));
-/*********************************************************************//**
Gets the column data type. */
UNIV_INLINE
void
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 4db6a73bbc2..17b4adc10e2 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2013, 2018, 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
@@ -41,7 +41,7 @@ dict_col_get_mbminlen(
/*==================*/
const dict_col_t* col) /*!< in: column */
{
- return(DATA_MBMINLEN(col->mbminmaxlen));
+ return col->mbminlen;
}
/*********************************************************************//**
Gets the maximum number of bytes per character.
@@ -52,25 +52,7 @@ dict_col_get_mbmaxlen(
/*==================*/
const dict_col_t* col) /*!< in: column */
{
- return(DATA_MBMAXLEN(col->mbminmaxlen));
-}
-/*********************************************************************//**
-Sets the minimum and maximum number of bytes per character. */
-UNIV_INLINE
-void
-dict_col_set_mbminmaxlen(
-/*=====================*/
- dict_col_t* col, /*!< in/out: column */
- ulint mbminlen, /*!< in: minimum multi-byte
- character size, in bytes */
- ulint mbmaxlen) /*!< in: minimum multi-byte
- character size, in bytes */
-{
- ut_ad(mbminlen < DATA_MBMAX);
- ut_ad(mbmaxlen < DATA_MBMAX);
- ut_ad(mbminlen <= mbmaxlen);
-
- col->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen);
+ return col->mbmaxlen;
}
/*********************************************************************//**
Gets the column data type. */
@@ -87,7 +69,8 @@ dict_col_copy_type(
type->mtype = col->mtype;
type->prtype = col->prtype;
type->len = col->len;
- type->mbminmaxlen = col->mbminmaxlen;
+ type->mbminlen = col->mbminlen;
+ type->mbmaxlen = col->mbmaxlen;
}
#endif /* !UNIV_HOTBACKUP */
@@ -109,7 +92,8 @@ dict_col_type_assert_equal(
ut_ad(col->prtype == type->prtype);
//ut_ad(col->len == type->len);
# ifndef UNIV_HOTBACKUP
- ut_ad(col->mbminmaxlen == type->mbminmaxlen);
+ ut_ad(col->mbminlen == type->mbminlen);
+ ut_ad(col->mbmaxlen == type->mbmaxlen);
# endif /* !UNIV_HOTBACKUP */
return(TRUE);
@@ -127,7 +111,7 @@ dict_col_get_min_size(
const dict_col_t* col) /*!< in: column */
{
return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
- col->mbminmaxlen));
+ col->mbminlen, col->mbmaxlen));
}
/***********************************************************************//**
Returns the maximum size of the column.
@@ -152,7 +136,7 @@ dict_col_get_fixed_size(
ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
- col->mbminmaxlen, comp));
+ col->mbminlen, col->mbmaxlen, comp));
}
/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
@@ -1077,6 +1061,27 @@ dict_table_x_lock_indexes(
}
/*********************************************************************//**
+Returns true if the particular FTS index in the table is still syncing
+in the background, false otherwise.
+@param [in] table Table containing FTS index
+@return True if sync of fts index is still going in the background */
+UNIV_INLINE
+bool
+dict_fts_index_syncing(
+ dict_table_t* table)
+{
+ dict_index_t* index;
+
+ for (index = dict_table_get_first_index(table);
+ index != NULL;
+ index = dict_table_get_next_index(index)) {
+ if (index->index_fts_syncing) {
+ return(true);
+ }
+ }
+ return(false);
+}
+/*********************************************************************//**
Release the exclusive locks on all index tree. */
UNIV_INLINE
void
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index 2a4422fc18b..bdec503c88c 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -1,8 +1,8 @@
/*****************************************************************************
-Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -538,11 +538,10 @@ struct dict_col_t{
the string, MySQL uses 1 or 2
bytes to store the string length) */
- unsigned mbminmaxlen:5; /*!< minimum and maximum length of a
- character, in bytes;
- DATA_MBMINMAXLEN(mbminlen,mbmaxlen);
- mbminlen=DATA_MBMINLEN(mbminmaxlen);
- mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */
+ unsigned mbminlen:3; /*!< minimum length of a
+ character, in bytes */
+ unsigned mbmaxlen:3; /*!< maximum length of a
+ character, in bytes */
/*----------------------*/
/* End of definitions copied from dtype_t */
/* @} */
@@ -720,6 +719,8 @@ struct dict_index_t{
dict_sys->mutex. Other changes are
protected by index->lock. */
dict_field_t* fields; /*!< array of field descriptions */
+ bool index_fts_syncing;/*!< Whether the fts index is
+ still syncing in the background */
#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(dict_index_t)
indexes;/*!< list of indexes of the table */
diff --git a/storage/xtradb/include/dict0stats_bg.h b/storage/xtradb/include/dict0stats_bg.h
index 8f3385eb22b..66fcf7a0998 100644
--- a/storage/xtradb/include/dict0stats_bg.h
+++ b/storage/xtradb/include/dict0stats_bg.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@@ -83,7 +83,7 @@ dict_stats_defrag_pool_del(
/** Yield the data dictionary latch when waiting
for the background thread to stop accessing a table.
@param trx transaction holding the data dictionary locks */
-#define DICT_STATS_BG_YIELD(trx) do { \
+#define DICT_BG_YIELD(trx) do { \
row_mysql_unlock_data_dictionary(trx); \
os_thread_sleep(250000); \
row_mysql_lock_data_dictionary(trx); \
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 5fe2d20b4f0..8c3bf7d2b06 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2018, 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
@@ -1161,7 +1161,7 @@ Reads or writes data. This operation is asynchronous (aio).
i/o on a tablespace which does not exist */
UNIV_INTERN
dberr_t
-_fil_io(
+fil_io(
/*===*/
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
@@ -1189,16 +1189,18 @@ _fil_io(
void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
ulint* write_size, /*!< in/out: Actual write size initialized
- after fist successfull trim
- operation for this page and if
- initialized we do not trim again if
- actual page size does not decrease. */
- trx_t* trx) /*!< in: trx */
-
- __attribute__((nonnull(8)));
-
-#define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size) \
- _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, write_size, NULL)
+ after fist successfull trim
+ operation for this page and if
+ initialized we do not trim again if
+ actual page size does not decrease. */
+ trx_t* trx = NULL, /*!< in: trx */
+ bool should_buffer = false)
+ /*!< in: whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
+ MY_ATTRIBUTE((nonnull(8)));
/** Determine the block size of the data file.
@param[in] space tablespace
diff --git a/storage/xtradb/include/log0crypt.h b/storage/xtradb/include/log0crypt.h
index 0ad7e7d7037..b7a221e0a81 100644
--- a/storage/xtradb/include/log0crypt.h
+++ b/storage/xtradb/include/log0crypt.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (C) 2014, 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2014, 2018, 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
@@ -73,6 +73,8 @@ log_encrypt_before_write(
/*=====================*/
ib_uint64_t next_checkpoint_no, /*!< in: log group to be flushed */
byte* block, /*!< in/out: pointer to a log block */
+ lsn_t lsn, /*!< in: log sequence number of
+ the start of the buffer */
const ulint size); /*!< in: size of log blocks */
/********************************************************
@@ -83,6 +85,8 @@ void
log_decrypt_after_read(
/*===================*/
byte* frame, /*!< in/out: log segment */
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
const ulint size); /*!< in: log segment size */
/* Error codes for crypt info */
diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h
index 5c3e7d07fd9..2d1febe9b9f 100644
--- a/storage/xtradb/include/log0online.h
+++ b/storage/xtradb/include/log0online.h
@@ -129,7 +129,11 @@ log_online_bitmap_iterator_next(
/** Struct for single bitmap file information */
struct log_online_bitmap_file_struct {
- char name[FN_REFLEN]; /*!< Name with full path */
+ /** Name with full path
+ 61 is a nice magic constant for the extra space needed for the sprintf
+ template in the cc file
+ */
+ char name[FN_REFLEN+61]; /*!< Name with full path */
pfs_os_file_t file; /*!< Handle to opened file */
ib_uint64_t size; /*!< Size of the file */
os_offset_t offset; /*!< Offset of the next read,
diff --git a/storage/xtradb/include/mem0mem.ic b/storage/xtradb/include/mem0mem.ic
index 63e68150b61..2b4638718fd 100644
--- a/storage/xtradb/include/mem0mem.ic
+++ b/storage/xtradb/include/mem0mem.ic
@@ -305,8 +305,8 @@ mem_heap_free_heap_top(
mem_block_set_free(block, old_top - (byte*) block);
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
- UNIV_MEM_ASSERT_W(old_top, (byte*) block + block->len - old_top);
#if defined UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top);
/* In the debug version erase block from top up */
mem_erase_buf(old_top, (byte*) block + block->len - old_top);
@@ -315,7 +315,7 @@ mem_heap_free_heap_top(
mem_current_allocated_memory -= (total_size - size);
mutex_exit(&mem_hash_mutex);
#endif /* UNIV_MEM_DEBUG */
- UNIV_MEM_ALLOC(old_top, (byte*) block + block->len - old_top);
+ UNIV_MEM_FREE(old_top, (byte*)block + block->len - old_top);
/* If free == start, we may free the block if it is not the first
one */
@@ -396,11 +396,11 @@ mem_heap_free_top(
/* Subtract the free field of block */
mem_block_set_free(block, mem_block_get_free(block)
- MEM_SPACE_NEEDED(n));
- UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n);
#ifdef UNIV_MEM_DEBUG
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
+ UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
/* In the debug version check the consistency, and erase field */
mem_field_erase((byte*) block + mem_block_get_free(block), n);
#endif
@@ -412,11 +412,7 @@ mem_heap_free_top(
== mem_block_get_start(block))) {
mem_heap_block_free(heap, block);
} else {
- /* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a
- subsequent invocation of mem_heap_free_top().
- Originally, this was UNIV_MEM_FREE(), to catch writes
- to freed memory. */
- UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
+ UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n);
}
}
diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h
index ef6cd61719d..42a57f1022a 100644
--- a/storage/xtradb/include/mtr0mtr.h
+++ b/storage/xtradb/include/mtr0mtr.h
@@ -35,7 +35,6 @@ Created 11/26/1995 Heikki Tuuri
#include "ut0byte.h"
#include "mtr0types.h"
#include "page0types.h"
-#include "trx0types.h"
/* Logging modes for a mini-transaction */
#define MTR_LOG_ALL 21 /* default mode: log all operations
@@ -213,22 +212,10 @@ functions). The page number parameter was originally written as 0. @{ */
Starts a mini-transaction. */
UNIV_INLINE
void
-mtr_start_trx(
-/*======*/
- mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx) /*!< in: transaction */
- __attribute__((nonnull (1)));
-/***************************************************************//**
-Starts a mini-transaction. */
-UNIV_INLINE
-void
mtr_start(
/*======*/
mtr_t* mtr) /*!< out: mini-transaction */
-{
- mtr_start_trx(mtr, NULL);
-}
- MY_ATTRIBUTE((nonnull))
+ MY_ATTRIBUTE((nonnull));
/***************************************************************//**
Commits a mini-transaction. */
UNIV_INTERN
@@ -435,7 +422,6 @@ struct mtr_t{
#ifdef UNIV_DEBUG
ulint magic_n;
#endif /* UNIV_DEBUG */
- trx_t* trx; /*!< transaction */
};
#ifdef UNIV_DEBUG
diff --git a/storage/xtradb/include/mtr0mtr.ic b/storage/xtradb/include/mtr0mtr.ic
index a6d9df09925..04c39cf7f7e 100644
--- a/storage/xtradb/include/mtr0mtr.ic
+++ b/storage/xtradb/include/mtr0mtr.ic
@@ -43,10 +43,9 @@ mtr_block_dirtied(
Starts a mini-transaction. */
UNIV_INLINE
void
-mtr_start_trx(
+mtr_start(
/*======*/
- mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx) /*!< in: transaction */
+ mtr_t* mtr) /*!< out: mini-transaction */
{
UNIV_MEM_INVALID(mtr, sizeof *mtr);
@@ -59,7 +58,6 @@ mtr_start_trx(
mtr->made_dirty = FALSE;
mtr->n_log_recs = 0;
mtr->n_freed_pages = 0;
- mtr->trx = trx;
ut_d(mtr->state = MTR_ACTIVE);
ut_d(mtr->magic_n = MTR_MAGIC_N);
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index f69230240c5..5e93b3454c7 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -382,11 +382,12 @@ The wrapper functions have the prefix of "innodb_". */
pfs_os_file_close_no_error_handling_func(file, __FILE__, __LINE__)
# define os_aio(type, is_log, mode, name, file, buf, offset, \
- n, page_size, message1, message2, space_id, \
- trx, write_size) \
+ n, page_size, message1, message2, space_id, \
+ trx, write_size, should_buffer) \
pfs_os_aio_func(type, is_log, mode, name, file, buf, offset, \
- n, page_size, message1, message2, space_id, trx, write_size, \
- __FILE__, __LINE__)
+ n, page_size, message1, message2, space_id, \
+ trx, write_size, should_buffer, \
+ __FILE__, __LINE__)
# define os_file_read(file, buf, offset, n) \
pfs_os_file_read_func(file, buf, offset, n, NULL, \
@@ -454,10 +455,12 @@ to original un-instrumented file I/O APIs */
# define os_file_close_no_error_handling(file) \
os_file_close_no_error_handling_func(file)
-# define os_aio(type, is_log, mode, name, file, buf, offset, n, page_size, message1, \
- message2, space_id, trx, write_size) \
+# define os_aio(type, is_log, mode, name, file, buf, offset, \
+ n, page_size, message1, \
+ message2, space_id, trx, write_size, should_buffer) \
os_aio_func(type, is_log, mode, name, file, buf, offset, n, \
- page_size, message1, message2, space_id, trx, write_size)
+ page_size, message1, message2, space_id, \
+ trx, write_size, should_buffer)
# define os_file_read(file, buf, offset, n) \
os_file_read_func(file, buf, offset, n, NULL)
@@ -939,6 +942,12 @@ pfs_os_aio_func(
operation for this page and if
initialized we do not trim again if
actual page size does not decrease. */
+ bool should_buffer,
+ /*!< in: Whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
const char* src_file,/*!< in: file name where func invoked */
ulint src_line);/*!< in: line where the func invoked */
/*******************************************************************//**
@@ -1359,11 +1368,17 @@ os_aio_func(
OS_AIO_SYNC */
ulint space_id,
trx_t* trx,
- ulint* write_size);/*!< in/out: Actual write size initialized
+ ulint* write_size,/*!< in/out: Actual write size initialized
after fist successfull trim
operation for this page and if
initialized we do not trim again if
actual page size does not decrease. */
+ bool should_buffer);
+ /*!< in: Whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
/************************************************************************//**
Wakes up all async i/o threads so that they know to exit themselves in
shutdown. */
@@ -1547,6 +1562,10 @@ os_file_handle_error_no_exit(
ibool on_error_silent);/*!< in: if TRUE then don't print
any message to the log. */
+/** Submit buffered AIO requests on the given segment to the kernel. */
+UNIV_INTERN
+void
+os_aio_dispatch_read_array_submit();
/***********************************************************************//**
Try to get number of bytes per sector from file system.
diff --git a/storage/xtradb/include/os0file.ic b/storage/xtradb/include/os0file.ic
index 72ac9d9dd6a..a2011da3545 100644
--- a/storage/xtradb/include/os0file.ic
+++ b/storage/xtradb/include/os0file.ic
@@ -258,6 +258,9 @@ pfs_os_aio_func(
operation for this page and if
initialized we do not trim again if
actual page size does not decrease. */
+ bool should_buffer,
+ /*!< in: whether to buffer an aio request.
+ Only used by aio read ahead*/
const char* src_file,/*!< in: file name where func invoked */
ulint src_line)/*!< in: line where the func invoked */
{
@@ -274,7 +277,7 @@ pfs_os_aio_func(
result = os_aio_func(type, is_log, mode, name, file, buf, offset,
n, page_size, message1, message2, space_id, trx,
- write_size);
+ write_size, should_buffer);
register_pfs_file_io_end(locker, n);
diff --git a/storage/xtradb/include/rem0rec.ic b/storage/xtradb/include/rem0rec.ic
index 5811a77a48b..89f6902059d 100644
--- a/storage/xtradb/include/rem0rec.ic
+++ b/storage/xtradb/include/rem0rec.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -922,7 +923,7 @@ rec_offs_set_n_alloc(
{
ut_ad(offsets);
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
- UNIV_MEM_ASSERT_AND_ALLOC(offsets, n_alloc * sizeof *offsets);
+ UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets);
offsets[0] = n_alloc;
}
diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h
index 4326f1208e5..4915e7c7a31 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -591,18 +591,6 @@ void
row_mysql_close(void);
/*=================*/
-/*********************************************************************//**
-Reassigns the table identifier of a table.
-@return error code or DB_SUCCESS */
-UNIV_INTERN
-dberr_t
-row_mysql_table_id_reassign(
-/*========================*/
- dict_table_t* table, /*!< in/out: table */
- trx_t* trx, /*!< in/out: transaction */
- table_id_t* new_id) /*!< out: new table id */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-
/* A struct describing a place for an individual column in the MySQL
row format which is presented to the table handler in ha_innobase.
This template struct is used to speed up row transformations between
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index e7f6350987e..6df60e0e52d 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -195,6 +195,9 @@ struct srv_stats_t {
wait timeout */
ulint_ctr_1_t n_lock_max_wait_time;
+ /** Number of buffered aio requests submitted */
+ ulint_ctr_64_t n_aio_submitted;
+
/** Number of times page 0 is read from tablespace */
ulint_ctr_64_t page0_read;
@@ -720,6 +723,9 @@ extern ulong srv_sync_array_size;
/* print all user-level transactions deadlocks to mysqld stderr */
extern my_bool srv_print_all_deadlocks;
+/* print lock wait timeout info to mysqld stderr */
+extern my_bool srv_print_lock_wait_timeout_info;
+
extern my_bool srv_cmp_per_index_enabled;
/* is encryption enabled */
@@ -1294,7 +1300,9 @@ struct export_var_t{
ib_int64_t innodb_n_rowlog_blocks_decrypted;
ulint innodb_sec_rec_cluster_reads; /*!< srv_sec_rec_cluster_reads */
- ulint innodb_sec_rec_cluster_reads_avoided;/*!< srv_sec_rec_cluster_reads_avoided */
+ ulint innodb_sec_rec_cluster_reads_avoided; /*!< srv_sec_rec_cluster_reads_avoided */
+
+ ulint innodb_buffered_aio_submitted;
ulint innodb_encryption_rotation_pages_read_from_cache;
ulint innodb_encryption_rotation_pages_read_from_disk;
diff --git a/storage/xtradb/include/trx0rec.h b/storage/xtradb/include/trx0rec.h
index 630818a8648..fef12548003 100644
--- a/storage/xtradb/include/trx0rec.h
+++ b/storage/xtradb/include/trx0rec.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -196,6 +196,7 @@ trx_undo_rec_get_partial_row(
used, as we do NOT copy the data in the
record! */
dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: updated columns */
dtuple_t** row, /*!< out, own: partial row */
ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
@@ -228,7 +229,7 @@ trx_undo_report_row_operation(
const ulint* offsets, /*!< in: rec_get_offsets(rec) */
roll_ptr_t* roll_ptr) /*!< out: DB_ROLL_PTR to the
undo log record */
- MY_ATTRIBUTE((nonnull(1,2,8), warn_unused_result));
+ MY_ATTRIBUTE((nonnull(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.
diff --git a/storage/xtradb/include/trx0undo.h b/storage/xtradb/include/trx0undo.h
index 190308112ba..0148cc61579 100644
--- a/storage/xtradb/include/trx0undo.h
+++ b/storage/xtradb/include/trx0undo.h
@@ -243,13 +243,22 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end(
+trx_undo_truncate_end_func(
/*=======================*/
- trx_t* trx, /*!< in: transaction whose undo log it is */
+#ifdef UNIV_DEBUG
+ const trx_t* trx, /*!< in: transaction whose undo log it is */
+#endif /* UNIV_DEBUG */
trx_undo_t* undo, /*!< in/out: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
MY_ATTRIBUTE((nonnull));
+#ifdef UNIV_DEBUG
+# define trx_undo_truncate_end(trx,undo,limit) \
+ trx_undo_truncate_end_func(trx,undo,limit)
+#else /* UNIV_DEBUG */
+# define trx_undo_truncate_end(trx,undo,limit) \
+ trx_undo_truncate_end_func(undo,limit)
+#endif /* UNIV_DEBUG */
/***********************************************************************//**
Truncates an undo log from the start. This function is used during a purge
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 5886b078e4d..93ab71bf46c 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -48,7 +48,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_BUGFIX 36
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 82.2
+#define PERCONA_INNODB_VERSION 83.0
#endif
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
@@ -691,14 +691,6 @@ typedef void* os_thread_ret_t;
# define UNIV_MEM_ASSERT_W(addr, size) do {} while(0)
# define UNIV_MEM_TRASH(addr, c, size) do {} while(0)
#endif
-#define UNIV_MEM_ASSERT_AND_FREE(addr, size) do { \
- UNIV_MEM_ASSERT_W(addr, size); \
- UNIV_MEM_FREE(addr, size); \
-} while (0)
-#define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) do { \
- UNIV_MEM_ASSERT_W(addr, size); \
- UNIV_MEM_ALLOC(addr, size); \
-} while (0)
extern ulong srv_page_size_shift;
extern ulong srv_page_size;
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index 20e3f5adeb7..a9077cb19a3 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation
+Copyright (c) 2014, 2018, 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
@@ -6970,7 +6970,7 @@ lock_rec_block_validate(
/* Make sure that the tablespace is not deleted while we are
trying to access the page. */
- if (fil_space_t* space = fil_space_acquire(space_id)) {
+ if (fil_space_t* space = fil_space_acquire_silent(space_id)) {
mtr_start(&mtr);
block = buf_page_get_gen(
diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc
index a0f557e18e5..da4b0301df8 100644
--- a/storage/xtradb/lock/lock0wait.cc
+++ b/storage/xtradb/lock/lock0wait.cc
@@ -33,6 +33,20 @@ Created 25/5/2010 Sunny Bains
#include "srv0start.h"
#include "ha_prototypes.h"
#include "lock0priv.h"
+#include "lock0iter.h"
+
+#include <sstream>
+
+extern "C"
+LEX_STRING* thd_query_string(MYSQL_THD thd);
+
+struct blocking_trx_info {
+ uint64_t trx_id;
+ uint32_t thread_id;
+ int64_t query_id;
+};
+
+static const size_t MAX_BLOCKING_TRX_IN_REPORT = 10;
#include <mysql/service_wsrep.h>
@@ -187,6 +201,46 @@ lock_wait_table_reserve_slot(
return(NULL);
}
+/** Print lock wait timeout info to stderr. It's supposed this function
+is executed in trx's THD thread as it calls some non-thread-safe
+functions to get some info from THD.
+@param[in] trx requested trx
+@param[in] blocking blocking info array
+@param[in] blocking_count blocking info array size */
+void
+print_lock_wait_timeout(
+ const trx_t &trx,
+ blocking_trx_info *blocking,
+ size_t blocking_count)
+{
+ std::ostringstream outs;
+
+ outs << "Lock wait timeout info:\n";
+ outs << "Requested thread id: " <<
+ thd_get_thread_id(trx.mysql_thd) <<
+ "\n";
+ outs << "Requested trx id: " << trx.id << "\n";
+ outs << "Requested query: " <<
+ thd_query_string(trx.mysql_thd)->str << "\n";
+
+ outs << "Total blocking transactions count: " <<
+ blocking_count <<
+ "\n";
+
+ for (size_t i = 0; i < blocking_count; ++i) {
+ outs << "Blocking transaction number: " << (i + 1) << "\n";
+ outs << "Blocking thread id: " <<
+ blocking[i].thread_id <<
+ "\n";
+ outs << "Blocking query id: " <<
+ blocking[i].query_id <<
+ "\n";
+ outs << "Blocking trx id: " << blocking[i].trx_id << "\n";
+ }
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " %s", outs.str().c_str());
+}
+
#ifdef WITH_WSREP
/*********************************************************************//**
check if lock timeout was for priority thread,
@@ -235,6 +289,8 @@ lock_wait_suspend_thread(
ulint sec;
ulint ms;
ulong lock_wait_timeout;
+ blocking_trx_info blocking[MAX_BLOCKING_TRX_IN_REPORT];
+ size_t blocking_count = 0;
trx = thr_get_trx(thr);
@@ -411,6 +467,8 @@ lock_wait_suspend_thread(
#endif /* WITH_WSREP */
trx->error_state = DB_LOCK_WAIT_TIMEOUT;
+ if (srv_print_lock_wait_timeout_info)
+ print_lock_wait_timeout(*trx, blocking, blocking_count);
#ifdef WITH_WSREP
}
diff --git a/storage/xtradb/log/log0crypt.cc b/storage/xtradb/log/log0crypt.cc
index a5fbbab17ef..2a0a7abb686 100644
--- a/storage/xtradb/log/log0crypt.cc
+++ b/storage/xtradb/log/log0crypt.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (C) 2014, 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (C) 2014, 2018, 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
@@ -70,22 +70,6 @@ struct crypt_info_t {
static std::deque<crypt_info_t> crypt_info;
/*********************************************************************//**
-Get a log block's start lsn.
-@return a log block's start lsn */
-static inline
-lsn_t
-log_block_get_start_lsn(
-/*====================*/
- lsn_t lsn, /*!< in: checkpoint lsn */
- ulint log_block_no) /*!< in: log block number */
-{
- lsn_t start_lsn =
- (lsn & (lsn_t)0xffffffff00000000ULL) |
- (((log_block_no - 1) & (lsn_t)0x3fffffff) << 9);
- return start_lsn;
-}
-
-/*********************************************************************//**
Get crypt info from checkpoint.
@return a crypt info or NULL if not present. */
static
@@ -161,6 +145,8 @@ Crypt_result
log_blocks_crypt(
/*=============*/
const byte* block, /*!< in: blocks before encrypt/decrypt*/
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
ulint size, /*!< in: size of block */
byte* dst_block, /*!< out: blocks after encrypt/decrypt */
int what, /*!< in: encrypt or decrypt*/
@@ -170,21 +156,18 @@ log_blocks_crypt(
Crypt_result rc = MY_AES_OK;
uint dst_len;
byte aes_ctr_counter[MY_AES_BLOCK_SIZE];
- byte is_encrypt= what == ENCRYPTION_FLAG_ENCRYPT;
- lsn_t lsn = is_encrypt ? log_sys->lsn : srv_start_lsn;
const uint src_len = OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_HDR_SIZE;
- for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE) {
+ for (ulint i = 0; i < size ; i += OS_FILE_LOG_BLOCK_SIZE,
+ lsn += OS_FILE_LOG_BLOCK_SIZE) {
ulint log_block_no = log_block_get_hdr_no(log_block);
- lsn_t log_block_start_lsn = log_block_get_start_lsn(
- lsn, log_block_no);
const crypt_info_t* info = crypt_info == NULL ? get_crypt_info(log_block) :
crypt_info;
#ifdef DEBUG_CRYPT
fprintf(stderr,
"%s %lu chkpt: %lu key: %u lsn: %lu\n",
- is_encrypt ? "crypt" : "decrypt",
+ what == ENCRYPTION_FLAG_ENCRYPT ? "crypt" : "decrypt",
log_block_no,
log_block_get_checkpoint_no(log_block),
info ? info->key_version : 0,
@@ -213,7 +196,7 @@ log_blocks_crypt(
// (1-byte, only 5 bits are used). "+" means concatenate.
bzero(aes_ctr_counter, MY_AES_BLOCK_SIZE);
memcpy(aes_ctr_counter, info->crypt_nonce, 3);
- mach_write_to_8(aes_ctr_counter + 3, log_block_start_lsn);
+ mach_write_to_8(aes_ctr_counter + 3, lsn);
mach_write_to_4(aes_ctr_counter + 11, log_block_no);
bzero(aes_ctr_counter + 15, 1);
@@ -459,19 +442,6 @@ add_crypt_info(
}
/*********************************************************************//**
-Encrypt log blocks. */
-UNIV_INTERN
-Crypt_result
-log_blocks_encrypt(
-/*===============*/
- const byte* block, /*!< in: blocks before encryption */
- const ulint size, /*!< in: size of blocks, must be multiple of a log block */
- byte* dst_block) /*!< out: blocks after encryption */
-{
- return log_blocks_crypt(block, size, dst_block, ENCRYPTION_FLAG_ENCRYPT, NULL);
-}
-
-/*********************************************************************//**
Set next checkpoint's key version to latest one, and generate current
key. Key version 0 means no encryption. */
UNIV_INTERN
@@ -522,6 +492,8 @@ log_encrypt_before_write(
/*=====================*/
ib_uint64_t next_checkpoint_no, /*!< in: log group to be flushed */
byte* block, /*!< in/out: pointer to a log block */
+ lsn_t lsn, /*!< in: log sequence number of
+ the start of the buffer */
const ulint size) /*!< in: size of log blocks */
{
ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0);
@@ -540,7 +512,8 @@ log_encrypt_before_write(
byte* dst_frame = (byte*)malloc(size);
//encrypt log blocks content
- Crypt_result result = log_blocks_crypt(block, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT, NULL);
+ Crypt_result result = log_blocks_crypt(
+ block, lsn, size, dst_frame, ENCRYPTION_FLAG_ENCRYPT, NULL);
if (result == MY_AES_OK) {
ut_ad(block[0] == dst_frame[0]);
@@ -560,13 +533,16 @@ void
log_decrypt_after_read(
/*===================*/
byte* frame, /*!< in/out: log segment */
+ lsn_t lsn, /*!< in: log sequence number of the start
+ of the buffer */
const ulint size) /*!< in: log segment size */
{
ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0);
byte* dst_frame = (byte*)malloc(size);
// decrypt log blocks content
- Crypt_result result = log_blocks_crypt(frame, size, dst_frame, ENCRYPTION_FLAG_DECRYPT, NULL);
+ Crypt_result result = log_blocks_crypt(
+ frame, lsn, size, dst_frame, ENCRYPTION_FLAG_DECRYPT, NULL);
if (result == MY_AES_OK) {
memcpy(frame, dst_frame, size);
diff --git a/storage/xtradb/log/log0log.cc b/storage/xtradb/log/log0log.cc
index 1542f4a646f..8f8984f8880 100644
--- a/storage/xtradb/log/log0log.cc
+++ b/storage/xtradb/log/log0log.cc
@@ -1490,7 +1490,7 @@ loop:
ut_a(next_offset / UNIV_PAGE_SIZE <= ULINT_MAX);
log_encrypt_before_write(log_sys->next_checkpoint_no,
- buf, write_len);
+ buf, start_lsn, write_len);
#ifdef DEBUG_CRYPT
fprintf(stderr, "WRITE: block: %lu checkpoint: %lu %.8lx %.8lx\n",
@@ -2582,7 +2582,7 @@ loop:
log_block_get_checksum(buf), source_offset);
#endif
- log_decrypt_after_read(buf, len);
+ log_decrypt_after_read(buf, start_lsn, len);
#ifdef DEBUG_CRYPT
fprintf(stderr, "AFTER DECRYPT: block: %lu checkpoint: %lu %.8lx %.8lx\n",
@@ -2890,7 +2890,8 @@ loop:
MONITOR_INC(MONITOR_LOG_IO);
//TODO (jonaso): This must be dead code??
- log_encrypt_before_write(log_sys->next_checkpoint_no, buf, len);
+ log_encrypt_before_write(log_sys->next_checkpoint_no,
+ buf, start_lsn, len);
fil_io(OS_FILE_WRITE | OS_FILE_LOG, false, group->archive_space_id,
0,
diff --git a/storage/xtradb/log/log0online.cc b/storage/xtradb/log/log0online.cc
index 27382977e5c..af32237243b 100644
--- a/storage/xtradb/log/log0online.cc
+++ b/storage/xtradb/log/log0online.cc
@@ -479,9 +479,9 @@ log_online_make_bitmap_name(
/*=========================*/
lsn_t start_lsn) /*!< in: the start LSN name part */
{
- ut_snprintf(log_bmp_sys->out.name, FN_REFLEN, bmp_file_name_template,
- log_bmp_sys->bmp_file_home, bmp_file_name_stem,
- log_bmp_sys->out_seq_num, start_lsn);
+ ut_snprintf(log_bmp_sys->out.name, sizeof(log_bmp_sys->out.name),
+ bmp_file_name_template, log_bmp_sys->bmp_file_home,
+ bmp_file_name_stem, log_bmp_sys->out_seq_num, start_lsn);
}
/*********************************************************************//**
diff --git a/storage/xtradb/mem/mem0mem.cc b/storage/xtradb/mem/mem0mem.cc
index e066aff5b30..b9f190509ee 100644
--- a/storage/xtradb/mem/mem0mem.cc
+++ b/storage/xtradb/mem/mem0mem.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -506,13 +507,13 @@ mem_heap_block_free(
#ifndef UNIV_HOTBACKUP
if (!srv_use_sys_malloc) {
#ifdef UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*) block, len);
-#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ mem_erase_buf((byte*)block, len);
#endif /* UNIV_MEM_DEBUG */
+ UNIV_MEM_FREE(block, len);
}
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
@@ -526,13 +527,13 @@ mem_heap_block_free(
}
#else /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG
+ UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*) block, len);
-#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ mem_erase_buf((byte*)block, len);
#endif /* UNIV_MEM_DEBUG */
+ UNIV_MEM_FREE(block, len);
ut_free(block);
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 8b0fa059100..634ebb2af49 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -296,6 +296,16 @@ struct os_aio_array_t{
There is one such event for each
possible pending IO. The size of the
array is equal to n_slots. */
+ struct iocb** pending;
+ /* Array to buffer the not-submitted aio
+ requests. The array length is n_slots.
+ It is divided into n_segments segments.
+ pending requests on each segment are buffered
+ separately.*/
+ ulint* count;
+ /* Array of length n_segments. Each element
+ counts the number of not-submitted aio
+ request on that segment.*/
#endif /* LINUX_NATIV_AIO */
};
@@ -4276,6 +4286,13 @@ os_aio_array_create(
memset(io_event, 0x0, sizeof(*io_event) * n);
array->aio_events = io_event;
+ array->pending = static_cast<struct iocb**>(
+ ut_malloc(n * sizeof(struct iocb*)));
+ memset(array->pending, 0x0, sizeof(struct iocb*) * n);
+ array->count = static_cast<ulint*>(
+ ut_malloc(n_segments * sizeof(ulint)));
+ memset(array->count, 0x0, sizeof(ulint) * n_segments);
+
skip_native_aio:
#endif /* LINUX_NATIVE_AIO */
for (ulint i = 0; i < n; i++) {
@@ -4310,6 +4327,16 @@ os_aio_array_free(
if (srv_use_native_aio) {
ut_free(array->aio_events);
ut_free(array->aio_ctx);
+
+#ifdef UNIV_DEBUG
+ for (size_t idx = 0; idx < array->n_slots; ++idx)
+ ut_ad(array->pending[idx] == NULL);
+ for (size_t idx = 0; idx < array->n_segments; ++idx)
+ ut_ad(array->count[idx] == 0);
+#endif
+
+ ut_free(array->pending);
+ ut_free(array->count);
}
#endif /* LINUX_NATIVE_AIO */
@@ -4957,6 +4984,83 @@ readahead requests. */
}
#endif /* _WIN32 */
+/** Submit buffered AIO requests on the given segment to the kernel
+(low level function).
+@param acquire_mutex specifies whether to lock array mutex
+*/
+static
+void
+os_aio_dispatch_read_array_submit_low(bool acquire_mutex MY_ATTRIBUTE((unused)))
+{
+ if (!srv_use_native_aio) {
+ return;
+ }
+#if defined(LINUX_NATIVE_AIO)
+ os_aio_array_t* array = os_aio_read_array;
+ ulint total_submitted = 0;
+ if (acquire_mutex)
+ os_mutex_enter(array->mutex);
+ /* Submit aio requests buffered on all segments. */
+ for (ulint i = 0; i < array->n_segments; i++) {
+ const int count = array->count[i];
+ int offset = 0;
+ while (offset != count) {
+ struct iocb** const iocb_array = array->pending
+ + i * array->n_slots / array->n_segments
+ + offset;
+ const int partial_count = count - offset;
+ /* io_submit() returns number of successfully queued
+ requests or (-errno).
+ It returns 0 only if the number of iocb blocks passed
+ is also 0. */
+ const int submitted = io_submit(array->aio_ctx[i],
+ partial_count, iocb_array);
+
+ /* This assertion prevents infinite loop in both
+ debug and release modes. */
+ ut_a(submitted != 0);
+
+ if (submitted < 0) {
+ /* Terminating with fatal error */
+ const char* errmsg =
+ strerror(-submitted);
+ ib_logf(IB_LOG_LEVEL_FATAL,
+ "Trying to sumbit %d aio requests, "
+ "io_submit() set errno to %d: %s",
+ partial_count, -submitted,
+ errmsg ? errmsg : "<unknown>");
+ }
+ ut_ad(submitted <= partial_count);
+ if (submitted < partial_count)
+ {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Trying to sumbit %d aio requests, "
+ "io_submit() submitted only %d",
+ partial_count, submitted);
+ }
+ offset += submitted;
+ }
+ total_submitted += count;
+ }
+ /* Reset the aio request buffer. */
+ memset(array->pending, 0x0, sizeof(struct iocb*) * array->n_slots);
+ memset(array->count, 0x0, sizeof(ulint) * array->n_segments);
+
+ if (acquire_mutex)
+ os_mutex_exit(array->mutex);
+
+ srv_stats.n_aio_submitted.add(total_submitted);
+#endif
+}
+
+/** Submit buffered AIO requests on the given segment to the kernel. */
+UNIV_INTERN
+void
+os_aio_dispatch_read_array_submit()
+{
+ os_aio_dispatch_read_array_submit_low(true);
+}
+
#if defined(LINUX_NATIVE_AIO)
/*******************************************************************//**
Dispatch an AIO request to the kernel.
@@ -4966,10 +5070,11 @@ ibool
os_aio_linux_dispatch(
/*==================*/
os_aio_array_t* array, /*!< in: io request array. */
- os_aio_slot_t* slot) /*!< in: an already reserved slot. */
+ os_aio_slot_t* slot, /*!< in: an already reserved slot. */
+ bool should_buffer) /*!< in: should buffer the request
+ rather than submit. */
{
int ret;
- ulint io_ctx_index;
struct iocb* iocb;
ut_ad(slot != NULL);
@@ -4981,9 +5086,31 @@ os_aio_linux_dispatch(
The iocb struct is directly in the slot.
The io_context is one per segment. */
+ ulint slots_per_segment = array->n_slots / array->n_segments;
iocb = &slot->control;
- io_ctx_index = (slot->pos * array->n_segments) / array->n_slots;
+ ulint io_ctx_index = slot->pos / slots_per_segment;
+ if (should_buffer) {
+ ut_ad(array == os_aio_read_array);
+ os_mutex_enter(array->mutex);
+ /* There are array->n_slots elements in array->pending,
+ which is divided into array->n_segments area of equal size.
+ The iocb of each segment are buffered in its corresponding area
+ in the pending array consecutively as they come.
+ array->count[i] records the number of buffered aio requests
+ in the ith segment.*/
+ ulint& count = array->count[io_ctx_index];
+ ut_ad(count != slots_per_segment);
+ ulint n = io_ctx_index * slots_per_segment + count;
+ array->pending[n] = iocb;
+ ++count;
+ if (count == slots_per_segment) {
+ os_aio_dispatch_read_array_submit_low(false);
+ }
+ os_mutex_exit(array->mutex);
+ return(TRUE);
+ }
+ /* Submit the given request. */
ret = io_submit(array->aio_ctx[io_ctx_index], 1, &iocb);
#if defined(UNIV_AIO_DEBUG)
@@ -5046,11 +5173,17 @@ os_aio_func(
OS_AIO_SYNC */
ulint space_id,
trx_t* trx,
- ulint* write_size)/*!< in/out: Actual write size initialized
+ ulint* write_size,/*!< in/out: Actual write size initialized
after fist successfull trim
operation for this page and if
initialized we do not trim again if
actual page size does not decrease. */
+ bool should_buffer)
+ /*!< in: Whether to buffer an aio request.
+ AIO read ahead uses this. If you plan to
+ use this parameter, make sure you remember
+ to call os_aio_dispatch_read_array_submit()
+ when you're ready to commit all your requests.*/
{
os_aio_array_t* array;
os_aio_slot_t* slot;
@@ -5168,7 +5301,8 @@ try_again:
goto err_exit;
#elif defined(LINUX_NATIVE_AIO)
- if (!os_aio_linux_dispatch(array, slot)) {
+ if (!os_aio_linux_dispatch(array, slot,
+ should_buffer)) {
goto err_exit;
}
#endif /* WIN_ASYNC_IO */
@@ -5192,7 +5326,7 @@ try_again:
if(!ret && GetLastError() != ERROR_IO_PENDING)
goto err_exit;
#elif defined(LINUX_NATIVE_AIO)
- if (!os_aio_linux_dispatch(array, slot)) {
+ if (!os_aio_linux_dispatch(array, slot, false)) {
goto err_exit;
}
#endif /* WIN_ASYNC_IO */
diff --git a/storage/xtradb/page/page0page.cc b/storage/xtradb/page/page0page.cc
index 800f76e1532..fc93eebd445 100644
--- a/storage/xtradb/page/page0page.cc
+++ b/storage/xtradb/page/page0page.cc
@@ -2839,7 +2839,7 @@ page_warn_strict_checksum(
ulint space_id,
ulint page_no)
{
- srv_checksum_algorithm_t curr_algo_nonstrict;
+ srv_checksum_algorithm_t curr_algo_nonstrict = srv_checksum_algorithm_t();
switch (curr_algo) {
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
curr_algo_nonstrict = SRV_CHECKSUM_ALGORITHM_CRC32;
diff --git a/storage/xtradb/rem/rem0rec.cc b/storage/xtradb/rem/rem0rec.cc
index c62e8c90434..2314f110312 100644
--- a/storage/xtradb/rem/rem0rec.cc
+++ b/storage/xtradb/rem/rem0rec.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -865,13 +865,10 @@ rec_get_converted_size_comp_prefix_low(
if (fixed_len) {
#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
-
ut_ad(len <= fixed_len);
- ut_ad(!mbmaxlen || len >= mbminlen
- * (fixed_len / mbmaxlen));
+ ut_ad(!col->mbmaxlen || len >= col->mbminlen
+ * (fixed_len / col->mbmaxlen));
/* dict_index_add_col() should guarantee this */
ut_ad(!field->prefix_len
@@ -1259,14 +1256,10 @@ rec_convert_dtuple_to_rec_comp(
it is 128 or more, or when the field is stored externally. */
if (fixed_len) {
#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(
- ifield->col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(
- ifield->col->mbminmaxlen);
-
ut_ad(len <= fixed_len);
- ut_ad(!mbmaxlen || len >= mbminlen
- * (fixed_len / mbmaxlen));
+ ut_ad(!ifield->col->mbmaxlen
+ || len >= ifield->col->mbminlen
+ * (fixed_len / ifield->col->mbmaxlen));
ut_ad(!dfield_is_ext(field));
#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(field)) {
diff --git a/storage/xtradb/row/row0ext.cc b/storage/xtradb/row/row0ext.cc
index ad852577ad2..32b78391d6a 100644
--- a/storage/xtradb/row/row0ext.cc
+++ b/storage/xtradb/row/row0ext.cc
@@ -78,8 +78,7 @@ row_ext_cache_fill(
crashed during the execution of
btr_free_externally_stored_field(). */
ext->len[i] = btr_copy_externally_stored_field_prefix(
- buf, ext->max_len, zip_size, field, f_len,
- NULL);
+ buf, ext->max_len, zip_size, field, f_len);
}
}
}
diff --git a/storage/xtradb/row/row0ftsort.cc b/storage/xtradb/row/row0ftsort.cc
index 0f9c15f6a69..bd57685b71c 100644
--- a/storage/xtradb/row/row0ftsort.cc
+++ b/storage/xtradb/row/row0ftsort.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -106,8 +106,9 @@ row_merge_create_fts_sort_index(
field->col->prtype = idx_field->col->prtype | DATA_NOT_NULL;
field->col->mtype = charset == &my_charset_latin1
? DATA_VARCHAR : DATA_VARMYSQL;
- field->col->mbminmaxlen = idx_field->col->mbminmaxlen;
- field->col->len = HA_FT_MAXCHARLEN * DATA_MBMAXLEN(field->col->mbminmaxlen);
+ field->col->mbminlen = idx_field->col->mbminlen;
+ field->col->mbmaxlen = idx_field->col->mbmaxlen;
+ field->col->len = HA_FT_MAXCHARLEN * field->col->mbmaxlen;
field->fixed_len = 0;
@@ -150,7 +151,8 @@ row_merge_create_fts_sort_index(
field->col->prtype = DATA_NOT_NULL | DATA_BINARY_TYPE;
- field->col->mbminmaxlen = 0;
+ field->col->mbminlen = 0;
+ field->col->mbmaxlen = 0;
/* The third field is on the word's position in the original doc */
field = dict_index_get_nth_field(new_index, 2);
@@ -162,7 +164,8 @@ row_merge_create_fts_sort_index(
field->col->len = 4 ;
field->fixed_len = 4;
field->col->prtype = DATA_NOT_NULL;
- field->col->mbminmaxlen = 0;
+ field->col->mbminlen = 0;
+ field->col->mbmaxlen = 0;
return(new_index);
}
@@ -540,7 +543,8 @@ row_merge_fts_doc_tokenize(
field->type.mtype = DATA_INT;
field->type.prtype = DATA_NOT_NULL | DATA_BINARY_TYPE;
field->type.len = len;
- field->type.mbminmaxlen = 0;
+ field->type.mbminlen = 0;
+ field->type.mbmaxlen = 0;
cur_len += len;
dfield_dup(field, buf->heap);
@@ -559,7 +563,8 @@ row_merge_fts_doc_tokenize(
field->type.mtype = DATA_INT;
field->type.prtype = DATA_NOT_NULL;
field->type.len = len;
- field->type.mbminmaxlen = 0;
+ field->type.mbminlen = 0;
+ field->type.mbmaxlen = 0;
cur_len += len;
dfield_dup(field, buf->heap);
@@ -709,8 +714,7 @@ loop:
doc.text.f_str =
btr_copy_externally_stored_field(
&doc.text.f_len, data,
- zip_size, data_len, blob_heap,
- NULL);
+ zip_size, data_len, blob_heap);
} else {
doc.text.f_str = data;
doc.text.f_len = data_len;
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index 3efc2a30037..f0035302852 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, 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
@@ -1259,7 +1259,8 @@ row_import::match_table_columns(
err = DB_ERROR;
}
- if (cfg_col->mbminmaxlen != col->mbminmaxlen) {
+ if (cfg_col->mbminlen != col->mbminlen
+ || cfg_col->mbmaxlen != col->mbmaxlen) {
ib_errf(thd,
IB_LOG_LEVEL_ERROR,
ER_TABLE_SCHEMA_MISMATCH,
@@ -2877,7 +2878,9 @@ row_import_read_columns(
col->len = mach_read_from_4(ptr);
ptr += sizeof(ib_uint32_t);
- col->mbminmaxlen = mach_read_from_4(ptr);
+ ulint mbminmaxlen = mach_read_from_4(ptr);
+ col->mbmaxlen = mbminmaxlen / 5;
+ col->mbminlen = mbminmaxlen % 5;
ptr += sizeof(ib_uint32_t);
col->ind = mach_read_from_4(ptr);
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index f653a4df77d..472be8ad848 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -571,7 +571,8 @@ row_ins_cascade_calc_update_vec(
if (!dfield_is_null(&ufield->new_val)
&& dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype,
+ col->mbminlen, col->mbmaxlen,
col->len,
ufield_len,
static_cast<char*>(
@@ -1330,7 +1331,7 @@ row_ins_foreign_check_on_constraint(
row_mysql_freeze_data_dictionary(thr_get_trx(thr));
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
/* Restore pcur position */
@@ -1358,7 +1359,7 @@ nonstandard_exit_func:
btr_pcur_store_position(pcur, mtr);
mtr_commit(mtr);
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr);
@@ -1571,7 +1572,7 @@ run_again:
}
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Store old value on n_fields_cmp */
@@ -2390,7 +2391,7 @@ row_ins_clust_index_entry_low(
search_mode = mode;
}
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_LEAF && dict_index_is_online_ddl(index)) {
@@ -2628,10 +2629,9 @@ Starts a mini-transaction and checks if the index will be dropped.
@return true if the index is to be dropped */
static MY_ATTRIBUTE((nonnull, warn_unused_result))
bool
-row_ins_sec_mtr_start_trx_and_check_if_aborted(
+row_ins_sec_mtr_start_and_check_if_aborted(
/*=======================================*/
mtr_t* mtr, /*!< out: mini-transaction */
- trx_t* trx, /*!< in: transaction handle */
dict_index_t* index, /*!< in/out: secondary index */
bool check, /*!< in: whether to check */
ulint search_mode)
@@ -2639,7 +2639,7 @@ row_ins_sec_mtr_start_trx_and_check_if_aborted(
{
ut_ad(!dict_index_is_clust(index));
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
if (!check) {
return(false);
@@ -2697,14 +2697,13 @@ row_ins_sec_index_entry_low(
ulint n_unique;
mtr_t mtr;
ulint* offsets = NULL;
- trx_t* trx = thr_get_trx(thr);
ut_ad(!dict_index_is_clust(index));
ut_ad(mode == BTR_MODIFY_LEAF || mode == BTR_MODIFY_TREE);
cursor.thr = thr;
ut_ad(thr_get_trx(thr)->id);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* If running with fake_changes mode on then avoid using insert buffer
and also switch from modify to search so that code takes only s-latch
@@ -2766,7 +2765,7 @@ row_ins_sec_index_entry_low(
if (err != DB_SUCCESS) {
if (err == DB_DECRYPTION_FAILED) {
- ib_push_warning(trx->mysql_thd,
+ ib_push_warning(thr_get_trx(thr)->mysql_thd,
DB_DECRYPTION_FAILED,
"Table %s is encrypted but encryption service or"
" used key_id is not available. "
@@ -2802,8 +2801,8 @@ row_ins_sec_index_entry_low(
DEBUG_SYNC_C("row_ins_sec_index_unique");
- if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
- &mtr, trx, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_and_check_if_aborted(
+ &mtr, index, check, search_mode)) {
goto func_exit;
}
@@ -2837,8 +2836,8 @@ row_ins_sec_index_entry_low(
return(err);
}
- if (row_ins_sec_mtr_start_trx_and_check_if_aborted(
- &mtr, trx, index, check, search_mode)) {
+ if (row_ins_sec_mtr_start_and_check_if_aborted(
+ &mtr, index, check, search_mode)) {
goto func_exit;
}
@@ -3147,7 +3146,7 @@ row_ins_index_entry_set_vals(
= dict_field_get_col(ind_field);
len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype, col->mbminlen, col->mbmaxlen,
ind_field->prefix_len,
len,
static_cast<const char*>(
diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc
index 82fde841f39..040fb37ee30 100644
--- a/storage/xtradb/row/row0log.cc
+++ b/storage/xtradb/row/row0log.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -1064,7 +1064,7 @@ row_log_table_get_pk_col(
mem_heap_alloc(heap, field_len));
len = btr_copy_externally_stored_field_prefix(
- blob_field, field_len, zip_size, field, len, NULL);
+ blob_field, field_len, zip_size, field, len);
if (len >= max_len + 1) {
return(DB_TOO_BIG_INDEX_COL);
}
@@ -1183,7 +1183,7 @@ row_log_table_get_pk(
dict_field_t* ifield;
dfield_t* dfield;
ulint prtype;
- ulint mbminmaxlen;
+ ulint mbminlen, mbmaxlen;
ifield = dict_index_get_nth_field(new_index, new_i);
dfield = dtuple_get_nth_field(tuple, new_i);
@@ -1212,7 +1212,8 @@ err_exit:
goto func_exit;
}
- mbminmaxlen = col->mbminmaxlen;
+ mbminlen = col->mbminlen;
+ mbmaxlen = col->mbmaxlen;
prtype = col->prtype;
} else {
/* No matching column was found in the old
@@ -1222,7 +1223,8 @@ err_exit:
dfield_copy(dfield, dtuple_get_nth_field(
log->add_cols, col_no));
- mbminmaxlen = dfield->type.mbminmaxlen;
+ mbminlen = dfield->type.mbminlen;
+ mbmaxlen = dfield->type.mbmaxlen;
prtype = dfield->type.prtype;
}
@@ -1231,7 +1233,7 @@ err_exit:
if (ifield->prefix_len) {
ulint len = dtype_get_at_most_n_mbchars(
- prtype, mbminmaxlen,
+ prtype, mbminlen, mbmaxlen,
ifield->prefix_len,
dfield_get_len(dfield),
static_cast<const char*>(
@@ -1455,7 +1457,7 @@ row_log_table_apply_convert_mrec(
data = btr_rec_copy_externally_stored_field(
mrec, offsets,
dict_table_zip_size(index->table),
- i, &len, heap, NULL);
+ i, &len, heap);
ut_a(data);
dfield_set_data(dfield, data, len);
blob_done:
diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc
index cbcc3cc62f3..d9585818577 100644
--- a/storage/xtradb/row/row0merge.cc
+++ b/storage/xtradb/row/row0merge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2017, MariaDB Corporation.
+Copyright (c) 2014, 2018, 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
@@ -268,8 +268,8 @@ row_merge_buf_redundant_convert(
mem_heap_t* heap,
trx_t* trx)
{
- ut_ad(DATA_MBMINLEN(field->type.mbminmaxlen) == 1);
- ut_ad(DATA_MBMAXLEN(field->type.mbminmaxlen) > 1);
+ ut_ad(field->type.mbminlen == 1);
+ ut_ad(field->type.mbmaxlen > 1);
byte* buf = (byte*) mem_heap_alloc(heap, len);
ulint field_len = row_field->len;
@@ -285,7 +285,7 @@ row_merge_buf_redundant_convert(
field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE));
byte* data = btr_copy_externally_stored_field(
- &ext_len, field_data, zip_size, field_len, heap, trx);
+ &ext_len, field_data, zip_size, field_len, heap);
ut_ad(ext_len < len);
@@ -396,7 +396,8 @@ row_merge_buf_add(
field->type.mtype = ifield->col->mtype;
field->type.prtype = ifield->col->prtype;
- field->type.mbminmaxlen = DATA_MBMINMAXLEN(0, 0);
+ field->type.mbminlen = 0;
+ field->type.mbmaxlen = 0;
field->type.len = ifield->col->len;
} else {
row_field = dtuple_get_nth_field(row, col_no);
@@ -531,7 +532,7 @@ row_merge_buf_add(
if (ifield->prefix_len) {
len = dtype_get_at_most_n_mbchars(
col->prtype,
- col->mbminmaxlen,
+ col->mbminlen, col->mbmaxlen,
ifield->prefix_len,
len,
static_cast<char*>(dfield_get_data(field)));
@@ -546,8 +547,7 @@ row_merge_buf_add(
fixed_len = ifield->fixed_len;
if (fixed_len && !dict_table_is_comp(index->table)
- && DATA_MBMINLEN(col->mbminmaxlen)
- != DATA_MBMAXLEN(col->mbminmaxlen)) {
+ && col->mbminlen != col->mbmaxlen) {
/* CHAR in ROW_FORMAT=REDUNDANT is always
fixed-length, but in the temporary file it is
variable-length for variable-length character
@@ -557,14 +557,11 @@ row_merge_buf_add(
if (fixed_len) {
#ifdef UNIV_DEBUG
- ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
- ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
-
/* len should be between size calcualted base on
mbmaxlen and mbminlen */
ut_ad(len <= fixed_len);
- ut_ad(!mbmaxlen || len >= mbminlen
- * (fixed_len / mbmaxlen));
+ ut_ad(!col->mbmaxlen || len >= col->mbminlen
+ * (fixed_len / col->mbmaxlen));
ut_ad(!dfield_is_ext(field));
#endif /* UNIV_DEBUG */
@@ -2626,7 +2623,7 @@ row_merge_copy_blobs(
BLOB pointers are read (row_merge_read_clustered_index())
and dereferenced (below). */
data = btr_rec_copy_externally_stored_field(
- mrec, offsets, zip_size, i, &len, heap, NULL);
+ mrec, offsets, zip_size, i, &len, heap);
/* Because we have locked the table, any records
written by incomplete transactions must have been
rolled back already. There must not be any incomplete
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 43f4d4bcdd3..549a19799b3 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2015, 2018, 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
@@ -58,6 +58,7 @@ Created 9/17/2000 Heikki Tuuri
#include "btr0sea.h"
#include "btr0defragment.h"
#include "fil0fil.h"
+#include "srv0srv.h"
#include "fil0crypt.h"
#include "ibuf0ibuf.h"
#include "fts0fts.h"
@@ -1998,7 +1999,7 @@ row_unlock_for_mysql(
trx_id_t rec_trx_id;
mtr_t mtr;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Restore the cursor position and find the record */
@@ -2888,7 +2889,7 @@ func_exit:
/*********************************************************************//**
Reassigns the table identifier of a table.
@return error code or DB_SUCCESS */
-UNIV_INTERN
+static
dberr_t
row_mysql_table_id_reassign(
/*========================*/
@@ -3585,7 +3586,7 @@ row_truncate_table_for_mysql(
index = dict_table_get_next_index(index);
} while (index);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
fsp_header_init(space_id,
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
mtr_commit(&mtr);
@@ -3614,7 +3615,7 @@ row_truncate_table_for_mysql(
sys_index = dict_table_get_first_index(dict_sys->sys_indexes);
dict_index_copy_types(tuple, sys_index, 1);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
BTR_MODIFY_LEAF, &pcur, &mtr);
for (;;) {
@@ -3661,7 +3662,7 @@ row_truncate_table_for_mysql(
a page in this mini-transaction, and the rest of
this loop could latch another index page. */
mtr_commit(&mtr);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
btr_pcur_restore_position(BTR_MODIFY_LEAF,
&pcur, &mtr);
}
@@ -4003,6 +4004,16 @@ row_drop_table_for_mysql(
ut_ad(!table->fts->add_wq);
ut_ad(lock_trx_has_sys_table_locks(trx) == 0);
+ for (;;) {
+ bool retry = false;
+ if (dict_fts_index_syncing(table)) {
+ retry = true;
+ }
+ if (!retry) {
+ break;
+ }
+ DICT_BG_YIELD(trx);
+ }
row_mysql_unlock_data_dictionary(trx);
fts_optimize_remove_table(table);
row_mysql_lock_data_dictionary(trx);
diff --git a/storage/xtradb/row/row0purge.cc b/storage/xtradb/row/row0purge.cc
index 333677edf21..0cd0941987d 100644
--- a/storage/xtradb/row/row0purge.cc
+++ b/storage/xtradb/row/row0purge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -823,7 +823,7 @@ err_exit:
if (!(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
ptr = trx_undo_rec_get_partial_row(
- ptr, clust_index, &node->row,
+ ptr, clust_index, node->update, &node->row,
type == TRX_UNDO_UPD_DEL_REC,
node->heap);
}
diff --git a/storage/xtradb/row/row0quiesce.cc b/storage/xtradb/row/row0quiesce.cc
index 6c4e6adb96c..53b4040f74e 100644
--- a/storage/xtradb/row/row0quiesce.cc
+++ b/storage/xtradb/row/row0quiesce.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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,7 +237,11 @@ row_quiesce_write_table(
mach_write_to_4(ptr, col->len);
ptr += sizeof(ib_uint32_t);
- mach_write_to_4(ptr, col->mbminmaxlen);
+ /* FIXME: This will not work if mbminlen>4.
+ This field is also redundant, because the lengths
+ are a property of the character set encoding, which
+ in turn is encodedin prtype above. */
+ mach_write_to_4(ptr, col->mbmaxlen * 5 + col->mbminlen);
ptr += sizeof(ib_uint32_t);
mach_write_to_4(ptr, col->ind);
diff --git a/storage/xtradb/row/row0row.cc b/storage/xtradb/row/row0row.cc
index 96d25e15777..9bf9e7182ca 100644
--- a/storage/xtradb/row/row0row.cc
+++ b/storage/xtradb/row/row0row.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -173,7 +174,7 @@ row_build_index_entry_low(
/* If a column prefix index, take only the prefix. */
if (ind_field->prefix_len) {
len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype, col->mbminlen, col->mbmaxlen,
ind_field->prefix_len, len,
static_cast<char*>(dfield_get_data(dfield)));
dfield_set_len(dfield, len);
@@ -588,7 +589,8 @@ row_build_row_ref(
dfield_set_len(dfield,
dtype_get_at_most_n_mbchars(
dtype->prtype,
- dtype->mbminmaxlen,
+ dtype->mbminlen,
+ dtype->mbmaxlen,
clust_col_prefix_len,
len, (char*) field));
}
@@ -702,7 +704,8 @@ notfound:
dfield_set_len(dfield,
dtype_get_at_most_n_mbchars(
dtype->prtype,
- dtype->mbminmaxlen,
+ dtype->mbminlen,
+ dtype->mbmaxlen,
clust_col_prefix_len,
len, (char*) field));
}
diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc
index 6131129d0a6..03ae6822fb7 100644
--- a/storage/xtradb/row/row0sel.cc
+++ b/storage/xtradb/row/row0sel.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -98,8 +98,10 @@ row_sel_sec_rec_is_for_blob(
/*========================*/
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type */
- ulint mbminmaxlen, /*!< in: minimum and maximum length of
- a multi-byte character */
+ ulint mbminlen, /*!< in: minimum length of
+ a character, in bytes */
+ ulint mbmaxlen, /*!< in: maximum length of
+ a character, in bytes */
const byte* clust_field, /*!< in: the locally stored part of
the clustered index column, including
the BLOB pointer; the clustered
@@ -138,8 +140,7 @@ row_sel_sec_rec_is_for_blob(
len = btr_copy_externally_stored_field_prefix(buf, prefix_len,
zip_size,
- clust_field, clust_len,
- NULL);
+ clust_field, clust_len);
if (UNIV_UNLIKELY(len == 0)) {
/* The BLOB was being deleted as the server crashed.
@@ -150,7 +151,7 @@ row_sel_sec_rec_is_for_blob(
return(FALSE);
}
- len = dtype_get_at_most_n_mbchars(prtype, mbminmaxlen,
+ len = dtype_get_at_most_n_mbchars(prtype, mbminlen, mbmaxlen,
prefix_len, len, (const char*) buf);
return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
@@ -234,14 +235,14 @@ row_sel_sec_rec_is_for_clust_rec(
}
len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminmaxlen,
+ col->prtype, col->mbminlen, col->mbmaxlen,
ifield->prefix_len, len, (char*) clust_field);
if (rec_offs_nth_extern(clust_offs, clust_pos)
&& len < sec_len) {
if (!row_sel_sec_rec_is_for_blob(
col->mtype, col->prtype,
- col->mbminmaxlen,
+ col->mbminlen, col->mbmaxlen,
clust_field, clust_len,
sec_field, sec_len,
ifield->prefix_len,
@@ -458,7 +459,7 @@ row_sel_fetch_columns(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(index->table),
- field_no, &len, heap, NULL);
+ field_no, &len, heap);
/* data == NULL means that the
externally stored field was not
@@ -1406,7 +1407,7 @@ table_loop:
/* Open a cursor to index, or restore an open cursor position */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (consistent_read && plan->unique_search && !plan->pcur_is_open
&& !plan->must_get_clust
@@ -1447,7 +1448,7 @@ table_loop:
plan_reset_cursor(plan);
mtr_commit(&mtr);
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
}
if (search_latch_locked) {
@@ -2828,7 +2829,7 @@ row_sel_store_mysql_field_func(
data = btr_rec_copy_externally_stored_field(
rec, offsets,
dict_table_zip_size(prebuilt->table),
- field_no, &len, heap, NULL);
+ field_no, &len, heap);
if (UNIV_UNLIKELY(!data)) {
/* The externally stored field was not written
@@ -3933,7 +3934,7 @@ row_search_for_mysql(
}
}
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/*-------------------------------------------------------------*/
/* PHASE 2: Try fast adaptive hash index search if possible */
@@ -5159,7 +5160,7 @@ next_rec:
mtr_commit(&mtr);
mtr_has_extra_clust_latch = FALSE;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
if (sel_restore_position_for_mysql(&same_user_rec,
BTR_SEARCH_LEAF,
pcur, moves_up, &mtr)) {
@@ -5226,7 +5227,7 @@ lock_table_wait:
/* It was a lock wait, and it ended */
thr->lock_state = QUE_THR_LOCK_NOLOCK;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* Table lock waited, go try to obtain table lock
again */
diff --git a/storage/xtradb/row/row0umod.cc b/storage/xtradb/row/row0umod.cc
index 2e5cc14bfe1..bb2fc536616 100644
--- a/storage/xtradb/row/row0umod.cc
+++ b/storage/xtradb/row/row0umod.cc
@@ -269,7 +269,7 @@ row_undo_mod_clust(
pcur = &node->pcur;
index = btr_cur_get_index(btr_pcur_get_btr_cur(pcur));
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
online = dict_index_is_online_ddl(index);
if (online) {
@@ -298,7 +298,7 @@ row_undo_mod_clust(
/* We may have to modify tree structure: do a pessimistic
descent down the index tree */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
err = row_undo_mod_clust_low(
node, &offsets, &offsets_heap,
@@ -350,7 +350,7 @@ row_undo_mod_clust(
if (err == DB_SUCCESS && node->rec_type == TRX_UNDO_UPD_DEL_REC) {
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
/* It is not necessary to call row_log_table,
because the record is delete-marked and would thus
@@ -363,7 +363,7 @@ row_undo_mod_clust(
/* We may have to modify tree structure: do a
pessimistic descent down the index tree */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
err = row_undo_mod_remove_clust_low(node, thr, &mtr,
BTR_MODIFY_TREE);
@@ -410,7 +410,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
enum row_search_result search_result;
log_free_check();
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_TREE
&& index->space == IBUF_SPACE_ID
&& !dict_index_is_unique(index)) {
@@ -471,7 +471,7 @@ row_undo_mod_del_mark_or_remove_sec_low(
which cannot be purged yet, requires its existence. If some requires,
we should delete mark the record. */
- mtr_start_trx(&mtr_vers, thr_get_trx(thr));
+ mtr_start(&mtr_vers);
success = btr_pcur_restore_position(BTR_SEARCH_LEAF, &(node->pcur),
&mtr_vers);
@@ -587,7 +587,7 @@ row_undo_mod_del_unmark_sec_and_undo_update(
ut_ad(trx->id);
log_free_check();
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
if (mode == BTR_MODIFY_TREE
&& index->space == IBUF_SPACE_ID
&& !dict_index_is_unique(index)) {
diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc
index 113d2f10fc2..9ac72f8d068 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2018, 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
@@ -261,7 +262,7 @@ row_upd_check_references_constraints(
DEBUG_SYNC_C("foreign_constraint_check_for_update");
- mtr_start_trx(mtr, trx);
+ mtr_start(mtr);
if (trx->dict_operation_lock_mode == 0) {
got_s_lock = TRUE;
@@ -1155,7 +1156,7 @@ row_upd_ext_fetch(
byte* buf = static_cast<byte*>(mem_heap_alloc(heap, *len));
*len = btr_copy_externally_stored_field_prefix(
- buf, *len, zip_size, data, local_len, NULL);
+ buf, *len, zip_size, data, local_len);
/* We should never update records containing a half-deleted BLOB. */
ut_a(*len);
@@ -1207,7 +1208,7 @@ row_upd_index_replace_new_col_val(
}
len = dtype_get_at_most_n_mbchars(col->prtype,
- col->mbminmaxlen,
+ col->mbminlen, col->mbmaxlen,
field->prefix_len, len,
(const char*) data);
@@ -1855,7 +1856,7 @@ row_upd_sec_index_entry(
}
#endif /* UNIV_DEBUG */
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
if (*index->name == TEMP_INDEX_PREFIX) {
/* The index->online_status may change if the
@@ -2398,7 +2399,7 @@ row_upd_clust_rec(
/* We may have to modify the tree structure: do a pessimistic descent
down the index tree */
- mtr_start_trx(mtr, thr_get_trx(thr));
+ mtr_start(mtr);
/* NOTE: this transaction has an s-lock or x-lock on the record and
therefore other transactions cannot modify the record when we have no
@@ -2613,7 +2614,7 @@ row_upd_clust_step(
/* We have to restore the cursor to its position */
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
/* If the restoration does not succeed, then the same
transaction has deleted the record on which the cursor was,
@@ -2686,7 +2687,7 @@ row_upd_clust_step(
mtr_commit(&mtr);
- mtr_start_trx(&mtr, thr_get_trx(thr));
+ mtr_start(&mtr);
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur,
&mtr);
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index 65a15b15aec..02314db6b07 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -82,10 +82,6 @@ Created 10/8/1995 Heikki Tuuri
/* prototypes for new functions added to ha_innodb.cc */
ibool innobase_get_slow_log();
-#ifdef WITH_WSREP
-extern int wsrep_debug;
-extern int wsrep_trx_is_aborting(void *thd_ptr);
-#endif
/* The following counter is incremented whenever there is some user activity
in the server */
UNIV_INTERN ulint srv_activity_count = 0;
@@ -479,6 +475,9 @@ UNIV_INTERN my_bool srv_print_all_deadlocks = FALSE;
/* Produce a stacktrace on long semaphore wait */
UNIV_INTERN my_bool srv_use_stacktrace = FALSE;
+/** Print lock wait timeout info to mysqld stderr */
+my_bool srv_print_lock_wait_timeout_info = FALSE;
+
/** Enable INFORMATION_SCHEMA.innodb_cmp_per_index */
UNIV_INTERN my_bool srv_cmp_per_index_enabled = FALSE;
@@ -2137,6 +2136,9 @@ srv_export_innodb_status(void)
scrub_stat.page_split_failures_unknown;
}
+ export_vars.innodb_buffered_aio_submitted =
+ srv_stats.n_aio_submitted;
+
mutex_exit(&srv_innodb_monitor_mutex);
}
diff --git a/storage/xtradb/trx/trx0purge.cc b/storage/xtradb/trx/trx0purge.cc
index ff82bb2ad4e..cbf783628f9 100644
--- a/storage/xtradb/trx/trx0purge.cc
+++ b/storage/xtradb/trx/trx0purge.cc
@@ -584,32 +584,6 @@ trx_purge_rseg_get_next_history_log(
mutex_exit(&(rseg->mutex));
mtr_commit(&mtr);
-
- mutex_enter(&trx_sys->mutex);
-
- /* Add debug code to track history list corruption reported
- on the MySQL mailing list on Nov 9, 2004. The fut0lst.cc
- file-based list was corrupt. The prev node pointer was
- FIL_NULL, even though the list length was over 8 million nodes!
- We assume that purge truncates the history list in large
- size pieces, and if we here reach the head of the list, the
- list cannot be longer than 2000 000 undo logs now. */
-
- if (trx_sys->rseg_history_len > 2000000) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: purge reached the"
- " head of the history list,\n"
- "InnoDB: but its length is still"
- " reported as %lu! Make a detailed bug\n"
- "InnoDB: report, and submit it"
- " to https://jira.mariadb.org/\n",
- (ulong) trx_sys->rseg_history_len);
- ut_ad(0);
- }
-
- mutex_exit(&trx_sys->mutex);
-
return;
}
diff --git a/storage/xtradb/trx/trx0rec.cc b/storage/xtradb/trx/trx0rec.cc
index 8cd51c8066b..dc9b0829925 100644
--- a/storage/xtradb/trx/trx0rec.cc
+++ b/storage/xtradb/trx/trx0rec.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2018, 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
@@ -467,7 +467,7 @@ trx_undo_page_fetch_ext(
{
/* Fetch the BLOB. */
ulint ext_len = btr_copy_externally_stored_field_prefix(
- ext_buf, prefix_len, zip_size, field, *len, NULL);
+ ext_buf, prefix_len, zip_size, field, *len);
/* BLOBs should always be nonempty. */
ut_a(ext_len);
/* Append the BLOB pointer to the prefix. */
@@ -1076,6 +1076,7 @@ trx_undo_rec_get_partial_row(
used, as we do NOT copy the data in the
record! */
dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: updated columns */
dtuple_t** row, /*!< out, own: partial row */
ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
@@ -1103,6 +1104,13 @@ trx_undo_rec_get_partial_row(
->mtype = DATA_MISSING;
}
+ for (const upd_field_t* uf = update->fields, * const ue
+ = update->fields + update->n_fields;
+ uf != ue; uf++) {
+ ulint c = dict_index_get_nth_col(index, uf->field_no)->ind;
+ *dtuple_get_nth_field(*row, c) = uf->new_val;
+ }
+
end_ptr = ptr + mach_read_from_2(ptr);
ptr += 2;
@@ -1123,6 +1131,10 @@ trx_undo_rec_get_partial_row(
ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
dfield = dtuple_get_nth_field(*row, col_no);
+ ut_ad(dfield->type.mtype == DATA_MISSING
+ || dict_col_type_assert_equal(col, &dfield->type));
+ ut_ad(dfield->type.mtype == DATA_MISSING
+ || dfield->len == len);
dict_col_copy_type(
dict_table_get_nth_col(index->table, col_no),
dfield_get_type(dfield));
@@ -1256,7 +1268,7 @@ trx_undo_report_row_operation(
rseg = trx->rseg;
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&trx->undo_mutex);
/* If the undo log is not assigned yet, assign one */
@@ -1333,7 +1345,7 @@ trx_undo_report_row_operation(
latches, such as SYNC_FSP and SYNC_FSP_PAGE. */
mtr_commit(&mtr);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&rseg->mutex);
trx_undo_free_last_page(trx, undo, &mtr);
@@ -1370,7 +1382,7 @@ trx_undo_report_row_operation(
/* We have to extend the undo log by one page */
ut_ad(++loop_count < 2);
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
/* When we add a page to an undo log, this is analogous to
a pessimistic insert in a B-tree, and we must reserve the
diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc
index 9a5fcea71de..1075064a2d6 100644
--- a/storage/xtradb/trx/trx0roll.cc
+++ b/storage/xtradb/trx/trx0roll.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2017, MariaDB Corporation.
+Copyright (c) 2016, 2018, 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
@@ -751,7 +751,8 @@ trx_roll_must_shutdown()
mutex_enter(&recv_sys->mutex);
if (recv_sys->report(time)) {
- ulint n_trx = 0, n_rows = 0;
+ ulint n_trx = 0;
+ ulonglong n_rows = 0;
for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
t != NULL;
t = UT_LIST_GET_NEXT(trx_list, t)) {
@@ -765,9 +766,9 @@ trx_roll_must_shutdown()
}
ib_logf(IB_LOG_LEVEL_INFO,
"To roll back: " ULINTPF " transactions, "
- ULINTPF " rows", n_trx, n_rows);
+ "%llu rows", n_trx, n_rows);
sd_notifyf(0, "STATUS=To roll back: " ULINTPF " transactions, "
- ULINTPF " rows", n_trx, n_rows);
+ "%llu rows", n_trx, n_rows);
}
mutex_exit(&recv_sys->mutex);
diff --git a/storage/xtradb/trx/trx0undo.cc b/storage/xtradb/trx/trx0undo.cc
index 24d14e06080..0d5a0f55f0d 100644
--- a/storage/xtradb/trx/trx0undo.cc
+++ b/storage/xtradb/trx/trx0undo.cc
@@ -1070,9 +1070,11 @@ Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
-trx_undo_truncate_end(
+trx_undo_truncate_end_func(
/*=======================*/
- trx_t* trx, /*!< in: transaction whose undo log it is */
+#ifdef UNIV_DEBUG
+ const trx_t* trx, /*!< in: transaction whose undo log it is */
+#endif /* UNIV_DEBUG */
trx_undo_t* undo, /*!< in: undo log */
undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
@@ -1087,7 +1089,7 @@ trx_undo_truncate_end(
ut_ad(mutex_own(&(trx->rseg->mutex)));
for (;;) {
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
trunc_here = NULL;
@@ -1774,7 +1776,7 @@ trx_undo_assign_undo(
ut_ad(mutex_own(&(trx->undo_mutex)));
- mtr_start_trx(&mtr, trx);
+ mtr_start(&mtr);
mutex_enter(&rseg->mutex);