summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--client/mysqldump.c2
-rw-r--r--cmake/make_dist.cmake.in2
-rw-r--r--debian/mariadb-plugin-tokudb.install2
-rw-r--r--extra/mariabackup/encryption_plugin.cc50
-rw-r--r--extra/mariabackup/xtrabackup.cc31
-rw-r--r--include/myisamchk.h3
-rw-r--r--man/CMakeLists.txt7
-rw-r--r--man/mariabackup.116
-rw-r--r--man/mbstream.116
-rw-r--r--man/mysql_embedded.11
-rw-r--r--man/mysql_ldb.116
-rw-r--r--man/tokuft_logprint.1 (renamed from man/tokuft_logdump.1)2
-rw-r--r--man/wsrep_sst_mariabackup.116
-rw-r--r--man/wsrep_sst_rsync.14
-rw-r--r--man/wsrep_sst_rsync_wan.116
-rw-r--r--mysql-test/collections/10.0-compatible.list591
-rw-r--r--mysql-test/include/search_pattern_in_file.inc16
-rw-r--r--mysql-test/main/derived_cond_pushdown.result368
-rw-r--r--mysql-test/main/derived_cond_pushdown.test124
-rw-r--r--mysql-test/main/func_isnull.result20
-rw-r--r--mysql-test/main/func_isnull.test16
-rw-r--r--mysql-test/main/func_time.result6
-rw-r--r--mysql-test/main/func_time.test5
-rw-r--r--mysql-test/main/group_min_max.result17
-rw-r--r--mysql-test/main/group_min_max.test27
-rw-r--r--mysql-test/main/information_schema-big.result2
-rw-r--r--mysql-test/main/information_schema.result2
-rw-r--r--mysql-test/main/information_schema_all_engines.result8
-rw-r--r--mysql-test/main/mysql.result2
-rw-r--r--mysql-test/main/mysql.test5
-rw-r--r--mysql-test/main/mysql_not_windows.result2
-rw-r--r--mysql-test/main/mysql_not_windows.test7
-rw-r--r--mysql-test/main/mysqld--help.result6
-rw-r--r--mysql-test/main/opt_tvc.result30
-rw-r--r--mysql-test/main/opt_tvc.test2
-rw-r--r--mysql-test/main/range.result65
-rw-r--r--mysql-test/main/range.test57
-rw-r--r--mysql-test/main/range_debug.result24
-rw-r--r--mysql-test/main/range_debug.test30
-rw-r--r--mysql-test/main/range_mrr_icp.result65
-rw-r--r--mysql-test/main/subselect_extra_no_semijoin.result22
-rw-r--r--mysql-test/main/subselect_extra_no_semijoin.test31
-rw-r--r--mysql-test/main/subselect_mat.result6
-rw-r--r--mysql-test/main/subselect_sj_mat.result6
-rw-r--r--mysql-test/main/table_value_constr.result92
-rw-r--r--mysql-test/main/table_value_constr.test48
-rw-r--r--mysql-test/main/win.result4
-rw-r--r--mysql-test/main/win.test4
-rw-r--r--mysql-test/main/win_lead_lag.result11
-rw-r--r--mysql-test/main/win_lead_lag.test13
-rw-r--r--mysql-test/suite/compat/oracle/r/table_value_constr.result84
-rw-r--r--mysql-test/suite/compat/oracle/t/table_value_constr.test44
-rw-r--r--mysql-test/suite/funcs_1/r/is_check_constraints.result144
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_is.result10
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_is_embedded.result10
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_is.result50
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_is_embedded.result50
-rw-r--r--mysql-test/suite/funcs_1/t/is_check_constraints.test69
-rw-r--r--mysql-test/suite/galera/disabled.def7
-rw-r--r--mysql-test/suite/galera/r/MW-336.result100
-rw-r--r--mysql-test/suite/galera/r/MW-44.result15
-rw-r--r--mysql-test/suite/galera/r/galera_sst_rsync_data_dir.result396
-rw-r--r--mysql-test/suite/galera/r/galera_var_desync_on.result2
-rw-r--r--mysql-test/suite/galera/t/MW-336.test65
-rw-r--r--mysql-test/suite/galera/t/MW-44.test11
-rw-r--r--mysql-test/suite/galera/t/galera_sst_rsync_data_dir.cnf11
-rw-r--r--mysql-test/suite/galera/t/galera_sst_rsync_data_dir.test16
-rw-r--r--mysql-test/suite/galera/t/galera_var_desync_on.test7
-rw-r--r--mysql-test/suite/maria/concurrent.result33
-rw-r--r--mysql-test/suite/maria/concurrent.test28
-rw-r--r--mysql-test/suite/maria/maria.result6
-rw-r--r--mysql-test/suite/mariabackup/disabled.def1
-rw-r--r--mysql-test/suite/mariabackup/skip_innodb.opt1
-rw-r--r--mysql-test/suite/mariabackup/skip_innodb.result10
-rw-r--r--mysql-test/suite/mariabackup/skip_innodb.test12
-rw-r--r--mysql-test/suite/mariabackup/truncate_during_backup.result4
-rw-r--r--mysql-test/suite/mariabackup/truncate_during_backup.test19
-rw-r--r--mysql-test/suite/mariabackup/unsupported_redo.result2
-rw-r--r--mysql-test/suite/mariabackup/unsupported_redo.test35
-rw-r--r--mysql-test/suite/plugins/r/auth_ed25519.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_spatial.result16
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_spatial.test17
-rw-r--r--mysql-test/suite/sql_sequence/auto_increment.result30
-rw-r--r--mysql-test/suite/sql_sequence/auto_increment.test30
-rw-r--r--mysql-test/suite/sql_sequence/next.result15
-rw-r--r--mysql-test/suite/sql_sequence/next.test11
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result14
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result14
-rw-r--r--mysql-test/suite/vcol/r/index.result10
-rw-r--r--mysql-test/suite/vcol/t/index.test16
-rw-r--r--mysql-test/suite/versioning/r/truncate.result6
-rw-r--r--mysql-test/suite/versioning/t/truncate.test10
-rw-r--r--mysql-test/suite/wsrep/t/variables.test9
-rw-r--r--mysql-test/unstable-tests277
-rw-r--r--plugin/auth_ed25519/server_ed25519.c2
-rw-r--r--plugin/auth_pam/mapper/pam_user_map.c6
-rw-r--r--scripts/galera_recovery.sh3
-rwxr-xr-xscripts/wsrep_sst_common.sh6
-rw-r--r--scripts/wsrep_sst_rsync.sh105
-rw-r--r--sql/field.cc8
-rw-r--r--sql/field.h1
-rw-r--r--sql/filesort.cc4
-rw-r--r--sql/handler.cc43
-rw-r--r--sql/handler.h1
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_cmpfunc.cc19
-rw-r--r--sql/item_cmpfunc.h1
-rw-r--r--sql/item_windowfunc.h2
-rw-r--r--sql/key.cc3
-rw-r--r--sql/multi_range_read.cc13
-rw-r--r--sql/mysqld.cc22
-rw-r--r--sql/opt_range.cc26
-rw-r--r--sql/opt_range.h5
-rw-r--r--sql/opt_range_mrr.cc54
-rw-r--r--sql/protocol.cc8
-rw-r--r--sql/sql_class.h6
-rw-r--r--sql/sql_delete.cc14
-rw-r--r--sql/sql_lex.cc6
-rw-r--r--sql/sql_parse.cc1
-rw-r--r--sql/sql_select.cc18
-rw-r--r--sql/sql_sequence.cc5
-rw-r--r--sql/sql_show.cc52
-rw-r--r--sql/sql_statistics.h2
-rw-r--r--sql/sql_time.cc2
-rw-r--r--sql/sql_tvc.h2
-rw-r--r--sql/sql_union.cc2
-rw-r--r--sql/sql_yacc.yy42
-rw-r--r--sql/sql_yacc_ora.yy42
-rw-r--r--sql/sys_vars.cc10
-rw-r--r--sql/table.cc5
-rw-r--r--sql/wsrep_mysqld.h1
-rw-r--r--sql/wsrep_sst.cc50
-rw-r--r--sql/wsrep_var.cc10
-rw-r--r--storage/innobase/btr/btr0sea.cc2
-rw-r--r--storage/innobase/buf/buf0dump.cc4
-rw-r--r--storage/innobase/dict/dict0dict.cc2
-rw-r--r--storage/innobase/handler/ha_innodb.cc398
-rw-r--r--storage/innobase/handler/ha_innodb.h43
-rw-r--r--storage/innobase/handler/handler0alter.cc66
-rw-r--r--storage/innobase/include/log0recv.h35
-rw-r--r--storage/innobase/include/srv0srv.h6
-rw-r--r--storage/innobase/lock/lock0lock.cc4
-rw-r--r--storage/innobase/log/log0log.cc13
-rw-r--r--storage/innobase/log/log0recv.cc57
-rw-r--r--storage/innobase/page/page0cur.cc3
-rw-r--r--storage/innobase/row/row0import.cc3
-rw-r--r--storage/innobase/row/row0merge.cc11
-rw-r--r--storage/innobase/row/row0mysql.cc2
-rw-r--r--storage/innobase/row/row0purge.cc5
-rw-r--r--storage/innobase/row/row0vers.cc1
-rw-r--r--storage/innobase/srv/srv0srv.cc25
-rw-r--r--storage/innobase/trx/trx0purge.cc17
-rw-r--r--storage/innobase/trx/trx0undo.cc2
-rw-r--r--storage/maria/ha_maria.cc3
-rw-r--r--storage/maria/ma_check.c17
-rw-r--r--storage/maria/ma_commit.c7
-rw-r--r--storage/maria/ma_control_file.c4
-rw-r--r--storage/maria/ma_control_file.h2
-rw-r--r--storage/maria/ma_info.c6
-rw-r--r--storage/maria/ma_page.c3
-rw-r--r--storage/maria/ma_recovery.c11
-rw-r--r--storage/maria/maria_chk.c52
-rw-r--r--storage/maria/maria_def.h2
-rw-r--r--storage/myisam/mi_check.c10
-rw-r--r--storage/rocksdb/CMakeLists.txt8
-rw-r--r--storage/rocksdb/build_rocksdb.cmake13
-rw-r--r--storage/rocksdb/ha_rocksdb.cc1236
-rw-r--r--storage/rocksdb/ha_rocksdb.h53
-rw-r--r--storage/rocksdb/ha_rocksdb_proto.h7
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/combinations6
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/include/have_write_committed.inc3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result24
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace_sstfilewriter.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result40
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars.result26
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/bloomfilter_bulk_load.result15
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/bulk_load_sk.result229
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/cardinality.result17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/collation.result20
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/com_rpc_tx.result21
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/create_no_primary_key_table.result38
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/ddl_high_priority.result71
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/deadlock_tracking.result57
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/drop_table.result19
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/explicit_snapshot.result265
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/i_s_deadlock.result55
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/index_file_map.result3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/index_merge_rocksdb2.result52
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/information_schema.result1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/lock.result15
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/mysqldump.result5
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/percona_nonflushing_analyze_debug.result19
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/prefix_extractor_override.result7
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result24
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rocksdb_checksums.result27
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rc.result23
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rr.result23
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/secondary_key_update_lock.result18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/show_engine.result53
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/transaction.result17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/trx_info_rpl.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/update.result8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/use_direct_reads.result18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/validate_datadic.result5
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_sstfilewriter.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/autoinc_vars.test33
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/bloomfilter5-master.opt4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load-master.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load.test35
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/bulk_load_sk.test119
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/cardinality.test21
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test6
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/collation.test36
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.cnf4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.test87
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table.test44
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/deadlock_tracking.test76
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/disabled.def9
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/drop_table.test27
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot-master.opt1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot.test263
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/i_s_deadlock.test14
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/index_file_map.test3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/index_merge_rocksdb2-master.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/information_schema.test1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config-master.opt8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test10
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/lock.test22
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/percona_nonflushing_analyze_debug.test11
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/prefix_extractor_override.test14
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test3
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/rocksdb_checksums.test23
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/rocksdb_deadlock_detect.inc35
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/secondary_key_update_lock.test26
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/set_checkpoint.inc2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/show_engine.test13
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/transaction.test23
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/trx_info_rpl.test4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/update.test10
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/use_direct_reads.test37
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test25
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/combinations8
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_missing_columns_sk_update.result62
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_mts_dependency_unique_key_conflicts.result44
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_rocksdb_snapshot.result4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf13
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test69
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test64
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_stress/combinations5
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_block_cache_size_basic.result84
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_bulk_load_allow_sk_basic.result100
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_commit_time_batch_for_recovery_basic.result121
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_create_checkpoint_basic.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_debug_manual_compaction_delay_basic.result46
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_error_on_suboptimal_collation_basic.result7
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_manual_compaction_threads_basic.result93
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manifest_file_size_basic.result2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manual_compactions_basic.result57
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_row_locks_basic.result21
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_stats_recalc_rate_basic.result53
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_batch_max_bytes_basic.result4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_policy_basic.result15
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_block_cache_size_basic.test16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_bulk_load_allow_sk_basic.test18
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_commit_time_batch_for_recovery_basic.test20
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_create_checkpoint_basic.test2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_debug_manual_compaction_delay_basic.test16
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_error_on_suboptimal_collation_basic.test6
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_manual_compaction_threads_basic.test17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_manual_compactions_basic.test17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_row_locks_basic.test1
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_stats_recalc_rate_basic.test17
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_batch_max_bytes_basic.test4
-rw-r--r--storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_policy_basic.test17
-rw-r--r--storage/rocksdb/properties_collector.cc61
-rw-r--r--storage/rocksdb/properties_collector.h3
-rw-r--r--storage/rocksdb/rdb_cf_options.cc2
-rw-r--r--storage/rocksdb/rdb_comparator.h46
-rw-r--r--storage/rocksdb/rdb_datadic.cc6
-rw-r--r--storage/rocksdb/rdb_datadic.h5
-rw-r--r--storage/rocksdb/rdb_i_s.cc167
-rw-r--r--storage/rocksdb/rdb_i_s.h1
-rw-r--r--storage/rocksdb/rdb_index_merge.cc5
-rw-r--r--storage/rocksdb/rdb_perf_context.cc2
-rw-r--r--storage/rocksdb/rdb_psi.cc17
-rw-r--r--storage/rocksdb/rdb_psi.h10
-rw-r--r--storage/rocksdb/rdb_sst_info.cc4
-rw-r--r--storage/rocksdb/rdb_threads.h31
-rw-r--r--storage/rocksdb/rdb_utils.cc23
m---------storage/rocksdb/rocksdb0
299 files changed, 8441 insertions, 1671 deletions
diff --git a/.travis.yml b/.travis.yml
index 6142e76e1e0..95e0796099b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -111,8 +111,8 @@ addons:
apt:
sources:
- ubuntu-toolchain-r-test
- - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main'
- - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main'
+ - llvm-toolchain-trusty-5.0
+ - llvm-toolchain-trusty-6.0
packages: # make sure these include all compilers and all build dependencies (see list above)
- gcc-5
- g++-5
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 1958d5c173a..ae92adbc8ba 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -2129,7 +2129,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
{
create_stmt_ptr= (*row)[i];
create_stmt_len= lengths[i];
-#ifndef DBUG_OFF
+#ifdef DBUG_ASSERT_EXISTS
body_found= 1;
#endif
}
diff --git a/cmake/make_dist.cmake.in b/cmake/make_dist.cmake.in
index 43498f1f888..6fad17137fd 100644
--- a/cmake/make_dist.cmake.in
+++ b/cmake/make_dist.cmake.in
@@ -110,7 +110,7 @@ CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc.cc
CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.hh
${PACKAGE_DIR}/sql/sql_yacc_ora.hh COPYONLY)
CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/sql_yacc_ora.cc
- ${PACKAGE_DIR}/sql/sql_yacc_orac.cc COPYONLY)
+ ${PACKAGE_DIR}/sql/sql_yacc_ora.cc COPYONLY)
# Add documentation, if user has specified where to find them
IF(MYSQL_DOCS_LOCATION)
diff --git a/debian/mariadb-plugin-tokudb.install b/debian/mariadb-plugin-tokudb.install
index 8bbed858be4..40dd0e78c65 100644
--- a/debian/mariadb-plugin-tokudb.install
+++ b/debian/mariadb-plugin-tokudb.install
@@ -4,5 +4,5 @@ usr/bin/tokuft_logprint
usr/bin/tokuftdump
usr/lib/mysql/plugin/ha_tokudb.so
usr/share/doc/mariadb-server-10.4/README.md usr/share/doc/mariadb-plugin-tokudb/README.md
-usr/share/man/man1/tokuft_logdump.1
+usr/share/man/man1/tokuft_logprint.1
usr/share/man/man1/tokuftdump.1
diff --git a/extra/mariabackup/encryption_plugin.cc b/extra/mariabackup/encryption_plugin.cc
index 7f230256e7a..6335cdf3cd7 100644
--- a/extra/mariabackup/encryption_plugin.cc
+++ b/extra/mariabackup/encryption_plugin.cc
@@ -51,6 +51,36 @@ static void add_to_plugin_load_list(const char *plugin_def)
static char XTRABACKUP_EXE[] = "xtrabackup";
+/*
+ Read "plugin-load" value (encryption plugin) from backup-my.cnf during
+ prepare phase.
+ The value is stored during backup phase.
+*/
+static std::string get_encryption_plugin_from_cnf()
+{
+ FILE *f = fopen("backup-my.cnf", "r");
+ if (!f)
+ {
+ msg("cannot open backup-my.cnf for reading\n");
+ exit(EXIT_FAILURE);
+ }
+ char line[512];
+ std::string plugin_load;
+ while (fgets(line, sizeof(line), f))
+ {
+ if (strncmp(line, "plugin_load=", 12) == 0)
+ {
+ plugin_load = line + 12;
+ // remote \n at the end of string
+ plugin_load.resize(plugin_load.size() - 1);
+ break;
+ }
+ }
+ fclose(f);
+ return plugin_load;
+}
+
+
void encryption_plugin_backup_init(MYSQL *mysql)
{
MYSQL_RES *result;
@@ -78,7 +108,17 @@ void encryption_plugin_backup_init(MYSQL *mysql)
std::string plugin_load(name);
if (library)
+ {
+ /* Remove shared library suffixes, in case we'll prepare on different OS.*/
+ const char *extensions[] = { ".dll", ".so", 0 };
+ for (size_t i = 0; extensions[i]; i++)
+ {
+ const char *ext = extensions[i];
+ if (ends_with(library, ext))
+ library[strlen(library) - strlen(ext)] = 0;
+ }
plugin_load += std::string("=") + library;
+ }
oss << "plugin_load=" << plugin_load << std::endl;
@@ -140,14 +180,18 @@ extern int finalize_encryption_plugin(st_plugin_int *plugin);
void encryption_plugin_prepare_init(int argc, char **argv)
{
-
- if (!xb_plugin_load)
+ std::string plugin_load= get_encryption_plugin_from_cnf();
+ if (plugin_load.size())
+ {
+ msg("Loading encryption plugin from %s\n", plugin_load.c_str());
+ }
+ else
{
finalize_encryption_plugin(0);
return;
}
- add_to_plugin_load_list(xb_plugin_load);
+ add_to_plugin_load_list(plugin_load.c_str());
if (xb_plugin_dir)
strncpy(opt_plugin_dir, xb_plugin_dir, FN_REFLEN);
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index 8006404de15..80211084a76 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -359,9 +359,8 @@ struct ddl_tracker_t {
/* For DDL operation found in redo log, */
space_id_to_name_t id_to_name;
};
-const space_id_t REMOVED_SPACE_ID = ULINT_MAX;
-static ddl_tracker_t ddl_tracker;
+static ddl_tracker_t ddl_tracker;
/* Whether xtrabackup_binlog_info should be created on recovery */
static bool recover_binlog_info;
@@ -617,9 +616,8 @@ void backup_file_op(ulint space_id, const byte* flags,
/** Callback whenever MLOG_INDEX_LOAD happens.
-@param[in] space_id space id to check
-@return false */
-void backup_optimized_ddl_op(ulint space_id)
+@param[in] space_id space id to check */
+static void backup_optimized_ddl_op(ulint space_id)
{
// TODO : handle incremental
if (xtrabackup_incremental)
@@ -630,6 +628,15 @@ void backup_optimized_ddl_op(ulint space_id)
pthread_mutex_unlock(&backup_mutex);
}
+/** Callback whenever MLOG_TRUNCATE happens. */
+static void backup_truncate_fail()
+{
+ msg("mariabackup: Incompatible TRUNCATE operation detected.%s\n",
+ opt_lock_ddl_per_table
+ ? ""
+ : " Use --lock-ddl-per-table to lock all tables before backup.");
+}
+
/* ======== Date copying thread context ======== */
typedef struct {
@@ -702,7 +709,6 @@ enum options_xtrabackup
OPT_INNODB_LOG_CHECKSUMS,
OPT_XTRA_INCREMENTAL_FORCE_SCAN,
OPT_DEFAULTS_GROUP,
- OPT_PLUGIN_LOAD,
OPT_INNODB_ENCRYPT_LOG,
OPT_CLOSE_FILES,
OPT_CORE_FILE,
@@ -1209,7 +1215,7 @@ struct my_option xb_server_options[] =
"Use native AIO if supported on this platform.",
(G_PTR*) &srv_use_native_aio,
(G_PTR*) &srv_use_native_aio, 0, GET_BOOL, NO_ARG,
- FALSE, 0, 0, 0, 0, 0},
+ TRUE, 0, 0, 0, 0, 0},
{"innodb_page_size", OPT_INNODB_PAGE_SIZE,
"The universal page size of the database.",
(G_PTR*) &innobase_page_size, (G_PTR*) &innobase_page_size, 0,
@@ -1261,11 +1267,7 @@ struct my_option xb_server_options[] =
&xb_plugin_dir, &xb_plugin_dir,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- { "plugin-load", OPT_PLUGIN_LOAD, "encrypton plugin to load during 'prepare' phase.",
- &xb_plugin_load, &xb_plugin_load,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-
- { "innodb-encrypt-log", OPT_INNODB_ENCRYPT_LOG, "encrypton plugin to load",
+ { "innodb-encrypt-log", OPT_INNODB_ENCRYPT_LOG, "Whether to encrypt innodb log",
&srv_encrypt_log, &srv_encrypt_log,
0, GET_BOOL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
@@ -2703,7 +2705,7 @@ static os_thread_ret_t DECLARE_THREAD(log_copying_thread)(void*)
log_mutex_enter();
bool completed = metadata_to_lsn
- && metadata_to_lsn < log_copy_scanned_lsn;
+ && metadata_to_lsn <= log_copy_scanned_lsn;
log_mutex_exit();
if (completed) {
break;
@@ -4181,12 +4183,13 @@ fail_before_log_copying_thread_start:
/* copy log file by current position */
log_copy_scanned_lsn = checkpoint_lsn_start;
recv_sys->recovered_lsn = log_copy_scanned_lsn;
+ log_optimized_ddl_op = backup_optimized_ddl_op;
+ log_truncate = backup_truncate_fail;
if (xtrabackup_copy_logfile())
goto fail_before_log_copying_thread_start;
log_copying_stop = os_event_create(0);
- log_optimized_ddl_op = backup_optimized_ddl_op;
os_thread_create(log_copying_thread, NULL, &log_copying_thread_id);
/* FLUSH CHANGED_PAGE_BITMAPS call */
diff --git a/include/myisamchk.h b/include/myisamchk.h
index 1a9605aac46..67c8a20e0b8 100644
--- a/include/myisamchk.h
+++ b/include/myisamchk.h
@@ -100,12 +100,13 @@ typedef struct st_handler_check_param
time_t backup_time; /* To sign backup files */
ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];
double new_rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];
- uint out_flag, warning_printed, error_printed, note_printed, verbose;
+ uint out_flag, error_printed, verbose;
uint opt_sort_key, total_files, max_level;
uint key_cache_block_size, pagecache_block_size;
int tmpfile_createflag, err_count;
myf myf_rw;
uint16 language;
+ my_bool warning_printed, note_printed, wrong_trd_printed;
my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
my_bool retry_repair, force_sort, calc_checksum, static_row_size;
char temp_filename[FN_REFLEN];
diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt
index f5899577a47..9c34ede59c7 100644
--- a/man/CMakeLists.txt
+++ b/man/CMakeLists.txt
@@ -26,12 +26,15 @@ SET(MAN1_SERVER innochecksum.1 my_print_defaults.1 myisam_ftdump.1 myisamchk.1
mysqld_safe_helper.1 tokuftdump.1 wsrep_sst_common.1
wsrep_sst_mysqldump.1 wsrep_sst_rsync.1
wsrep_sst_xtrabackup-v2.1 wsrep_sst_xtrabackup.1
- galera_recovery.1 galera_new_cluster.1 tokuft_logdump.1)
+ galera_recovery.1 galera_new_cluster.1 tokuft_logprint.1
+ mysql_ldb.1
+ wsrep_sst_mariabackup.1 mbstream.1 mariabackup.1
+ wsrep_sst_rsync_wan.1)
SET(MAN8_SERVER mysqld.8)
SET(MAN1_CLIENT msql2mysql.1 mysql.1 mysql_find_rows.1 mysql_waitpid.1
mysqlaccess.1 mysqladmin.1 mysqlbinlog.1 mysqlcheck.1
mysqldump.1 mysqlimport.1 mysqlshow.1 mysqlslap.1
- mysql_plugin.1)
+ mysql_plugin.1 mysql_embedded.1)
SET(MAN1_DEVEL mysql_config.1)
SET(MAN1_TEST mysql-stress-test.pl.1 mysql-test-run.pl.1 mysql_client_test.1
mysqltest_embedded.1 mysql_client_test_embedded.1 my_safe_process.1)
diff --git a/man/mariabackup.1 b/man/mariabackup.1
new file mode 100644
index 00000000000..628c9cf74fa
--- /dev/null
+++ b/man/mariabackup.1
@@ -0,0 +1,16 @@
+'\" t
+.\"
+.TH "\FBMARIABACKUP\FR" "1" "9 August 2018" "MariaDB 10\&.1" "MariaDB Database System"
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH NAME
+mariabackup \- Backup tool
+.SH DESCRIPTION
+Use \fBmariabackup \-\-help\fR for details on usage\.
+.PP
+For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/
diff --git a/man/mbstream.1 b/man/mbstream.1
new file mode 100644
index 00000000000..2aba73fe400
--- /dev/null
+++ b/man/mbstream.1
@@ -0,0 +1,16 @@
+'\" t
+.\"
+.TH "\FBMBSTREAM\FR" "1" "9 August 2018" "MariaDB 10\&.1" "MariaDB Database System"
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH NAME
+mbstream \- Serialize/deserialize files in the XBSTREAM format
+.SH DESCRIPTION
+Use \fBmbstream \-\-help\fR for details on usage\.
+.PP
+For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/
diff --git a/man/mysql_embedded.1 b/man/mysql_embedded.1
new file mode 100644
index 00000000000..735c4e05ae0
--- /dev/null
+++ b/man/mysql_embedded.1
@@ -0,0 +1 @@
+.so man1/mysql.1
diff --git a/man/mysql_ldb.1 b/man/mysql_ldb.1
new file mode 100644
index 00000000000..5c08a1a14df
--- /dev/null
+++ b/man/mysql_ldb.1
@@ -0,0 +1,16 @@
+'\" t
+.\"
+.TH "\FBMYSQL_LDB\FR" "1" "9 August 2018" "MariaDB 10\&.2" "MariaDB Database System"
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH NAME
+mysql_ldb \- RocksDB tool
+.SH DESCRIPTION
+Use \fBmysql_ldb \-\-help\fR for details on usage\.
+.PP
+For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/
diff --git a/man/tokuft_logdump.1 b/man/tokuft_logprint.1
index f6cf08080f7..bc3b85a55d6 100644
--- a/man/tokuft_logdump.1
+++ b/man/tokuft_logprint.1
@@ -11,6 +11,6 @@
.SH NAME
tokuft_logprint \- Dump the log from stdin to stdout
.SH DESCRIPTION
-Use: Dump the log from stdin to stdout\.
+Use: Dump the log from stdin to stdout\. Use \fBtokuft_logprint \-\-help\fR for details on usage\.
.PP
For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/
diff --git a/man/wsrep_sst_mariabackup.1 b/man/wsrep_sst_mariabackup.1
new file mode 100644
index 00000000000..34ae4b6f82e
--- /dev/null
+++ b/man/wsrep_sst_mariabackup.1
@@ -0,0 +1,16 @@
+'\" t
+.\"
+.TH "\FBWSREP_SST_MARIABACKUP\FR" "1" "8 August 2018" "MariaDB 10\&.1" "MariaDB Database System"
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH NAME
+wsrep_sst_mariabackup \- mariabackup\-based state snapshot transfer
+.SH DESCRIPTION
+Use: mariabackup-based state snapshot transfer\.
+.PP
+For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/
diff --git a/man/wsrep_sst_rsync.1 b/man/wsrep_sst_rsync.1
index 30fcfbfba19..bbaeb64016e 100644
--- a/man/wsrep_sst_rsync.1
+++ b/man/wsrep_sst_rsync.1
@@ -1,6 +1,6 @@
'\" t
.\"
-.TH "\FBWSREP_SST_RSYNC\FR" "1" "9 May 2017" "MariaDB 10\&.3" "MariaDB Database System"
+.TH "\FBWSREP_SST_RSYNC\FR" "1" "9 August 2018" "MariaDB 10\&.3" "MariaDB Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -9,7 +9,7 @@
.\" disable justification (adjust text to left margin only)
.ad l
.SH NAME
-wsrep_sst_mysqldump \- rsync-based state snapshot transfer
+wsrep_sst_rsync \- rsync-based state snapshot transfer
.SH DESCRIPTION
Use: rsync-based state snapshot transfer\.
.PP
diff --git a/man/wsrep_sst_rsync_wan.1 b/man/wsrep_sst_rsync_wan.1
new file mode 100644
index 00000000000..6d465d554a8
--- /dev/null
+++ b/man/wsrep_sst_rsync_wan.1
@@ -0,0 +1,16 @@
+'\" t
+.\"
+.TH "\FBWSREP_SST_RSYNC_WAN\FR" "1" "9 August 2018" "MariaDB 10\&.1" "MariaDB Database System"
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH NAME
+wsrep_sst_rsync_wan \- rsync_wan (rsync with delta transfers)\-based state snapshot transfer
+.SH DESCRIPTION
+Use: rsync_wan\-based state snapshot transfer\.
+.PP
+For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/
diff --git a/mysql-test/collections/10.0-compatible.list b/mysql-test/collections/10.0-compatible.list
new file mode 100644
index 00000000000..415c74ab00c
--- /dev/null
+++ b/mysql-test/collections/10.0-compatible.list
@@ -0,0 +1,591 @@
+main.1st
+main.adddate_454
+main.almost_full
+main.alter_table_autoinc-5574
+main.alter_table_errors
+main.alter_table_mdev539_maria
+main.alter_table_mdev539_myisam
+main.alter_table_online
+main.alter_table_trans
+main.analyze
+main.analyze_stmt
+main.analyze_stmt_orderby
+main.analyze_stmt_slow_query_log
+main.ansi
+main.assign_key_cache
+main.auth_rpl
+main.auto_increment
+main.auto_increment_ranges_innodb
+main.auto_increment_ranges_myisam
+main.bad_frm_crash_5029
+main.bench_count_distinct
+main.bigint
+main.binary
+main.binary_to_hex
+main.blackhole
+main.blackhole_plugin
+main.bool
+main.bootstrap
+main.bug12427262
+main.bug13633383
+main.bug46760
+main.bug47671
+main.bulk_replace
+main.case
+main.change_user
+main.check_constraint_show
+main.client_xml
+main.comment_column
+main.comment_column2
+main.comment_index
+main.comments
+main.comment_table
+main.commit_1innodb
+main.compare
+main.compound
+main.contributors
+main.count_distinct
+main.count_distinct2
+main.create_drop_db
+main.create_drop_event
+main.create_drop_function
+main.create_drop_index
+main.create_drop_procedure
+main.create_drop_server
+main.create_drop_trigger
+main.create_drop_user
+main.create_drop_view
+main.create_not_windows
+main.create_select_tmp
+main.create-uca
+main.create_user
+main.create_w_max_indexes_64
+main.ctype_ascii
+main.ctype_big5
+main.ctype_binary
+main.ctype_collate
+main.ctype_cp1250_ch
+main.ctype_cp1251
+main.ctype_cp850
+main.ctype_cp932
+main.ctype_cp932_binlog_row
+main.ctype_cp932_binlog_stm
+main.ctype_create
+main.ctype_eucjpms
+main.ctype_euckr
+main.ctype_filename
+main.ctype_filesystem
+main.ctype_gb2312
+main.ctype_gbk
+main.ctype_gbk_binlog
+main.ctype_gbk_export_import
+main.ctype_hebrew
+main.ctype_latin1
+main.ctype_latin1_de
+main.ctype_latin2
+main.ctype_latin2_ch
+main.ctype_ldml
+main.ctype_many
+main.ctype_mb
+main.ctype_nopad_8bit
+main.ctype_partitions
+main.ctype_recoding
+main.ctype_sjis
+main.ctype_swe7
+main.ctype_tis620
+main.ctype_uca
+main.ctype_uca_innodb
+main.ctype_uca_partitions
+main.ctype_ucs
+main.ctype_ucs2_def
+main.ctype_ucs2_query_cache
+main.ctype_ucs2_uca
+main.ctype_ujis
+main.ctype_ujis_ucs2
+main.ctype_upgrade
+main.ctype_utf16
+main.ctype_utf16_def
+main.ctype_utf16le
+main.ctype_utf16_uca
+main.ctype_utf32
+main.ctype_utf32_uca
+main.ctype_utf8
+main.ctype_utf8mb4
+main.ctype_utf8mb4_heap
+main.ctype_utf8mb4_innodb
+main.ctype_utf8mb4_myisam
+main.ctype_utf8mb4_uca
+main.ctype_utf8_uca
+main.date_formats
+main.datetime_456
+main.default_storage_engine
+main.delete
+main.delete_returning
+main.deprecated_features
+main.derived_cond_pushdown
+main.derived_opt
+main.derived_view
+main.distinct
+main.drop-no_root
+main.dyncol
+main.empty_server_name-8224
+main.empty_table
+main.endspace
+main.enforce_storage_engine_opt
+main.errors
+main.events_2
+main.events_logs_tests
+main.events_microsec
+main.events_restart
+main.events_scheduling
+main.events_slowlog
+main.events_trans
+main.execution_constants
+main.explain
+main.explain_json
+main.explain_json_format_partitions
+main.explain_json_innodb
+main.explain_non_select
+main.ext_key_noPK_6794
+main.fast_prefix_index_fetch_innodb
+main.features
+main.filesort_bad_i_s-7585
+main.flush2
+main.foreign_key
+main.frm_bad_row_type-7333
+main.fulltext
+main.fulltext2
+main.fulltext3
+main.fulltext_cache
+main.fulltext_charsets
+main.fulltext_derived_4257
+main.fulltext_derived_4316
+main.fulltext_distinct
+main.fulltext_left_join
+main.fulltext_multi
+main.fulltext_order_by
+main.fulltext_update
+main.fulltext_var
+main.func_analyse
+main.func_concat
+main.func_crypt
+main.func_date_add
+main.func_default
+main.func_des_encrypt
+main.func_digest
+main.func_encrypt
+main.func_encrypt_ucs2
+main.func_equal
+main.func_gconcat
+main.func_group_innodb
+main.func_hybrid_type
+main.func_if
+main.func_in
+main.func_isnull
+main.func_like
+main.func_math
+main.func_op
+main.func_regexp
+main.func_regexp_pcre
+main.func_rollback
+main.func_sapdb
+main.func_set
+main.func_system
+main.func_test
+main.func_time
+main.func_time_hires
+main.func_timestamp
+main.function_defaults
+main.function_defaults_innodb
+main.gcc296
+main.get_diagnostics
+main.gis
+main.gis2
+main.gis-alter_table_online
+main.gis-precise
+main.gis-rt-precise
+main.gis-rtree
+main.grant_4332
+main.greedy_optimizer
+main.group_by
+main.group_by_innodb
+main.group_by_null
+main.group_min_max
+main.group_min_max_innodb
+main.handler_read_last
+main.handlersocket
+main.having
+main.help
+main.host_cache_size_functionality
+main.huge_frm-6224
+main.implicit_char_to_num_conversion
+main.implicit_commit
+main.in_datetime_241
+main.index_intersect
+main.index_intersect_innodb
+main.index_merge_innodb
+main.index_merge_myisam
+main.information_schema2
+main.information_schema_all_engines
+main.information_schema_chmod
+main.information_schema_inno
+main.information_schema_parameters
+main.information_schema_part
+main.information_schema_routines
+main.information_schema_stats
+main.init_file
+main.init_file_longline_3816
+main.init_file_set_password-7656
+main.innodb_bug878769
+main.innodb_ext_key
+main.innodb_group
+main.innodb_icp
+main.innodb_ignore_builtin
+main.innodb_mrr_cpk
+main.innodb_utf8
+main.insert
+main.insert_innodb
+main.insert_select
+main.insert_update
+main.insert_update_autoinc-7150
+main.join
+main.join_cache
+main.join_crash
+main.join_nested
+main.join_nested_jcl6
+main.join_optimizer
+main.join_outer
+main.join_outer_innodb
+main.join_outer_jcl6
+main.key
+main.key_cache
+main.key_diff
+main.key_primary
+main.keyread
+main.keywords
+main.last_value
+main.limit
+main.limit_rows_examined
+main.loaddata_autocom_innodb
+main.locale
+main.log_errchk
+main.log_slow
+main.log_state_bug33693
+main.log_tables_upgrade
+main.long_tmpdir
+main.lowercase_mixed_tmpdir
+main.lowercase_table
+main.lowercase_table5
+main.lowercase_table_grant
+main.lowercase_table_qcache
+main.lowercase_utf8
+main.lowercase_view
+main.mdev13607
+main.mdev_14586
+main.mdev316
+main.mdl
+main.merge_innodb
+main.merge_mmap
+main.metadata
+main.mix2_myisam_ucs2
+main.mrr_derived_crash_4610
+main.mrr_icp_extra
+main.multi_statement
+main.multi_update2
+main.multi_update_innodb
+main.multi_update_tiny_hash
+main.myisam-blob
+main.myisam_enable_keys-10506
+main.myisam_explain_non_select_all
+main.myisam_icp
+main.myisam_mrr
+main.myisampack
+main.myisam-system
+main.mysql
+main.mysql5613mysql
+main.mysql57_virtual
+main.mysqladmin
+main.mysql_binary_mode
+main.mysqlcheck
+main.mysql_comments
+main.mysql_cp932
+main.mysqld--defaults-file
+main.mysqld--help
+main.mysqld_help_crash-9183
+main.mysqld_option_err
+main.mysqldump-compat
+main.mysqldump-nl
+main.mysqldump-no-binlog
+main.mysqldump_restore
+main.mysql_not_windows
+main.mysql_protocols
+main.mysqlshow
+main.mysqlslap
+main.mysqltest_256
+main.mysqltest_cont_on_error
+main.mysql_tzinfo_to_sql_symlink
+main.mysql_upgrade_noengine
+main.mysql_upgrade_no_innodb
+main.mysql_upgrade_ssl
+main.mysql_upgrade_view
+main.negation_elimination
+main.no_binlog
+main.no_password_column-mdev-11170
+main.null
+main.null_key
+main.odbc
+main.olap
+main.old-mode
+main.order_by
+main.order_by_innodb
+main.order_by-mdev-10122
+main.order_by_optimizer
+main.order_by_optimizer_innodb
+main.order_by_sortkey
+main.order_by_zerolength-4285
+main.order_fill_sortbuf
+main.outfile_loaddata
+main.parser
+main.parser_bug21114_innodb
+main.parser_precedence
+main.parser_stack
+main.partition
+main.partition_binlog
+main.partition_binlog_stmt
+main.partition_blackhole
+main.partition_bug18198
+main.partition_cache_innodb
+main.partition_cache_myisam
+main.partition_charset
+main.partition_column
+main.partition_column_prune
+main.partition_datatype
+main.partition_disabled
+main.partition_error
+main.partition_example
+main.partition_exchange
+main.partition_explicit_prune
+main.partition_hash
+main.partition_key_cache
+main.partition_list
+main.partition_mgm
+main.partition_mgm_err
+main.partition_mgm_err2
+main.partition_myisam
+main.partition_not_blackhole
+main.partition_not_windows
+main.partition_order
+main.partition_pruning
+main.partition_range
+main.partition_rename_longfilename
+main.partition_truncate
+main.partition_utf8
+main.perror
+main.plugin
+main.plugin_auth_qa
+main.plugin_auth_qa_2
+main.plugin_auth_qa_3
+main.plugin_innodb
+main.plugin_load
+main.plugin_loaderr
+main.plugin_load_option
+main.plugin_maturity
+main.preload
+main.profiling
+main.progress_976225
+main.ps_10nestset
+main.ps_11bugs
+main.ps_1general
+main.ps_2myisam
+main.ps_3innodb
+main.ps_4heap
+main.ps_5merge
+main.ps_change_master
+main.ps_ddl1
+main.ps_max_subselect-5113
+main.ps_not_windows
+main.query_cache
+main.query_cache_innodb
+main.query_cache_merge
+main.query_cache_with_views
+main.range
+main.range_innodb
+main.range_mrr_icp
+main.range_vs_index_merge
+main.range_vs_index_merge_innodb
+main.renamedb
+main.reopen_temp_table
+main.repair
+main.repair_symlink-5543
+main.replace
+main.rollback
+main.round
+main.row
+main.row-checksum
+main.row-checksum-old
+main.rowid_order_innodb
+main.rpl_mysqldump_slave
+main.second_frac-9175
+main.select
+main.select_found
+main.selectivity
+main.selectivity_innodb
+main.selectivity_no_engine
+main.select_jcl6
+main.select_pkeycache
+main.select_safe
+main.servers
+main.set_password
+main.set_statement_notembedded
+main.set_statement_notembedded_binlog
+main.show
+main.show_bad_definer-5553
+main.show_create_user
+main.show_function_with_pad_char_to_full_length
+main.show_profile
+main.show_row_order-9226
+main.sighup-6580
+main.signal
+main.signal_demo1
+main.signal_demo2
+main.signal_demo3
+main.signal_sqlmode
+main.single_delete_update
+main.single_delete_update_innodb
+main.skip_grants
+main.skip_log_bin
+main.sp-big
+main.sp-bugs
+main.sp-bugs2
+main.sp-destruct
+main.sp-dynamic
+main.sp-error
+main.sp-fib
+main.sp_gis
+main.sp-group
+main.sp_missing_4665
+main.sp-no-code
+main.sp-prelocking
+main.sp_stress_case
+main.sp_trans
+main.sp_trans_log
+main.sp-ucs2
+main.sp-vars
+main.ssl_7937
+main.ssl_8k_key
+main.ssl_and_innodb
+main.ssl_ca
+main.ssl_cert_verify
+main.ssl_connect
+main.ssl_crl_clients
+main.stack-crash
+main.statistics
+main.statistics_index_crash-7362
+main.stat_tables
+main.stat_tables_disabled
+main.stat_tables_innodb
+main.stat_tables_partition
+main.stat_tables_repl
+main.strict
+main.strict_autoinc_1myisam
+main.strict_autoinc_2innodb
+main.strict_autoinc_3heap
+main.str_to_datetime_457
+main.subselect2
+main.subselect3
+main.subselect3_jcl6
+main.subselect4
+main.subselect_cache
+main.subselect-crash_15755
+main.subselect_exists2in
+main.subselect_exists2in_costmat
+main.subselect_extra
+main.subselect_extra_no_semijoin
+main.subselect_gis
+main.subselect_innodb
+main.subselect_mat
+main.subselect_mat_cost
+main.subselect_mat_cost_bugs
+main.subselect_notembedded
+main.subselect_nulls
+main.subselect_partial_match
+main.subselect_sj2
+main.subselect_sj2_jcl6
+main.subselect_sj2_mat
+main.subselect_sj_aria
+main.subselect_sj_mat
+main.subselect_sj_nonmerged
+main.sum_distinct
+main.sysdate_is_now
+main.system_mysql_db
+main.system_mysql_db_refs
+main.table_elim
+main.table_elim_debug
+main.table_keyinfo-6838
+main.tablelock
+main.table_options
+main.table_options-5867
+main.temporal_literal
+main.temporal_scale_4283
+main.temp_table_frm
+main.timezone
+main.timezone2
+main.timezone3
+main.timezone4
+main.tmp_table_count-7586
+main.trigger_no_defaults-11698
+main.trigger_null-8605
+main.truncate
+main.truncate_badse
+main.truncate-stale-6500
+main.type_binary
+main.type_bit
+main.type_bit_innodb
+main.type_blob
+main.type_datetime_hires
+main.type_decimal
+main.type_enum
+main.type_float
+main.type_int
+main.type_nchar
+main.type_newdecimal
+main.type_num
+main.type_num_innodb
+main.type_ranges
+main.type_set
+main.type_temporal_innodb
+main.type_temporal_mysql56
+main.type_time
+main.type_time_6065
+main.type_time_hires
+main.type_timestamp_hires
+main.type_uint
+main.type_varchar
+main.type_year
+main.update_ignore_216
+main.update_innodb
+main.upgrade
+main.user_var
+main.varbinary
+main.variables_community
+main.view_alias
+main.warnings_engine_disabled
+main.win_avg
+main.win_big
+main.win_big-mdev-10092
+main.win_big-mdev-11697
+main.win_bit
+main.win_empty_over
+main.win_first_last_value
+main.win_insert_select
+main.win_i_s
+main.win_lead_lag
+main.win_min_max
+main.win_nth_value
+main.win_orderby
+main.win_percent_cume
+main.win_rank
+main.win_sum
+main.xa_binlog
+main.xml
+main.xtradb_mrr
diff --git a/mysql-test/include/search_pattern_in_file.inc b/mysql-test/include/search_pattern_in_file.inc
index 21192b55efb..6bead628fb0 100644
--- a/mysql-test/include/search_pattern_in_file.inc
+++ b/mysql-test/include/search_pattern_in_file.inc
@@ -18,6 +18,11 @@
# Optionally, SEARCH_ABORT can be set to "FOUND" or "NOT FOUND" and this
# will abort if the search result doesn't match the requested one.
#
+# Optionally, SEARCH_OUTPUT can be set to control the format of output.
+# Supported formats:
+# - (default) : "FOUND n /pattern/ in FILE " or "NOT FOUND ..."
+# - "matches" : Each match is printed, on a separate line
+#
# In case of
# - SEARCH_FILE and/or SEARCH_PATTERN is not set
# - SEARCH_FILE cannot be opened
@@ -75,7 +80,14 @@ perl;
my @matches=($content =~ m/$search_pattern/gs);
my $res=@matches ? "FOUND " . scalar(@matches) : "NOT FOUND";
$ENV{SEARCH_FILE} =~ s{^.*?([^/\\]+)$}{$1};
- print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n";
+
+ if ($ENV{SEARCH_OUTPUT} eq "matches") {
+ foreach (@matches) {
+ print $_ . "\n";
+ }
+ } else {
+ print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n";
+ }
die "$ENV{SEARCH_ABORT}\n"
- if $ENV{SEARCH_ABORT} && $res =~ /^$ENV{SEARCH_ABORT}/;
+ if $ENV{SEARCH_ABORT} && $res =~ /^$ENV{SEARCH_ABORT}/;
EOF
diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result
index 2c983e3de3e..a1120ba6de7 100644
--- a/mysql-test/main/derived_cond_pushdown.result
+++ b/mysql-test/main/derived_cond_pushdown.result
@@ -16027,6 +16027,374 @@ a
aa
DROP FUNCTION f1;
#
+# MDEV-17011: condition pushdown into materialized derived used
+# in INSERT SELECT, multi-table UPDATE and DELETE
+#
+CREATE TABLE t1 (a int ,b int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+(1, 1), (1, 2), (2, 1), (2, 2), (3,1), (3,3), (4,2);
+CREATE TABLE t2 (a int) ENGINE MYISAM;
+INSERT INTO t2 VALUES
+(3), (7), (1), (4), (1);
+CREATE TABLE t3 (a int, b int) ENGINE MYISAM;
+EXPLAIN FORMAT=JSON INSERT INTO t3
+SELECT * FROM (SELECT a, count(*) as c FROM t1 GROUP BY a) t WHERE a<=2;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 7,
+ "filtered": 100,
+ "attached_condition": "t.a <= 2",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "filesort": {
+ "sort_key": "t1.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 7,
+ "filtered": 100,
+ "attached_condition": "t1.a <= 2"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+INSERT INTO t3
+SELECT * FROM (SELECT a, count(*) as c FROM t1 GROUP BY a) t WHERE a<=2;
+SELECT * FROM t3;
+a b
+1 2
+2 2
+EXPLAIN FORMAT=JSON UPDATE t2, (SELECT a, count(*) as c FROM t1 GROUP BY a) t SET t2.a=t.c+10
+WHERE t2.a= t.c and t.a>=3;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "t2.a is not null"
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "8",
+ "used_key_parts": ["c"],
+ "ref": ["test.t2.a"],
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "t2.a = t.c and t.a >= 3",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "filesort": {
+ "sort_key": "t1.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 7,
+ "filtered": 100,
+ "attached_condition": "t1.a >= 3"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+UPDATE t2, (SELECT a, count(*) as c FROM t1 GROUP BY a) t SET t2.a=t.c+10
+WHERE t2.a= t.c and t.a>=3;
+SELECT * FROM t2;
+a
+3
+7
+11
+4
+11
+EXPLAIN FORMAT=JSON DELETE t2 FROM t2, (SELECT a, count(*) as c FROM t1 GROUP BY a) t
+WHERE t2.a= t.c+9 and t.a=2;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ },
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 7,
+ "filtered": 100,
+ "attached_condition": "t.a = 2 and t2.a = t.c + 9",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 7,
+ "filtered": 100,
+ "attached_condition": "t1.a = 2"
+ }
+ }
+ }
+ }
+ }
+}
+DELETE t2 FROM t2, (SELECT a, count(*) as c FROM t1 GROUP BY a) t
+WHERE t2.a= t.c+9 and t.a=2;
+SELECT * FROM t2;
+a
+3
+7
+4
+DROP TABLE t1,t2,t3;
+#
+# MDEV-16765: pushdown condition with the CASE structure
+# defined with Item_cond item
+#
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,2), (3,4), (2,3);
+SELECT *
+FROM
+(
+SELECT CASE WHEN ((tab2.max_a=1) OR (tab2.max_a=2))
+THEN 1 ELSE 0 END AS max_a,b
+FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+max_a b
+1 2
+1 3
+EXPLAIN FORMAT=JSON SELECT *
+FROM
+(
+SELECT CASE WHEN ((tab2.max_a=1) OR (tab2.max_a=2))
+THEN 1 ELSE 0 END AS max_a,b
+FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "case when (tab2.max_a = 1 or tab2.max_a = 2) then 1 else 0 end = 1",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "case when (max_a = 1 or max_a = 2) then 1 else 0 end = 1",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT *
+FROM
+(
+SELECT CASE WHEN ((tab2.max_a=1) OR ((tab2.max_a>2) AND (tab2.max_a<4)))
+THEN 1 ELSE 0 END AS max_a,b
+FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+max_a b
+1 2
+1 4
+EXPLAIN FORMAT=JSON SELECT *
+FROM
+(
+SELECT CASE WHEN ((tab2.max_a=1) OR ((tab2.max_a>2) AND (tab2.max_a<4)))
+THEN 1 ELSE 0 END AS max_a,b
+FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "case when (tab2.max_a = 1 or tab2.max_a > 2 and tab2.max_a < 4) then 1 else 0 end = 1",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "case when (max_a = 1 or max_a > 2 and max_a < 4) then 1 else 0 end = 1",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT *
+FROM
+(
+SELECT CASE WHEN ((tab2.max_a>1) AND ((tab2.max_a=2) OR (tab2.max_a>2)))
+THEN 1 ELSE 0 END AS max_a,b
+FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+max_a b
+1 3
+1 4
+EXPLAIN FORMAT=JSON SELECT *
+FROM
+(
+SELECT CASE WHEN ((tab2.max_a>1) AND ((tab2.max_a=2) OR (tab2.max_a>2)))
+THEN 1 ELSE 0 END AS max_a,b
+FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "case when (tab2.max_a > 1 and (tab2.max_a = 2 or tab2.max_a > 2)) then 1 else 0 end = 1",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "case when (max_a > 1 and (max_a = 2 or max_a > 2)) then 1 else 0 end = 1",
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT *
+FROM
+(
+SELECT CASE WHEN ((tab2.b=2) OR (tab2.b=4))
+THEN 1 ELSE 0 END AS max_a,b
+FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+max_a b
+1 2
+1 4
+EXPLAIN FORMAT=JSON SELECT *
+FROM
+(
+SELECT CASE WHEN ((tab2.b=2) OR (tab2.b=4))
+THEN 1 ELSE 0 END AS max_a,b
+FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "case when (tab2.b = 2 or tab2.b = 4) then 1 else 0 end = 1",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "filesort": {
+ "sort_key": "t1.b",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "case when (t1.b = 2 or t1.b = 4) then 1 else 0 end = 1"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+DROP TABLE t1;
+#
+# MDEV-16803: pushdown condition with IN predicate in the derived table
+# defined with several SELECT statements
+#
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,2),(3,2),(1,1);
+SELECT * FROM
+(
+SELECT a,b,1 as c
+FROM t1
+UNION ALL
+SELECT a,b,2 as c
+FROM t1
+) AS tab
+WHERE ((a,b) IN ((1,2),(3,2)));
+a b c
+1 2 1
+3 2 1
+1 2 2
+3 2 2
+DROP TABLE t1;
+# Start of 10.3 tests
+#
# MDEV-16801: splittable materialized derived/views with
# one grouping field from table without keys
#
diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test
index b75c56e9ff2..61541d2cdf5 100644
--- a/mysql-test/main/derived_cond_pushdown.test
+++ b/mysql-test/main/derived_cond_pushdown.test
@@ -2988,6 +2988,130 @@ SELECT a FROM (SELECT "aa" a) t WHERE f1(t.a, (SELECT MAX('aa') FROM DUAL LIMIT
DROP FUNCTION f1;
--echo #
+--echo # MDEV-17011: condition pushdown into materialized derived used
+--echo # in INSERT SELECT, multi-table UPDATE and DELETE
+--echo #
+
+CREATE TABLE t1 (a int ,b int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+ (1, 1), (1, 2), (2, 1), (2, 2), (3,1), (3,3), (4,2);
+
+CREATE TABLE t2 (a int) ENGINE MYISAM;
+INSERT INTO t2 VALUES
+ (3), (7), (1), (4), (1);
+
+CREATE TABLE t3 (a int, b int) ENGINE MYISAM;
+
+let $q1=
+INSERT INTO t3
+SELECT * FROM (SELECT a, count(*) as c FROM t1 GROUP BY a) t WHERE a<=2;
+
+eval EXPLAIN FORMAT=JSON $q1;
+eval $q1;
+
+SELECT * FROM t3;
+
+let $q2=
+UPDATE t2, (SELECT a, count(*) as c FROM t1 GROUP BY a) t SET t2.a=t.c+10
+ WHERE t2.a= t.c and t.a>=3;
+
+eval EXPLAIN FORMAT=JSON $q2;
+eval $q2;
+
+SELECT * FROM t2;
+
+let $q3=
+DELETE t2 FROM t2, (SELECT a, count(*) as c FROM t1 GROUP BY a) t
+ WHERE t2.a= t.c+9 and t.a=2;
+
+eval EXPLAIN FORMAT=JSON $q3;
+eval $q3;
+
+SELECT * FROM t2;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # MDEV-16765: pushdown condition with the CASE structure
+--echo # defined with Item_cond item
+--echo #
+
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,2), (3,4), (2,3);
+
+LET $query=
+SELECT *
+FROM
+(
+ SELECT CASE WHEN ((tab2.max_a=1) OR (tab2.max_a=2))
+ THEN 1 ELSE 0 END AS max_a,b
+ FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+EVAL $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT *
+FROM
+(
+ SELECT CASE WHEN ((tab2.max_a=1) OR ((tab2.max_a>2) AND (tab2.max_a<4)))
+ THEN 1 ELSE 0 END AS max_a,b
+ FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+EVAL $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT *
+FROM
+(
+ SELECT CASE WHEN ((tab2.max_a>1) AND ((tab2.max_a=2) OR (tab2.max_a>2)))
+ THEN 1 ELSE 0 END AS max_a,b
+ FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+EVAL $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT *
+FROM
+(
+ SELECT CASE WHEN ((tab2.b=2) OR (tab2.b=4))
+ THEN 1 ELSE 0 END AS max_a,b
+ FROM (SELECT MAX(a) as max_a,b FROM t1 GROUP BY t1.b) AS tab2
+) AS tab1
+WHERE (tab1.max_a=1);
+EVAL $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-16803: pushdown condition with IN predicate in the derived table
+--echo # defined with several SELECT statements
+--echo #
+
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,2),(3,2),(1,1);
+
+SELECT * FROM
+(
+ SELECT a,b,1 as c
+ FROM t1
+ UNION ALL
+ SELECT a,b,2 as c
+ FROM t1
+) AS tab
+WHERE ((a,b) IN ((1,2),(3,2)));
+
+DROP TABLE t1;
+
+--echo # Start of 10.3 tests
+
+--echo #
--echo # MDEV-16801: splittable materialized derived/views with
--echo # one grouping field from table without keys
--echo #
diff --git a/mysql-test/main/func_isnull.result b/mysql-test/main/func_isnull.result
index 15d87997e29..8cbd528f2de 100644
--- a/mysql-test/main/func_isnull.result
+++ b/mysql-test/main/func_isnull.result
@@ -106,5 +106,25 @@ Note 1003 select `test`.`t2`.`d1` AS `d1`,`test`.`t1`.`d1` AS `d1` from `test`.`
DROP VIEW v1;
DROP TABLE t1,t2;
#
+# MDEV-15475: Assertion `!table || (!table->read_set ||
+# bitmap_is_set(table->read_set, field_index))'
+# failed on EXPLAIN EXTENDED with constant table and view
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=MyISAM;
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1);
+EXPLAIN EXTENDED SELECT ISNULL(pk) FROM v1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select /*always not null*/ 1 is null AS `ISNULL(pk)` from dual
+EXPLAIN EXTENDED SELECT IFNULL(pk,0) FROM v1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select ifnull(1,0) AS `IFNULL(pk,0)` from dual
+DROP VIEW v1;
+DROP TABLE t1;
+#
# End of 5.5 tests
#
diff --git a/mysql-test/main/func_isnull.test b/mysql-test/main/func_isnull.test
index 4c59fa3cbe8..7d1a7e83a1a 100644
--- a/mysql-test/main/func_isnull.test
+++ b/mysql-test/main/func_isnull.test
@@ -83,6 +83,22 @@ SELECT * FROM t2 LEFT JOIN v1 ON t2.d1=v1.d1 WHERE v1.d1 IS NULL;
DROP VIEW v1;
DROP TABLE t1,t2;
+
+--echo #
+--echo # MDEV-15475: Assertion `!table || (!table->read_set ||
+--echo # bitmap_is_set(table->read_set, field_index))'
+--echo # failed on EXPLAIN EXTENDED with constant table and view
+--echo #
+
+CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=MyISAM;
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1);
+EXPLAIN EXTENDED SELECT ISNULL(pk) FROM v1;
+EXPLAIN EXTENDED SELECT IFNULL(pk,0) FROM v1;
+# Cleanup
+DROP VIEW v1;
+DROP TABLE t1;
+
--echo #
--echo # End of 5.5 tests
--echo #
diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result
index b6f9ca8e628..840db182fe7 100644
--- a/mysql-test/main/func_time.result
+++ b/mysql-test/main/func_time.result
@@ -2805,6 +2805,11 @@ SEC_TO_TIME(MAKEDATE(0,RAND(~0)))
838:59:59
Warnings:
Warning 1292 Truncated incorrect seconds value: '20000101'
+SELECT PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli'));
+PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli'))
+24257
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: '-3S\xFA\xDE?\x00\x00\xCA\xB3\xEEE\xA4\xD1\xC1\xA8'
#
# End of 5.5 tests
#
@@ -3578,6 +3583,7 @@ DROP TABLE t1;
#
# MDEV-15363 Wrong result for CAST(LAST_DAY(TIME'00:00:00') AS TIME)
#
+set timestamp=unix_timestamp('2018-08-02 10:10:10');
SELECT
LAST_DAY(TIME'00:00:00') AS c1,
CAST(CAST(LAST_DAY(TIME'00:00:00') AS DATE) AS TIME) AS c2,
diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test
index b03c14fb8ba..aebe3df761f 100644
--- a/mysql-test/main/func_time.test
+++ b/mysql-test/main/func_time.test
@@ -1705,6 +1705,10 @@ DO TO_DAYS(SEC_TO_TIME(TIME(CEILING(UUID()))));
DO TO_DAYS(SEC_TO_TIME(MAKEDATE('',RAND(~('')))));
SELECT SEC_TO_TIME(MAKEDATE(0,RAND(~0)));
+#
+# MDEV-16810 AddressSanitizer: stack-buffer-overflow in int10_to_str
+#
+SELECT PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli'));
--echo #
--echo # End of 5.5 tests
@@ -2158,6 +2162,7 @@ DROP TABLE t1;
--echo # MDEV-15363 Wrong result for CAST(LAST_DAY(TIME'00:00:00') AS TIME)
--echo #
+set timestamp=unix_timestamp('2018-08-02 10:10:10');
SELECT
LAST_DAY(TIME'00:00:00') AS c1,
CAST(CAST(LAST_DAY(TIME'00:00:00') AS DATE) AS TIME) AS c2,
diff --git a/mysql-test/main/group_min_max.result b/mysql-test/main/group_min_max.result
index 36a44b05817..b3b660c4170 100644
--- a/mysql-test/main/group_min_max.result
+++ b/mysql-test/main/group_min_max.result
@@ -3893,5 +3893,22 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index a a 13 NULL 2 Using where; Using index
drop table t1;
#
+# MDEV-15433: Optimizer does not use group by optimization with distinct
+#
+CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, a INT NOT NULL, KEY(a));
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+EXPLAIN SELECT DISTINCT a FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL a 4 NULL 5 Using index for group-by
+SELECT DISTINCT a FROM t1;
+a
+1
+2
+3
+4
+drop table t1;
+#
# End of 10.1 tests
#
diff --git a/mysql-test/main/group_min_max.test b/mysql-test/main/group_min_max.test
index b0bc42d7f8c..adad9073235 100644
--- a/mysql-test/main/group_min_max.test
+++ b/mysql-test/main/group_min_max.test
@@ -1609,5 +1609,32 @@ explain select min(a) from t1 where a between "abbbbbbbbbbbbbbbbbbbb" and "Cafe2
drop table t1;
--echo #
+--echo # MDEV-15433: Optimizer does not use group by optimization with distinct
+--echo #
+
+CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, a INT NOT NULL, KEY(a));
+--disable_query_log
+INSERT INTO t1(a) VALUES (1), (2), (3), (4);
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+INSERT INTO t1(a) SELECT a FROM t1;
+--enable_query_log
+OPTIMIZE TABLE t1;
+EXPLAIN SELECT DISTINCT a FROM t1;
+SELECT DISTINCT a FROM t1;
+drop table t1;
+
+--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/mysql-test/main/information_schema-big.result b/mysql-test/main/information_schema-big.result
index cbd8191bc54..d4aa6deb2e2 100644
--- a/mysql-test/main/information_schema-big.result
+++ b/mysql-test/main/information_schema-big.result
@@ -20,6 +20,7 @@ table_name column_name
ALL_PLUGINS PLUGIN_NAME
APPLICABLE_ROLES GRANTEE
CHARACTER_SETS CHARACTER_SET_NAME
+CHECK_CONSTRAINTS CONSTRAINT_SCHEMA
CLIENT_STATISTICS CLIENT
COLLATIONS COLLATION_NAME
COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
@@ -77,6 +78,7 @@ table_name column_name
ALL_PLUGINS PLUGIN_NAME
APPLICABLE_ROLES GRANTEE
CHARACTER_SETS CHARACTER_SET_NAME
+CHECK_CONSTRAINTS CONSTRAINT_SCHEMA
CLIENT_STATISTICS CLIENT
COLLATIONS COLLATION_NAME
COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result
index 6e987dd3266..b6e331a0382 100644
--- a/mysql-test/main/information_schema.result
+++ b/mysql-test/main/information_schema.result
@@ -51,6 +51,7 @@ c
ALL_PLUGINS
APPLICABLE_ROLES
CHARACTER_SETS
+CHECK_CONSTRAINTS
CLIENT_STATISTICS
COLLATIONS
COLLATION_CHARACTER_SET_APPLICABILITY
@@ -937,6 +938,7 @@ connection user10261;
SELECT TABLE_NAME, COLUMN_NAME, PRIVILEGES FROM INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME='TABLE_NAME' and table_name not like 'innodb%';
TABLE_NAME COLUMN_NAME PRIVILEGES
+CHECK_CONSTRAINTS TABLE_NAME select
COLUMNS TABLE_NAME select
COLUMN_PRIVILEGES TABLE_NAME select
FILES TABLE_NAME select
diff --git a/mysql-test/main/information_schema_all_engines.result b/mysql-test/main/information_schema_all_engines.result
index 126a6f4bccd..0ce9f15f753 100644
--- a/mysql-test/main/information_schema_all_engines.result
+++ b/mysql-test/main/information_schema_all_engines.result
@@ -4,6 +4,7 @@ Tables_in_information_schema
ALL_PLUGINS
APPLICABLE_ROLES
CHARACTER_SETS
+CHECK_CONSTRAINTS
CLIENT_STATISTICS
COLLATIONS
COLLATION_CHARACTER_SET_APPLICABILITY
@@ -83,6 +84,7 @@ table_name column_name
ALL_PLUGINS PLUGIN_NAME
APPLICABLE_ROLES GRANTEE
CHARACTER_SETS CHARACTER_SET_NAME
+CHECK_CONSTRAINTS CONSTRAINT_SCHEMA
CLIENT_STATISTICS CLIENT
COLLATIONS COLLATION_NAME
COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
@@ -162,6 +164,7 @@ table_name column_name
ALL_PLUGINS PLUGIN_NAME
APPLICABLE_ROLES GRANTEE
CHARACTER_SETS CHARACTER_SET_NAME
+CHECK_CONSTRAINTS CONSTRAINT_SCHEMA
CLIENT_STATISTICS CLIENT
COLLATIONS COLLATION_NAME
COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
@@ -247,6 +250,7 @@ table_name group_concat(t.table_schema, '.', t.table_name) num1
ALL_PLUGINS information_schema.ALL_PLUGINS 1
APPLICABLE_ROLES information_schema.APPLICABLE_ROLES 1
CHARACTER_SETS information_schema.CHARACTER_SETS 1
+CHECK_CONSTRAINTS information_schema.CHECK_CONSTRAINTS 1
CLIENT_STATISTICS information_schema.CLIENT_STATISTICS 1
COLLATIONS information_schema.COLLATIONS 1
COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 1
@@ -315,6 +319,7 @@ Database: information_schema
| ALL_PLUGINS |
| APPLICABLE_ROLES |
| CHARACTER_SETS |
+| CHECK_CONSTRAINTS |
| CLIENT_STATISTICS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
@@ -384,6 +389,7 @@ Database: INFORMATION_SCHEMA
| ALL_PLUGINS |
| APPLICABLE_ROLES |
| CHARACTER_SETS |
+| CHECK_CONSTRAINTS |
| CLIENT_STATISTICS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
@@ -453,5 +459,5 @@ Wildcard: inf_rmation_schema
| information_schema |
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') GROUP BY TABLE_SCHEMA;
table_schema count(*)
-information_schema 64
+information_schema 65
mysql 30
diff --git a/mysql-test/main/mysql.result b/mysql-test/main/mysql.result
index 09f014da627..06ef7e95bc9 100644
--- a/mysql-test/main/mysql.result
+++ b/mysql-test/main/mysql.result
@@ -538,8 +538,6 @@ a
#
# End of 10.1 tests
#
-ERROR 1300 (HY000): Invalid utf8 character string: 'test\xF0\x9F\x98\x81 '
-ERROR 1300 (HY000): Invalid binary character string: 'test\xF0\x9F\x98\x81 '
ERROR 1300 (HY000) at line 2: Invalid utf8 character string: 'test\xF0\x9F\x98\x81'
set GLOBAL sql_mode=default;
diff --git a/mysql-test/main/mysql.test b/mysql-test/main/mysql.test
index 01953ba2112..c65860eb822 100644
--- a/mysql-test/main/mysql.test
+++ b/mysql-test/main/mysql.test
@@ -638,10 +638,7 @@ EOF
--echo # End of 10.1 tests
--echo #
---error 1
---exec $MYSQL --default-character-set=utf8 -e "select 1" "test😁 " 2>&1
---error 1
---exec $MYSQL --default-character-set=binary -e "select 1" "test😁 " 2>&1
+
--write_file $MYSQLTEST_VARDIR/tmp/mdev-6572.sql
SET NAMES utf8;
USE test😁 ;
diff --git a/mysql-test/main/mysql_not_windows.result b/mysql-test/main/mysql_not_windows.result
index 1df62d9a12d..96210a366a6 100644
--- a/mysql-test/main/mysql_not_windows.result
+++ b/mysql-test/main/mysql_not_windows.result
@@ -9,3 +9,5 @@ End of tests
2
X
3
+ERROR 1300 (HY000): Invalid utf8 character string: 'test\xF0\x9F\x98\x81 '
+ERROR 1300 (HY000): Invalid binary character string: 'test\xF0\x9F\x98\x81 '
diff --git a/mysql-test/main/mysql_not_windows.test b/mysql-test/main/mysql_not_windows.test
index 591de74cbbf..816160c4f3e 100644
--- a/mysql-test/main/mysql_not_windows.test
+++ b/mysql-test/main/mysql_not_windows.test
@@ -22,3 +22,10 @@ exec $MYSQL test -e "select
let $query = select 3
as X;
exec $MYSQL test -e "$query";
+
+# Not ran on Windows, since non-ASCII does not work on command line.
+# (MDEV-16220)
+--error 1
+--exec $MYSQL --default-character-set=utf8 -e "select 1" "test😁 " 2>&1
+--error 1
+--exec $MYSQL --default-character-set=binary -e "select 1" "test😁 " 2>&1
diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result
index ac490afe229..8032702ffbb 100644
--- a/mysql-test/main/mysqld--help.result
+++ b/mysql-test/main/mysqld--help.result
@@ -231,6 +231,11 @@ The following specify which files/extra groups are read (specified before remain
cache, etc)
--enforce-storage-engine=name
Force the use of a storage engine for new tables
+ --eq-range-index-dive-limit=#
+ The optimizer will use existing index statistics instead
+ of doing index dives for equality ranges if the number of
+ equality ranges for the index is larger than or equal to
+ this number. If set to 0, index dives are always used.
--event-scheduler[=name]
Enable the event scheduler. Possible values are ON, OFF,
and DISABLED (keep the event scheduler completely
@@ -1404,6 +1409,7 @@ encrypt-binlog FALSE
encrypt-tmp-disk-tables FALSE
encrypt-tmp-files FALSE
enforce-storage-engine (No default value)
+eq-range-index-dive-limit 0
event-scheduler OFF
expensive-subquery-limit 100
expire-logs-days 0
diff --git a/mysql-test/main/opt_tvc.result b/mysql-test/main/opt_tvc.result
index 0ecae5bf157..fdbd932a433 100644
--- a/mysql-test/main/opt_tvc.result
+++ b/mysql-test/main/opt_tvc.result
@@ -486,34 +486,32 @@ a b
deallocate prepare stmt;
# use inside out access from tvc rows
set @@in_predicate_conversion_threshold= default;
-select * from t3 where a in (1,4,10);
+select * from t3 where a in (1,4);
a b
1 abc
1 todd
1 sm
4 yq
-10 abc
-explain extended select * from t3 where a in (1,4,10);
+explain extended select * from t3 where a in (1,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t3 range idx idx 5 NULL 5 100.00 Using index condition
+1 SIMPLE t3 range idx idx 5 NULL 4 100.00 Using index condition
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where `test`.`t3`.`a` in (1,4,10)
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where `test`.`t3`.`a` in (1,4)
set @@in_predicate_conversion_threshold= 2;
-select * from t3 where a in (1,4,10);
+select * from t3 where a in (1,4);
a b
1 abc
1 todd
1 sm
4 yq
-10 abc
-explain extended select * from t3 where a in (1,4,10);
+explain extended select * from t3 where a in (1,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 100.00
1 PRIMARY t3 ref idx idx 5 tvc_0.1 3 100.00
2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` semi join ((values (1),(4),(10)) `tvc_0`) where `test`.`t3`.`a` = `tvc_0`.`1`
+Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` semi join ((values (1),(4)) `tvc_0`) where `test`.`t3`.`a` = `tvc_0`.`1`
# use vectors in IN predeicate
set @@in_predicate_conversion_threshold= 4;
select * from t1 where (a,b) in ((1,2),(3,4));
@@ -540,9 +538,9 @@ explain extended select * from t2
where (a,b) in ((1,2),(8,9)) and
(a,c) in ((1,3),(8,0),(5,1));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 100.00
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 100.00
1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Using where; Using join buffer (flat, BNL join)
-2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 3 100.00
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` semi join ((values (1,3),(8,0),(5,1)) `tvc_0`) where `test`.`t2`.`a` = `tvc_0`.`1` and `test`.`t2`.`c` = `tvc_0`.`3` and (`tvc_0`.`1`,`test`.`t2`.`b`) in (<cache>((1,2)),<cache>((8,9)))
@@ -570,7 +568,7 @@ explain extended select * from t1
where (a,b) not in ((1,2),(8,9), (5,1));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
-2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 3 100.00
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<expr_cache><`test`.`t1`.`a`,`test`.`t1`.`b`>(<in_optimizer>((`test`.`t1`.`a`,`test`.`t1`.`b`),(`test`.`t1`.`a`,`test`.`t1`.`b`) in ( <materialize> (/* select#2 */ select `tvc_0`.`1`,`tvc_0`.`2` from (values (1,2),(8,9),(5,1)) `tvc_0` ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`1` and `test`.`t1`.`b` = `<subquery2>`.`2`))))
@@ -578,7 +576,7 @@ explain extended select * from t1
where (a,b) not in (select * from (values (1,2),(8,9), (5,1)) as tvc_0);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
-2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 3 100.00
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<expr_cache><`test`.`t1`.`a`,`test`.`t1`.`b`>(<in_optimizer>((`test`.`t1`.`a`,`test`.`t1`.`b`),(`test`.`t1`.`a`,`test`.`t1`.`b`) in ( <materialize> (/* select#2 */ select `tvc_0`.`1`,`tvc_0`.`2` from (values (1,2),(8,9),(5,1)) `tvc_0` ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`1` and `test`.`t1`.`b` = `<subquery2>`.`2`))))
@@ -592,7 +590,7 @@ explain extended select * from t1
where b < 7 and (a,b) not in ((1,2),(8,9), (5,1));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
-2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 3 100.00
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` < 7 and !<expr_cache><`test`.`t1`.`a`,`test`.`t1`.`b`>(<in_optimizer>((`test`.`t1`.`a`,`test`.`t1`.`b`),(`test`.`t1`.`a`,`test`.`t1`.`b`) in ( <materialize> (/* select#2 */ select `tvc_0`.`1`,`tvc_0`.`2` from (values (1,2),(8,9),(5,1)) `tvc_0` ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`1` and `test`.`t1`.`b` = `<subquery2>`.`2`))))
@@ -608,7 +606,7 @@ explain extended select * from t2
where (a,c) not in ((1,2),(8,9), (5,1));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
-2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 3 100.00
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where !<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`c`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`c`),(`test`.`t2`.`a`,`test`.`t2`.`c`) in ( <materialize> (/* select#2 */ select `tvc_0`.`1`,`tvc_0`.`2` from (values (1,2),(8,9),(5,1)) `tvc_0` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where `test`.`t2`.`a` = `<subquery2>`.`1` and `test`.`t2`.`c` = `<subquery2>`.`2`))))
@@ -632,7 +630,7 @@ i
EXPLAIN EXTENDED SELECT * FROM t1 WHERE i IN (NULL, NULL, NULL, NULL, NULL);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
-1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join)
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join)
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`i` AS `i` from `test`.`t1` semi join ((values (NULL),(NULL),(NULL),(NULL),(NULL)) `tvc_0`) where `test`.`t1`.`i` = `tvc_0`.`NULL`
diff --git a/mysql-test/main/opt_tvc.test b/mysql-test/main/opt_tvc.test
index d5c9a5cbd3d..2d06a0a0b20 100644
--- a/mysql-test/main/opt_tvc.test
+++ b/mysql-test/main/opt_tvc.test
@@ -255,7 +255,7 @@ deallocate prepare stmt;
--echo # use inside out access from tvc rows
-let $query= select * from t3 where a in (1,4,10);
+let $query= select * from t3 where a in (1,4);
set @@in_predicate_conversion_threshold= default;
eval $query;
eval explain extended $query;
diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result
index e2996b963bc..464c0bf031a 100644
--- a/mysql-test/main/range.result
+++ b/mysql-test/main/range.result
@@ -1048,30 +1048,6 @@ select a, hex(filler) from t1 where a not between 'b' and 'b';
a hex(filler)
a 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
drop table t1,t2,t3;
-create table t1 (a int);
-insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-create table t2 (a int, key(a));
-insert into t2 select 2*(A.a + 10*(B.a + 10*C.a)) from t1 A, t1 B, t1 C;
-set @a="select * from t2 force index (a) where a NOT IN(0";
-select count(*) from (select @a:=concat(@a, ',', a) from t2 ) Z;
-count(*)
-1000
-set @a=concat(@a, ')');
-insert into t2 values (11),(13),(15);
-set @b= concat("explain ", @a);
-prepare stmt1 from @b;
-execute stmt1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 index NULL a 5 NULL 1003 Using where; Using index
-2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2
-3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
-prepare stmt1 from @a;
-execute stmt1;
-a
-11
-13
-15
-drop table t1, t2;
CREATE TABLE t1 (
id int NOT NULL DEFAULT '0',
b int NOT NULL DEFAULT '0',
@@ -3005,5 +2981,46 @@ deallocate prepare stmt;
set optimizer_switch=@save_optimizer_switch;
drop table t1,t2,t3;
#
+# MDEV-16934: using system variable eq_range_index_dive_limit
+# to reduce the number of index dives
+#
+create table t1 (a int, b varchar(31), index idx(a));
+insert into t1 values
+(7,'xxxx'), (1,'yy'), (3,'aaa'), (1,'bbb'), (2,'zz'),
+(4,'vvvvv'), (7,'ddd'), (9,'zzzzz'), (1,'cc'), (5,'ffff');
+insert into t1 select a+10, concat(b,'zz') from t1;
+insert into t1 select a+15, concat(b,'yy') from t1;
+insert into t1 select a+100, concat(b,'xx') from t1;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select cast(count(a)/count(distinct a) as unsigned) as rec_per_key from t1;
+rec_per_key
+2
+set eq_range_index_dive_limit=0;
+explain select * from t1 where a in (8, 15, 31, 1, 9);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx idx 5 NULL 7 Using index condition
+select * from t1 where a in (8, 15, 31, 1, 9);
+a b
+1 yy
+1 bbb
+1 cc
+9 zzzzz
+15 ffffzz
+set eq_range_index_dive_limit=2;
+explain select * from t1 where a in (8, 15, 31, 1, 9);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx idx 5 NULL 10 Using index condition
+select * from t1 where a in (8, 15, 31, 1, 9);
+a b
+1 yy
+1 bbb
+1 cc
+9 zzzzz
+15 ffffzz
+set eq_range_index_dive_limit=default;
+drop table t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test
index 36e0e32b28b..bd2299bac5f 100644
--- a/mysql-test/main/range.test
+++ b/mysql-test/main/range.test
@@ -863,30 +863,6 @@ select a, hex(filler) from t1 where a not between 'b' and 'b';
drop table t1,t2,t3;
#
-# BUG#21282
-#
-create table t1 (a int);
-insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-create table t2 (a int, key(a));
-insert into t2 select 2*(A.a + 10*(B.a + 10*C.a)) from t1 A, t1 B, t1 C;
-
-set @a="select * from t2 force index (a) where a NOT IN(0";
-select count(*) from (select @a:=concat(@a, ',', a) from t2 ) Z;
-set @a=concat(@a, ')');
-
-insert into t2 values (11),(13),(15);
-
-set @b= concat("explain ", @a);
-
-prepare stmt1 from @b;
-execute stmt1;
-
-prepare stmt1 from @a;
-execute stmt1;
-
-drop table t1, t2;
-
-#
# Bug #18165: range access for BETWEEN with a constant for the first argument
#
@@ -2042,5 +2018,38 @@ set optimizer_switch=@save_optimizer_switch;
drop table t1,t2,t3;
--echo #
+--echo # MDEV-16934: using system variable eq_range_index_dive_limit
+--echo # to reduce the number of index dives
+--echo #
+
+create table t1 (a int, b varchar(31), index idx(a));
+
+insert into t1 values
+ (7,'xxxx'), (1,'yy'), (3,'aaa'), (1,'bbb'), (2,'zz'),
+ (4,'vvvvv'), (7,'ddd'), (9,'zzzzz'), (1,'cc'), (5,'ffff');
+insert into t1 select a+10, concat(b,'zz') from t1;
+insert into t1 select a+15, concat(b,'yy') from t1;
+insert into t1 select a+100, concat(b,'xx') from t1;
+
+analyze table t1;
+
+select cast(count(a)/count(distinct a) as unsigned) as rec_per_key from t1;
+
+let $q=
+select * from t1 where a in (8, 15, 31, 1, 9);
+
+set eq_range_index_dive_limit=0;
+eval explain $q;
+eval $q;
+
+set eq_range_index_dive_limit=2;
+eval explain $q;
+eval $q;
+
+set eq_range_index_dive_limit=default;
+
+drop table t1;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/main/range_debug.result b/mysql-test/main/range_debug.result
new file mode 100644
index 00000000000..5597671071e
--- /dev/null
+++ b/mysql-test/main/range_debug.result
@@ -0,0 +1,24 @@
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, key(a));
+insert into t2 select 2*(A.a + 10*(B.a + 10*C.a)) from t1 A, t1 B, t1 C;
+set in_predicate_conversion_threshold= 2000;
+set @a="select * from t2 force index (a) where a NOT IN(0";
+select count(*) from (select @a:=concat(@a, ',', a) from t2 ) Z;
+count(*)
+1000
+set @a=concat(@a, ')');
+insert into t2 values (11),(13),(15);
+set @b= concat("explain ", @a);
+prepare stmt1 from @b;
+execute stmt1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index a a 5 NULL 1003 Using where; Using index
+prepare stmt1 from @a;
+execute stmt1;
+a
+11
+13
+15
+set in_predicate_conversion_threshold= default;
+drop table t1, t2;
diff --git a/mysql-test/main/range_debug.test b/mysql-test/main/range_debug.test
new file mode 100644
index 00000000000..ef331cdc84f
--- /dev/null
+++ b/mysql-test/main/range_debug.test
@@ -0,0 +1,30 @@
+source include/have_debug.inc;
+#
+# BUG#21282
+#
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, key(a));
+insert into t2 select 2*(A.a + 10*(B.a + 10*C.a)) from t1 A, t1 B, t1 C;
+
+set in_predicate_conversion_threshold= 2000;
+
+set @a="select * from t2 force index (a) where a NOT IN(0";
+select count(*) from (select @a:=concat(@a, ',', a) from t2 ) Z;
+set @a=concat(@a, ')');
+
+insert into t2 values (11),(13),(15);
+
+set @b= concat("explain ", @a);
+
+prepare stmt1 from @b;
+execute stmt1;
+
+prepare stmt1 from @a;
+execute stmt1;
+
+set in_predicate_conversion_threshold= default;
+
+drop table t1, t2;
+
+
diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result
index 629d183bee7..b132e63b732 100644
--- a/mysql-test/main/range_mrr_icp.result
+++ b/mysql-test/main/range_mrr_icp.result
@@ -1050,30 +1050,6 @@ select a, hex(filler) from t1 where a not between 'b' and 'b';
a hex(filler)
a 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
drop table t1,t2,t3;
-create table t1 (a int);
-insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
-create table t2 (a int, key(a));
-insert into t2 select 2*(A.a + 10*(B.a + 10*C.a)) from t1 A, t1 B, t1 C;
-set @a="select * from t2 force index (a) where a NOT IN(0";
-select count(*) from (select @a:=concat(@a, ',', a) from t2 ) Z;
-count(*)
-1000
-set @a=concat(@a, ')');
-insert into t2 values (11),(13),(15);
-set @b= concat("explain ", @a);
-prepare stmt1 from @b;
-execute stmt1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 index NULL a 5 NULL 1003 Using where; Using index
-2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2
-3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
-prepare stmt1 from @a;
-execute stmt1;
-a
-11
-13
-15
-drop table t1, t2;
CREATE TABLE t1 (
id int NOT NULL DEFAULT '0',
b int NOT NULL DEFAULT '0',
@@ -3017,6 +2993,47 @@ deallocate prepare stmt;
set optimizer_switch=@save_optimizer_switch;
drop table t1,t2,t3;
#
+# MDEV-16934: using system variable eq_range_index_dive_limit
+# to reduce the number of index dives
+#
+create table t1 (a int, b varchar(31), index idx(a));
+insert into t1 values
+(7,'xxxx'), (1,'yy'), (3,'aaa'), (1,'bbb'), (2,'zz'),
+(4,'vvvvv'), (7,'ddd'), (9,'zzzzz'), (1,'cc'), (5,'ffff');
+insert into t1 select a+10, concat(b,'zz') from t1;
+insert into t1 select a+15, concat(b,'yy') from t1;
+insert into t1 select a+100, concat(b,'xx') from t1;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select cast(count(a)/count(distinct a) as unsigned) as rec_per_key from t1;
+rec_per_key
+2
+set eq_range_index_dive_limit=0;
+explain select * from t1 where a in (8, 15, 31, 1, 9);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx idx 5 NULL 7 Using index condition; Rowid-ordered scan
+select * from t1 where a in (8, 15, 31, 1, 9);
+a b
+1 yy
+1 bbb
+9 zzzzz
+1 cc
+15 ffffzz
+set eq_range_index_dive_limit=2;
+explain select * from t1 where a in (8, 15, 31, 1, 9);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx idx 5 NULL 10 Using index condition; Rowid-ordered scan
+select * from t1 where a in (8, 15, 31, 1, 9);
+a b
+1 yy
+1 bbb
+9 zzzzz
+1 cc
+15 ffffzz
+set eq_range_index_dive_limit=default;
+drop table t1;
+#
# End of 10.2 tests
#
set optimizer_switch=@mrr_icp_extra_tmp;
diff --git a/mysql-test/main/subselect_extra_no_semijoin.result b/mysql-test/main/subselect_extra_no_semijoin.result
index fc8d5759945..ec9ddb0452e 100644
--- a/mysql-test/main/subselect_extra_no_semijoin.result
+++ b/mysql-test/main/subselect_extra_no_semijoin.result
@@ -482,3 +482,25 @@ DROP TABLE t1,t2;
set optimizer_switch= @tmp_subselect_extra_derived;
set optimizer_switch= @subselect_extra_no_sj_tmp;
set @optimizer_switch_for_subselect_extra_test=null;
+#
+# MDEV-6439: Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset
+#
+connect con1,localhost,root,,;
+SET NAMES tis620;
+set @tmp= @@global.slow_query_log;
+SET GLOBAL slow_query_log = 1;
+SET long_query_time = 0.000001;
+SET log_slow_verbosity = 'explain';
+CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM;
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo');
+a
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' );
+ERROR HY000: Illegal mix of collations (tis620_thai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<='
+create table t2 (b int);
+insert into t2 values (1),(2),(3);
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' FROM t2);
+ERROR HY000: Illegal mix of collations (tis620_thai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<='
+drop table t1,t2;
+SET GLOBAL slow_query_log=@tmp;
+disconnect con1;
+connection default;
diff --git a/mysql-test/main/subselect_extra_no_semijoin.test b/mysql-test/main/subselect_extra_no_semijoin.test
index 4340f4165e7..681f92bd8c4 100644
--- a/mysql-test/main/subselect_extra_no_semijoin.test
+++ b/mysql-test/main/subselect_extra_no_semijoin.test
@@ -6,4 +6,33 @@ set @optimizer_switch_for_subselect_extra_test='semijoin=off,firstmatch=off,loo
set optimizer_switch= @subselect_extra_no_sj_tmp;
-set @optimizer_switch_for_subselect_extra_test=null; \ No newline at end of file
+set @optimizer_switch_for_subselect_extra_test=null;
+
+--echo #
+--echo # MDEV-6439: Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset
+--echo #
+
+## Using a separate client connection is easier than restoring state
+connect(con1,localhost,root,,);
+
+SET NAMES tis620;
+set @tmp= @@global.slow_query_log;
+SET GLOBAL slow_query_log = 1;
+SET long_query_time = 0.000001;
+SET log_slow_verbosity = 'explain';
+
+CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM;
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo');
+--error ER_CANT_AGGREGATE_2COLLATIONS
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' );
+
+create table t2 (b int);
+insert into t2 values (1),(2),(3);
+
+--error ER_CANT_AGGREGATE_2COLLATIONS
+SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' FROM t2);
+
+drop table t1,t2;
+SET GLOBAL slow_query_log=@tmp;
+disconnect con1;
+connection default;
diff --git a/mysql-test/main/subselect_mat.result b/mysql-test/main/subselect_mat.result
index e208dfe74c1..010ba03153b 100644
--- a/mysql-test/main/subselect_mat.result
+++ b/mysql-test/main/subselect_mat.result
@@ -499,7 +499,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or /*always not null*/ 1 is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or /*always not null*/ 1 is null) and '1 - 01' is null and '2 - 01' is null)))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
a1 a2
1 - 01 2 - 01
@@ -509,7 +509,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or /*always not null*/ 1 is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or /*always not null*/ 1 is null) and '1 - 01' is null and '2 - 01' is null)))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
a1 a2
1 - 01 2 - 01
@@ -1925,7 +1925,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2` having `MAX(c)` is null or `MAX(c)` = 7) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(`<subquery2>`.`MAX(c)` is null) or `<subquery2>`.`MAX(c)` = 7)
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2` having `MAX(c)` is null or `MAX(c)` = 7) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(/*always not null*/ 1 is null) or `<subquery2>`.`MAX(c)` = 7)
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
a b
diff --git a/mysql-test/main/subselect_sj_mat.result b/mysql-test/main/subselect_sj_mat.result
index 7630b0b9c0f..983c6c31c65 100644
--- a/mysql-test/main/subselect_sj_mat.result
+++ b/mysql-test/main/subselect_sj_mat.result
@@ -520,7 +520,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or /*always not null*/ 1 is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or /*always not null*/ 1 is null) and '1 - 01' is null and '2 - 01' is null)))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
a1 a2
1 - 01 2 - 01
@@ -530,7 +530,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or /*always not null*/ 1 is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or /*always not null*/ 1 is null) and '1 - 01' is null and '2 - 01' is null)))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
a1 a2
1 - 01 2 - 01
@@ -1963,7 +1963,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2` having `MAX(c)` is null or `MAX(c)` = 7) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(`<subquery2>`.`MAX(c)` is null) or `<subquery2>`.`MAX(c)` = 7)
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2` having `MAX(c)` is null or `MAX(c)` = 7) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(/*always not null*/ 1 is null) or `<subquery2>`.`MAX(c)` = 7)
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
a b
diff --git a/mysql-test/main/table_value_constr.result b/mysql-test/main/table_value_constr.result
index 9129fd0a23b..454356bb5fb 100644
--- a/mysql-test/main/table_value_constr.result
+++ b/mysql-test/main/table_value_constr.result
@@ -2096,3 +2096,95 @@ v
#
with t as (values (),()) select 1 from t;
ERROR HY000: Row with no elements is not allowed in table value constructor in this context
+#
+# MDEV-17017: TVC in derived table
+#
+create table t1 (a int);
+insert into t1 values (9), (3), (2);
+select * from (values (7), (5), (8), (1), (3), (8), (1)) t;
+7
+7
+5
+8
+1
+3
+8
+1
+explain select * from (values (7), (5), (8), (1), (3), (8), (1)) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+select * from (values (1,11), (7,77), (3,31), (4,42)) t;
+1 11
+1 11
+7 77
+3 31
+4 42
+explain select * from (values (1,11), (7,77), (3,31), (4,42)) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+select * from (values (7), (5), (8), (1) union values (3), (8), (1)) t;
+7
+7
+5
+8
+1
+3
+explain select * from (values (7), (5), (8), (1) union values (3), (8), (1)) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+select * from (values (7), (5), (8), (1) union select * from t1) t;
+7
+7
+5
+8
+1
+9
+3
+2
+explain select * from (values (7), (5), (8), (1) union select * from t1) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION t1 ALL NULL NULL NULL NULL 3
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+drop table t1;
+#
+# MDEV-16930: expression in the first row of TVC specifying derived table
+#
+SELECT 1 + 1, 2, "abc";
+1 + 1 2 abc
+2 2 abc
+SELECT * FROM (SELECT 1 + 1, 2, "abc") t;
+1 + 1 2 abc
+2 2 abc
+WITH cte AS (SELECT 1 + 1, 2, "abc") SELECT * FROM cte;
+1 + 1 2 abc
+2 2 abc
+SELECT 1 + 1, 2, "abc" UNION SELECT 3+4, 3, "abc";
+1 + 1 2 abc
+2 2 abc
+7 3 abc
+CREATE VIEW v1 AS SELECT 1 + 1, 2, "abc";
+SELECT * FROM v1;
+1 + 1 2 abc
+2 2 abc
+DROP VIEW v1;
+VALUES(1 + 1,2,"abc");
+1 + 1 2 abc
+2 2 abc
+SELECT * FROM (VALUES(1 + 1,2,"abc")) t;
+1 + 1 2 abc
+2 2 abc
+PREPARE stmt FROM "SELECT * FROM (VALUES(1 + 1,2,'abc')) t";
+EXECUTE stmt;
+1 + 1 2 abc
+2 2 abc
+EXECUTE stmt;
+1 + 1 2 abc
+2 2 abc
+DEALLOCATE PREPARE stmt;
diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test
index eb5ea59f829..0dd0a7a04b0 100644
--- a/mysql-test/main/table_value_constr.test
+++ b/mysql-test/main/table_value_constr.test
@@ -1075,3 +1075,51 @@ DELIMITER ;|
--error ER_EMPTY_ROW_IN_TVC
with t as (values (),()) select 1 from t;
+
+--echo #
+--echo # MDEV-17017: TVC in derived table
+--echo #
+
+create table t1 (a int);
+insert into t1 values (9), (3), (2);
+
+let $q1=
+select * from (values (7), (5), (8), (1), (3), (8), (1)) t;
+eval $q1;
+eval explain $q1;
+
+let $q2=
+select * from (values (1,11), (7,77), (3,31), (4,42)) t;
+eval $q2;
+eval explain $q2;
+
+let $q3=
+select * from (values (7), (5), (8), (1) union values (3), (8), (1)) t;
+eval $q3;
+eval explain $q3;
+
+let $q4=
+select * from (values (7), (5), (8), (1) union select * from t1) t;
+eval $q4;
+eval explain $q4;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-16930: expression in the first row of TVC specifying derived table
+--echo #
+
+SELECT 1 + 1, 2, "abc";
+SELECT * FROM (SELECT 1 + 1, 2, "abc") t;
+WITH cte AS (SELECT 1 + 1, 2, "abc") SELECT * FROM cte;
+SELECT 1 + 1, 2, "abc" UNION SELECT 3+4, 3, "abc";
+CREATE VIEW v1 AS SELECT 1 + 1, 2, "abc";
+SELECT * FROM v1;
+DROP VIEW v1;
+
+VALUES(1 + 1,2,"abc");
+SELECT * FROM (VALUES(1 + 1,2,"abc")) t;
+PREPARE stmt FROM "SELECT * FROM (VALUES(1 + 1,2,'abc')) t";
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result
index fd0fbefdcc5..97801b5e285 100644
--- a/mysql-test/main/win.result
+++ b/mysql-test/main/win.result
@@ -3219,8 +3219,8 @@ DROP TABLE fv_test, fv_result;
#
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (0),(1),(2);
-SELECT LEAD(a) OVER (PARTITION BY a) as lead,
-a AND LEAD(a) OVER (PARTITION BY a) AS a_and_lead_part
+SELECT LEAD(a) OVER (PARTITION BY a ORDER BY a) as lead,
+a AND LEAD(a) OVER (PARTITION BY a ORDER BY a) AS a_and_lead_part
FROM t1;
lead a_and_lead_part
NULL 0
diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test
index cc16595fcd4..f038316ce98 100644
--- a/mysql-test/main/win.test
+++ b/mysql-test/main/win.test
@@ -2000,8 +2000,8 @@ DROP TABLE fv_test, fv_result;
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (0),(1),(2);
-SELECT LEAD(a) OVER (PARTITION BY a) as lead,
- a AND LEAD(a) OVER (PARTITION BY a) AS a_and_lead_part
+SELECT LEAD(a) OVER (PARTITION BY a ORDER BY a) as lead,
+ a AND LEAD(a) OVER (PARTITION BY a ORDER BY a) AS a_and_lead_part
FROM t1;
SELECT a OR LEAD(a) OVER (ORDER BY a) AS a_or_lead_order
diff --git a/mysql-test/main/win_lead_lag.result b/mysql-test/main/win_lead_lag.result
index 5ead58fa11a..f3c0b8f7ef2 100644
--- a/mysql-test/main/win_lead_lag.result
+++ b/mysql-test/main/win_lead_lag.result
@@ -226,4 +226,15 @@ pk a b a+b lag(a + b) over (partition by a order by pk) + pk
9 2 2 4 12
10 2 0 2 14
11 2 10 12 13
+#
+# MDEV-15204 - LAG function doesn't require ORDER BY in OVER clause
+#
+select pk,
+lag(pk, 1) over ()
+from t1;
+ERROR HY000: No order list in window specification for 'lag'
+select pk,
+lead(pk, 1) over ()
+from t1;
+ERROR HY000: No order list in window specification for 'lead'
drop table t1;
diff --git a/mysql-test/main/win_lead_lag.test b/mysql-test/main/win_lead_lag.test
index 2824f83789c..d154244ecd0 100644
--- a/mysql-test/main/win_lead_lag.test
+++ b/mysql-test/main/win_lead_lag.test
@@ -107,4 +107,17 @@ select pk, a, b, a+b,
from t1
order by pk asc;
+--echo #
+--echo # MDEV-15204 - LAG function doesn't require ORDER BY in OVER clause
+--echo #
+--error ER_NO_ORDER_LIST_IN_WINDOW_SPEC
+select pk,
+ lag(pk, 1) over ()
+from t1;
+
+--error ER_NO_ORDER_LIST_IN_WINDOW_SPEC
+select pk,
+ lead(pk, 1) over ()
+from t1;
+
drop table t1;
diff --git a/mysql-test/suite/compat/oracle/r/table_value_constr.result b/mysql-test/suite/compat/oracle/r/table_value_constr.result
index 31dcecfdb18..18fce086f6e 100644
--- a/mysql-test/suite/compat/oracle/r/table_value_constr.result
+++ b/mysql-test/suite/compat/oracle/r/table_value_constr.result
@@ -2099,3 +2099,87 @@ v
#
with t as (values (),()) select 1 from t;
ERROR HY000: Row with no elements is not allowed in table value constructor in this context
+#
+# MDEV-17017: TVC in derived table
+#
+create table t1 (a int);
+insert into t1 values (9), (3), (2);
+select * from (values (7), (5), (8), (1), (3), (8), (1)) t;
+7
+7
+5
+8
+1
+3
+8
+1
+explain select * from (values (7), (5), (8), (1), (3), (8), (1)) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+select * from (values (1,11), (7,77), (3,31), (4,42)) t;
+1 11
+1 11
+7 77
+3 31
+4 42
+explain select * from (values (1,11), (7,77), (3,31), (4,42)) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+select * from (values (7), (5), (8), (1) union values (3), (8), (1)) t;
+7
+7
+5
+8
+1
+3
+explain select * from (values (7), (5), (8), (1) union values (3), (8), (1)) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+select * from (values (7), (5), (8), (1) union select * from t1) t;
+7
+7
+5
+8
+1
+9
+3
+2
+explain select * from (values (7), (5), (8), (1) union select * from t1) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION t1 ALL NULL NULL NULL NULL 3
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+drop table t1;
+#
+# MDEV-16930: expression in the first row of TVC specifying derived table
+#
+SELECT 1 + 1, 2, 'abc';
+1 + 1 2 abc
+2 2 abc
+SELECT * FROM (SELECT 1 + 1, 2, 'abc') t;
+1 + 1 2 abc
+2 2 abc
+WITH cte AS (SELECT 1 + 1, 2, 'abc') SELECT * FROM cte;
+1 + 1 2 abc
+2 2 abc
+SELECT 1 + 1, 2, 'abc' UNION SELECT 3+4, 3, 'abc';
+1 + 1 2 abc
+2 2 abc
+7 3 abc
+CREATE VIEW v1 AS SELECT 1 + 1, 2, 'abc';
+SELECT * FROM v1;
+1 + 1 2 abc
+2 2 abc
+DROP VIEW v1;
+VALUES(1 + 1,2,'abc');
+1 + 1 2 abc
+2 2 abc
+SELECT * FROM (VALUES(1 + 1,2,'abc')) t;
+1 + 1 2 abc
+2 2 abc
diff --git a/mysql-test/suite/compat/oracle/t/table_value_constr.test b/mysql-test/suite/compat/oracle/t/table_value_constr.test
index 66519e93a36..37d25218664 100644
--- a/mysql-test/suite/compat/oracle/t/table_value_constr.test
+++ b/mysql-test/suite/compat/oracle/t/table_value_constr.test
@@ -1081,3 +1081,47 @@ DELIMITER ;|
--error ER_EMPTY_ROW_IN_TVC
with t as (values (),()) select 1 from t;
+
+--echo #
+--echo # MDEV-17017: TVC in derived table
+--echo #
+
+create table t1 (a int);
+insert into t1 values (9), (3), (2);
+
+let $q1=
+select * from (values (7), (5), (8), (1), (3), (8), (1)) t;
+eval $q1;
+eval explain $q1;
+
+let $q2=
+select * from (values (1,11), (7,77), (3,31), (4,42)) t;
+eval $q2;
+eval explain $q2;
+
+let $q3=
+select * from (values (7), (5), (8), (1) union values (3), (8), (1)) t;
+eval $q3;
+eval explain $q3;
+
+let $q4=
+select * from (values (7), (5), (8), (1) union select * from t1) t;
+eval $q4;
+eval explain $q4;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-16930: expression in the first row of TVC specifying derived table
+--echo #
+
+SELECT 1 + 1, 2, 'abc';
+SELECT * FROM (SELECT 1 + 1, 2, 'abc') t;
+WITH cte AS (SELECT 1 + 1, 2, 'abc') SELECT * FROM cte;
+SELECT 1 + 1, 2, 'abc' UNION SELECT 3+4, 3, 'abc';
+CREATE VIEW v1 AS SELECT 1 + 1, 2, 'abc';
+SELECT * FROM v1;
+DROP VIEW v1;
+
+VALUES(1 + 1,2,'abc');
+SELECT * FROM (VALUES(1 + 1,2,'abc')) t;
diff --git a/mysql-test/suite/funcs_1/r/is_check_constraints.result b/mysql-test/suite/funcs_1/r/is_check_constraints.result
new file mode 100644
index 00000000000..678cfb8db2f
--- /dev/null
+++ b/mysql-test/suite/funcs_1/r/is_check_constraints.result
@@ -0,0 +1,144 @@
+#
+# MDEV-14474: Create INFORMATION_SCHEMA.CHECK_CONSTRAINTS
+#
+set check_constraint_checks=1;
+use test;
+create table t0
+(
+t int, check (t>32) # table constraint
+) ENGINE=myisam;
+SELECT * from information_schema.check_constraints order by check_clause;
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CONSTRAINT_1
+TABLE_NAME t0
+CHECK_CLAUSE `t` > 32
+ALTER TABLE t0
+ADD CONSTRAINT CHK_t0_t CHECK(t<100);
+SELECT * from information_schema.check_constraints order by check_clause;
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CHK_t0_t
+TABLE_NAME t0
+CHECK_CLAUSE `t` < 100
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CONSTRAINT_1
+TABLE_NAME t0
+CHECK_CLAUSE `t` > 32
+ALTER TABLE t0
+DROP CONSTRAINT CHK_t0_t;
+SELECT * from information_schema.check_constraints order by check_clause;
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CONSTRAINT_1
+TABLE_NAME t0
+CHECK_CLAUSE `t` > 32
+CREATE TABLE t1
+( t int CHECK(t>2), # field constraint
+tt int, CONSTRAINT CHK_tt CHECK(tt<100) # table constraint
+) ENGINE=InnoDB;
+SELECT * from information_schema.check_constraints order by check_clause;
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CHK_tt
+TABLE_NAME t1
+CHECK_CLAUSE `tt` < 100
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME t
+TABLE_NAME t1
+CHECK_CLAUSE `t` > 2
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CONSTRAINT_1
+TABLE_NAME t0
+CHECK_CLAUSE `t` > 32
+ALTER TABLE t1
+DROP CONSTRAINT CHK_tt;
+SELECT * from information_schema.check_constraints order by check_clause;
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME t
+TABLE_NAME t1
+CHECK_CLAUSE `t` > 2
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CONSTRAINT_1
+TABLE_NAME t0
+CHECK_CLAUSE `t` > 32
+create table t2
+(
+name VARCHAR(30) CHECK(CHAR_LENGTH(name)>2), #field constraint
+start_date DATE,
+end_date DATE,
+CONSTRAINT CHK_dates CHECK(start_date IS NULL) #table constraint
+)ENGINE=Innodb;
+SELECT * from information_schema.check_constraints order by check_clause;
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME name
+TABLE_NAME t2
+CHECK_CLAUSE char_length(`name`) > 2
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CHK_dates
+TABLE_NAME t2
+CHECK_CLAUSE `start_date` is null
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME t
+TABLE_NAME t1
+CHECK_CLAUSE `t` > 2
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CONSTRAINT_1
+TABLE_NAME t0
+CHECK_CLAUSE `t` > 32
+ALTER TABLE t1
+ADD CONSTRAINT CHK_new_ CHECK(t>tt);
+SELECT * from information_schema.check_constraints order by check_clause;
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME name
+TABLE_NAME t2
+CHECK_CLAUSE char_length(`name`) > 2
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CHK_dates
+TABLE_NAME t2
+CHECK_CLAUSE `start_date` is null
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME t
+TABLE_NAME t1
+CHECK_CLAUSE `t` > 2
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CONSTRAINT_1
+TABLE_NAME t0
+CHECK_CLAUSE `t` > 32
+CONSTRAINT_CATALOG def
+CONSTRAINT_SCHEMA test
+CONSTRAINT_NAME CHK_new_
+TABLE_NAME t1
+CHECK_CLAUSE `t` > `tt`
+create table t3
+(
+a int,
+b int check (b>0), # field constraint named 'b'
+CONSTRAINT b check (b>10) # table constraint
+) ENGINE=InnoDB;
+select * from information_schema.check_constraints order by check_clause;
+CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_NAME CHECK_CLAUSE
+def test name t2 char_length(`name`) > 2
+def test b t3 `b` > 0
+def test b t3 `b` > 10
+def test CHK_dates t2 `start_date` is null
+def test t t1 `t` > 2
+def test CONSTRAINT_1 t0 `t` > 32
+def test CHK_new_ t1 `t` > `tt`
+drop table t0;
+drop table t1;
+drop table t2;
+drop table t3;
diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result
index d76efef3e08..dfaa5d75137 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result
@@ -24,6 +24,11 @@ def information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 '' NO varchar 32 96 N
def information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 '' NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select NEVER NULL
def information_schema CHARACTER_SETS DESCRIPTION 3 '' NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60) select NEVER NULL
def information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(3) select NEVER NULL
+def information_schema CHECK_CONSTRAINTS CHECK_CLAUSE 5 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
+def information_schema CHECK_CONSTRAINTS CONSTRAINT_CATALOG 1 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select NEVER NULL
+def information_schema CHECK_CONSTRAINTS CONSTRAINT_NAME 3 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
+def information_schema CHECK_CONSTRAINTS CONSTRAINT_SCHEMA 2 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
+def information_schema CHECK_CONSTRAINTS TABLE_NAME 4 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
def information_schema CLIENT_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select NEVER NULL
def information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) select NEVER NULL
def information_schema CLIENT_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL NULL double select NEVER NULL
@@ -557,6 +562,11 @@ COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH C
3.0000 information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME varchar 32 96 utf8 utf8_general_ci varchar(32)
3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 60 180 utf8 utf8_general_ci varchar(60)
NULL information_schema CHARACTER_SETS MAXLEN bigint NULL NULL NULL NULL bigint(3)
+3.0000 information_schema CHECK_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
+3.0000 information_schema CHECK_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
+3.0000 information_schema CHECK_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
+3.0000 information_schema CHECK_CONSTRAINTS TABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
+3.0000 information_schema CHECK_CONSTRAINTS CHECK_CLAUSE varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema CLIENT_STATISTICS CLIENT varchar 64 192 utf8 utf8_general_ci varchar(64)
NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS bigint NULL NULL NULL NULL bigint(21)
NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS bigint NULL NULL NULL NULL bigint(21)
diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
index b0d3c177580..96fb1e286c0 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
@@ -24,6 +24,11 @@ def information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 '' NO varchar 32 96 N
def information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 '' NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) NEVER NULL
def information_schema CHARACTER_SETS DESCRIPTION 3 '' NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60) NEVER NULL
def information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(3) NEVER NULL
+def information_schema CHECK_CONSTRAINTS CHECK_CLAUSE 5 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) NEVER NULL
+def information_schema CHECK_CONSTRAINTS CONSTRAINT_CATALOG 1 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) NEVER NULL
+def information_schema CHECK_CONSTRAINTS CONSTRAINT_NAME 3 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) NEVER NULL
+def information_schema CHECK_CONSTRAINTS CONSTRAINT_SCHEMA 2 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) NEVER NULL
+def information_schema CHECK_CONSTRAINTS TABLE_NAME 4 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) NEVER NULL
def information_schema CLIENT_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) NEVER NULL
def information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21) NEVER NULL
def information_schema CLIENT_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL NULL double NEVER NULL
@@ -557,6 +562,11 @@ COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH C
3.0000 information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME varchar 32 96 utf8 utf8_general_ci varchar(32)
3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 60 180 utf8 utf8_general_ci varchar(60)
NULL information_schema CHARACTER_SETS MAXLEN bigint NULL NULL NULL NULL bigint(3)
+3.0000 information_schema CHECK_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
+3.0000 information_schema CHECK_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
+3.0000 information_schema CHECK_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
+3.0000 information_schema CHECK_CONSTRAINTS TABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
+3.0000 information_schema CHECK_CONSTRAINTS CHECK_CLAUSE varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema CLIENT_STATISTICS CLIENT varchar 64 192 utf8 utf8_general_ci varchar(64)
NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS bigint NULL NULL NULL NULL bigint(21)
NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS bigint NULL NULL NULL NULL bigint(21)
diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result
index e0e5a82a265..5fee1e0050a 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_is.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_is.result
@@ -89,6 +89,31 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA information_schema
+TABLE_NAME CHECK_CONSTRAINTS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 11
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG def
+TABLE_SCHEMA information_schema
TABLE_NAME CLIENT_STATISTICS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1105,6 +1130,31 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA information_schema
+TABLE_NAME CHECK_CONSTRAINTS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 11
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG def
+TABLE_SCHEMA information_schema
TABLE_NAME CLIENT_STATISTICS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
diff --git a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
index e0e5a82a265..5fee1e0050a 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
@@ -89,6 +89,31 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA information_schema
+TABLE_NAME CHECK_CONSTRAINTS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 11
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG def
+TABLE_SCHEMA information_schema
TABLE_NAME CLIENT_STATISTICS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1105,6 +1130,31 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA information_schema
+TABLE_NAME CHECK_CONSTRAINTS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 11
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+MAX_INDEX_LENGTH #MIL#
+TEMPORARY Y
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG def
+TABLE_SCHEMA information_schema
TABLE_NAME CLIENT_STATISTICS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
diff --git a/mysql-test/suite/funcs_1/t/is_check_constraints.test b/mysql-test/suite/funcs_1/t/is_check_constraints.test
new file mode 100644
index 00000000000..b39abdc1b24
--- /dev/null
+++ b/mysql-test/suite/funcs_1/t/is_check_constraints.test
@@ -0,0 +1,69 @@
+--source include/have_innodb.inc
+--echo #
+--echo # MDEV-14474: Create INFORMATION_SCHEMA.CHECK_CONSTRAINTS
+--echo #
+
+set check_constraint_checks=1;
+
+use test;
+create table t0
+(
+ t int, check (t>32) # table constraint
+) ENGINE=myisam;
+
+--vertical_results
+SELECT * from information_schema.check_constraints order by check_clause;
+
+ALTER TABLE t0
+ADD CONSTRAINT CHK_t0_t CHECK(t<100);
+
+SELECT * from information_schema.check_constraints order by check_clause;
+
+ALTER TABLE t0
+DROP CONSTRAINT CHK_t0_t;
+
+SELECT * from information_schema.check_constraints order by check_clause;
+
+CREATE TABLE t1
+( t int CHECK(t>2), # field constraint
+ tt int, CONSTRAINT CHK_tt CHECK(tt<100) # table constraint
+) ENGINE=InnoDB;
+
+SELECT * from information_schema.check_constraints order by check_clause;
+
+ALTER TABLE t1
+DROP CONSTRAINT CHK_tt;
+
+SELECT * from information_schema.check_constraints order by check_clause;
+
+create table t2
+(
+name VARCHAR(30) CHECK(CHAR_LENGTH(name)>2), #field constraint
+start_date DATE,
+end_date DATE,
+CONSTRAINT CHK_dates CHECK(start_date IS NULL) #table constraint
+)ENGINE=Innodb;
+
+SELECT * from information_schema.check_constraints order by check_clause;
+
+ALTER TABLE t1
+ADD CONSTRAINT CHK_new_ CHECK(t>tt);
+
+SELECT * from information_schema.check_constraints order by check_clause;
+
+
+# Create table with same field and table check constraint name
+create table t3
+(
+a int,
+b int check (b>0), # field constraint named 'b'
+CONSTRAINT b check (b>10) # table constraint
+) ENGINE=InnoDB;
+
+--horizontal_results
+select * from information_schema.check_constraints order by check_clause;
+
+drop table t0;
+drop table t1;
+drop table t2;
+drop table t3;
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index c3b5e070158..28fc908c237 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -37,3 +37,10 @@ galera_ist_progress: MDEV-15236 galera_ist_progress fails when trying to read tr
galera_concurrent_ctas : MDEV-15845 Test failure on galera.galera_concurrent_ctas
pxc-421: Lock timeout exceeded
galera_sst_mysqldump_with_key : MDEV-16890 Galera test failure
+galera_sst_xtrabackup-v2-options : Failed to read uuid:seqno and wsrep_gtid_domain_id from joiner script
+MW-328C : Timeouts
+galera_gcs_fc_limit : Timeouts
+pool_of_threads: WSREP has not yet prepared node for application use
+galera_var_innodb_disallow_writes : Timeout
+galera.galera_kill_ddl : MDEV-17108 Test failure on galera.galera_kill_ddl
+MW-336 : nondeterministic wsrep_thread_count
diff --git a/mysql-test/suite/galera/r/MW-336.result b/mysql-test/suite/galera/r/MW-336.result
index 0bf8d9d3909..1b5d2984e39 100644
--- a/mysql-test/suite/galera/r/MW-336.result
+++ b/mysql-test/suite/galera/r/MW-336.result
@@ -2,39 +2,99 @@ CREATE TABLE t1 (f1 INTEGER) Engine=InnoDB;
connection node_1;
SET GLOBAL wsrep_slave_threads = 10;
SET GLOBAL wsrep_slave_threads = 1;
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND (STATE IS NULL OR STATE NOT LIKE 'InnoDB%');
+COUNT(*)
+11
+SHOW STATUS LIKE 'wsrep_thread_count';
+Variable_name Value
+wsrep_thread_count 11
connection node_2;
INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
connection node_1;
SET GLOBAL wsrep_slave_threads = 10;
SET GLOBAL wsrep_slave_threads = 20;
SET GLOBAL wsrep_slave_threads = 1;
connection node_2;
INSERT INTO t1 VALUES (1);
-INSERT INTO t1 VALUES (2);
-INSERT INTO t1 VALUES (3);
-INSERT INTO t1 VALUES (4);
-INSERT INTO t1 VALUES (5);
-INSERT INTO t1 VALUES (6);
-INSERT INTO t1 VALUES (7);
-INSERT INTO t1 VALUES (8);
-INSERT INTO t1 VALUES (9);
-connection node_1;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
SET GLOBAL wsrep_slave_threads = 10;
SET GLOBAL wsrep_slave_threads = 0;
Warnings:
Warning 1292 Truncated incorrect wsrep_slave_threads value: '0'
connection node_2;
-INSERT INTO t1 VALUES (10);
-INSERT INTO t1 VALUES (11);
-INSERT INTO t1 VALUES (12);
-INSERT INTO t1 VALUES (13);
-INSERT INTO t1 VALUES (14);
-INSERT INTO t1 VALUES (15);
-INSERT INTO t1 VALUES (16);
-INSERT INTO t1 VALUES (17);
-INSERT INTO t1 VALUES (18);
-INSERT INTO t1 VALUES (19);
-INSERT INTO t1 VALUES (20);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
connection node_1;
SET GLOBAL wsrep_slave_threads = 1;
+connection node_2;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1);
+connection node_1;
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/MW-44.result b/mysql-test/suite/galera/r/MW-44.result
index 459a61030a4..a1e55318422 100644
--- a/mysql-test/suite/galera/r/MW-44.result
+++ b/mysql-test/suite/galera/r/MW-44.result
@@ -1,21 +1,10 @@
SET GLOBAL general_log='OFF';
TRUNCATE TABLE mysql.general_log;
-SELECT COUNT(*) from mysql.general_log;
-COUNT(*)
-0
-SELECT * FROM mysql.general_log;
-event_time user_host thread_id server_id command_type argument
SET GLOBAL general_log='OFF';
TRUNCATE TABLE mysql.general_log;
-SELECT COUNT(*) from mysql.general_log;
-COUNT(*)
-0
-SELECT * FROM mysql.general_log;
-event_time user_host thread_id server_id command_type argument
SET GLOBAL general_log='ON';
-SELECT COUNT(*) from mysql.general_log;
-COUNT(*)
-1
+SELECT argument from mysql.general_log WHERE argument NOT LIKE 'SELECT%';
+argument
SET SESSION wsrep_osu_method=TOI;
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
SET SESSION wsrep_osu_method=RSU;
diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_data_dir.result b/mysql-test/suite/galera/r/galera_sst_rsync_data_dir.result
new file mode 100644
index 00000000000..d5c6a11f61f
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_sst_rsync_data_dir.result
@@ -0,0 +1,396 @@
+connection node_1;
+connection node_2;
+Performing State Transfer on a server that has been shut down cleanly and restarted
+connection node_1;
+CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+COMMIT;
+connection node_2;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+COMMIT;
+Shutting down server ...
+connection node_1;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+COMMIT;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+connect node_1a_galera_st_shutdown_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+connection node_2;
+Starting server ...
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+COMMIT;
+connection node_1;
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+COMMIT;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+COMMIT;
+connection node_1a_galera_st_shutdown_slave;
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+ROLLBACK;
+SELECT COUNT(*) = 35 FROM t1;
+COUNT(*) = 35
+1
+SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
+COUNT(*) = 0
+1
+COMMIT;
+SET AUTOCOMMIT=ON;
+connection node_1;
+SELECT COUNT(*) = 35 FROM t1;
+COUNT(*) = 35
+1
+SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
+COUNT(*) = 0
+1
+DROP TABLE t1;
+COMMIT;
+SET AUTOCOMMIT=ON;
+Performing State Transfer on a server that starts from a clean var directory
+This is accomplished by shutting down node #2 and removing its var directory before restarting it
+connection node_1;
+CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+COMMIT;
+connection node_2;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+COMMIT;
+Shutting down server ...
+connection node_1;
+Cleaning var directory ...
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+COMMIT;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+connect node_1a_galera_st_clean_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+connection node_2;
+Starting server ...
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+COMMIT;
+connection node_1;
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+COMMIT;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+COMMIT;
+connection node_1a_galera_st_clean_slave;
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+ROLLBACK;
+SELECT COUNT(*) = 35 FROM t1;
+COUNT(*) = 35
+1
+SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
+COUNT(*) = 0
+1
+COMMIT;
+SET AUTOCOMMIT=ON;
+connection node_1;
+SELECT COUNT(*) = 35 FROM t1;
+COUNT(*) = 35
+1
+SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
+COUNT(*) = 0
+1
+DROP TABLE t1;
+COMMIT;
+SET AUTOCOMMIT=ON;
+Performing State Transfer on a server that has been killed and restarted
+connection node_1;
+CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+COMMIT;
+connection node_2;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+COMMIT;
+Killing server ...
+connection node_1;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+INSERT INTO t1 VALUES ('node1_committed_during');
+COMMIT;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+connect node_1a_galera_st_kill_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+connection node_2;
+Performing --wsrep-recover ...
+Starting server ...
+Using --wsrep-start-position when starting mysqld ...
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+INSERT INTO t1 VALUES ('node2_committed_after');
+COMMIT;
+connection node_1;
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 VALUES ('node1_to_be_committed_after');
+COMMIT;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+INSERT INTO t1 VALUES ('node1_committed_after');
+COMMIT;
+connection node_1a_galera_st_kill_slave;
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after');
+ROLLBACK;
+SELECT COUNT(*) = 35 FROM t1;
+COUNT(*) = 35
+1
+SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
+COUNT(*) = 0
+1
+COMMIT;
+SET AUTOCOMMIT=ON;
+connection node_1;
+SELECT COUNT(*) = 35 FROM t1;
+COUNT(*) = 35
+1
+SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
+COUNT(*) = 0
+1
+DROP TABLE t1;
+COMMIT;
+SET AUTOCOMMIT=ON;
+Performing State Transfer on a server that has been killed and restarted
+while a DDL was in progress on it
+connection node_1;
+CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+INSERT INTO t1 VALUES ('node1_committed_before');
+connection node_2;
+START TRANSACTION;
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+INSERT INTO t1 VALUES ('node2_committed_before');
+COMMIT;
+SET GLOBAL debug_dbug = 'd,sync.alter_opened_table';
+connection node_1;
+ALTER TABLE t1 ADD COLUMN f2 INTEGER;
+connection node_2;
+SET wsrep_sync_wait = 0;
+Killing server ...
+connection node_1;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 (f1) VALUES ('node1_committed_during');
+INSERT INTO t1 (f1) VALUES ('node1_committed_during');
+INSERT INTO t1 (f1) VALUES ('node1_committed_during');
+INSERT INTO t1 (f1) VALUES ('node1_committed_during');
+INSERT INTO t1 (f1) VALUES ('node1_committed_during');
+COMMIT;
+START TRANSACTION;
+INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
+connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
+connection node_2;
+Performing --wsrep-recover ...
+connection node_2;
+Starting server ...
+Using --wsrep-start-position when starting mysqld ...
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 (f1) VALUES ('node2_committed_after');
+INSERT INTO t1 (f1) VALUES ('node2_committed_after');
+INSERT INTO t1 (f1) VALUES ('node2_committed_after');
+INSERT INTO t1 (f1) VALUES ('node2_committed_after');
+INSERT INTO t1 (f1) VALUES ('node2_committed_after');
+COMMIT;
+connection node_1;
+INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after');
+COMMIT;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 (f1) VALUES ('node1_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_committed_after');
+INSERT INTO t1 (f1) VALUES ('node1_committed_after');
+COMMIT;
+connection node_1a_galera_st_kill_slave_ddl;
+INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
+INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after');
+ROLLBACK;
+SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
+COUNT(*) = 2
+1
+SELECT COUNT(*) = 35 FROM t1;
+COUNT(*) = 35
+1
+SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
+COUNT(*) = 0
+1
+COMMIT;
+SET AUTOCOMMIT=ON;
+connection node_1;
+SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
+COUNT(*) = 2
+1
+SELECT COUNT(*) = 35 FROM t1;
+COUNT(*) = 35
+1
+SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
+COUNT(*) = 0
+1
+DROP TABLE t1;
+COMMIT;
+SET AUTOCOMMIT=ON;
+SET GLOBAL debug_dbug = $debug_orig;
diff --git a/mysql-test/suite/galera/r/galera_var_desync_on.result b/mysql-test/suite/galera/r/galera_var_desync_on.result
index a26acbd4d6b..26798e51926 100644
--- a/mysql-test/suite/galera/r/galera_var_desync_on.result
+++ b/mysql-test/suite/galera/r/galera_var_desync_on.result
@@ -2,7 +2,6 @@ CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
connection node_2;
SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1';
-SET GLOBAL wsrep_desync = TRUE;
FLUSH TABLES WITH READ LOCK;
connection node_1;
INSERT INTO t1 VALUES (2);
@@ -19,7 +18,6 @@ SET SESSION wsrep_sync_wait = 0;
SELECT COUNT(*) = 1 FROM t1;
COUNT(*) = 1
1
-SET GLOBAL wsrep_desync = FALSE;
UNLOCK TABLES;
SET SESSION wsrep_sync_wait = 1;
SELECT COUNT(*) = 10 FROM t1;
diff --git a/mysql-test/suite/galera/t/MW-336.test b/mysql-test/suite/galera/t/MW-336.test
index 8cd363aa019..4bdbfb2ecff 100644
--- a/mysql-test/suite/galera/t/MW-336.test
+++ b/mysql-test/suite/galera/t/MW-336.test
@@ -8,15 +8,28 @@
CREATE TABLE t1 (f1 INTEGER) Engine=InnoDB;
--connection node_1
+
SET GLOBAL wsrep_slave_threads = 10;
SET GLOBAL wsrep_slave_threads = 1;
+
+--let $wait_timeout=600
--let $wait_condition = SELECT COUNT(*) = 11 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND (STATE IS NULL OR STATE NOT LIKE 'InnoDB%');
--source include/wait_condition.inc
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND (STATE IS NULL OR STATE NOT LIKE 'InnoDB%');
+SHOW STATUS LIKE 'wsrep_thread_count';
+
--connection node_2
-INSERT INTO t1 VALUES (1);
+# Generate 11 replication events
+--let $count = 11
+while ($count)
+{
+ INSERT INTO t1 VALUES (1);
+ --dec $count
+}
--connection node_1
+
SET GLOBAL wsrep_slave_threads = 10;
--let $wait_condition = SELECT COUNT(*) = 11 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND (STATE IS NULL OR STATE NOT LIKE 'InnoDB%');
--source include/wait_condition.inc
@@ -28,40 +41,40 @@ SET GLOBAL wsrep_slave_threads = 20;
SET GLOBAL wsrep_slave_threads = 1;
--connection node_2
-INSERT INTO t1 VALUES (1);
-INSERT INTO t1 VALUES (2);
-INSERT INTO t1 VALUES (3);
-INSERT INTO t1 VALUES (4);
-INSERT INTO t1 VALUES (5);
-INSERT INTO t1 VALUES (6);
-INSERT INTO t1 VALUES (7);
-INSERT INTO t1 VALUES (8);
-INSERT INTO t1 VALUES (9);
-
-
---connection node_1
---let $wait_condition = SELECT COUNT(*) = 12 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND (STATE IS NULL OR STATE NOT LIKE 'InnoDB%');
---source include/wait_condition.inc
+# Generate 21 replication events
+--let $count = 21
+while ($count)
+{
+ INSERT INTO t1 VALUES (1);
+ --dec $count
+}
SET GLOBAL wsrep_slave_threads = 10;
SET GLOBAL wsrep_slave_threads = 0;
--connection node_2
-INSERT INTO t1 VALUES (10);
-INSERT INTO t1 VALUES (11);
-INSERT INTO t1 VALUES (12);
-INSERT INTO t1 VALUES (13);
-INSERT INTO t1 VALUES (14);
-INSERT INTO t1 VALUES (15);
-INSERT INTO t1 VALUES (16);
-INSERT INTO t1 VALUES (17);
-INSERT INTO t1 VALUES (18);
-INSERT INTO t1 VALUES (19);
-INSERT INTO t1 VALUES (20);
+# Generate 21 replication events
+--let $count = 21
+while ($count)
+{
+ INSERT INTO t1 VALUES (1);
+ --dec $count
+}
--connection node_1
--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND (STATE IS NULL OR STATE NOT LIKE 'InnoDB%');
--source include/wait_condition.inc
SET GLOBAL wsrep_slave_threads = 1;
+
+--connection node_2
+# Generate 21 replication events
+--let $count = 21
+while ($count)
+{
+ INSERT INTO t1 VALUES (1);
+ --dec $count
+}
+
+--connection node_1
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/MW-44.test b/mysql-test/suite/galera/t/MW-44.test
index 7c988a29548..e8caa28c80e 100644
--- a/mysql-test/suite/galera/t/MW-44.test
+++ b/mysql-test/suite/galera/t/MW-44.test
@@ -8,20 +8,21 @@
--connection node_1
SET GLOBAL general_log='OFF';
TRUNCATE TABLE mysql.general_log;
-SELECT COUNT(*) from mysql.general_log;
-SELECT * FROM mysql.general_log;
+--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.general_log;
+--source include/wait_condition.inc
--sleep 1
--connection node_2
SET GLOBAL general_log='OFF';
TRUNCATE TABLE mysql.general_log;
-SELECT COUNT(*) from mysql.general_log;
-SELECT * FROM mysql.general_log;
+--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.general_log;
+--source include/wait_condition.inc
--sleep 1
--connection node_1
SET GLOBAL general_log='ON';
-SELECT COUNT(*) from mysql.general_log;
+SELECT argument from mysql.general_log WHERE argument NOT LIKE 'SELECT%';
+
SET SESSION wsrep_osu_method=TOI;
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
SET SESSION wsrep_osu_method=RSU;
diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_data_dir.cnf b/mysql-test/suite/galera/t/galera_sst_rsync_data_dir.cnf
new file mode 100644
index 00000000000..afe9796a11a
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_sst_rsync_data_dir.cnf
@@ -0,0 +1,11 @@
+!include ../galera_2nodes.cnf
+
+[mysqld]
+wsrep_sst_method=rsync
+
+[mysqld.1]
+wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true'
+
+[mysqld.2]
+innodb_data_home_dir=@ENV.MYSQL_TMP_DIR/rsync_test_2
+wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_data_dir.test b/mysql-test/suite/galera/t/galera_sst_rsync_data_dir.test
new file mode 100644
index 00000000000..68aa1068f75
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_sst_rsync_data_dir.test
@@ -0,0 +1,16 @@
+--source include/big_test.inc
+--source include/galera_cluster.inc
+
+--let $node_1=node_1
+--let $node_2=node_2
+--source include/auto_increment_offset_save.inc
+
+--source suite/galera/include/galera_st_shutdown_slave.inc
+--source suite/galera/include/galera_st_clean_slave.inc
+
+--source suite/galera/include/galera_st_kill_slave.inc
+--source suite/galera/include/galera_st_kill_slave_ddl.inc
+--source include/auto_increment_offset_restore.inc
+
+# cleanup temporary database files:
+--remove_files_wildcard $MYSQL_TMP_DIR/rsync_test_2 *
diff --git a/mysql-test/suite/galera/t/galera_var_desync_on.test b/mysql-test/suite/galera/t/galera_var_desync_on.test
index 06c5d30a769..fbf660d3ab5 100644
--- a/mysql-test/suite/galera/t/galera_var_desync_on.test
+++ b/mysql-test/suite/galera/t/galera_var_desync_on.test
@@ -1,5 +1,7 @@
#
-# Test wsrep_desync = ON . Node should temporarily not participate in flow control
+# Desync will be done once the global read lock is acquired and resync will be done when
+# it is released.
+# Node should temporarily not participate in flow control
# so even if fc_limit has been reached, the master should be able to continue to
# commit transactions.
#
@@ -13,7 +15,6 @@ INSERT INTO t1 VALUES (1);
--connection node_2
--let $wsrep_provider_options_orig = `SELECT @@wsrep_provider_options`
SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=1';
-SET GLOBAL wsrep_desync = TRUE;
# Block the slave applier thread
FLUSH TABLES WITH READ LOCK;
@@ -37,8 +38,6 @@ SET SESSION wsrep_sync_wait = 0;
# No updates have arrived after the FLUSH TABLES
SELECT COUNT(*) = 1 FROM t1;
-# Resync the slave
-SET GLOBAL wsrep_desync = FALSE;
--disable_query_log
--eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_orig';
--enable_query_log
diff --git a/mysql-test/suite/maria/concurrent.result b/mysql-test/suite/maria/concurrent.result
new file mode 100644
index 00000000000..caea6fd1fb9
--- /dev/null
+++ b/mysql-test/suite/maria/concurrent.result
@@ -0,0 +1,33 @@
+CREATE TABLE t1 (a INT, b CHAR(12), c INT, FULLTEXT KEY(b), KEY (c)) ENGINE=Aria;
+CREATE TABLE t2 (a INT, b CHAR(12), c INT) ENGINE=Aria;
+INSERT INTO t2 VALUES (1,'foo',8), (2,'bar',9);
+connect con1,localhost,root,,test;
+INSERT INTO t1 SELECT * FROM t2;
+connection default;
+select 1;
+1
+1
+select 1;
+1
+1
+select 1;
+1
+1
+select 1;
+1
+1
+select 1;
+1
+1
+select 1;
+1
+1
+select 1;
+1
+1
+SELECT * FROM t1 WHERE a = ( SELECT 1 FROM non_existing_table2 );
+ERROR 42S02: Table 'test.non_existing_table2' doesn't exist
+connection con1;
+disconnect con1;
+connection default;
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/maria/concurrent.test b/mysql-test/suite/maria/concurrent.test
new file mode 100644
index 00000000000..42adb082d40
--- /dev/null
+++ b/mysql-test/suite/maria/concurrent.test
@@ -0,0 +1,28 @@
+#
+# MDEV-15797 Assertion `thd->killed != 0' failed in ha_maria::enable_indexes
+#
+
+CREATE TABLE t1 (a INT, b CHAR(12), c INT, FULLTEXT KEY(b), KEY (c)) ENGINE=Aria;
+CREATE TABLE t2 (a INT, b CHAR(12), c INT) ENGINE=Aria;
+INSERT INTO t2 VALUES (1,'foo',8), (2,'bar',9);
+
+--connect (con1,localhost,root,,test)
+--send
+ INSERT INTO t1 SELECT * FROM t2;
+--connection default
+select 1;
+select 1;
+select 1;
+select 1;
+select 1;
+select 1;
+select 1;
+--error ER_NO_SUCH_TABLE
+SELECT * FROM t1 WHERE a = ( SELECT 1 FROM non_existing_table2 );
+--connection con1
+--reap
+
+# Cleanup
+--disconnect con1
+--connection default
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/maria/maria.result b/mysql-test/suite/maria/maria.result
index 765a417e4f2..c17ae47322e 100644
--- a/mysql-test/suite/maria/maria.result
+++ b/mysql-test/suite/maria/maria.result
@@ -2227,9 +2227,9 @@ Block_size: 8192
Recordlength: 99
Table description:
-Key Start Len Index Type
-1 2 30 multip. varchar
-2 33 30 multip. char NULL
+Key Start Len Index Type
+1 2 30 multip. varchar
+2 33 30 multip. char NULL
DROP TABLE t1;
create table t1 (n int not null, c char(1)) transactional=1;
show create table t1;
diff --git a/mysql-test/suite/mariabackup/disabled.def b/mysql-test/suite/mariabackup/disabled.def
deleted file mode 100644
index a7be04bfc16..00000000000
--- a/mysql-test/suite/mariabackup/disabled.def
+++ /dev/null
@@ -1 +0,0 @@
-unsupported_redo : MDEV-16791 allows optimized redo \ No newline at end of file
diff --git a/mysql-test/suite/mariabackup/skip_innodb.opt b/mysql-test/suite/mariabackup/skip_innodb.opt
new file mode 100644
index 00000000000..213331f5575
--- /dev/null
+++ b/mysql-test/suite/mariabackup/skip_innodb.opt
@@ -0,0 +1 @@
+--loose-skip-innodb \ No newline at end of file
diff --git a/mysql-test/suite/mariabackup/skip_innodb.result b/mysql-test/suite/mariabackup/skip_innodb.result
new file mode 100644
index 00000000000..0d56b55bf4b
--- /dev/null
+++ b/mysql-test/suite/mariabackup/skip_innodb.result
@@ -0,0 +1,10 @@
+CREATE TABLE t(i int);
+INSERT INTO t VALUES(1);
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT * from t;
+i
+1
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/skip_innodb.test b/mysql-test/suite/mariabackup/skip_innodb.test
new file mode 100644
index 00000000000..14e4bc007f6
--- /dev/null
+++ b/mysql-test/suite/mariabackup/skip_innodb.test
@@ -0,0 +1,12 @@
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+CREATE TABLE t(i int);
+INSERT INTO t VALUES(1);
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir;
+exec $XTRABACKUP --prepare --target-dir=$targetdir;
+-- source include/restart_and_restore.inc
+--enable_result_log
+SELECT * from t;
+DROP TABLE t;
+
+rmdir $targetdir; \ No newline at end of file
diff --git a/mysql-test/suite/mariabackup/truncate_during_backup.result b/mysql-test/suite/mariabackup/truncate_during_backup.result
new file mode 100644
index 00000000000..f9d5c785749
--- /dev/null
+++ b/mysql-test/suite/mariabackup/truncate_during_backup.result
@@ -0,0 +1,4 @@
+CREATE TABLE t1 ENGINE=InnoDB SELECT 1;
+DROP TABLE t1;
+SET GLOBAL innodb_log_checkpoint_now=1;
+SET GLOBAL innodb_log_checkpoint_now=DEFAULT;
diff --git a/mysql-test/suite/mariabackup/truncate_during_backup.test b/mysql-test/suite/mariabackup/truncate_during_backup.test
new file mode 100644
index 00000000000..c01a74588e7
--- /dev/null
+++ b/mysql-test/suite/mariabackup/truncate_during_backup.test
@@ -0,0 +1,19 @@
+--source include/have_debug.inc
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+mkdir $targetdir;
+
+CREATE TABLE t1 ENGINE=InnoDB SELECT 1;
+
+--let after_load_tablespaces=TRUNCATE test.t1
+
+--disable_result_log
+--error 1
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events;
+--enable_result_log
+
+--let after_load_tablespaces=
+
+DROP TABLE t1;
+SET GLOBAL innodb_log_checkpoint_now=1;
+SET GLOBAL innodb_log_checkpoint_now=DEFAULT;
+rmdir $targetdir;
diff --git a/mysql-test/suite/mariabackup/unsupported_redo.result b/mysql-test/suite/mariabackup/unsupported_redo.result
index a1f95c099cd..fbad89be0ac 100644
--- a/mysql-test/suite/mariabackup/unsupported_redo.result
+++ b/mysql-test/suite/mariabackup/unsupported_redo.result
@@ -7,7 +7,7 @@ call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: ");
call mtr.add_suppression("Table .* in the InnoDB data dictionary has tablespace id .*, but tablespace with that id or name does not exist");
CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB;
ALTER TABLE t1 FORCE, ALGORITHM=INPLACE;
-# Fails during full backup
+# No longer fails during full backup
DROP TABLE t1;
CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB;
INSERT INTO t1(a) select 1 union select 2 union select 3;
diff --git a/mysql-test/suite/mariabackup/unsupported_redo.test b/mysql-test/suite/mariabackup/unsupported_redo.test
index 319ee2c7571..b9456751b9c 100644
--- a/mysql-test/suite/mariabackup/unsupported_redo.test
+++ b/mysql-test/suite/mariabackup/unsupported_redo.test
@@ -11,33 +11,15 @@ let $basedir=$MYSQLTEST_VARDIR/tmp/backup;
let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1;
CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB;
---source ../../suite/innodb/include/no_checkpoint_start.inc
ALTER TABLE t1 FORCE, ALGORITHM=INPLACE;
-# Below mariabackup operation may complete successfully if checkpoint happens
-# after the alter table command.
-
-echo # Fails during full backup;
+echo # No longer fails during full backup;
--disable_result_log
---error 0,1
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir;
--enable_result_log
DROP TABLE t1;
---let MYSQLD_DATADIR=$basedir/
-perl;
-open(OUT, ">$ENV{MYSQLTEST_VARDIR}/log/check.txt") || die;
-print OUT '
---let no_checkpoint_end=1
---let CLEANUP_IF_CHECKPOINT=rmdir $basedir;
---source ../../suite/innodb/include/no_checkpoint_end.inc
---exit Backup failed to fail despite MLOG_INDEX_LOAD record
-' if (-f "$ENV{MYSQLD_DATADIR}/xtrabackup_info");
-close(OUT);
-EOF
---source $MYSQLTEST_VARDIR/log/check.txt
---remove_file $MYSQLTEST_VARDIR/log/check.txt
rmdir $basedir;
CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB;
@@ -50,29 +32,14 @@ INSERT INTO t1(a) select 1 union select 2 union select 3;
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir;
--enable_result_log
---source ../../suite/innodb/include/no_checkpoint_start.inc
ALTER TABLE t1 FORCE, ALGORITHM=INPLACE;
--disable_result_log
---error 0,1
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir;
--enable_result_log
DROP TABLE t1;
---let MYSQLD_DATADIR=$incremental_dir/
-perl;
-open(OUT, ">$ENV{MYSQLTEST_VARDIR}/log/check.txt") || die;
-print OUT '
---let no_checkpoint_end=1
---let CLEANUP_IF_CHECKPOINT=rmdir $basedir;rmdir $incremental_dir;
---source ../../suite/innodb/include/no_checkpoint_end.inc
---exit Backup failed to fail despite MLOG_INDEX_LOAD record
-' if (-f "$ENV{MYSQLD_DATADIR}/xtrabackup_info");
-close(OUT);
-EOF
---source $MYSQLTEST_VARDIR/log/check.txt
---remove_file $MYSQLTEST_VARDIR/log/check.txt
rmdir $basedir;rmdir $incremental_dir;
CREATE TABLE t1(i INT) ENGINE INNODB;
diff --git a/mysql-test/suite/plugins/r/auth_ed25519.result b/mysql-test/suite/plugins/r/auth_ed25519.result
index ee9320bbc6c..4785bef3ef7 100644
--- a/mysql-test/suite/plugins/r/auth_ed25519.result
+++ b/mysql-test/suite/plugins/r/auth_ed25519.result
@@ -33,7 +33,7 @@ PLUGIN_DESCRIPTION Elliptic curve ED25519 based authentication
PLUGIN_LICENSE GPL
LOAD_OPTION ON
PLUGIN_MATURITY Stable
-PLUGIN_AUTH_VERSION 1.0-alpha
+PLUGIN_AUTH_VERSION 1.0
create user test1@localhost identified via ed25519 using 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY';
show grants for test1@localhost;
Grants for test1@localhost
diff --git a/mysql-test/suite/rpl/r/rpl_row_spatial.result b/mysql-test/suite/rpl/r/rpl_row_spatial.result
new file mode 100644
index 00000000000..86bac89a174
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_spatial.result
@@ -0,0 +1,16 @@
+include/master-slave.inc
+[connection master]
+CREATE TABLE t1 (g POINT NOT NULL, SPATIAL INDEX(g));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(1 1)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(2 1)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(1 2)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(2 2)'));
+DELETE FROM t1 where MBREqual(g, ST_GEOMFROMTEXT('Point(1 2)'));
+connection slave;
+select count(*) from t1;
+count(*)
+3
+connection master;
+DELETE FROM t1;
+drop table t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_row_spatial.test b/mysql-test/suite/rpl/t/rpl_row_spatial.test
new file mode 100644
index 00000000000..00c3dd7c54d
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_spatial.test
@@ -0,0 +1,17 @@
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+CREATE TABLE t1 (g POINT NOT NULL, SPATIAL INDEX(g));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(1 1)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(2 1)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(1 2)'));
+INSERT INTO t1 VALUES (ST_GEOMFROMTEXT('Point(2 2)'));
+DELETE FROM t1 where MBREqual(g, ST_GEOMFROMTEXT('Point(1 2)'));
+
+--sync_slave_with_master
+select count(*) from t1;
+
+--connection master
+DELETE FROM t1;
+drop table t1;
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/sql_sequence/auto_increment.result b/mysql-test/suite/sql_sequence/auto_increment.result
new file mode 100644
index 00000000000..bf0a04bbaf1
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/auto_increment.result
@@ -0,0 +1,30 @@
+set global auto_increment_increment= 2, auto_increment_offset= 2;
+create sequence s start with -3 minvalue= -1000 increment 0;
+select nextval(s);
+nextval(s)
+-2
+select nextval(s);
+nextval(s)
+0
+flush tables;
+select nextval(s);
+nextval(s)
+1998
+drop sequence s;
+set global auto_increment_increment= 2, auto_increment_offset= 1;
+create sequence s start with -3 minvalue= -1000 increment 0;
+select nextval(s);
+nextval(s)
+-3
+select nextval(s);
+nextval(s)
+-1
+select nextval(s);
+nextval(s)
+1
+flush tables;
+select nextval(s);
+nextval(s)
+1997
+drop sequence s;
+set global auto_increment_increment= default, auto_increment_offset= default;
diff --git a/mysql-test/suite/sql_sequence/auto_increment.test b/mysql-test/suite/sql_sequence/auto_increment.test
new file mode 100644
index 00000000000..335bef7ea37
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/auto_increment.test
@@ -0,0 +1,30 @@
+--source include/have_sequence.inc
+
+#
+# tests with auto_increment_increment and auto_increment_offset
+#
+
+set global auto_increment_increment= 2, auto_increment_offset= 2;
+
+create sequence s start with -3 minvalue= -1000 increment 0;
+
+select nextval(s);
+select nextval(s);
+flush tables;
+select nextval(s);
+drop sequence s;
+
+set global auto_increment_increment= 2, auto_increment_offset= 1;
+
+create sequence s start with -3 minvalue= -1000 increment 0;
+
+select nextval(s);
+select nextval(s);
+select nextval(s);
+flush tables;
+select nextval(s);
+drop sequence s;
+
+# Clean up
+
+set global auto_increment_increment= default, auto_increment_offset= default;
diff --git a/mysql-test/suite/sql_sequence/next.result b/mysql-test/suite/sql_sequence/next.result
index d138c342c9d..b1b1bb69306 100644
--- a/mysql-test/suite/sql_sequence/next.result
+++ b/mysql-test/suite/sql_sequence/next.result
@@ -519,3 +519,18 @@ create temporary table tmp (i int);
select next value for tmp;
ERROR 42S02: 'test.tmp' is not a SEQUENCE
drop table tmp;
+#
+# Test negative numbers
+#
+create sequence s start with 1 minvalue=-1000 maxvalue=1000 increment -1;
+select next value for s;
+next value for s
+1
+select next value for s;
+next value for s
+0
+flush tables;
+select next value for s;
+next value for s
+-999
+drop sequence s;
diff --git a/mysql-test/suite/sql_sequence/next.test b/mysql-test/suite/sql_sequence/next.test
index 79249002d8f..a1f91bd7823 100644
--- a/mysql-test/suite/sql_sequence/next.test
+++ b/mysql-test/suite/sql_sequence/next.test
@@ -269,3 +269,14 @@ create temporary table tmp (i int);
--error ER_NOT_SEQUENCE
select next value for tmp;
drop table tmp;
+
+--echo #
+--echo # Test negative numbers
+--echo #
+
+create sequence s start with 1 minvalue=-1000 maxvalue=1000 increment -1;
+select next value for s;
+select next value for s;
+flush tables;
+select next value for s;
+drop sequence s;
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
index 01c426b117f..e5a684e71fe 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -880,6 +880,20 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT NULL
+VARIABLE_NAME EQ_RANGE_INDEX_DIVE_LIMIT
+SESSION_VALUE 0
+GLOBAL_VALUE 0
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 0
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE INT UNSIGNED
+VARIABLE_COMMENT The optimizer will use existing index statistics instead of doing index dives for equality ranges if the number of equality ranges for the index is larger than or equal to this number. If set to 0, index dives are always used.
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 4294967295
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME ERROR_COUNT
SESSION_VALUE 0
GLOBAL_VALUE NULL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index 9f9513867a9..08214e3e888 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -894,6 +894,20 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT NULL
+VARIABLE_NAME EQ_RANGE_INDEX_DIVE_LIMIT
+SESSION_VALUE 0
+GLOBAL_VALUE 0
+GLOBAL_VALUE_ORIGIN COMPILE-TIME
+DEFAULT_VALUE 0
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE INT UNSIGNED
+VARIABLE_COMMENT The optimizer will use existing index statistics instead of doing index dives for equality ranges if the number of equality ranges for the index is larger than or equal to this number. If set to 0, index dives are always used.
+NUMERIC_MIN_VALUE 0
+NUMERIC_MAX_VALUE 4294967295
+NUMERIC_BLOCK_SIZE 1
+ENUM_VALUE_LIST NULL
+READ_ONLY NO
+COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME ERROR_COUNT
SESSION_VALUE 0
GLOBAL_VALUE NULL
diff --git a/mysql-test/suite/vcol/r/index.result b/mysql-test/suite/vcol/r/index.result
index 8860a728bd1..6ab9aa5eb29 100644
--- a/mysql-test/suite/vcol/r/index.result
+++ b/mysql-test/suite/vcol/r/index.result
@@ -89,3 +89,13 @@ pk left(c, 10) length(c) i
1 bar bar ba 60000 11
drop table t1;
disconnect c1;
+CREATE TABLE t1 (b BLOB, vb TEXT AS (b) PERSISTENT, KEY(vb(64))) ENGINE=InnoDB;
+INSERT INTO t1 (b) VALUES ('foo');
+connect con1,localhost,root,,test;
+CREATE TABLE t2 LIKE t1;
+connection default;
+DELETE FROM t1;
+connection con1;
+disconnect con1;
+connection default;
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/vcol/t/index.test b/mysql-test/suite/vcol/t/index.test
index 72eed0a8a40..b93c337fab6 100644
--- a/mysql-test/suite/vcol/t/index.test
+++ b/mysql-test/suite/vcol/t/index.test
@@ -79,3 +79,19 @@ commit;
select pk, left(c, 10), length(c), i from t1;
drop table t1;
disconnect c1;
+
+#
+# MDEV-16961 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed upon concurrent DELETE and DDL with virtual blob column
+#
+
+CREATE TABLE t1 (b BLOB, vb TEXT AS (b) PERSISTENT, KEY(vb(64))) ENGINE=InnoDB;
+INSERT INTO t1 (b) VALUES ('foo');
+--connect (con1,localhost,root,,test)
+--send CREATE TABLE t2 LIKE t1
+--connection default
+DELETE FROM t1;
+--connection con1
+--reap
+--disconnect con1
+--connection default
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/versioning/r/truncate.result b/mysql-test/suite/versioning/r/truncate.result
index 308501915dc..d38b9eed162 100644
--- a/mysql-test/suite/versioning/r/truncate.result
+++ b/mysql-test/suite/versioning/r/truncate.result
@@ -100,5 +100,11 @@ ERROR 42S02: 'v' is a view
unlock tables;
drop view v;
drop table t;
+create table t1 (i int) with system versioning;
+create procedure pr() delete history from t1 before system_time now();
+call pr;
+call pr;
+drop procedure pr;
+drop table t1;
drop database test;
create database test;
diff --git a/mysql-test/suite/versioning/t/truncate.test b/mysql-test/suite/versioning/t/truncate.test
index 4e039a76567..1727c7787ef 100644
--- a/mysql-test/suite/versioning/t/truncate.test
+++ b/mysql-test/suite/versioning/t/truncate.test
@@ -107,5 +107,15 @@ unlock tables;
drop view v;
drop table t;
+#
+# MDEV-16783 Assertion `!conds' failed in mysql_delete upon 2nd execution of SP with DELETE HISTORY
+#
+create table t1 (i int) with system versioning;
+create procedure pr() delete history from t1 before system_time now();
+call pr;
+call pr;
+drop procedure pr;
+drop table t1;
+
drop database test;
create database test;
diff --git a/mysql-test/suite/wsrep/t/variables.test b/mysql-test/suite/wsrep/t/variables.test
index 1315f090d5c..40b869422ff 100644
--- a/mysql-test/suite/wsrep/t/variables.test
+++ b/mysql-test/suite/wsrep/t/variables.test
@@ -101,8 +101,10 @@ SHOW STATUS LIKE 'wsrep_thread_count';
--echo # Setting wsrep_cluster_address triggers the creation of
--echo # applier/rollbacker threads.
SET GLOBAL wsrep_cluster_address= 'gcomm://';
+
--echo # Wait for applier threads to get created.
-sleep 3;
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
+--source include/wait_condition.inc
--replace_regex /.*libgalera_smm.*/libgalera_smm.so/
SELECT @@global.wsrep_provider;
@@ -113,8 +115,11 @@ SHOW STATUS LIKE 'wsrep_thread_count';
SET @wsrep_slave_threads_saved= @@global.wsrep_slave_threads;
SET GLOBAL wsrep_slave_threads= 10;
+
--echo # Wait for applier threads to get created.
-sleep 3;
+--let $wait_condition = SELECT VARIABLE_VALUE = 11 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
+--source include/wait_condition.inc
+
SHOW STATUS LIKE 'threads_connected';
SHOW STATUS LIKE 'wsrep_thread_count';
diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests
index d97792355b4..2c28c9a663b 100644
--- a/mysql-test/unstable-tests
+++ b/mysql-test/unstable-tests
@@ -23,7 +23,7 @@
#
##############################################################################
-# Based on bb-10.3-release 36e59752e7fc70bc5179a3d730b5ce3ee58e4e30
+# Based on bb-10.3-release fac3e575b203e8d6a522a475f9aab4ec5041b146
#-----------------------------------------------------------------------
@@ -32,12 +32,17 @@ archive.archive_symlink : MDEV-12170
archive.discover : MDEV-10510 - Table is marked as crashed
archive.mysqlhotcopy_archive : MDEV-10995 - Hang on debug
+archive-test_sql_discovery.discover : MDEV-16817 - Table marked as crashed
+
#-----------------------------------------------------------------------
binlog.binlog_commit_wait : MDEV-10150 - Mismatch
binlog.binlog_flush_binlogs_delete_domain : MDEV-14431 - Wrong exit code
binlog.binlog_killed : MDEV-12925 - Wrong result
+binlog.binlog_tmp_table_row : Added in 10.1.35, 10.2.17
binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint
+binlog.load_data_stm_view : MDEV-16948 - Wrong result
+binlog_tmp_table_row : Added in 10.3.9
#-----------------------------------------------------------------------
@@ -47,6 +52,8 @@ binlog_encryption.encrypted_master_switch_to_unencrypted : MDEV-14190
binlog_encryption.encrypted_slave : Modified in 10.3.8
binlog_encryption.encryption_combo : MDEV-14199 - Table is marked as crashed
binlog_encryption.rpl_binlog_errors : MDEV-12742 - Crash
+binlog_encryption.rpl_checksum : MDEV-16951 - Wrong result
+binlog_encryption.rpl_gtid_basic : MDEV-16947 - Server failed to start
binlog_encryption.rpl_loadfile : MDEV-16645 - Timeout in include
binlog_encryption.rpl_parallel : MDEV-10653 - Timeout in include
binlog_encryption.rpl_relayrotate : MDEV-15194 - Timeout
@@ -55,17 +62,13 @@ binlog_encryption.rpl_skip_replication : MDEV-13571
binlog_encryption.rpl_ssl : MDEV-14507 - Timeouts
binlog_encryption.rpl_stm_relay_ign_space : MDEV-13278 - Wrong result (test assertion)
binlog_encryption.rpl_sync : MDEV-13830 - Assertion failure
+binlog_encryption.rpl_typeconv : MDEV-14362 - Lost connection to MySQL server during query
#-----------------------------------------------------------------------
-compat/oracle.column_compression : Added in 10.3.7
-compat/oracle.func_concat : Modified in 10.3.7
-compat/oracle.gis : Added in 10.3.7
+compat/oracle.events : Added in 10.3.9
compat/oracle.parser : Modified in 10.3.8
compat/oracle.sp-cursor-rowtype : Modified in 10.3.8
-compat/oracle.table_value_constr : Added in 10.3.7
-compat/oracle.versioning : Added in 10.3.7
-compat/oracle.win : Added in 10.3.7
#-----------------------------------------------------------------------
@@ -79,7 +82,7 @@ encryption.create_or_replace : MDEV-12694
encryption.debug_key_management : MDEV-13841 - Timeout
encryption.encrypt_and_grep : MDEV-13765 - Wrong result
encryption.innochecksum : MDEV-13644 - Assertion failure
-encryption.innodb-checksum-algorithm : MDEV-12898 - Deadlock of threads
+encryption.innodb-checksum-algorithm : MDEV-12898 - Deadlock of threads; MDEV-16896 - Server crash
encryption.innodb-compressed-blob : MDEV-14728 - Unable to get certificate
encryption.innodb-discard-import : Modified in 10.3.8
encryption.innodb-encryption-alter : MDEV-13566 - Lock wait timeout
@@ -97,6 +100,7 @@ encryption.innodb_encryption_discard_import : MDEV-16116
encryption.innodb_encryption_filekeys : MDEV-15673 - Timeout
encryption.innodb_encryption_row_compressed : MDEV-16113 - Crash
encryption.innodb_first_page : MDEV-10689 - Crash
+encryption.innodb_lotoftables : MDEV-16111 - Wrong result
encryption.innodb_scrub : MDEV-8139 - scrubbing tests need fixing
encryption.innodb_scrub_background : MDEV-8139 - scrubbing tests need fixing
encryption.innodb_scrub_compressed : MDEV-8139 - scrubbing tests need fixing
@@ -109,18 +113,17 @@ engines/rr_trx.* : MDEV-10998
#-----------------------------------------------------------------------
-federated.assisted_discovery : Modified in 10.3.7
+federated.assisted_discovery : Include file modified in 10.0.36
federated.federated_bug_35333 : MDEV-13410 - Wrong result
federated.federated_bug_585688 : MDEV-14805 - Server crash, MDEV-12907 - Valgrind
federated.federated_innodb : MDEV-10617 - Wrong checksum
federated.federated_partition : MDEV-10417 - Fails on Mips
federated.federated_transactions : MDEV-10617 - Wrong checksum
federated.federatedx : MDEV-10617 - Wrong checksum
-federated.federatedx_versioning : Added in 10.3.7
-federated.timestamps : Added in 10.3.7
#-----------------------------------------------------------------------
+funcs_1.is_engines_federated : Include file modified in 10.0.36
funcs_1.memory_views : MDEV-11773 - timeout
funcs_1.processlist_val_no_prot : MDEV-11223 - Wrong result
funcs_1.processlist_val_ps : MDEV-12175 - Wrong plan
@@ -153,63 +156,73 @@ galera_3nodes.* : Suite is no
#-----------------------------------------------------------------------
+gcol.gcol_rollback : MDEV-16954 - Unknown storage engine 'InnoDB'
+gcol.gcol_update : Include file modified in 10.2.17, 10.3.9
+gcol.innodb_virtual_basic : MDEV-16950 - Failing assertion
gcol.innodb_virtual_debug : MDEV-14134 - Crash, assertion failure; modified in 10.3.8
-gcol.innodb_virtual_index : Modified in 10.3.7
+gcol.innodb_virtual_debug_purge : MDEV-16952 - Wrong result; modified in 10.2.17, 10.3.9
+gcol.innodb_virtual_index : Include file modified in 10.2.17, 10.3.9
+gcol.innodb_virtual_purge : Include file modified in 10.3.9
#-----------------------------------------------------------------------
-handler.heap : Modified in 10.3.7
-handler.innodb : Modified in 10.3.7
-handler.interface : Modified in 10.3.7
handler.ps : Added in 10.3.8
#-----------------------------------------------------------------------
-heap.heap_auto_increment : MDEV-16652 - Out of range, modified in 10.3.8
+heap.heap_auto_increment : Modified in 10.3.8
#-----------------------------------------------------------------------
innodb.101_compatibility : MDEV-13891 - Wrong result
innodb.alter_copy : MDEV-16181 - Assertion failure
-innodb.alter_foreign_crash : Added in 10.3.7
-innodb.alter_kill : MDEV-16273 - Unknown storage engine 'InnoDB'; added in 10.3.7
-innodb.alter_non_null : Added in 10.3.8
-innodb.alter_non_null_debug : Added in 10.3.8
-innodb.alter_not_null : Modified in 10.3.8
-innodb.alter_partitioned : Added in 10.3.7
-innodb.alter_rename_files : Added in 10.3.7
+innodb.alter_crash : MDEV-16944 - The process cannot access the file
+innodb.alter_foreign_crash : Added in 10.2.16
+innodb.alter_kill : MDEV-16273 - Unknown storage engine 'InnoDB', MDEV-16946 - Wrong result
+innodb.alter_not_null : Modified in 10.3.9
+innodb.alter_not_null_debug : Added in 10.3.9
+innodb.alter_partitioned_xa : Added in 10.0.36
+innodb.alter_rename_files : Added in 10.2.16
innodb.alter_sql_mode : Combinations added in 10.3.8
-innodb.analyze_table : Added in 10.3.7
+innodb.analyze_table : Added in 10.2.16
innodb.autoinc_persist : MDEV-15282 - Assertion failure
innodb.binlog_consistent : MDEV-10618 - Server fails to start
+innodb.dml_purge : Include file modified in 10.3.9
innodb.doublewrite : MDEV-12905 - Server crash
innodb.group_commit_crash : MDEV-14191 - InnoDB registration failed
innodb.group_commit_crash_no_optimize_thread : MDEV-13830 - Assertion failure
+innodb.index_merge_threshold : Include files modified in 10.2.17, 10.3.9
+innodb.innodb-16k : Modified in 10.3.9
+innodb.innodb-32k-crash : MDEV-16953 - Corrupt log record found
innodb.innodb-64k-crash : MDEV-13872 - Failure and crash on startup
+innodb.innodb-alter : Modified in 10.0.36
innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS
innodb.innodb-alter-table : MDEV-10619 - Testcase timeout
innodb.innodb-alter-tempfile : MDEV-15285 - Table already exists
innodb.innodb-alter-timestamp : Modified in 10.3.8
innodb.innodb-autoinc : Modified in 10.3.8
innodb.innodb-blob : Modified in 10.3.8
+innodb.innodb-corrupted-table : Modified in 10.3.9
innodb.innodb-fk : MDEV-13832 - Assertion failure on shutdown
innodb.innodb-get-fk : MDEV-13276 - Server crash
innodb.innodb-index-online : MDEV-14809 - Cannot save statistics
+innodb.innodb-mdev-7513 : Modified in 10.3.9
innodb.innodb-mdev7046 : Modified in 10.3.8
-innodb.innodb-online-alter-gis : Modified in 10.3.7
+innodb.innodb-online-alter-gis : Modified in 10.2.16
innodb.innodb-page_compression_default : MDEV-13644 - Assertion failure; modified in 10.3.8
innodb.innodb-page_compression_lzma : MDEV-14353 - Wrong result
innodb.innodb-page_compression_snappy : /MDEV-13644 - Assertion failure; modified in 10.3.8
innodb.innodb-page_compression_zip : MDEV-10641 - mutex problem
innodb.innodb-table-online : MDEV-13894 - Wrong result; modified in 10.3.8
-innodb.innodb-wl5522 : MDEV-13644 - Assertion failure
+innodb.innodb-wl5522 : MDEV-13644 - Assertion failure; modified in 10.3.9
innodb.innodb-wl5522-debug : MDEV-14200 - Wrong errno
-innodb.innodb_bug13510739 : Modified in 10.3.7
innodb.innodb_bug14147491 : MDEV-11808 - Index is corrupt
innodb.innodb_bug30423 : MDEV-7311 - Wrong result
innodb.innodb_bug48024 : MDEV-14352 - Assertion failure
-innodb.innodb_bug54044 : Modified in 10.3.7
+innodb.innodb_bug54044 : Modified in 10.2.16
innodb.innodb_bug59641 : MDEV-13830 - Assertion failure
+innodb.innodb_buffer_pool_resize : MDEV-16964 - Assertion failure
+innodb.innodb_buffer_pool_resize_with_chunks : MDEV-16964 - Assertion failure
innodb.innodb_bulk_create_index_replication : MDEV-15273 - Slave failed to start
innodb.innodb_defrag_stats_many_tables : MDEV-14198 - Table is full
innodb.innodb_defragment_small : Modified in 10.3.8
@@ -219,49 +232,60 @@ innodb.innodb_max_recordsize_64k : MDEV-15203
innodb.innodb_monitor : MDEV-10939 - Testcase timeout
innodb.innodb_query_cache : Added in 10.3.8
innodb.innodb_stats : MDEV-10682 - wrong result
+innodb.innodb_stats_persistent : Include file modified in 10.2.17, 10.3.9
innodb.innodb_stats_persistent_debug : MDEV-14801 - Operation failed
innodb.innodb_sys_semaphore_waits : MDEV-10331 - Semaphore wait
innodb.innodb_zip_innochecksum2 : MDEV-13882 - Extra warnings
innodb.innodb_zip_innochecksum3 : MDEV-14486 - Resource temporarily unavailable
+innodb.instant_alter : Modified in 10.3.9
+innodb.instant_alter_crash : Include file modified in 10.3.9
+innodb.instant_alter_debug : Modified in 10.3.9
+innodb.instant_alter_rollback : Include file modified in 10.3.9
innodb.log_corruption : MDEV-13251 - Wrong result
innodb.log_data_file_size : MDEV-14204 - Server failed to start
innodb.log_file_name : MDEV-14193 - Exception
innodb.log_file_size : MDEV-15668 - Not found pattern
-innodb.monitor : MDEV-16179 - Wrong result
-innodb.purge_secondary : MDEV-15681 - Wrong result
+innodb.monitor : MDEV-16179 - Wrong result; modified in 10.3.9
+innodb.purge_secondary : MDEV-15681 - Wrong result; include file modified in 10.3.9
innodb.purge_thread_shutdown : MDEV-13792 - Wrong result
innodb.read_only_recovery : MDEV-13886 - Server crash
innodb.recovery_shutdown : MDEV-15671 - Checksum mismatch in datafile
innodb.rename_table : Modified in 10.3.8
innodb.row_format_redundant : MDEV-15192 - Trying to access missing tablespace
innodb.sp_temp_table : MDEV-16647 - Could not remove temporary table
+innodb.strict_mode : Modified in 10.3.9
innodb.table_definition_cache_debug : MDEV-14206 - Extra warning
innodb.table_flags : MDEV-13572 - Wrong result
innodb.temp_table_savepoint : MDEV-16182 - Wrong result
-innodb.temporary_table : MDEV-13265 - Wrong result; modified in 10.3.7
-innodb.tmpdir : Modified in 10.3.7
+innodb.temporary_table : MDEV-13265 - Wrong result; modified in 10.3.9
+innodb.truncate_purge_debug : Include file modified in 10.2.17, 10.3.9
innodb.update_time : MDEV-14804 - Wrong result
+innodb.undo_log : Include file modified in 10.2.17, 10.3.9
innodb.xa_recovery : MDEV-15279 - mysqld got exception
#-----------------------------------------------------------------------
-innodb_fts.fulltext2 : Modified in 10.3.7
-innodb_fts.fulltext_var : Modified in 10.3.7
+innodb_fts.basic : Added in 10.0.36
+innodb_fts.fts_kill_query : Added in 10.1.35, 10.2.17, 10.3.9
innodb_fts.innodb-fts-fic : MDEV-14154 - Assertion failure
-innodb_fts.innodb_fts_misc : Modified in 10.3.7
innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning
+innodb_fts.innodb_fts_multiple_index : Modified in 10.3.9
innodb_fts.innodb_fts_plugin : MDEV-13888 - Errors in server log
innodb_fts.innodb_fts_stopword_charset : MDEV-13259 - Table crashed
innodb_fts.sync : MDEV-14808 - Wrong result
+innodb_fts.sync_ddl : Added in 10.1.35, 10.2.17, 10.3.9
#-----------------------------------------------------------------------
+innodb_gis.create_spatial_index : Modified in 10.2.17, 10.3.9
+innodb_gis.kill_server : MDEV-16941 - Checksum mismatch
+innodb_gis.rtree_compress : Include file modified in 10.2.17, 10.3.9
innodb_gis.rtree_compress2 : MDEV-16269 - Wrong result
innodb_gis.rtree_concurrent_srch : MDEV-15284 - Wrong result with embedded
-innodb_gis.rtree_purge : MDEV-15275 - Timeout
+innodb_gis.rtree_purge : MDEV-15275 - Timeout; include file modified in 10.3.9
innodb_gis.rtree_recovery : MDEV-15274 - Error on check
innodb_gis.rtree_split : MDEV-14208 - Too many arguments
-innodb_gis.rtree_undo : MDEV-14456 - Timeout in include file
+innodb_gis.rtree_undo : MDEV-14456 - Timeout in include file; include file modified in 10.3.9
innodb_gis.types : MDEV-15679 - Table is marked as crashed
#-----------------------------------------------------------------------
@@ -276,51 +300,70 @@ innodb_zip.wl6501_scale_1 : MDEV-13254
#-----------------------------------------------------------------------
main.alter_table : Modified in 10.3.8
-main.alter_table_errors : Added in 10.3.7
main.alter_table_trans : MDEV-12084 - timeout
main.analyze_stmt_slow_query_log : MDEV-12237 - Wrong result
-main.ansi : Modified in 10.3.7
+main.assign_key_cache : Added in 10.0.36
+main.assign_key_cache_debug : Added in 10.0.36
main.auth_named_pipe : MDEV-14724 - System error 2
-main.auto_increment : MDEV-16652 - Out of range, modified in 10.3.8
+main.auto_increment : Modified in 10.3.8
+main.bootstrap : Modified in 10.1.35, 10.2.17, 10.3.9
+main.check_constraint : Modified in 10.2.17, 10.3.9
main.check : Modified in 10.3.8
-main.check_constraint : Modified in 10.3.7
-main.connect : MDEV-16270 - Wrong result
+main.column_compression : Modified in 10.3.9
main.connect2 : MDEV-13885 - Server crash
+main.connect_debug : Added in 10.0.36
+main.connect : MDEV-16270 - Wrong result
main.count_distinct2 : MDEV-11768 - timeout
main.create_delayed : MDEV-10605 - failed with timeout
main.create_drop_event : MDEV-16271 - Wrong result
-main.create_or_replace : Modified in 10.3.7
+main.create_or_replace : Modified in 10.2.16
+main.create_replace_tmp : Added in 10.2.17, 10.3.9
main.cte_nonrecursive : Modified in 10.3.8
-main.cte_recursive : Modified in 10.3.7
-main.ctype_utf16le : MDEV-10675: timeout or extra warnings
-main.custom_aggregate_functions : Modified in 10.3.7
+main.cte_recursive : Modified in 10.2.17, 10.3.9
+main.cte_recursive_not_embedded : Added in 10.2.17, 10.3.9
+main.ctype_binary : Modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_eucjpms : Modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_euckr : Modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_gbk : Modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_latin1 : Modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_ucs : Modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_ujis : Modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_upgrade : MDEV-16945 - Error upon mysql_upgrade
+main.ctype_utf16le : MDEV-10675: timeout or extra warnings; modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_utf16 : MDEV-10675: timeout or extra warnings; modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_utf32 : Modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_utf8mb4 : Modified in 10.1.35, 10.2.17, 10.3.9
+main.ctype_utf8 : Modified in 10.1.35, 10.2.17, 10.3.9
main.debug_sync : MDEV-10607 - internal error
-main.derived_cond_pushdown : Modified in 10.3.8
+main.derived_cond_pushdown : Modified in 10.2.17, 10.3.9
+main.derived : Modified in 10.1.35, 10.2.17, 10.3.9
main.derived_opt : MDEV-11768 - timeout
main.derived_view : Modified in 10.3.8
-main.distinct : MDEV-14194 - Crash; modified in 10.3.7
+main.distinct : MDEV-14194 - Crash
main.drop_bad_db_type : MDEV-15676 - Wrong result
main.events_2 : MDEV-13277 - Crash
main.events_bugs : MDEV-12892 - Crash
main.events_restart : MDEV-12236 - Server shutdown problem
main.events_slowlog : MDEV-12821 - Wrong result
-main.explain_slowquerylog : Modified in 10.3.7
-main.func_json : Modified in 10.3.8
+main.explain_slowquerylog : Modified in 10.2.16
+main.func_json : Modified in 10.3.9
main.func_misc : Modified in 10.3.8
-main.func_time : Modified in 10.3.8
main.func_time_hires : Modified in 10.3.8
+main.func_time : Modified in 10.3.9
main.gis : MDEV-13411 - wrong result on P8
-main.grant : Modified in 10.3.8
main.grant2 : Modified in 10.3.8
-main.grant_not_windows : Added in 10.3.7
+main.grant : Modified in 10.3.9
+main.grant_not_windows : Added in 10.2.16
main.having : Modified in 10.3.8
main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown
main.index_intersect_innodb : MDEV-10643 - failed with timeout
main.index_merge_innodb : MDEV-7142 - Plan mismatch
main.innodb_mysql_lock : MDEV-7861 - Wrong result
-main.insert_select : Modified in 10.3.7
-main.invisible_field_grant_completely : Added in 10.3.7
-main.invisible_field_grant_system : Added in 10.3.7
+main.insert_select : Modified in 10.2.16
+main.invisible_field_debug : Modified in 10.3.9
+main.join : Modified in 10.1.35, 10.2.17, 10.3.9
+main.join_cache : Modified in 10.1.35, 10.2.17, 10.3.9
+main.join_outer : Modified in 10.1.35, 10.2.17, 10.3.9
main.kill-2 : MDEV-13257 - Wrong result
main.kill_processlist-6619 : MDEV-10793 - Wrong result
main.limit : Modified in 10.3.8
@@ -328,39 +371,34 @@ main.lock : Modified in
main.log_slow : MDEV-13263 - Wrong result
main.log_tables-big : MDEV-13408 - wrong result
main.max_statement_time : Modified in 10.3.8
+main.mdev375 : MDEV-10607 - sporadic "can't connect"
main.mdev-504 : MDEV-15171 - warning
main.merge : MDEV-10607 - sporadic "can't connect"
-main.multi_update : Modified in 10.3.7
-main.mysql : Modified in 10.3.7
-main.mysql_client_test_comp : MDEV-16641 - exec failed
+main.myisam : Modified in 10.0.36
+main.mysql_client_test_comp : MDEV-16641 - Error in exec
main.mysql_client_test_nonblock : CONC-208 - Error on Power; MDEV-15096 - exec failed
-main.mysql_cp932 : Modified in 10.3.7
-main.mysql_upgrade_noengine : MDEV-14355 - Wrong result
-main.mysql_upgrade_ssl : MDEV-13492 - Unknown SSL error
+main.mysql_cp932 : Modified in 10.2.16
main.mysqld_option_err : MDEV-12747 - Timeout
-main.mysqldump : MDEV-14800 - Stack smashing detected; modified in 10.3.8
+main.mysqldump : MDEV-14800 - Stack smashing detected; modified in 10.2.16, 10.3.8
main.mysqlhotcopy_myisam : MDEV-10995 - Hang on debug
+main.mysql : Modified in 10.2.16
main.mysqlslap : Modified in 10.3.8
main.mysqltest : MDEV-13887 - Wrong result
-main.mysqltest_tracking_info : Added in 10.3.8
+main.mysqltest_tracking_info : Added in 10.2.17, 10.3.8
+main.mysql_upgrade_noengine : MDEV-14355 - Wrong result
+main.mysql_upgrade_ssl : MDEV-13492 - Unknown SSL error
main.olap : Modified in 10.3.8
main.openssl_1 : MDEV-13492 - Unknown SSL error
main.order_by_optimizer_innodb : MDEV-10683 - Wrong result
-main.parser : Modified in 10.3.7
main.partition_debug_sync : MDEV-15669 - Deadlock found when trying to get lock
-main.partition_innodb : Modified in 10.3.7
main.partition_innodb_plugin : MDEV-12901 - Valgrind warnings
-main.partition_open_files_limit : Modified in 10.3.8
-main.ps : MDEV-11017 - Wrong result; modified in 10.3.8
-main.query_cache : MDEV-16180 - Wrong result
+main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count; modified in 10.1.34
main.query_cache_debug : MDEV-15281 - Query cache is disabled
+main.query_cache : MDEV-16180 - Wrong result
main.range_vs_index_merge_innodb : MDEV-15283 - Server has gone away
main.read_only_innodb : Modified in 10.3.8
-main.rename : Modified in 10.3.8
+main.rename : Modified in 10.3.9
main.reset_connection : Added in 10.3.8
-main.select : MDEV-15430 - Wrong result with clang-4 (compiler bug)
-main.select_jcl6 : MDEV-15430 - Wrong result with clang-4 (compiler bug)
-main.select_pkeycache : MDEV-15430 - Wrong result with clang-4 (compiler bug)
main.selectivity : Modified in 10.3.8
main.session_tracker_last_gtid : Added in 10.3.8
main.set_password : Added in 10.3.8
@@ -368,55 +406,55 @@ main.set_statement : MDEV-13183
main.shm : MDEV-12727 - Mismatch, ERROR 2013
main.show_explain : MDEV-10674 - Wrong result code
main.show_grants_with_plugin-7985 : Modified in 10.3.8
-main.sp : MDEV-7866 - Mismatch; modified in 10.3.8
-main.sp-code : Modified in 10.3.7
main.sp-condition-handler : Added in 10.3.8
main.sp-cursor : Modified in 10.3.8
+main.sp-innodb : Modified in 10.0.36
+main.sp : MDEV-7866 - Mismatch; modified in 10.3.8
+main.sp_notembedded : MDEV-10607 - internal error
main.sp-row : Modified in 10.3.8
main.sp-security : Modified in 10.3.8
-main.sp_notembedded : MDEV-10607 - internal error
main.sql_mode : Modified in 10.3.8
main.ssl_ca : MDEV-10895 - SSL connection error on Power
main.ssl_cert_verify : MDEV-13735 - Server crash
main.ssl_connect : MDEV-13492 - Unknown SSL error
main.ssl_timeout : MDEV-11244 - Crash
-main.stat_tables_par : MDEV-13266 - Wrong result
-main.stat_tables_par_innodb : MDEV-14155 - Wrong rounding
-main.statistics : Modified in 10.3.8
main.statistics_close : Added in 10.3.8
+main.statistics : Modified in 10.3.8
+main.stat_tables : Modified in 10.1.35, 10.2.17, 10.3.9
+main.stat_tables_par_innodb : MDEV-14155 - Wrong rounding
+main.stat_tables_par : MDEV-13266 - Wrong result
main.status : MDEV-13255 - Wrong result
-main.subselect-crash_15755 : Added in 10.3.7
+main.subselect4 : Modified in 10.0.36
main.subselect_innodb : MDEV-10614 - Wrong result
-main.subselect_sj2_mat : Modified in 10.3.8
-main.symlink-aria-11902 : MDEV-15098 - error 40 from storage engine
-main.symlink-myisam-11902 : MDEV-15098 - Error 40 from storage engine
+main.subselect : Modified in 10.1.35, 10.2.17, 10.3.9
+main.subselect_sj2_mat : Modified in 10.1.35, 10.2.17, 10.3.9
+main.subselect_sj_mat : Modified in 10.1.35, 10.2.17, 10.3.9
+main.subselect_sj : Modified in 10.0.36
main.tc_heuristic_recover : MDEV-14189 - Wrong result
main.trigger : Modified in 10.3.8
main.type_bit : Modified in 10.3.8
main.type_blob : MDEV-15195 - Wrong result; modified in 10.3.8
main.type_datetime : MDEV-14322 - wrong result
-main.type_datetime_hires : MDEV-15430 - Wrong result with clang-4 (compiler bug)
main.type_decimal : Modified in 10.3.8
-main.type_float : MDEV-15430 - Wrong result with clang-4 (compiler bug)
main.type_int : Modified in 10.3.8
-main.type_time_hires : MDEV-15430 - Wrong result with clang-4 (compiler bug)
-main.type_timestamp_hires : MDEV-15430 - Wrong result with clang-4 (compiler bug)
+main.union : Modified in 10.1.35, 10.2.17, 10.3.9
main.userstat : MDEV-12904 - SSL errors
main.win : Modified in 10.3.8
-main.xa : MDEV-11769 - lock wait timeout
+main.xa : MDEV-11769 - lock wait timeout; modified in 10.3.9
+
#-----------------------------------------------------------------------
-maria.alter : Modified in 10.3.7
+maria.alter : Modified in 10.2.16
maria.insert_select : MDEV-12757 - Timeout
maria.insert_select-7314 : MDEV-16492 - Timeout
maria.lock : Modified in 10.3.8
maria.maria : MDEV-14430 - Extra warning; modified in 10.3.8
-maria.maria-autoinc : MDEV-16652 - Out of range; added in 10.3.8
+maria.maria-autoinc : Added in 10.3.8
#-----------------------------------------------------------------------
-mariabackup.absolute_ibdata_paths : MDEV-16642 - Wrong result
+mariabackup.absolute_ibdata_paths : MDEV-16571 - Wrong result
mariabackup.apply-log-only : MDEV-14192 - Assertion failure
mariabackup.apply-log-only-incr : MDEV-14192 - Assertion failure; modified in 10.3.8
mariabackup.backup_ssl : MDEV-14192 - Assertion failure
@@ -424,34 +462,43 @@ mariabackup.data_directory : MDEV-15270
mariabackup.full_backup : MDEV-16571 - Wrong result
mariabackup.huge_lsn : MDEV-15662 - Sequence number is in the future
mariabackup.incremental_backup : MDEV-14192 - Assertion failure
-mariabackup.incremental_encrypted : MDEV-14188 - Wrong result, MDEV-15667 - timeout
+mariabackup.incremental_encrypted : MDEV-15667 - timeout; modified in 10.3.9
+mariabackup.innodb_log_optimize_ddl : Added in 10.2.17, 10.3.9
+mariabackup.log_checksum_mismatch : MDEV-16571 - Wrong result
mariabackup.lock_ddl_per_table : Modified in 10.3.8
mariabackup.mdev-14447 : MDEV-15201 - Timeout; modified in 10.3.8
mariabackup.partial_exclude : MDEV-15270 - Error on exec
mariabackup.partition_datadir : Modified in 10.3.8
mariabackup.rename_during_mdl_lock : Added in 10.3.8
+mariabackup.unsupported_redo : MDEV-14192 - Crash; modified in 10.2.17, 10.3.9
mariabackup.xb_aws_key_management : MDEV-15680 - Error: xtrabackup_copy_logfile() failed
mariabackup.xb_compressed_encrypted : MDEV-14812 - Segmentation fault
-mariabackup.xb_file_key_management : MDEV-16650 - Wrong result
+mariabackup.xb_file_key_management : MDEV-16571 - Wrong result
mariabackup.xb_history : MDEV-16268 - Error on exec
mariabackup.xb_page_compress : MDEV-14810 - status: 1, errno: 11
-mariabackup.xb_partition : MDEV-16643 - Table does not exist
mariabackup.xb_rocksdb : Added in 10.3.8
mariabackup.xb_rocksdb_datadir : Added in 10.3.8
mariabackup.xb_rocksdb_datadir_debug : Added in 10.3.8
+mariabackup.xb_partition : MDEV-14192 - Crash
mariabackup.xbstream : MDEV-14192 - Crash
#-----------------------------------------------------------------------
-mroonga/storage.* : MDEV-16127 - Wrong result
-
mroonga/storage.column_datetime_32bit_2038 : Wrong result on Alpha
mroonga/storage.column_datetime_32bit_before_unix_epoch : Wrong result on Alpha
mroonga/storage.column_datetime_32bit_max : Wrong result on Alpha
mroonga/storage.column_datetime_32bit_out_of_range : Wrong result on Alpha
+mroonga/storage.index_multiple_column_range_all_used_less_than : MDEV-16127 - Wrong result with GCC 8
+mroonga/storage.index_multiple_column_range_all_used_less_than_or_equal : MDEV-16127 - Wrong result with GCC 8
+mroonga/storage.index_multiple_column_range_partially_used_have_prefix_less_than : MDEV-16127 - Wrong result with GCC 8
+mroonga/storage.index_multiple_column_range_partially_used_have_prefix_less_than_or_equal : MDEV-16127 - Wrong result with GCC 8
+mroonga/storage.index_multiple_column_range_partially_used_no_prefix_less_than : MDEV-16127 - Wrong result with GCC 8
+mroonga/storage.index_multiple_column_range_partially_used_no_prefix_less_than_or_equal : MDEV-16127 - Wrong result with GCC 8
mroonga/storage.index_multiple_column_unique_date_32bit_equal : Wrong result on Alpha
mroonga/storage.index_multiple_column_unique_date_order_32bit_desc : Wrong result on Alpha
mroonga/storage.index_multiple_column_unique_datetime_index_read : MDEV-8643 - Valgrind
+mroonga/storage.optimization_order_limit_optimized_datetime_less_than : MDEV-16127 - Wrong result with GCC 8
+mroonga/storage.optimization_order_limit_optimized_datetime_less_than_or_equal : MDEV-16127 - Wrong result with GCC 8
mroonga/storage.repair_table_no_index_file : MDEV-9364 - wrong result, MDEV-14807 - wrong error message
mroonga/wrapper.repair_table_no_index_file : MDEV-14807 - Wrong error message
@@ -474,7 +521,8 @@ parts.partition_auto_increment_maria : MDEV-14430
parts.partition_debug_innodb : MDEV-10891 - Can't create UNIX socket; MDEV-15095 - Table doesn't exist
parts.partition_exch_qa_10 : MDEV-11765 - wrong result
parts.partition_innodb_status_file : MDEV-12901 - Valgrind
-parts.show_create : Added in 10.3.7
+parts.partition_special_innodb : MDEV-16942 - Timeout
+parts.truncate_locked : Added in 10.1.35, 10.2.17, 10.3.9
#-----------------------------------------------------------------------
@@ -494,6 +542,7 @@ perfschema.hostcache_ipv6_addrinfo_bad_allow : MDEV-13260
perfschema.hostcache_ipv6_ssl : MDEV-10696 - Crash
perfschema.partition : Added in 10.3.8
perfschema.privilege_table_io : MDEV-13184 - Extra lines
+perfschema.rpl_gtid_func : MDEV-16897 - Wrong result
perfschema.socket_connect : MDEV-15677 - Wrong result
perfschema.socket_summary_by_event_name_func : MDEV-10622 - Wrong result
perfschema.stage_mdl_global : MDEV-11803 - wrong result on slow builders
@@ -520,20 +569,19 @@ rocksdb.2pc_group_commit : MDEV-14455
rocksdb.add_index_inplace : MDEV-16648 - Crash
rocksdb.allow_no_primary_key : MDEV-16634 - Crash
rocksdb.allow_no_primary_key_with_sk : MDEV-16639 - Crash
-rocksdb.analyze_table : Modified in 10.3.7
+rocksdb.analyze_table : Modified in 10.2.16
rocksdb.autoinc_crash_safe : MDEV-16637 - Crash
rocksdb.autoinc_crash_safe_partition : MDEV-16639 - Crash
-rocksdb.autoinc_debug : MDEV-16203 - Wrong result
rocksdb.autoinc_secondary : MDEV-16638 - Crash
rocksdb.autoinc_vars_thread : MDEV-16573 - Debug sync timed out
rocksdb.bloomfilter2 : MDEV-16564 - Wrong result
rocksdb.bloomfilter4 : MDEV-16649 - Crash
-rocksdb.bulk_load_errors : MDEV-16575 - Wrong result
-rocksdb.check_ignore_unknown_options : MDEV-16310 - Non-portable commands; modified in 10.3.8
+rocksdb.check_ignore_unknown_options : Modified in 10.3.8
rocksdb.deadlock : MDEV-16033 - Timeout
rocksdb.drop_index_inplace : MDEV-14162 - Crash on shutdown
rocksdb.drop_table : MDEV-14308 - Timeout
rocksdb.drop_table2 : MDEV-16631 - Crash
+rocksdb.drop_table3 : MDEV-16949 - Server crash
rocksdb.issue255 : MDEV-16577 - Wrong plan; modified in 10.3.8
rocksdb.locking_issues : MDEV-14464 - Wrong result
rocksdb.mariadb_ignore_dirs : MDEV-16639 - Crash
@@ -546,9 +594,12 @@ rocksdb.rocksdb_parts : MDEV-13843
rocksdb.singledelete : MDEV-16633 - Crash
rocksdb.truncate_table3 : MDEV-14506 - Lost connection to server
rocksdb.ttl_primary_read_filtering : MDEV-16560 - Wrong result
+rocksdb.ttl_secondary : MDEV-16943 - Timeout
rocksdb.ttl_secondary_read_filtering : MDEV-16560 - Wrong result
rocksdb.unique_check : MDEV-16576 - Wrong errno
rocksdb.use_direct_reads_writes : MDEV-16646 - Crash
+rocksdb.validate_datadic : MDEV-12445 - Memory leak
+rocksdb.write_sync : MDEV-16965 - Wrong result
#-----------------------------------------------------------------------
@@ -557,7 +608,10 @@ rocksdb_rpl.rpl_binlog_xid_count : MDEV-16644
#-----------------------------------------------------------------------
+rocksdb_sys_vars.rocksdb_rate_limiter_bytes_per_sec_basic : MDEV-16639 - Crash
rocksdb_sys_vars.rocksdb_remove_mariabackup_checkpoint_basic : Added in 10.3.8
+rocksdb_sys_vars.rocksdb_update_cf_options_basic : MDEV-16955 - Bytes lost
+rocksdb_sys_vars.rocksdb_update_cf_options : MDEV-16955 - Bytes lost
#-----------------------------------------------------------------------
@@ -570,8 +624,11 @@ roles.set_default_role_ps-6960 : Modified in
rpl-tokudb.* : MDEV-14354 - Tests fail with tcmalloc
+rpl-tokudb.rpl_tokudb_commit_after_flush : MDEV-16966 - Server crash
+
rpl.last_insert_id : MDEV-10625 - warnings in error log
rpl.rename : Added in 10.3.8
+rpl.rpl_15867 : Added in 10.2.17, 10.3.9
rpl.rpl_auto_increment : MDEV-10417 - Fails on Mips
rpl.rpl_auto_increment_bug45679 : MDEV-10417 - Fails on Mips
rpl.rpl_auto_increment_update_failure : MDEV-10625 - warnings in error log
@@ -583,6 +640,7 @@ rpl.rpl_ddl : MDEV-10417
rpl.rpl_do_grant : Modified in 10.3.8
rpl.rpl_domain_id_filter_io_crash : MDEV-12729 - Timeout in include file, MDEV-13677 - Server crash
rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result
+rpl.rpl_drop_db_fail : MDEV-16898 - Slave fails to start
rpl.rpl_extra_col_master_innodb : MDEV-16570 - Extra warning
rpl.rpl_extra_col_master_myisam : MDEV-14203 - Extra warning
rpl.rpl_gtid_basic : MDEV-10681 - server startup problem
@@ -602,9 +660,8 @@ rpl.rpl_insert_id_pk : MDEV-16567
rpl.rpl_insert_ignore : MDEV-14365 - Lost connection to MySQL server during query
rpl.rpl_invoked_features : MDEV-10417 - Fails on Mips
rpl.rpl_mariadb_slave_capability : MDEV-11018 - Extra lines in binlog
-rpl.rpl_mdev12179 : Modified in 10.3.7
-rpl.rpl_mdev382 : Modified in 10.3.7
rpl.rpl_mdev6020 : MDEV-15272 - Server crash
+rpl.rpl_mixed_implicit_commit_binlog : Included file modified in 10.0.36
rpl.rpl_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed
rpl.rpl_non_direct_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed
rpl.rpl_non_direct_row_mixing_engines : MDEV-16561 - Timeout in master_pos_wait
@@ -619,13 +676,14 @@ rpl.rpl_parallel_retry : MDEV-11119
rpl.rpl_parallel_temptable : MDEV-10356 - Crash
rpl.rpl_partition_innodb : MDEV-10417 - Fails on Mips
rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings
-rpl.rpl_row_001 : MDEV-16653 - MTR's internal check fails
+rpl.rpl_row_001 : MDEV-16653 - MTR's internal check fails; modified in 10.3.9
rpl.rpl_row_basic_11bugs : MDEV-12171 - Server failed to start
rpl.rpl_row_basic_2myisam : MDEV-13875 - command "diff_files" failed
rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result
rpl.rpl_row_img_blobs : MDEV-13875 - command "diff_files" failed
rpl.rpl_row_img_eng_min : MDEV-13875 - diff_files failed
rpl.rpl_row_img_eng_noblob : MDEV-13875 - command "diff_files" failed
+rpl.rpl_row_implicit_commit_binlog : Included file modified in 10.0.36
rpl.rpl_row_index_choice : MDEV-15196 - Slave crash
rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x
rpl.rpl_row_until : MDEV-14052 - Master will not send events with checksum
@@ -633,6 +691,7 @@ rpl.rpl_semi_sync : MDEV-11220
rpl.rpl_semi_sync_after_sync : MDEV-14366 - Wrong result
rpl.rpl_semi_sync_after_sync_row : MDEV-14366 - Wrong result
rpl.rpl_semi_sync_event_after_sync : MDEV-11806 - warnings
+rpl.rpl_semi_sync_master_shutdown : Added in 10.3.9
rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Assorted failures
rpl.rpl_semi_sync_wait_point : MDEV-11807 - timeout in wait condition
rpl.rpl_semisync_ali_issues : MDEV-16272 - Wrong result
@@ -644,7 +703,8 @@ rpl.rpl_slave_load_tmpdir_not_exist : MDEV-14203
rpl.rpl_slow_query_log : MDEV-13250 - Test abort
rpl.rpl_sp_effects : MDEV-13249 - Crash
rpl.rpl_start_stop_slave : MDEV-13567 - Sync slave timeout
-rpl.rpl_stm_000001 : MDEV-16274 - Connection attributes were truncated
+rpl.rpl_stm_000001 : MDEV-16274 - Connection attributes were truncated; modified in 10.3.9
+rpl.rpl_stm_implicit_commit_binlog : Included file modified in 10.0.36
rpl.rpl_stm_mixing_engines : MDEV-14489 - Sync slave with master failed
rpl.rpl_stm_multi_query : MDEV-9501 - Failed registering on master
rpl.rpl_stm_relay_ign_space : MDEV-14360 - Test assertion
@@ -669,6 +729,7 @@ sphinx.union-5539 : MDEV-10986
spider.* : MDEV-9329 - tests are too memory-consuming
spider.basic_sql : MDEV-11186 - Internal check fails
spider.spider_fixes_part : Modified in 10.3.8
+spider.timestamp : Added in 10.3.9
spider/bg.direct_aggregate : MDEV-7098 - Packets out of order
spider/bg.direct_aggregate_part : MDEV-7098 - Trying to unlock mutex that wasn't locked
@@ -699,7 +760,7 @@ stress.ddl_innodb : MDEV-10635
sys_vars.autocommit_func2 : MDEV-9329 - Fails on Ubuntu/s390x
sys_vars.innodb_buffer_pool_dump_at_shutdown_basic : MDEV-14280 - Unexpected error
-sys_vars.innodb_stats_include_delete_marked_basic : Modified in 10.3.7
+sys_vars.innodb_log_optimize_ddl_basic : Added in 10.2.17, 10.3.9
sys_vars.keep_files_on_create_basic : MDEV-10676 - timeout
sys_vars.log_slow_admin_statements_func : MDEV-12235 - Server crash
sys_vars.maximum_basic : Modified in 10.3.8
@@ -748,6 +809,7 @@ tokudb_bugs.frm_store : MDEV-12823
tokudb_bugs.frm_store2 : MDEV-12823 - Valgrind
tokudb_bugs.frm_store3 : MDEV-12823 - Valgrind
tokudb_bugs.xa : MDEV-11804 - Lock wait timeout
+tokudb_bugs.xa-3 : MDEV-16953 - Corrupt log record found
#-----------------------------------------------------------------------
@@ -783,16 +845,13 @@ vcol.vcol_misc : MDEV-16651
#-----------------------------------------------------------------------
versioning.alter : Modified in 10.3.8
-versioning.partition : Modified in 10.3.7
versioning.replace : Modified in 10.3.8
versioning.select : Modified in 10.3.8
-versioning.truncate : Modified in 10.3.7
versioning.trx_id : Modified in 10.3.8
versioning.trx_id_versioning_attribute_persistence : Added in 10.3.8
#-----------------------------------------------------------------------
-wsrep.binlog_format : MDEV-11532 - Could not execute check-testcase
wsrep.foreign_key : MDEV-14725 - WSREP has not yet prepared node
wsrep.mdev_6832 : MDEV-14195 - Check testcase failed
wsrep.pool_of_threads : MDEV-12234 - GLIBCXX_3.4.20 not found
diff --git a/plugin/auth_ed25519/server_ed25519.c b/plugin/auth_ed25519/server_ed25519.c
index 8870c271b18..23b4e7389c7 100644
--- a/plugin/auth_ed25519/server_ed25519.c
+++ b/plugin/auth_ed25519/server_ed25519.c
@@ -100,7 +100,7 @@ maria_declare_plugin(ed25519)
0x0100,
NULL,
NULL,
- "1.0-alpha",
+ "1.0",
MariaDB_PLUGIN_MATURITY_STABLE
}
maria_declare_plugin_end;
diff --git a/plugin/auth_pam/mapper/pam_user_map.c b/plugin/auth_pam/mapper/pam_user_map.c
index c03ea12be74..e1d11acabb9 100644
--- a/plugin/auth_pam/mapper/pam_user_map.c
+++ b/plugin/auth_pam/mapper/pam_user_map.c
@@ -189,13 +189,15 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
s++;
}
from= s;
- skip(isalnum(*s) || (*s == '_') || (*s == '.') || (*s == '-') || (*s == '$'));
+ skip(isalnum(*s) || (*s == '_') || (*s == '.') || (*s == '-') ||
+ (*s == '$') || (*s == '\\') || (*s == '/'));
end_from= s;
skip(isspace(*s));
if (end_from == from || *s++ != ':') goto syntax_error;
skip(isspace(*s));
to= s;
- skip(isalnum(*s) || (*s == '_') || (*s == '.') || (*s == '-') || (*s == '$'));
+ skip(isalnum(*s) || (*s == '_') || (*s == '.') || (*s == '-') ||
+ (*s == '$'));
end_to= s;
if (end_to == to) goto syntax_error;
diff --git a/scripts/galera_recovery.sh b/scripts/galera_recovery.sh
index 09de6721762..c58f3d8f6b9 100644
--- a/scripts/galera_recovery.sh
+++ b/scripts/galera_recovery.sh
@@ -107,8 +107,7 @@ else
log "WSREP: mktemp failed"
fi
-parse_arguments `$print_defaults $cmdline_args --loose-verbose \
- mariadb mariadb_safe mysqld mysqld_safe safe_mysqld galera`
+parse_arguments `$print_defaults $cmdline_args --loose-verbose --mysqld`
# Perform wsrep position recovery if wsrep_on=1, skip otherwise.
if [ "$wsrep_on" -eq 1 ]; then
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index 21da52b015e..313821f522d 100755
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -27,6 +27,7 @@ WSREP_SST_OPT_PSWD=${WSREP_SST_OPT_PSWD:-}
WSREP_SST_OPT_DEFAULT=""
WSREP_SST_OPT_EXTRA_DEFAULT=""
WSREP_SST_OPT_SUFFIX_DEFAULT=""
+WSREP_SST_OPT_SUFFIX_VALUE=""
while [ $# -gt 0 ]; do
case "$1" in
@@ -76,6 +77,7 @@ case "$1" in
;;
'--defaults-group-suffix')
readonly WSREP_SST_OPT_SUFFIX_DEFAULT="$1=$2"
+ readonly WSREP_SST_OPT_SUFFIX_VALUE="$2"
shift
;;
'--host')
@@ -272,8 +274,8 @@ parse_cnf()
reval=$($MY_PRINT_DEFAULTS "${group}" | awk -v var="${var}" 'BEGIN { OFS=FS="=" } { gsub(/_/,"-",$1); if ( $1=="--"var) lastval=substr($0,length($1)+2) } END { print lastval}')
# use default if we haven't found a value
- if [ -z $reval ]; then
- [ -n $3 ] && reval=$3
+ if [ -z "$reval" ]; then
+ [ -n "$3" ] && reval=$3
fi
echo $reval
}
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index ca78d4917ff..1bfdb83633a 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -41,6 +41,8 @@ cleanup_joiner()
kill -9 $RSYNC_REAL_PID >/dev/null 2>&1 || \
:
rm -rf "$RSYNC_CONF"
+ rm -f "$STUNNEL_CONF"
+ rm -f "$STUNNEL_PID"
rm -rf "$MAGIC_FILE"
rm -rf "$RSYNC_PID"
wsrep_log_info "Joiner cleanup done."
@@ -68,7 +70,7 @@ check_pid_and_port()
local port_info="$(sockstat -46lp ${rsync_port} 2>/dev/null | \
grep ":${rsync_port}")"
local is_rsync="$(echo $port_info | \
- grep '[[:space:]]\+rsync[[:space:]]\+'"$rsync_pid" 2>/dev/null)"
+ grep -E '[[:space:]]+(rsync|stunnel)[[:space:]]+'"$rsync_pid" 2>/dev/null)"
;;
*)
if ! command -v lsof > /dev/null; then
@@ -79,7 +81,7 @@ check_pid_and_port()
local port_info="$(lsof -i :$rsync_port -Pn 2>/dev/null | \
grep "(LISTEN)")"
local is_rsync="$(echo $port_info | \
- grep -w '^rsync[[:space:]]\+'"$rsync_pid" 2>/dev/null)"
+ grep -E '^(rsync|stunnel)[[:space:]]+'"$rsync_pid" 2>/dev/null)"
;;
esac
@@ -120,6 +122,12 @@ is_local_ip()
$get_addr_bin | grep "$address" > /dev/null
}
+STUNNEL_CONF="$WSREP_SST_OPT_DATA/stunnel.conf"
+rm -f "$STUNNEL_CONF"
+
+STUNNEL_PID="$WSREP_SST_OPT_DATA/stunnel.pid"
+rm -f "$STUNNEL_PID"
+
MAGIC_FILE="$WSREP_SST_OPT_DATA/rsync_sst_complete"
rm -rf "$MAGIC_FILE"
@@ -147,6 +155,20 @@ else
WSREP_LOG_DIR=$(cd $WSREP_SST_OPT_DATA; pwd -P)
fi
+INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""}
+# if INNODB_DATA_HOME_DIR env. variable is not set, try to get it from my.cnf
+if [ -z "$INNODB_DATA_HOME_DIR" ]; then
+ INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '')
+fi
+
+if [ -n "$INNODB_DATA_HOME_DIR" ]; then
+ # handle both relative and absolute paths
+ INNODB_DATA_HOME_DIR=$(cd $WSREP_SST_OPT_DATA; mkdir -p "$INNODB_DATA_HOME_DIR"; cd $INNODB_DATA_HOME_DIR; pwd -P)
+else
+ # default to datadir
+ INNODB_DATA_HOME_DIR=$(cd $WSREP_SST_OPT_DATA; pwd -P)
+fi
+
# Old filter - include everything except selected
# FILTER=(--exclude '*.err' --exclude '*.pid' --exclude '*.sock' \
# --exclude '*.conf' --exclude core --exclude 'galera.*' \
@@ -155,11 +177,30 @@ fi
# New filter - exclude everything except dirs (schemas) and innodb files
FILTER="-f '- /lost+found' -f '- /.fseventsd' -f '- /.Trashes'
- -f '+ /wsrep_sst_binlog.tar' -f '+ /ib_lru_dump' -f '+ /ibdata*' -f '+ /*/' -f '- /*'"
+ -f '+ /wsrep_sst_binlog.tar' -f '- $INNODB_DATA_HOME_DIR/ib_lru_dump' -f '- $INNODB_DATA_HOME_DIR/ibdata*' -f '+ /*/' -f '- /*'"
+
+SSTKEY=$(parse_cnf sst tkey "")
+SSTCERT=$(parse_cnf sst tcert "")
+STUNNEL=""
+if [ -f "$SSTKEY" ] && [ -f "$SSTCERT" ] && wsrep_check_programs stunnel
+then
+ STUNNEL="stunnel ${STUNNEL_CONF}"
+fi
if [ "$WSREP_SST_OPT_ROLE" = "donor" ]
then
+cat << EOF > "$STUNNEL_CONF"
+CApath = ${SSTCERT%/*}
+foreground = yes
+pid = $STUNNEL_PID
+debug = warning
+client = yes
+connect = ${WSREP_SST_OPT_ADDR%/*}
+TIMEOUTclose = 0
+verifyPeer = yes
+EOF
+
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
then
@@ -221,7 +262,8 @@ then
# first, the normal directories, so that we can detect incompatible protocol
RC=0
- eval rsync --owner --group --perms --links --specials \
+ eval rsync ${STUNNEL:+--rsh="$STUNNEL"} \
+ --owner --group --perms --links --specials \
--ignore-times --inplace --dirs --delete --quiet \
$WHOLE_FILE_OPT ${FILTER} "$WSREP_SST_OPT_DATA/" \
rsync://$WSREP_SST_OPT_ADDR >&2 || RC=$?
@@ -243,8 +285,22 @@ then
exit $RC
fi
+ # Transfer InnoDB data files
+ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
+ --owner --group --perms --links --specials \
+ --ignore-times --inplace --dirs --delete --quiet \
+ $WHOLE_FILE_OPT -f '+ /ibdata*' -f '+ /ib_lru_dump' \
+ -f '- **' "$INNODB_DATA_HOME_DIR/" \
+ rsync://$WSREP_SST_OPT_ADDR-data_dir >&2 || RC=$?
+
+ if [ $RC -ne 0 ]; then
+ wsrep_log_error "rsync innodb_data_home_dir returned code $RC:"
+ exit 255 # unknown error
+ fi
+
# second, we transfer InnoDB and Aria log files
- rsync --owner --group --perms --links --specials \
+ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
+ --owner --group --perms --links --specials \
--ignore-times --inplace --dirs --delete --quiet \
$WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '+ /aria_log.*' -f '+ /aria_log_control' -f '- **' "$WSREP_LOG_DIR/" \
rsync://$WSREP_SST_OPT_ADDR-log_dir >&2 || RC=$?
@@ -264,7 +320,8 @@ then
find . -maxdepth 1 -mindepth 1 -type d -not -name "lost+found" \
-print0 | xargs -I{} -0 -P $count \
- rsync --owner --group --perms --links --specials \
+ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
+ --owner --group --perms --links --specials \
--ignore-times --inplace --recursive --delete --quiet \
$WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude "*/aria_log.*" --exclude "*/aria_log_control" "$WSREP_SST_OPT_DATA"/{}/ \
rsync://$WSREP_SST_OPT_ADDR/{} >&2 || RC=$?
@@ -287,7 +344,8 @@ then
echo "continue" # now server can resume updating data
echo "$STATE" > "$MAGIC_FILE"
- rsync --archive --quiet --checksum "$MAGIC_FILE" rsync://$WSREP_SST_OPT_ADDR
+ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
+ --archive --quiet --checksum "$MAGIC_FILE" rsync://$WSREP_SST_OPT_ADDR
echo "done $STATE"
@@ -340,6 +398,8 @@ $SILENT
path = $WSREP_SST_OPT_DATA
[$MODULE-log_dir]
path = $WSREP_LOG_DIR
+[$MODULE-data_dir]
+ path = $INNODB_DATA_HOME_DIR
EOF
# rm -rf "$DATA"/ib_logfile* # we don't want old logs around
@@ -348,14 +408,37 @@ EOF
# If the IP is local listen only in it
if is_local_ip "$RSYNC_ADDR"
then
- rsync --daemon --no-detach --address "$RSYNC_ADDR" --port "$RSYNC_PORT" --config "$RSYNC_CONF" &
+ RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR"
+ STUNNEL_ACCEPT="$RSYNC_ADDR:$RSYNC_PORT"
else
- # Not local, possibly a NAT, listen in all interface
- rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" &
+ # Not local, possibly a NAT, listen on all interfaces
+ RSYNC_EXTRA_ARGS=""
+ STUNNEL_ACCEPT="$RSYNC_PORT"
# Overwrite address with all
RSYNC_ADDR="*"
fi
- RSYNC_REAL_PID=$!
+
+ if [ -z "$STUNNEL" ]
+ then
+ rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" ${RSYNC_EXTRA_ARGS} &
+ RSYNC_REAL_PID=$!
+ else
+ cat << EOF > "$STUNNEL_CONF"
+key = $SSTKEY
+cert = $SSTCERT
+foreground = yes
+pid = $STUNNEL_PID
+debug = warning
+client = no
+[rsync]
+accept = $STUNNEL_ACCEPT
+exec = $(which rsync)
+execargs = rsync --server --daemon --config=$RSYNC_CONF .
+EOF
+ stunnel "$STUNNEL_CONF" &
+ RSYNC_REAL_PID=$!
+ RSYNC_PID=$STUNNEL_PID
+ fi
until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR" "$RSYNC_PORT"
do
diff --git a/sql/field.cc b/sql/field.cc
index 549fc157da9..743f12f3cc9 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -7120,7 +7120,9 @@ int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr)
void Field_string::sort_string(uchar *to,uint length)
{
- IF_DBUG(size_t tmp= ,)
+#ifdef DBUG_ASSERT_EXISTS
+ size_t tmp=
+#endif
field_charset->coll->strnxfrm(field_charset,
to, length,
char_length() *
@@ -7526,7 +7528,7 @@ void Field_varstring::sort_string(uchar *to,uint length)
length-= length_bytes;
}
-#ifndef DBUG_OFF
+#ifdef DBUG_ASSERT_EXISTS
size_t rc=
#endif
field_charset->coll->strnxfrm(field_charset, to, length,
@@ -8394,7 +8396,7 @@ void Field_blob::sort_string(uchar *to,uint length)
store_bigendian(buf.length(), to + length, packlength);
}
-#ifndef DBUG_OFF
+#ifdef DBUG_ASSERT_EXISTS
size_t rc=
#endif
field_charset->coll->strnxfrm(field_charset, to, length, length,
diff --git a/sql/field.h b/sql/field.h
index 8b080a0d06f..ed61afe01eb 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -2390,7 +2390,6 @@ public:
{
return unpack_int64(to, from, from_end);
}
-
void set_max();
bool is_max();
};
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 1855430b944..6901cee043f 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1004,7 +1004,9 @@ Type_handler_string_result::make_sort_key(uchar *to, Item *item,
if (use_strnxfrm(cs))
{
- IF_DBUG(size_t tmp_length= ,)
+#ifdef DBUG_ASSERT_EXISTS
+ size_t tmp_length=
+#endif
cs->coll->strnxfrm(cs, to, sort_field->length,
item->max_char_length() *
cs->strxfrm_multiply,
diff --git a/sql/handler.cc b/sql/handler.cc
index e45607cad66..943722af3b3 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -74,7 +74,7 @@ KEY_CREATE_INFO default_key_create_info=
ulong total_ha= 0;
/* number of storage engines (from handlertons[]) that support 2pc */
ulong total_ha_2pc= 0;
-#ifndef DBUG_OFF
+#ifdef DBUG_ASSERT_EXISTS
/*
Number of non-mandatory 2pc handlertons whose initialization failed
to estimate total_ha_2pc value under supposition of the failures
@@ -661,7 +661,7 @@ err_deinit:
(void) plugin->plugin->deinit(NULL);
err:
-#ifndef DBUG_OFF
+#ifdef DBUG_ASSERT_EXISTS
if (hton->prepare && hton->state == SHOW_OPTION_YES)
failed_ha_2pc++;
#endif
@@ -3073,6 +3073,45 @@ void handler::adjust_next_insert_id_after_explicit_value(ulonglong nr)
}
+/** @brief
+ Computes the largest number X:
+ - smaller than or equal to "nr"
+ - of the form: auto_increment_offset + N * auto_increment_increment
+ where N>=0.
+
+ SYNOPSIS
+ prev_insert_id
+ nr Number to "round down"
+ variables variables struct containing auto_increment_increment and
+ auto_increment_offset
+
+ RETURN
+ The number X if it exists, "nr" otherwise.
+*/
+inline ulonglong
+prev_insert_id(ulonglong nr, struct system_variables *variables)
+{
+ if (unlikely(nr < variables->auto_increment_offset))
+ {
+ /*
+ There's nothing good we can do here. That is a pathological case, where
+ the offset is larger than the column's max possible value, i.e. not even
+ the first sequence value may be inserted. User will receive warning.
+ */
+ DBUG_PRINT("info",("auto_increment: nr: %lu cannot honour "
+ "auto_increment_offset: %lu",
+ (ulong) nr, variables->auto_increment_offset));
+ return nr;
+ }
+ if (variables->auto_increment_increment == 1)
+ return nr; // optimization of the formula below
+ nr= (((nr - variables->auto_increment_offset)) /
+ (ulonglong) variables->auto_increment_increment);
+ return (nr * (ulonglong) variables->auto_increment_increment +
+ variables->auto_increment_offset);
+}
+
+
/**
Update the auto_increment field if necessary.
diff --git a/sql/handler.h b/sql/handler.h
index f1080d56bb9..68a54cc207a 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -950,6 +950,7 @@ enum enum_schema_tables
SCH_ALL_PLUGINS,
SCH_APPLICABLE_ROLES,
SCH_CHARSETS,
+ SCH_CHECK_CONSTRAINTS,
SCH_COLLATIONS,
SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
SCH_COLUMNS,
diff --git a/sql/item.cc b/sql/item.cc
index 7171a95c21d..f6198e1df68 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -7637,7 +7637,7 @@ Item_direct_view_ref::grouping_field_transformer_for_where(THD *thd,
void Item_field::print(String *str, enum_query_type query_type)
{
if (field && field->table->const_table &&
- !(query_type & QT_NO_DATA_EXPANSION))
+ !(query_type & (QT_NO_DATA_EXPANSION | QT_VIEW_INTERNAL)))
{
print_value(str);
return;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 189b315ede6..fb6d99b9498 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -4984,6 +4984,19 @@ Item *Item_cond::build_clone(THD *thd)
}
+bool Item_cond::excl_dep_on_grouping_fields(st_select_lex *sel)
+{
+ List_iterator_fast<Item> li(list);
+ Item *item;
+ while ((item= li++))
+ {
+ if (!item->excl_dep_on_grouping_fields(sel))
+ return false;
+ }
+ return true;
+}
+
+
void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding)
{
List_iterator<Item> li(list);
@@ -5120,7 +5133,11 @@ longlong Item_func_isnull::val_int()
void Item_func_isnull::print(String *str, enum_query_type query_type)
{
- args[0]->print_parenthesised(str, query_type, precedence());
+ if (const_item() && !args[0]->maybe_null &&
+ !(query_type & (QT_NO_DATA_EXPANSION | QT_VIEW_INTERNAL)))
+ str->append("/*always not null*/ 1");
+ else
+ args[0]->print_parenthesised(str, query_type, precedence());
str->append(STRING_WITH_LEN(" is null"));
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index e58644c1699..db1075b1936 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -2964,6 +2964,7 @@ public:
Item_transformer transformer, uchar *arg_t);
bool eval_not_null_tables(void *opt_arg);
Item *build_clone(THD *thd);
+ bool excl_dep_on_grouping_fields(st_select_lex *sel);
};
template <template<class> class LI, class T> class Item_equal_iterator;
diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h
index 48851da7d96..b3e23748246 100644
--- a/sql/item_windowfunc.h
+++ b/sql/item_windowfunc.h
@@ -1085,6 +1085,8 @@ public:
case Item_sum::DENSE_RANK_FUNC:
case Item_sum::PERCENT_RANK_FUNC:
case Item_sum::CUME_DIST_FUNC:
+ case Item_sum::LAG_FUNC:
+ case Item_sum::LEAD_FUNC:
case Item_sum::PERCENTILE_CONT_FUNC:
case Item_sum::PERCENTILE_DISC_FUNC:
return true;
diff --git a/sql/key.cc b/sql/key.cc
index 34196a973c5..9ad1103fbe8 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -146,7 +146,8 @@ void key_copy(uchar *to_key, const uchar *from_record, KEY *key_info,
{
key_length-= HA_KEY_BLOB_LENGTH;
length= MY_MIN(key_length, key_part->length);
- uint bytes= key_part->field->get_key_image(to_key, length, Field::itRAW);
+ uint bytes= key_part->field->get_key_image(to_key, length,
+ key_info->flags & HA_SPATIAL ? Field::itMBR : Field::itRAW);
if (with_zerofill && bytes < length)
bzero((char*) to_key + bytes, length - bytes);
to_key+= HA_KEY_BLOB_LENGTH;
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
index cf587ef4acd..d6952e71899 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -18,6 +18,7 @@
#include <my_bit.h>
#include "sql_select.h"
#include "key.h"
+#include "sql_statistics.h"
/****************************************************************************
* Default MRR implementation (MRR to non-MRR converter)
@@ -64,7 +65,12 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
ha_rows rows, total_rows= 0;
uint n_ranges=0;
THD *thd= table->in_use;
+ uint limit= thd->variables.eq_range_index_dive_limit;
+ bool use_statistics_for_eq_range= eq_ranges_exceeds_limit(seq,
+ seq_init_param,
+ limit);
+
/* Default MRR implementation doesn't need buffer */
*bufsz= 0;
@@ -88,8 +94,15 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
min_endp= range.start_key.length? &range.start_key : NULL;
max_endp= range.end_key.length? &range.end_key : NULL;
}
+ int keyparts_used= my_count_bits(range.start_key.keypart_map);
if ((range.range_flag & UNIQUE_RANGE) && !(range.range_flag & NULL_RANGE))
rows= 1; /* there can be at most one row */
+ else if (use_statistics_for_eq_range &&
+ !(range.range_flag & NULL_RANGE) &&
+ (range.range_flag & EQ_RANGE) &&
+ table->key_info[keyno].actual_rec_per_key(keyparts_used - 1) > 0.5)
+ rows=
+ (ha_rows) table->key_info[keyno].actual_rec_per_key(keyparts_used - 1);
else
{
if (HA_POS_ERROR == (rows= this->records_in_range(keyno, min_endp,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 3ed6846bde9..acb7532f922 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1476,9 +1476,9 @@ static NTService Service; ///< Service object for WinNT
#endif /* __WIN__ */
#ifdef _WIN32
+#include <sddl.h> /* ConvertStringSecurityDescriptorToSecurityDescriptor */
static char pipe_name[512];
static SECURITY_ATTRIBUTES saPipeSecurity;
-static SECURITY_DESCRIPTOR sdPipeDescriptor;
static HANDLE hPipe = INVALID_HANDLE_VALUE;
#endif
@@ -2711,21 +2711,20 @@ static void network_init(void)
strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
mysqld_unix_port, NullS);
- bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
- bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));
- if (!InitializeSecurityDescriptor(&sdPipeDescriptor,
- SECURITY_DESCRIPTOR_REVISION))
+ /*
+ Create a security descriptor for pipe.
+ - Use low integrity level, so that it is possible to connect
+ from any process.
+ - Give Everyone read/write access to pipe.
+ */
+ if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
+ "S:(ML;; NW;;; LW) D:(A;; FRFW;;; WD)",
+ SDDL_REVISION_1, &saPipeSecurity.lpSecurityDescriptor, NULL))
{
sql_perror("Can't start server : Initialize security descriptor");
unireg_abort(1);
}
- if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE))
- {
- sql_perror("Can't start server : Set security descriptor");
- unireg_abort(1);
- }
saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
- saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
saPipeSecurity.bInheritHandle = FALSE;
if ((hPipe= CreateNamedPipe(pipe_name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
@@ -6965,6 +6964,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
connect->host= my_localhost;
create_new_thread(connect);
}
+ LocalFree(saPipeSecurity.lpSecurityDescriptor);
CloseHandle(connectOverlapped.hEvent);
DBUG_LEAVE;
decrement_handler_count();
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 107c0d8ed89..7faae008dab 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -14829,6 +14829,32 @@ void QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths(String *key_names,
}
+/* Check whether the number for equality ranges exceeds the set threshold */
+
+bool eq_ranges_exceeds_limit(RANGE_SEQ_IF *seq, void *seq_init_param,
+ uint limit)
+{
+ KEY_MULTI_RANGE range;
+ range_seq_t seq_it;
+ uint count = 0;
+
+ if (limit == 0)
+ {
+ /* 'Statistics instead of index dives' feature is turned off */
+ return false;
+ }
+ seq_it= seq->init(seq_init_param, 0, 0);
+ while (!seq->next(seq_it, &range))
+ {
+ if ((range.range_flag & EQ_RANGE) && !(range.range_flag & NULL_RANGE))
+ {
+ if (++count >= limit)
+ return true;
+ }
+ }
+ return false;
+}
+
#ifndef DBUG_OFF
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
diff --git a/sql/opt_range.h b/sql/opt_range.h
index bd85a12d4a1..d5416988b88 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -242,7 +242,7 @@ public:
Number of children of this element in the RB-tree, plus 1 for this
element itself.
*/
- uint16 elements;
+ uint32 elements;
/*
Valid only for elements which are RB-tree roots: Number of times this
RB-tree is referred to (it is referred by SEL_ARG::next_key_part or by
@@ -1724,6 +1724,9 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond);
+bool eq_ranges_exceeds_limit(RANGE_SEQ_IF *seq, void *seq_init_param,
+ uint limit);
+
#ifdef WITH_PARTITION_STORAGE_ENGINE
bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond);
#endif
diff --git a/sql/opt_range_mrr.cc b/sql/opt_range_mrr.cc
index 515d94e8748..2981c8182ea 100644
--- a/sql/opt_range_mrr.cc
+++ b/sql/opt_range_mrr.cc
@@ -72,6 +72,7 @@ typedef struct st_sel_arg_range_seq
range_seq_t sel_arg_range_seq_init(void *init_param, uint n_ranges, uint flags)
{
SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
+ seq->param->range_count=0;
seq->at_start= TRUE;
seq->stack[0].key_tree= NULL;
seq->stack[0].min_key= seq->param->min_key;
@@ -272,25 +273,44 @@ walk_up_n_right:
key_info= NULL;
else
key_info= &seq->param->table->key_info[seq->real_keyno];
-
+
/*
- Conditions below:
- (1) - range analysis is used for estimating condition selectivity
- (2) - This is a unique key, and we have conditions for all its
- user-defined key parts.
- (3) - The table uses extended keys, this key covers all components,
- and we have conditions for all key parts.
+ This is an equality range (keypart_0=X and ... and keypart_n=Z) if
+ (1) - There are no flags indicating open range (e.g.,
+ "keypart_x > y") or GIS.
+ (2) - The lower bound and the upper bound of the range has the
+ same value (min_key == max_key).
*/
- if (!(cur->min_key_flag & ~NULL_RANGE) && !cur->max_key_flag &&
- (!key_info || // (1)
- ((uint)key_tree->part+1 == key_info->user_defined_key_parts && // (2)
- key_info->flags & HA_NOSAME) || // (2)
- ((key_info->flags & HA_EXT_NOSAME) && // (3)
- (uint)key_tree->part+1 == key_info->ext_key_parts) // (3)
- ) &&
- range->start_key.length == range->end_key.length &&
- !memcmp(seq->param->min_key,seq->param->max_key,range->start_key.length))
- range->range_flag= UNIQUE_RANGE | (cur->min_key_flag & NULL_RANGE);
+ const uint is_open_range =
+ (NO_MIN_RANGE | NO_MAX_RANGE | NEAR_MIN | NEAR_MAX | GEOM_FLAG);
+ const bool is_eq_range_pred =
+ !(cur->min_key_flag & is_open_range) && // (1)
+ !(cur->max_key_flag & is_open_range) && // (1)
+ range->start_key.length == range->end_key.length && // (2)
+ !memcmp(seq->param->min_key, seq->param->max_key, // (2)
+ range->start_key.length);
+
+ if (is_eq_range_pred)
+ {
+ range->range_flag = EQ_RANGE;
+
+ /*
+ Conditions below:
+ (1) - Range analysis is used for estimating condition selectivity
+ (2) - This is a unique key, and we have conditions for all its
+ user-defined key parts.
+ (3) - The table uses extended keys, this key covers all components,
+ and we have conditions for all key parts.
+ */
+ if (
+ !key_info || // (1)
+ ((uint)key_tree->part+1 == key_info->user_defined_key_parts && // (2)
+ key_info->flags & HA_NOSAME) || // (2)
+ ((key_info->flags & HA_EXT_NOSAME) && // (3)
+ (uint)key_tree->part+1 == key_info->ext_key_parts) // (3)
+ )
+ range->range_flag |= UNIQUE_RANGE | (cur->min_key_flag & NULL_RANGE);
+ }
if (seq->param->is_ror_scan)
{
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 29004fe24e4..7eee9283989 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -711,7 +711,7 @@ uchar *net_store_data(uchar *to, const uchar *from, size_t length)
uchar *net_store_data(uchar *to,int32 from)
{
- char buff[20];
+ char buff[22];
uint length=(uint) (int10_to_str(from,buff,10)-buff);
to=net_store_length_fast(to,length);
memcpy(to,buff,length);
@@ -1137,7 +1137,7 @@ bool Protocol_text::store_tiny(longlong from)
DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
field_pos++;
#endif
- char buff[20];
+ char buff[22];
return net_store_data((uchar*) buff,
(size_t) (int10_to_str((int) from, buff, -10) - buff));
}
@@ -1151,7 +1151,7 @@ bool Protocol_text::store_short(longlong from)
field_types[field_pos] == MYSQL_TYPE_SHORT);
field_pos++;
#endif
- char buff[20];
+ char buff[22];
return net_store_data((uchar*) buff,
(size_t) (int10_to_str((int) from, buff, -10) -
buff));
@@ -1166,7 +1166,7 @@ bool Protocol_text::store_long(longlong from)
field_types[field_pos] == MYSQL_TYPE_LONG);
field_pos++;
#endif
- char buff[20];
+ char buff[22];
return net_store_data((uchar*) buff,
(size_t) (int10_to_str((long int)from, buff,
(from <0)?-10:10)-buff));
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 64ce52049d0..30622fde577 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -581,6 +581,7 @@ typedef struct system_variables
ha_rows max_join_size;
ha_rows expensive_subquery_limit;
ulong auto_increment_increment, auto_increment_offset;
+ uint eq_range_index_dive_limit;
ulong column_compression_zlib_strategy;
ulong lock_wait_timeout;
ulong join_cache_level;
@@ -5023,7 +5024,8 @@ protected:
SELECT_LEX_UNIT *unit;
/* Something used only by the parser: */
public:
- select_result(THD *thd_arg): select_result_sink(thd_arg) {}
+ ha_rows est_records; /* estimated number of records in the result */
+ select_result(THD *thd_arg): select_result_sink(thd_arg), est_records(0) {}
void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; }
virtual ~select_result() {};
/**
@@ -5595,7 +5597,6 @@ public:
TMP_TABLE_PARAM tmp_table_param;
int write_err; /* Error code from the last send_data->ha_write_row call. */
TABLE *table;
- ha_rows records;
select_unit(THD *thd_arg):
select_result_interceptor(thd_arg),
@@ -5633,7 +5634,6 @@ public:
curr_sel= UINT_MAX;
step= UNION_TYPE;
write_err= 0;
- records= 0;
}
void change_select();
};
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 80ee4a22419..326f2a64bbe 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -323,12 +323,16 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_ASSERT(table);
DBUG_ASSERT(!conds || thd->stmt_arena->is_stmt_execute());
- if (select_lex->vers_setup_conds(thd, table_list))
- DBUG_RETURN(TRUE);
- DBUG_ASSERT(!conds);
- conds= table_list->on_expr;
- table_list->on_expr= NULL;
+ // conds could be cached from previous SP call
+ if (!conds)
+ {
+ if (select_lex->vers_setup_conds(thd, table_list))
+ DBUG_RETURN(TRUE);
+
+ conds= table_list->on_expr;
+ table_list->on_expr= NULL;
+ }
}
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT))
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 20b1eb413cf..bff6dfb0e05 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -4765,18 +4765,18 @@ void SELECT_LEX::increase_derived_records(ha_rows records)
return;
}
- select_unit *result= (select_unit*)unit->result;
+ select_result *result= unit->result;
switch (linkage)
{
case INTERSECT_TYPE:
// result of intersect can't be more then one of components
- set_if_smaller(result->records, records);
+ set_if_smaller(result->est_records, records);
case EXCEPT_TYPE:
// in worse case none of record will be removed
break;
default:
// usual UNION
- result->records+= records;
+ result->est_records+= records;
break;
}
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 147147f0191..201cb4f1dbe 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2565,6 +2565,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
case SCH_TABLE_NAMES:
case SCH_TABLES:
+ case SCH_CHECK_CONSTRAINTS:
case SCH_VIEWS:
case SCH_TRIGGERS:
case SCH_EVENTS:
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 7a8631a4ac1..3b927510c80 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1701,8 +1701,7 @@ JOIN::optimize_inner()
DBUG_RETURN(1);
}
- if (thd->lex->sql_command == SQLCOM_SELECT &&
- optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_SUBQUERY))
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_SUBQUERY))
{
TABLE_LIST *tbl;
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
@@ -1727,8 +1726,7 @@ JOIN::optimize_inner()
DBUG_RETURN(TRUE);
}
- if (thd->lex->sql_command == SQLCOM_SELECT &&
- optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED))
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED))
{
TABLE_LIST *tbl;
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
@@ -1925,6 +1923,14 @@ JOIN::optimize_inner()
error= 1;
DBUG_RETURN(1);
}
+ if (!group_list)
+ {
+ /* The output has only one row */
+ order=0;
+ simple_order=1;
+ group_optimized_away= 1;
+ select_distinct=0;
+ }
}
/* Calculate how to do the join */
@@ -3811,7 +3817,7 @@ bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
If there is SELECT in this statement with the same number it must be the
same SELECT
*/
- DBUG_ASSERT(select_lex->select_number == UINT_MAX ||
+ DBUG_SLOW_ASSERT(select_lex->select_number == UINT_MAX ||
select_lex->select_number == INT_MAX ||
!output ||
!output->get_select(select_lex->select_number) ||
@@ -6577,7 +6583,7 @@ add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
Item_field *cur_item;
key_map possible_keys(0);
- if (join->group_list || join->simple_group)
+ if (join->group_list)
{ /* Collect all query fields referenced in the GROUP clause. */
for (cur_group= join->group_list; cur_group; cur_group= cur_group->next)
(*cur_group->item)->walk(&Item::collect_item_field_processor, 0,
diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc
index baaa4571c9e..1ed0bb38e64 100644
--- a/sql/sql_sequence.cc
+++ b/sql/sql_sequence.cc
@@ -542,7 +542,8 @@ void sequence_definition::adjust_values(longlong next_value)
if ((real_increment= global_system_variables.auto_increment_increment)
!= 1)
- offset= global_system_variables.auto_increment_offset;
+ offset= (global_system_variables.auto_increment_offset %
+ global_system_variables.auto_increment_increment);
/*
Ensure that next_free_value has the right offset, so that we
@@ -564,7 +565,7 @@ void sequence_definition::adjust_values(longlong next_value)
else
{
next_free_value+= to_add;
- DBUG_ASSERT(next_free_value % real_increment == offset);
+ DBUG_ASSERT(llabs(next_free_value % real_increment) == offset);
}
}
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index e8f42003691..ea6ef7d86fb 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2616,7 +2616,7 @@ static int show_create_view(THD *thd, TABLE_LIST *table, String *buff)
We can't just use table->query, because our SQL_MODE may trigger
a different syntax, like when ANSI_QUOTES is defined.
*/
- table->view->unit.print(buff, enum_query_type(QT_ORDINARY |
+ table->view->unit.print(buff, enum_query_type(QT_VIEW_INTERNAL |
QT_ITEM_ORIGINAL_FUNC_NULLIF));
if (table->with_check != VIEW_CHECK_NONE)
@@ -6795,6 +6795,42 @@ store_constraints(THD *thd, TABLE *table, const LEX_CSTRING *db_name,
return schema_table_store_record(thd, table);
}
+static int get_check_constraints_record(THD *thd, TABLE_LIST *tables,
+ TABLE *table, bool res,
+ const LEX_CSTRING *db_name,
+ const LEX_CSTRING *table_name)
+{
+ DBUG_ENTER("get_check_constraints_record");
+ if (res)
+ {
+ if (thd->is_error())
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
+ thd->get_stmt_da()->sql_errno(),
+ thd->get_stmt_da()->message());
+ thd->clear_error();
+ DBUG_RETURN(0);
+ }
+ else if (!tables->view)
+ {
+ if (tables->table->s->table_check_constraints)
+ {
+ for (uint i= 0; i < tables->table->s->table_check_constraints; i++)
+ {
+ StringBuffer<MAX_FIELD_WIDTH> str(system_charset_info);
+ Virtual_column_info *check= tables->table->check_constraints[i];
+ restore_record(table, s->default_values);
+ table->field[0]->store(STRING_WITH_LEN("def"), system_charset_info);
+ table->field[1]->store(db_name->str, db_name->length, system_charset_info);
+ table->field[2]->store(check->name.str, check->name.length, system_charset_info);
+ table->field[3]->store(table_name->str, table_name->length, system_charset_info);
+ check->print(&str);
+ table->field[4]->store(str.ptr(), str.length(), system_charset_info);
+ schema_table_store_record(thd, table);
+ }
+ }
+ }
+ DBUG_RETURN(res);
+}
static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
TABLE *table, bool res,
@@ -9715,6 +9751,18 @@ ST_FIELD_INFO spatial_ref_sys_fields_info[]=
#endif /*HAVE_SPATIAL*/
+ST_FIELD_INFO check_constraints_fields_info[]=
+{
+ {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+ {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+ OPEN_FULL_TABLE},
+ {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+ OPEN_FULL_TABLE},
+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+ {"CHECK_CLAUSE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+ OPEN_FULL_TABLE},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
+};
/*
Description of ST_FIELD_INFO in table.h
@@ -9730,6 +9778,8 @@ ST_SCHEMA_TABLE schema_tables[]=
fill_schema_applicable_roles, 0, 0, -1, -1, 0, 0},
{"CHARACTER_SETS", charsets_fields_info, 0,
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
+ {"CHECK_CONSTRAINTS", check_constraints_fields_info, 0,
+ get_all_tables, 0, get_check_constraints_record, 1, 2, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY},
{"COLLATIONS", collation_fields_info, 0,
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h
index c2700eaee41..714a9075f92 100644
--- a/sql/sql_statistics.h
+++ b/sql/sql_statistics.h
@@ -21,7 +21,7 @@ enum enum_use_stat_tables_mode
{
NEVER,
COMPLEMENTARY,
- PEFERABLY,
+ PREFERABLY,
} Use_stat_tables_mode;
typedef
diff --git a/sql/sql_time.cc b/sql/sql_time.cc
index 430eb192052..c1300c78ad9 100644
--- a/sql/sql_time.cc
+++ b/sql/sql_time.cc
@@ -264,7 +264,7 @@ bool get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month,
ulong convert_period_to_month(ulong period)
{
ulong a,b;
- if (period == 0)
+ if (period == 0 || period > 999912)
return 0L;
if ((a=period/100) < YY_PART_YEAR)
a+=2000;
diff --git a/sql/sql_tvc.h b/sql/sql_tvc.h
index 420311cccb2..128cc883dd8 100644
--- a/sql/sql_tvc.h
+++ b/sql/sql_tvc.h
@@ -50,6 +50,8 @@ public:
have_query_plan(QEP_NOT_PRESENT_YET), explain(0),
select_options(select_options_arg)
{ };
+
+ ha_rows get_records() { return lists_of_values.elements; }
bool prepare(THD *thd_arg, SELECT_LEX *sl,
select_result *tmp_result,
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index be987b82cba..29ea427842f 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1321,6 +1321,8 @@ bool st_select_lex_unit::optimize()
thd->lex->current_select= lex_select_save;
DBUG_RETURN(TRUE);
}
+ if (derived)
+ sl->increase_derived_records(sl->tvc->get_records());
continue;
}
thd->lex->current_select= sl;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index cf894325ba5..cc22908ec4b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1996,6 +1996,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
preload_list preload_list_or_parts preload_keys preload_keys_parts
select_item_list select_item values_list no_braces
delete_limit_clause fields opt_values values
+ no_braces_with_names opt_values_with_names values_with_names
procedure_list procedure_list2 procedure_item
field_def handler opt_generated_always
opt_ignore opt_column opt_restrict
@@ -13156,7 +13157,7 @@ insert_values:
values_list:
values_list ',' no_braces
- | no_braces
+ | no_braces_with_names
;
ident_eq_list:
@@ -13209,11 +13210,31 @@ no_braces:
}
;
+no_braces_with_names:
+ '('
+ {
+ if (unlikely(!(Lex->insert_list= new (thd->mem_root) List_item)))
+ MYSQL_YYABORT;
+ }
+ opt_values_with_names ')'
+ {
+ LEX *lex=Lex;
+ if (unlikely(lex->many_values.push_back(lex->insert_list,
+ thd->mem_root)))
+ MYSQL_YYABORT;
+ }
+ ;
+
opt_values:
/* empty */ {}
| values
;
+opt_values_with_names:
+ /* empty */ {}
+ | values_with_names
+ ;
+
values:
values ',' expr_or_default
{
@@ -13227,6 +13248,25 @@ values:
}
;
+values_with_names:
+ values_with_names ',' remember_name expr_or_default remember_end
+ {
+ if (unlikely(Lex->insert_list->push_back($4, thd->mem_root)))
+ MYSQL_YYABORT;
+ // give some name in case of using in table value constuctor (TVC)
+ if (!$4->name.str || $4->name.str == item_empty_name)
+ $4->set_name(thd, $3, (uint) ($5 - $3), thd->charset());
+ }
+ | remember_name expr_or_default remember_end
+ {
+ if (unlikely(Lex->insert_list->push_back($2, thd->mem_root)))
+ MYSQL_YYABORT;
+ // give some name in case of using in table value constuctor (TVC)
+ if (!$2->name.str || $2->name.str == item_empty_name)
+ $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
+ }
+ ;
+
expr_or_default:
expr { $$= $1;}
| DEFAULT
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index ef12b9c0c53..d4838590075 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -1487,6 +1487,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
assign_to_keycache_parts
preload_list preload_list_or_parts preload_keys preload_keys_parts
select_item_list select_item values_list no_braces
+ no_braces_with_names opt_values_with_names values_with_names
delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item
field_def handler opt_generated_always
@@ -13384,7 +13385,7 @@ insert_values:
values_list:
values_list ',' no_braces
- | no_braces
+ | no_braces_with_names
;
ident_eq_list:
@@ -13437,11 +13438,31 @@ no_braces:
}
;
+no_braces_with_names:
+ '('
+ {
+ if (unlikely(!(Lex->insert_list= new (thd->mem_root) List_item)))
+ MYSQL_YYABORT;
+ }
+ opt_values_with_names ')'
+ {
+ LEX *lex=Lex;
+ if (unlikely(lex->many_values.push_back(lex->insert_list,
+ thd->mem_root)))
+ MYSQL_YYABORT;
+ }
+ ;
+
opt_values:
/* empty */ {}
| values
;
+opt_values_with_names:
+ /* empty */ {}
+ | values_with_names
+ ;
+
values:
values ',' expr_or_default
{
@@ -13455,6 +13476,25 @@ values:
}
;
+values_with_names:
+ values_with_names ',' remember_name expr_or_default remember_end
+ {
+ if (unlikely(Lex->insert_list->push_back($4, thd->mem_root)))
+ MYSQL_YYABORT;
+ // give some name in case of using in table value constuctor (TVC)
+ if (!$4->name.str || $4->name.str == item_empty_name)
+ $4->set_name(thd, $3, (uint) ($5 - $3), thd->charset());
+ }
+ | remember_name expr_or_default remember_end
+ {
+ if (unlikely(Lex->insert_list->push_back($2, thd->mem_root)))
+ MYSQL_YYABORT;
+ // give some name in case of using in table value constuctor (TVC)
+ if (!$2->name.str || $2->name.str == item_empty_name)
+ $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
+ }
+ ;
+
expr_or_default:
expr { $$= $1;}
| DEFAULT
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 37ae2fbb68a..6d2dbbf646e 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -2672,6 +2672,16 @@ static Sys_var_ulong Sys_div_precincrement(
SESSION_VAR(div_precincrement), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, DECIMAL_MAX_SCALE), DEFAULT(4), BLOCK_SIZE(1));
+static Sys_var_uint Sys_eq_range_index_dive_limit(
+ "eq_range_index_dive_limit",
+ "The optimizer will use existing index statistics instead of "
+ "doing index dives for equality ranges if the number of equality "
+ "ranges for the index is larger than or equal to this number. "
+ "If set to 0, index dives are always used.",
+ SESSION_VAR(eq_range_index_dive_limit), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, UINT_MAX32), DEFAULT(0),
+ BLOCK_SIZE(1));
+
static Sys_var_ulong Sys_range_alloc_block_size(
"range_alloc_block_size",
"Allocation block size for storing ranges during optimization",
diff --git a/sql/table.cc b/sql/table.cc
index b0468be17f2..de5a71f6af1 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -6885,7 +6885,10 @@ void TABLE::mark_columns_used_by_virtual_fields(void)
for (uint i= 0 ; i < s->fields ; i++)
{
if (bitmap_is_set(&tmp_set, i))
+ {
+ s->field[i]->flags|= PART_INDIRECT_KEY_FLAG;
field[i]->flags|= PART_INDIRECT_KEY_FLAG;
+ }
}
bitmap_clear_all(&tmp_set);
}
@@ -8335,7 +8338,7 @@ int TABLE_LIST::fetch_number_of_rows()
}
if (is_materialized_derived() && !fill_me)
{
- table->file->stats.records= ((select_unit*)(get_unit()->result))->records;
+ table->file->stats.records= get_unit()->result->est_records;
set_if_bigger(table->file->stats.records, 2);
table->used_stat_records= table->file->stats.records;
}
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 699a4daf27a..6aa8a68f222 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -159,6 +159,7 @@ extern "C" time_t wsrep_thd_query_start(THD *thd);
extern "C" query_id_t wsrep_thd_query_id(THD *thd);
extern "C" query_id_t wsrep_thd_wsrep_last_query_id(THD *thd);
extern "C" void wsrep_thd_set_wsrep_last_query_id(THD *thd, query_id_t id);
+extern "C" void wsrep_set_data_home_dir(const char *data_dir);
extern void wsrep_close_client_connections(my_bool wait_to_end);
extern int wsrep_wait_committing_connections_close(int wait_time);
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 8816a31330e..0a1d95f30b8 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -58,6 +58,13 @@ bool wsrep_sst_method_update (sys_var *self, THD* thd, enum_var_type type)
return 0;
}
+static const char* data_home_dir = NULL;
+
+extern "C"
+void wsrep_set_data_home_dir(const char *data_dir)
+{
+ data_home_dir= (data_dir && *data_dir) ? data_dir : NULL;
+}
static void make_wsrep_defaults_file()
{
@@ -595,6 +602,29 @@ static int sst_append_auth_env(wsp::env& env, const char* sst_auth)
return -env.error();
}
+#define DATA_HOME_DIR_ENV "INNODB_DATA_HOME_DIR"
+
+static int sst_append_data_dir(wsp::env& env, const char* data_dir)
+{
+ int const data_dir_size= strlen(DATA_HOME_DIR_ENV) + 1 /* = */
+ + (data_dir ? strlen(data_dir) : 0) + 1 /* \0 */;
+
+ wsp::string data_dir_str(data_dir_size); // for automatic cleanup on return
+ if (!data_dir_str()) return -ENOMEM;
+
+ int ret= snprintf(data_dir_str(), data_dir_size, "%s=%s",
+ DATA_HOME_DIR_ENV, data_dir ? data_dir : "");
+
+ if (ret < 0 || ret >= data_dir_size)
+ {
+ WSREP_ERROR("sst_append_data_dir(): snprintf() failed: %d", ret);
+ return (ret < 0 ? ret : -EMSGSIZE);
+ }
+
+ env.append(data_dir_str());
+ return -env.error();
+}
+
static ssize_t sst_prepare_other (const char* method,
const char* sst_auth,
const char* addr_in,
@@ -656,6 +686,16 @@ static ssize_t sst_prepare_other (const char* method,
return ret;
}
+ if (data_home_dir)
+ {
+ if ((ret= sst_append_data_dir(env, data_home_dir)))
+ {
+ WSREP_ERROR("sst_prepare_other(): appending data "
+ "directory failed: %d", ret);
+ return ret;
+ }
+ }
+
pthread_t tmp;
sst_thread_arg arg(cmd_str(), env());
mysql_mutex_lock (&arg.lock);
@@ -1347,6 +1387,16 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx,
return WSREP_CB_FAILURE;
}
+ if (data_home_dir)
+ {
+ if ((ret= sst_append_data_dir(env, data_home_dir)))
+ {
+ WSREP_ERROR("wsrep_sst_donate_cb(): appending data "
+ "directory failed: %d", ret);
+ return WSREP_CB_FAILURE;
+ }
+ }
+
if (!strcmp (WSREP_SST_MYSQLDUMP, method))
{
ret = sst_donate_mysqldump(data, &current_gtid->uuid, uuid_str,
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index 7fe120beb8e..bc43b844a35 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -594,7 +594,9 @@ void wsrep_node_address_init (const char* value)
static void wsrep_slave_count_change_update ()
{
- wsrep_slave_count_change += (wsrep_slave_threads - wsrep_prev_slave_threads);
+ wsrep_slave_count_change = (wsrep_slave_threads - wsrep_prev_slave_threads);
+ WSREP_DEBUG("Change on slave threads: New %lu old %lu difference %lu",
+ wsrep_slave_threads, wsrep_prev_slave_threads, wsrep_slave_count_change);
wsrep_prev_slave_threads = wsrep_slave_threads;
}
@@ -617,6 +619,12 @@ bool wsrep_desync_check (sys_var *self, THD* thd, set_var* var)
return true;
}
+ if (thd->global_read_lock.is_acquired())
+ {
+ my_message (ER_CANNOT_USER, "Global read lock acquired. Can't set 'wsrep_desync'", MYF(0));
+ return true;
+ }
+
bool new_wsrep_desync= (bool) var->save_result.ulonglong_value;
if (wsrep_desync == new_wsrep_desync) {
if (new_wsrep_desync) {
diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc
index db9e028b8f3..1041ad8614a 100644
--- a/storage/innobase/btr/btr0sea.cc
+++ b/storage/innobase/btr/btr0sea.cc
@@ -1279,8 +1279,6 @@ void btr_search_drop_page_hash_when_freed(const page_id_t& page_id)
mtr_t mtr;
dberr_t err = DB_SUCCESS;
- ut_d(export_vars.innodb_ahi_drop_lookups++);
-
mtr_start(&mtr);
/* If the caller has a latch on the page, then the caller must
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index 7ede67fd0e4..088741e8ce8 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2017, 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
@@ -391,7 +391,7 @@ buf_dump(
/* leave tmp_filename to exist */
return;
}
- if ( (j % 1024) == 0) {
+ if (SHUTTING_DOWN() && !(j % 1024)) {
service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
"Dumping buffer pool "
ULINTPF "/" ULINTPF ", "
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 51190ff2ef6..3fba1679cdf 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -6110,7 +6110,7 @@ dict_table_get_index_on_name(
while (index != NULL) {
if (index->is_committed() == committed
- && innobase_strcasecmp(index->name, name) == 0) {
+ && strcmp(index->name, name) == 0) {
return(index);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 0bdb3834f6f..5e80a8a0e08 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -169,8 +169,6 @@ static int innobase_wsrep_set_checkpoint(handlerton* hton, const XID* xid);
static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid);
#endif /* WITH_WSREP */
-/** to protect innobase_open_files */
-static mysql_mutex_t innobase_share_mutex;
/** to force correct commit order in binlog */
static ulong commit_threads = 0;
static mysql_cond_t commit_cond;
@@ -461,8 +459,6 @@ operation, we only do it every INNOBASE_WAKE_INTERVAL'th step. */
#define INNOBASE_WAKE_INTERVAL 32
static ulong innobase_active_counter = 0;
-static hash_table_t* innobase_open_tables;
-
/** Allowed values of innodb_change_buffering */
static const char* innodb_change_buffering_names[] = {
"none", /* IBUF_USE_NONE */
@@ -571,7 +567,6 @@ const struct _ft_vft_ext ft_vft_ext_result = {innobase_fts_get_version,
/* Keys to register pthread mutexes/cond in the current file with
performance schema */
-static mysql_pfs_key_t innobase_share_mutex_key;
static mysql_pfs_key_t commit_cond_mutex_key;
static mysql_pfs_key_t commit_cond_key;
static mysql_pfs_key_t pending_checkpoint_mutex_key;
@@ -580,7 +575,6 @@ static mysql_pfs_key_t thd_destructor_thread_key;
static PSI_mutex_info all_pthread_mutexes[] = {
PSI_KEY(commit_cond_mutex),
PSI_KEY(pending_checkpoint_mutex),
- PSI_KEY(innobase_share_mutex)
};
static PSI_cond_info all_innodb_conds[] = {
@@ -1072,10 +1066,6 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_truncated_status_writes, SHOW_LONG},
{"available_undo_logs",
(char*) &export_vars.innodb_available_undo_logs, SHOW_LONG},
-#ifdef UNIV_DEBUG
- {"ahi_drop_lookups",
- (char*) &export_vars.innodb_ahi_drop_lookups, SHOW_LONG},
-#endif /* UNIV_DEBUG */
/* Status variables for page compression */
{"page_compression_saved",
@@ -1195,23 +1185,6 @@ static SHOW_VAR innodb_status_variables[]= {
{NullS, NullS, SHOW_LONG}
};
-/************************************************************************//**
-Handling the shared INNOBASE_SHARE structure that is needed to provide table
-locking. Register the table name if it doesn't exist in the hash table. */
-static
-INNOBASE_SHARE*
-get_share(
-/*======*/
- const char* table_name); /*!< in: table to lookup */
-
-/************************************************************************//**
-Free the shared object that was registered with get_share(). */
-static
-void
-free_share(
-/*=======*/
- INNOBASE_SHARE* share); /*!< in/own: share to free */
-
/*****************************************************************//**
Frees a possible InnoDB trx object associated with the current THD.
@return 0 or error number */
@@ -3848,6 +3821,12 @@ static int innodb_init_params()
srv_data_home = innobase_data_home_dir
? innobase_data_home_dir : default_path;
+#ifdef WITH_WSREP
+ /* If we use the wsrep API, then we need to tell the server
+ the path to the data files (for passing it to the SST scripts): */
+ wsrep_set_data_home_dir(srv_data_home);
+#endif /* WITH_WSREP */
+
/*--------------- Shared tablespaces -------------------------*/
@@ -4289,10 +4268,6 @@ static int innodb_init(void* p)
ibuf_max_size_update(srv_change_buffer_max_size);
- innobase_open_tables = hash_create(200);
- mysql_mutex_init(innobase_share_mutex_key,
- &innobase_share_mutex,
- MY_MUTEX_INIT_FAST);
mysql_mutex_init(commit_cond_mutex_key,
&commit_cond_m, MY_MUTEX_INIT_FAST);
mysql_cond_init(commit_cond_key, &commit_cond, 0);
@@ -4361,9 +4336,6 @@ innobase_end(handlerton*, ha_panic_function)
}
}
- hash_table_free(innobase_open_tables);
- innobase_open_tables = NULL;
-
st_my_thread_var* running = reinterpret_cast<st_my_thread_var*>(
my_atomic_loadptr_explicit(
reinterpret_cast<void**>(&srv_running),
@@ -4381,7 +4353,6 @@ innobase_end(handlerton*, ha_panic_function)
innodb_shutdown();
innobase_space_shutdown();
- mysql_mutex_destroy(&innobase_share_mutex);
mysql_mutex_destroy(&commit_cond_m);
mysql_cond_destroy(&commit_cond);
mysql_mutex_destroy(&pending_checkpoint_mutex);
@@ -5617,6 +5588,7 @@ is consistent between KEY info from mysql and that from innodb index.
@param[in] key_info Index info from mysql
@param[in] index_info Index info from InnoDB
@return true if all column types match. */
+static
bool
innobase_match_index_columns(
const KEY* key_info,
@@ -5906,90 +5878,33 @@ innobase_build_v_templ(
s_templ->tb_name = table->s->table_name.str;
}
-/*******************************************************************//**
-This function builds a translation table in INNOBASE_SHARE
-structure for fast index location with mysql array number from its
-table->key_info structure. This also provides the necessary translation
-between the key order in mysql key_info and InnoDB ib_table->indexes if
-they are not fully matched with each other.
-Note we do not have any mutex protecting the translation table
-building based on the assumption that there is no concurrent
-index creation/drop and DMLs that requires index lookup. All table
-handle will be closed before the index creation/drop.
-@return true if index translation table built successfully */
-static
-bool
-innobase_build_index_translation(
-/*=============================*/
- const TABLE* table, /*!< in: table in MySQL data
- dictionary */
- dict_table_t* ib_table,/*!< in: table in InnoDB data
- dictionary */
- INNOBASE_SHARE* share) /*!< in/out: share structure
- where index translation table
- will be constructed in. */
+/** Check consistency between .frm indexes and InnoDB indexes.
+@param[in] table table object formed from .frm
+@param[in] ib_table InnoDB table definition
+@retval true if not errors were found */
+static bool
+check_index_consistency(const TABLE* table, const dict_table_t* ib_table)
{
- DBUG_ENTER("innobase_build_index_translation");
-
- bool ret = true;
-
- mutex_enter(&dict_sys->mutex);
-
- ulint mysql_num_index = table->s->keys;
- ulint ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
- dict_index_t** index_mapping = share->idx_trans_tbl.index_mapping;
+ ulint mysql_num_index = table->s->keys;
+ ulint ib_num_index = UT_LIST_GET_LEN(ib_table->indexes);
+ bool ret = true;
/* If there exists inconsistency between MySQL and InnoDB dictionary
(metadata) information, the number of index defined in MySQL
- could exceed that in InnoDB, do not build index translation
- table in such case */
+ could exceed that in InnoDB, return error */
if (ib_num_index < mysql_num_index) {
ret = false;
goto func_exit;
}
- /* If index entry count is non-zero, nothing has
- changed since last update, directly return TRUE */
- if (share->idx_trans_tbl.index_count) {
- /* Index entry count should still match mysql_num_index */
- ut_a(share->idx_trans_tbl.index_count == mysql_num_index);
- goto func_exit;
- }
-
- /* The number of index increased, rebuild the mapping table */
- if (mysql_num_index > share->idx_trans_tbl.array_size) {
-
- index_mapping = reinterpret_cast<dict_index_t**>(
- ut_realloc(index_mapping,
- mysql_num_index * sizeof(*index_mapping)));
-
- if (index_mapping == NULL) {
- /* Report an error if index_mapping continues to be
- NULL and mysql_num_index is a non-zero value */
- sql_print_error("InnoDB: fail to allocate memory for "
- "index translation table. Number of "
- "Index: " ULINTPF
- ", array size:" ULINTPF,
- mysql_num_index,
- share->idx_trans_tbl.array_size);
- ret = false;
- goto func_exit;
- }
-
- share->idx_trans_tbl.array_size = mysql_num_index;
- }
-
/* For each index in the mysql key_info array, fetch its
corresponding InnoDB index pointer into index_mapping
array. */
for (ulint count = 0; count < mysql_num_index; count++) {
-
- /* Fetch index pointers into index_mapping according to mysql
- index sequence */
- index_mapping[count] = dict_table_get_index_on_name(
+ const dict_index_t* index = dict_table_get_index_on_name(
ib_table, table->key_info[count].name.str);
- if (index_mapping[count] == 0) {
+ if (index == NULL) {
sql_print_error("Cannot find index %s in InnoDB"
" index dictionary.",
table->key_info[count].name.str);
@@ -6000,7 +5915,7 @@ innobase_build_index_translation(
/* Double check fetched index has the same
column info as those in mysql key_info. */
if (!innobase_match_index_columns(&table->key_info[count],
- index_mapping[count])) {
+ index)) {
sql_print_error("Found index %s whose column info"
" does not match that of MariaDB.",
table->key_info[count].name.str);
@@ -6009,51 +5924,10 @@ innobase_build_index_translation(
}
}
- /* Successfully built the translation table */
- share->idx_trans_tbl.index_count = mysql_num_index;
-
func_exit:
- if (!ret) {
- /* Build translation table failed. */
- ut_free(index_mapping);
-
- share->idx_trans_tbl.array_size = 0;
- share->idx_trans_tbl.index_count = 0;
- index_mapping = NULL;
- }
-
- share->idx_trans_tbl.index_mapping = index_mapping;
-
- mutex_exit(&dict_sys->mutex);
-
- DBUG_RETURN(ret);
+ return ret;
}
-/*******************************************************************//**
-This function uses index translation table to quickly locate the
-requested index structure.
-Note we do not have mutex protection for the index translatoin table
-access, it is based on the assumption that there is no concurrent
-translation table rebuild (fter create/drop index) and DMLs that
-require index lookup.
-@return dict_index_t structure for requested index. NULL if
-fail to locate the index structure. */
-static
-dict_index_t*
-innobase_index_lookup(
-/*==================*/
- INNOBASE_SHARE* share, /*!< in: share structure for index
- translation table. */
- uint keynr) /*!< in: index number for the requested
- index */
-{
- if (share->idx_trans_tbl.index_mapping == NULL
- || keynr >= share->idx_trans_tbl.index_count) {
- return(NULL);
- }
-
- return(share->idx_trans_tbl.index_mapping[keynr]);
-}
/********************************************************************//**
Get the upper limit of the MySQL integral and floating-point type.
@return maximum allowed value for the field */
@@ -6183,11 +6057,6 @@ ha_innobase::open(const char* name, int, uint)
m_user_thd = NULL;
- if (!(m_share = get_share(name))) {
-
- DBUG_RETURN(1);
- }
-
/* Will be allocated if it is needed in ::update_row() */
m_upd_buf = NULL;
m_upd_buf_size = 0;
@@ -6211,7 +6080,6 @@ ha_innobase::open(const char* name, int, uint)
norm_name);
}
no_such_table:
- free_share(m_share);
set_my_errno(ENOENT);
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
@@ -6269,7 +6137,6 @@ no_such_table:
}
if (!thd_tablespace_op(thd)) {
- free_share(m_share);
set_my_errno(ENOENT);
int ret_err = HA_ERR_NO_SUCH_TABLE;
@@ -6326,9 +6193,10 @@ no_such_table:
mutex_exit(&dict_sys->mutex);
}
- if (!innobase_build_index_translation(table, ib_table, m_share)) {
- sql_print_error("Build InnoDB index translation table for"
- " Table %s failed", name);
+ if (!check_index_consistency(table, ib_table)) {
+ sql_print_error("InnoDB indexes are inconsistent with what "
+ "defined in .frm for table %s",
+ name);
}
/* Allocate a buffer for a 'row reference'. A row reference is
@@ -6424,9 +6292,6 @@ no_such_table:
/* Index block size in InnoDB: used by MySQL in query optimization */
stats.block_size = srv_page_size;
- /* Init table lock structure */
- thr_lock_data_init(&m_share->lock, &lock, NULL);
-
if (m_prebuilt->table == NULL
|| m_prebuilt->table->is_temporary()
|| m_prebuilt->table->persistent_autoinc
@@ -6619,8 +6484,6 @@ ha_innobase::close()
m_upd_buf_size = 0;
}
- free_share(m_share);
-
MONITOR_INC(MONITOR_TABLE_CLOSE);
/* Tell InnoDB server that there might be work for
@@ -8184,7 +8047,8 @@ ha_innobase::write_row(
/* We need the upper limit of the col type to check for
whether we update the table autoinc counter or not. */
- col_max_value = innobase_get_int_col_max_value(table->next_number_field);
+ col_max_value = innobase_get_int_col_max_value(
+ table->next_number_field);
/* Get the value that MySQL attempted to store in the table.*/
auto_inc = table->next_number_field->val_uint();
@@ -9487,60 +9351,18 @@ ha_innobase::innobase_get_index(
clustered index, even if it was internally
generated by InnoDB */
{
- KEY* key;
+ KEY* key = NULL;
+ dict_table_t* ib_table = m_prebuilt->table;
dict_index_t* index;
DBUG_ENTER("innobase_get_index");
if (keynr != MAX_KEY && table->s->keys > 0) {
-
- key = table->key_info + keynr;
-
- index = innobase_index_lookup(m_share, keynr);
-
- if (index != NULL) {
- if (!key || ut_strcmp(index->name, key->name.str) != 0) {
- ib::error() << " Index for key no " << keynr
- << " mysql name " << (key ? key->name.str : "NULL")
- << " InnoDB name " << index->name()
- << " for table " << m_prebuilt->table->name.m_name;
-
- for(uint i=0; i < table->s->keys; i++) {
- index = innobase_index_lookup(m_share, i);
- key = table->key_info + keynr;
-
- if (index) {
- ib::info() << " Index for key no " << keynr
- << " mysql name " << (key ? key->name.str : "NULL")
- << " InnoDB name " << index->name()
- << " for table " << m_prebuilt->table->name.m_name;
- }
- }
-
- }
-
- ut_a(ut_strcmp(index->name, key->name.str) == 0);
- } else {
- /* Can't find index with keynr in the translation
- table. Only print message if the index translation
- table exists */
- if (m_share->idx_trans_tbl.index_mapping != NULL) {
- sql_print_warning("InnoDB could not find"
- " index %s key no %u for"
- " table %s through its"
- " index translation table",
- key ? key->name.str : "NULL",
- keynr,
- m_prebuilt->table->name
- .m_name);
- }
-
- index = dict_table_get_index_on_name(
- m_prebuilt->table, key->name.str);
- }
+ key = &table->key_info[keynr];
+ index = dict_table_get_index_on_name(ib_table, key->name.str);
+ ut_ad(index);
} else {
- key = 0;
- index = dict_table_get_first_index(m_prebuilt->table);
+ index = dict_table_get_first_index(ib_table);
}
if (index == NULL) {
@@ -9548,7 +9370,7 @@ ha_innobase::innobase_get_index(
"InnoDB could not find key no %u with name %s"
" from dict cache for table %s",
keynr, key ? key->name.str : "NULL",
- m_prebuilt->table->name.m_name);
+ ib_table->name.m_name);
}
DBUG_RETURN(index);
@@ -13699,20 +13521,12 @@ innodb_set_buf_pool_size(ulonglong buf_pool_size)
}
/*********************************************************************//**
-Calculates the key number used inside MySQL for an Innobase index. We will
-first check the "index translation table" for a match of the index to get
-the index number. If there does not exist an "index translation table",
-or not able to find the index in the translation table, then we will fall back
-to the traditional way of looping through dict_index_t list to find a
-match. In this case, we have to take into account if we generated a
-default clustered index for the table
+Calculates the key number used inside MySQL for an Innobase index.
@return the key number used inside MySQL */
static
unsigned
innobase_get_mysql_key_number_for_index(
/*====================================*/
- INNOBASE_SHARE* share, /*!< in: share structure for index
- translation table. */
const TABLE* table, /*!< in: table in MySQL data
dictionary */
dict_table_t* ib_table,/*!< in: table in InnoDB data
@@ -13742,27 +13556,8 @@ innobase_get_mysql_key_number_for_index(
return(i);
}
- /* If index translation table exists, we will first check
- the index through index translation table for a match. */
- if (share->idx_trans_tbl.index_mapping != NULL) {
- for (i = 0; i < share->idx_trans_tbl.index_count; i++) {
- if (share->idx_trans_tbl.index_mapping[i] == index) {
- return(i);
- }
- }
-
- /* Print an error message if we cannot find the index
- in the "index translation table". */
- if (index->is_committed()) {
- sql_print_error("Cannot find index %s in InnoDB index"
- " translation table.", index->name());
- }
- }
-
- /* If we do not have an "index translation table", or not able
- to find the index in the translation table, we'll directly find
- matching index with information from mysql TABLE structure and
- InnoDB dict_index_t list */
+ /* Directly find matching index with information from mysql TABLE
+ structure and InnoDB dict_index_t list */
for (i = 0; i < table->s->keys; i++) {
ind = dict_table_get_index_on_name(
ib_table, table->key_info[i].name.str);
@@ -14119,11 +13914,6 @@ ha_innobase::info_low(
for (i = 0; i < table->s->keys; i++) {
ulong j;
- /* We could get index quickly through internal
- index mapping with the index translation table.
- The identity of index (match up index name with
- that of table->key_info[i]) is already verified in
- innobase_get_index(). */
dict_index_t* index = innobase_get_index(i);
if (index == NULL) {
@@ -14231,7 +14021,7 @@ ha_innobase::info_low(
if (err_index) {
errkey = innobase_get_mysql_key_number_for_index(
- m_share, table, ib_table, err_index);
+ table, ib_table, err_index);
} else {
errkey = (unsigned int) (
(m_prebuilt->trx->error_key_num
@@ -16061,7 +15851,7 @@ static
int
innodb_show_mutex_status(
handlerton*
-#ifndef DBUG_OFF
+#ifdef DBUG_ASSERT_EXISTS
hton
#endif
,
@@ -16092,7 +15882,7 @@ static
int
innodb_show_rwlock_status(
handlerton*
-#ifndef DBUG_OFF
+#ifdef DBUG_ASSERT_EXISTS
hton
#endif
,
@@ -16236,104 +16026,6 @@ innobase_show_status(
/* Success */
return(false);
}
-
-/************************************************************************//**
-Handling the shared INNOBASE_SHARE structure that is needed to provide table
-locking. Register the table name if it doesn't exist in the hash table. */
-static
-INNOBASE_SHARE*
-get_share(
-/*======*/
- const char* table_name)
-{
- INNOBASE_SHARE* share;
-
- mysql_mutex_lock(&innobase_share_mutex);
-
- ulint fold = ut_fold_string(table_name);
-
- HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
- INNOBASE_SHARE*, share,
- ut_ad(share->use_count > 0),
- !strcmp(share->table_name, table_name));
-
- if (share == NULL) {
-
- uint length = (uint) strlen(table_name);
-
- /* TODO: invoke HASH_MIGRATE if innobase_open_tables
- grows too big */
-
- share = reinterpret_cast<INNOBASE_SHARE*>(
- my_malloc(//PSI_INSTRUMENT_ME,
- sizeof(*share) + length + 1,
- MYF(MY_FAE | MY_ZEROFILL)));
-
- share->table_name = reinterpret_cast<char*>(
- memcpy(share + 1, table_name, length + 1));
-
- HASH_INSERT(INNOBASE_SHARE, table_name_hash,
- innobase_open_tables, fold, share);
-
- thr_lock_init(&share->lock);
-
- /* Index translation table initialization */
- share->idx_trans_tbl.index_mapping = NULL;
- share->idx_trans_tbl.index_count = 0;
- share->idx_trans_tbl.array_size = 0;
- }
-
- ++share->use_count;
-
- mysql_mutex_unlock(&innobase_share_mutex);
-
- return(share);
-}
-
-/************************************************************************//**
-Free the shared object that was registered with get_share(). */
-static
-void
-free_share(
-/*=======*/
- INNOBASE_SHARE* share) /*!< in/own: table share to free */
-{
- mysql_mutex_lock(&innobase_share_mutex);
-
-#ifdef UNIV_DEBUG
- INNOBASE_SHARE* share2;
- ulint fold = ut_fold_string(share->table_name);
-
- HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
- INNOBASE_SHARE*, share2,
- ut_ad(share->use_count > 0),
- !strcmp(share->table_name, share2->table_name));
-
- ut_a(share2 == share);
-#endif /* UNIV_DEBUG */
-
- --share->use_count;
-
- if (share->use_count == 0) {
- ulint fold = ut_fold_string(share->table_name);
-
- HASH_DELETE(INNOBASE_SHARE, table_name_hash,
- innobase_open_tables, fold, share);
-
- thr_lock_delete(&share->lock);
-
- /* Free any memory from index translation table */
- ut_free(share->idx_trans_tbl.index_mapping);
-
- my_free(share);
-
- /* TODO: invoke HASH_MIGRATE if innobase_open_tables
- shrinks too much */
- }
-
- mysql_mutex_unlock(&innobase_share_mutex);
-}
-
/*********************************************************************//**
Returns number of THR_LOCK locks used for one instance of InnoDB table.
InnoDB no longer relies on THR_LOCK locks so 0 value is returned.
@@ -16785,11 +16477,11 @@ ha_innobase::get_auto_increment(
"THD: %ld, current: %llu, autoinc: %llu",
m_prebuilt->autoinc_increment,
increment,
- thd_get_thread_id(ha_thd()),
+ thd_get_thread_id(m_user_thd),
current, autoinc);
-
- if (!wsrep_on(ha_thd())) {
- current = autoinc - m_prebuilt->autoinc_increment;
+ if (!wsrep_on(m_user_thd)) {
+ current = autoinc
+ - m_prebuilt->autoinc_increment;
}
current = innobase_next_autoinc(
@@ -20718,6 +20410,7 @@ static TABLE* innodb_acquire_mdl(THD* thd, dict_table_t* table)
if (!table_name_parse(table->name, db_buf, tbl_buf,
db_buf_len, tbl_buf_len)) {
+ table->release();
return NULL;
}
@@ -20800,6 +20493,7 @@ static TABLE* innodb_find_table_for_vc(THD* thd, dict_table_t* table)
if (!table_name_parse(table->name, db_buf, tbl_buf,
db_buf_len, tbl_buf_len)) {
+ ut_ad(!"invalid table name");
return NULL;
}
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index f2bb8aa5ef2..c98779f6823 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -23,35 +23,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
system clustered index when there is no primary key. */
extern const char innobase_index_reserve_name[];
-/* Structure defines translation table between mysql index and InnoDB
-index structures */
-struct innodb_idx_translate_t {
-
- ulint index_count; /*!< number of valid index entries
- in the index_mapping array */
-
- ulint array_size; /*!< array size of index_mapping */
-
- dict_index_t** index_mapping; /*!< index pointer array directly
- maps to index in InnoDB from MySQL
- array index */
-};
-
-/** InnoDB table share */
-typedef struct st_innobase_share {
- THR_LOCK lock;
- const char* table_name; /*!< InnoDB table name */
- uint use_count; /*!< reference count,
- incremented in get_share()
- and decremented in
- free_share() */
- void* table_name_hash;
- /*!< hash table chain node */
- innodb_idx_translate_t
- idx_trans_tbl; /*!< index translation table between
- MySQL and InnoDB */
-} INNOBASE_SHARE;
-
/** Prebuilt structures in an InnoDB table handle used within MySQL */
struct row_prebuilt_t;
@@ -496,9 +467,6 @@ protected:
THR_LOCK_DATA lock;
- /** information for MySQL table locking */
- INNOBASE_SHARE* m_share;
-
/** buffer used in updates */
uchar* m_upd_buf;
@@ -635,17 +603,6 @@ trx_t*
innobase_trx_allocate(
MYSQL_THD thd); /*!< in: user thread handle */
-/** Match index columns between MySQL and InnoDB.
-This function checks whether the index column information
-is consistent between KEY info from mysql and that from innodb index.
-@param[in] key_info Index info from mysql
-@param[in] index_info Index info from InnoDB
-@return true if all column types match. */
-bool
-innobase_match_index_columns(
- const KEY* key_info,
- const dict_index_t* index_info);
-
/*********************************************************************//**
This function checks each index name for a table against reserved
system default primary index name 'GEN_CLUST_INDEX'. If a name
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index aadb0641a72..af0eac0dac4 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -5350,14 +5350,14 @@ new_clustered_failed:
= dict_table_get_nth_col(user_table, i));
ut_d(const dict_index_t* index
= user_table->indexes.start);
- DBUG_ASSERT(col->mtype == old_col->mtype);
- DBUG_ASSERT(col->prtype == old_col->prtype);
- DBUG_ASSERT(col->mbminlen
+ DBUG_SLOW_ASSERT(col->mtype == old_col->mtype);
+ DBUG_SLOW_ASSERT(col->prtype == old_col->prtype);
+ DBUG_SLOW_ASSERT(col->mbminlen
== old_col->mbminlen);
- DBUG_ASSERT(col->mbmaxlen
+ DBUG_SLOW_ASSERT(col->mbmaxlen
== old_col->mbmaxlen);
- DBUG_ASSERT(col->len >= old_col->len);
- DBUG_ASSERT(old_col->is_instant()
+ DBUG_SLOW_ASSERT(col->len >= old_col->len);
+ DBUG_SLOW_ASSERT(old_col->is_instant()
== (dict_col_get_clust_pos(
old_col, index)
>= index->n_core_fields));
@@ -8491,36 +8491,17 @@ change_fields_versioning_try(
DBUG_RETURN(false);
}
- uint virtual_count = 0;
-
List_iterator_fast<Create_field> it(
ha_alter_info->alter_info->create_list);
- for (uint i = 0; i < table->s->fields; i++) {
- const Field* field = table->field[i];
-
- if (innobase_is_v_fld(field)) {
- virtual_count++;
- continue;
- }
-
- const Create_field* create_field = NULL;
- while (const Create_field* cf = it++) {
- if (cf->field == field) {
- create_field = cf;
- break;
- }
- }
- it.rewind();
- DBUG_ASSERT(create_field);
-
+ while (const Create_field* create_field = it++) {
if (create_field->versioning
== Column_definition::VERSIONING_NOT_SET) {
continue;
}
const dict_table_t* new_table = ctx->new_table;
- ulint pos = i - virtual_count;
+ const uint pos = innodb_col_no(create_field->field);
const dict_col_t* col = dict_table_get_nth_col(new_table, pos);
DBUG_ASSERT(!col->vers_sys_start());
@@ -8560,31 +8541,12 @@ change_fields_versioning_cache(
DBUG_ASSERT(ctx);
DBUG_ASSERT(ha_alter_info->handler_flags & ALTER_COLUMN_UNVERSIONED);
- uint virtual_count = 0;
-
List_iterator_fast<Create_field> it(
ha_alter_info->alter_info->create_list);
- for (uint i = 0; i < table->s->fields; i++) {
- const Field* field = table->field[i];
-
- if (innobase_is_v_fld(field)) {
- virtual_count++;
- continue;
- }
-
- const Create_field* create_field = NULL;
- while (const Create_field* cf = it++) {
- if (cf->field == field) {
- create_field = cf;
- break;
- }
- }
- it.rewind();
- DBUG_ASSERT(create_field);
-
- dict_col_t* col
- = dict_table_get_nth_col(ctx->new_table, i - virtual_count);
+ while (const Create_field* create_field = it++) {
+ dict_col_t* col = dict_table_get_nth_col(
+ ctx->new_table, innodb_col_no(create_field->field));
if (create_field->versioning
== Column_definition::WITHOUT_VERSIONING) {
@@ -9775,12 +9737,6 @@ foreign_fail:
log_append_on_checkpoint(NULL);
- /* Invalidate the index translation table. In partitioned
- tables, there is no share. */
- if (m_share) {
- m_share->idx_trans_tbl.index_count = 0;
- }
-
/* Tell the InnoDB server that there might be work for
utility threads: */
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index eda991661c1..99530a3799c 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -139,10 +139,15 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply);
/** Moves the parsing buffer data left to the buffer start. */
void recv_sys_justify_left_parsing_buf();
-/** Report optimized DDL operation (without redo log), corresponding to MLOG_INDEX_LOAD.
+/** Report optimized DDL operation (without redo log),
+corresponding to MLOG_INDEX_LOAD.
@param[in] space_id tablespace identifier
*/
-extern void(*log_optimized_ddl_op)(ulint space_id);
+extern void (*log_optimized_ddl_op)(ulint space_id);
+
+/** Report backup-unfriendly TRUNCATE operation (with separate log file),
+corresponding to MLOG_TRUNCATE. */
+extern void (*log_truncate)();
/** Report an operation to create, delete, or rename a file during backup.
@param[in] space_id tablespace identifier
@@ -181,32 +186,6 @@ struct recv_t{
rec_list;/*!< list of log records for this page */
};
-/** States of recv_addr_t */
-enum recv_addr_state {
- /** not yet processed */
- RECV_NOT_PROCESSED,
- /** page is being read */
- RECV_BEING_READ,
- /** log records are being applied on the page */
- RECV_BEING_PROCESSED,
- /** log records have been applied on the page */
- RECV_PROCESSED,
- /** log records have been discarded because the tablespace
- does not exist */
- RECV_DISCARDED
-};
-
-/** Hashed page file address struct */
-struct recv_addr_t{
- enum recv_addr_state state;
- /*!< recovery state of the page */
- unsigned space:32;/*!< space id */
- unsigned page_no:32;/*!< page number */
- UT_LIST_BASE_NODE_T(recv_t)
- rec_list;/*!< list of log records for this page */
- hash_node_t addr_hash;/*!< hash node in the hash bucket chain */
-};
-
struct recv_dblwr_t {
/** Add a page frame to the doublewrite recovery buffer. */
void add(byte* page) {
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index a5a73265170..c0fa20d7725 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -1010,12 +1010,6 @@ struct export_var_t{
of used row log buffer */
ulint innodb_onlineddl_pct_progress; /*!< Online alter progress */
-#ifdef UNIV_DEBUG
- ulint innodb_ahi_drop_lookups; /*!< number of adaptive hash
- index lookups when freeing
- file pages */
-#endif /* UNIV_DEBUG */
-
int64_t innodb_page_compression_saved;/*!< Number of bytes saved
by page compression */
int64_t innodb_index_pages_written; /*!< Number of index pages
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 07ae85ced5a..b7c4f8d37cd 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -3528,7 +3528,7 @@ lock_table_create(
UT_LIST_ADD_LAST(trx->lock.trx_locks, lock);
#ifdef WITH_WSREP
- if (c_lock) {
+ if (c_lock && wsrep_on_trx(trx)) {
if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
ut_list_insert(table->locks, c_lock, lock,
TableLockGetNode());
@@ -3758,7 +3758,7 @@ lock_table_enqueue_waiting(
}
#ifdef WITH_WSREP
- if (trx->lock.was_chosen_as_deadlock_victim) {
+ if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) {
return(DB_DEADLOCK);
}
#endif /* WITH_WSREP */
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 08f4f72efbc..a98397b0f7c 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -954,12 +954,6 @@ void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key)
return;
}
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
- service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
- "log write up to: " LSN_PF,
- lsn);
- }
-
loop:
ut_ad(++loop_count < 128);
@@ -1087,6 +1081,13 @@ loop:
}
}
+ if (UNIV_UNLIKELY(srv_shutdown_state != SRV_SHUTDOWN_NONE)) {
+ service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "InnoDB log write: "
+ LSN_PF "," LSN_PF,
+ log_sys.write_lsn, lsn);
+ }
+
if (log_sys.is_encrypted()) {
log_crypt(write_buf + area_start, log_sys.write_lsn,
area_end - area_start,
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 1cbb102bfdd..f8fccea5617 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -169,11 +169,45 @@ typedef std::map<
static recv_spaces_t recv_spaces;
-/** Report optimized DDL operation (without redo log), corresponding to MLOG_INDEX_LOAD.
+/** States of recv_addr_t */
+enum recv_addr_state {
+ /** not yet processed */
+ RECV_NOT_PROCESSED,
+ /** page is being read */
+ RECV_BEING_READ,
+ /** log records are being applied on the page */
+ RECV_BEING_PROCESSED,
+ /** log records have been applied on the page */
+ RECV_PROCESSED,
+ /** log records have been discarded because the tablespace
+ does not exist */
+ RECV_DISCARDED
+};
+
+/** Hashed page file address struct */
+struct recv_addr_t{
+ /** recovery state of the page */
+ recv_addr_state state;
+ /** tablespace identifier */
+ unsigned space:32;
+ /** page number */
+ unsigned page_no:32;
+ /** list of log records for this page */
+ UT_LIST_BASE_NODE_T(recv_t) rec_list;
+ /** hash node in the hash bucket chain */
+ hash_node_t addr_hash;
+};
+
+/** Report optimized DDL operation (without redo log),
+corresponding to MLOG_INDEX_LOAD.
@param[in] space_id tablespace identifier
*/
void (*log_optimized_ddl_op)(ulint space_id);
+/** Report backup-unfriendly TRUNCATE operation (with separate log file),
+corresponding to MLOG_TRUNCATE. */
+void (*log_truncate)();
+
/** Report an operation to create, delete, or rename a file during backup.
@param[in] space_id tablespace identifier
@param[in] flags tablespace flags (NULL if not create)
@@ -189,11 +223,9 @@ void (*log_file_op)(ulint space_id, const byte* flags,
@param[in,out] name file name
@param[in] len length of the file name
@param[in] space_id the tablespace ID
-@param[in] deleted whether this is a MLOG_FILE_DELETE record
-@retval true if able to process file successfully.
-@retval false if unable to process the file */
+@param[in] deleted whether this is a MLOG_FILE_DELETE record */
static
-bool
+void
fil_name_process(
char* name,
ulint len,
@@ -201,15 +233,13 @@ fil_name_process(
bool deleted)
{
if (srv_operation == SRV_OPERATION_BACKUP) {
- return true;
+ return;
}
ut_ad(srv_operation == SRV_OPERATION_NORMAL
|| srv_operation == SRV_OPERATION_RESTORE
|| srv_operation == SRV_OPERATION_RESTORE_EXPORT);
- bool processed = true;
-
/* We will also insert space=NULL into the map, so that
further checks can ensure that a MLOG_FILE_NAME record was
scanned before applying any page records for the space_id. */
@@ -256,7 +286,6 @@ fil_name_process(
<< f.name << "' and '" << name << "'."
" You must delete one of them.";
recv_sys->found_corrupt_fs = true;
- processed = false;
}
break;
@@ -309,7 +338,6 @@ fil_name_process(
" remove the .ibd file, you can set"
" --innodb_force_recovery.";
recv_sys->found_corrupt_fs = true;
- processed = false;
break;
}
@@ -320,7 +348,6 @@ fil_name_process(
break;
}
}
- return(processed);
}
/** Parse or process a MLOG_FILE_* record.
@@ -1097,6 +1124,12 @@ recv_parse_or_apply_log_rec_body(
}
return(ptr + 8);
case MLOG_TRUNCATE:
+ if (log_truncate) {
+ ut_ad(srv_operation != SRV_OPERATION_NORMAL);
+ log_truncate();
+ recv_sys->found_corrupt_fs = true;
+ return NULL;
+ }
return(truncate_t::parse_redo_entry(ptr, end_ptr, space_id));
default:
@@ -1174,6 +1207,7 @@ parse_log:
redo log been written with something
older than InnoDB Plugin 1.0.4. */
ut_ad(offs == FIL_PAGE_TYPE
+ || srv_is_undo_tablespace(space_id)
|| offs == IBUF_TREE_SEG_HEADER
+ IBUF_HEADER + FSEG_HDR_OFFSET
|| offs == PAGE_BTR_IBUF_FREE_LIST
@@ -1199,6 +1233,7 @@ parse_log:
ut_ad(0
/* fil_crypt_rotate_page() writes this */
|| offs == FIL_PAGE_SPACE_ID
+ || srv_is_undo_tablespace(space_id)
|| offs == IBUF_TREE_SEG_HEADER
+ IBUF_HEADER + FSEG_HDR_SPACE
|| offs == IBUF_TREE_SEG_HEADER
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index 36b9a135b10..fb8f62f5fe3 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -846,7 +846,8 @@ page_cur_insert_rec_write_log(
ulint i;
if (index->table->is_temporary()) {
- ut_ad(!mlog_open(mtr, 0));
+ mtr->set_modified();
+ ut_ad(mtr->get_log_mode() == MTR_LOG_NO_REDO);
return;
}
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index aab445cb197..8758db3c346 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -3915,7 +3915,7 @@ row_import_for_mysql(
DBUG_EXECUTE_IF("ib_import_reset_space_and_lsn_failure",
err = DB_TOO_MANY_CONCURRENT_TRXS;);
-
+#ifdef BTR_CUR_HASH_ADAPT
/* On DISCARD TABLESPACE, we did not drop any adaptive hash
index entries. If we replaced the discarded tablespace with a
smaller one here, there could still be some adaptive hash
@@ -3932,6 +3932,7 @@ row_import_for_mysql(
break;
}
}
+#endif /* BTR_CUR_HASH_ADAPT */
if (err != DB_SUCCESS) {
char table_name[MAX_FULL_NAME_LEN + 1];
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index ba8a7044baa..000da4b0562 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -3934,17 +3934,6 @@ row_merge_drop_indexes(
ut_ad(prev);
ut_a(table->fts);
fts_drop_index(table, index, trx);
- /* Since
- INNOBASE_SHARE::idx_trans_tbl
- is shared between all open
- ha_innobase handles to this
- table, no thread should be
- accessing this dict_index_t
- object. Also, we should be
- holding LOCK=SHARED MDL on the
- table even after the MDL
- upgrade timeout. */
-
/* We can remove a DICT_FTS
index from the cache, because
we do not allow ADD FULLTEXT INDEX
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index a3c3d0eaaa6..7c68bf6f7c2 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -3536,6 +3536,7 @@ row_drop_table_for_mysql(
if (!table->no_rollback()) {
if (table->space != fil_system.sys_space) {
+#ifdef BTR_CUR_HASH_ADAPT
/* On DISCARD TABLESPACE, we would not drop the
adaptive hash index entries. If the tablespace is
missing here, delete-marking the record in SYS_INDEXES
@@ -3557,6 +3558,7 @@ row_drop_table_for_mysql(
goto funct_exit;
}
}
+#endif /* BTR_CUR_HASH_ADAPT */
/* Delete the link file if used. */
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index e2bbb5a3d5e..30eacbfc518 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -1076,9 +1076,7 @@ try_again:
ut_ad(!node->table->is_temporary());
if (!fil_table_accessible(node->table)) {
- dict_table_close(node->table, FALSE, FALSE);
- node->table = NULL;
- goto err_exit;
+ goto close_exit;
}
switch (type) {
@@ -1113,6 +1111,7 @@ try_again:
dict_set_corrupted() works on an index, and
we do not have an index to call it with. */
dict_table_close(node->table, FALSE, FALSE);
+ node->table = NULL;
err_exit:
rw_lock_s_unlock(dict_operation_lock);
return(false);
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index 187fa2a0929..fac01fe26cc 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -452,6 +452,7 @@ row_vers_build_clust_v_col(
byte* record= 0;
ut_ad(dict_index_has_virtual(index));
+ ut_ad(index->table == clust_index->table);
if (vcol_info != NULL) {
vcol_info->set_used();
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index ca60949ad5f..8f674f47b4c 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -2416,7 +2416,22 @@ static bool srv_purge_should_exit()
return(true);
}
/* Slow shutdown was requested. */
- return !trx_sys.any_active_transactions() && !trx_sys.history_size();
+ if (ulint history_size = trx_sys.history_size()) {
+#if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY
+ static ib_time_t progress_time;
+ ib_time_t time = ut_time();
+ if (time - progress_time >= 15) {
+ progress_time = time;
+ service_manager_extend_timeout(
+ INNODB_EXTEND_TIMEOUT_INTERVAL,
+ "InnoDB: to purge " ULINTPF " transactions",
+ history_size);
+ }
+#endif
+ return false;
+ }
+
+ return !trx_sys.any_active_transactions();
}
/*********************************************************************//**
@@ -2582,14 +2597,6 @@ srv_do_purge(ulint* n_total_purged)
(++count % rseg_truncate_frequency) == 0);
*n_total_purged += n_pages_purged;
-
- if (n_pages_purged) {
- service_manager_extend_timeout(
- INNODB_EXTEND_TIMEOUT_INTERVAL,
- "InnoDB " ULINTPF " pages purged", n_pages_purged);
- /* The previous round still did some work. */
- continue;
- }
} while (n_pages_purged > 0 && !purge_sys.paused()
&& !srv_purge_should_exit());
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 32e050e9b91..8f6e585f66b 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -258,7 +258,12 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
trx_sys.get_max_trx_id(), mtr);
}
- /* Before any transaction-generating background threads or the
+ /* After the purge thread has been given permission to exit,
+ we may roll back transactions (trx->undo_no==0)
+ in THD::cleanup() invoked from unlink_thd() in fast shutdown,
+ or in trx_rollback_resurrected() in slow shutdown.
+
+ Before any transaction-generating background threads or the
purge have been started, recv_recovery_rollback_active() can
start transactions in row_merge_drop_temp_indexes() and
fts_drop_orphaned_tables(), and roll back recovered transactions.
@@ -268,17 +273,15 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
innodb_force_recovery=2 or innodb_force_recovery=3.
DROP TABLE may be executed at any innodb_force_recovery level.
- After the purge thread has been given permission to exit,
- in fast shutdown, we may roll back transactions (trx->undo_no==0)
- in THD::cleanup() invoked from unlink_thd(), and we may also
- continue to execute user transactions. */
+ During fast shutdown, we may also continue to execute
+ user transactions. */
ut_ad(srv_undo_sources
+ || trx->undo_no == 0
|| (!purge_sys.enabled()
&& (srv_startup_is_before_trx_rollback_phase
|| trx_rollback_is_active
|| srv_force_recovery >= SRV_FORCE_NO_BACKGROUND))
- || ((trx->undo_no == 0 || trx->mysql_thd
- || trx->internal)
+ || ((trx->mysql_thd || trx->internal)
&& srv_fast_shutdown));
#ifdef WITH_WSREP
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index 18755d0457a..63ec73fc2b3 100644
--- a/storage/innobase/trx/trx0undo.cc
+++ b/storage/innobase/trx/trx0undo.cc
@@ -1444,7 +1444,7 @@ buf_block_t*
trx_undo_assign_low(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo,
dberr_t* err, mtr_t* mtr)
{
- const bool is_temp = rseg == trx->rsegs.m_noredo.rseg;
+ const bool is_temp __attribute__((unused)) = rseg == trx->rsegs.m_noredo.rseg;
ut_ad(rseg == trx->rsegs.m_redo.rseg
|| rseg == trx->rsegs.m_noredo.rseg);
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index aa9f18966c4..6fe00e52081 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -1512,6 +1512,7 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
while ((error= repair(thd, param, 0)) && param->retry_repair)
{
param->retry_repair= 0;
+ file->state->records= start_records;
if (test_all_bits(param->testflag,
(uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
{
@@ -2016,6 +2017,7 @@ int ha_maria::disable_indexes(uint mode)
int ha_maria::enable_indexes(uint mode)
{
int error;
+ ha_rows start_rows= file->state->records;
DBUG_PRINT("info", ("ha_maria::enable_indexes mode: %d", mode));
if (maria_is_all_keys_active(file->s->state.key_map, file->s->base.keys))
{
@@ -2078,6 +2080,7 @@ int ha_maria::enable_indexes(uint mode)
DBUG_ASSERT(thd->killed != 0);
/* Repairing by sort failed. Now try standard repair method. */
param->testflag &= ~T_REP_BY_SORT;
+ file->state->records= start_rows;
error= (repair(thd, param, 0) != HA_ADMIN_OK);
/*
If the standard repair succeeded, clear all error messages which
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 316a1a06ccc..d0613d4f0d8 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -149,7 +149,7 @@ void maria_chk_init_for_check(HA_CHECK *param, MARIA_HA *info)
*/
param->max_trid= ~(TrID) 0;
}
- else if (param->max_trid == 0)
+ else if (param->max_trid == 0 || param->max_trid == ~(TrID) 0)
{
if (!ma_control_file_inited())
param->max_trid= 0; /* Give warning for first trid found */
@@ -179,7 +179,7 @@ int maria_chk_status(HA_CHECK *param, MARIA_HA *info)
if (share->state.open_count != (uint) (share->global_changed ? 1 : 0))
{
/* Don't count this as a real warning, as check can correct this ! */
- uint save=param->warning_printed;
+ my_bool save=param->warning_printed;
_ma_check_print_warning(param,
share->state.open_count==1 ?
"%d client is using or hasn't closed the table properly" :
@@ -191,6 +191,7 @@ int maria_chk_status(HA_CHECK *param, MARIA_HA *info)
}
if (share->state.create_trid > param->max_trid)
{
+ param->wrong_trd_printed= 1; /* Force should run zerofill */
_ma_check_print_warning(param,
"Table create_trd (%llu) > current max_transaction id (%llu). Table needs to be repaired or zerofilled to be usable",
share->state.create_trid, param->max_trid);
@@ -643,7 +644,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
(key_part_map) 1, HA_READ_KEY_EXACT))
{
/* Don't count this as a real warning, as maria_chk can't correct it */
- uint save=param->warning_printed;
+ my_bool save=param->warning_printed;
_ma_check_print_warning(param, "Found row where the auto_increment "
"column has the value 0");
param->warning_printed=save;
@@ -891,11 +892,10 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (level > param->max_level)
param->max_level=level;
- if (_ma_get_keynr(share, anc_page->buff) !=
- (uint) (keyinfo - share->keyinfo))
+ if (_ma_get_keynr(share, anc_page->buff) != keyinfo->key_nr)
_ma_check_print_error(param, "Page at %s is not marked for index %u",
llstr(anc_page->pos, llbuff),
- (uint) (keyinfo - share->keyinfo));
+ (uint) keyinfo->key_nr);
if ((page_flag & KEYPAGE_FLAG_HAS_TRANSID) &&
!share->base.born_transactional)
{
@@ -1011,6 +1011,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (subkeys < 0)
{
ha_rows tmp_keys=0;
+ share->ft2_keyinfo.key_nr= keyinfo->key_nr;
if (chk_index_down(param,info,&share->ft2_keyinfo,record,
temp_buff,&tmp_keys,key_checksum,1))
goto err;
@@ -2381,6 +2382,7 @@ static int initialize_variables_for_repair(HA_CHECK *param,
param->retry_repair= 0;
param->warning_printed= 0;
param->error_printed= 0;
+ param->wrong_trd_printed= 0;
sort_param->sort_info= sort_info;
sort_param->fix_datafile= ! rep_quick;
@@ -5754,8 +5756,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
a_length= share->keypage_header + nod_flag;
key_block->end_pos= anc_buff + share->keypage_header;
bzero(anc_buff, share->keypage_header);
- _ma_store_keynr(share, anc_buff, (uint) (sort_param->keyinfo -
- share->keyinfo));
+ _ma_store_keynr(share, anc_buff, sort_param->key);
lastkey=0; /* No previous key in block */
}
else
diff --git a/storage/maria/ma_commit.c b/storage/maria/ma_commit.c
index f557cd211e2..3850af8246c 100644
--- a/storage/maria/ma_commit.c
+++ b/storage/maria/ma_commit.c
@@ -98,12 +98,7 @@ int maria_commit(MARIA_HA *info)
if (!info->s->now_transactional)
return 0;
trn= info->trn;
- /*
- trn is reset as it's checked in maria_close
- Note that info is still linked in info->trn->used_instances, as this is
- used in ha_maria::implicit_commit()
- */
- info->trn= 0;
+ _ma_reset_trn_for_table(info);
return ma_commit(trn);
}
diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c
index 3b7d2dd4850..3c536d2c46f 100644
--- a/storage/maria/ma_control_file.c
+++ b/storage/maria/ma_control_file.c
@@ -583,8 +583,8 @@ int ma_control_file_end(void)
close_error= mysql_file_close(control_file_fd, MYF(MY_WME));
/*
- As mysql_file_close() frees structures even if close() fails, we do the same,
- i.e. we mark the file as closed in all cases.
+ As mysql_file_close() frees structures even if close() fails, we do the
+ same, i.e. we mark the file as closed in all cases.
*/
control_file_fd= -1;
/*
diff --git a/storage/maria/ma_control_file.h b/storage/maria/ma_control_file.h
index 155c778c105..85e8f2c899d 100644
--- a/storage/maria/ma_control_file.h
+++ b/storage/maria/ma_control_file.h
@@ -42,7 +42,7 @@ extern LSN last_checkpoint_lsn;
*/
extern uint32 last_logno;
-extern TrID max_trid_in_control_file;
+extern TrID max_trid_in_control_file, max_long_trid;
extern uint8 recovery_failures;
diff --git a/storage/maria/ma_info.c b/storage/maria/ma_info.c
index 081df0bc5ce..22b9c86f21d 100644
--- a/storage/maria/ma_info.c
+++ b/storage/maria/ma_info.c
@@ -56,7 +56,11 @@ int maria_status(MARIA_HA *info, register MARIA_INFO *x, uint flag)
}
if (flag & HA_STATUS_VARIABLE)
{
- x->records = info->state->records;
+ /* If table is locked, give versioned number otherwise last commited */
+ if (info->lock_type == F_UNLCK)
+ x->records = share->state.state.records;
+ else
+ x->records = info->state->records;
x->deleted = share->state.state.del;
x->delete_length = share->state.state.empty;
x->data_file_length = share->state.state.data_file_length;
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index e41b7dd1177..389e1bc068b 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -153,8 +153,9 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
if (page_size < 4 || page_size > share->max_index_block_size ||
_ma_get_keynr(share, tmp) != keyinfo->key_nr)
{
- DBUG_PRINT("error",("page %lu had wrong page length: %u keynr: %u",
+ DBUG_PRINT("error",("page %lu had wrong page length: %u page_header: %u keynr: %u",
(ulong) (pos / block_size), page_size,
+ share->keypage_header,
_ma_get_keynr(share, tmp)));
DBUG_DUMP("page", tmp, page_size);
info->last_keypage = HA_OFFSET_ERROR;
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index ea91c65ff3d..dbb8d46bdbc 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -49,7 +49,6 @@ static LSN current_group_end_lsn;
/** Current group of REDOs is about this table and only this one */
static MARIA_HA *current_group_table;
#endif
-static TrID max_long_trid= 0; /**< max long trid seen by REDO phase */
static my_bool skip_DDLs; /**< if REDO phase should skip DDL records */
/** @brief to avoid writing a checkpoint if recovery did nothing. */
static my_bool checkpoint_useful;
@@ -62,6 +61,7 @@ static uint recovery_warnings; /**< count of warnings */
static uint recovery_found_crashed_tables;
HASH tables_to_redo; /* For maria_read_log */
ulong maria_recovery_force_crash_counter;
+TrID max_long_trid= 0; /**< max long trid seen by REDO phase */
#define prototype_redo_exec_hook(R) \
static int exec_REDO_LOGREC_ ## R(const TRANSLOG_HEADER_BUFFER *rec)
@@ -473,6 +473,7 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn,
fflush(stderr);
}
+ set_if_bigger(max_trid_in_control_file, max_long_trid);
if (take_checkpoints && checkpoint_useful)
{
/* No dirty pages, all tables are closed, no active transactions, save: */
@@ -3560,8 +3561,8 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
info->state may point to a state that was deleted by
_ma_trnman_end_trans_hook()
*/
- share->state.common= *info->state;
- info->state= &share->state.common;
+ share->state.no_logging= *info->state;
+ info->state= &share->state.no_logging;
info->switched_transactional= TRUE;
/*
@@ -3622,6 +3623,10 @@ my_bool _ma_reenable_logging_for_table(MARIA_HA *info, my_bool flush_pages)
_ma_copy_nontrans_state_information(info);
_ma_reset_history(info->s);
+ /* Reset state to point to state.common, as on open() */
+ info->state= &share->state.common;
+ *info->state= share->state.state;
+
if (flush_pages)
{
/* Ensure that recover is not executing any redo before this */
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 86a27a13136..ae3b95db6ec 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -22,6 +22,7 @@
#include <stdarg.h>
#include <my_getopt.h>
#include <my_check_opt.h>
+#include <my_handler_errors.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
@@ -93,12 +94,28 @@ ATTRIBUTE_NORETURN static void my_exit(int exit_code);
HA_CHECK check_param;
+/*
+ Register handler error messages for usage with my_error()
+
+ NOTES
+ This is safe to call multiple times as my_error_register()
+ will ignore calls to register already registered error numbers.
+*/
+
+static const char **get_handler_error_messages(int e __attribute__((unused)))
+{
+ return handler_error_messages;
+}
+
+
/* Free memory and exit */
static void my_exit(int exit_code)
{
free_tmpdir(&maria_chk_tmpdir);
free_defaults(default_argv);
+ my_error_unregister(HA_ERR_FIRST,
+ HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
my_end(check_param.testflag & T_INFO ?
MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
exit(exit_code);
@@ -120,6 +137,8 @@ int main(int argc, char **argv)
maria_quick_table_bits=decode_bits;
error=0;
maria_init();
+ my_error_register(get_handler_error_messages, HA_ERR_FIRST,
+ HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
maria_block_size= 0; /* Use block size from control file */
if (!opt_ignore_control_file &&
@@ -160,6 +179,20 @@ int main(int argc, char **argv)
check_param.testflag&= ~T_REP;
fflush(stdout);
fflush(stderr);
+ if (check_param.wrong_trd_printed &&
+ (check_param.testflag & T_FORCE_CREATE) &&
+ !(check_param.error_printed | check_param.warning_printed))
+ {
+ /* Only wrong create_trd. Run zerofill */
+ ulonglong old_testflag= check_param.testflag;
+ check_param.testflag= T_ZEROFILL;
+ error|= maria_chk(&check_param, argv[-1]);
+ check_param.testflag= old_testflag;
+ check_param.error_printed= 0;
+ check_param.warning_printed= 0;
+ fflush(stdout);
+ fflush(stderr);
+ }
if ((check_param.error_printed | check_param.warning_printed) &&
(check_param.testflag & T_FORCE_CREATE) &&
(!(check_param.testflag & (T_REP | T_REP_BY_SORT | T_SORT_RECORDS |
@@ -174,7 +207,6 @@ int main(int argc, char **argv)
fflush(stdout);
fflush(stderr);
}
- else
error|=new_error;
if (argc && (!(check_param.testflag & T_SILENT) ||
check_param.testflag & T_INFO))
@@ -693,8 +725,8 @@ get_one_option(int optid,
}
else
{
- if (check_param.testflag & T_FORCE_CREATE)
- check_param.testflag= T_FORCE_SORT_MEMORY;
+ if (check_param.testflag & T_FORCE_CREATE)
+ check_param.testflag= T_FORCE_SORT_MEMORY;
check_param.tmpfile_createflag= O_RDWR | O_TRUNC;
check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE;
}
@@ -981,8 +1013,8 @@ static int maria_chk(HA_CHECK *param, char *filename)
MARIA_SHARE *share;
DBUG_ENTER("maria_chk");
- param->out_flag=error=param->warning_printed=param->error_printed=
- recreate=0;
+ param->out_flag= error= param->error_printed= recreate= 0;
+ param->warning_printed= param->wrong_trd_printed= 0;
datafile=0;
param->isam_file_name=filename; /* For error messages */
warning_printed_by_chk_status= 0;
@@ -1128,7 +1160,7 @@ static int maria_chk(HA_CHECK *param, char *filename)
{
fprintf(stderr, "Aria table '%s' is not fixed because of errors\n",
filename);
- return(-1);
+ DBUG_RETURN(-1);
}
recreate=1;
if (!(param->testflag & T_REP_ANY))
@@ -1150,7 +1182,7 @@ static int maria_chk(HA_CHECK *param, char *filename)
param->total_deleted+=info->state->del;
descript(param, info, filename);
maria_close(info); /* Should always succeed */
- return(0);
+ DBUG_RETURN(0);
}
if (!stopwords_inited++)
@@ -1617,7 +1649,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
buff, share->base.keys);
}
puts("\nTable description:");
- printf("Key Start Len Index Type");
+ printf("Key Start Len Index Type");
if (param->testflag & T_VERBOSE)
printf(" Rec/key Root Blocksize");
putchar('\n');
@@ -1649,7 +1681,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
pos=strmov(pos,null_txt);
*pos=0;
- printf("%-4d%-6ld%-3d %-8s%-23s",
+ printf("%-4d%-6ld%-3d %-9s%-23s",
key+1,(long) keyseg->start+1,keyseg->length,text,buff);
if (share->state.key_root[key] != HA_OFFSET_ERROR)
llstr(share->state.key_root[key],buff);
@@ -1674,7 +1706,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
if (keyseg->flag & HA_NULL_PART)
pos=strmov(pos,null_txt);
*pos=0;
- printf(" %-6ld%-3d %-21s",
+ printf(" %-6ld%-3d %-21s",
(long) keyseg->start+1,keyseg->length,buff);
if (param->testflag & T_VERBOSE)
printf("%11.0f", share->state.rec_per_key_part[keyseg_nr++]);
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 37b24492be6..d5f2b1e80fd 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -150,6 +150,8 @@ typedef struct st_maria_state_info
MARIA_STATUS_INFO state;
/* maria_ha->state points here for crash-safe but not versioned tables */
MARIA_STATUS_INFO common;
+ /* State for a versioned table that is temporary non versioned */
+ MARIA_STATUS_INFO no_logging;
ha_rows split; /* number of split blocks */
my_off_t dellink; /* Link to next removed block */
pgcache_page_no_t first_bitmap_with_space;
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index c638dcbe3e8..f6929438ac0 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -111,7 +111,7 @@ int chk_status(HA_CHECK *param, register MI_INFO *info)
if (share->state.open_count != (uint) (info->s->global_changed ? 1 : 0))
{
/* Don't count this as a real warning, as check can correct this ! */
- uint save=param->warning_printed;
+ my_bool save=param->warning_printed;
mi_check_print_warning(param,
share->state.open_count==1 ?
"%d client is using or hasn't closed the table properly" :
@@ -526,7 +526,7 @@ int chk_key(HA_CHECK *param, register MI_INFO *info)
(key_part_map)1, HA_READ_KEY_EXACT))
{
/* Don't count this as a real warning, as myisamchk can't correct it */
- uint save=param->warning_printed;
+ my_bool save=param->warning_printed;
mi_check_print_warning(param, "Found row where the auto_increment "
"column has the value 0");
param->warning_printed=save;
@@ -1515,7 +1515,8 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info,
new_file= -1;
sort_param.sort_info=&sort_info;
param->retry_repair= 0;
- param->warning_printed= param->error_printed= param->note_printed= 0;
+ param->warning_printed= param->note_printed= 0;
+ param->error_printed= 0;
if (!(param->testflag & T_SILENT))
{
@@ -2210,7 +2211,8 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
}
param->testflag|=T_REP_BY_SORT; /* for easy checking */
param->retry_repair= 0;
- param->warning_printed= param->error_printed= param->note_printed= 0;
+ param->warning_printed= param->note_printed= 0;
+ param->error_printed= 0;
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM;
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index e56c5b1033e..090763a2ece 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -159,6 +159,9 @@ if (UNIX AND NOT APPLE)
endif()
TARGET_LINK_LIBRARIES(rocksdb rocksdb_aux_lib)
+ FIND_LIBRARY(LZ4_LIBRARY
+ NAMES liblz4${PIC_EXT}.a lz4
+ HINTS ${WITH_LZ4}/lib)
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
@@ -186,8 +189,11 @@ IF(HAVE_SCHED_GETCPU)
ENDIF()
IF (WITH_TBB)
+ FIND_LIBRARY(TBB_LIBRARY
+ NAMES libtbb${PIC_EXT}.a tbb
+ HINTS ${WITH_TBB}/lib)
SET(rocksdb_static_libs ${rocksdb_static_libs}
- ${WITH_TBB}/lib/libtbb${PIC_EXT}.a)
+ ${TBB_LIBRARY})
ADD_DEFINITIONS(-DTBB)
ENDIF()
diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake
index d854bdaa03a..c36c761f92f 100644
--- a/storage/rocksdb/build_rocksdb.cmake
+++ b/storage/rocksdb/build_rocksdb.cmake
@@ -178,6 +178,7 @@ set(ROCKSDB_SOURCES
db/db_info_dumper.cc
db/db_iter.cc
db/dbformat.cc
+ db/error_handler.cc
db/event_helpers.cc
db/experimental.cc
db/external_sst_file_ingestion_job.cc
@@ -188,6 +189,7 @@ set(ROCKSDB_SOURCES
db/internal_stats.cc
db/log_reader.cc
db/log_writer.cc
+ db/logs_with_prep_tracker.cc
db/malloc_stats.cc
db/managed_iterator.cc
db/memtable.cc
@@ -284,6 +286,7 @@ set(ROCKSDB_SOURCES
util/coding.cc
util/compaction_job_stats_impl.cc
util/comparator.cc
+ util/compression_context_cache.cc
util/concurrent_arena.cc
util/crc32c.cc
util/delete_scheduler.cc
@@ -304,6 +307,7 @@ set(ROCKSDB_SOURCES
util/status_message.cc
util/string_util.cc
util/sync_point.cc
+ util/sync_point_impl.cc
util/testutil.cc
util/thread_local.cc
util/threadpool_imp.cc
@@ -352,6 +356,8 @@ set(ROCKSDB_SOURCES
utilities/transactions/transaction_util.cc
utilities/transactions/write_prepared_txn.cc
utilities/transactions/write_prepared_txn_db.cc
+ utilities/transactions/write_unprepared_txn.cc
+ utilities/transactions/write_unprepared_txn_db.cc
utilities/ttl/db_ttl_impl.cc
utilities/write_batch_with_index/write_batch_with_index.cc
utilities/write_batch_with_index/write_batch_with_index_internal.cc
@@ -379,6 +385,13 @@ ENDFOREACH()
if(MSVC)
add_definitions(-DHAVE_SSE42 -DHAVE_PCLMUL)
+ # Workaround broken compilation with -DWIN32_LEAN_AND_MEAN
+ # (https://github.com/facebook/rocksdb/issues/4344)
+ set_source_files_properties(${ROCKSDB_SOURCE_DIR}/port/win/env_win.cc
+ PROPERTIES COMPILE_FLAGS "/FI\"windows.h\" /FI\"winioctl.h\"")
+
+ # Workaround Win8.1 SDK bug, that breaks /permissive-
+ string(REPLACE "/permissive-" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_REQUIRED_FLAGS "-msse4.2 -mpclmul ${CXX11_FLAGS}")
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index 2c7737a821d..49104911c69 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -32,6 +32,7 @@
/* C++ standard header files */
#include <algorithm>
+#include <inttypes.h>
#include <limits>
#include <map>
#include <queue>
@@ -127,6 +128,60 @@ const std::string DEFAULT_CF_NAME("default");
const std::string DEFAULT_SYSTEM_CF_NAME("__system__");
const std::string PER_INDEX_CF_NAME("$per_index_cf");
+class Rdb_explicit_snapshot;
+
+std::mutex explicit_snapshot_mutex;
+ulonglong explicit_snapshot_counter = 0;
+std::unordered_map<ulonglong, std::weak_ptr<Rdb_explicit_snapshot>>
+ explicit_snapshots;
+static std::vector<GL_INDEX_ID> rdb_indexes_to_recalc;
+
+#ifdef MARIADB_NOT_YET
+class Rdb_explicit_snapshot : public explicit_snapshot {
+ std::unique_ptr<rocksdb::ManagedSnapshot> snapshot;
+
+ public:
+ static std::shared_ptr<Rdb_explicit_snapshot>
+ create(snapshot_info_st *ss_info, rocksdb::DB *db,
+ const rocksdb::Snapshot *snapshot) {
+ std::lock_guard<std::mutex> lock(explicit_snapshot_mutex);
+ auto s = std::unique_ptr<rocksdb::ManagedSnapshot>(
+ new rocksdb::ManagedSnapshot(db, snapshot));
+ if (!s) {
+ return nullptr;
+ }
+ ss_info->snapshot_id = ++explicit_snapshot_counter;
+ auto ret = std::make_shared<Rdb_explicit_snapshot>(*ss_info, std::move(s));
+ if (!ret) {
+ return nullptr;
+ }
+ explicit_snapshots[ss_info->snapshot_id] = ret;
+ return ret;
+ }
+
+ static std::shared_ptr<Rdb_explicit_snapshot>
+ get(const ulonglong snapshot_id) {
+ std::lock_guard<std::mutex> lock(explicit_snapshot_mutex);
+ auto elem = explicit_snapshots.find(snapshot_id);
+ if (elem == explicit_snapshots.end()) {
+ return nullptr;
+ }
+ return elem->second.lock();
+ }
+
+ rocksdb::ManagedSnapshot *get_snapshot() { return snapshot.get(); }
+
+ Rdb_explicit_snapshot(snapshot_info_st ss_info,
+ std::unique_ptr<rocksdb::ManagedSnapshot> snapshot)
+ : explicit_snapshot(ss_info), snapshot(std::move(snapshot)) {}
+
+ virtual ~Rdb_explicit_snapshot() {
+ std::lock_guard<std::mutex> lock(explicit_snapshot_mutex);
+ explicit_snapshots.erase(ss_info.snapshot_id);
+ }
+};
+#endif
+
/**
Updates row counters based on the table type and operation type.
*/
@@ -144,11 +199,15 @@ static handler *rocksdb_create_handler(my_core::handlerton *hton,
my_core::TABLE_SHARE *table_arg,
my_core::MEM_ROOT *mem_root);
-static rocksdb::CompactRangeOptions getCompactRangeOptions() {
+static rocksdb::CompactRangeOptions
+getCompactRangeOptions(int concurrency = 0) {
rocksdb::CompactRangeOptions compact_range_options;
compact_range_options.bottommost_level_compaction =
rocksdb::BottommostLevelCompaction::kForce;
compact_range_options.exclusive_manual_compaction = false;
+ if (concurrency > 0) {
+ compact_range_options.max_subcompactions = concurrency;
+ }
return compact_range_options;
}
@@ -187,6 +246,8 @@ Rdb_io_watchdog *io_watchdog = nullptr;
static Rdb_background_thread rdb_bg_thread;
+static Rdb_manual_compaction_thread rdb_mc_thread;
+
// List of table names (using regex) that are exceptions to the strict
// collation check requirement.
Regex_list_handler *rdb_collation_exceptions;
@@ -200,30 +261,6 @@ static void rocksdb_flush_all_memtables() {
}
}
-static void rocksdb_compact_column_family_stub(
- THD *const thd, struct st_mysql_sys_var *const var, void *const var_ptr,
- const void *const save) {}
-
-static int rocksdb_compact_column_family(THD *const thd,
- struct st_mysql_sys_var *const var,
- void *const var_ptr,
- struct st_mysql_value *const value) {
- char buff[STRING_BUFFER_USUAL_SIZE];
- int len = sizeof(buff);
-
- DBUG_ASSERT(value != nullptr);
-
- if (const char *const cf = value->val_str(value, buff, &len)) {
- auto cfh = cf_manager.get_cf(cf);
- if (cfh != nullptr && rdb != nullptr) {
- sql_print_verbose_info("RocksDB: Manual compaction of column family: %s\n",
- cf);
- rdb->CompactRange(getCompactRangeOptions(), cfh, nullptr, nullptr);
- }
- }
- return HA_EXIT_SUCCESS;
-}
-
///////////////////////////////////////////////////////////
// Hash map: table name => open table handler
///////////////////////////////////////////////////////////
@@ -249,6 +286,8 @@ struct Rdb_open_tables_map {
Rdb_open_tables_map() : m_hash(get_hash_key, system_charset_info) { }
+ void free_hash(void) { m_hash.~Rdb_table_set(); }
+
std::vector<std::string> get_table_names(void) const;
};
@@ -368,6 +407,7 @@ static void rocksdb_drop_index_wakeup_thread(
static my_bool rocksdb_pause_background_work = 0;
static mysql_mutex_t rdb_sysvars_mutex;
+static mysql_mutex_t rdb_block_cache_resize_mutex;
static void rocksdb_set_pause_background_work(
my_core::THD *const,
@@ -450,6 +490,9 @@ static void rocksdb_set_wal_bytes_per_sync(THD *thd,
struct st_mysql_sys_var *const var,
void *const var_ptr,
const void *const save);
+static int rocksdb_validate_set_block_cache_size(
+ THD *thd, struct st_mysql_sys_var *const var, void *var_ptr,
+ struct st_mysql_value *value);
//////////////////////////////////////////////////////////////////////////////
// Options definitions
//////////////////////////////////////////////////////////////////////////////
@@ -510,11 +553,19 @@ static char* rocksdb_git_hash;
char *compression_types_val=
const_cast<char*>(get_rocksdb_supported_compression_types());
+static unsigned long rocksdb_write_policy =
+ rocksdb::TxnDBWritePolicy::WRITE_COMMITTED;
+static my_bool rocksdb_error_on_suboptimal_collation = 1;
+static uint32_t rocksdb_stats_recalc_rate = 0;
+static uint32_t rocksdb_debug_manual_compaction_delay = 0;
+static uint32_t rocksdb_max_manual_compactions = 0;
std::atomic<uint64_t> rocksdb_row_lock_deadlocks(0);
std::atomic<uint64_t> rocksdb_row_lock_wait_timeouts(0);
std::atomic<uint64_t> rocksdb_snapshot_conflict_errors(0);
std::atomic<uint64_t> rocksdb_wal_group_syncs(0);
+std::atomic<uint64_t> rocksdb_manual_compactions_processed(0);
+std::atomic<uint64_t> rocksdb_manual_compactions_running(0);
@@ -600,6 +651,14 @@ static std::unique_ptr<rocksdb::DBOptions> rocksdb_db_options =
static std::shared_ptr<rocksdb::RateLimiter> rocksdb_rate_limiter;
+/* This enum needs to be kept up to date with rocksdb::TxnDBWritePolicy */
+static const char *write_policy_names[] = {"write_committed", "write_prepared",
+ "write_unprepared", NullS};
+
+static TYPELIB write_policy_typelib = {array_elements(write_policy_names) - 1,
+ "write_policy_typelib",
+ write_policy_names, nullptr};
+
/* This enum needs to be kept up to date with rocksdb::InfoLogLevel */
static const char *info_log_level_names[] = {"debug_level", "info_level",
"warn_level", "error_level",
@@ -694,6 +753,14 @@ static int rocksdb_validate_flush_log_at_trx_commit(
*static_cast<uint32_t *>(var_ptr) = static_cast<uint32_t>(new_value);
return HA_EXIT_SUCCESS;
}
+static void rocksdb_compact_column_family_stub(
+ THD *const thd, struct st_mysql_sys_var *const var, void *const var_ptr,
+ const void *const save) {}
+
+static int rocksdb_compact_column_family(THD *const thd,
+ struct st_mysql_sys_var *const var,
+ void *const var_ptr,
+ struct st_mysql_value *const value);
static const char *index_type_names[] = {"kBinarySearch", "kHashSearch", NullS};
@@ -702,7 +769,8 @@ static TYPELIB index_type_typelib = {array_elements(index_type_names) - 1,
nullptr};
const ulong RDB_MAX_LOCK_WAIT_SECONDS = 1024 * 1024 * 1024;
-const ulong RDB_MAX_ROW_LOCKS = 1024 * 1024;
+const ulong RDB_DEFAULT_MAX_ROW_LOCKS = 1024 * 1024;
+const ulong RDB_MAX_ROW_LOCKS = 1024 * 1024 * 1024;
const ulong RDB_DEFAULT_BULK_LOAD_SIZE = 1000;
const ulong RDB_MAX_BULK_LOAD_SIZE = 1024 * 1024 * 1024;
const size_t RDB_DEFAULT_MERGE_BUF_SIZE = 64 * 1024 * 1024;
@@ -734,6 +802,11 @@ static MYSQL_THDVAR_ULONG(deadlock_detect_depth, PLUGIN_VAR_RQCMDARG,
/*max*/ ULONG_MAX, 0);
static MYSQL_THDVAR_BOOL(
+ commit_time_batch_for_recovery, PLUGIN_VAR_RQCMDARG,
+ "TransactionOptions::commit_time_batch_for_recovery for RocksDB", nullptr,
+ nullptr, FALSE);
+
+static MYSQL_THDVAR_BOOL(
trace_sst_api, PLUGIN_VAR_RQCMDARG,
"Generate trace output in the log for each call to the SstFileWriter",
nullptr, nullptr, FALSE);
@@ -744,6 +817,13 @@ static MYSQL_THDVAR_BOOL(
"unique_checks and enables rocksdb_commit_in_the_middle.",
rocksdb_check_bulk_load, nullptr, FALSE);
+static MYSQL_THDVAR_BOOL(bulk_load_allow_sk, PLUGIN_VAR_RQCMDARG,
+ "Allow bulk loading of sk keys during bulk-load. "
+ "Can be changed only when bulk load is disabled.",
+ /* Intentionally reuse unsorted's check function */
+ rocksdb_check_bulk_load_allow_unsorted, nullptr,
+ FALSE);
+
static MYSQL_THDVAR_BOOL(bulk_load_allow_unsorted, PLUGIN_VAR_RQCMDARG,
"Allow unsorted input during bulk-load. "
"Can be changed only when bulk load is disabled.",
@@ -794,7 +874,7 @@ static MYSQL_THDVAR_BOOL(skip_bloom_filter_on_read, PLUGIN_VAR_RQCMDARG,
static MYSQL_THDVAR_ULONG(max_row_locks, PLUGIN_VAR_RQCMDARG,
"Maximum number of locks a transaction can have",
nullptr, nullptr,
- /*default*/ RDB_MAX_ROW_LOCKS,
+ /*default*/ RDB_DEFAULT_MAX_ROW_LOCKS,
/*min*/ 1,
/*max*/ RDB_MAX_ROW_LOCKS, 0);
@@ -846,6 +926,12 @@ static MYSQL_THDVAR_ULONGLONG(
/* min (0ms) */ RDB_MIN_MERGE_TMP_FILE_REMOVAL_DELAY,
/* max */ SIZE_T_MAX, 1);
+static MYSQL_THDVAR_INT(
+ manual_compaction_threads, PLUGIN_VAR_RQCMDARG,
+ "How many rocksdb threads to run for manual compactions", nullptr, nullptr,
+ /* default rocksdb.dboption max_subcompactions */ 0,
+ /* min */ 0, /* max */ 128, 0);
+
static MYSQL_SYSVAR_BOOL(
create_if_missing,
*reinterpret_cast<my_bool *>(&rocksdb_db_options->create_if_missing),
@@ -867,6 +953,12 @@ static MYSQL_SYSVAR_BOOL(
"DBOptions::manual_wal_flush for RocksDB", nullptr, nullptr,
rocksdb_db_options->manual_wal_flush);
+static MYSQL_SYSVAR_ENUM(write_policy, rocksdb_write_policy,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "DBOptions::write_policy for RocksDB", nullptr,
+ nullptr, rocksdb::TxnDBWritePolicy::WRITE_COMMITTED,
+ &write_policy_typelib);
+
static MYSQL_SYSVAR_BOOL(
create_missing_column_families,
*reinterpret_cast<my_bool *>(
@@ -1077,7 +1169,9 @@ static MYSQL_SYSVAR_INT(table_cache_numshardbits,
"DBOptions::table_cache_numshardbits for RocksDB",
nullptr, nullptr,
rocksdb_db_options->table_cache_numshardbits,
- /* min */ 0, /* max */ INT_MAX, 0);
+ // LRUCache limits this to 19 bits, anything greater
+ // fails to create a cache and returns a nullptr
+ /* min */ 0, /* max */ 19, 0);
static MYSQL_SYSVAR_UINT64_T(wal_ttl_seconds, rocksdb_db_options->WAL_ttl_seconds,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -1187,8 +1281,9 @@ static MYSQL_SYSVAR_BOOL(
"DBOptions::enable_thread_tracking for RocksDB", nullptr, nullptr, true);
static MYSQL_SYSVAR_LONGLONG(block_cache_size, rocksdb_block_cache_size,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "block_cache size for RocksDB", nullptr, nullptr,
+ PLUGIN_VAR_RQCMDARG,
+ "block_cache size for RocksDB",
+ rocksdb_validate_set_block_cache_size, nullptr,
/* default */ RDB_DEFAULT_BLOCK_CACHE_SIZE,
/* min */ RDB_MIN_BLOCK_CACHE_SIZE,
/* max */ LONGLONG_MAX,
@@ -1435,6 +1530,18 @@ static MYSQL_SYSVAR_BOOL(
"on PK TTL data. This variable is a no-op in non-debug builds.",
nullptr, nullptr, FALSE);
+static MYSQL_SYSVAR_UINT(
+ max_manual_compactions, rocksdb_max_manual_compactions, PLUGIN_VAR_RQCMDARG,
+ "Maximum number of pending + ongoing number of manual compactions.",
+ nullptr, nullptr, /* default */ 10, /* min */ 0, /* max */ UINT_MAX, 0);
+
+static MYSQL_SYSVAR_UINT(
+ debug_manual_compaction_delay, rocksdb_debug_manual_compaction_delay,
+ PLUGIN_VAR_RQCMDARG,
+ "For debugging purposes only. Sleeping specified seconds "
+ "for simulating long running compactions.",
+ nullptr, nullptr, 0, /* min */ 0, /* max */ UINT_MAX, 0);
+
static MYSQL_SYSVAR_BOOL(
reset_stats, rocksdb_reset_stats, PLUGIN_VAR_RQCMDARG,
"Reset the RocksDB internal statistics without restarting the DB.", nullptr,
@@ -1597,6 +1704,13 @@ static MYSQL_SYSVAR_UINT(
RDB_DEFAULT_TBL_STATS_SAMPLE_PCT, /* everything */ 0,
/* max */ RDB_TBL_STATS_SAMPLE_PCT_MAX, 0);
+static MYSQL_SYSVAR_UINT(
+ stats_recalc_rate, rocksdb_stats_recalc_rate, PLUGIN_VAR_RQCMDARG,
+ "The number of indexes per second to recalculate statistics for. 0 to "
+ "disable background recalculation.",
+ nullptr, nullptr, 0 /* default value */, 0 /* min value */,
+ UINT_MAX /* max value */, 0);
+
static MYSQL_SYSVAR_BOOL(
large_prefix, rocksdb_large_prefix, PLUGIN_VAR_RQCMDARG,
"Support large index prefix length of 3072 bytes. If off, the maximum "
@@ -1610,16 +1724,25 @@ static MYSQL_SYSVAR_BOOL(
"detected.",
nullptr, nullptr, FALSE);
+static MYSQL_SYSVAR_BOOL(error_on_suboptimal_collation,
+ rocksdb_error_on_suboptimal_collation,
+ PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
+ "Raise an error instead of warning if a sub-optimal "
+ "collation is used",
+ nullptr, nullptr, TRUE);
+
static const int ROCKSDB_ASSUMED_KEY_VALUE_DISK_SIZE = 100;
static struct st_mysql_sys_var *rocksdb_system_variables[] = {
MYSQL_SYSVAR(lock_wait_timeout),
MYSQL_SYSVAR(deadlock_detect),
MYSQL_SYSVAR(deadlock_detect_depth),
+ MYSQL_SYSVAR(commit_time_batch_for_recovery),
MYSQL_SYSVAR(max_row_locks),
MYSQL_SYSVAR(write_batch_max_bytes),
MYSQL_SYSVAR(lock_scanned_rows),
MYSQL_SYSVAR(bulk_load),
+ MYSQL_SYSVAR(bulk_load_allow_sk),
MYSQL_SYSVAR(bulk_load_allow_unsorted),
MYSQL_SYSVAR(skip_unique_check_tables),
MYSQL_SYSVAR(trace_sst_api),
@@ -1637,6 +1760,7 @@ static struct st_mysql_sys_var *rocksdb_system_variables[] = {
MYSQL_SYSVAR(create_if_missing),
MYSQL_SYSVAR(two_write_queues),
MYSQL_SYSVAR(manual_wal_flush),
+ MYSQL_SYSVAR(write_policy),
MYSQL_SYSVAR(create_missing_column_families),
MYSQL_SYSVAR(error_if_exists),
MYSQL_SYSVAR(paranoid_checks),
@@ -1754,6 +1878,11 @@ static struct st_mysql_sys_var *rocksdb_system_variables[] = {
MYSQL_SYSVAR(large_prefix),
MYSQL_SYSVAR(allow_to_start_after_corruption),
MYSQL_SYSVAR(git_hash),
+ MYSQL_SYSVAR(error_on_suboptimal_collation),
+ MYSQL_SYSVAR(stats_recalc_rate),
+ MYSQL_SYSVAR(debug_manual_compaction_delay),
+ MYSQL_SYSVAR(max_manual_compactions),
+ MYSQL_SYSVAR(manual_compaction_threads),
nullptr};
static rocksdb::WriteOptions
@@ -1768,6 +1897,50 @@ rdb_get_rocksdb_write_options(my_core::THD *const thd) {
return opt;
}
+static int rocksdb_compact_column_family(THD *const thd,
+ struct st_mysql_sys_var *const var,
+ void *const var_ptr,
+ struct st_mysql_value *const value) {
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ int len = sizeof(buff);
+
+ DBUG_ASSERT(value != nullptr);
+
+ if (const char *const cf = value->val_str(value, buff, &len)) {
+ auto cfh = cf_manager.get_cf(cf);
+ if (cfh != nullptr && rdb != nullptr) {
+ int mc_id = rdb_mc_thread.request_manual_compaction(
+ cfh, nullptr, nullptr, THDVAR(thd, manual_compaction_threads));
+ if (mc_id == -1) {
+ my_error(ER_INTERNAL_ERROR, MYF(0),
+ "Can't schedule more manual compactions. "
+ "Increase rocksdb_max_manual_compactions or stop issuing "
+ "more manual compactions.");
+ return HA_EXIT_FAILURE;
+ } else if (mc_id < 0) {
+ return HA_EXIT_FAILURE;
+ }
+ // NO_LINT_DEBUG
+ sql_print_information("RocksDB: Manual compaction of column family: %s\n",
+ cf);
+ // Checking thd state every short cycle (100ms). This is for allowing to
+ // exiting this function without waiting for CompactRange to finish.
+ do {
+ my_sleep(100000);
+ } while (!thd->killed &&
+ !rdb_mc_thread.is_manual_compaction_finished(mc_id));
+
+ if (thd->killed) {
+ // This cancels if requested compaction state is INITED.
+ // TODO(yoshinorim): Cancel running compaction as well once
+ // it is supported in RocksDB.
+ rdb_mc_thread.clear_manual_compaction_request(mc_id, true);
+ }
+ }
+ }
+ return HA_EXIT_SUCCESS;
+}
+
///////////////////////////////////////////////////////////////////////////////////////////
/**
@@ -1887,8 +2060,6 @@ protected:
bool m_is_two_phase = false;
private:
- /* Number of RockDB savepoints taken */
- int m_n_savepoints;
/*
Number of write operations this transaction had when we took the last
savepoint (the idea is not to take another savepoint if we haven't made
@@ -1897,9 +2068,9 @@ private:
ulonglong m_writes_at_last_savepoint;
protected:
- THD *m_thd = nullptr;
- rocksdb::ReadOptions m_read_opts;
+protected:
+ THD *m_thd = nullptr;
static std::multiset<Rdb_transaction *> s_tx_list;
static mysql_mutex_t s_tx_list_mutex;
@@ -1957,6 +2128,7 @@ protected:
}
public:
+ rocksdb::ReadOptions m_read_opts;
const char *m_mysql_log_file_name;
my_off_t m_mysql_log_offset;
#ifdef MARIAROCKS_NOT_YET
@@ -1967,6 +2139,7 @@ protected:
String m_detailed_error;
int64_t m_snapshot_timestamp = 0;
bool m_ddl_transaction;
+ std::shared_ptr<Rdb_explicit_snapshot> m_explicit_snapshot;
/*
Tracks the number of tables in use through external_lock.
@@ -2032,7 +2205,7 @@ protected:
if (s.IsDeadlock()) {
my_core::thd_mark_transaction_to_rollback(thd,
- false /* just statement */);
+ true /* whole transaction */);
m_detailed_error = String();
table_handler->m_deadlock_counter.inc();
rocksdb_row_lock_deadlocks++;
@@ -2049,7 +2222,7 @@ protected:
}
m_detailed_error = String(" (snapshot conflict)", system_charset_info);
table_handler->m_deadlock_counter.inc();
- return HA_ERR_LOCK_DEADLOCK;
+ return HA_ERR_ROCKSDB_STATUS_BUSY;
}
if (s.IsIOError() || s.IsCorruption()) {
@@ -2462,7 +2635,6 @@ public:
entire transaction.
*/
do_set_savepoint();
- m_n_savepoints= 1;
m_writes_at_last_savepoint= m_write_count;
}
@@ -2479,7 +2651,6 @@ public:
{
do_set_savepoint();
m_writes_at_last_savepoint= m_write_count;
- m_n_savepoints++;
}
}
@@ -2490,10 +2661,14 @@ public:
void rollback_to_stmt_savepoint() {
if (m_writes_at_last_savepoint != m_write_count) {
do_rollback_to_savepoint();
- if (!--m_n_savepoints) {
- do_set_savepoint();
- m_n_savepoints= 1;
- }
+ /*
+ RollbackToSavePoint "removes the most recent SetSavePoint()", so
+ we need to set it again so that next statement can roll back to this
+ stage.
+ It's ok to do it here at statement end (instead of doing it at next
+ statement start) because setting a savepoint is cheap.
+ */
+ do_set_savepoint();
m_writes_at_last_savepoint= m_write_count;
}
}
@@ -2666,6 +2841,17 @@ public:
void acquire_snapshot(bool acquire_now) override {
if (m_read_opts.snapshot == nullptr) {
+#ifdef MARIAROCKS_NOT_YET
+ const auto thd_ss = std::static_pointer_cast<Rdb_explicit_snapshot>(
+ m_thd->get_explicit_snapshot());
+ if (thd_ss) {
+ m_explicit_snapshot = thd_ss;
+ }
+ if (m_explicit_snapshot) {
+ auto snapshot = m_explicit_snapshot->get_snapshot()->snapshot();
+ snapshot_created(snapshot);
+ } else
+#endif
if (is_tx_read_only()) {
snapshot_created(rdb->GetSnapshot());
} else if (acquire_now) {
@@ -2683,6 +2869,12 @@ public:
if (m_read_opts.snapshot != nullptr) {
m_snapshot_timestamp = 0;
+#ifdef MARIAROCKS_NOT_YET
+ if (m_explicit_snapshot) {
+ m_explicit_snapshot.reset();
+ need_clear = false;
+ } else
+#endif
if (is_tx_read_only()) {
rdb->ReleaseSnapshot(m_read_opts.snapshot);
need_clear = false;
@@ -2792,6 +2984,10 @@ public:
tx_opts.lock_timeout = rdb_convert_sec_to_ms(m_timeout_sec);
tx_opts.deadlock_detect = THDVAR(m_thd, deadlock_detect);
tx_opts.deadlock_detect_depth = THDVAR(m_thd, deadlock_detect_depth);
+ // If this variable is set, this will write commit time write batch
+ // information on recovery or memtable flush.
+ tx_opts.use_only_the_last_commit_time_batch_for_recovery =
+ THDVAR(m_thd, commit_time_batch_for_recovery);
tx_opts.max_write_batch_size = THDVAR(m_thd, write_batch_max_bytes);
write_opts.sync = (rocksdb_flush_log_at_trx_commit == FLUSH_LOG_SYNC);
@@ -2886,7 +3082,7 @@ public:
/* This is a rocksdb write batch. This class doesn't hold or wait on any
transaction locks (skips rocksdb transaction API) thus giving better
- performance. The commit is done through rdb->GetBaseDB()->Commit().
+ performance.
Currently this is only used for replication threads which are guaranteed
to be non-conflicting. Any further usage of this class should completely
@@ -2908,6 +3104,8 @@ private:
bool commit_no_binlog() override {
bool res = false;
rocksdb::Status s;
+ rocksdb::TransactionDBWriteOptimizations optimize;
+ optimize.skip_concurrency_control = true;
s = merge_auto_incr_map(m_batch->GetWriteBatch());
if (!s.ok()) {
@@ -2918,7 +3116,7 @@ private:
release_snapshot();
- s = rdb->GetBaseDB()->Write(write_opts, m_batch->GetWriteBatch());
+ s = rdb->Write(write_opts, optimize, m_batch->GetWriteBatch());
if (!s.ok()) {
rdb_handle_io_error(s, RDB_IO_ERROR_TX_COMMIT);
res = true;
@@ -2936,7 +3134,6 @@ error:
return res;
}
-protected:
/* Implementations of do_*savepoint based on rocksdB::WriteBatch savepoints */
void do_set_savepoint() override {
m_batch->SetSavePoint();
@@ -2946,6 +3143,7 @@ protected:
m_batch->RollbackToSavePoint();
}
+
public:
bool is_writebatch_trx() const override { return true; }
@@ -3033,6 +3231,13 @@ public:
get_for_update(rocksdb::ColumnFamilyHandle *const column_family,
const rocksdb::Slice &key, rocksdb::PinnableSlice *const value,
bool exclusive) override {
+ if (value == nullptr) {
+ rocksdb::PinnableSlice pin_val;
+ rocksdb::Status s = get(column_family, key, &pin_val);
+ pin_val.Reset();
+ return s;
+ }
+
return get(column_family, key, value);
}
@@ -3564,6 +3769,7 @@ static int rocksdb_commit(handlerton* hton, THD* thd, bool commit_tx)
We get here when committing a statement within a transaction.
*/
tx->make_stmt_savepoint_permanent();
+ tx->make_stmt_savepoint_permanent();
}
if (my_core::thd_tx_isolation(thd) <= ISO_READ_COMMITTED) {
@@ -3752,6 +3958,7 @@ private:
if (!path_entry.path.empty() && !path_entry.limit_exceeded) {
auto deadlocking_txn = *(path_entry.path.end() - 1);
deadlock_info.victim_trx_id = deadlocking_txn.m_txn_id;
+ deadlock_info.deadlock_time = path_entry.deadlock_time;
}
return deadlock_info;
}
@@ -3799,16 +4006,18 @@ private:
path_data += "\n*** DEADLOCK PATH\n"
"=========================================\n";
const auto dl_info = get_dl_path_trx_info(path_entry);
+ const auto deadlock_time = dl_info.deadlock_time;
for (auto it = dl_info.path.begin(); it != dl_info.path.end(); it++) {
const auto trx_info = *it;
path_data += format_string(
+ "TIMESTAMP: %" PRId64 "\n"
"TRANSACTION ID: %u\n"
"COLUMN FAMILY NAME: %s\n"
"WAITING KEY: %s\n"
"LOCK TYPE: %s\n"
"INDEX NAME: %s\n"
"TABLE NAME: %s\n",
- trx_info.trx_id, trx_info.cf_name.c_str(),
+ deadlock_time, trx_info.trx_id, trx_info.cf_name.c_str(),
trx_info.waiting_key.c_str(),
trx_info.exclusive_lock ? "EXCLUSIVE" : "SHARED",
trx_info.index_name.c_str(), trx_info.table_name.c_str());
@@ -4082,7 +4291,7 @@ static bool rocksdb_show_status(handlerton *const hton, THD *const thd,
(ulonglong)internal_cache_count * kDefaultInternalCacheSize);
str.append(buf);
res |= print_stats(thd, "MEMORY_STATS", "rocksdb", str, stat_print);
-#ifdef MARIAROCKS_NOT_YET
+
/* Show the background thread status */
std::vector<rocksdb::ThreadStatus> thread_list;
rocksdb::Status s = rdb->GetEnv()->GetThreadList(&thread_list);
@@ -4119,8 +4328,27 @@ static bool rocksdb_show_status(handlerton *const hton, THD *const thd,
str, stat_print);
}
}
+
+#ifdef MARIAROCKS_NOT_YET
+ /* Explicit snapshot information */
+ str.clear();
+ {
+ std::lock_guard<std::mutex> lock(explicit_snapshot_mutex);
+ for (const auto &elem : explicit_snapshots) {
+ const auto &ss = elem.second.lock();
+ DBUG_ASSERT(ss != nullptr);
+ const auto &info = ss->ss_info;
+ str += "\nSnapshot ID: " + std::to_string(info.snapshot_id) +
+ "\nBinlog File: " + info.binlog_file +
+ "\nBinlog Pos: " + std::to_string(info.binlog_pos) +
+ "\nGtid Executed: " + info.gtid_executed + "\n";
+ }
+ }
#endif
+ if (!str.empty()) {
+ res |= print_stats(thd, "EXPLICIT_SNAPSHOTS", "rocksdb", str, stat_print);
+ }
#ifdef MARIAROCKS_NOT_YET
} else if (stat_type == HA_ENGINE_TRX) {
/* Handle the SHOW ENGINE ROCKSDB TRANSACTION STATUS command */
@@ -4143,6 +4371,50 @@ static inline void rocksdb_register_tx(handlerton *const hton, THD *const thd,
static const char *ha_rocksdb_exts[] = {NullS};
+#ifdef MARIAROCKS_NOT_YET
+static bool rocksdb_explicit_snapshot(
+ handlerton *const /* hton */, /*!< in: RocksDB handlerton */
+ THD *const thd, /*!< in: MySQL thread handle */
+ snapshot_info_st *ss_info) /*!< out: Snapshot information */
+{
+ switch (ss_info->op) {
+ case snapshot_operation::SNAPSHOT_CREATE: {
+ if (mysql_bin_log_is_open()) {
+ mysql_bin_log_lock_commits(ss_info);
+ }
+ auto s = Rdb_explicit_snapshot::create(ss_info, rdb, rdb->GetSnapshot());
+ if (mysql_bin_log_is_open()) {
+ mysql_bin_log_unlock_commits(ss_info);
+ }
+
+ thd->set_explicit_snapshot(s);
+ return s == nullptr;
+ }
+ case snapshot_operation::SNAPSHOT_ATTACH: {
+ auto s = Rdb_explicit_snapshot::get(ss_info->snapshot_id);
+ if (!s) {
+ return true;
+ }
+ *ss_info = s->ss_info;
+ thd->set_explicit_snapshot(s);
+ return false;
+ }
+ case snapshot_operation::SNAPSHOT_RELEASE: {
+ if (!thd->get_explicit_snapshot()) {
+ return true;
+ }
+ *ss_info = thd->get_explicit_snapshot()->ss_info;
+ thd->set_explicit_snapshot(nullptr);
+ return false;
+ }
+ default:
+ DBUG_ASSERT(false);
+ return true;
+ }
+ return true;
+}
+#endif
+
/*
Supporting START TRANSACTION WITH CONSISTENT [ROCKSDB] SNAPSHOT
@@ -4165,10 +4437,15 @@ static const char *ha_rocksdb_exts[] = {NullS};
InnoDB and RocksDB transactions.
*/
static int rocksdb_start_tx_and_assign_read_view(
- handlerton *const hton, /*!< in: RocksDB handlerton */
- THD* thd) /*!< in: MySQL thread handle of the
- user for whom the transaction should
- be committed */
+ handlerton *const hton, /*!< in: RocksDB handlerton */
+ THD *const thd /*!< in: MySQL thread handle of the
+ user for whom the transaction should
+ be committed */
+)
+#ifdef MARIAROCKS_NOT_YET
+ snapshot_info_st *ss_info) /*!< in/out: Snapshot info like binlog file, pos,
+ gtid executed and snapshot ID */
+#endif
{
ulong const tx_isolation = my_core::thd_tx_isolation(thd);
@@ -4176,14 +4453,25 @@ static int rocksdb_start_tx_and_assign_read_view(
my_error(ER_ISOLATION_LEVEL_WITH_CONSISTENT_SNAPSHOT, MYF(0));
return HA_EXIT_FAILURE;
}
+
+#ifdef MARIADB_NOT_YET
+ if (ss_info) {
+ if (mysql_bin_log_is_open()) {
+ mysql_bin_log_lock_commits(ss_info);
+ } else {
+ return HA_EXIT_FAILURE;
+ }
+#endif
+
/*
MariaDB: there is no need to call mysql_bin_log_lock_commits and then
unlock back.
SQL layer calls start_consistent_snapshot() for all engines, including the
binlog under LOCK_commit_ordered mutex.
+
The mutex prevents binlog commits from happening (right?) while the storage
engine(s) allocate read snapshots. That way, each storage engine is
- synchronized with current binlog position.
+ synchronized with current binlog position.
*/
mysql_mutex_assert_owner(&LOCK_commit_ordered);
@@ -4195,9 +4483,106 @@ static int rocksdb_start_tx_and_assign_read_view(
rocksdb_register_tx(hton, thd, tx);
tx->acquire_snapshot(true);
+#ifdef MARIADB_NOT_YET
+ if (ss_info) {
+ mysql_bin_log_unlock_commits(ss_info);
+ }
+#endif
return HA_EXIT_SUCCESS;
}
+#ifdef MARIADB_NOT_YET
+static int rocksdb_start_tx_with_shared_read_view(
+ handlerton *const hton, /*!< in: RocksDB handlerton */
+ THD *const thd) /*!< in: MySQL thread handle of the
+ user for whom the transaction should
+ be committed */
+#ifdef MARIADB_NOT_YET
+ snapshot_info_st *ss_info) /*!< out: Snapshot info like binlog file, pos,
+ gtid executed and snapshot ID */
+#endif
+{
+ DBUG_ASSERT(thd != nullptr);
+
+ int error = HA_EXIT_SUCCESS;
+
+ ulong const tx_isolation = my_core::thd_tx_isolation(thd);
+ if (tx_isolation != ISO_REPEATABLE_READ) {
+ my_error(ER_ISOLATION_LEVEL_WITH_CONSISTENT_SNAPSHOT, MYF(0));
+ return HA_EXIT_FAILURE;
+ }
+
+ Rdb_transaction *tx = nullptr;
+#ifdef MARIADB_NOT_YET
+ std::shared_ptr<Rdb_explicit_snapshot> explicit_snapshot;
+ const auto op = ss_info->op;
+
+ DBUG_ASSERT(op == snapshot_operation::SNAPSHOT_CREATE ||
+ op == snapshot_operation::SNAPSHOT_ATTACH);
+
+ // case: if binlogs are available get binlog file/pos and gtid info
+ if (op == snapshot_operation::SNAPSHOT_CREATE && mysql_bin_log_is_open()) {
+ mysql_bin_log_lock_commits(ss_info);
+ }
+
+ if (op == snapshot_operation::SNAPSHOT_ATTACH) {
+ explicit_snapshot = Rdb_explicit_snapshot::get(ss_info->snapshot_id);
+ if (!explicit_snapshot) {
+ my_printf_error(ER_UNKNOWN_ERROR, "Snapshot %llu does not exist", MYF(0),
+ ss_info->snapshot_id);
+ error = HA_EXIT_FAILURE;
+ }
+ }
+#endif
+
+ // case: all good till now
+ if (error == HA_EXIT_SUCCESS) {
+ tx = get_or_create_tx(thd);
+ Rdb_perf_context_guard guard(tx, rocksdb_perf_context_level(thd));
+
+#ifdef MARIADB_NOT_YET
+ if (explicit_snapshot) {
+ tx->m_explicit_snapshot = explicit_snapshot;
+ }
+#endif
+
+ DBUG_ASSERT(!tx->has_snapshot());
+ tx->set_tx_read_only(true);
+ rocksdb_register_tx(hton, thd, tx);
+ tx->acquire_snapshot(true);
+
+#ifdef MARIADB_NOT_YET
+ // case: an explicit snapshot was not assigned to this transaction
+ if (!tx->m_explicit_snapshot) {
+ tx->m_explicit_snapshot =
+ Rdb_explicit_snapshot::create(ss_info, rdb, tx->m_read_opts.snapshot);
+ if (!tx->m_explicit_snapshot) {
+ my_printf_error(ER_UNKNOWN_ERROR, "Could not create snapshot", MYF(0));
+ error = HA_EXIT_FAILURE;
+ }
+ }
+#endif
+ }
+
+#ifdef MARIADB_NOT_YET
+ // case: unlock the binlog
+ if (op == snapshot_operation::SNAPSHOT_CREATE && mysql_bin_log_is_open()) {
+ mysql_bin_log_unlock_commits(ss_info);
+ }
+
+ DBUG_ASSERT(error == HA_EXIT_FAILURE || tx->m_explicit_snapshot);
+
+ // copy over the snapshot details to pass to the upper layers
+ if (tx->m_explicit_snapshot) {
+ *ss_info = tx->m_explicit_snapshot->ss_info;
+ ss_info->op = op;
+ }
+#endif
+
+ return error;
+}
+#endif
+
/* Dummy SAVEPOINT support. This is needed for long running transactions
* like mysqldump (https://bugs.mysql.com/bug.php?id=71017).
* Current SAVEPOINT does not correctly handle ROLLBACK and does not return
@@ -4422,9 +4807,11 @@ static int rocksdb_init_func(void *const p) {
rdb_bg_thread.init(rdb_signal_bg_psi_mutex_key, rdb_signal_bg_psi_cond_key);
rdb_drop_idx_thread.init(rdb_signal_drop_idx_psi_mutex_key,
rdb_signal_drop_idx_psi_cond_key);
+ rdb_mc_thread.init(rdb_signal_mc_psi_mutex_key, rdb_signal_mc_psi_cond_key);
#else
rdb_bg_thread.init();
rdb_drop_idx_thread.init();
+ rdb_mc_thread.init();
#endif
mysql_mutex_init(rdb_collation_data_mutex_key, &rdb_collation_data_mutex,
MY_MUTEX_INIT_FAST);
@@ -4445,6 +4832,8 @@ static int rocksdb_init_func(void *const p) {
mysql_mutex_init(rdb_sysvars_psi_mutex_key, &rdb_sysvars_mutex,
MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(rdb_block_cache_resize_mutex_key,
+ &rdb_block_cache_resize_mutex, MY_MUTEX_INIT_FAST);
Rdb_transaction::init_mutex();
rocksdb_hton->state = SHOW_OPTION_YES;
@@ -4465,8 +4854,14 @@ static int rocksdb_init_func(void *const p) {
rocksdb_hton->rollback = rocksdb_rollback;
rocksdb_hton->show_status = rocksdb_show_status;
+#ifdef MARIADB_NOT_YET
+ rocksdb_hton->explicit_snapshot = rocksdb_explicit_snapshot;
+#endif
rocksdb_hton->start_consistent_snapshot =
rocksdb_start_tx_and_assign_read_view;
+#ifdef MARIADB_NOT_YET
+ rocksdb_hton->start_shared_snapshot = rocksdb_start_tx_with_shared_read_view;
+#endif
rocksdb_hton->savepoint_set = rocksdb_savepoint;
rocksdb_hton->savepoint_rollback = rocksdb_rollback_to_savepoint;
rocksdb_hton->savepoint_rollback_can_release_mdl =
@@ -4535,6 +4930,35 @@ static int rocksdb_init_func(void *const p) {
DBUG_RETURN(HA_EXIT_FAILURE);
}
+ // Check whether the filesystem backing rocksdb_datadir allows O_DIRECT
+ if (rocksdb_db_options->use_direct_reads) {
+ rocksdb::EnvOptions soptions;
+ rocksdb::Status check_status;
+ rocksdb::Env *const env = rocksdb_db_options->env;
+
+ std::string fname = format_string("%s/DIRECT_CHECK", rocksdb_datadir);
+ if (env->FileExists(fname).ok()) {
+ std::unique_ptr<rocksdb::SequentialFile> file;
+ soptions.use_direct_reads = true;
+ check_status = env->NewSequentialFile(fname, &file, soptions);
+ } else {
+ std::unique_ptr<rocksdb::WritableFile> file;
+ soptions.use_direct_writes = true;
+ check_status = env->ReopenWritableFile(fname, &file, soptions);
+ if (file != nullptr) {
+ file->Close();
+ }
+ env->DeleteFile(fname);
+ }
+
+ if (!check_status.ok()) {
+ sql_print_error("RocksDB: Unable to use direct io in rocksdb-datadir:"
+ "(%s)", check_status.getState());
+ rdb_open_tables.free_hash();
+ DBUG_RETURN(HA_EXIT_FAILURE);
+ }
+ }
+
if (rocksdb_db_options->allow_mmap_writes &&
rocksdb_db_options->use_direct_io_for_flush_and_compaction) {
// See above comment for allow_mmap_reads. (NO_LINT_DEBUG)
@@ -4687,8 +5111,10 @@ static int rocksdb_init_func(void *const p) {
cf_options_map->get_defaults());
rocksdb::TransactionDBOptions tx_db_options;
- tx_db_options.transaction_lock_timeout = 2; // 2 seconds
+ tx_db_options.transaction_lock_timeout = 2000; // 2 seconds
tx_db_options.custom_mutex_factory = std::make_shared<Rdb_mutex_factory>();
+ tx_db_options.write_policy =
+ static_cast<rocksdb::TxnDBWritePolicy>(rocksdb_write_policy);
status =
check_rocksdb_options_compatibility(rocksdb_datadir, main_opts, cf_descr);
@@ -4710,7 +5136,7 @@ static int rocksdb_init_func(void *const p) {
}
cf_manager.init(std::move(cf_options_map), &cf_handles);
- if (dict_manager.init(rdb->GetBaseDB(), &cf_manager)) {
+ if (dict_manager.init(rdb, &cf_manager)) {
// NO_LINT_DEBUG
sql_print_error("RocksDB: Failed to initialize data dictionary.");
DBUG_RETURN(HA_EXIT_FAILURE);
@@ -4771,6 +5197,21 @@ static int rocksdb_init_func(void *const p) {
DBUG_RETURN(HA_EXIT_FAILURE);
}
+ err = rdb_mc_thread.create_thread(MANUAL_COMPACTION_THREAD_NAME
+#ifdef HAVE_PSI_INTERFACE
+ ,
+ rdb_mc_psi_thread_key
+#endif
+ );
+ if (err != 0) {
+ // NO_LINT_DEBUG
+ sql_print_error(
+ "RocksDB: Couldn't start the manual compaction thread: (errno=%d)",
+ err);
+ rdb_open_tables.free_hash();
+ DBUG_RETURN(HA_EXIT_FAILURE);
+ }
+
rdb_set_collation_exception_list(rocksdb_strict_collation_exceptions);
if (rocksdb_pause_background_work) {
@@ -4877,6 +5318,16 @@ static int rocksdb_done_func(void *const p) {
sql_print_error("RocksDB: Couldn't stop the index thread: (errno=%d)", err);
}
+ // signal the manual compaction thread to stop
+ rdb_mc_thread.signal(true);
+ // Wait for the manual compaction thread to finish.
+ err = rdb_mc_thread.join();
+ if (err != 0) {
+ // NO_LINT_DEBUG
+ sql_print_error(
+ "RocksDB: Couldn't stop the manual compaction thread: (errno=%d)", err);
+ }
+
if (rdb_open_tables.m_hash.size()) {
// Looks like we are getting unloaded and yet we have some open tables
// left behind.
@@ -4933,6 +5384,7 @@ static int rocksdb_done_func(void *const p) {
rdb_open_tables.m_hash.~Rdb_table_set();
mysql_mutex_destroy(&rdb_open_tables.m_mutex);
mysql_mutex_destroy(&rdb_sysvars_mutex);
+ mysql_mutex_destroy(&rdb_block_cache_resize_mutex);
delete rdb_collation_exceptions;
@@ -5348,7 +5800,6 @@ longlong ha_rocksdb::update_hidden_pk_val() {
/* Get the id of the hidden pk id from m_last_rowkey */
int ha_rocksdb::read_hidden_pk_id_from_rowkey(longlong *const hidden_pk_id) {
- DBUG_ASSERT(hidden_pk_id != nullptr);
DBUG_ASSERT(table != nullptr);
DBUG_ASSERT(has_hidden_pk(table));
@@ -5404,14 +5855,14 @@ ha_rocksdb::ha_rocksdb(my_core::handlerton *const hton,
my_core::TABLE_SHARE *const table_arg)
: handler(hton, table_arg), m_table_handler(nullptr), m_scan_it(nullptr),
m_scan_it_skips_bloom(false), m_scan_it_snapshot(nullptr),
+ m_scan_it_lower_bound(nullptr), m_scan_it_upper_bound(nullptr),
m_tbl_def(nullptr), m_pk_descr(nullptr), m_key_descr_arr(nullptr),
m_pk_can_be_decoded(false), m_maybe_unpack_info(false),
m_pk_tuple(nullptr), m_pk_packed_tuple(nullptr),
m_sk_packed_tuple(nullptr), m_end_key_packed_tuple(nullptr),
m_sk_match_prefix(nullptr), m_sk_match_prefix_buf(nullptr),
m_sk_packed_tuple_old(nullptr), m_dup_sk_packed_tuple(nullptr),
- m_dup_sk_packed_tuple_old(nullptr), m_eq_cond_lower_bound(nullptr),
- m_eq_cond_upper_bound(nullptr), m_pack_buffer(nullptr),
+ m_dup_sk_packed_tuple_old(nullptr), m_pack_buffer(nullptr),
m_lock_rows(RDB_LOCK_NONE), m_keyread_only(FALSE), m_encoder_arr(nullptr),
m_row_checksums_checked(0), m_in_rpl_delete_rows(false),
m_in_rpl_update_rows(false), m_force_skip_unique_check(false) {}
@@ -5950,9 +6401,6 @@ int ha_rocksdb::convert_field_from_storage_format(
int ha_rocksdb::convert_record_from_storage_format(
const rocksdb::Slice *const key, const rocksdb::Slice *const value,
uchar *const buf) {
- DBUG_ASSERT(key != nullptr);
- DBUG_ASSERT(buf != nullptr);
-
Rdb_string_reader reader(value);
/*
@@ -6196,7 +6644,6 @@ int ha_rocksdb::alloc_key_buffers(const TABLE *const table_arg,
DBUG_ENTER_FUNC();
DBUG_ASSERT(m_pk_tuple == nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
std::shared_ptr<Rdb_key_def> *const kd_arr = tbl_def_arg->m_key_descr_arr;
@@ -6248,9 +6695,9 @@ int ha_rocksdb::alloc_key_buffers(const TABLE *const table_arg,
m_pack_buffer =
reinterpret_cast<uchar *>(my_malloc(max_packed_sk_len, MYF(0)));
- m_eq_cond_upper_bound =
+ m_scan_it_lower_bound =
reinterpret_cast<uchar *>(my_malloc(max_packed_sk_len, MYF(0)));
- m_eq_cond_lower_bound =
+ m_scan_it_upper_bound =
reinterpret_cast<uchar *>(my_malloc(max_packed_sk_len, MYF(0)));
/*
@@ -6267,7 +6714,7 @@ int ha_rocksdb::alloc_key_buffers(const TABLE *const table_arg,
if (m_pk_tuple == nullptr || m_pk_packed_tuple == nullptr ||
m_sk_packed_tuple == nullptr || m_sk_packed_tuple_old == nullptr ||
m_end_key_packed_tuple == nullptr || m_pack_buffer == nullptr ||
- m_eq_cond_upper_bound == nullptr || m_eq_cond_lower_bound == nullptr ||
+ m_scan_it_upper_bound == nullptr || m_scan_it_lower_bound == nullptr ||
(alloc_alter_buffers && (m_dup_sk_packed_tuple == nullptr ||
m_dup_sk_packed_tuple_old == nullptr))) {
// One or more of the above allocations failed. Clean up and exit
@@ -6307,11 +6754,11 @@ void ha_rocksdb::free_key_buffers() {
my_free(m_dup_sk_packed_tuple_old);
m_dup_sk_packed_tuple_old = nullptr;
- my_free(m_eq_cond_upper_bound);
- m_eq_cond_upper_bound = nullptr;
+ my_free(m_scan_it_lower_bound);
+ m_scan_it_lower_bound = nullptr;
- my_free(m_eq_cond_lower_bound);
- m_eq_cond_lower_bound = nullptr;
+ my_free(m_scan_it_upper_bound);
+ m_scan_it_upper_bound = nullptr;
}
#ifdef MARIAROCKS_NOT_YET
@@ -6569,9 +7016,8 @@ bool ha_rocksdb::get_error_message(const int error, String *const buf) {
static_assert(HA_ERR_ROCKSDB_LAST > HA_ERR_LAST,
"HA_ERR_ROCKSDB_LAST > HA_ERR_LAST");
- DBUG_ASSERT(buf != nullptr);
-
- if (error == HA_ERR_LOCK_WAIT_TIMEOUT || error == HA_ERR_LOCK_DEADLOCK) {
+ if (error == HA_ERR_LOCK_WAIT_TIMEOUT || error == HA_ERR_LOCK_DEADLOCK ||
+ error == HA_ERR_ROCKSDB_STATUS_BUSY) {
Rdb_transaction *const tx = get_tx_from_thd(ha_thd());
DBUG_ASSERT(tx != nullptr);
buf->append(tx->m_detailed_error);
@@ -6653,10 +7099,10 @@ int ha_rocksdb::rdb_error_to_mysql(const rocksdb::Status &s,
}
if (opt_msg) {
- my_error(ER_RDB_STATUS_MSG, MYF(0), opt_msg, s.code(),
- s.ToString().c_str());
+ std::string concatenated_error = s.ToString() + " (" + std::string(opt_msg) + ")";
+ my_error(ER_GET_ERRMSG, MYF(0), s.code(), concatenated_error.c_str(), rocksdb_hton_name);
} else {
- my_error(ER_RDB_STATUS_GENERAL, MYF(0), s.code(), s.ToString().c_str());
+ my_error(ER_GET_ERRMSG, MYF(0), s.code(), s.ToString().c_str(), rocksdb_hton_name);
}
return err;
@@ -6725,7 +7171,6 @@ int ha_rocksdb::create_key_defs(
/* = nullptr */) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
uint i;
@@ -6796,9 +7241,7 @@ int ha_rocksdb::create_cfs(
std::array<struct key_def_cf_info, MAX_INDEXES + 1> *const cfs) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
char tablename_sys[NAME_LEN + 1];
bool tsys_set= false;
@@ -6904,10 +7347,6 @@ int ha_rocksdb::create_inplace_key_defs(
const std::array<key_def_cf_info, MAX_INDEXES + 1> &cfs) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(table_arg != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
- DBUG_ASSERT(old_tbl_def_arg != nullptr);
-
std::shared_ptr<Rdb_key_def> *const old_key_descr =
old_tbl_def_arg->m_key_descr_arr;
std::shared_ptr<Rdb_key_def> *const new_key_descr =
@@ -6975,11 +7414,6 @@ std::unordered_map<std::string, uint> ha_rocksdb::get_old_key_positions(
const Rdb_tbl_def *const old_tbl_def_arg) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(table_arg != nullptr);
- DBUG_ASSERT(old_table_arg != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
- DBUG_ASSERT(old_tbl_def_arg != nullptr);
-
std::shared_ptr<Rdb_key_def> *const old_key_descr =
old_tbl_def_arg->m_key_descr_arr;
std::unordered_map<std::string, uint> old_key_pos;
@@ -7045,9 +7479,6 @@ int ha_rocksdb::compare_keys(const KEY *const old_key,
const KEY *const new_key) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(old_key != nullptr);
- DBUG_ASSERT(new_key != nullptr);
-
/* Check index name. */
if (strcmp(old_key->name.str, new_key->name.str) != 0) {
DBUG_RETURN(HA_EXIT_FAILURE);
@@ -7078,9 +7509,6 @@ int ha_rocksdb::compare_key_parts(const KEY *const old_key,
const KEY *const new_key) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(old_key != nullptr);
- DBUG_ASSERT(new_key != nullptr);
-
/* Skip if key parts do not match, as it is a different key */
if (new_key->user_defined_key_parts != old_key->user_defined_key_parts) {
DBUG_RETURN(HA_EXIT_FAILURE);
@@ -7125,7 +7553,6 @@ int ha_rocksdb::create_key_def(const TABLE *const table_arg, const uint &i,
const struct key_def_cf_info &cf_info) const {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(new_key_def != nullptr);
DBUG_ASSERT(*new_key_def == nullptr);
uint64 ttl_duration = 0;
@@ -7212,8 +7639,6 @@ int ha_rocksdb::create_key_def(const TABLE *const table_arg, const uint &i,
int rdb_normalize_tablename(const std::string &tablename,
std::string *const strbuf) {
- DBUG_ASSERT(strbuf != nullptr);
-
if (tablename.size() < 2 || tablename[0] != '.' ||
(tablename[1] != FN_LIBCHAR && tablename[1] != FN_LIBCHAR2)) {
DBUG_ASSERT(0); // We were not passed table name?
@@ -7537,8 +7962,6 @@ int ha_rocksdb::read_key_exact(const Rdb_key_def &kd,
const bool &full_key_match,
const rocksdb::Slice &key_slice,
const int64_t ttl_filter_ts) {
- DBUG_ASSERT(iter != nullptr);
-
/*
We are looking for the first record such that
index_tuple= lookup_tuple.
@@ -7746,8 +8169,6 @@ int ha_rocksdb::calc_eq_cond_len(const Rdb_key_def &kd,
}
int ha_rocksdb::read_row_from_primary_key(uchar *const buf) {
- DBUG_ASSERT(buf != nullptr);
-
int rc;
const rocksdb::Slice &rkey = m_scan_it->key();
const uint pk_size = rkey.size();
@@ -7771,8 +8192,6 @@ int ha_rocksdb::read_row_from_primary_key(uchar *const buf) {
int ha_rocksdb::read_row_from_secondary_key(uchar *const buf,
const Rdb_key_def &kd,
bool move_forward) {
- DBUG_ASSERT(buf != nullptr);
-
int rc = 0;
uint pk_size;
@@ -7875,7 +8294,6 @@ ulong ha_rocksdb::index_flags(uint inx, uint part, bool all_parts) const {
pair for.
*/
int ha_rocksdb::secondary_index_read(const int keyno, uchar *const buf) {
- DBUG_ASSERT(buf != nullptr);
DBUG_ASSERT(table != nullptr);
#ifdef MARIAROCKS_NOT_YET
stats.rows_requested++;
@@ -8192,7 +8610,7 @@ int ha_rocksdb::index_read_map_impl(uchar *const buf, const uchar *const key,
else
rc = read_row_from_secondary_key(buf, kd, move_forward);
- if (rc != HA_ERR_LOCK_DEADLOCK || !is_new_snapshot)
+ if (rc != HA_ERR_ROCKSDB_STATUS_BUSY || !is_new_snapshot)
break; /* Exit the loop */
// release the snapshot and iterator so they will be regenerated
@@ -8237,8 +8655,6 @@ int ha_rocksdb::index_read_map_impl(uchar *const buf, const uchar *const key,
int ha_rocksdb::find_icp_matching_index_rec(const bool &move_forward,
uchar *const buf) {
- DBUG_ASSERT(buf != nullptr);
-
if (pushed_idx_cond && pushed_idx_cond_keyno == active_index) {
const Rdb_key_def &kd = *m_key_descr_arr[active_index];
@@ -8552,8 +8968,6 @@ int ha_rocksdb::get_row_by_rowid(uchar *const buf, const char *const rowid,
const bool skip_ttl_check) {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(buf != nullptr);
- DBUG_ASSERT(rowid != nullptr);
DBUG_ASSERT(table != nullptr);
int rc;
@@ -8766,8 +9180,6 @@ int ha_rocksdb::index_last(uchar *const buf) {
int ha_rocksdb::index_first_intern(uchar *const buf) {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(buf != nullptr);
-
uchar *key;
uint key_size;
int rc;
@@ -8797,7 +9209,7 @@ int ha_rocksdb::index_first_intern(uchar *const buf) {
m_skip_scan_it_next_call = true;
rc = index_next_with_direction(buf, true);
- if (rc != HA_ERR_LOCK_DEADLOCK || !is_new_snapshot)
+ if (rc != HA_ERR_ROCKSDB_STATUS_BUSY || !is_new_snapshot)
break; // exit the loop
// release the snapshot and iterator so they will be regenerated
@@ -8859,8 +9271,6 @@ int ha_rocksdb::index_first_intern(uchar *const buf) {
int ha_rocksdb::index_last_intern(uchar *const buf) {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(buf != nullptr);
-
uchar *key;
uint key_size;
int rc;
@@ -8902,7 +9312,7 @@ int ha_rocksdb::index_last_intern(uchar *const buf) {
rc = secondary_index_read(active_index, buf);
}
- if (rc != HA_ERR_LOCK_DEADLOCK || !is_new_snapshot)
+ if (rc != HA_ERR_ROCKSDB_STATUS_BUSY || !is_new_snapshot)
break; /* exit the loop */
// release the snapshot and iterator so they will be regenerated
@@ -8987,7 +9397,6 @@ bool ha_rocksdb::commit_in_the_middle() {
@retval false if bulk commit was skipped or succeeded
*/
bool ha_rocksdb::do_bulk_commit(Rdb_transaction *const tx) {
- DBUG_ASSERT(tx != nullptr);
return commit_in_the_middle() &&
tx->get_write_count() >= THDVAR(table->in_use, bulk_load_size) &&
tx->flush_batch();
@@ -9000,7 +9409,6 @@ bool ha_rocksdb::do_bulk_commit(Rdb_transaction *const tx) {
'auto-incremented' pk.)
*/
bool ha_rocksdb::has_hidden_pk(const TABLE *const table) const {
- DBUG_ASSERT(table != nullptr);
return Rdb_key_def::table_has_hidden_pk(table);
}
@@ -9010,9 +9418,7 @@ bool ha_rocksdb::has_hidden_pk(const TABLE *const table) const {
*/
bool ha_rocksdb::is_hidden_pk(const uint index, const TABLE *const table_arg,
const Rdb_tbl_def *const tbl_def_arg) {
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
return (table_arg->s->primary_key == MAX_INDEXES &&
index == tbl_def_arg->m_key_count - 1);
@@ -9021,9 +9427,7 @@ bool ha_rocksdb::is_hidden_pk(const uint index, const TABLE *const table_arg,
/* Returns index of primary key */
uint ha_rocksdb::pk_index(const TABLE *const table_arg,
const Rdb_tbl_def *const tbl_def_arg) {
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
return table_arg->s->primary_key == MAX_INDEXES ? tbl_def_arg->m_key_count - 1
: table_arg->s->primary_key;
@@ -9032,9 +9436,7 @@ uint ha_rocksdb::pk_index(const TABLE *const table_arg,
/* Returns true if given index number is a primary key */
bool ha_rocksdb::is_pk(const uint index, const TABLE *const table_arg,
const Rdb_tbl_def *const tbl_def_arg) {
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
return index == table_arg->s->primary_key ||
is_hidden_pk(index, table_arg, tbl_def_arg);
@@ -9049,9 +9451,6 @@ uint ha_rocksdb::max_supported_key_part_length() const {
const char *ha_rocksdb::get_key_name(const uint index,
const TABLE *const table_arg,
const Rdb_tbl_def *const tbl_def_arg) {
- DBUG_ASSERT(table_arg != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
-
if (is_hidden_pk(index, table_arg, tbl_def_arg)) {
return HIDDEN_PK_NAME;
}
@@ -9065,9 +9464,6 @@ const char *ha_rocksdb::get_key_name(const uint index,
const char *ha_rocksdb::get_key_comment(const uint index,
const TABLE *const table_arg,
const Rdb_tbl_def *const tbl_def_arg) {
- DBUG_ASSERT(table_arg != nullptr);
- DBUG_ASSERT(tbl_def_arg != nullptr);
-
if (is_hidden_pk(index, table_arg, tbl_def_arg)) {
return nullptr;
}
@@ -9119,7 +9515,6 @@ const std::string ha_rocksdb::generate_cf_name(const uint index,
}
const std::string ha_rocksdb::get_table_comment(const TABLE *const table_arg) {
- DBUG_ASSERT(table_arg != nullptr);
DBUG_ASSERT(table_arg->s != nullptr);
return table_arg->s->comment.str;
@@ -9236,8 +9631,7 @@ int ha_rocksdb::check_and_lock_unique_pk(const uint &key_id,
/*
If the keys are the same, then no lock is needed
*/
- if (!Rdb_pk_comparator::bytewise_compare(row_info.new_pk_slice,
- row_info.old_pk_slice)) {
+ if (!row_info.new_pk_slice.compare(row_info.old_pk_slice)) {
*found = false;
return HA_EXIT_SUCCESS;
}
@@ -9326,8 +9720,7 @@ int ha_rocksdb::check_and_lock_sk(const uint &key_id,
rocksdb::Slice((const char *)m_sk_packed_tuple, size);
/*
- For UPDATEs, if the key has changed, we need to obtain a lock. INSERTs
- always require locking.
+ Acquire lock on the old key in case of UPDATE
*/
if (row_info.old_data != nullptr) {
size = kd.pack_record(table, m_pack_buffer, row_info.old_data,
@@ -9336,14 +9729,18 @@ int ha_rocksdb::check_and_lock_sk(const uint &key_id,
const rocksdb::Slice old_slice =
rocksdb::Slice((const char *)m_sk_packed_tuple_old, size);
- /*
- For updates, if the keys are the same, then no lock is needed
+ const rocksdb::Status s =
+ get_for_update(row_info.tx, kd.get_cf(), old_slice, nullptr);
+ if (!s.ok()) {
+ return row_info.tx->set_status_error(table->in_use, s, kd, m_tbl_def,
+ m_table_handler);
+ }
- Also check to see if the key has any fields set to NULL. If it does, then
- this key is unique since NULL is not equal to each other, so no lock is
- needed.
+ /*
+ If the old and new keys are the same we're done since we've already taken
+ the lock on the old key
*/
- if (!Rdb_pk_comparator::bytewise_compare(new_slice, old_slice)) {
+ if (!new_slice.compare(old_slice)) {
return HA_EXIT_SUCCESS;
}
}
@@ -9369,16 +9766,14 @@ int ha_rocksdb::check_and_lock_sk(const uint &key_id,
The bloom filter may need to be disabled for this lookup.
*/
- uchar min_bound_buf[MAX_KEY_LENGTH];
- uchar max_bound_buf[MAX_KEY_LENGTH];
- rocksdb::Slice min_bound_slice;
- rocksdb::Slice max_bound_slice;
+ uchar lower_bound_buf[Rdb_key_def::INDEX_NUMBER_SIZE];
+ uchar upper_bound_buf[Rdb_key_def::INDEX_NUMBER_SIZE];
+ rocksdb::Slice lower_bound_slice;
+ rocksdb::Slice upper_bound_slice;
+
const bool total_order_seek = !check_bloom_and_set_bounds(
- ha_thd(), kd, new_slice, all_parts_used,
- min_bound_buf,
- max_bound_buf,
- &min_bound_slice,
- &max_bound_slice);
+ ha_thd(), kd, new_slice, all_parts_used, Rdb_key_def::INDEX_NUMBER_SIZE,
+ lower_bound_buf, upper_bound_buf, &lower_bound_slice, &upper_bound_slice);
const bool fill_cache = !THDVAR(ha_thd(), skip_fill_cache);
const rocksdb::Status s =
@@ -9389,9 +9784,8 @@ int ha_rocksdb::check_and_lock_sk(const uint &key_id,
}
rocksdb::Iterator *const iter = row_info.tx->get_iterator(
- kd.get_cf(), total_order_seek, fill_cache,
- min_bound_slice, max_bound_slice,
- true /* read current data */,
+ kd.get_cf(), total_order_seek, fill_cache, lower_bound_slice,
+ upper_bound_slice, true /* read current data */,
false /* acquire snapshot */);
/*
Need to scan the transaction to see if there is a duplicate key.
@@ -9553,7 +9947,7 @@ int ha_rocksdb::update_pk(const Rdb_key_def &kd,
}
}
- if (table->next_number_field) {
+ if (table->found_next_number_field) {
update_auto_incr_val_from_field();
}
@@ -9601,9 +9995,11 @@ int ha_rocksdb::update_pk(const Rdb_key_def &kd,
}
int ha_rocksdb::update_sk(const TABLE *const table_arg, const Rdb_key_def &kd,
- const struct update_row_info &row_info) {
+ const struct update_row_info &row_info,
+ const bool bulk_load_sk) {
int new_packed_size;
int old_packed_size;
+ int rc = HA_EXIT_SUCCESS;
rocksdb::Slice new_key_slice;
rocksdb::Slice new_value_slice;
@@ -9681,18 +10077,23 @@ int ha_rocksdb::update_sk(const TABLE *const table_arg, const Rdb_key_def &kd,
rocksdb::Slice(reinterpret_cast<const char *>(m_sk_tails.ptr()),
m_sk_tails.get_current_pos());
- row_info.tx->get_indexed_write_batch()->Put(kd.get_cf(), new_key_slice,
- new_value_slice);
+ if (bulk_load_sk && row_info.old_data == nullptr) {
+ rc = bulk_load_key(row_info.tx, kd, new_key_slice, new_value_slice, true);
+ } else {
+ row_info.tx->get_indexed_write_batch()->Put(kd.get_cf(), new_key_slice,
+ new_value_slice);
+ }
row_info.tx->update_bytes_written(bytes_written + new_key_slice.size() +
new_value_slice.size());
- return HA_EXIT_SUCCESS;
+ return rc;
}
int ha_rocksdb::update_indexes(const struct update_row_info &row_info,
const bool &pk_changed) {
int rc;
+ bool bulk_load_sk;
// The PK must be updated first to pull out the TTL value.
rc = update_pk(*m_pk_descr, row_info, pk_changed);
@@ -9700,13 +10101,17 @@ int ha_rocksdb::update_indexes(const struct update_row_info &row_info,
return rc;
}
- // Update the remaining indexes.
+ // Update the remaining indexes. Allow bulk loading only if
+ // allow_sk is enabled
+ bulk_load_sk = rocksdb_enable_bulk_load_api &&
+ THDVAR(table->in_use, bulk_load) &&
+ THDVAR(table->in_use, bulk_load_allow_sk);
for (uint key_id = 0; key_id < m_tbl_def->m_key_count; key_id++) {
if (is_pk(key_id, table, m_tbl_def)) {
continue;
}
- rc = update_sk(table, *m_key_descr_arr[key_id], row_info);
+ rc = update_sk(table, *m_key_descr_arr[key_id], row_info, bulk_load_sk);
if (rc != HA_EXIT_SUCCESS) {
return rc;
}
@@ -9804,28 +10209,22 @@ int ha_rocksdb::update_write_row(const uchar *const old_data,
@param outer_u
*/
-void ha_rocksdb::setup_iterator_bounds(const Rdb_key_def &kd,
- const rocksdb::Slice &eq_cond,
- uchar *lower_bound_buf,
- uchar *upper_bound_buf,
- rocksdb::Slice *out_lower_bound,
- rocksdb::Slice *out_upper_bound) {
- uint eq_cond_len = eq_cond.size();
- memcpy(upper_bound_buf, eq_cond.data(), eq_cond_len);
- kd.successor(upper_bound_buf, eq_cond_len);
- memcpy(lower_bound_buf, eq_cond.data(), eq_cond_len);
- kd.predecessor(lower_bound_buf, eq_cond_len);
+void ha_rocksdb::setup_iterator_bounds(
+ const Rdb_key_def &kd, const rocksdb::Slice &eq_cond, size_t bound_len,
+ uchar *const lower_bound, uchar *const upper_bound,
+ rocksdb::Slice *lower_bound_slice, rocksdb::Slice *upper_bound_slice) {
+ uint min_len = std::min(eq_cond.size(), bound_len);
+ memcpy(upper_bound, eq_cond.data(), min_len);
+ kd.successor(upper_bound, min_len);
+ memcpy(lower_bound, eq_cond.data(), min_len);
+ kd.predecessor(lower_bound, min_len);
if (kd.m_is_reverse_cf) {
- *out_upper_bound =
- rocksdb::Slice((const char *)lower_bound_buf, eq_cond_len);
- *out_lower_bound =
- rocksdb::Slice((const char *)upper_bound_buf, eq_cond_len);
+ *upper_bound_slice = rocksdb::Slice((const char *)lower_bound, min_len);
+ *lower_bound_slice = rocksdb::Slice((const char *)upper_bound, min_len);
} else {
- *out_upper_bound =
- rocksdb::Slice((const char *)upper_bound_buf, eq_cond_len);
- *out_lower_bound =
- rocksdb::Slice((const char *)lower_bound_buf, eq_cond_len);
+ *upper_bound_slice = rocksdb::Slice((const char *)upper_bound, min_len);
+ *lower_bound_slice = rocksdb::Slice((const char *)lower_bound, min_len);
}
}
@@ -9837,7 +10236,6 @@ void ha_rocksdb::setup_scan_iterator(const Rdb_key_def &kd,
rocksdb::Slice *const slice,
const bool use_all_keys,
const uint eq_cond_len) {
- DBUG_ASSERT(slice != nullptr);
DBUG_ASSERT(slice->size() >= eq_cond_len);
Rdb_transaction *const tx = get_or_create_tx(table->in_use);
@@ -9845,11 +10243,10 @@ void ha_rocksdb::setup_scan_iterator(const Rdb_key_def &kd,
bool skip_bloom = true;
const rocksdb::Slice eq_cond(slice->data(), eq_cond_len);
- if (check_bloom_and_set_bounds(ha_thd(), kd, eq_cond, use_all_keys,
- m_eq_cond_lower_bound,
- m_eq_cond_upper_bound,
- &m_eq_cond_lower_bound_slice,
- &m_eq_cond_upper_bound_slice)) {
+ if (check_bloom_and_set_bounds(
+ ha_thd(), kd, eq_cond, use_all_keys, eq_cond_len,
+ m_scan_it_lower_bound, m_scan_it_upper_bound,
+ &m_scan_it_lower_bound_slice, &m_scan_it_upper_bound_slice)) {
skip_bloom = false;
}
@@ -9890,8 +10287,8 @@ void ha_rocksdb::setup_scan_iterator(const Rdb_key_def &kd,
m_scan_it = rdb->NewIterator(read_opts, kd.get_cf());
} else {
m_scan_it = tx->get_iterator(kd.get_cf(), skip_bloom, fill_cache,
- m_eq_cond_lower_bound_slice,
- m_eq_cond_upper_bound_slice);
+ m_scan_it_lower_bound_slice,
+ m_scan_it_upper_bound_slice);
}
m_scan_it_skips_bloom = skip_bloom;
}
@@ -9957,7 +10354,7 @@ int ha_rocksdb::rnd_next(uchar *const buf) {
int rc;
for (;;) {
rc = rnd_next_with_direction(buf, true);
- if (rc != HA_ERR_LOCK_DEADLOCK || !m_rnd_scan_is_new_snapshot)
+ if (rc != HA_ERR_ROCKSDB_STATUS_BUSY || !m_rnd_scan_is_new_snapshot)
break; /* exit the loop */
// release the snapshot and iterator and then regenerate them
@@ -10286,7 +10683,7 @@ int ha_rocksdb::info(uint flag) {
if (static_cast<longlong>(stats.data_file_length) < 0 ||
static_cast<longlong>(stats.index_file_length) < 0 ||
static_cast<longlong>(stats.records) < 0) {
- if (analyze(nullptr, nullptr)) {
+ if (calculate_stats_for_table()) {
DBUG_RETURN(HA_EXIT_FAILURE);
}
@@ -10364,10 +10761,21 @@ int ha_rocksdb::info(uint flag) {
KEY *const k = &table->key_info[i];
for (uint j = 0; j < k->ext_key_parts; j++) {
const Rdb_index_stats &k_stats = m_key_descr_arr[i]->m_stats;
- uint x = k_stats.m_distinct_keys_per_prefix.size() > j &&
- k_stats.m_distinct_keys_per_prefix[j] > 0
- ? k_stats.m_rows / k_stats.m_distinct_keys_per_prefix[j]
- : 0;
+ uint x;
+
+ if (k_stats.m_distinct_keys_per_prefix.size() > j &&
+ k_stats.m_distinct_keys_per_prefix[j] > 0) {
+ x = k_stats.m_rows / k_stats.m_distinct_keys_per_prefix[j];
+ /*
+ If the number of rows is less than the number of prefixes (due to
+ sampling), the average number of rows with the same prefix is 1.
+ */
+ if (x == 0) {
+ x = 1;
+ }
+ } else {
+ x = 0;
+ }
if (x > stats.records)
x = stats.records;
if ((x == 0 && rocksdb_debug_optimizer_no_zero_cardinality) ||
@@ -10572,7 +10980,7 @@ THR_LOCK_DATA **ha_rocksdb::store_lock(THD *const thd, THR_LOCK_DATA **to,
m_lock_rows = RDB_LOCK_WRITE;
} else if (lock_type == TL_READ_WITH_SHARED_LOCKS) {
m_lock_rows = RDB_LOCK_READ;
- } else {
+ } else if (lock_type != TL_IGNORE) {
m_lock_rows = RDB_LOCK_NONE;
if (THDVAR(thd, lock_scanned_rows)) {
/*
@@ -10737,6 +11145,13 @@ int ha_rocksdb::external_lock(THD *const thd, int lock_type) {
DBUG_RETURN(HA_ERR_UNSUPPORTED);
}
+#ifdef MARIADB_NOT_YET
+ if (thd->get_explicit_snapshot()) {
+ my_error(ER_UPDATES_WITH_EXPLICIT_SNAPSHOT, MYF(0));
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+ }
+#endif
+
/*
SQL layer signals us to take a write lock. It does so when starting DML
statement. We should put locks on the rows we're reading.
@@ -10958,8 +11373,6 @@ void Rdb_drop_index_thread::run() {
}
Rdb_tbl_def *ha_rocksdb::get_table_if_exists(const char *const tablename) {
- DBUG_ASSERT(tablename != nullptr);
-
std::string str;
if (rdb_normalize_tablename(tablename, &str) != HA_EXIT_SUCCESS) {
// We were not passed table name?
@@ -11022,6 +11435,12 @@ int ha_rocksdb::remove_rows(Rdb_tbl_def *const tbl) {
char key_buf[MAX_KEY_LENGTH];
uint key_len;
ulonglong bytes_written = 0;
+
+ uchar lower_bound_buf[Rdb_key_def::INDEX_NUMBER_SIZE];
+ uchar upper_bound_buf[Rdb_key_def::INDEX_NUMBER_SIZE];
+ rocksdb::Slice lower_bound_slice;
+ rocksdb::Slice upper_bound_slice;
+
/*
Remove all records in each index.
(This is is not crash-safe, but it doesn't matter, because bulk row
@@ -11032,13 +11451,12 @@ int ha_rocksdb::remove_rows(Rdb_tbl_def *const tbl) {
kd.get_infimum_key(reinterpret_cast<uchar *>(key_buf), &key_len);
rocksdb::ColumnFamilyHandle *cf = kd.get_cf();
const rocksdb::Slice table_key(key_buf, key_len);
- setup_iterator_bounds(kd, table_key,
- m_eq_cond_lower_bound,
- m_eq_cond_upper_bound,
- &m_eq_cond_lower_bound_slice,
- &m_eq_cond_upper_bound_slice);
- opts.iterate_lower_bound = &m_eq_cond_lower_bound_slice;
- opts.iterate_upper_bound = &m_eq_cond_upper_bound_slice;
+ setup_iterator_bounds(kd, table_key, Rdb_key_def::INDEX_NUMBER_SIZE,
+ lower_bound_buf, upper_bound_buf, &lower_bound_slice,
+ &upper_bound_slice);
+ DBUG_ASSERT(key_len == Rdb_key_def::INDEX_NUMBER_SIZE);
+ opts.iterate_lower_bound = &lower_bound_slice;
+ opts.iterate_upper_bound = &upper_bound_slice;
std::unique_ptr<rocksdb::Iterator> it(rdb->NewIterator(opts, cf));
it->Seek(table_key);
@@ -11077,9 +11495,6 @@ int ha_rocksdb::remove_rows(Rdb_tbl_def *const tbl) {
int ha_rocksdb::rename_table(const char *const from, const char *const to) {
DBUG_ENTER_FUNC();
- DBUG_ASSERT(from != nullptr);
- DBUG_ASSERT(to != nullptr);
-
std::string from_str;
std::string to_str;
std::string from_db;
@@ -11330,29 +11745,28 @@ int ha_rocksdb::optimize(THD *const thd, HA_CHECK_OPT *const check_opt) {
DBUG_RETURN(HA_EXIT_SUCCESS);
}
-int ha_rocksdb::calculate_stats(const TABLE *const table_arg, THD *const thd,
- HA_CHECK_OPT *const check_opt) {
+static int calculate_stats(
+ const std::unordered_map<GL_INDEX_ID, std::shared_ptr<const Rdb_key_def>>
+ &to_recalc,
+ bool include_memtables) {
DBUG_ENTER_FUNC();
// find per column family key ranges which need to be queried
std::unordered_map<rocksdb::ColumnFamilyHandle *, std::vector<rocksdb::Range>>
ranges;
- std::unordered_set<GL_INDEX_ID> ids_to_check;
- std::vector<uchar> buf(table_arg->s->keys * 2 *
- Rdb_key_def::INDEX_NUMBER_SIZE);
std::unordered_map<GL_INDEX_ID, Rdb_index_stats> stats;
- for (uint i = 0; i < table_arg->s->keys; i++) {
- const auto bufp = &buf[i * 2 * Rdb_key_def::INDEX_NUMBER_SIZE];
- const Rdb_key_def &kd = *m_key_descr_arr[i];
- const GL_INDEX_ID index_id = kd.get_gl_index_id();
- ranges[kd.get_cf()].push_back(get_range(i, bufp));
-
- ids_to_check.insert(index_id);
- // Initialize the stats to 0. If there are no files that contain
- // this gl_index_id, then 0 should be stored for the cached stats.
+ std::vector<uchar> buf(to_recalc.size() * 2 * Rdb_key_def::INDEX_NUMBER_SIZE);
+
+ uchar *bufp = buf.data();
+ for (const auto &it : to_recalc) {
+ const GL_INDEX_ID index_id = it.first;
+ auto &kd = it.second;
+ ranges[kd->get_cf()].push_back(myrocks::get_range(*kd, bufp));
+ bufp += 2 * Rdb_key_def::INDEX_NUMBER_SIZE;
+
stats[index_id] = Rdb_index_stats(index_id);
- DBUG_ASSERT(kd.get_key_parts() > 0);
- stats[index_id].m_distinct_keys_per_prefix.resize(kd.get_key_parts());
+ DBUG_ASSERT(kd->get_key_parts() > 0);
+ stats[index_id].m_distinct_keys_per_prefix.resize(kd->get_key_parts());
}
// get RocksDB table properties for these ranges
@@ -11363,8 +11777,8 @@ int ha_rocksdb::calculate_stats(const TABLE *const table_arg, THD *const thd,
it.first, &it.second[0], it.second.size(), &props);
DBUG_ASSERT(props.size() >= old_size);
if (!status.ok()) {
- DBUG_RETURN(
- rdb_error_to_mysql(status, "Could not access RocksDB properties"));
+ DBUG_RETURN(ha_rocksdb::rdb_error_to_mysql(
+ status, "Could not access RocksDB properties"));
}
}
@@ -11385,61 +11799,62 @@ int ha_rocksdb::calculate_stats(const TABLE *const table_arg, THD *const thd,
other SQL tables, it can be that we're only seeing a small fraction
of table's entries (and so we can't update statistics based on that).
*/
- if (ids_to_check.find(it1.m_gl_index_id) == ids_to_check.end())
+ if (stats.find(it1.m_gl_index_id) == stats.end()) {
continue;
+ }
- auto kd = ddl_manager.safe_find(it1.m_gl_index_id);
- DBUG_ASSERT(kd != nullptr);
- stats[it1.m_gl_index_id].merge(it1, true, kd->max_storage_fmt_length());
+ auto it_index = to_recalc.find(it1.m_gl_index_id);
+ DBUG_ASSERT(it_index != to_recalc.end());
+ if (it_index == to_recalc.end()) {
+ continue;
+ }
+ stats[it1.m_gl_index_id].merge(
+ it1, true, it_index->second->max_storage_fmt_length());
}
num_sst++;
}
- // calculate memtable cardinality
- Rdb_tbl_card_coll cardinality_collector(rocksdb_table_stats_sampling_pct);
- auto read_opts = rocksdb::ReadOptions();
- read_opts.read_tier = rocksdb::ReadTier::kMemtableTier;
- for (uint i = 0; i < table_arg->s->keys; i++) {
- const Rdb_key_def &kd = *m_key_descr_arr[i];
- Rdb_index_stats &stat = stats[kd.get_gl_index_id()];
-
- uchar r_buf[Rdb_key_def::INDEX_NUMBER_SIZE * 2];
- auto r = get_range(i, r_buf);
- uint64_t memtableCount;
- uint64_t memtableSize;
- rdb->GetApproximateMemTableStats(kd.get_cf(), r, &memtableCount,
- &memtableSize);
- if (memtableCount < (uint64_t)stat.m_rows / 10) {
- // skip tables that already have enough stats from SST files to reduce
- // overhead and avoid degradation of big tables stats by sampling from
- // relatively tiny (less than 10% of full data set) memtable dataset
- continue;
- }
+ if (include_memtables) {
+ // calculate memtable cardinality
+ Rdb_tbl_card_coll cardinality_collector(rocksdb_table_stats_sampling_pct);
+ auto read_opts = rocksdb::ReadOptions();
+ read_opts.read_tier = rocksdb::ReadTier::kMemtableTier;
+ for (const auto &it_kd : to_recalc) {
+ const std::shared_ptr<const Rdb_key_def> &kd = it_kd.second;
+ Rdb_index_stats &stat = stats[kd->get_gl_index_id()];
+
+ uchar r_buf[Rdb_key_def::INDEX_NUMBER_SIZE * 2];
+ auto r = myrocks::get_range(*kd, r_buf);
+ uint64_t memtableCount;
+ uint64_t memtableSize;
+ rdb->GetApproximateMemTableStats(kd->get_cf(), r, &memtableCount,
+ &memtableSize);
+ if (memtableCount < (uint64_t)stat.m_rows / 10) {
+ // skip tables that already have enough stats from SST files to reduce
+ // overhead and avoid degradation of big tables stats by sampling from
+ // relatively tiny (less than 10% of full data set) memtable dataset
+ continue;
+ }
- std::unique_ptr<rocksdb::Iterator> it = std::unique_ptr<rocksdb::Iterator>(
- rdb->NewIterator(read_opts, kd.get_cf()));
+ std::unique_ptr<rocksdb::Iterator> it =
+ std::unique_ptr<rocksdb::Iterator>(
+ rdb->NewIterator(read_opts, kd->get_cf()));
- uchar *first_key;
- uint key_size;
- if (is_pk(i, table, m_tbl_def)) {
- first_key = m_pk_packed_tuple;
- } else {
- first_key = m_sk_packed_tuple;
- }
- kd.get_first_key(first_key, &key_size);
- rocksdb::Slice first_index_key((const char *)first_key, key_size);
+ rocksdb::Slice first_index_key((const char *)r_buf,
+ Rdb_key_def::INDEX_NUMBER_SIZE);
- cardinality_collector.Reset();
- for (it->Seek(first_index_key); is_valid(it.get()); it->Next()) {
- const rocksdb::Slice key = it->key();
- if (!kd.covers_key(key)) {
- break; // end of this index
- }
- stat.m_rows++;
+ cardinality_collector.Reset();
+ for (it->Seek(first_index_key); is_valid(it.get()); it->Next()) {
+ const rocksdb::Slice key = it->key();
+ if (!kd->covers_key(key)) {
+ break; // end of this index
+ }
+ stat.m_rows++;
- cardinality_collector.ProcessKey(key, &kd, &stat);
+ cardinality_collector.ProcessKey(key, kd.get(), &stat);
+ }
+ cardinality_collector.AdjustStats(&stat);
}
- cardinality_collector.AdjustStats(&stat);
}
// set and persist new stats
@@ -11449,6 +11864,19 @@ int ha_rocksdb::calculate_stats(const TABLE *const table_arg, THD *const thd,
DBUG_RETURN(HA_EXIT_SUCCESS);
}
+int ha_rocksdb::calculate_stats_for_table() {
+ DBUG_ENTER_FUNC();
+
+ std::unordered_map<GL_INDEX_ID, std::shared_ptr<const Rdb_key_def>>
+ ids_to_check;
+ for (uint i = 0; i < table->s->keys; i++) {
+ ids_to_check.insert(std::make_pair(m_key_descr_arr[i]->get_gl_index_id(),
+ m_key_descr_arr[i]));
+ }
+
+ DBUG_RETURN(calculate_stats(ids_to_check, true));
+}
+
/*
@return
HA_ADMIN_OK OK
@@ -11457,7 +11885,16 @@ int ha_rocksdb::calculate_stats(const TABLE *const table_arg, THD *const thd,
int ha_rocksdb::analyze(THD *const thd, HA_CHECK_OPT *const check_opt) {
DBUG_ENTER_FUNC();
- if (table && calculate_stats(table, thd, check_opt) != HA_EXIT_SUCCESS) {
+ if (table) {
+ if (calculate_stats_for_table() != HA_EXIT_SUCCESS) {
+ DBUG_RETURN(HA_ADMIN_FAILED);
+ }
+ }
+
+ // A call to ::info is needed to repopulate some SQL level structs. This is
+ // necessary for online analyze because we cannot rely on another ::open
+ // call to call info for us.
+ if (info(HA_STATUS_CONST | HA_STATUS_VARIABLE) != HA_EXIT_SUCCESS) {
DBUG_RETURN(HA_ADMIN_FAILED);
}
@@ -12286,18 +12723,6 @@ bool ha_rocksdb::commit_inplace_alter_table(
dict_manager.finish_indexes_operation(
create_index_ids, Rdb_key_def::DDL_CREATE_INDEX_ONGOING);
- /*
- We need to recalculate the index stats here manually. The reason is that
- the secondary index does not exist inside
- m_index_num_to_keydef until it is committed to the data dictionary, which
- prevents us from updating the stats normally as the ddl_manager cannot
- find the proper gl_index_ids yet during adjust_stats calls.
- */
- if (calculate_stats(altered_table, nullptr, nullptr)) {
- /* Failed to update index statistics, should never happen */
- DBUG_ASSERT(0);
- }
-
rdb_drop_idx_thread.signal();
}
@@ -12368,6 +12793,8 @@ struct rocksdb_status_counters_t {
uint64_t block_cache_data_hit;
uint64_t block_cache_data_add;
uint64_t bloom_filter_useful;
+ uint64_t bloom_filter_full_positive;
+ uint64_t bloom_filter_full_true_positive;
uint64_t memtable_hit;
uint64_t memtable_miss;
uint64_t get_hit_l0;
@@ -12442,6 +12869,8 @@ DEF_SHOW_FUNC(block_cache_data_miss, BLOCK_CACHE_DATA_MISS)
DEF_SHOW_FUNC(block_cache_data_hit, BLOCK_CACHE_DATA_HIT)
DEF_SHOW_FUNC(block_cache_data_add, BLOCK_CACHE_DATA_ADD)
DEF_SHOW_FUNC(bloom_filter_useful, BLOOM_FILTER_USEFUL)
+DEF_SHOW_FUNC(bloom_filter_full_positive, BLOOM_FILTER_FULL_POSITIVE)
+DEF_SHOW_FUNC(bloom_filter_full_true_positive, BLOOM_FILTER_FULL_TRUE_POSITIVE)
DEF_SHOW_FUNC(memtable_hit, MEMTABLE_HIT)
DEF_SHOW_FUNC(memtable_miss, MEMTABLE_MISS)
DEF_SHOW_FUNC(get_hit_l0, GET_HIT_L0)
@@ -12676,6 +13105,8 @@ static SHOW_VAR rocksdb_status_vars[] = {
DEF_STATUS_VAR(block_cache_data_hit),
DEF_STATUS_VAR(block_cache_data_add),
DEF_STATUS_VAR(bloom_filter_useful),
+ DEF_STATUS_VAR(bloom_filter_full_positive),
+ DEF_STATUS_VAR(bloom_filter_full_true_positive),
DEF_STATUS_VAR(memtable_hit),
DEF_STATUS_VAR(memtable_miss),
DEF_STATUS_VAR(get_hit_l0),
@@ -12733,6 +13164,10 @@ static SHOW_VAR rocksdb_status_vars[] = {
&rocksdb_snapshot_conflict_errors, SHOW_LONGLONG),
DEF_STATUS_VAR_PTR("wal_group_syncs", &rocksdb_wal_group_syncs,
SHOW_LONGLONG),
+ DEF_STATUS_VAR_PTR("manual_compactions_processed",
+ &rocksdb_manual_compactions_processed, SHOW_LONGLONG),
+ DEF_STATUS_VAR_PTR("manual_compactions_running",
+ &rocksdb_manual_compactions_running, SHOW_LONGLONG),
DEF_STATUS_VAR_PTR("number_sst_entry_put", &rocksdb_num_sst_entry_put,
SHOW_LONGLONG),
DEF_STATUS_VAR_PTR("number_sst_entry_delete", &rocksdb_num_sst_entry_delete,
@@ -12806,24 +13241,193 @@ void Rdb_background_thread::run() {
rdb_handle_io_error(s, RDB_IO_ERROR_BG_THREAD);
}
}
+ // Recalculate statistics for indexes.
+ if (rocksdb_stats_recalc_rate) {
+ std::unordered_map<GL_INDEX_ID, std::shared_ptr<const Rdb_key_def>>
+ to_recalc;
+
+ if (rdb_indexes_to_recalc.empty()) {
+ struct Rdb_index_collector : public Rdb_tables_scanner {
+ int add_table(Rdb_tbl_def *tdef) override {
+ for (uint i = 0; i < tdef->m_key_count; i++) {
+ rdb_indexes_to_recalc.push_back(
+ tdef->m_key_descr_arr[i]->get_gl_index_id());
+ }
+ return HA_EXIT_SUCCESS;
+ }
+ } collector;
+ ddl_manager.scan_for_tables(&collector);
+ }
+
+ while (to_recalc.size() < rocksdb_stats_recalc_rate &&
+ !rdb_indexes_to_recalc.empty()) {
+ const auto index_id = rdb_indexes_to_recalc.back();
+ rdb_indexes_to_recalc.pop_back();
+
+ std::shared_ptr<const Rdb_key_def> keydef =
+ ddl_manager.safe_find(index_id);
+
+ if (keydef) {
+ to_recalc.insert(std::make_pair(keydef->get_gl_index_id(), keydef));
+ }
+ }
+
+ if (!to_recalc.empty()) {
+ calculate_stats(to_recalc, false);
+ }
+ }
+
}
// save remaining stats which might've left unsaved
ddl_manager.persist_stats();
}
-bool ha_rocksdb::check_bloom_and_set_bounds(THD *thd, const Rdb_key_def &kd,
- const rocksdb::Slice &eq_cond,
- const bool use_all_keys,
- uchar *lower_bound_buf,
- uchar *upper_bound_buf,
- rocksdb::Slice *out_lower_bound,
- rocksdb::Slice *out_upper_bound) {
+/*
+ A background thread to handle manual compactions,
+ except for dropping indexes/tables. Every second, it checks
+ pending manual compactions, and it calls CompactRange if there is.
+*/
+void Rdb_manual_compaction_thread::run() {
+ mysql_mutex_init(0, &m_mc_mutex, MY_MUTEX_INIT_FAST);
+ RDB_MUTEX_LOCK_CHECK(m_signal_mutex);
+ for (;;) {
+ if (m_stop) {
+ break;
+ }
+ timespec ts;
+ set_timespec(ts, 1);
+
+ const auto ret MY_ATTRIBUTE((__unused__)) =
+ mysql_cond_timedwait(&m_signal_cond, &m_signal_mutex, &ts);
+ if (m_stop) {
+ break;
+ }
+ // make sure, no program error is returned
+ DBUG_ASSERT(ret == 0 || ret == ETIMEDOUT);
+ RDB_MUTEX_UNLOCK_CHECK(m_signal_mutex);
+
+ RDB_MUTEX_LOCK_CHECK(m_mc_mutex);
+ // Grab the first item and proceed, if not empty.
+ if (m_requests.empty()) {
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+ RDB_MUTEX_LOCK_CHECK(m_signal_mutex);
+ continue;
+ }
+ Manual_compaction_request &mcr = m_requests.begin()->second;
+ DBUG_ASSERT(mcr.cf != nullptr);
+ DBUG_ASSERT(mcr.state == Manual_compaction_request::INITED);
+ mcr.state = Manual_compaction_request::RUNNING;
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+
+ DBUG_ASSERT(mcr.state == Manual_compaction_request::RUNNING);
+ // NO_LINT_DEBUG
+ sql_print_information("Manual Compaction id %d cf %s started.", mcr.mc_id,
+ mcr.cf->GetName().c_str());
+ rocksdb_manual_compactions_running++;
+ if (rocksdb_debug_manual_compaction_delay > 0) {
+ my_sleep(rocksdb_debug_manual_compaction_delay * 1000000);
+ }
+ // CompactRange may take a very long time. On clean shutdown,
+ // it is cancelled by CancelAllBackgroundWork, then status is
+ // set to shutdownInProgress.
+ const rocksdb::Status s = rdb->CompactRange(
+ getCompactRangeOptions(mcr.concurrency), mcr.cf, mcr.start, mcr.limit);
+ rocksdb_manual_compactions_running--;
+ if (s.ok()) {
+ // NO_LINT_DEBUG
+ sql_print_information("Manual Compaction id %d cf %s ended.", mcr.mc_id,
+ mcr.cf->GetName().c_str());
+ } else {
+ // NO_LINT_DEBUG
+ sql_print_information("Manual Compaction id %d cf %s aborted. %s",
+ mcr.mc_id, mcr.cf->GetName().c_str(), s.getState());
+ if (!s.IsShutdownInProgress()) {
+ rdb_handle_io_error(s, RDB_IO_ERROR_BG_THREAD);
+ } else {
+ DBUG_ASSERT(m_requests.size() == 1);
+ }
+ }
+ rocksdb_manual_compactions_processed++;
+ clear_manual_compaction_request(mcr.mc_id, false);
+ RDB_MUTEX_LOCK_CHECK(m_signal_mutex);
+ }
+ clear_all_manual_compaction_requests();
+ DBUG_ASSERT(m_requests.empty());
+ RDB_MUTEX_UNLOCK_CHECK(m_signal_mutex);
+ mysql_mutex_destroy(&m_mc_mutex);
+}
+
+void Rdb_manual_compaction_thread::clear_all_manual_compaction_requests() {
+ RDB_MUTEX_LOCK_CHECK(m_mc_mutex);
+ m_requests.clear();
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+}
+
+void Rdb_manual_compaction_thread::clear_manual_compaction_request(
+ int mc_id, bool init_only) {
+ bool erase = true;
+ RDB_MUTEX_LOCK_CHECK(m_mc_mutex);
+ auto it = m_requests.find(mc_id);
+ if (it != m_requests.end()) {
+ if (init_only) {
+ Manual_compaction_request mcr = it->second;
+ if (mcr.state != Manual_compaction_request::INITED) {
+ erase = false;
+ }
+ }
+ if (erase) {
+ m_requests.erase(it);
+ }
+ } else {
+ // Current code path guarantees that erasing by the same mc_id happens
+ // at most once. INITED state may be erased by a thread that requested
+ // the compaction. RUNNING state is erased by mc thread only.
+ DBUG_ASSERT(0);
+ }
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+}
+
+int Rdb_manual_compaction_thread::request_manual_compaction(
+ rocksdb::ColumnFamilyHandle *cf, rocksdb::Slice *start,
+ rocksdb::Slice *limit, int concurrency) {
+ int mc_id = -1;
+ RDB_MUTEX_LOCK_CHECK(m_mc_mutex);
+ if (m_requests.size() >= rocksdb_max_manual_compactions) {
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+ return mc_id;
+ }
+ Manual_compaction_request mcr;
+ mc_id = mcr.mc_id = ++m_latest_mc_id;
+ mcr.state = Manual_compaction_request::INITED;
+ mcr.cf = cf;
+ mcr.start = start;
+ mcr.limit = limit;
+ mcr.concurrency = concurrency;
+ m_requests.insert(std::make_pair(mcr.mc_id, mcr));
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+ return mc_id;
+}
+
+bool Rdb_manual_compaction_thread::is_manual_compaction_finished(int mc_id) {
+ bool finished = false;
+ RDB_MUTEX_LOCK_CHECK(m_mc_mutex);
+ if (m_requests.count(mc_id) == 0) {
+ finished = true;
+ }
+ RDB_MUTEX_UNLOCK_CHECK(m_mc_mutex);
+ return finished;
+}
+
+bool ha_rocksdb::check_bloom_and_set_bounds(
+ THD *thd, const Rdb_key_def &kd, const rocksdb::Slice &eq_cond,
+ const bool use_all_keys, size_t bound_len, uchar *const lower_bound,
+ uchar *const upper_bound, rocksdb::Slice *lower_bound_slice,
+ rocksdb::Slice *upper_bound_slice) {
bool can_use_bloom = can_use_bloom_filter(thd, kd, eq_cond, use_all_keys);
if (!can_use_bloom) {
- setup_iterator_bounds(kd, eq_cond,
- lower_bound_buf, upper_bound_buf,
- out_lower_bound, out_upper_bound);
+ setup_iterator_bounds(kd, eq_cond, bound_len, lower_bound, upper_bound,
+ lower_bound_slice, upper_bound_slice);
}
return can_use_bloom;
}
@@ -12933,7 +13537,6 @@ void rdb_update_global_stats(const operation_type &type, uint count,
int rdb_get_table_perf_counters(const char *const tablename,
Rdb_perf_counters *const counters) {
- DBUG_ASSERT(counters != nullptr);
DBUG_ASSERT(tablename != nullptr);
Rdb_table_handler *table_handler;
@@ -12973,10 +13576,7 @@ const char *get_rdb_io_error_string(const RDB_IO_ERROR_TYPE err_type) {
// so that we can capture as much data as possible to debug the root cause
// more efficiently.
#ifdef __GNUC__
-#pragma GCC push_options
-#pragma GCC optimize("O0")
#endif
-
void rdb_handle_io_error(const rocksdb::Status status,
const RDB_IO_ERROR_TYPE err_type) {
if (status.IsIOError()) {
@@ -12991,6 +13591,9 @@ void rdb_handle_io_error(const rocksdb::Status status,
}
case RDB_IO_ERROR_BG_THREAD: {
rdb_log_status_error(status, "BG thread failed to write to RocksDB");
+ /* NO_LINT_DEBUG */
+ sql_print_error("MyRocks: aborting on BG write error.");
+ abort();
break;
}
case RDB_IO_ERROR_GENERAL: {
@@ -13026,9 +13629,7 @@ void rdb_handle_io_error(const rocksdb::Status status,
}
}
#ifdef __GNUC__
-#pragma GCC pop_options
#endif
-
Rdb_dict_manager *rdb_get_dict_manager(void) { return &dict_manager; }
Rdb_ddl_manager *rdb_get_ddl_manager(void) { return &ddl_manager; }
@@ -13329,6 +13930,42 @@ static void rocksdb_set_wal_bytes_per_sync(
RDB_MUTEX_UNLOCK_CHECK(rdb_sysvars_mutex);
}
+/*
+ Validating and updating block cache size via sys_var::check path.
+ SetCapacity may take seconds when reducing block cache, and
+ sys_var::update holds LOCK_global_system_variables mutex, so
+ updating block cache size is done at check path instead.
+*/
+static int rocksdb_validate_set_block_cache_size(
+ THD *thd MY_ATTRIBUTE((__unused__)),
+ struct st_mysql_sys_var *const var MY_ATTRIBUTE((__unused__)),
+ void *var_ptr, struct st_mysql_value *value) {
+ DBUG_ASSERT(value != nullptr);
+
+ long long new_value;
+
+ /* value is NULL */
+ if (value->val_int(value, &new_value)) {
+ return HA_EXIT_FAILURE;
+ }
+
+ if (new_value < RDB_MIN_BLOCK_CACHE_SIZE ||
+ (uint64_t)new_value > (uint64_t)LONGLONG_MAX) {
+ return HA_EXIT_FAILURE;
+ }
+
+ RDB_MUTEX_LOCK_CHECK(rdb_block_cache_resize_mutex);
+ const rocksdb::BlockBasedTableOptions &table_options =
+ rdb_get_table_options();
+
+ if (rocksdb_block_cache_size != new_value && table_options.block_cache) {
+ table_options.block_cache->SetCapacity(new_value);
+ }
+ *static_cast<int64_t *>(var_ptr) = static_cast<int64_t>(new_value);
+ RDB_MUTEX_UNLOCK_CHECK(rdb_block_cache_resize_mutex);
+ return HA_EXIT_SUCCESS;
+}
+
static int
rocksdb_validate_update_cf_options(THD * /* unused */,
struct st_mysql_sys_var * /*unused*/,
@@ -13510,6 +14147,13 @@ double ha_rocksdb::read_time(uint index, uint ranges, ha_rows rows) {
DBUG_RETURN((rows / 20.0) + 1);
}
+void ha_rocksdb::print_error(int error, myf errflag) {
+ if (error == HA_ERR_ROCKSDB_STATUS_BUSY) {
+ error = HA_ERR_LOCK_DEADLOCK;
+ }
+ handler::print_error(error, errflag);
+}
+
std::string rdb_corruption_marker_file_name() {
std::string ret(rocksdb_datadir);
ret.append("/ROCKSDB_CORRUPTED");
@@ -13572,7 +14216,7 @@ maria_declare_plugin(rocksdb_se){
myrocks::rdb_i_s_perf_context, myrocks::rdb_i_s_perf_context_global,
myrocks::rdb_i_s_cfoptions, myrocks::rdb_i_s_compact_stats,
myrocks::rdb_i_s_global_info, myrocks::rdb_i_s_ddl,
- myrocks::rdb_i_s_index_file_map, myrocks::rdb_i_s_lock_info,
- myrocks::rdb_i_s_trx_info,
+ myrocks::rdb_i_s_sst_props, myrocks::rdb_i_s_index_file_map,
+ myrocks::rdb_i_s_lock_info, myrocks::rdb_i_s_trx_info,
myrocks::rdb_i_s_deadlock_info
maria_declare_plugin_end;
diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h
index 5bf473a2fb0..9b3352594d9 100644
--- a/storage/rocksdb/ha_rocksdb.h
+++ b/storage/rocksdb/ha_rocksdb.h
@@ -107,6 +107,7 @@ struct Rdb_deadlock_info {
std::string table_name;
};
std::vector <Rdb_dl_trx_info> path;
+ int64_t deadlock_time;
ulonglong victim_trx_id;
};
@@ -148,6 +149,11 @@ const char *const BG_THREAD_NAME = "myrocks-bg";
const char *const INDEX_THREAD_NAME = "myrocks-index";
/*
+ Name for the manual compaction thread.
+*/
+const char *const MANUAL_COMPACTION_THREAD_NAME = "myrocks-mc";
+
+/*
Separator between partition name and the qualifier. Sample usage:
- p0_cfname=foo
@@ -503,6 +509,12 @@ class ha_rocksdb : public my_core::handler {
const rocksdb::Snapshot *m_scan_it_snapshot;
+ /* Buffers used for upper/lower bounds for m_scan_it. */
+ uchar *m_scan_it_lower_bound;
+ uchar *m_scan_it_upper_bound;
+ rocksdb::Slice m_scan_it_lower_bound_slice;
+ rocksdb::Slice m_scan_it_upper_bound_slice;
+
Rdb_tbl_def *m_tbl_def;
/* Primary Key encoder from KeyTupleFormat to StorageFormat */
@@ -566,12 +578,6 @@ class ha_rocksdb : public my_core::handler {
uchar *m_dup_sk_packed_tuple;
uchar *m_dup_sk_packed_tuple_old;
- /* Buffers used for passing upper/bound eq conditions. */
- uchar *m_eq_cond_lower_bound;
- uchar *m_eq_cond_upper_bound;
- rocksdb::Slice m_eq_cond_lower_bound_slice;
- rocksdb::Slice m_eq_cond_upper_bound_slice;
-
/*
Temporary space for packing VARCHARs (we provide it to
pack_record()/pack_index_tuple() calls).
@@ -653,21 +659,20 @@ class ha_rocksdb : public my_core::handler {
enum ha_rkey_function find_flag) const
MY_ATTRIBUTE((__nonnull__, __warn_unused_result__));
void setup_iterator_bounds(const Rdb_key_def &kd,
- const rocksdb::Slice &eq_cond,
- uchar *lower_bound_buf,
- uchar *upper_bound_buf,
- rocksdb::Slice *out_lower_bound,
- rocksdb::Slice *out_upper_bound);
+ const rocksdb::Slice &eq_cond, size_t bound_len,
+ uchar *const lower_bound, uchar *const upper_bound,
+ rocksdb::Slice *lower_bound_slice,
+ rocksdb::Slice *upper_bound_slice);
bool can_use_bloom_filter(THD *thd, const Rdb_key_def &kd,
const rocksdb::Slice &eq_cond,
const bool use_all_keys);
bool check_bloom_and_set_bounds(THD *thd, const Rdb_key_def &kd,
const rocksdb::Slice &eq_cond,
- const bool use_all_keys,
- uchar *lower_bound_buf,
- uchar *upper_bound_buf,
- rocksdb::Slice *out_lower_bound,
- rocksdb::Slice *out_upper_bound);
+ const bool use_all_keys, size_t bound_len,
+ uchar *const lower_bound,
+ uchar *const upper_bound,
+ rocksdb::Slice *lower_bound_slice,
+ rocksdb::Slice *upper_bound_slice);
void setup_scan_iterator(const Rdb_key_def &kd, rocksdb::Slice *slice,
const bool use_all_keys, const uint eq_cond_len)
MY_ATTRIBUTE((__nonnull__));
@@ -1053,6 +1058,7 @@ public:
}
virtual double read_time(uint, uint, ha_rows rows) override;
+ virtual void print_error(int error, myf errflag) override;
int open(const char *const name, int mode, uint test_if_locked) override
MY_ATTRIBUTE((__warn_unused_result__));
@@ -1167,8 +1173,8 @@ private:
MY_ATTRIBUTE((__nonnull__));
int compare_key_parts(const KEY *const old_key,
- const KEY *const new_key) const;
- MY_ATTRIBUTE((__nonnull__, __warn_unused_result__));
+ const KEY *const new_key) const
+ MY_ATTRIBUTE((__nonnull__, __warn_unused_result__));
int compare_keys(const KEY *const old_key, const KEY *const new_key) const
MY_ATTRIBUTE((__nonnull__, __warn_unused_result__));
@@ -1223,7 +1229,7 @@ private:
int update_pk(const Rdb_key_def &kd, const struct update_row_info &row_info,
const bool &pk_changed) MY_ATTRIBUTE((__warn_unused_result__));
int update_sk(const TABLE *const table_arg, const Rdb_key_def &kd,
- const struct update_row_info &row_info)
+ const struct update_row_info &row_info, const bool bulk_load_sk)
MY_ATTRIBUTE((__warn_unused_result__));
int update_indexes(const struct update_row_info &row_info,
const bool &pk_changed)
@@ -1277,7 +1283,9 @@ private:
int finalize_bulk_load(bool print_client_error = true)
MY_ATTRIBUTE((__warn_unused_result__));
-public:
+ int calculate_stats_for_table() MY_ATTRIBUTE((__warn_unused_result__));
+
+ public:
int index_init(uint idx, bool sorted) override
MY_ATTRIBUTE((__warn_unused_result__));
int index_end() override MY_ATTRIBUTE((__warn_unused_result__));
@@ -1370,9 +1378,6 @@ public:
MY_ATTRIBUTE((__warn_unused_result__));
int analyze(THD *const thd, HA_CHECK_OPT *const check_opt) override
MY_ATTRIBUTE((__warn_unused_result__));
- int calculate_stats(const TABLE *const table_arg, THD *const thd,
- HA_CHECK_OPT *const check_opt)
- MY_ATTRIBUTE((__warn_unused_result__));
enum_alter_inplace_result check_if_supported_inplace_alter(
TABLE *altered_table,
@@ -1402,7 +1407,7 @@ public:
virtual void rpl_after_delete_rows() override;
virtual void rpl_before_update_rows() override;
virtual void rpl_after_update_rows() override;
- virtual bool use_read_free_rpl();
+ virtual bool use_read_free_rpl() override;
#endif // MARIAROCKS_NOT_YET
private:
diff --git a/storage/rocksdb/ha_rocksdb_proto.h b/storage/rocksdb/ha_rocksdb_proto.h
index 85c3968cc99..deb65edddd3 100644
--- a/storage/rocksdb/ha_rocksdb_proto.h
+++ b/storage/rocksdb/ha_rocksdb_proto.h
@@ -39,7 +39,12 @@ enum RDB_IO_ERROR_TYPE {
const char *get_rdb_io_error_string(const RDB_IO_ERROR_TYPE err_type);
void rdb_handle_io_error(const rocksdb::Status status,
- const RDB_IO_ERROR_TYPE err_type);
+ const RDB_IO_ERROR_TYPE err_type)
+#if defined(__clang__)
+ MY_ATTRIBUTE((optnone));
+#else
+ MY_ATTRIBUTE((optimize("O0")));
+#endif
int rdb_normalize_tablename(const std::string &tablename, std::string *str)
MY_ATTRIBUTE((__nonnull__, __warn_unused_result__));
diff --git a/storage/rocksdb/mysql-test/rocksdb/combinations b/storage/rocksdb/mysql-test/rocksdb/combinations
new file mode 100644
index 00000000000..d49de3d38b3
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/combinations
@@ -0,0 +1,6 @@
+[write_committed]
+loose-rocksdb_write_policy=write_committed
+
+[write_prepared]
+loose-rocksdb_write_policy=write_prepared
+loose-rocksdb_commit_time_batch_for_recovery=on
diff --git a/storage/rocksdb/mysql-test/rocksdb/include/have_write_committed.inc b/storage/rocksdb/mysql-test/rocksdb/include/have_write_committed.inc
new file mode 100644
index 00000000000..681b966f680
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/include/have_write_committed.inc
@@ -0,0 +1,3 @@
+if (`select count(*) = 0 from information_schema.session_variables where variable_name = 'rocksdb_write_policy' and variable_value = 'write_committed';`) {
+ --skip Test requires write_committed policy
+}
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result
index 6325dc97cf5..32c0537c780 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace.result
@@ -299,11 +299,13 @@ connection con1;
show global variables like 'rocksdb_bulk_load%';
Variable_name Value
rocksdb_bulk_load ON
+rocksdb_bulk_load_allow_sk OFF
rocksdb_bulk_load_allow_unsorted OFF
rocksdb_bulk_load_size 1000
show session variables like 'rocksdb_bulk_load%';
Variable_name Value
rocksdb_bulk_load ON
+rocksdb_bulk_load_allow_sk OFF
rocksdb_bulk_load_allow_unsorted OFF
rocksdb_bulk_load_size 1000
CREATE TABLE t1 (i INT, j INT, PRIMARY KEY (i)) ENGINE = ROCKSDB;
@@ -356,6 +358,7 @@ SET session rocksdb_merge_buf_size = 340;
show variables like 'rocksdb_bulk_load%';
Variable_name Value
rocksdb_bulk_load OFF
+rocksdb_bulk_load_allow_sk OFF
rocksdb_bulk_load_allow_unsorted OFF
rocksdb_bulk_load_size 1000
CREATE TABLE t1 (a VARCHAR(80)) ENGINE=RocksDB;
@@ -463,3 +466,24 @@ t1 CREATE TABLE `t1` (
KEY `kb` (`b`(8))
) ENGINE=ROCKSDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
DROP TABLE t1;
+SET @prior_rocksdb_table_stats_sampling_pct = @@rocksdb_table_stats_sampling_pct;
+set global rocksdb_table_stats_sampling_pct = 100;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY ka(a)) ENGINE=RocksDB;
+INSERT INTO t1 (a, b) VALUES (1, 10);
+INSERT INTO t1 (a, b) VALUES (2, 10);
+INSERT INTO t1 (a, b) VALUES (3, 20);
+INSERT INTO t1 (a, b) VALUES (4, 20);
+set global rocksdb_force_flush_memtable_now=1;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+SHOW INDEX in t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+t1 0 PRIMARY 1 a A 4 NULL NULL LSMTREE
+ALTER TABLE t1 ADD INDEX kb(b), ALGORITHM=INPLACE;
+SHOW INDEX in t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+t1 0 PRIMARY 1 a A 4 NULL NULL LSMTREE
+t1 1 kb 1 b A 2 NULL NULL YES LSMTREE
+DROP TABLE t1;
+SET global rocksdb_table_stats_sampling_pct = @prior_rocksdb_table_stats_sampling_pct;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace_sstfilewriter.result b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace_sstfilewriter.result
index 08f2329f688..0617232f1e3 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace_sstfilewriter.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/add_index_inplace_sstfilewriter.result
@@ -17,7 +17,7 @@ ALTER TABLE t1 ADD INDEX kb(b), ALGORITHM=INPLACE;
set @tmp= @@rocksdb_max_row_locks;
set session rocksdb_max_row_locks=1000;
ALTER TABLE t1 ADD INDEX kb_copy(b), ALGORITHM=COPY;
-ERROR HY000: Status error 10 received from RocksDB: Operation aborted: Failed to acquire lock due to max_num_locks limit
+ERROR HY000: Got error 10 'Operation aborted: Failed to acquire lock due to max_num_locks limit' from ROCKSDB
set session rocksdb_bulk_load=1;
ALTER TABLE t1 ADD INDEX kb_copy(b), ALGORITHM=COPY;
set session rocksdb_bulk_load=0;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result
index fe08cd7c361..604e5572eab 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result
@@ -59,12 +59,10 @@ insert into t values ();
set debug_dbug="+d,crash_commit_before";
commit;
ERROR HY000: Lost connection to MySQL server during query
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-table_schema table_name auto_increment
-test t 4
-select max(i) from t;
-max(i)
-3
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
+table_schema table_name auto_increment > @row_max
+test t 1
# After engine prepare
begin;
insert into t values ();
@@ -72,12 +70,10 @@ insert into t values ();
set debug_dbug="+d,crash_commit_after_prepare";
commit;
ERROR HY000: Lost connection to MySQL server during query
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-table_schema table_name auto_increment
-test t 4
-select max(i) from t;
-max(i)
-3
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
+table_schema table_name auto_increment > @row_max
+test t 1
# After binlog
begin;
insert into t values ();
@@ -85,12 +81,10 @@ insert into t values ();
set debug_dbug="+d,crash_commit_after_log";
commit;
ERROR HY000: Lost connection to MySQL server during query
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-table_schema table_name auto_increment
-test t 6
-select max(i) from t;
-max(i)
-5
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
+table_schema table_name auto_increment > @row_max
+test t 1
# After everything
begin;
insert into t values ();
@@ -98,10 +92,8 @@ insert into t values ();
set debug_dbug="+d,crash_commit_after";
commit;
ERROR HY000: Lost connection to MySQL server during query
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-table_schema table_name auto_increment
-test t 8
-select max(i) from t;
-max(i)
-7
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
+table_schema table_name auto_increment > @row_max
+test t 1
drop table t;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars.result b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars.result
index 8cc9b070a70..f59b841a595 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_vars.result
@@ -150,3 +150,29 @@ CREATE TABLE t0(c0 BLOB) ENGINE=ROCKSDB;
INSERT INTO t0 VALUES(0);
ALTER TABLE t0 AUTO_INCREMENT=0;
DROP TABLE t0;
+#---------------------------------------------------------------
+# MDEV-16703 Assertion failed in load_auto_incr_value_from_index
+#---------------------------------------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT, a INT, PRIMARY KEY(pk)) ENGINE=RocksDB;
+INSERT INTO t1 (a) VALUES (1);
+UPDATE t1 SET pk = 3;
+ALTER TABLE t1 AUTO_INCREMENT 2;
+DROP TABLE t1;
+#----------------------------------
+# Issue #792 Crash in autoincrement
+#----------------------------------
+CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY,C2 CHAR) ENGINE=ROCKSDB;
+INSERT INTO t1 VALUES(2177,0);
+DROP TABLE t1;
+CREATE TABLE t0(c0 BLOB) ENGINE=ROCKSDB;
+INSERT INTO t0 VALUES(0);
+ALTER TABLE t0 AUTO_INCREMENT=0;
+DROP TABLE t0;
+#----------------------------------
+# Issue #869 Crash in autoincrement
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT, a INT, PRIMARY KEY(pk)) ENGINE=RocksDB;
+INSERT INTO t1 (a) VALUES (1);
+UPDATE t1 SET pk = 3;
+ALTER TABLE t1 AUTO_INCREMENT 2;
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/bloomfilter_bulk_load.result b/storage/rocksdb/mysql-test/rocksdb/r/bloomfilter_bulk_load.result
new file mode 100644
index 00000000000..4b02d1103cf
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/bloomfilter_bulk_load.result
@@ -0,0 +1,15 @@
+create table r1 (id bigint primary key, value bigint) engine=rocksdb;
+create table r2 (id bigint, value bigint, primary key (id) comment 'cf2') engine=rocksdb;
+set session rocksdb_bulk_load=1;
+set session rocksdb_bulk_load=0;
+select variable_value into @h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+insert into r1 values (100, 100);
+select variable_value-@h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+variable_value-@h
+1
+select variable_value into @h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+insert into r2 values (100, 100);
+select variable_value-@h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+variable_value-@h
+0
+DROP TABLE r1, r2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_sk.result b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_sk.result
new file mode 100644
index 00000000000..42f820a2a42
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/bulk_load_sk.result
@@ -0,0 +1,229 @@
+SET rocksdb_bulk_load_size=15;
+CREATE TABLE t4 (a INT, b INT, c INT,
+PRIMARY KEY (a),
+KEY (b),
+KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t3 (a INT, b INT, c INT,
+PRIMARY KEY (a),
+KEY (b),
+KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t2 (a INT, b INT, c INT,
+PRIMARY KEY (a),
+KEY (b),
+KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t1 (a INT, b INT, c INT,
+PRIMARY KEY (a),
+KEY (b),
+KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+SET rocksdb_bulk_load=1;
+INSERT INTO t1 SELECT * FROM t3 FORCE INDEX (PRIMARY) ORDER BY a;
+SELECT count(*) FROM t1 FORCE INDEX (PRIMARY);
+count(*)
+0
+SELECT count(*) FROM t1 FORCE INDEX (b);
+count(*)
+10
+SELECT count(*) FROM t1 FORCE INDEX (c);
+count(*)
+10
+SET rocksdb_bulk_load=0;
+SELECT * FROM t1 FORCE INDEX (PRIMARY);
+a b c
+-9 11 11
+-7 9 9
+-5 7 7
+-3 5 5
+-1 3 3
+2 0 0
+4 -2 -2
+6 -4 -4
+8 -6 -6
+10 -8 -8
+SELECT b FROM t1 FORCE INDEX (b);
+b
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+SELECT c FROM t1 FORCE INDEX (c);
+c
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+Checksums should match
+CHECKSUM TABLE t3;
+Table Checksum
+test.t3 3862424802
+CHECKSUM TABLE t1;
+Table Checksum
+test.t1 3862424802
+SET rocksdb_bulk_load_allow_sk=1;
+SET rocksdb_bulk_load=1;
+INSERT INTO t4 SELECT * FROM t3 FORCE INDEX (PRIMARY) ORDER BY a;
+SELECT count(*) FROM t4 FORCE INDEX (PRIMARY);
+count(*)
+0
+SELECT count(*) FROM t4 FORCE INDEX (b);
+count(*)
+0
+SELECT count(*) FROM t4 FORCE INDEX (c);
+count(*)
+0
+SET rocksdb_bulk_load=0;
+SELECT * FROM t4 FORCE INDEX (PRIMARY);
+a b c
+-9 11 11
+-7 9 9
+-5 7 7
+-3 5 5
+-1 3 3
+2 0 0
+4 -2 -2
+6 -4 -4
+8 -6 -6
+10 -8 -8
+SELECT b FROM t4 FORCE INDEX (b);
+b
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+SELECT c FROM t4 FORCE INDEX (c);
+c
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+Checksums should match
+CHECKSUM TABLE t3;
+Table Checksum
+test.t3 3862424802
+CHECKSUM TABLE t4;
+Table Checksum
+test.t4 3862424802
+SET rocksdb_bulk_load_allow_unsorted=1;
+SET rocksdb_bulk_load_allow_sk=1;
+SET rocksdb_bulk_load=1;
+INSERT INTO t2 SELECT * FROM t3 WHERE b >= 0 ORDER BY b;
+INSERT INTO t2 SELECT * FROM t3 WHERE b < 0 ORDER BY b;
+SELECT count(*) FROM t2 FORCE INDEX (PRIMARY);
+count(*)
+0
+SELECT count(*) FROM t2 FORCE INDEX (b);
+count(*)
+0
+SELECT count(*) FROM t2 FORCE INDEX (c);
+count(*)
+0
+SELECT count(*) FROM t2 FORCE INDEX (PRIMARY);
+count(*)
+0
+SELECT count(*) FROM t2 FORCE INDEX (b);
+count(*)
+0
+SELECT count(*) FROM t2 FORCE INDEX (c);
+count(*)
+0
+SET rocksdb_bulk_load=0;
+SELECT * FROM t2 FORCE INDEX (PRIMARY);
+a b c
+-19 21 21
+-17 19 19
+-15 17 17
+-13 15 15
+-11 13 13
+-9 11 11
+-7 9 9
+-5 7 7
+-3 5 5
+-1 3 3
+2 0 0
+4 -2 -2
+6 -4 -4
+8 -6 -6
+10 -8 -8
+12 -10 -10
+14 -12 -12
+16 -14 -14
+18 -16 -16
+20 -18 -18
+SELECT b FROM t2 FORCE INDEX (b);
+b
+-18
+-16
+-14
+-12
+-10
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+13
+15
+17
+19
+21
+SELECT c FROM t2 FORCE INDEX (c);
+c
+-18
+-16
+-14
+-12
+-10
+-8
+-6
+-4
+-2
+0
+3
+5
+7
+9
+11
+13
+15
+17
+19
+21
+Checksums should match
+CHECKSUM TABLE t3;
+Table Checksum
+test.t3 1495594118
+CHECKSUM TABLE t2;
+Table Checksum
+test.t2 1495594118
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/cardinality.result b/storage/rocksdb/mysql-test/rocksdb/r/cardinality.result
index 4b201d523d9..d037c636a16 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/cardinality.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/cardinality.result
@@ -82,4 +82,19 @@ t1 1 t1_5 2 c1 A 100000 NULL NULL YES LSMTREE
SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema = DATABASE();
table_name table_rows
t1 100000
-drop table t1;
+CREATE TABLE t2 (a INT, b INT, c INT, d INT, e INT, f INT, g INT,
+PRIMARY KEY (a), KEY (c, b, a, d, e, f, g))
+ENGINE=ROCKSDB;
+SET GLOBAL rocksdb_force_flush_memtable_now = 1;
+ANALYZE TABLE t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status OK
+cardinality of the columns after 'a' must be equal to the cardinality of column 'a'
+SELECT CARDINALITY INTO @c FROM information_schema.statistics WHERE TABLE_NAME='t2' AND INDEX_NAME='c' AND COLUMN_NAME='a';
+SELECT COLUMN_NAME, CARDINALITY = @c FROM information_schema.statistics WHERE TABLE_NAME='t2' AND INDEX_NAME='c' AND SEQ_IN_INDEX > 3;
+COLUMN_NAME CARDINALITY = @c
+d 1
+e 1
+f 1
+g 1
+drop table t1, t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/collation.result b/storage/rocksdb/mysql-test/rocksdb/r/collation.result
index e372cbe2109..10e0d9b0002 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/collation.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/collation.result
@@ -1,6 +1,7 @@
-SET @start_global_value = @@global.ROCKSDB_STRICT_COLLATION_EXCEPTIONS;
-DROP TABLE IF EXISTS t1;
+call mtr.add_suppression("Invalid pattern");
CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text) engine=rocksdb charset utf8;
+ALTER TABLE t1 ADD INDEX (value);
+ERROR HY000: Unsupported collation on string indexed column test.t1.value Use binary collation (binary, latin1_bin, utf8_bin).
DROP TABLE t1;
CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text, index(value)) engine=rocksdb charset utf8;
ERROR HY000: Unsupported collation on string indexed column test.t1.value Use binary collation (latin1_bin, binary, utf8_bin).
@@ -13,6 +14,7 @@ SET GLOBAL rocksdb_strict_collation_check=1;
CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text, index(value2)) engine=rocksdb charset utf8;
DROP TABLE t1;
CREATE TABLE t1 (id varchar(20), value varchar(50), value2 varchar(50), value3 text, primary key (id), index(value, value2)) engine=rocksdb charset latin1 collate latin1_bin;
+ALTER TABLE t1 collate=latin1_general_ci;
DROP TABLE t1;
CREATE TABLE t1 (id varchar(20), value varchar(50), value2 varchar(50), value3 text, primary key (id), index(value, value2)) engine=rocksdb charset utf8 collate utf8_bin;
DROP TABLE t1;
@@ -127,4 +129,16 @@ CREATE TABLE abcd (id INT PRIMARY KEY, value varchar(50), index(value)) engine=r
ERROR HY000: Unsupported collation on string indexed column test.abcd.value Use binary collation (latin1_bin, binary, utf8_bin).
DROP TABLE abc;
SET GLOBAL rocksdb_strict_collation_exceptions=null;
-SET GLOBAL rocksdb_strict_collation_exceptions=@start_global_value;
+SET GLOBAL rocksdb_strict_collation_check=1;
+CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text, index(value)) engine=rocksdb charset utf8;
+Warnings:
+Warning 1210 Unsupported collation on string indexed column test.t1.value Use binary collation (binary, latin1_bin, utf8_bin).
+DROP TABLE t1;
+CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text) engine=rocksdb charset utf8;
+ALTER TABLE t1 ADD INDEX (value);
+Warnings:
+Warning 1210 Unsupported collation on string indexed column test.t1.value Use binary collation (binary, latin1_bin, utf8_bin).
+DROP TABLE t1;
+CREATE TABLE t1 (id varchar(20), value varchar(50), value2 varchar(50), value3 text, primary key (id), index(value, value2)) engine=rocksdb charset latin1 collate latin1_bin;
+ALTER TABLE t1 collate=latin1_general_ci;
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/com_rpc_tx.result b/storage/rocksdb/mysql-test/rocksdb/r/com_rpc_tx.result
new file mode 100644
index 00000000000..789ce12e900
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/com_rpc_tx.result
@@ -0,0 +1,21 @@
+CREATE DATABASE db_rpc;
+USE db_rpc;
+CREATE TABLE t1(pk INT PRIMARY KEY) ENGINE=rocksdb;
+SET GLOBAL rocksdb_enable_2pc=1;
+SET autocommit = 0;
+SET autocommit = 0;
+BEGIN;
+BEGIN;
+SELECT * from t1;
+pk
+SELECT * from t1;
+pk
+INSERT INTO t1 VALUES(1);
+INSERT INTO t1 VALUES(2);
+COMMIT;
+COMMIT;
+SELECT * from db_rpc.t1;
+pk
+1
+2
+DROP DATABASE db_rpc;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/create_no_primary_key_table.result b/storage/rocksdb/mysql-test/rocksdb/r/create_no_primary_key_table.result
new file mode 100644
index 00000000000..e5aeb57ebdf
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/create_no_primary_key_table.result
@@ -0,0 +1,38 @@
+USE mysql;
+CREATE TABLE mysql_table (a INT) ENGINE=ROCKSDB;
+CREATE TABLE test.mysql_table (a INT) ENGINE=ROCKSDB;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+USE test;
+CREATE TABLE mysql_table (a INT) ENGINE=ROCKSDB;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+CREATE TABLE IF NOT EXISTS mysql_table_2 (a INT) ENGINE=ROCKSDB;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+CREATE TABLE mysql_table_no_cols ENGINE=ROCKSDB;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+CREATE TABLE mysql.mysql_table_2 (a INT) ENGINE=ROCKSDB;
+CREATE TABLE mysql_primkey (a INT PRIMARY KEY, b INT, c INT, d INT, INDEX (c)) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey DROP b, DROP a, ADD (f INT PRIMARY KEY);
+ALTER TABLE mysql_primkey DROP PRIMARY KEY;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+CREATE TABLE mysql_primkey2 (a INT PRIMARY KEY, b INT, c INT) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey2 DROP b;
+ALTER TABLE mysql_primkey2 ADD (b INT);
+ALTER TABLE mysql_primkey2 DROP c, DROP A;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+CREATE TABLE mysql_primkey3 (a INT PRIMARY KEY, b INT, c INT, INDEX indexonb (b), INDEX indexonc (c)) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey3 DROP INDEX indexonb;
+ALTER TABLE mysql_primkey3 DROP c;
+ALTER TABLE mysql_primkey3 DROP PRIMARY KEY, ADD PRIMARY KEY(b);
+CREATE TABLE mysql_primkey4(a INT, b INT, PRIMARY KEY(a), INDEX si (a, b)) ENGINE=ROCKSDB;
+DROP INDEX si ON mysql_primkey4;
+DROP INDEX `PRIMARY` ON mysql_primkey4;
+ERROR HY000: Table without primary key cannot be created outside mysql schema.
+ALTER TABLE mysql.mysql_table ADD PRIMARY KEY (a);
+ALTER TABLE mysql.mysql_table DROP PRIMARY KEY;
+DROP TABLE mysql_primkey;
+DROP TABLE mysql_primkey2;
+DROP TABLE mysql_primkey3;
+DROP TABLE mysql_primkey4;
+USE mysql;
+DROP TABLE mysql_table;
+DROP TABLE mysql_table_2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/ddl_high_priority.result b/storage/rocksdb/mysql-test/rocksdb/r/ddl_high_priority.result
index 39130475349..50733f81598 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/ddl_high_priority.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/ddl_high_priority.result
@@ -45,7 +45,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
alter table t1 modify i bigint;;
set high_priority_ddl = 0;
@@ -98,7 +98,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
alter table t1 rename t1_new;;
set high_priority_ddl = 0;
@@ -152,7 +152,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
drop table t1;;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
@@ -202,7 +202,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
drop table t1;;
set high_priority_ddl = 0;
@@ -251,7 +251,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
alter table t1 modify i bigint;;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
@@ -302,7 +302,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
create index idx1 on t1 (i);;
set high_priority_ddl = 0;
@@ -342,7 +342,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
drop index idx1 on t1;;
set high_priority_ddl = 0;
@@ -390,7 +390,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
truncate t1;;
set high_priority_ddl = 0;
@@ -438,7 +438,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
create trigger ins_sum before insert on t1 for each row set @sum = @sum + new.i;;
set high_priority_ddl = 0;
@@ -478,7 +478,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
drop trigger ins_sum;;
set high_priority_ddl = 0;
@@ -528,7 +528,7 @@ set high_priority_ddl = 1;
select @@high_priority_ddl;
@@high_priority_ddl
1
-lock tables t1 write;
+rename table t1 to t2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
optimize table t1;;
Table Op Msg_type Msg_text
@@ -538,6 +538,55 @@ connection: default (for show processlist)
show processlist;
Id User Host db Command Time State Info Rows examined Rows sent Tid Srv_Id
<Id> root <Host> test <Command> <Time> <State> <Info> <RExam> <RSent> <TID> 0
+
+## Test parameters:
+## use_sys_var = 1;
+## con_block = con1
+## con_kill = default
+## cmd = lock tables t1 write;
+## high_priority_cmd = optimize high_priority table t1;
+## should_kill = 1
+## recreate_table = 1
+## throw_error = 1
+
+drop table if exists t1;
+create table t1 (i int);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `i` int(11) DEFAULT NULL
+) ENGINE=ROCKSDB DEFAULT CHARSET=latin1
+insert into t1 values (1), (2), (3);
+connection: con1
+lock tables t1 read;;
+connection: default
+set lock_wait_timeout = 0.02;
+set high_priority_lock_wait_timeout = 0.02;
+describe t1;
+Field Type Null Key Default Extra
+i int(11) YES NULL
+connection: default (for show processlist)
+# both con1 and default exist
+show processlist;
+Id User Host db Command Time State Info Rows examined Rows sent Tid Srv_Id
+<Id> root <Host> test <Command> <Time> <State> <Info> <RExam> <RSent> <TID> 0
+<Id> test_user1 <Host> test <Command> <Time> <State> <Info> <RExam> <RSent> <TID> 0
+connection: default
+lock tables t1 write;;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
+set high_priority_ddl = 1;
+select @@high_priority_ddl;
+@@high_priority_ddl
+1
+rename table t1 to t2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction: Timeout on table metadata: test.t1
+lock tables t1 write;;
+set high_priority_ddl = 0;
+connection: default (for show processlist)
+show processlist;
+Id User Host db Command Time State Info Rows examined Rows sent Tid Srv_Id
+<Id> root <Host> test <Command> <Time> <State> <Info> <RExam> <RSent> <TID> 0
+unlock tables;
drop user test_user1@localhost;
drop user test_user2@localhost;
drop table if exists t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/deadlock_tracking.result b/storage/rocksdb/mysql-test/rocksdb/r/deadlock_tracking.result
index 1e7509172cb..fffae916c12 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/deadlock_tracking.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/deadlock_tracking.result
@@ -53,6 +53,7 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -60,6 +61,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -102,6 +104,7 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -109,6 +112,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -120,6 +124,7 @@ TABLE NAME: test.t
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -127,6 +132,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -170,6 +176,7 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -177,6 +184,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -188,6 +196,7 @@ TABLE NAME: test.t
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -195,6 +204,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -206,6 +216,7 @@ TABLE NAME: test.t
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -213,6 +224,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -240,6 +252,7 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -247,6 +260,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -352,6 +366,7 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -359,6 +374,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: PRIMARY
TABLE NAME: test.t
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -373,6 +389,25 @@ TABLE NAME: test.t
END OF ROCKSDB TRANSACTION MONITOR OUTPUT
=========================================
+Deadlock #6
+create table t1 (id int primary key, value int) engine=rocksdb;
+insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
+begin;
+update t1 set value=value+100 where id=1;
+update t1 set value=value+100 where id=2;
+begin;
+update t1 set value=value+200 where id=3;
+update t1 set value=value+100 where id=3;
+update t1 set value=value+200 where id=1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+select * from t1;
+id value
+1 101
+2 102
+3 103
+4 4
+5 5
+drop table t1;
set global rocksdb_lock_wait_timeout = @prior_lock_wait_timeout;
set global rocksdb_deadlock_detect = @prior_deadlock_detect;
drop table t;
@@ -390,6 +425,27 @@ LIST OF SNAPSHOTS FOR EACH SESSION:
*** DEADLOCK PATH
=========================================
+TSTAMP
+TXN_ID
+COLUMN FAMILY NAME: default
+KEY
+LOCK TYPE: EXCLUSIVE
+INDEX NAME: NOT FOUND; IDX_ID
+TABLE NAME: NOT FOUND; IDX_ID
+---------------WAITING FOR---------------
+TSTAMP
+TXN_ID
+COLUMN FAMILY NAME: default
+KEY
+LOCK TYPE: EXCLUSIVE
+INDEX NAME: NOT FOUND; IDX_ID
+TABLE NAME: NOT FOUND; IDX_ID
+
+--------TXN_ID GOT DEADLOCK---------
+
+*** DEADLOCK PATH
+=========================================
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
@@ -397,6 +453,7 @@ LOCK TYPE: EXCLUSIVE
INDEX NAME: NOT FOUND; IDX_ID
TABLE NAME: NOT FOUND; IDX_ID
---------------WAITING FOR---------------
+TSTAMP
TXN_ID
COLUMN FAMILY NAME: default
KEY
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/drop_table.result b/storage/rocksdb/mysql-test/rocksdb/r/drop_table.result
index dba49d8ff41..4d20242f43e 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/drop_table.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/drop_table.result
@@ -45,6 +45,25 @@ DELETE FROM t4;
drop table t3;
DELETE FROM t1;
DELETE FROM t4;
+SET GLOBAL rocksdb_max_manual_compactions = 2;
+SET GLOBAL rocksdb_debug_manual_compaction_delay = 3600;
+connect con1, localhost, root,,;
+connect con2, localhost, root,,;
+connect con3, localhost, root,,;
+connection con1;
+SET GLOBAL rocksdb_compact_cf='cf1';
+connection con2;
+SET GLOBAL rocksdb_compact_cf='rev:cf2';
+connection default;
+select * from information_schema.global_status where variable_name='rocksdb_manual_compactions_running';
+VARIABLE_NAME VARIABLE_VALUE
+ROCKSDB_MANUAL_COMPACTIONS_RUNNING 1
+connection con3;
+SET GLOBAL rocksdb_compact_cf='cf1';
+ERROR HY000: Internal error: Can't schedule more manual compactions. Increase rocksdb_max_manual_compactions or stop issuing more manual compactions.
+SET GLOBAL rocksdb_compact_cf='rev:cf2';
+ERROR HY000: Internal error: Can't schedule more manual compactions. Increase rocksdb_max_manual_compactions or stop issuing more manual compactions.
+connection default;
drop table t4;
CREATE TABLE t5 (
a int not null,
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/explicit_snapshot.result b/storage/rocksdb/mysql-test/rocksdb/r/explicit_snapshot.result
new file mode 100644
index 00000000000..14f5ef65c59
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/explicit_snapshot.result
@@ -0,0 +1,265 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE T1 (a INT PRIMARY KEY AUTO_INCREMENT) ENGINE=ROCKSDB;
+INSERT INTO T1 VALUES();
+"con1: Creating explict snapshot"
+SELECT * FROM T1;
+a
+1
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+"con2: Attaching snapshot id 1"
+ATTACH EXPLICIT ROCKSDB SNAPSHOT 1;
+"con2: New row should not be visible"
+SELECT * FROM T1;
+a
+1
+"con2: Releasing snapshot"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con2: New row should be visible"
+SELECT * FROM T1;
+a
+1
+2
+"con1: New row should not be visible"
+SELECT * FROM T1;
+a
+1
+"con1: Releasing snapshot"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: New row should be visible"
+SELECT * FROM T1;
+a
+1
+2
+"con1: Starting shared snapshot"
+SELECT * FROM T1;
+a
+1
+2
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+3
+"con2: Starting existing snapshot"
+START TRANSACTION WITH EXISTING ROCKSDB SNAPSHOT 2;
+"con2: New row should not be visible"
+SELECT * FROM T1;
+a
+1
+2
+COMMIT;
+"con2: New row should be visible"
+SELECT * FROM T1;
+a
+1
+2
+3
+COMMIT;
+"con1: New row should be visible"
+SELECT * FROM T1;
+a
+1
+2
+3
+"con1: Creating explict snapshot"
+"con2: Trying to insert row"
+INSERT INTO T1 VALUES();
+ERROR HY000: Can't execute updates when an explicit snapshot is associated with the connection using CREATE|ATTACH EXPLICIT [ENGINE] SNAPSHOT
+"con2: Attaching existing snapshot"
+ATTACH EXPLICIT ROCKSDB SNAPSHOT 3;
+"con2: Trying to insert row"
+INSERT INTO T1 VALUES();
+ERROR HY000: Can't execute updates when an explicit snapshot is associated with the connection using CREATE|ATTACH EXPLICIT [ENGINE] SNAPSHOT
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: Starting shared snapshot"
+"con1: Trying to insert row"
+INSERT INTO T1 VALUES();
+ERROR HY000: Can't execute updates when you started a transaction with START TRANSACTION WITH CONSISTENT|SHARED|EXISTING [ROCKSDB] SNAPSHOT.
+"con2: Starting existing snapshot"
+START TRANSACTION WITH EXISTING ROCKSDB SNAPSHOT 4;
+"con2: Trying to insert row"
+INSERT INTO T1 VALUES();
+ERROR HY000: Can't execute updates when you started a transaction with START TRANSACTION WITH CONSISTENT|SHARED|EXISTING [ROCKSDB] SNAPSHOT.
+COMMIT;
+COMMIT;
+"con1: Creating explicit snapshot"
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+"con1: New row should not be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+"con1: Creating another explicit snapshot"
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: Now the new row should be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+"con1: Starting transaction with consistent snapshot"
+START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+"con1: The new row should not be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+"con1: Creating another explicit snapshot"
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: The new row should still not be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+"con1: Committing trx"
+COMMIT;
+"con1: The new row should now be seen because of the new explicit snapshot created above"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+"con1: Releasing explicit snapshot"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: Starting transaction with shared snapshot"
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+"con1: The new row should not be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+"con1: Starting another transaction with shared snapshot"
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+"con1: The new row should now be seen"
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+COMMIT;
+"con1: Creating explicit snapshot"
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+"con1: Releasing explicit snapshot"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: Releasing explicit snapshot again"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+ERROR HY000: Cannot process explicit snapshot
+"con1: Starting transaction with shared snapshot"
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+"con2: Inserting a row"
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+7
+"con1: Creating explicit snapshot"
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+SELECT * FROM T1;
+a
+1
+2
+3
+4
+5
+6
+"con1: Releasing explicit snapshot"
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+"con1: The new row should not be seen"
+SELECT* FROM T1;
+a
+1
+2
+3
+4
+5
+6
+COMMIT;
+DROP TABLE T1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/i_s_deadlock.result b/storage/rocksdb/mysql-test/rocksdb/r/i_s_deadlock.result
index 36db92095e9..3ec9294e3a1 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/i_s_deadlock.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/i_s_deadlock.result
@@ -14,6 +14,7 @@ show create table information_schema.rocksdb_deadlock;
Table Create Table
ROCKSDB_DEADLOCK CREATE TEMPORARY TABLE `ROCKSDB_DEADLOCK` (
`DEADLOCK_ID` bigint(8) NOT NULL DEFAULT 0,
+ `TIMESTAMP` bigint(8) NOT NULL DEFAULT 0,
`TRANSACTION_ID` bigint(8) NOT NULL DEFAULT 0,
`CF_NAME` varchar(193) NOT NULL DEFAULT '',
`WAITING_KEY` varchar(513) NOT NULL DEFAULT '',
@@ -25,7 +26,7 @@ ROCKSDB_DEADLOCK CREATE TEMPORARY TABLE `ROCKSDB_DEADLOCK` (
create table t (i int primary key) engine=rocksdb;
insert into t values (1), (2), (3);
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
Deadlock #1
connection con1;
begin;
@@ -49,9 +50,9 @@ i
rollback;
connection default;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
Deadlock #2
connection con1;
begin;
@@ -75,11 +76,11 @@ i
rollback;
connection default;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
set global rocksdb_max_latest_deadlocks = 10;
Deadlock #3
connection con1;
@@ -104,18 +105,18 @@ i
rollback;
connection default;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
set global rocksdb_max_latest_deadlocks = 1;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 1
connection con3;
set rocksdb_deadlock_detect_depth = 2;
Deadlock #4
@@ -153,7 +154,7 @@ rollback;
connection default;
set global rocksdb_max_latest_deadlocks = 5;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
Deadlock #5
connection con1;
begin;
@@ -195,9 +196,9 @@ connection con3;
rollback;
connection default;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY SHARED PRIMARY test.t 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE PRIMARY test.t 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY SHARED PRIMARY test.t 1
disconnect con1;
disconnect con2;
disconnect con3;
@@ -205,11 +206,11 @@ set global rocksdb_lock_wait_timeout = @prior_lock_wait_timeout;
set global rocksdb_deadlock_detect = @prior_deadlock_detect;
drop table t;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY EXCLUSIVE INDEX_NAME TABLE_NAME 0
-DEADLOCK_ID TRANSACTION_ID default WAITING_KEY SHARED INDEX_NAME TABLE_NAME 1
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY EXCLUSIVE INDEX_NAME TABLE_NAME 0
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID default WAITING_KEY SHARED INDEX_NAME TABLE_NAME 1
set global rocksdb_max_latest_deadlocks = 0;
# Clears deadlock buffer of any existent deadlocks.
set global rocksdb_max_latest_deadlocks = @prior_max_latest_deadlocks;
select * from information_schema.rocksdb_deadlock;
-DEADLOCK_ID TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
+DEADLOCK_ID TIMESTAMP TRANSACTION_ID CF_NAME WAITING_KEY LOCK_TYPE INDEX_NAME TABLE_NAME ROLLED_BACK
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/index_file_map.result b/storage/rocksdb/mysql-test/rocksdb/r/index_file_map.result
index 2c7d37c053f..ad007d71e15 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/index_file_map.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/index_file_map.result
@@ -24,5 +24,8 @@ WHERE INDEX_NUMBER =
WHERE TABLE_NAME = 't2' AND INDEX_NAME = "PRIMARY");
COLUMN_FAMILY INDEX_NUMBER SST_NAME NUM_ROWS DATA_SIZE ENTRY_DELETES ENTRY_SINGLEDELETES ENTRY_MERGES ENTRY_OTHERS DISTINCT_KEYS_PREFIX
# # SSTNAME 4 # # # # # 4
+select count(*) > 0 from information_schema.rocksdb_sst_props;
+count(*) > 0
+1
DROP TABLE t1;
DROP TABLE t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/index_merge_rocksdb2.result b/storage/rocksdb/mysql-test/rocksdb/r/index_merge_rocksdb2.result
index 4370715925a..e0248737381 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/index_merge_rocksdb2.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/index_merge_rocksdb2.result
@@ -30,7 +30,7 @@ id select_type table type possible_keys key key_len ref rows Extra
explain
select * from t0 where key1 < 3 or key2 > 1020;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using sort_union(i1,i2); Using where
+1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t0 where key1 < 3 or key2 > 1020;
key1 key2 key3 key4 key5 key6 key7 key8
1 1 1 1 1 1 1 1023
@@ -68,7 +68,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL # Using sort_union(i1,i2); Using where
explain select * from t0 where (key1 > 1 or key2 > 2);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 ALL i1,i2 NULL NULL NULL # Using where
+1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL # Using sort_union(i1,i2); Using where
explain select * from t0 force index (i1,i2) where (key1 > 1 or key2 > 2);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL # Using sort_union(i1,i2); Using where
@@ -124,13 +124,13 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select * from t0 where
(key1 < 3 or key2 < 3) and (key3 < 1000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL # Using sort_union(i1,i2); Using where
+1 SIMPLE t0 range i1,i2,i3 i3 4 NULL # Using index condition; Using where
explain select * from t0 where
((key1 < 3 or key2 < 3) and (key2 <4 or key3 < 3))
or
key2 > 4;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 ALL i1,i2,i3 NULL NULL NULL # Using where
+1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL # Using sort_union(i1,i2); Using where
explain select * from t0 where
((key1 < 4 or key2 < 4) and (key2 <4 or key3 < 3))
or
@@ -175,7 +175,7 @@ explain select * from t0 where
or
((key3 >5 or key5 < 2) and (key5 < 5 or key6 < 6));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 ALL i1,i2,i3,i5,i6 NULL NULL NULL # Using where
+1 SIMPLE t0 index_merge i1,i2,i3,i5,i6 i3,i5 4,4 NULL # Using sort_union(i3,i5); Using where
explain select * from t0 force index(i1, i2, i3, i4, i5, i6 ) where
((key3 <3 or key5 < 4) and (key1 < 3 or key2 < 3))
or
@@ -235,13 +235,13 @@ key1a key1b key2 key2_1 key2_2 key3
4 4 0 4 4 4
explain select * from t4 where key1a = 3 or key1b = 4;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 index_merge i1a,i1b i1a,i1b 4,4 NULL 2 Using sort_union(i1a,i1b); Using where
+1 SIMPLE t4 index_merge i1a,i1b i1a,i1b 4,4 NULL 4 Using sort_union(i1a,i1b); Using where
explain select * from t4 where key2 = 1 and (key2_1 = 1 or key3 = 5);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 1 Using where
+1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 2 Using where
explain select * from t4 where key2 = 1 and (key2_1 = 1 or key2_2 = 5);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 1 Using where
+1 SIMPLE t4 ref i2_1,i2_2 i2_1 4 const 2 Using where
explain select * from t4 where key2_1 = 1 or key2_2 = 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL # Using where
@@ -266,7 +266,7 @@ explain
select * from t0,t1 where (t0.key1=t1.key1) and
(t0.key1=3 or t0.key2<4) and t1.key1=2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 ref i1,i2 i1 4 const 1 Using where
+1 SIMPLE t0 ref i1,i2 i1 4 const 2 Using where
1 SIMPLE t1 ref i1 i1 4 const 1
explain select * from t0,t1 where t0.key1 = 5 and
(t1.key1 = t0.key1 or t1.key8 = t0.key1);
@@ -281,8 +281,8 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select * from t1 where key1=3 or key2=4
union select * from t1 where key1<4 or key3=5;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
-2 UNION t1 index_merge i1,i3 i1,i3 4,4 NULL 2 Using sort_union(i1,i3); Using where
+1 PRIMARY t1 index_merge i1,i2 i1,i2 4,4 NULL 4 Using union(i1,i2); Using where
+2 UNION t1 index_merge i1,i3 i1,i3 4,4 NULL 4 Using sort_union(i1,i3); Using where
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5;
id select_type table type possible_keys key key_len ref rows Extra
@@ -299,7 +299,7 @@ key1=1 or key2=2 or key3=3 or key4=4 or
key5=5 or key6=6 or key7=7 or key8=8 or
key9=9 or keyA=10 or keyB=11 or keyC=12;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 index_merge i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC 4,4,4,4,4,4,4,4,4,4,4,4 NULL 12 Using union(i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC); Using where
+1 SIMPLE t3 index_merge i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC 4,4,4,4,4,4,4,4,4,4,4,4 NULL 24 Using union(i1,i2,i3,i4,i5,i6,i7,i8,i9,iA,iB,iC); Using where
select * from t3 where
key1=1 or key2=2 or key3=3 or key4=4 or
key5=5 or key6=6 or key7=7 or key8=8 or
@@ -319,7 +319,7 @@ key1 key2 key3 key4 key5 key6 key7 key8 key9 keyA keyB keyC
1016 1016 1016 1016 1016 1016 1016 8 1016 1016 1016 1016
explain select * from t0 where key1 < 3 or key2 < 4;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using sort_union(i1,i2); Using where
+1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t0 where key1 < 3 or key2 < 4;
key1 key2 key3 key4 key5 key6 key7 key8
1 1 1 1 1 1 1 1023
@@ -696,7 +696,7 @@ count(a)
4
expla_or_bin select count(a_or_b) from t2 where a_or_b='AAAAAAAA' a_or_bnd a_or_b='AAAAAAAA';
id select_type ta_or_ba_or_ble type possia_or_ble_keys key key_len ref rows Extra_or_b
-1 SIMPLE t2 ref a_or_b,a_or_b a_or_b 6 const 1 Using where
+1 SIMPLE t2 ref a_or_b,a_or_b a_or_b 6 const 2 Using where
select count(a) from t2 where a='AAAAAAAA' and b='AAAAAAAA';
count(a)
4
@@ -706,7 +706,7 @@ count(a)
insert into t2 values ('ab', 'ab', 'uh', 'oh');
explain select a from t2 where a='ab';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref a a 6 const 1 Using where
+1 SIMPLE t2 ref a a 6 const 2 Using where
drop table t2;
CREATE TABLE t1(c1 INT, c2 INT DEFAULT 0, c3 CHAR(255) DEFAULT '',
KEY(c1), KEY(c2), KEY(c3));
@@ -732,7 +732,7 @@ INDEX i2(key2)
);
explain select * from t1 where key1 < 5 or key2 > 197;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using sort_union(i1,i2); Using where
+1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t1 where key1 < 5 or key2 > 197;
key1 key2
0 200
@@ -742,7 +742,7 @@ key1 key2
4 196
explain select * from t1 where key1 < 3 or key2 > 195;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using sort_union(i1,i2); Using where
+1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t1 where key1 < 3 or key2 > 195;
key1 key2
0 200
@@ -758,7 +758,7 @@ update t1 set str1='aaa', str2='bbb', str3=concat(key2, '-', key1 div 2, '_' ,if
alter table t1 add primary key (str1, zeroval, str2, str3);
explain select * from t1 where key1 < 5 or key2 > 197;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL i1,i2 NULL NULL NULL 200 Using where
+1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t1 where key1 < 5 or key2 > 197;
key1 key2 str1 zeroval str2 str3
4 196 aaa 0 bbb 196-2_a
@@ -768,7 +768,7 @@ key1 key2 str1 zeroval str2 str3
0 200 aaa 0 bbb 200-0_a
explain select * from t1 where key1 < 3 or key2 > 195;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL i1,i2 NULL NULL NULL 200 Using where
+1 SIMPLE t1 index_merge i1,i2 i1,i2 4,4 NULL 4 Using sort_union(i1,i2); Using where
select * from t1 where key1 < 3 or key2 > 195;
key1 key2 str1 zeroval str2 str3
4 196 aaa 0 bbb 196-2_a
@@ -789,7 +789,7 @@ show warnings;
Level Code Message
explain select pk from t1 where key1 = 1 and key2 = 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref key1,key2 key1 5 const 1 Using where
+1 SIMPLE t1 ref key1,key2 key1 5 const 2 Using where
select pk from t1 where key2 = 1 and key1 = 1;
pk
26
@@ -1057,7 +1057,7 @@ SELECT a
FROM t1
WHERE c = 1 AND b = 1 AND d = 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c,bd c 5 const 1 Using where
+1 SIMPLE t1 ref c,bd c 5 const 2 Using where
CREATE TABLE t2 ( a INT )
SELECT a
FROM t1
@@ -1303,7 +1303,7 @@ pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy b
1 19 0 0 0 0 0 0 0 19 0 filler-data-19 filler2
explain select pk1,pk2 from t1 where key1 = 10 and key2=10 and 2*pk1+1 < 2*96+1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref key1,key2 key1 4 const 1 Using index condition; Using where
+1 SIMPLE t1 index_merge key1,key2 key1,key2 4,4 NULL 1 Using intersect(key1,key2); Using where; Using index
select pk1,pk2 from t1 where key1 = 10 and key2=10 and 2*pk1+1 < 2*96+1;
pk1 pk2
95 50
@@ -1324,13 +1324,13 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,key1 key1 8 NULL ROWS Using index condition
explain select * from t1 where pktail1ok=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref key1,pktail1ok key1 4 const 1 Using where
+1 SIMPLE t1 index_merge key1,pktail1ok key1,pktail1ok 4,4 NULL 1 Using intersect(key1,pktail1ok); Using where
explain select * from t1 where pktail2ok=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref key1,pktail2ok key1 4 const 1 Using where
+1 SIMPLE t1 index_merge key1,pktail2ok key1,pktail2ok 4,4 NULL 1 Using intersect(key1,pktail2ok); Using where
explain select * from t1 where (pktail2ok=1 and pk1< 50000) or key1=10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge PRIMARY,key1,pktail2ok pktail2ok,key1 8,4 NULL ROWS Using sort_union(pktail2ok,key1); Using where
+1 SIMPLE t1 index_merge PRIMARY,key1,pktail2ok PRIMARY,key1 4,4 NULL ROWS Using union(PRIMARY,key1); Using where
explain select * from t1 where pktail3bad=1 and key1=10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref key1,pktail3bad EITHER_KEY 4 const ROWS Using where
@@ -1342,7 +1342,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref key1,pktail5bad key1 4 const ROWS Using where
explain select pk1,pk2,key1,key2 from t1 where key1 = 10 and key2=10 limit 10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref key1,key2 key1 4 const 1 Using where
+1 SIMPLE t1 index_merge key1,key2 key1,key2 4,4 NULL 1 Using intersect(key1,key2); Using where; Using index
select pk1,pk2,key1,key2 from t1 where key1 = 10 and key2=10 limit 10;
pk1 pk2 key1 key2
95 50 10 10
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result b/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result
index aba14e3c076..e22a85fd5c6 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/information_schema.result
@@ -16,6 +16,7 @@ SET GLOBAL ROCKSDB_PAUSE_BACKGROUND_WORK=0;
select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where CF_NAME = 'default' and LEVEL = 'Sum' and TYPE = 'KeyIn';
CREATE TABLE t1 (i1 INT, i2 INT, PRIMARY KEY (i1)) ENGINE = ROCKSDB;
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+set global rocksdb_force_flush_memtable_now = true;
select * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO;
TYPE NAME VALUE
MAX_INDEX_ID MAX_INDEX_ID max_index_id
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/lock.result b/storage/rocksdb/mysql-test/rocksdb/r/lock.result
index 36fea5b937f..7c4f54778d0 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/lock.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/lock.result
@@ -104,3 +104,18 @@ SELECT a,b FROM t1;
a b
UNLOCK TABLES;
DROP TABLE t1, t2;
+CREATE TABLE t1 (i INT) ENGINE=MyISAM;
+HANDLER t1 OPEN h;
+CREATE TABLE t2 (i INT) ENGINE=RocksDB;
+LOCK TABLES t2 WRITE;
+connect con1,localhost,root,,test;
+connection con1;
+FLUSH TABLES WITH READ LOCK;
+connection default;
+INSERT INTO t2 VALUES (1);
+UNLOCK TABLES;
+HANDLER h CLOSE;
+connection con1;
+disconnect con1;
+connection default;
+DROP TABLE t1, t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
index 017d7b77d31..730e12d02f6 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
@@ -78,6 +78,7 @@ ROCKSDB_CF_OPTIONS Stable
ROCKSDB_COMPACTION_STATS Stable
ROCKSDB_GLOBAL_INFO Stable
ROCKSDB_DDL Stable
+ROCKSDB_SST_PROPS Stable
ROCKSDB_INDEX_FILE_MAP Stable
ROCKSDB_LOCKS Stable
ROCKSDB_TRX Stable
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mysqldump.result b/storage/rocksdb/mysql-test/rocksdb/r/mysqldump.result
index 7e17c98668c..5ac36e1f4ba 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/mysqldump.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/mysqldump.result
@@ -34,7 +34,10 @@ update r1 set value1=value1+100 where id1=1 and id2=1 and id3='1';
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-/*!50601 SELECT count(*) INTO @is_rocksdb_supported FROM information_schema.SESSION_VARIABLES WHERE variable_name='rocksdb_bulk_load' */;
+/*!50601 SELECT count(*) INTO @is_mysql8 FROM information_schema.TABLES WHERE table_schema='performance_schema' AND table_name='session_variables' */;
+/*!50601 SET @check_rocksdb = CONCAT( 'SELECT count(*) INTO @is_rocksdb_supported FROM ', IF (@is_mysql8, 'performance', 'information'), '_schema.session_variables WHERE variable_name=\'rocksdb_bulk_load\'') */;
+/*!50601 PREPARE s FROM @check_rocksdb */;
+/*!50601 EXECUTE s */;
/*!50601 SET @enable_bulk_load = IF (@is_rocksdb_supported, 'SET SESSION rocksdb_bulk_load=1', 'SET @dummy = 0') */;
/*!50601 PREPARE s FROM @enable_bulk_load */;
/*!50601 EXECUTE s */;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/percona_nonflushing_analyze_debug.result b/storage/rocksdb/mysql-test/rocksdb/r/percona_nonflushing_analyze_debug.result
new file mode 100644
index 00000000000..84176da34fe
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/percona_nonflushing_analyze_debug.result
@@ -0,0 +1,19 @@
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=RocksDB;
+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/rocksdb/mysql-test/rocksdb/r/prefix_extractor_override.result b/storage/rocksdb/mysql-test/rocksdb/r/prefix_extractor_override.result
index 9c7d189e935..c0903eda663 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/prefix_extractor_override.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/prefix_extractor_override.result
@@ -24,11 +24,9 @@ CF_NAME OPTION_TYPE VALUE
__system__ PREFIX_EXTRACTOR rocksdb.CappedPrefix.24
cf1 PREFIX_EXTRACTOR rocksdb.CappedPrefix.24
default PREFIX_EXTRACTOR rocksdb.CappedPrefix.24
+SET @@global.rocksdb_update_cf_options = 'cf1={prefix_extractor=capped:26};';
-Restarting with new Prefix Extractor...
-
-
-Changed Prefix Extractor (after restart):
+Changed Prefix Extractor (after update_cf_options set, without restart):
SELECT * FROM information_schema.rocksdb_cf_options WHERE option_type like '%prefix_extractor%';
CF_NAME OPTION_TYPE VALUE
@@ -65,6 +63,7 @@ COUNT(*)
select variable_value-@u from information_schema.global_status where variable_name='rocksdb_bloom_filter_prefix_checked';
variable_value-@u
2
+SET @@global.rocksdb_update_cf_options = '';
set global rocksdb_compact_cf='cf1';
select variable_value into @u from information_schema.global_status where variable_name='rocksdb_bloom_filter_prefix_checked';
SELECT COUNT(*) FROM t1 WHERE id1=1 AND id2=30 AND id3=30;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
index e5fb9ceacba..6a21a339207 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb.result
@@ -880,6 +880,7 @@ rocksdb_block_restart_interval 16
rocksdb_block_size 4096
rocksdb_block_size_deviation 10
rocksdb_bulk_load OFF
+rocksdb_bulk_load_allow_sk OFF
rocksdb_bulk_load_allow_unsorted OFF
rocksdb_bulk_load_size 1000
rocksdb_bytes_per_sync 0
@@ -887,6 +888,7 @@ rocksdb_cache_index_and_filter_blocks ON
rocksdb_checksums_pct 100
rocksdb_collect_sst_properties ON
rocksdb_commit_in_the_middle OFF
+rocksdb_commit_time_batch_for_recovery OFF
rocksdb_compact_cf
rocksdb_compaction_readahead_size 0
rocksdb_compaction_sequential_deletes 0
@@ -900,6 +902,7 @@ rocksdb_datadir ./#rocksdb
rocksdb_db_write_buffer_size 0
rocksdb_deadlock_detect OFF
rocksdb_deadlock_detect_depth 50
+rocksdb_debug_manual_compaction_delay 0
rocksdb_debug_optimizer_no_zero_cardinality ON
rocksdb_debug_ttl_ignore_pk OFF
rocksdb_debug_ttl_read_filter_ts 0
@@ -915,6 +918,7 @@ rocksdb_enable_ttl ON
rocksdb_enable_ttl_read_filtering ON
rocksdb_enable_write_thread_adaptive_yield OFF
rocksdb_error_if_exists OFF
+rocksdb_error_on_suboptimal_collation ON
rocksdb_flush_log_at_trx_commit 0
rocksdb_force_compute_memtable_stats ON
rocksdb_force_compute_memtable_stats_cachetime 0
@@ -934,12 +938,14 @@ rocksdb_lock_scanned_rows OFF
rocksdb_lock_wait_timeout 1
rocksdb_log_file_time_to_roll 0
rocksdb_manifest_preallocation_size 4194304
+rocksdb_manual_compaction_threads 0
rocksdb_manual_wal_flush ON
rocksdb_master_skip_tx_api OFF
rocksdb_max_background_jobs 2
rocksdb_max_latest_deadlocks 5
rocksdb_max_log_file_size 0
-rocksdb_max_manifest_file_size 18446744073709551615
+rocksdb_max_manifest_file_size 1073741824
+rocksdb_max_manual_compactions 10
rocksdb_max_row_locks 1048576
rocksdb_max_subcompactions 1
rocksdb_max_total_wal_size 0
@@ -969,6 +975,7 @@ rocksdb_skip_fill_cache OFF
rocksdb_skip_unique_check_tables .*
rocksdb_sst_mgr_rate_bytes_per_sec 0
rocksdb_stats_dump_period_sec 600
+rocksdb_stats_recalc_rate 0
rocksdb_store_row_debug_checksums OFF
rocksdb_strict_collation_check OFF
rocksdb_strict_collation_exceptions
@@ -995,6 +1002,7 @@ rocksdb_whole_key_filtering ON
rocksdb_write_batch_max_bytes 0
rocksdb_write_disable_wal OFF
rocksdb_write_ignore_missing_column_families OFF
+rocksdb_write_policy write_committed
create table t47 (pk int primary key, col1 varchar(12)) engine=rocksdb;
insert into t47 values (1, 'row1');
insert into t47 values (2, 'row2');
@@ -1351,7 +1359,7 @@ insert into t1 select (@a:=@a+1), 1234 from information_schema.session_variables
set @tmp1= @@rocksdb_max_row_locks;
set rocksdb_max_row_locks= 20;
update t1 set a=a+10;
-ERROR HY000: Status error 10 received from RocksDB: Operation aborted: Failed to acquire lock due to max_num_locks limit
+ERROR HY000: Got error 10 'Operation aborted: Failed to acquire lock due to max_num_locks limit' from ROCKSDB
DROP TABLE t1;
#
# Test AUTO_INCREMENT behavior problem,
@@ -1495,6 +1503,8 @@ Rocksdb_block_cache_index_miss #
Rocksdb_block_cache_miss #
Rocksdb_block_cachecompressed_hit #
Rocksdb_block_cachecompressed_miss #
+Rocksdb_bloom_filter_full_positive #
+Rocksdb_bloom_filter_full_true_positive #
Rocksdb_bloom_filter_prefix_checked #
Rocksdb_bloom_filter_prefix_useful #
Rocksdb_bloom_filter_useful #
@@ -1511,6 +1521,8 @@ Rocksdb_get_hit_l1 #
Rocksdb_get_hit_l2_and_up #
Rocksdb_getupdatessince_calls #
Rocksdb_iter_bytes_read #
+Rocksdb_manual_compactions_processed #
+Rocksdb_manual_compactions_running #
Rocksdb_memtable_hit #
Rocksdb_memtable_miss #
Rocksdb_no_file_closes #
@@ -1602,6 +1614,8 @@ ROCKSDB_BLOCK_CACHE_INDEX_MISS
ROCKSDB_BLOCK_CACHE_MISS
ROCKSDB_BLOCK_CACHECOMPRESSED_HIT
ROCKSDB_BLOCK_CACHECOMPRESSED_MISS
+ROCKSDB_BLOOM_FILTER_FULL_POSITIVE
+ROCKSDB_BLOOM_FILTER_FULL_TRUE_POSITIVE
ROCKSDB_BLOOM_FILTER_PREFIX_CHECKED
ROCKSDB_BLOOM_FILTER_PREFIX_USEFUL
ROCKSDB_BLOOM_FILTER_USEFUL
@@ -1618,6 +1632,8 @@ ROCKSDB_GET_HIT_L1
ROCKSDB_GET_HIT_L2_AND_UP
ROCKSDB_GETUPDATESSINCE_CALLS
ROCKSDB_ITER_BYTES_READ
+ROCKSDB_MANUAL_COMPACTIONS_PROCESSED
+ROCKSDB_MANUAL_COMPACTIONS_RUNNING
ROCKSDB_MEMTABLE_HIT
ROCKSDB_MEMTABLE_MISS
ROCKSDB_NO_FILE_CLOSES
@@ -1711,6 +1727,8 @@ ROCKSDB_BLOCK_CACHE_INDEX_MISS
ROCKSDB_BLOCK_CACHE_MISS
ROCKSDB_BLOCK_CACHECOMPRESSED_HIT
ROCKSDB_BLOCK_CACHECOMPRESSED_MISS
+ROCKSDB_BLOOM_FILTER_FULL_POSITIVE
+ROCKSDB_BLOOM_FILTER_FULL_TRUE_POSITIVE
ROCKSDB_BLOOM_FILTER_PREFIX_CHECKED
ROCKSDB_BLOOM_FILTER_PREFIX_USEFUL
ROCKSDB_BLOOM_FILTER_USEFUL
@@ -1727,6 +1745,8 @@ ROCKSDB_GET_HIT_L1
ROCKSDB_GET_HIT_L2_AND_UP
ROCKSDB_GETUPDATESSINCE_CALLS
ROCKSDB_ITER_BYTES_READ
+ROCKSDB_MANUAL_COMPACTIONS_PROCESSED
+ROCKSDB_MANUAL_COMPACTIONS_RUNNING
ROCKSDB_MEMTABLE_HIT
ROCKSDB_MEMTABLE_MISS
ROCKSDB_NO_FILE_CLOSES
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_checksums.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_checksums.result
index 0ec2540e8dd..505487c08ba 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_checksums.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_checksums.result
@@ -11,7 +11,12 @@ insert into t1 values (1,1,1),(2,2,2),(3,3,3);
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
-FOUND 1 /0 table records had checksums/ in mysqld.1.err
+CHECKTABLE t1: Checking table t1
+CHECKTABLE t1: Checking index a
+CHECKTABLE t1: ... 3 index entries checked (0 had checksums)
+CHECKTABLE t1: Checking index b
+CHECKTABLE t1: ... 3 index entries checked (0 had checksums)
+CHECKTABLE t1: 0 table records had checksums
drop table t1;
set session rocksdb_store_row_debug_checksums=on;
create table t2 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksdb;
@@ -19,7 +24,12 @@ insert into t2 values (1,1,1),(2,2,2),(3,3,3);
check table t2;
Table Op Msg_type Msg_text
test.t2 check status OK
-FOUND 1 /3 table records had checksums/ in mysqld.1.err
+CHECKTABLE t2: Checking table t2
+CHECKTABLE t2: Checking index a
+CHECKTABLE t2: ... 3 index entries checked (3 had checksums)
+CHECKTABLE t2: Checking index b
+CHECKTABLE t2: ... 3 index entries checked (3 had checksums)
+CHECKTABLE t2: 3 table records had checksums
# Now, make a table that has both rows with checksums and without
create table t3 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksdb;
insert into t3 values (1,1,1),(2,2,2),(3,3,3);
@@ -29,16 +39,21 @@ set session rocksdb_store_row_debug_checksums=on;
check table t3;
Table Op Msg_type Msg_text
test.t3 check status OK
-FOUND 1 /2 table records had checksums/ in mysqld.1.err
+CHECKTABLE t3: Checking table t3
+CHECKTABLE t3: Checking index a
+CHECKTABLE t3: ... 3 index entries checked (3 had checksums)
+CHECKTABLE t3: Checking index b
+CHECKTABLE t3: ... 3 index entries checked (2 had checksums)
+CHECKTABLE t3: 2 table records had checksums
set session rocksdb_store_row_debug_checksums=on;
set session rocksdb_checksums_pct=5;
create table t4 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksdb;
check table t4;
Table Op Msg_type Msg_text
test.t4 check status OK
-10000 index entries had around 500 checksums
-10000 index entries had around 500 checksums
-Around 500 table records had checksums
+4000 index entries had around 200 checksums
+4000 index entries had around 200 checksums
+Around 200 table records had checksums
set session rocksdb_checksums_pct=100;
#
# Ok, table t2 has all rows with checksums. Simulate a few checksum mismatches.
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rc.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rc.result
index e52f495e7d5..ea2506941b2 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rc.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rc.result
@@ -50,10 +50,9 @@ i
3
insert into t values (4), (1);
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-# Statement should be rolled back
+# Transaction should be rolled back
select * from t;
i
-3
rollback;
connection con2;
i
@@ -62,6 +61,26 @@ connection con1;
i
rollback;
connection default;
+create table t1 (id int primary key, value int, value2 int, index(value)) engine=rocksdb;
+insert into t1 values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+connection con1;
+begin;
+update t1 force index (value) set value2=value2+1 where value=3;
+connection con2;
+begin;
+update t1 force index (value) set value2=value2+1 where value=2;
+update t1 force index (value) set value2=value2+1 where value=4;
+connection con1;
+update t1 force index (value) set value2=value2+1 where value=4;
+connection con2;
+update t1 force index (value) set value2=value2+1 where value=3;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+connection con1;
+rollback;
+connection con2;
+rollback;
+drop table t1;
+connection default;
disconnect con1;
disconnect con2;
disconnect con3;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rr.result b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rr.result
index e52f495e7d5..ea2506941b2 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rr.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/rocksdb_deadlock_detect_rr.result
@@ -50,10 +50,9 @@ i
3
insert into t values (4), (1);
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-# Statement should be rolled back
+# Transaction should be rolled back
select * from t;
i
-3
rollback;
connection con2;
i
@@ -62,6 +61,26 @@ connection con1;
i
rollback;
connection default;
+create table t1 (id int primary key, value int, value2 int, index(value)) engine=rocksdb;
+insert into t1 values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+connection con1;
+begin;
+update t1 force index (value) set value2=value2+1 where value=3;
+connection con2;
+begin;
+update t1 force index (value) set value2=value2+1 where value=2;
+update t1 force index (value) set value2=value2+1 where value=4;
+connection con1;
+update t1 force index (value) set value2=value2+1 where value=4;
+connection con2;
+update t1 force index (value) set value2=value2+1 where value=3;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+connection con1;
+rollback;
+connection con2;
+rollback;
+drop table t1;
+connection default;
disconnect con1;
disconnect con2;
disconnect con3;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/secondary_key_update_lock.result b/storage/rocksdb/mysql-test/rocksdb/r/secondary_key_update_lock.result
new file mode 100644
index 00000000000..14217824bb4
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/secondary_key_update_lock.result
@@ -0,0 +1,18 @@
+connect con, localhost, root,,;
+connection default;
+create table t1 (a int primary key, b int unique key) engine = rocksdb;
+insert into t1 values(1, 1);
+connection con;
+begin;
+update t1 set b = 2 where b = 1;
+connection default;
+insert into t1 values(2, 1);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection con;
+rollback;
+select * from t1;
+a b
+1 1
+connection default;
+drop table t1;
+disconnect con;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/show_engine.result b/storage/rocksdb/mysql-test/rocksdb/r/show_engine.result
index 9fc5db98d7d..eb23b71808b 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/show_engine.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/show_engine.result
@@ -136,6 +136,7 @@ __system__ TABLE_FACTORY::FLUSH_BLOCK_POLICY_FACTORY #
__system__ TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS #
__system__ TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS_WITH_HIGH_PRIORITY #
__system__ TABLE_FACTORY::PIN_L0_FILTER_AND_INDEX_BLOCKS_IN_CACHE #
+__system__ TABLE_FACTORY::PIN_TOP_LEVEL_INDEX_AND_FILTER #
__system__ TABLE_FACTORY::INDEX_TYPE #
__system__ TABLE_FACTORY::HASH_INDEX_ALLOW_COLLISION #
__system__ TABLE_FACTORY::CHECKSUM #
@@ -162,6 +163,7 @@ __system__ TABLE_FACTORY::VERIFY_COMPRESSION #
__system__ TABLE_FACTORY::READ_AMP_BYTES_PER_BIT #
__system__ TABLE_FACTORY::FORMAT_VERSION #
__system__ TABLE_FACTORY::ENABLE_INDEX_COMPRESSION #
+__system__ TABLE_FACTORY::BLOCK_ALIGN #
cf_t1 COMPARATOR #
cf_t1 MERGE_OPERATOR #
cf_t1 COMPACTION_FILTER #
@@ -207,6 +209,7 @@ cf_t1 TABLE_FACTORY::FLUSH_BLOCK_POLICY_FACTORY #
cf_t1 TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS #
cf_t1 TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS_WITH_HIGH_PRIORITY #
cf_t1 TABLE_FACTORY::PIN_L0_FILTER_AND_INDEX_BLOCKS_IN_CACHE #
+cf_t1 TABLE_FACTORY::PIN_TOP_LEVEL_INDEX_AND_FILTER #
cf_t1 TABLE_FACTORY::INDEX_TYPE #
cf_t1 TABLE_FACTORY::HASH_INDEX_ALLOW_COLLISION #
cf_t1 TABLE_FACTORY::CHECKSUM #
@@ -233,6 +236,7 @@ cf_t1 TABLE_FACTORY::VERIFY_COMPRESSION #
cf_t1 TABLE_FACTORY::READ_AMP_BYTES_PER_BIT #
cf_t1 TABLE_FACTORY::FORMAT_VERSION #
cf_t1 TABLE_FACTORY::ENABLE_INDEX_COMPRESSION #
+cf_t1 TABLE_FACTORY::BLOCK_ALIGN #
default COMPARATOR #
default MERGE_OPERATOR #
default COMPACTION_FILTER #
@@ -278,6 +282,7 @@ default TABLE_FACTORY::FLUSH_BLOCK_POLICY_FACTORY #
default TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS #
default TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS_WITH_HIGH_PRIORITY #
default TABLE_FACTORY::PIN_L0_FILTER_AND_INDEX_BLOCKS_IN_CACHE #
+default TABLE_FACTORY::PIN_TOP_LEVEL_INDEX_AND_FILTER #
default TABLE_FACTORY::INDEX_TYPE #
default TABLE_FACTORY::HASH_INDEX_ALLOW_COLLISION #
default TABLE_FACTORY::CHECKSUM #
@@ -304,6 +309,7 @@ default TABLE_FACTORY::VERIFY_COMPRESSION #
default TABLE_FACTORY::READ_AMP_BYTES_PER_BIT #
default TABLE_FACTORY::FORMAT_VERSION #
default TABLE_FACTORY::ENABLE_INDEX_COMPRESSION #
+default TABLE_FACTORY::BLOCK_ALIGN #
rev:cf_t2 COMPARATOR #
rev:cf_t2 MERGE_OPERATOR #
rev:cf_t2 COMPACTION_FILTER #
@@ -349,6 +355,7 @@ rev:cf_t2 TABLE_FACTORY::FLUSH_BLOCK_POLICY_FACTORY #
rev:cf_t2 TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS #
rev:cf_t2 TABLE_FACTORY::CACHE_INDEX_AND_FILTER_BLOCKS_WITH_HIGH_PRIORITY #
rev:cf_t2 TABLE_FACTORY::PIN_L0_FILTER_AND_INDEX_BLOCKS_IN_CACHE #
+rev:cf_t2 TABLE_FACTORY::PIN_TOP_LEVEL_INDEX_AND_FILTER #
rev:cf_t2 TABLE_FACTORY::INDEX_TYPE #
rev:cf_t2 TABLE_FACTORY::HASH_INDEX_ALLOW_COLLISION #
rev:cf_t2 TABLE_FACTORY::CHECKSUM #
@@ -375,6 +382,7 @@ rev:cf_t2 TABLE_FACTORY::VERIFY_COMPRESSION #
rev:cf_t2 TABLE_FACTORY::READ_AMP_BYTES_PER_BIT #
rev:cf_t2 TABLE_FACTORY::FORMAT_VERSION #
rev:cf_t2 TABLE_FACTORY::ENABLE_INDEX_COMPRESSION #
+rev:cf_t2 TABLE_FACTORY::BLOCK_ALIGN #
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
@@ -419,4 +427,49 @@ END OF ROCKSDB TRANSACTION MONITOR OUTPUT
=========================================
ROLLBACK;
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+File Position Gtid_executed Snapshot_ID
+ 0 1
+SHOW ENGINE rocksdb STATUS;
+Type Name Status
+STATISTICS # #
+DBSTATS # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+MEMORY_STATS # #
+BG_THREADS # #
+BG_THREADS # #
+EXPLICIT_SNAPSHOTS # #
+ROLLBACK;
+CREATE EXPLICIT rocksdb SNAPSHOT;
+File Position Gtid_executed Snapshot_ID
+ 0 2
+SHOW ENGINE rocksdb STATUS;
+Type Name Status
+STATISTICS # #
+DBSTATS # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+MEMORY_STATS # #
+BG_THREADS # #
+BG_THREADS # #
+EXPLICIT_SNAPSHOTS # #
+RELEASE EXPLICIT rocksdb SNAPSHOT;
+File Position Gtid_executed Snapshot_ID
+ 0 2
+SHOW ENGINE rocksdb STATUS;
+Type Name Status
+STATISTICS # #
+DBSTATS # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+CF_COMPACTION # #
+MEMORY_STATS # #
+BG_THREADS # #
+BG_THREADS # #
SET GLOBAL rocksdb_max_background_jobs= @save.rocksdb_max_background_jobs;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/transaction.result b/storage/rocksdb/mysql-test/rocksdb/r/transaction.result
index 006baaf1339..8a5825b9291 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/transaction.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/transaction.result
@@ -958,3 +958,20 @@ a
rollback;
drop function func;
drop table t1,t2,t3;
+#
+# MDEV-16710: Slave SQL: Could not execute Update_rows_v1 event with RocksDB and triggers
+# Issue#857: MyRocks: Incorrect behavior when multiple statements fail inside a transaction
+#
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=RocksDB;
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=RocksDB;
+CREATE TRIGGER tr AFTER INSERT ON t2 FOR EACH ROW INSERT INTO non_existing_table VALUES (NULL);
+BEGIN;
+DELETE FROM t1;
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+# Must return empty result:
+SELECT * FROM t1;
+a
+COMMIT;
+drop table t1,t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/trx_info_rpl.result b/storage/rocksdb/mysql-test/rocksdb/r/trx_info_rpl.result
index 24466d982b9..b096e42a11b 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/trx_info_rpl.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/trx_info_rpl.result
@@ -3,8 +3,8 @@ include/master-slave.inc
DROP TABLE IF EXISTS t1;
connection slave;
include/stop_slave.inc
+create table t1 (a int, b int, primary key (a), unique key (b)) engine=rocksdb;
connection master;
-create table t1 (a int) engine=rocksdb;
connection slave;
show variables like 'rpl_skip_tx_api';
Variable_name Value
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/update.result b/storage/rocksdb/mysql-test/rocksdb/r/update.result
index 33bf8d09405..791fddd27ef 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/update.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/update.result
@@ -111,3 +111,11 @@ a b pk
55 NULL 11
10050 NULL 12
DROP TABLE t1;
+CREATE TABLE t1 (a INT, b CHAR(8), UNIQUE INDEX(a)) ENGINE=RocksDB;
+INSERT INTO t1 (a,b) VALUES (1,'foo'),(2,'bar');
+UPDATE t1 SET a=a+100;
+SELECT * FROM t1;
+a b
+101 foo
+102 bar
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/use_direct_reads.result b/storage/rocksdb/mysql-test/rocksdb/r/use_direct_reads.result
new file mode 100644
index 00000000000..8a4ee14c116
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/r/use_direct_reads.result
@@ -0,0 +1,18 @@
+Checking direct reads
+CREATE TABLE t1 (pk INT PRIMARY KEY DEFAULT '0', a INT(11), b CHAR(8)) ENGINE=rocksdb;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL DEFAULT 0,
+ `a` int(11) DEFAULT NULL,
+ `b` char(8) DEFAULT NULL,
+ PRIMARY KEY (`pk`)
+) ENGINE=ROCKSDB DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (1, 1,'a');
+INSERT INTO t1 (a,b) VALUES (2,'b');
+set global rocksdb_force_flush_memtable_now=1;
+SELECT a,b FROM t1;
+a b
+1 a
+2 b
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/validate_datadic.result b/storage/rocksdb/mysql-test/rocksdb/r/validate_datadic.result
index b5ab85d14c6..5d9a6342ae9 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/validate_datadic.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/validate_datadic.result
@@ -2,7 +2,8 @@ call mtr.add_suppression('RocksDB: Schema mismatch');
CREATE TABLE t1 (pk int primary key) ENGINE=ROCKSDB;
CREATE TABLE t2 (pk int primary key) ENGINE=ROCKSDB PARTITION BY KEY(pk) PARTITIONS 4;
"Expect errors that we are missing two .frm files"
-FOUND 2 /Schema mismatch/ in mysqld.1.err
+FOUND 1 /RocksDB: Schema mismatch - Table test.t1 is registered in RocksDB but does not have a .frm file/ in validate_datadic.err
+FOUND 1 /RocksDB: Schema mismatch - Table test.t2 is registered in RocksDB but does not have a .frm file/ in validate_datadic.err
"Expect an error that we have an extra .frm file"
-FOUND 3 /Schema mismatch/ in mysqld.1.err
+FOUND 1 /Schema mismatch - A .frm file exists for table test.t1_dummy, but that table is not registered in RocksDB/ in validate_datadic.err
DROP TABLE t1, t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test
index 876ef2c9965..df7790ee4c2 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace.test
@@ -394,6 +394,24 @@ if ($end_max_index_id <= $start_max_index_id) {
SHOW CREATE TABLE t1;
DROP TABLE t1;
+# Cardinality checks for indexes statistics
+SET @prior_rocksdb_table_stats_sampling_pct = @@rocksdb_table_stats_sampling_pct;
+set global rocksdb_table_stats_sampling_pct = 100;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY ka(a)) ENGINE=RocksDB;
+INSERT INTO t1 (a, b) VALUES (1, 10);
+INSERT INTO t1 (a, b) VALUES (2, 10);
+INSERT INTO t1 (a, b) VALUES (3, 20);
+INSERT INTO t1 (a, b) VALUES (4, 20);
+set global rocksdb_force_flush_memtable_now=1;
+analyze table t1;
+
+SHOW INDEX in t1;
+
+ALTER TABLE t1 ADD INDEX kb(b), ALGORITHM=INPLACE;
+SHOW INDEX in t1;
+
+DROP TABLE t1;
+SET global rocksdb_table_stats_sampling_pct = @prior_rocksdb_table_stats_sampling_pct;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test
index d715eb7df7a..4f34cbe8f8a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test
@@ -1,6 +1,7 @@
--source include/have_rocksdb.inc
--source include/have_debug.inc
--source include/have_partition.inc
+--source include/not_valgrind.inc
--disable_warnings
drop table if exists t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_sstfilewriter.test b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_sstfilewriter.test
index 5eac8595f7b..61a10a60e7f 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_sstfilewriter.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_sstfilewriter.test
@@ -68,7 +68,7 @@ ALTER TABLE t1 ADD INDEX kb(b), ALGORITHM=INPLACE;
# hitting max row locks (1M)
set @tmp= @@rocksdb_max_row_locks;
set session rocksdb_max_row_locks=1000;
---error ER_RDB_STATUS_GENERAL
+--error ER_GET_ERRMSG
ALTER TABLE t1 ADD INDEX kb_copy(b), ALGORITHM=COPY;
set session rocksdb_bulk_load=1;
ALTER TABLE t1 ADD INDEX kb_copy(b), ALGORITHM=COPY;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test b/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test
index abcae8d98a5..b17548063d9 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test
@@ -1,6 +1,7 @@
--source include/have_rocksdb.inc
--source include/have_debug.inc
--source include/have_log_bin.inc
+--source include/not_valgrind.inc
--echo #
--echo # Testing upgrading from server without merges for auto_increment
@@ -64,8 +65,8 @@ commit;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
--disable_reconnect
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-select max(i) from t;
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
--echo # After engine prepare
begin;
@@ -80,8 +81,8 @@ commit;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
--disable_reconnect
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-select max(i) from t;
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
--echo # After binlog
begin;
@@ -96,8 +97,8 @@ commit;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
--disable_reconnect
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-select max(i) from t;
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
--echo # After everything
begin;
@@ -112,7 +113,7 @@ commit;
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
--disable_reconnect
-select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
-select max(i) from t;
+select max(i) into @row_max from t;
+select table_schema, table_name, auto_increment > @row_max from information_schema.tables where table_name = 't';
drop table t;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/autoinc_vars.test b/storage/rocksdb/mysql-test/rocksdb/t/autoinc_vars.test
index 9d7f0365d07..f4da0b7cb58 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/autoinc_vars.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/autoinc_vars.test
@@ -116,3 +116,36 @@ CREATE TABLE t0(c0 BLOB) ENGINE=ROCKSDB;
INSERT INTO t0 VALUES(0);
ALTER TABLE t0 AUTO_INCREMENT=0;
DROP TABLE t0;
+
+--echo #---------------------------------------------------------------
+--echo # MDEV-16703 Assertion failed in load_auto_incr_value_from_index
+--echo #---------------------------------------------------------------
+
+CREATE TABLE t1 (pk INT AUTO_INCREMENT, a INT, PRIMARY KEY(pk)) ENGINE=RocksDB;
+INSERT INTO t1 (a) VALUES (1);
+UPDATE t1 SET pk = 3;
+ALTER TABLE t1 AUTO_INCREMENT 2;
+DROP TABLE t1;
+
+--echo #----------------------------------
+--echo # Issue #792 Crash in autoincrement
+--echo #----------------------------------
+
+CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY,C2 CHAR) ENGINE=ROCKSDB;
+INSERT INTO t1 VALUES(2177,0);
+DROP TABLE t1;
+
+CREATE TABLE t0(c0 BLOB) ENGINE=ROCKSDB;
+INSERT INTO t0 VALUES(0);
+ALTER TABLE t0 AUTO_INCREMENT=0;
+DROP TABLE t0;
+
+--echo #----------------------------------
+--echo # Issue #869 Crash in autoincrement
+--echo #----------------------------------
+
+CREATE TABLE t1 (pk INT AUTO_INCREMENT, a INT, PRIMARY KEY(pk)) ENGINE=RocksDB;
+INSERT INTO t1 (a) VALUES (1);
+UPDATE t1 SET pk = 3;
+ALTER TABLE t1 AUTO_INCREMENT 2;
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter5-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter5-master.opt
index 7d63dc74bb8..efcd69ba5bf 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter5-master.opt
+++ b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter5-master.opt
@@ -1 +1,3 @@
---rocksdb_override_cf_options=rev:bf5_1={prefix_extractor=capped:4;block_based_table_factory={filter_policy=bloomfilter:10:false;whole_key_filtering=0;}};
+--rocksdb_default_cf_options=write_buffer_size=256k;block_based_table_factory={filter_policy=bloomfilter:10:false;whole_key_filtering=0;}
+--rocksdb_override_cf_options=rev:bf5_1={prefix_extractor=capped:4};
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load-master.opt
new file mode 100644
index 00000000000..c28681ef030
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load-master.opt
@@ -0,0 +1,2 @@
+--rocksdb_default_cf_options=write_buffer_size=16k;block_based_table_factory={filter_policy=bloomfilter:10:false;whole_key_filtering=0;};prefix_extractor=capped:12
+--rocksdb_override_cf_options=cf2={optimize_filters_for_hits=true}
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load.test b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load.test
new file mode 100644
index 00000000000..09d9d734f9e
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/bloomfilter_bulk_load.test
@@ -0,0 +1,35 @@
+--source include/have_rocksdb.inc
+
+create table r1 (id bigint primary key, value bigint) engine=rocksdb;
+create table r2 (id bigint, value bigint, primary key (id) comment 'cf2') engine=rocksdb;
+set session rocksdb_bulk_load=1;
+--disable_query_log
+let $t = 1;
+let $i = 1;
+while ($t <= 2) {
+ while ($i <= 1000) {
+ let $insert = INSERT INTO r$t VALUES($i, $i);
+ #skipping a row
+ if ($i != 100) {
+ eval $insert;
+ }
+ inc $i;
+ }
+ inc $t;
+}
+--enable_query_log
+set session rocksdb_bulk_load=0;
+
+# bloom filter should be useful on insert (calling GetForUpdate)
+select variable_value into @h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+insert into r1 values (100, 100);
+select variable_value-@h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+
+# cf2 has no bloo filter in the bottommost level
+select variable_value into @h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+insert into r2 values (100, 100);
+select variable_value-@h from information_schema.global_status where variable_name='rocksdb_block_cache_filter_hit';
+
+DROP TABLE r1, r2;
+
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/bulk_load_sk.test b/storage/rocksdb/mysql-test/rocksdb/t/bulk_load_sk.test
new file mode 100644
index 00000000000..0fb47f74669
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/bulk_load_sk.test
@@ -0,0 +1,119 @@
+--source include/have_rocksdb.inc
+
+SET rocksdb_bulk_load_size=15;
+
+CREATE TABLE t4 (a INT, b INT, c INT,
+ PRIMARY KEY (a),
+ KEY (b),
+ KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t3 (a INT, b INT, c INT,
+ PRIMARY KEY (a),
+ KEY (b),
+ KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t2 (a INT, b INT, c INT,
+ PRIMARY KEY (a),
+ KEY (b),
+ KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+CREATE TABLE t1 (a INT, b INT, c INT,
+ PRIMARY KEY (a),
+ KEY (b),
+ KEY (c) COMMENT "rev:cf") ENGINE=ROCKSDB;
+
+### Setup the control table ###
+--disable_query_log
+let $sign = 1;
+let $max = 10;
+let $i = 1;
+while ($i <= $max) {
+ let $a = 1 + $sign * $i;
+ let $b = 1 - $sign * $i;
+ let $sign = -$sign;
+ let $insert = INSERT INTO t3 VALUES ($a, $b, $b);
+ eval $insert;
+ inc $i;
+}
+--enable_query_log
+
+### Bulk load PK only ###
+SET rocksdb_bulk_load=1;
+INSERT INTO t1 SELECT * FROM t3 FORCE INDEX (PRIMARY) ORDER BY a;
+SELECT count(*) FROM t1 FORCE INDEX (PRIMARY);
+SELECT count(*) FROM t1 FORCE INDEX (b);
+SELECT count(*) FROM t1 FORCE INDEX (c);
+SET rocksdb_bulk_load=0;
+SELECT * FROM t1 FORCE INDEX (PRIMARY);
+SELECT b FROM t1 FORCE INDEX (b);
+SELECT c FROM t1 FORCE INDEX (c);
+--echo Checksums should match
+CHECKSUM TABLE t3;
+CHECKSUM TABLE t1;
+
+### Bulk load PK and SK but require PK order ###
+SET rocksdb_bulk_load_allow_sk=1;
+SET rocksdb_bulk_load=1;
+INSERT INTO t4 SELECT * FROM t3 FORCE INDEX (PRIMARY) ORDER BY a;
+SELECT count(*) FROM t4 FORCE INDEX (PRIMARY);
+SELECT count(*) FROM t4 FORCE INDEX (b);
+SELECT count(*) FROM t4 FORCE INDEX (c);
+SET rocksdb_bulk_load=0;
+SELECT * FROM t4 FORCE INDEX (PRIMARY);
+SELECT b FROM t4 FORCE INDEX (b);
+SELECT c FROM t4 FORCE INDEX (c);
+--echo Checksums should match
+CHECKSUM TABLE t3;
+CHECKSUM TABLE t4;
+
+### Bulk load both PK and SK in random order for all ###
+SET rocksdb_bulk_load_allow_unsorted=1;
+SET rocksdb_bulk_load_allow_sk=1;
+SET rocksdb_bulk_load=1;
+
+INSERT INTO t2 SELECT * FROM t3 WHERE b >= 0 ORDER BY b;
+INSERT INTO t2 SELECT * FROM t3 WHERE b < 0 ORDER BY b;
+SELECT count(*) FROM t2 FORCE INDEX (PRIMARY);
+SELECT count(*) FROM t2 FORCE INDEX (b);
+SELECT count(*) FROM t2 FORCE INDEX (c);
+
+--disable_query_log
+let $sign = 1;
+let $max = 20;
+let $i = 11;
+while ($i <= $max) {
+ let $a = 1 + $sign * $i;
+ let $b = 1 - $sign * $i;
+ let $sign = -$sign;
+ let $insert = INSERT INTO t2 VALUES ($a, $b, $b);
+ eval $insert;
+ inc $i;
+}
+--enable_query_log
+SELECT count(*) FROM t2 FORCE INDEX (PRIMARY);
+SELECT count(*) FROM t2 FORCE INDEX (b);
+SELECT count(*) FROM t2 FORCE INDEX (c);
+SET rocksdb_bulk_load=0;
+
+--disable_query_log
+let $sign = 1;
+let $max = 20;
+let $i = 11;
+while ($i <= $max) {
+ let $a = 1 + $sign * $i;
+ let $b = 1 - $sign * $i;
+ let $sign = -$sign;
+ let $insert = INSERT INTO t3 VALUES ($a, $b, $b);
+ eval $insert;
+ inc $i;
+}
+--enable_query_log
+
+SELECT * FROM t2 FORCE INDEX (PRIMARY);
+SELECT b FROM t2 FORCE INDEX (b);
+SELECT c FROM t2 FORCE INDEX (c);
+--echo Checksums should match
+CHECKSUM TABLE t3;
+CHECKSUM TABLE t2;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/cardinality.test b/storage/rocksdb/mysql-test/rocksdb/t/cardinality.test
index 14a82d7e462..21e4b49e560 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/cardinality.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/cardinality.test
@@ -94,5 +94,24 @@ SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema
show index in t1;
SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema = DATABASE();
-drop table t1;
+CREATE TABLE t2 (a INT, b INT, c INT, d INT, e INT, f INT, g INT,
+ PRIMARY KEY (a), KEY (c, b, a, d, e, f, g))
+ ENGINE=ROCKSDB;
+--disable_query_log
+let $i=0;
+while ($i<100)
+{
+ inc $i;
+ eval insert t2 values($i, $i div 10, 1, 1, 1, 1, 1);
+}
+--enable_query_log
+
+# Cardinality of key c should be 1 for c, 10 for b, 100 for a and the other fields.
+SET GLOBAL rocksdb_force_flush_memtable_now = 1;
+ANALYZE TABLE t2;
+--echo cardinality of the columns after 'a' must be equal to the cardinality of column 'a'
+SELECT CARDINALITY INTO @c FROM information_schema.statistics WHERE TABLE_NAME='t2' AND INDEX_NAME='c' AND COLUMN_NAME='a';
+SELECT COLUMN_NAME, CARDINALITY = @c FROM information_schema.statistics WHERE TABLE_NAME='t2' AND INDEX_NAME='c' AND SEQ_IN_INDEX > 3;
+
+drop table t1, t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
index 9e7c816ae6e..b39c022fc46 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
@@ -8,7 +8,9 @@ let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
let $error_log= $MYSQLTEST_VARDIR/log/my_restart.err;
select variable_name, variable_value from information_schema.global_variables where variable_name="rocksdb_ignore_unknown_options";
---exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -n | tail -1 | xargs -0 -I {} -t sh -c "echo hello=world>>{}"
+--exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -t- -k 2 -n | tail -1 | xargs -0 -I {} -t sh -c "sed -i 's/rocksdb_version=.*/rocksdb_version=99.9.9/' {}"
+--exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -t- -k 2 -n | tail -1 | xargs -0 -I {} -t sh -c "echo hello=world>>{}"
+
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server 10
@@ -19,8 +21,8 @@ select variable_name, variable_value from information_schema.global_variables wh
let SEARCH_FILE= $error_log;
let SEARCH_PATTERN= RocksDB: Compatibility check against existing database options failed;
--source include/search_pattern_in_file.inc
+--remove_file $error_log
--enable_reconnect
--exec echo "restart" > $restart_file
--source include/wait_until_connected_again.inc
---exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -n | tail -1 | xargs -0 -I {} -t sh -c "sed -i'' -e '/hello=world/d' {}"
select variable_name, variable_value from information_schema.global_variables where variable_name="rocksdb_ignore_unknown_options";
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/collation.test b/storage/rocksdb/mysql-test/rocksdb/t/collation.test
index 7152925dca4..3b808bc329a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/collation.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/collation.test
@@ -3,14 +3,13 @@
# following check is commented out:
# --source include/have_fullregex.inc
-SET @start_global_value = @@global.ROCKSDB_STRICT_COLLATION_EXCEPTIONS;
-
---disable_warnings
-DROP TABLE IF EXISTS t1;
---enable_warnings
+call mtr.add_suppression("Invalid pattern");
# ci non-indexed column is allowed
CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text) engine=rocksdb charset utf8;
+# ci indexed column is not allowed
+--error ER_UNSUPPORTED_COLLATION
+ALTER TABLE t1 ADD INDEX (value);
DROP TABLE t1;
# ci indexed column is not allowed
@@ -30,6 +29,8 @@ DROP TABLE t1;
# cs latin1_bin is allowed
CREATE TABLE t1 (id varchar(20), value varchar(50), value2 varchar(50), value3 text, primary key (id), index(value, value2)) engine=rocksdb charset latin1 collate latin1_bin;
+# THIS SHOULD FAIL BUT IT DOES NOT
+ALTER TABLE t1 collate=latin1_general_ci;
DROP TABLE t1;
# cs utf8_bin is allowed
@@ -183,5 +184,28 @@ DROP TABLE abc;
# test bad regex (null caused a crash) - Issue 493
SET GLOBAL rocksdb_strict_collation_exceptions=null;
+# test for warnings instead of errors
+--let $_mysqld_option=--rocksdb_error_on_suboptimal_collation=0
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--source include/restart_mysqld_with_option.inc
+
+SET GLOBAL rocksdb_strict_collation_check=1;
+
+# ci indexed column is not optimal, should emit a warning
+CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text, index(value)) engine=rocksdb charset utf8;
+DROP TABLE t1;
+
+# ci non-indexed column is allowed
+CREATE TABLE t1 (id INT primary key, value varchar(50), value2 varbinary(50), value3 text) engine=rocksdb charset utf8;
+# ci indexed column is not allowed, should emit a warning
+ALTER TABLE t1 ADD INDEX (value);
+DROP TABLE t1;
+
+# cs latin1_bin is allowed
+CREATE TABLE t1 (id varchar(20), value varchar(50), value2 varchar(50), value3 text, primary key (id), index(value, value2)) engine=rocksdb charset latin1 collate latin1_bin;
+# THIS SHOULD WARN BUT IT DOES NOT
+ALTER TABLE t1 collate=latin1_general_ci;
+DROP TABLE t1;
+
# cleanup
-SET GLOBAL rocksdb_strict_collation_exceptions=@start_global_value;
+--source include/restart_mysqld.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.cnf b/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.cnf
new file mode 100644
index 00000000000..49ebd28c793
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.cnf
@@ -0,0 +1,4 @@
+!include suite/rpl/my.cnf
+
+[mysqld.1]
+binlog_format=row
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.test b/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.test
new file mode 100644
index 00000000000..c2058474b01
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/com_rpc_tx.test
@@ -0,0 +1,87 @@
+--source "include/have_rocksdb.inc"
+--source "include/have_log_bin.inc"
+
+#
+# This test was created because 2pc transactions were failing in MyRocks
+# when using detached sessions. The test generates two separate transactions
+# in two detached sessions and then attempts to commit them as simultaneously
+# as possible. This consistently showed the problem but succeeds after the
+# fix was put in place.
+
+CREATE DATABASE db_rpc;
+USE db_rpc;
+CREATE TABLE t1(pk INT PRIMARY KEY) ENGINE=rocksdb;
+
+SET GLOBAL rocksdb_enable_2pc=1;
+
+connect(con2,localhost,root,,);
+connection default;
+
+query_attrs_add rpc_role root;
+query_attrs_add rpc_db db_rpc;
+SET autocommit = 0;
+let $rpc_id1 = get_rpc_id();
+if ($rpc_id1 == "") {
+ echo "Fail: rpc_id not returned as expected";
+}
+
+SET autocommit = 0;
+let $rpc_id2 = get_rpc_id();
+if ($rpc_id2 == "") {
+ echo "Fail: rpc_id not returned as expected";
+}
+
+query_attrs_delete rpc_role;
+query_attrs_delete rpc_db;
+
+query_attrs_add rpc_id $rpc_id1;
+BEGIN;
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id2;
+BEGIN;
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id1;
+SELECT * from t1;
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id2;
+SELECT * from t1;
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id1;
+INSERT INTO t1 VALUES(1);
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id2;
+INSERT INTO t1 VALUES(2);
+query_attrs_delete rpc_id;
+
+query_attrs_add rpc_id $rpc_id1;
+send COMMIT;
+
+connection con2;
+query_attrs_add rpc_id $rpc_id2;
+send COMMIT;
+
+connection default;
+reap;
+query_attrs_delete rpc_id;
+
+connection con2;
+reap;
+query_attrs_delete rpc_id;
+
+connection default;
+disconnect con2;
+
+SELECT * from db_rpc.t1;
+
+disable_query_log;
+eval KILL $rpc_id1;
+eval KILL $rpc_id2;
+enable_query_log;
+
+DROP DATABASE db_rpc;
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table-master.opt
new file mode 100644
index 00000000000..ce274af3507
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table-master.opt
@@ -0,0 +1 @@
+--block_create_no_primary_key=TRUE
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table.test b/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table.test
new file mode 100644
index 00000000000..c5650359d8c
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/create_no_primary_key_table.test
@@ -0,0 +1,44 @@
+USE mysql;
+CREATE TABLE mysql_table (a INT) ENGINE=ROCKSDB;
+-- error ER_BLOCK_NO_PRIMARY_KEY
+CREATE TABLE test.mysql_table (a INT) ENGINE=ROCKSDB;
+USE test;
+-- error ER_BLOCK_NO_PRIMARY_KEY
+CREATE TABLE mysql_table (a INT) ENGINE=ROCKSDB;
+-- error ER_BLOCK_NO_PRIMARY_KEY
+CREATE TABLE IF NOT EXISTS mysql_table_2 (a INT) ENGINE=ROCKSDB;
+-- error ER_BLOCK_NO_PRIMARY_KEY
+CREATE TABLE mysql_table_no_cols ENGINE=ROCKSDB;
+CREATE TABLE mysql.mysql_table_2 (a INT) ENGINE=ROCKSDB;
+
+CREATE TABLE mysql_primkey (a INT PRIMARY KEY, b INT, c INT, d INT, INDEX (c)) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey DROP b, DROP a, ADD (f INT PRIMARY KEY);
+-- error ER_BLOCK_NO_PRIMARY_KEY
+ALTER TABLE mysql_primkey DROP PRIMARY KEY;
+
+CREATE TABLE mysql_primkey2 (a INT PRIMARY KEY, b INT, c INT) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey2 DROP b;
+ALTER TABLE mysql_primkey2 ADD (b INT);
+-- error ER_BLOCK_NO_PRIMARY_KEY
+ALTER TABLE mysql_primkey2 DROP c, DROP A;
+
+CREATE TABLE mysql_primkey3 (a INT PRIMARY KEY, b INT, c INT, INDEX indexonb (b), INDEX indexonc (c)) ENGINE=ROCKSDB;
+ALTER TABLE mysql_primkey3 DROP INDEX indexonb;
+ALTER TABLE mysql_primkey3 DROP c;
+ALTER TABLE mysql_primkey3 DROP PRIMARY KEY, ADD PRIMARY KEY(b);
+
+CREATE TABLE mysql_primkey4(a INT, b INT, PRIMARY KEY(a), INDEX si (a, b)) ENGINE=ROCKSDB;
+DROP INDEX si ON mysql_primkey4;
+-- error ER_BLOCK_NO_PRIMARY_KEY
+DROP INDEX `PRIMARY` ON mysql_primkey4;
+
+ALTER TABLE mysql.mysql_table ADD PRIMARY KEY (a);
+ALTER TABLE mysql.mysql_table DROP PRIMARY KEY;
+
+DROP TABLE mysql_primkey;
+DROP TABLE mysql_primkey2;
+DROP TABLE mysql_primkey3;
+DROP TABLE mysql_primkey4;
+USE mysql;
+DROP TABLE mysql_table;
+DROP TABLE mysql_table_2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/deadlock_tracking.test b/storage/rocksdb/mysql-test/rocksdb/t/deadlock_tracking.test
index 9677d2dbbaa..8ceebef8f72 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/deadlock_tracking.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/deadlock_tracking.test
@@ -1,7 +1,7 @@
-set @prior_lock_wait_timeout = @@rocksdb_lock_wait_timeout;
-set @prior_deadlock_detect = @@rocksdb_deadlock_detect;
-set @prior_max_latest_deadlocks = @@rocksdb_max_latest_deadlocks;
-set global rocksdb_deadlock_detect = on;
+set @prior_lock_wait_timeout = @@rocksdb_lock_wait_timeout;
+set @prior_deadlock_detect = @@rocksdb_deadlock_detect;
+set @prior_max_latest_deadlocks = @@rocksdb_max_latest_deadlocks;
+set global rocksdb_deadlock_detect = on;
set global rocksdb_lock_wait_timeout = 10000;
--echo # Clears deadlock buffer of any prior deadlocks.
set global rocksdb_max_latest_deadlocks = 0;
@@ -21,29 +21,29 @@ let $con3= `SELECT CONNECTION_ID()`;
connection default;
eval create table t (i int primary key) engine=$engine;
insert into t values (1), (2), (3);
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
echo Deadlock #1;
--source include/simple_deadlock.inc
connection default;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
echo Deadlock #2;
--source include/simple_deadlock.inc
connection default;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
set global rocksdb_max_latest_deadlocks = 10;
echo Deadlock #3;
--source include/simple_deadlock.inc
connection default;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
set global rocksdb_max_latest_deadlocks = 1;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
connection con3;
@@ -51,15 +51,15 @@ set rocksdb_deadlock_detect_depth = 2;
echo Deadlock #4;
connection con1;
-begin;
+begin;
select * from t where i=1 for update;
connection con2;
-begin;
+begin;
select * from t where i=2 for update;
connection con3;
-begin;
+begin;
select * from t where i=3 for update;
connection con1;
@@ -84,29 +84,29 @@ select case when variable_value-@a = 1 then 'true' else 'false' end as deadlocks
rollback;
connection con2;
-reap;
+reap;
rollback;
connection con1;
-reap;
+reap;
rollback;
connection default;
set global rocksdb_max_latest_deadlocks = 5;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
echo Deadlock #5;
connection con1;
-begin;
+begin;
select * from t where i=1 for update;
connection con2;
-begin;
+begin;
select * from t where i=2 for update;
connection con3;
-begin;
+begin;
select * from t where i=3 lock in share mode;
connection con1;
@@ -128,28 +128,58 @@ select * from t where i=1 lock in share mode;
rollback;
connection con1;
-reap;
+reap;
rollback;
connection con3;
rollback;
connection default;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
+echo Deadlock #6;
+connection con1;
+create table t1 (id int primary key, value int) engine=rocksdb;
+insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
+begin;
+update t1 set value=value+100 where id=1;
+update t1 set value=value+100 where id=2;
+
+connection con2;
+begin;
+update t1 set value=value+200 where id=3;
+
+connection con1;
+send update t1 set value=value+100 where id=3;
+
+connection con2;
+let $wait_condition = select count(*) = 1 from information_schema.rocksdb_trx
+where thread_id = $con1 and waiting_key != "";
+--source include/wait_condition.inc
+--error ER_LOCK_DEADLOCK
+update t1 set value=value+200 where id=1;
+
+# con2 tx is automatically rolled back
+connection con1;
+reap;
+select * from t1;
+drop table t1;
+
+connection default;
+
disconnect con1;
disconnect con2;
disconnect con3;
-set global rocksdb_lock_wait_timeout = @prior_lock_wait_timeout;
+set global rocksdb_lock_wait_timeout = @prior_lock_wait_timeout;
set global rocksdb_deadlock_detect = @prior_deadlock_detect;
drop table t;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /INDEX_ID: [0-9a-f]*/IDX_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /INDEX_ID: [0-9a-f]*/IDX_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
set global rocksdb_max_latest_deadlocks = 0;
--echo # Clears deadlock buffer of any existent deadlocks.
set global rocksdb_max_latest_deadlocks = @prior_max_latest_deadlocks;
---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /INDEX_ID: [0-9a-f]*/IDX_ID/
+--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/TIMESTAMP/ /WAITING KEY: [0-9a-f]{16}/KEY/ /TRANSACTION ID: [0-9]*/TXN_ID/ /INDEX_ID: [0-9a-f]*/IDX_ID/ /TIMESTAMP: [0-9]*/TSTAMP/
show engine rocksdb transaction status;
--source include/wait_until_count_sessions.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
index d0cd1ce6407..a9877ed9e64 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
+++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
@@ -21,7 +21,9 @@ mysqldump2 : MariaDB's mysqldump doesn't support --print-ordering-key
native_procedure : Not supported in MariaDB
slow_query_log: MDEV-11480
select_for_update_skip_locked_nowait: MDEV-11481
-
+create_no_primary_key_table: MariaDB doesn't have --block_create_no_primary_key
+explicit_snapshot: MariaDB doesn't support Shared/Explicit snapshots
+percona_nonflushing_analyze_debug : Requires Percona Server's Non-flushing ANALYZE feature
##
## Tests that do not fit MariaDB's test environment. Upstream seems to test
@@ -34,7 +36,7 @@ rqg_transactions : Test that use RQG are disabled
allow_no_pk_concurrent_insert: stress test
rocksdb_deadlock_stress_rc: stress test
rocksdb_deadlock_stress_rr: stress test
-
+use_direct_reads: Direct IO is not supported on all filesystems
##
## Tests which hit a problem elsewhere (Upstream, SQL layer, etc)
@@ -77,3 +79,6 @@ information_schema: MDEV-14372: unstable testcase
mysqlbinlog_gtid_skip_empty_trans_rocksdb : MariaRocks: requires GTIDs
autoinc_debug: Fails with wrong results
+drop_table: Hangs on shutdown
+allow_to_start_after_corruption : result difference and assertion failure
+index_merge_rocksdb2 : result difference
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/drop_table.test b/storage/rocksdb/mysql-test/rocksdb/t/drop_table.test
index 0d3dee5ab17..9667c7ba650 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/drop_table.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/drop_table.test
@@ -78,6 +78,33 @@ let $table = t1;
let $table = t4;
--source drop_table_repopulate_table.inc
+# Run manual compaction, then restarting mysqld
+# and confirming it is not blocked.
+SET GLOBAL rocksdb_max_manual_compactions = 2;
+SET GLOBAL rocksdb_debug_manual_compaction_delay = 3600;
+connect (con1, localhost, root,,);
+connect (con2, localhost, root,,);
+connect (con3, localhost, root,,);
+connection con1;
+send SET GLOBAL rocksdb_compact_cf='cf1';
+connection con2;
+send SET GLOBAL rocksdb_compact_cf='rev:cf2';
+connection default;
+let $wait_condition = select count(*) = 2 from information_schema.processlist where info like 'SET GLOBAL rocksdb_compact_cf%';
+--source include/wait_condition.inc
+# longer enough than manual compaction thread to start compaction
+--sleep 2
+select * from information_schema.global_status where variable_name='rocksdb_manual_compactions_running';
+
+connection con3;
+--error ER_INTERNAL_ERROR
+SET GLOBAL rocksdb_compact_cf='cf1';
+--error ER_INTERNAL_ERROR
+SET GLOBAL rocksdb_compact_cf='rev:cf2';
+
+connection default;
+--source include/restart_mysqld.inc
+
drop table t4;
# Restart the server before t4's indices are deleted
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot-master.opt
new file mode 100644
index 00000000000..d7dd66b4480
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot-master.opt
@@ -0,0 +1 @@
+--log-bin --binlog_format=row --gtid_mode=ON --enforce_gtid_consistency --log-slave-updates
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot.test b/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot.test
new file mode 100644
index 00000000000..efe1980b694
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/explicit_snapshot.test
@@ -0,0 +1,263 @@
+source include/have_log_bin.inc;
+source include/have_rocksdb.inc;
+
+disable_warnings;
+DROP TABLE IF EXISTS t1;
+enable_warnings;
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+CREATE TABLE T1 (a INT PRIMARY KEY AUTO_INCREMENT) ENGINE=ROCKSDB;
+INSERT INTO T1 VALUES();
+
+#
+
+echo "con1: Creating explict snapshot";
+let $snapshot=
+ query_get_value(CREATE EXPLICIT ROCKSDB SNAPSHOT, Snapshot_ID, 1);
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+echo "con2: Attaching snapshot id $snapshot";
+disable_result_log;
+eval ATTACH EXPLICIT ROCKSDB SNAPSHOT $snapshot;
+enable_result_log;
+echo "con2: New row should not be visible";
+SELECT * FROM T1;
+echo "con2: Releasing snapshot";
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+echo "con2: New row should be visible";
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: New row should not be visible";
+SELECT * FROM T1;
+echo "con1: Releasing snapshot";
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+echo "con1: New row should be visible";
+SELECT * FROM T1;
+
+#
+
+echo "con1: Starting shared snapshot";
+let $snapshot=
+query_get_value(START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT, Snapshot_ID, 1);
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+echo "con2: Starting existing snapshot";
+disable_result_log;
+eval START TRANSACTION WITH EXISTING ROCKSDB SNAPSHOT $snapshot;
+enable_result_log;
+echo "con2: New row should not be visible";
+SELECT * FROM T1;
+COMMIT;
+echo "con2: New row should be visible";
+SELECT * FROM T1;
+
+connection con1;
+COMMIT;
+echo "con1: New row should be visible";
+SELECT * FROM T1;
+
+## Negative test cases
+
+connection con1;
+echo "con1: Creating explict snapshot";
+let $snapshot=
+ query_get_value(CREATE EXPLICIT ROCKSDB SNAPSHOT, Snapshot_ID, 1);
+echo "con2: Trying to insert row";
+error ER_UPDATES_WITH_EXPLICIT_SNAPSHOT;
+INSERT INTO T1 VALUES();
+
+connection con2;
+echo "con2: Attaching existing snapshot";
+disable_result_log;
+eval ATTACH EXPLICIT ROCKSDB SNAPSHOT $snapshot;
+enable_result_log;
+echo "con2: Trying to insert row";
+error ER_UPDATES_WITH_EXPLICIT_SNAPSHOT;
+INSERT INTO T1 VALUES();
+
+connection con1;
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+connection con2;
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+
+connection con1;
+echo "con1: Starting shared snapshot";
+let $snapshot=
+query_get_value(START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT, Snapshot_ID, 1);
+echo "con1: Trying to insert row";
+error ER_UPDATES_WITH_CONSISTENT_SNAPSHOT;
+INSERT INTO T1 VALUES();
+
+connection con2;
+echo "con2: Starting existing snapshot";
+disable_result_log;
+eval START TRANSACTION WITH EXISTING ROCKSDB SNAPSHOT $snapshot;
+enable_result_log;
+echo "con2: Trying to insert row";
+error ER_UPDATES_WITH_CONSISTENT_SNAPSHOT;
+INSERT INTO T1 VALUES();
+
+connection con1;
+COMMIT;
+connection con2;
+COMMIT;
+
+## Test how overlapping explicit snapshot statements work
+
+connection con1;
+echo "con1: Creating explicit snapshot";
+disable_result_log;
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: New row should not be seen";
+SELECT * FROM T1;
+echo "con1: Creating another explicit snapshot";
+disable_result_log;
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+echo "con1: Now the new row should be seen";
+SELECT * FROM T1;
+
+#
+
+echo "con1: Starting transaction with consistent snapshot";
+disable_result_log;
+START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: The new row should not be seen";
+SELECT * FROM T1;
+
+echo "con1: Creating another explicit snapshot";
+disable_result_log;
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+echo "con1: The new row should still not be seen";
+SELECT * FROM T1;
+
+echo "con1: Committing trx";
+COMMIT;
+echo "con1: The new row should now be seen because of the new explicit snapshot created above";
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: Releasing explicit snapshot";
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+
+#
+
+echo "con1: Starting transaction with shared snapshot";
+disable_result_log;
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: The new row should not be seen";
+SELECT * FROM T1;
+
+echo "con1: Starting another transaction with shared snapshot";
+disable_result_log;
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+enable_result_log;
+echo "con1: The new row should now be seen";
+SELECT * FROM T1;
+COMMIT;
+
+#
+
+echo "con1: Creating explicit snapshot";
+disable_result_log;
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+echo "con1: Releasing explicit snapshot";
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+
+echo "con1: Releasing explicit snapshot again";
+error ER_UNKNOWN_ERROR;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+
+#
+
+echo "con1: Starting transaction with shared snapshot";
+disable_result_log;
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+connection con2;
+echo "con2: Inserting a row";
+INSERT INTO T1 VALUES();
+SELECT * FROM T1;
+
+connection con1;
+echo "con1: Creating explicit snapshot";
+disable_result_log;
+CREATE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+SELECT * FROM T1;
+
+echo "con1: Releasing explicit snapshot";
+disable_result_log;
+RELEASE EXPLICIT ROCKSDB SNAPSHOT;
+enable_result_log;
+
+echo "con1: The new row should not be seen";
+SELECT* FROM T1;
+COMMIT;
+
+#
+
+## Cleanup
+DROP TABLE T1;
+
+connection default;
+disconnect con1;
+disconnect con2;
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/i_s_deadlock.test b/storage/rocksdb/mysql-test/rocksdb/t/i_s_deadlock.test
index 21558899782..e0479d6a337 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/i_s_deadlock.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/i_s_deadlock.test
@@ -32,23 +32,23 @@ select * from information_schema.rocksdb_deadlock;
echo Deadlock #1;
--source include/simple_deadlock.inc
connection default;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
echo Deadlock #2;
--source include/simple_deadlock.inc
connection default;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
set global rocksdb_max_latest_deadlocks = 10;
echo Deadlock #3;
--source include/simple_deadlock.inc
connection default;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
set global rocksdb_max_latest_deadlocks = 1;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
connection con3;
@@ -96,7 +96,7 @@ rollback;
connection default;
set global rocksdb_max_latest_deadlocks = 5;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
echo Deadlock #5;
@@ -138,7 +138,7 @@ connection con3;
rollback;
connection default;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY
select * from information_schema.rocksdb_deadlock;
disconnect con1;
@@ -148,7 +148,7 @@ disconnect con3;
set global rocksdb_lock_wait_timeout = @prior_lock_wait_timeout;
set global rocksdb_deadlock_detect = @prior_deadlock_detect;
drop table t;
---replace_column 1 DEADLOCK_ID 2 TRANSACTION_ID 4 WAITING_KEY 6 INDEX_NAME 7 TABLE_NAME
+--replace_column 1 DEADLOCK_ID 2 TIMESTAMP 3 TRANSACTION_ID 5 WAITING_KEY 7 INDEX_NAME 8 TABLE_NAME
select * from information_schema.rocksdb_deadlock;
set global rocksdb_max_latest_deadlocks = 0;
--echo # Clears deadlock buffer of any existent deadlocks.
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/index_file_map.test b/storage/rocksdb/mysql-test/rocksdb/t/index_file_map.test
index 1021846c508..8b0e2339426 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/index_file_map.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/index_file_map.test
@@ -46,6 +46,9 @@ WHERE INDEX_NUMBER =
(SELECT INDEX_NUMBER FROM INFORMATION_SCHEMA.ROCKSDB_DDL
WHERE TABLE_NAME = 't2' AND INDEX_NAME = "PRIMARY");
+# The number of sst files should be 1 or more
+select count(*) > 0 from information_schema.rocksdb_sst_props;
+
# cleanup
DROP TABLE t1;
DROP TABLE t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/index_merge_rocksdb2-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/index_merge_rocksdb2-master.opt
index c07b063f07c..7681c42eeb3 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/index_merge_rocksdb2-master.opt
+++ b/storage/rocksdb/mysql-test/rocksdb/t/index_merge_rocksdb2-master.opt
@@ -1 +1 @@
---rocksdb_strict_collation_check=off --binlog_format=row --log-bin
+--rocksdb_strict_collation_check=off --binlog_format=row --log-bin --rocksdb_records_in_range=2
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test b/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test
index 67dae5d6263..09998b9ae5f 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/information_schema.test
@@ -28,6 +28,7 @@ select VALUE into @keysIn from INFORMATION_SCHEMA.ROCKSDB_COMPACTION_STATS where
CREATE TABLE t1 (i1 INT, i2 INT, PRIMARY KEY (i1)) ENGINE = ROCKSDB;
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+set global rocksdb_force_flush_memtable_now = true;
# No binlog coordinates in MariaDB: --let $MASTER_UUID = query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
--let $max_index_id = query_get_value(SELECT * from INFORMATION_SCHEMA.ROCKSDB_GLOBAL_INFO where type = 'MAX_INDEX_ID', VALUE, 1)
# No binlog coordinates in MariaDB: --replace_result $MASTER_UUID uuid $max_index_id max_index_id
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config-master.opt
deleted file mode 100644
index 3b7d80662db..00000000000
--- a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config-master.opt
+++ /dev/null
@@ -1,8 +0,0 @@
---rocksdb_write_disable_wal=1
---rocksdb_flush_log_at_trx_commit=0
---rocksdb_default_cf_options=write_buffer_size=16k;target_file_size_base=16k;level0_file_num_compaction_trigger=4;level0_slowdown_writes_trigger=256;level0_stop_writes_trigger=256;max_write_buffer_number=16;compression_per_level=kNoCompression;memtable=vector:1024
---rocksdb_override_cf_options=__system__={memtable=skip_list:16}
---rocksdb_compaction_sequential_deletes=0
---rocksdb_compaction_sequential_deletes_window=0
---rocksdb_allow_concurrent_memtable_write=0
-
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
index 3e1cf7375e8..46ea7f0eb0a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test
@@ -1,9 +1,19 @@
--source include/have_rocksdb.inc
+--source include/have_write_committed.inc
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# reload with load optimized config
+let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
+--exec echo "wait" > $restart_file
+--shutdown_server 10
+--source include/wait_until_disconnected.inc
+-- exec echo "restart:--rocksdb_write_disable_wal=1 --rocksdb_flush_log_at_trx_commit=0 --rocksdb_default_cf_options=write_buffer_size=16k;target_file_size_base=16k;level0_file_num_compaction_trigger=4;level0_slowdown_writes_trigger=256;level0_stop_writes_trigger=256;max_write_buffer_number=16;compression_per_level=kNoCompression;memtable=vector:1024 --rocksdb_override_cf_options=__system__={memtable=skip_list:16} --rocksdb_compaction_sequential_deletes=0 --rocksdb_compaction_sequential_deletes_window=0 --rocksdb_allow_concurrent_memtable_write=0" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+-- enable_reconnect
+-- source include/wait_until_connected_again.inc
+
create table t1(
id bigint not null primary key,
i1 bigint, #unique
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/lock.test b/storage/rocksdb/mysql-test/rocksdb/t/lock.test
index 015a08bef57..9ce5e566505 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/lock.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/lock.test
@@ -196,6 +196,28 @@ SELECT a,b FROM t1;
UNLOCK TABLES;
DROP TABLE t1, t2;
+CREATE TABLE t1 (i INT) ENGINE=MyISAM;
+HANDLER t1 OPEN h;
+CREATE TABLE t2 (i INT) ENGINE=RocksDB;
+LOCK TABLES t2 WRITE;
+
+--connect (con1,localhost,root,,test)
+--connection con1
+--send
+FLUSH TABLES WITH READ LOCK;
+
+--connection default
+INSERT INTO t2 VALUES (1);
+UNLOCK TABLES;
+HANDLER h CLOSE;
+
+--connection con1
+--reap
+--disconnect con1
+
+--connection default
+DROP TABLE t1, t2;
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/percona_nonflushing_analyze_debug.test b/storage/rocksdb/mysql-test/rocksdb/t/percona_nonflushing_analyze_debug.test
new file mode 100644
index 00000000000..c0c73e683bf
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/percona_nonflushing_analyze_debug.test
@@ -0,0 +1,11 @@
+--source include/have_debug_sync.inc
+--source include/have_rocksdb.inc
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=RocksDB;
+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/rocksdb/mysql-test/rocksdb/t/prefix_extractor_override.test b/storage/rocksdb/mysql-test/rocksdb/t/prefix_extractor_override.test
index c6b91071171..161f7b566f5 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/prefix_extractor_override.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/prefix_extractor_override.test
@@ -26,9 +26,6 @@ select variable_value into @u from information_schema.global_status where variab
SELECT COUNT(*) FROM t1 WHERE id1=1 AND id2=1 AND id3=1;
select variable_value-@u from information_schema.global_status where variable_name='rocksdb_bloom_filter_prefix_checked';
-# MariaDB: the following doesn't work on Windows and doesn't seem to be needed
-# on Linux:
-#--exec echo "" > $MYSQLTEST_VARDIR/log/mysqld.1.err
--let $_mysqld_option=--rocksdb_override_cf_options=cf1={prefix_extractor=capped:26};
--echo
@@ -37,16 +34,12 @@ select variable_value-@u from information_schema.global_status where variable_na
--sorted_result
SELECT * FROM information_schema.rocksdb_cf_options WHERE option_type like '%prefix_extractor%';
-# This should no longer crash. See https://github.com/facebook/mysql-5.6/issues/641
+SET @@global.rocksdb_update_cf_options = 'cf1={prefix_extractor=capped:26};';
--echo
---echo Restarting with new Prefix Extractor...
---echo
---source include/restart_mysqld_with_option.inc
-
---echo
---echo Changed Prefix Extractor (after restart):
+--echo Changed Prefix Extractor (after update_cf_options set, without restart):
--echo
--sorted_result
+# Restart no longer needed
SELECT * FROM information_schema.rocksdb_cf_options WHERE option_type like '%prefix_extractor%';
# Satisfies can_use_bloom_filter (4+8+8+8), but can't use because the old SST
@@ -88,6 +81,7 @@ select variable_value into @u from information_schema.global_status where variab
SELECT COUNT(*) FROM t1 WHERE id1=1 AND id2=1 AND id3=1;
select variable_value-@u from information_schema.global_status where variable_name='rocksdb_bloom_filter_prefix_checked';
+SET @@global.rocksdb_update_cf_options = '';
set global rocksdb_compact_cf='cf1';
# Select the updated, make sure bloom filter is checked now
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
index b884738424f..13f1bd68a72 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb.test
@@ -1,5 +1,6 @@
--source include/have_rocksdb.inc
--source include/have_partition.inc
+--source include/have_write_committed.inc
#
# RocksDB Storage Engine tests
@@ -1150,7 +1151,7 @@ set @a=-1;
insert into t1 select (@a:=@a+1), 1234 from information_schema.session_variables limit 100;
set @tmp1= @@rocksdb_max_row_locks;
set rocksdb_max_row_locks= 20;
---error ER_RDB_STATUS_GENERAL
+--error ER_GET_ERRMSG
update t1 set a=a+10;
DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_checksums.test b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_checksums.test
index 9a7704c7ab0..42a4c83ff04 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_checksums.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_checksums.test
@@ -5,6 +5,11 @@
#
--source include/have_debug.inc
+--let LOG=$MYSQLTEST_VARDIR/tmp/rocksdb_checksum.err
+--let $_mysqld_option=--log-error=$LOG
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--source include/restart_mysqld_with_option.inc
+
set @save_rocksdb_store_row_debug_checksums=@@global.rocksdb_store_row_debug_checksums;
set @save_rocksdb_verify_row_debug_checksums=@@global.rocksdb_verify_row_debug_checksums;
set @save_rocksdb_checksums_pct=@@global.rocksdb_checksums_pct;
@@ -14,8 +19,10 @@ show variables like 'rocksdb_%checksum%';
create table t1 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksdb;
insert into t1 values (1,1,1),(2,2,2),(3,3,3);
check table t1;
---let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err
+--let SEARCH_FILE=$LOG
--let SEARCH_PATTERN=0 table records had checksums
+--let SEARCH_PATTERN=CHECKTABLE t1[^\n]*
+--let SEARCH_OUTPUT=matches
--source include/search_pattern_in_file.inc
drop table t1;
@@ -24,7 +31,7 @@ set session rocksdb_store_row_debug_checksums=on;
create table t2 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksdb;
insert into t2 values (1,1,1),(2,2,2),(3,3,3);
check table t2;
---let SEARCH_PATTERN=3 table records had checksums
+--let SEARCH_PATTERN=CHECKTABLE t2[^\n]*
--source include/search_pattern_in_file.inc
--echo # Now, make a table that has both rows with checksums and without
@@ -34,7 +41,7 @@ set session rocksdb_store_row_debug_checksums=off;
update t3 set b=3 where a=2;
set session rocksdb_store_row_debug_checksums=on;
check table t3;
---let SEARCH_PATTERN=2 table records had checksums
+--let SEARCH_PATTERN=CHECKTABLE t3[^\n]*
--source include/search_pattern_in_file.inc
set session rocksdb_store_row_debug_checksums=on;
@@ -43,7 +50,7 @@ create table t4 (pk int primary key, a int, b int, key(a), key(b)) engine=rocksd
--disable_query_log
let $i=0;
let $x= 100000;
-while ($i<10000)
+while ($i<4000)
{
inc $i;
eval insert t4(pk,a,b) values($i, $i, $i div 10);
@@ -53,11 +60,12 @@ while ($i<10000)
--enable_query_log
check table t4;
perl;
-$total=10000;
+$total=4000;
$pct=5;
@out=();
-$filename= "$ENV{MYSQLTEST_VARDIR}/log/mysqld.1.err";
+$filename= "$ENV{LOG}";
+print $filename "\n";
open(F, '<', $filename) || die("Can't open file $filename: $!");
while(<F>) {
@out=() if /^CURRENT_TEST:/;
@@ -138,4 +146,7 @@ set @@global.rocksdb_store_row_debug_checksums=@save_rocksdb_store_row_debug_che
set @@global.rocksdb_verify_row_debug_checksums=@save_rocksdb_verify_row_debug_checksums;
set @@global.rocksdb_checksums_pct=@save_rocksdb_checksums_pct;
+--source include/restart_mysqld.inc
+#--remove_file $LOG
+
drop table t2,t3,t4;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_deadlock_detect.inc b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_deadlock_detect.inc
index 01180ea29a8..082c61308f3 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_deadlock_detect.inc
+++ b/storage/rocksdb/mysql-test/rocksdb/t/rocksdb_deadlock_detect.inc
@@ -68,7 +68,7 @@ let $wait_condition =
select * from t;
--error ER_LOCK_DEADLOCK
insert into t values (4), (1);
---echo # Statement should be rolled back
+--echo # Transaction should be rolled back
select * from t;
rollback;
@@ -80,6 +80,39 @@ connection con1;
--reap
rollback;
+
+connection default;
+create table t1 (id int primary key, value int, value2 int, index(value)) engine=rocksdb;
+insert into t1 values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
+
+connection con1;
+begin;
+update t1 force index (value) set value2=value2+1 where value=3;
+
+connection con2;
+begin;
+update t1 force index (value) set value2=value2+1 where value=2;
+update t1 force index (value) set value2=value2+1 where value=4;
+
+connection con1;
+send update t1 force index (value) set value2=value2+1 where value=4;
+
+connection con2;
+let $wait_condition =
+`SELECT CONCAT('select count(*) = 1 from information_schema.rocksdb_trx where THREAD_ID = ', '$con1', ' and WAITING_KEY != ""')`;
+--source include/wait_condition.inc
+--error ER_LOCK_DEADLOCK
+update t1 force index (value) set value2=value2+1 where value=3;
+
+connection con1;
+--reap
+rollback;
+
+connection con2;
+rollback;
+drop table t1;
+
+
connection default;
disconnect con1;
disconnect con2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/secondary_key_update_lock.test b/storage/rocksdb/mysql-test/rocksdb/t/secondary_key_update_lock.test
new file mode 100644
index 00000000000..b43a32b6a0d
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/secondary_key_update_lock.test
@@ -0,0 +1,26 @@
+--source include/have_rocksdb.inc
+
+# Tests if locks are held for the secondary keys of old rows in updates
+
+connect (con, localhost, root,,);
+
+connection default;
+create table t1 (a int primary key, b int unique key) engine = rocksdb;
+insert into t1 values(1, 1);
+
+connection con;
+begin;
+update t1 set b = 2 where b = 1; # this should lock the row where b = 1
+
+connection default;
+error ER_LOCK_WAIT_TIMEOUT;
+insert into t1 values(2, 1); # should error out with lock_wait_timeout
+
+connection con;
+rollback;
+select * from t1;
+
+# Cleanup
+connection default;
+drop table t1;
+disconnect con;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/set_checkpoint.inc b/storage/rocksdb/mysql-test/rocksdb/t/set_checkpoint.inc
index 558e2413256..aae9db6c927 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/set_checkpoint.inc
+++ b/storage/rocksdb/mysql-test/rocksdb/t/set_checkpoint.inc
@@ -23,7 +23,7 @@ if (!$succeeds)
{
--disable_result_log
--disable_query_log
- --error ER_RDB_STATUS_GENERAL
+ --error ER_GET_ERRMSG
eval SET GLOBAL ROCKSDB_CREATE_CHECKPOINT = '$checkpoint';
--enable_query_log
--enable_result_log
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/show_engine.test b/storage/rocksdb/mysql-test/rocksdb/t/show_engine.test
index 06f64ddb3fa..ccca197d317 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/show_engine.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/show_engine.test
@@ -86,5 +86,18 @@ SHOW ENGINE rocksdb TRANSACTION STATUS;
ROLLBACK;
+# Check if explicit snapshots are correctly populated
+START TRANSACTION WITH SHARED ROCKSDB SNAPSHOT;
+--replace_column 2 # 3 #
+SHOW ENGINE rocksdb STATUS;
+ROLLBACK;
+CREATE EXPLICIT rocksdb SNAPSHOT;
+--replace_column 2 # 3 #
+SHOW ENGINE rocksdb STATUS;
+RELEASE EXPLICIT rocksdb SNAPSHOT;
+--replace_column 2 # 3 #
+SHOW ENGINE rocksdb STATUS;
+
+
# Restore old values
SET GLOBAL rocksdb_max_background_jobs= @save.rocksdb_max_background_jobs;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/transaction.test b/storage/rocksdb/mysql-test/rocksdb/t/transaction.test
index 3350db99dab..129484bac91 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/transaction.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/transaction.test
@@ -133,3 +133,26 @@ rollback;
drop function func;
drop table t1,t2,t3;
+--echo #
+--echo # MDEV-16710: Slave SQL: Could not execute Update_rows_v1 event with RocksDB and triggers
+--echo # Issue#857: MyRocks: Incorrect behavior when multiple statements fail inside a transaction
+--echo #
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=RocksDB;
+INSERT INTO t1 VALUES (1);
+
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=RocksDB;
+
+CREATE TRIGGER tr AFTER INSERT ON t2 FOR EACH ROW INSERT INTO non_existing_table VALUES (NULL);
+
+BEGIN;
+DELETE FROM t1;
+--error 0,ER_NO_SUCH_TABLE
+INSERT INTO t2 VALUES (1);
+--error 0,ER_NO_SUCH_TABLE
+INSERT INTO t2 VALUES (2);
+--echo # Must return empty result:
+SELECT * FROM t1;
+COMMIT;
+
+drop table t1,t2;
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/trx_info_rpl.test b/storage/rocksdb/mysql-test/rocksdb/t/trx_info_rpl.test
index af3cce19630..91ab266cdc4 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/trx_info_rpl.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/trx_info_rpl.test
@@ -9,11 +9,11 @@ connection slave;
--enable_warnings
connection master;
-create table t1 (a int) engine=rocksdb;
+create table t1 (a int, b int, primary key (a), unique key (b)) engine=rocksdb;
--disable_query_log
--let $aa= 0
while ($aa < 1000) {
- eval insert into t1 values ($aa);
+ eval insert into t1 values ($aa, $aa);
--inc $aa
}
--enable_query_log
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/update.test b/storage/rocksdb/mysql-test/rocksdb/t/update.test
index 51e2c5be0a6..6220c4f55a3 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/update.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/update.test
@@ -70,3 +70,13 @@ SELECT * FROM t1 ORDER BY pk;
DROP TABLE t1;
+
+#
+# Issue #830 UPDATE with unique constraint does not work
+#
+
+CREATE TABLE t1 (a INT, b CHAR(8), UNIQUE INDEX(a)) ENGINE=RocksDB;
+INSERT INTO t1 (a,b) VALUES (1,'foo'),(2,'bar');
+UPDATE t1 SET a=a+100;
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/use_direct_reads.test b/storage/rocksdb/mysql-test/rocksdb/t/use_direct_reads.test
new file mode 100644
index 00000000000..c347a85518f
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb/t/use_direct_reads.test
@@ -0,0 +1,37 @@
+--source include/have_rocksdb.inc
+
+--perl
+use Cwd 'abs_path';
+
+open(FILE, ">", "$ENV{MYSQL_TMP_DIR}/data_in_shm.inc") or die;
+my $real_path= abs_path($ENV{'MYSQLTEST_VARDIR'});
+my $in_shm= index($real_path, "/dev/shm") != -1;
+print FILE "let \$DATA_IN_SHM= $in_shm;\n";
+close FILE;
+EOF
+
+--source $MYSQL_TMP_DIR/data_in_shm.inc
+--remove_file $MYSQL_TMP_DIR/data_in_shm.inc
+
+if ($DATA_IN_SHM)
+{
+ --skip DATADIR is in /dev/shm, possibly due to --mem
+}
+
+--echo Checking direct reads
+--let $_mysqld_option=--rocksdb_use_direct_reads=1
+--source include/restart_mysqld_with_option.inc
+
+CREATE TABLE t1 (pk INT PRIMARY KEY DEFAULT '0', a INT(11), b CHAR(8)) ENGINE=rocksdb;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1, 1,'a');
+INSERT INTO t1 (a,b) VALUES (2,'b');
+set global rocksdb_force_flush_memtable_now=1;
+--sorted_result
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+# cleanup
+--let _$mysqld_option=
+--source include/restart_mysqld.inc
+
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test b/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
index e9dcc604155..ec48dc03ec8 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test
@@ -19,6 +19,8 @@ CREATE TABLE t2 (pk int primary key) ENGINE=ROCKSDB PARTITION BY KEY(pk) PARTITI
# server until it is told to
--let $_server_id= `SELECT @@server_id`
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
+--let LOG=$MYSQLTEST_VARDIR/tmp/validate_datadic.err
+
--exec echo "wait" >$_expect_file_name
# Send shutdown to the connected server and give it 10 seconds to die before
@@ -47,7 +49,7 @@ shutdown_server 10;
--move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t2.frm $MYSQLTEST_VARDIR/mysqld.1/data/test/t2.frm.tmp
# Attempt to restart the server
---exec echo "restart:--rocksdb_validate_tables=2" >$_expect_file_name
+--exec echo "restart:--rocksdb_validate_tables=2 --log-error=$LOG" >$_expect_file_name
--enable_reconnect
--source include/wait_until_connected_again.inc
@@ -55,21 +57,28 @@ shutdown_server 10;
# We should now have an error message
--echo "Expect errors that we are missing two .frm files"
---let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err
---let SEARCH_PATTERN=Schema mismatch
+#--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err
+#--let SEARCH_PATTERN=Schema mismatch
+#--source include/search_pattern_in_file.inc
+#--let SEARCH_PATTERN=RocksDB: Schema mismatch - Table test.t2 is registered in RocksDB but does not have a .frm file
+#--source include/search_pattern_in_file.inc
+--let SEARCH_FILE=$LOG
+--let SEARCH_PATTERN=RocksDB: Schema mismatch - Table test.t1 is registered in RocksDB but does not have a .frm file
+--source include/search_pattern_in_file.inc
+--let SEARCH_PATTERN=RocksDB: Schema mismatch - Table test.t2 is registered in RocksDB but does not have a .frm file
--source include/search_pattern_in_file.inc
# Now shut down again and rename one the .frm file back and make a copy of it
--exec echo "wait" >$_expect_file_name
shutdown_server 10;
-
+--remove_file $LOG
# Rename the file
--move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm.tmp $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm
--move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t2.frm.tmp $MYSQLTEST_VARDIR/mysqld.1/data/test/t2.frm
--copy_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm $MYSQLTEST_VARDIR/mysqld.1/data/test/t1_dummy.frm
# Attempt to restart the server
---exec echo "restart:--rocksdb_validate_tables=2" >$_expect_file_name
+--exec echo "restart:--rocksdb_validate_tables=2 --log-error=$LOG" >$_expect_file_name
--enable_reconnect
--source include/wait_until_connected_again.inc
@@ -77,7 +86,8 @@ shutdown_server 10;
# We should now have an error message for the second case
--echo "Expect an error that we have an extra .frm file"
---let SEARCH_PATTERN=Schema mismatch
+--let SEARCH_FILE=$LOG
+--let SEARCH_PATTERN=Schema mismatch - A .frm file exists for table test.t1_dummy, but that table is not registered in RocksDB
--source include/search_pattern_in_file.inc
# Shut down an clean up
@@ -89,6 +99,9 @@ shutdown_server 10;
--source include/wait_until_connected_again.inc
--disable_reconnect
+# Remove log file
+--remove_file $LOG
+
--disable_warnings
DROP TABLE t1, t2;
--enable_warnings
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/combinations b/storage/rocksdb/mysql-test/rocksdb_rpl/combinations
index f09d338c357..fe97111940a 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/combinations
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/combinations
@@ -1,2 +1,8 @@
-[row]
+[row-write-committed]
binlog-format=row
+rocksdb_write_policy=write_committed
+
+[row-write-prepared]
+binlog-format=row
+rocksdb_write_policy=write_prepared
+rocksdb_commit_time_batch_for_recovery=on
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_missing_columns_sk_update.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_missing_columns_sk_update.result
new file mode 100644
index 00000000000..19b0a191a1b
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_missing_columns_sk_update.result
@@ -0,0 +1,62 @@
+include/master-slave.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection master]
+set @@sql_log_bin = 0;
+CREATE TABLE `t1` (
+`a` int(10) unsigned NOT NULL DEFAULT '0',
+`b` bigint(20) unsigned NOT NULL DEFAULT '0',
+`c` bigint(20) unsigned NOT NULL DEFAULT '0',
+`d` bigint(20) unsigned NOT NULL DEFAULT '0',
+`e` varbinary(64) DEFAULT NULL,
+`f` int(10) NOT NULL DEFAULT '0',
+`g` int(10) NOT NULL DEFAULT '0',
+`h` int(10) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (`a`,`b`),
+KEY `key1` (`a`, `e`(1)),
+KEY `key2` (`a`,`h`)
+) ENGINE=RocksDB;
+set @@sql_log_bin = 1;
+set @@sql_log_bin = 0;
+CREATE TABLE `t1` (
+`a` int(10) unsigned NOT NULL DEFAULT '0',
+`b` bigint(20) unsigned NOT NULL DEFAULT '0',
+`c` bigint(20) unsigned NOT NULL DEFAULT '0',
+`d` bigint(20) unsigned NOT NULL DEFAULT '0',
+`e` varbinary(64) DEFAULT NULL,
+`f` int(10) NOT NULL DEFAULT '0',
+`g` int(10) NOT NULL DEFAULT '0',
+`x` TINYINT(3) UNSIGNED DEFAULT NULL,
+`y` INT(10) DEFAULT NULL,
+`h` int(10) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (`a`,`b`),
+KEY `key1` (`a`, `e`(1)),
+KEY `key2` (`a`,`h`)
+) ENGINE=RocksDB;
+set @@sql_log_bin = 1;
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'a', 1, 1, 1);
+SELECT * FROM t1;
+a b c d e f g h
+1 1 1 1 a 1 1 1
+SELECT * FROM t1;
+a b c d e f g x y h
+1 1 1 1 a 1 1 NULL NULL 1
+UPDATE t1 SET h = 10 WHERE h = 1;
+SELECT * FROM t1;
+a b c d e f g h
+1 1 1 1 a 1 1 10
+SELECT * FROM t1;
+a b c d e f g x y h
+1 1 1 1 a 1 1 NULL NULL 10
+SELECT COUNT(*) FROM t1 FORCE INDEX (key1) WHERE h = 10 AND a = 1;
+COUNT(*)
+1
+SELECT COUNT(*) FROM t1 FORCE INDEX (key2) WHERE h = 10 AND a = 1;
+COUNT(*)
+1
+SELECT COUNT(*) FROM t1 FORCE INDEX (PRIMARY) WHERE h = 10 AND a = 1;
+COUNT(*)
+1
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_mts_dependency_unique_key_conflicts.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_mts_dependency_unique_key_conflicts.result
new file mode 100644
index 00000000000..0eadc7deafe
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_mts_dependency_unique_key_conflicts.result
@@ -0,0 +1,44 @@
+include/master-slave.inc
+Warnings:
+Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
+Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
+[connection master]
+include/stop_slave.inc
+set @save.slave_parallel_workers= @@global.slave_parallel_workers;
+set @save.slave_use_idempotent_for_recovery= @@global.slave_use_idempotent_for_recovery;
+set @save.mts_dependency_replication= @@global.mts_dependency_replication;
+set @save.mts_dependency_order_commits= @@global.mts_dependency_order_commits;
+set @save.debug= @@global.debug;
+set @@global.slave_parallel_workers= 2;
+set @@global.slave_use_idempotent_for_recovery= YES;
+set @@global.mts_dependency_replication= STMT;
+set @@global.mts_dependency_order_commits= false;
+set @@global.debug= '+d,dbug.dep_wait_before_update_execution';
+include/start_slave.inc
+create table t1 (a int primary key, b int unique key) engine = rocksdb;
+insert into t1 values(1, 1);
+include/sync_slave_sql_with_master.inc
+include/stop_slave.inc
+update t1 set b = 2 where a = 1;
+insert into t1 values(2, 1);
+include/start_slave.inc
+set debug_sync="now wait_for signal.reached";
+select * from t1;
+a b
+1 1
+set debug_sync="now signal signal.done";
+include/sync_slave_sql_with_master.inc
+select * from t1;
+a b
+2 1
+1 2
+drop table t1;
+include/sync_slave_sql_with_master.inc
+include/stop_slave.inc
+set @@global.slave_parallel_workers= @save.slave_parallel_workers;
+set @@global.mts_dependency_replication= @save.mts_dependency_replication;
+set @@global.slave_use_idempotent_for_recovery= @save.slave_use_idempotent_for_recovery;
+set @@global.mts_dependency_order_commits= @save.mts_dependency_order_commits;
+set @@global.debug= @save.debug;
+include/start_slave.inc
+include/rpl_end.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_rocksdb_snapshot.result b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_rocksdb_snapshot.result
index eb2c6cfcda3..f5e861feddc 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_rocksdb_snapshot.result
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/r/rpl_rocksdb_snapshot.result
@@ -23,9 +23,9 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=rocksdb;
INSERT INTO t1 VALUES(1);
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
-ERROR HY000: Only REPEATABLE READ isolation level is supported for START TRANSACTION WITH CONSISTENT SNAPSHOT in RocksDB Storage Engine.
+ERROR HY000: Only REPEATABLE READ isolation level is supported for START TRANSACTION WITH CONSISTENT|SHARED|EXISTING SNAPSHOT in RocksDB Storage Engine.
START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT;
-ERROR HY000: Only REPEATABLE READ isolation level is supported for START TRANSACTION WITH CONSISTENT SNAPSHOT in RocksDB Storage Engine.
+ERROR HY000: Only REPEATABLE READ isolation level is supported for START TRANSACTION WITH CONSISTENT|SHARED|EXISTING SNAPSHOT in RocksDB Storage Engine.
ROLLBACK;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT;
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
index 956355dceee..3896a822872 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/disabled.def
@@ -9,6 +9,8 @@ rpl_skip_trx_api_binlog_format : requires @@rpl_skip_tx_api
rpl_ddl_high_priority : DDL commands with HIGH_PRIORITY syntax are not in MariaDB
rpl_gtid_rocksdb_sys_header : MariaDB doesn't support printing "RocksDB: Last MySQL Gtid UUID" into server stderr on startup
singledelete_idempotent_recovery: MariaDB doesn't support --slave-use-idempotent-for-recovery
+rpl_mts_dependency_unique_key_conflicts: MariaDB doesn't support --slave-use-idempotent-for-recovery
+rpl_missing_columns_sk_update : Uses log_column_names=ON feature which is only present in FB/MySQL
##
## Tests that do not fit MariaDB's test environment (Functional tests only,
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc
index 5e5961f3aef..16ad535ff9e 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_gtid_crash_safe_wal_corrupt.inc
@@ -42,7 +42,7 @@ select * from mysql.slave_gtid_info;
F=`ls -t $slave_data_dir/\#rocksdb/*.log | head -n 1`
SIZE=`stat -c %s $F`
-NEW_SIZE=`expr $SIZE - 10`
+NEW_SIZE=`expr $SIZE - 30`
truncate -s $NEW_SIZE $F
rc=$?
if [[ $rc != 0 ]]; then
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf
new file mode 100644
index 00000000000..92ed71986fe
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.cnf
@@ -0,0 +1,13 @@
+!include include/default_mysqld.cnf
+
+[mysqld.1]
+binlog_row_image = COMPLETE
+log_column_names= ON
+
+[mysqld.2]
+binlog_row_image = COMPLETE
+log_column_names= ON
+
+[ENV]
+SERVER_MYPORT_1= @mysqld.1.port
+SERVER_MYPORT_2= @mysqld.2.port
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test
new file mode 100644
index 00000000000..624f54ac326
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_missing_columns_sk_update.test
@@ -0,0 +1,69 @@
+source include/master-slave.inc;
+source include/have_binlog_format_row.inc;
+
+# Create a table with SKs on master
+connection master;
+set @@sql_log_bin = 0;
+CREATE TABLE `t1` (
+ `a` int(10) unsigned NOT NULL DEFAULT '0',
+ `b` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `c` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `d` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `e` varbinary(64) DEFAULT NULL,
+ `f` int(10) NOT NULL DEFAULT '0',
+ `g` int(10) NOT NULL DEFAULT '0',
+ `h` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`a`,`b`),
+ KEY `key1` (`a`, `e`(1)),
+ KEY `key2` (`a`,`h`)
+) ENGINE=RocksDB;
+set @@sql_log_bin = 1;
+
+# Create same table on slaves but with two extra columns in the middle (x, y)
+connection slave;
+set @@sql_log_bin = 0;
+CREATE TABLE `t1` (
+ `a` int(10) unsigned NOT NULL DEFAULT '0',
+ `b` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `c` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `d` bigint(20) unsigned NOT NULL DEFAULT '0',
+ `e` varbinary(64) DEFAULT NULL,
+ `f` int(10) NOT NULL DEFAULT '0',
+ `g` int(10) NOT NULL DEFAULT '0',
+ `x` TINYINT(3) UNSIGNED DEFAULT NULL,
+ `y` INT(10) DEFAULT NULL,
+ `h` int(10) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`a`,`b`),
+ KEY `key1` (`a`, `e`(1)),
+ KEY `key2` (`a`,`h`)
+) ENGINE=RocksDB;
+set @@sql_log_bin = 1;
+
+# Insert something in the table
+connection master;
+INSERT INTO t1 VALUES (1, 1, 1, 1, 'a', 1, 1, 1);
+SELECT * FROM t1;
+sync_slave_with_master;
+
+connection slave;
+SELECT * FROM t1;
+
+# Update a column that belongs to an SK
+connection master;
+UPDATE t1 SET h = 10 WHERE h = 1;
+SELECT * FROM t1;
+sync_slave_with_master;
+
+# Check if all keys are updated on the slave
+connection slave;
+SELECT * FROM t1;
+SELECT COUNT(*) FROM t1 FORCE INDEX (key1) WHERE h = 10 AND a = 1;
+SELECT COUNT(*) FROM t1 FORCE INDEX (key2) WHERE h = 10 AND a = 1;
+SELECT COUNT(*) FROM t1 FORCE INDEX (PRIMARY) WHERE h = 10 AND a = 1;
+
+# Cleanup
+connection master;
+DROP TABLE t1;
+sync_slave_with_master;
+
+source include/rpl_end.inc;
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test
new file mode 100644
index 00000000000..5869b9a39b9
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_mts_dependency_unique_key_conflicts.test
@@ -0,0 +1,64 @@
+# RocksDB clone of rpl_mts.rpl_mts_dependency_unique_key_conflicts
+source include/have_rocksdb.inc;
+source include/have_debug_sync.inc;
+source include/master-slave.inc;
+
+connection slave;
+source include/stop_slave.inc;
+set @save.slave_parallel_workers= @@global.slave_parallel_workers;
+set @save.slave_use_idempotent_for_recovery= @@global.slave_use_idempotent_for_recovery;
+set @save.mts_dependency_replication= @@global.mts_dependency_replication;
+set @save.mts_dependency_order_commits= @@global.mts_dependency_order_commits;
+set @save.debug= @@global.debug;
+set @@global.slave_parallel_workers= 2;
+set @@global.slave_use_idempotent_for_recovery= YES;
+set @@global.mts_dependency_replication= STMT;
+set @@global.mts_dependency_order_commits= false;
+set @@global.debug= '+d,dbug.dep_wait_before_update_execution';
+source include/start_slave.inc;
+
+connection master;
+create table t1 (a int primary key, b int unique key) engine = rocksdb;
+insert into t1 values(1, 1);
+source include/sync_slave_sql_with_master.inc;
+source include/stop_slave.inc;
+
+connection master;
+update t1 set b = 2 where a = 1; # this will stall on slave due to dbug_sync
+insert into t1 values(2, 1); # this should wait for the update to finish
+
+connection slave;
+source include/start_slave.inc;
+# wait till one of the workers reach the point just before execution of update
+set debug_sync="now wait_for signal.reached";
+
+# wait till the other worker is waiting after executing the table map for the
+# insert
+let $wait_condition=
+ select count(*)= 1 from information_schema.processlist
+ where state = 'Waiting for dependencies to be satisfied';
+source include/wait_condition.inc;
+
+select * from t1;
+set debug_sync="now signal signal.done";
+
+connection master;
+source include/sync_slave_sql_with_master.inc;
+
+connection slave;
+select * from t1;
+
+# Cleanup
+connection master;
+drop table t1;
+source include/sync_slave_sql_with_master.inc;
+connection slave;
+source include/stop_slave.inc;
+set @@global.slave_parallel_workers= @save.slave_parallel_workers;
+set @@global.mts_dependency_replication= @save.mts_dependency_replication;
+set @@global.slave_use_idempotent_for_recovery= @save.slave_use_idempotent_for_recovery;
+set @@global.mts_dependency_order_commits= @save.mts_dependency_order_commits;
+set @@global.debug= @save.debug;
+source include/start_slave.inc;
+
+source include/rpl_end.inc;
diff --git a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test
index 3aa006c84be..58b3720904c 100644
--- a/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test
+++ b/storage/rocksdb/mysql-test/rocksdb_rpl/t/rpl_rocksdb_2pc_crash_recover.test
@@ -1,6 +1,7 @@
--source include/have_binlog_format_row.inc
--source include/have_rocksdb.inc
--source include/have_debug.inc
+--source include/not_valgrind.inc
--disable_warnings
DROP TABLE IF EXISTS t1;
diff --git a/storage/rocksdb/mysql-test/rocksdb_stress/combinations b/storage/rocksdb/mysql-test/rocksdb_stress/combinations
new file mode 100644
index 00000000000..b7316c71485
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_stress/combinations
@@ -0,0 +1,5 @@
+[write_committed]
+rocksdb_write_policy=write_committed
+
+[write_prepared]
+rocksdb_write_policy=write_prepared
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_block_cache_size_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_block_cache_size_basic.result
index 1cfe5385d5c..b319c39a1cd 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_block_cache_size_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_block_cache_size_basic.result
@@ -1,7 +1,85 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(65536);
+INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(1*1024*1024);
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'bbb\'');
+INSERT INTO invalid_values VALUES('\'-1\'');
+INSERT INTO invalid_values VALUES('\'101\'');
+INSERT INTO invalid_values VALUES('\'484436\'');
SET @start_global_value = @@global.ROCKSDB_BLOCK_CACHE_SIZE;
SELECT @start_global_value;
@start_global_value
536870912
-"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 444. It should fail because it is readonly."
-SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 444;
-ERROR HY000: Variable 'rocksdb_block_cache_size' is a read only variable
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 65536"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 65536;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+65536
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = DEFAULT;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 1024"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 1024;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+1024
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = DEFAULT;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 1048576"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 1048576;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+1048576
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = DEFAULT;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@session.ROCKSDB_BLOCK_CACHE_SIZE to 444. It should fail because it is not session."
+SET @@session.ROCKSDB_BLOCK_CACHE_SIZE = 444;
+ERROR HY000: Variable 'rocksdb_block_cache_size' is a GLOBAL variable and should be set with SET GLOBAL
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 'aaa'"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to 'bbb'"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = 'bbb';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to '-1'"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = '-1';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to '101'"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = '101';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+"Trying to set variable @@global.ROCKSDB_BLOCK_CACHE_SIZE to '484436'"
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = '484436';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+SET @@global.ROCKSDB_BLOCK_CACHE_SIZE = @start_global_value;
+SELECT @@global.ROCKSDB_BLOCK_CACHE_SIZE;
+@@global.ROCKSDB_BLOCK_CACHE_SIZE
+536870912
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_bulk_load_allow_sk_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_bulk_load_allow_sk_basic.result
new file mode 100644
index 00000000000..c0d09d89c11
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_bulk_load_allow_sk_basic.result
@@ -0,0 +1,100 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(0);
+INSERT INTO valid_values VALUES('on');
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'bbb\'');
+SET @start_global_value = @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+SELECT @start_global_value;
+@start_global_value
+0
+SET @start_session_value = @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+SELECT @start_session_value;
+@start_session_value
+0
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_BULK_LOAD_ALLOW_SK to 1"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = 1;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Trying to set variable @@global.ROCKSDB_BULK_LOAD_ALLOW_SK to 0"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = 0;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Trying to set variable @@global.ROCKSDB_BULK_LOAD_ALLOW_SK to on"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = on;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+'# Setting to valid values in session scope#'
+"Trying to set variable @@session.ROCKSDB_BULK_LOAD_ALLOW_SK to 1"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = 1;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+1
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Trying to set variable @@session.ROCKSDB_BULK_LOAD_ALLOW_SK to 0"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = 0;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Trying to set variable @@session.ROCKSDB_BULK_LOAD_ALLOW_SK to on"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = on;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+1
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = DEFAULT;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_BULK_LOAD_ALLOW_SK to 'aaa'"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+"Trying to set variable @@global.ROCKSDB_BULK_LOAD_ALLOW_SK to 'bbb'"
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = 'bbb';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+SET @@global.ROCKSDB_BULK_LOAD_ALLOW_SK = @start_global_value;
+SELECT @@global.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@global.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+SET @@session.ROCKSDB_BULK_LOAD_ALLOW_SK = @start_session_value;
+SELECT @@session.ROCKSDB_BULK_LOAD_ALLOW_SK;
+@@session.ROCKSDB_BULK_LOAD_ALLOW_SK
+0
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_commit_time_batch_for_recovery_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_commit_time_batch_for_recovery_basic.result
new file mode 100644
index 00000000000..1d409bbedb4
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_commit_time_batch_for_recovery_basic.result
@@ -0,0 +1,121 @@
+CREATE TABLE valid_values (value varchar(255));
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(0);
+INSERT INTO valid_values VALUES('on');
+INSERT INTO valid_values VALUES('off');
+CREATE TABLE invalid_values (value varchar(255));
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'bbb\'');
+SET @start_global_value = @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+SELECT @start_global_value;
+@start_global_value
+0
+SET @start_session_value = @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+SELECT @start_session_value;
+@start_session_value
+0
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 1"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 1;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 0"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 0;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to on"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = on;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to off"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = off;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+'# Setting to valid values in session scope#'
+"Trying to set variable @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 1"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 1;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+1
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 0"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 0;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to on"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = on;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+1
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to off"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = off;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = DEFAULT;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 'aaa'"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+"Trying to set variable @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY to 'bbb'"
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = 'bbb';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+SET @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = @start_global_value;
+SELECT @@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@global.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+SET @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY = @start_session_value;
+SELECT @@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY;
+@@session.ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+0
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_create_checkpoint_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_create_checkpoint_basic.result
index ba280a32ab2..630fa78e933 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_create_checkpoint_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_create_checkpoint_basic.result
@@ -12,4 +12,4 @@ SET @@global.ROCKSDB_CREATE_CHECKPOINT = DEFAULT;
SET @@session.ROCKSDB_CREATE_CHECKPOINT = 444;
ERROR HY000: Variable 'rocksdb_create_checkpoint' is a GLOBAL variable and should be set with SET GLOBAL
SET @@global.ROCKSDB_CREATE_CHECKPOINT = @start_value;
-ERROR HY000: Status error 5 received from RocksDB: IO error: While renaming a file to : .tmp: No such file or directory
+ERROR HY000: Got error 4 'Invalid argument: invalid checkpoint directory name' from ROCKSDB
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_debug_manual_compaction_delay_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_debug_manual_compaction_delay_basic.result
new file mode 100644
index 00000000000..6c5db01533b
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_debug_manual_compaction_delay_basic.result
@@ -0,0 +1,46 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(2400);
+INSERT INTO valid_values VALUES(100000);
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+SET @start_global_value = @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+SELECT @start_global_value;
+@start_global_value
+0
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY to 2400"
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = 2400;
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+2400
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = DEFAULT;
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+0
+"Trying to set variable @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY to 100000"
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = 100000;
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+100000
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = DEFAULT;
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+0
+"Trying to set variable @@session.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY to 444. It should fail because it is not session."
+SET @@session.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = 444;
+ERROR HY000: Variable 'rocksdb_debug_manual_compaction_delay' is a GLOBAL variable and should be set with SET GLOBAL
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY to 'aaa'"
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+0
+SET @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY = @start_global_value;
+SELECT @@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY;
+@@global.ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+0
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_error_on_suboptimal_collation_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_error_on_suboptimal_collation_basic.result
new file mode 100644
index 00000000000..e10583bff09
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_error_on_suboptimal_collation_basic.result
@@ -0,0 +1,7 @@
+SET @start_global_value = @@global.ROCKSDB_ERROR_ON_SUBOPTIMAL_COLLATION;
+SELECT @start_global_value;
+@start_global_value
+1
+"Trying to set variable @@global.ROCKSDB_ERROR_ON_SUBOPTIMAL_COLLATION to 444. It should fail because it is readonly."
+SET @@global.ROCKSDB_ERROR_ON_SUBOPTIMAL_COLLATION = 444;
+ERROR HY000: Variable 'rocksdb_error_on_suboptimal_collation' is a read only variable
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_manual_compaction_threads_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_manual_compaction_threads_basic.result
new file mode 100644
index 00000000000..3d599e1768e
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_manual_compaction_threads_basic.result
@@ -0,0 +1,93 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(0);
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(99);
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+SET @start_global_value = @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+SELECT @start_global_value;
+@start_global_value
+0
+SET @start_session_value = @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+SELECT @start_session_value;
+@start_session_value
+0
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_MANUAL_COMPACTION_THREADS to 0"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = 0;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Trying to set variable @@global.ROCKSDB_MANUAL_COMPACTION_THREADS to 1"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = 1;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Trying to set variable @@global.ROCKSDB_MANUAL_COMPACTION_THREADS to 99"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = 99;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+99
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+'# Setting to valid values in session scope#'
+"Trying to set variable @@session.ROCKSDB_MANUAL_COMPACTION_THREADS to 0"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = 0;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Trying to set variable @@session.ROCKSDB_MANUAL_COMPACTION_THREADS to 1"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = 1;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+1
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+"Trying to set variable @@session.ROCKSDB_MANUAL_COMPACTION_THREADS to 99"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = 99;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+99
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = DEFAULT;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_MANUAL_COMPACTION_THREADS to 'aaa'"
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+SET @@global.ROCKSDB_MANUAL_COMPACTION_THREADS = @start_global_value;
+SELECT @@global.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@global.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+SET @@session.ROCKSDB_MANUAL_COMPACTION_THREADS = @start_session_value;
+SELECT @@session.ROCKSDB_MANUAL_COMPACTION_THREADS;
+@@session.ROCKSDB_MANUAL_COMPACTION_THREADS
+0
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manifest_file_size_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manifest_file_size_basic.result
index 27cddc9f60a..45330b82702 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manifest_file_size_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manifest_file_size_basic.result
@@ -1,7 +1,7 @@
SET @start_global_value = @@global.ROCKSDB_MAX_MANIFEST_FILE_SIZE;
SELECT @start_global_value;
@start_global_value
-18446744073709551615
+1073741824
"Trying to set variable @@global.ROCKSDB_MAX_MANIFEST_FILE_SIZE to 444. It should fail because it is readonly."
SET @@global.ROCKSDB_MAX_MANIFEST_FILE_SIZE = 444;
ERROR HY000: Variable 'rocksdb_max_manifest_file_size' is a read only variable
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manual_compactions_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manual_compactions_basic.result
new file mode 100644
index 00000000000..815506ccac8
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_manual_compactions_basic.result
@@ -0,0 +1,57 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(512*1024*1024);
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+SET @start_global_value = @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+SELECT @start_global_value;
+@start_global_value
+10
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS to 1"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = 1;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = DEFAULT;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+10
+"Trying to set variable @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS to 1024"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = 1024;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+1024
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = DEFAULT;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+10
+"Trying to set variable @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS to 536870912"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = 536870912;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+536870912
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = DEFAULT;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+10
+"Trying to set variable @@session.ROCKSDB_MAX_MANUAL_COMPACTIONS to 444. It should fail because it is not session."
+SET @@session.ROCKSDB_MAX_MANUAL_COMPACTIONS = 444;
+ERROR HY000: Variable 'rocksdb_max_manual_compactions' is a GLOBAL variable and should be set with SET GLOBAL
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS to 'aaa'"
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+10
+SET @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS = @start_global_value;
+SELECT @@global.ROCKSDB_MAX_MANUAL_COMPACTIONS;
+@@global.ROCKSDB_MAX_MANUAL_COMPACTIONS
+10
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_row_locks_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_row_locks_basic.result
index c925a68d4ed..b195df092dc 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_row_locks_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_max_row_locks_basic.result
@@ -1,6 +1,7 @@
CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO valid_values VALUES(1);
INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(512*1024*1024);
CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO invalid_values VALUES('\'aaa\'');
SET @start_global_value = @@global.ROCKSDB_MAX_ROW_LOCKS;
@@ -32,6 +33,16 @@ SET @@global.ROCKSDB_MAX_ROW_LOCKS = DEFAULT;
SELECT @@global.ROCKSDB_MAX_ROW_LOCKS;
@@global.ROCKSDB_MAX_ROW_LOCKS
1048576
+"Trying to set variable @@global.ROCKSDB_MAX_ROW_LOCKS to 536870912"
+SET @@global.ROCKSDB_MAX_ROW_LOCKS = 536870912;
+SELECT @@global.ROCKSDB_MAX_ROW_LOCKS;
+@@global.ROCKSDB_MAX_ROW_LOCKS
+536870912
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_MAX_ROW_LOCKS = DEFAULT;
+SELECT @@global.ROCKSDB_MAX_ROW_LOCKS;
+@@global.ROCKSDB_MAX_ROW_LOCKS
+1048576
'# Setting to valid values in session scope#'
"Trying to set variable @@session.ROCKSDB_MAX_ROW_LOCKS to 1"
SET @@session.ROCKSDB_MAX_ROW_LOCKS = 1;
@@ -53,6 +64,16 @@ SET @@session.ROCKSDB_MAX_ROW_LOCKS = DEFAULT;
SELECT @@session.ROCKSDB_MAX_ROW_LOCKS;
@@session.ROCKSDB_MAX_ROW_LOCKS
1048576
+"Trying to set variable @@session.ROCKSDB_MAX_ROW_LOCKS to 536870912"
+SET @@session.ROCKSDB_MAX_ROW_LOCKS = 536870912;
+SELECT @@session.ROCKSDB_MAX_ROW_LOCKS;
+@@session.ROCKSDB_MAX_ROW_LOCKS
+536870912
+"Setting the session scope variable back to default"
+SET @@session.ROCKSDB_MAX_ROW_LOCKS = DEFAULT;
+SELECT @@session.ROCKSDB_MAX_ROW_LOCKS;
+@@session.ROCKSDB_MAX_ROW_LOCKS
+1048576
'# Testing with invalid values in global scope #'
"Trying to set variable @@global.ROCKSDB_MAX_ROW_LOCKS to 'aaa'"
SET @@global.ROCKSDB_MAX_ROW_LOCKS = 'aaa';
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_stats_recalc_rate_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_stats_recalc_rate_basic.result
new file mode 100644
index 00000000000..4f337b84e3c
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_stats_recalc_rate_basic.result
@@ -0,0 +1,53 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(100);
+INSERT INTO valid_values VALUES(1);
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'123\'');
+SET @start_global_value = @@global.ROCKSDB_STATS_RECALC_RATE;
+SELECT @start_global_value;
+@start_global_value
+0
+'# Setting to valid values in global scope#'
+"Trying to set variable @@global.ROCKSDB_STATS_RECALC_RATE to 100"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = 100;
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+100
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = DEFAULT;
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+0
+"Trying to set variable @@global.ROCKSDB_STATS_RECALC_RATE to 1"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = 1;
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+1
+"Setting the global scope variable back to default"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = DEFAULT;
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+0
+"Trying to set variable @@session.ROCKSDB_STATS_RECALC_RATE to 444. It should fail because it is not session."
+SET @@session.ROCKSDB_STATS_RECALC_RATE = 444;
+ERROR HY000: Variable 'rocksdb_stats_recalc_rate' is a GLOBAL variable and should be set with SET GLOBAL
+'# Testing with invalid values in global scope #'
+"Trying to set variable @@global.ROCKSDB_STATS_RECALC_RATE to 'aaa'"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = 'aaa';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+0
+"Trying to set variable @@global.ROCKSDB_STATS_RECALC_RATE to '123'"
+SET @@global.ROCKSDB_STATS_RECALC_RATE = '123';
+Got one of the listed errors
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+0
+SET @@global.ROCKSDB_STATS_RECALC_RATE = @start_global_value;
+SELECT @@global.ROCKSDB_STATS_RECALC_RATE;
+@@global.ROCKSDB_STATS_RECALC_RATE
+0
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_batch_max_bytes_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_batch_max_bytes_basic.result
index af4da8177d4..8f6d91b2780 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_batch_max_bytes_basic.result
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_batch_max_bytes_basic.result
@@ -4,12 +4,12 @@ set session rocksdb_write_batch_max_bytes = 1000;
insert into t values (1), (2), (3), (4), (5);
set session rocksdb_write_batch_max_bytes = 10;
insert into t values (1), (2), (3), (4), (5);
-ERROR HY000: Status error 10 received from RocksDB: Operation aborted: Memory limit reached
+ERROR HY000: Got error 10 'Operation aborted: Memory limit reached' from ROCKSDB
set session rocksdb_write_batch_max_bytes = 0;
insert into t values (1), (2), (3), (4), (5);
set session rocksdb_write_batch_max_bytes = 10;
begin;
insert into t values (1), (2), (3), (4), (5);
-ERROR HY000: Status error 10 received from RocksDB: Operation aborted: Memory limit reached
+ERROR HY000: Got error 10 'Operation aborted: Memory limit reached' from ROCKSDB
rollback;
drop table t;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_policy_basic.result b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_policy_basic.result
new file mode 100644
index 00000000000..58e040e05f1
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/r/rocksdb_write_policy_basic.result
@@ -0,0 +1,15 @@
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES("write_committed");
+INSERT INTO valid_values VALUES("write_prepared");
+INSERT INTO valid_values VALUES("write_unprepared");
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+SET @start_global_value = @@global.ROCKSDB_WRITE_POLICY;
+SELECT @start_global_value;
+@start_global_value
+write_committed
+"Trying to set variable @@global.ROCKSDB_WRITE_POLICY to 444. It should fail because it is readonly."
+SET @@global.ROCKSDB_WRITE_POLICY = 444;
+ERROR HY000: Variable 'rocksdb_write_policy' is a read only variable
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_block_cache_size_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_block_cache_size_basic.test
index 39688e63556..8d3bab4e5ec 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_block_cache_size_basic.test
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_block_cache_size_basic.test
@@ -1,7 +1,21 @@
--source include/have_rocksdb.inc
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(65536);
+INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(1*1024*1024);
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'bbb\'');
+INSERT INTO invalid_values VALUES('\'-1\'');
+INSERT INTO invalid_values VALUES('\'101\'');
+INSERT INTO invalid_values VALUES('\'484436\'');
+
--let $sys_var=ROCKSDB_BLOCK_CACHE_SIZE
---let $read_only=1
+--let $read_only=0
--let $session=0
--source include/rocksdb_sys_var.inc
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_bulk_load_allow_sk_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_bulk_load_allow_sk_basic.test
new file mode 100644
index 00000000000..14e5f38b335
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_bulk_load_allow_sk_basic.test
@@ -0,0 +1,18 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(0);
+INSERT INTO valid_values VALUES('on');
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'bbb\'');
+
+--let $sys_var=ROCKSDB_BULK_LOAD_ALLOW_SK
+--let $read_only=0
+--let $session=1
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_commit_time_batch_for_recovery_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_commit_time_batch_for_recovery_basic.test
new file mode 100644
index 00000000000..0d36e0a173d
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_commit_time_batch_for_recovery_basic.test
@@ -0,0 +1,20 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255));
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(0);
+INSERT INTO valid_values VALUES('on');
+INSERT INTO valid_values VALUES('off');
+
+CREATE TABLE invalid_values (value varchar(255));
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'bbb\'');
+
+--let $sys_var=ROCKSDB_COMMIT_TIME_BATCH_FOR_RECOVERY
+--let $read_only=0
+--let $session=1
+--let $sticky=1
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_create_checkpoint_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_create_checkpoint_basic.test
index a53df21524f..32d4a6a23bc 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_create_checkpoint_basic.test
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_create_checkpoint_basic.test
@@ -21,7 +21,7 @@
# Set back to original value
# validate that DEFAULT causes failure in creating checkpoint since
# DEFAULT == ''
---error ER_RDB_STATUS_GENERAL
+--error ER_GET_ERRMSG
--eval SET @@global.ROCKSDB_CREATE_CHECKPOINT = @start_value
# clean up
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_debug_manual_compaction_delay_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_debug_manual_compaction_delay_basic.test
new file mode 100644
index 00000000000..518c284c0cf
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_debug_manual_compaction_delay_basic.test
@@ -0,0 +1,16 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(2400);
+INSERT INTO valid_values VALUES(100000);
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+
+--let $sys_var=ROCKSDB_DEBUG_MANUAL_COMPACTION_DELAY
+--let $read_only=0
+--let $session=0
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_error_on_suboptimal_collation_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_error_on_suboptimal_collation_basic.test
new file mode 100644
index 00000000000..9278fa31933
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_error_on_suboptimal_collation_basic.test
@@ -0,0 +1,6 @@
+--source include/have_rocksdb.inc
+
+--let $sys_var=ROCKSDB_ERROR_ON_SUBOPTIMAL_COLLATION
+--let $read_only=1
+--let $session=0
+--source ../include/rocksdb_sys_var.inc
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_manual_compaction_threads_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_manual_compaction_threads_basic.test
new file mode 100644
index 00000000000..4f166a9ca8e
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_manual_compaction_threads_basic.test
@@ -0,0 +1,17 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(0);
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(99);
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+
+--let $sys_var=ROCKSDB_MANUAL_COMPACTION_THREADS
+--let $read_only=0
+--let $session=1
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_manual_compactions_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_manual_compactions_basic.test
new file mode 100644
index 00000000000..1c66316858b
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_manual_compactions_basic.test
@@ -0,0 +1,17 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(1);
+INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(512*1024*1024);
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+
+--let $sys_var=ROCKSDB_MAX_MANUAL_COMPACTIONS
+--let $read_only=0
+--let $session=0
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_row_locks_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_row_locks_basic.test
index 4eb00329cf2..8a26ae91411 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_row_locks_basic.test
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_max_row_locks_basic.test
@@ -3,6 +3,7 @@
CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO valid_values VALUES(1);
INSERT INTO valid_values VALUES(1024);
+INSERT INTO valid_values VALUES(512*1024*1024);
CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
INSERT INTO invalid_values VALUES('\'aaa\'');
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_stats_recalc_rate_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_stats_recalc_rate_basic.test
new file mode 100644
index 00000000000..a3b9059b2b1
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_stats_recalc_rate_basic.test
@@ -0,0 +1,17 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES(100);
+INSERT INTO valid_values VALUES(1);
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+INSERT INTO invalid_values VALUES('\'123\'');
+
+--let $sys_var=ROCKSDB_STATS_RECALC_RATE
+--let $read_only=0
+--let $session=0
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_batch_max_bytes_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_batch_max_bytes_basic.test
index 295d8e1594b..40d22373fbe 100644
--- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_batch_max_bytes_basic.test
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_batch_max_bytes_basic.test
@@ -10,7 +10,7 @@ insert into t values (1), (2), (3), (4), (5);
set session rocksdb_write_batch_max_bytes = 10;
---error ER_RDB_STATUS_GENERAL
+--error ER_GET_ERRMSG
insert into t values (1), (2), (3), (4), (5);
set session rocksdb_write_batch_max_bytes = 0;
@@ -19,7 +19,7 @@ insert into t values (1), (2), (3), (4), (5);
set session rocksdb_write_batch_max_bytes = 10;
begin;
---error ER_RDB_STATUS_GENERAL
+--error ER_GET_ERRMSG
insert into t values (1), (2), (3), (4), (5);
rollback;
diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_policy_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_policy_basic.test
new file mode 100644
index 00000000000..720b9d67378
--- /dev/null
+++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_write_policy_basic.test
@@ -0,0 +1,17 @@
+--source include/have_rocksdb.inc
+
+CREATE TABLE valid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO valid_values VALUES("write_committed");
+INSERT INTO valid_values VALUES("write_prepared");
+INSERT INTO valid_values VALUES("write_unprepared");
+
+CREATE TABLE invalid_values (value varchar(255)) ENGINE=myisam;
+INSERT INTO invalid_values VALUES('\'aaa\'');
+
+--let $sys_var=ROCKSDB_WRITE_POLICY
+--let $read_only=1
+--let $session=0
+--source ../include/rocksdb_sys_var.inc
+
+DROP TABLE valid_values;
+DROP TABLE invalid_values;
diff --git a/storage/rocksdb/properties_collector.cc b/storage/rocksdb/properties_collector.cc
index c2bfb2b0474..6670e9d69f9 100644
--- a/storage/rocksdb/properties_collector.cc
+++ b/storage/rocksdb/properties_collector.cc
@@ -56,7 +56,7 @@ Rdb_tbl_prop_coll::Rdb_tbl_prop_coll(Rdb_ddl_manager *const ddl_manager,
: m_cf_id(cf_id), m_ddl_manager(ddl_manager), m_last_stats(nullptr),
m_rows(0l), m_window_pos(0l), m_deleted_rows(0l), m_max_deleted_rows(0l),
m_file_size(0), m_params(params),
- m_cardinality_collector(table_stats_sampling_pct) {
+ m_cardinality_collector(table_stats_sampling_pct), m_recorded(false) {
DBUG_ASSERT(ddl_manager != nullptr);
m_deleted_rows_window.resize(m_params.m_window, false);
@@ -212,28 +212,31 @@ Rdb_tbl_prop_coll::Finish(rocksdb::UserCollectedProperties *const properties) {
num_sst_entry_other += it->m_entry_others;
}
- if (num_sst_entry_put > 0) {
- rocksdb_num_sst_entry_put += num_sst_entry_put;
- }
+ if (!m_recorded) {
+ if (num_sst_entry_put > 0) {
+ rocksdb_num_sst_entry_put += num_sst_entry_put;
+ }
- if (num_sst_entry_delete > 0) {
- rocksdb_num_sst_entry_delete += num_sst_entry_delete;
- }
+ if (num_sst_entry_delete > 0) {
+ rocksdb_num_sst_entry_delete += num_sst_entry_delete;
+ }
- if (num_sst_entry_singledelete > 0) {
- rocksdb_num_sst_entry_singledelete += num_sst_entry_singledelete;
- }
+ if (num_sst_entry_singledelete > 0) {
+ rocksdb_num_sst_entry_singledelete += num_sst_entry_singledelete;
+ }
- if (num_sst_entry_merge > 0) {
- rocksdb_num_sst_entry_merge += num_sst_entry_merge;
- }
+ if (num_sst_entry_merge > 0) {
+ rocksdb_num_sst_entry_merge += num_sst_entry_merge;
+ }
- if (num_sst_entry_other > 0) {
- rocksdb_num_sst_entry_other += num_sst_entry_other;
- }
+ if (num_sst_entry_other > 0) {
+ rocksdb_num_sst_entry_other += num_sst_entry_other;
+ }
- for (Rdb_index_stats &stat : m_stats) {
- m_cardinality_collector.AdjustStats(&stat);
+ for (Rdb_index_stats &stat : m_stats) {
+ m_cardinality_collector.AdjustStats(&stat);
+ }
+ m_recorded = true;
}
properties->insert({INDEXSTATS_KEY, Rdb_index_stats::materialize(m_stats)});
return rocksdb::Status::OK();
@@ -443,15 +446,8 @@ void Rdb_index_stats::merge(const Rdb_index_stats &s, const bool &increment,
m_entry_single_deletes += s.m_entry_single_deletes;
m_entry_merges += s.m_entry_merges;
m_entry_others += s.m_entry_others;
- if (s.m_distinct_keys_per_prefix.size() > 0) {
- for (i = 0; i < s.m_distinct_keys_per_prefix.size(); i++) {
- m_distinct_keys_per_prefix[i] += s.m_distinct_keys_per_prefix[i];
- }
- } else {
- for (i = 0; i < m_distinct_keys_per_prefix.size(); i++) {
- m_distinct_keys_per_prefix[i] +=
- s.m_rows >> (m_distinct_keys_per_prefix.size() - i - 1);
- }
+ for (i = 0; i < s.m_distinct_keys_per_prefix.size(); i++) {
+ m_distinct_keys_per_prefix[i] += s.m_distinct_keys_per_prefix[i];
}
} else {
m_rows -= s.m_rows;
@@ -462,15 +458,8 @@ void Rdb_index_stats::merge(const Rdb_index_stats &s, const bool &increment,
m_entry_single_deletes -= s.m_entry_single_deletes;
m_entry_merges -= s.m_entry_merges;
m_entry_others -= s.m_entry_others;
- if (s.m_distinct_keys_per_prefix.size() > 0) {
- for (i = 0; i < s.m_distinct_keys_per_prefix.size(); i++) {
- m_distinct_keys_per_prefix[i] -= s.m_distinct_keys_per_prefix[i];
- }
- } else {
- for (i = 0; i < m_distinct_keys_per_prefix.size(); i++) {
- m_distinct_keys_per_prefix[i] -=
- s.m_rows >> (m_distinct_keys_per_prefix.size() - i - 1);
- }
+ for (i = 0; i < s.m_distinct_keys_per_prefix.size(); i++) {
+ m_distinct_keys_per_prefix[i] -= s.m_distinct_keys_per_prefix[i];
}
}
}
diff --git a/storage/rocksdb/properties_collector.h b/storage/rocksdb/properties_collector.h
index 1441d893420..c4a48265a50 100644
--- a/storage/rocksdb/properties_collector.h
+++ b/storage/rocksdb/properties_collector.h
@@ -118,7 +118,7 @@ public:
const rocksdb::Slice &value,
rocksdb::EntryType type,
rocksdb::SequenceNumber seq,
- uint64_t file_size);
+ uint64_t file_size) override;
virtual rocksdb::Status
Finish(rocksdb::UserCollectedProperties *properties) override;
@@ -164,6 +164,7 @@ private:
uint64_t m_file_size;
Rdb_compact_params m_params;
Rdb_tbl_card_coll m_cardinality_collector;
+ bool m_recorded;
};
class Rdb_tbl_prop_coll_factory
diff --git a/storage/rocksdb/rdb_cf_options.cc b/storage/rocksdb/rdb_cf_options.cc
index 96a683e5eb3..9569e81472b 100644
--- a/storage/rocksdb/rdb_cf_options.cc
+++ b/storage/rocksdb/rdb_cf_options.cc
@@ -334,8 +334,6 @@ Rdb_cf_options::get_cf_merge_operator(const std::string &cf_name) {
void Rdb_cf_options::get_cf_options(const std::string &cf_name,
rocksdb::ColumnFamilyOptions *const opts) {
- DBUG_ASSERT(opts != nullptr);
-
*opts = m_default_cf_opts;
get(cf_name, opts);
diff --git a/storage/rocksdb/rdb_comparator.h b/storage/rocksdb/rdb_comparator.h
index 47b83abc70a..963a8615c6b 100644
--- a/storage/rocksdb/rdb_comparator.h
+++ b/storage/rocksdb/rdb_comparator.h
@@ -41,27 +41,9 @@ public:
Rdb_pk_comparator &operator=(const Rdb_pk_comparator &) = delete;
Rdb_pk_comparator() = default;
- static int bytewise_compare(const rocksdb::Slice &a,
- const rocksdb::Slice &b) {
- const size_t a_size = a.size();
- const size_t b_size = b.size();
- const size_t len = (a_size < b_size) ? a_size : b_size;
- int res;
-
- if ((res = memcmp(a.data(), b.data(), len)))
- return res;
-
- /* Ok, res== 0 */
- if (a_size != b_size) {
- return a_size < b_size ? -1 : 1;
- }
- return HA_EXIT_SUCCESS;
- }
-
- /* Override virtual methods of interest */
-
+ // extracting from rocksdb::BytewiseComparator()->Compare() for optimization
int Compare(const rocksdb::Slice &a, const rocksdb::Slice &b) const override {
- return bytewise_compare(a, b);
+ return a.compare(b);
}
const char *Name() const override { return "RocksDB_SE_v3.10"; }
@@ -72,8 +54,12 @@ public:
// for now, do-nothing implementations:
void FindShortestSeparator(std::string *start,
- const rocksdb::Slice &limit) const override {}
- void FindShortSuccessor(std::string *key) const override {}
+ const rocksdb::Slice &limit) const override {
+ rocksdb::BytewiseComparator()->FindShortestSeparator(start, limit);
+ }
+ void FindShortSuccessor(std::string *key) const override {
+ rocksdb::BytewiseComparator()->FindShortSuccessor(key);
+ }
};
class Rdb_rev_comparator : public rocksdb::Comparator {
@@ -82,18 +68,18 @@ public:
Rdb_rev_comparator &operator=(const Rdb_rev_comparator &) = delete;
Rdb_rev_comparator() = default;
- static int bytewise_compare(const rocksdb::Slice &a,
- const rocksdb::Slice &b) {
- return -Rdb_pk_comparator::bytewise_compare(a, b);
- }
-
+ // extracting from rocksdb::BytewiseComparator()->Compare() for optimization
int Compare(const rocksdb::Slice &a, const rocksdb::Slice &b) const override {
- return -Rdb_pk_comparator::bytewise_compare(a, b);
+ return -a.compare(b);
}
const char *Name() const override { return "rev:RocksDB_SE_v3.10"; }
void FindShortestSeparator(std::string *start,
- const rocksdb::Slice &limit) const override {}
- void FindShortSuccessor(std::string *key) const override {}
+ const rocksdb::Slice &limit) const override {
+ rocksdb::ReverseBytewiseComparator()->FindShortestSeparator(start, limit);
+ }
+ void FindShortSuccessor(std::string *key) const override {
+ rocksdb::ReverseBytewiseComparator()->FindShortSuccessor(key);
+ }
};
} // namespace myrocks
diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc
index 5664bd901b3..32b01a698e1 100644
--- a/storage/rocksdb/rdb_datadic.cc
+++ b/storage/rocksdb/rdb_datadic.cc
@@ -4583,7 +4583,7 @@ void Rdb_binlog_manager::update_slave_gtid_info(
}
}
-bool Rdb_dict_manager::init(rocksdb::DB *const rdb_dict,
+bool Rdb_dict_manager::init(rocksdb::TransactionDB *const rdb_dict,
Rdb_cf_manager *const cf_manager) {
DBUG_ASSERT(rdb_dict != nullptr);
DBUG_ASSERT(cf_manager != nullptr);
@@ -4657,7 +4657,9 @@ int Rdb_dict_manager::commit(rocksdb::WriteBatch *const batch,
int res = HA_EXIT_SUCCESS;
rocksdb::WriteOptions options;
options.sync = sync;
- rocksdb::Status s = m_db->Write(options, batch);
+ rocksdb::TransactionDBWriteOptimizations optimize;
+ optimize.skip_concurrency_control = true;
+ rocksdb::Status s = m_db->Write(options, optimize, batch);
res = !s.ok(); // we return true when something failed
if (res) {
rdb_handle_io_error(s, RDB_IO_ERROR_DICT_COMMIT);
diff --git a/storage/rocksdb/rdb_datadic.h b/storage/rocksdb/rdb_datadic.h
index 585ea4344f9..1385709a1c9 100644
--- a/storage/rocksdb/rdb_datadic.h
+++ b/storage/rocksdb/rdb_datadic.h
@@ -1261,7 +1261,7 @@ private:
class Rdb_dict_manager {
private:
mysql_mutex_t m_mutex;
- rocksdb::DB *m_db = nullptr;
+ rocksdb::TransactionDB *m_db = nullptr;
rocksdb::ColumnFamilyHandle *m_system_cfh = nullptr;
/* Utility to put INDEX_INFO and CF_DEFINITION */
@@ -1287,7 +1287,8 @@ public:
Rdb_dict_manager &operator=(const Rdb_dict_manager &) = delete;
Rdb_dict_manager() = default;
- bool init(rocksdb::DB *const rdb_dict, Rdb_cf_manager *const cf_manager);
+ bool init(rocksdb::TransactionDB *const rdb_dict,
+ Rdb_cf_manager *const cf_manager);
inline void cleanup() { mysql_mutex_destroy(&m_mutex); }
diff --git a/storage/rocksdb/rdb_i_s.cc b/storage/rocksdb/rdb_i_s.cc
index 591d4923ca2..59ae6821214 100644
--- a/storage/rocksdb/rdb_i_s.cc
+++ b/storage/rocksdb/rdb_i_s.cc
@@ -1130,6 +1130,150 @@ static std::string rdb_filename_without_path(const std::string &path) {
}
/*
+ Support for INFORMATION_SCHEMA.ROCKSDB_SST_PROPS dynamic table
+ */
+namespace RDB_SST_PROPS_FIELD {
+enum {
+ SST_NAME = 0,
+ COLUMN_FAMILY,
+ DATA_BLOCKS,
+ ENTRIES,
+ RAW_KEY_SIZE,
+ RAW_VALUE_SIZE,
+ DATA_BLOCK_SIZE,
+ INDEX_BLOCK_SIZE,
+ INDEX_PARTITIONS,
+ TOP_LEVEL_INDEX_SIZE,
+ FILTER_BLOCK_SIZE,
+ COMPRESSION_ALGO,
+ CREATION_TIME
+};
+} // namespace RDB_SST_PROPS_FIELD
+
+static ST_FIELD_INFO rdb_i_s_sst_props_fields_info[] = {
+ ROCKSDB_FIELD_INFO("SST_NAME", NAME_LEN + 1, MYSQL_TYPE_STRING, 0),
+ ROCKSDB_FIELD_INFO("COLUMN_FAMILY", sizeof(uint32_t), MYSQL_TYPE_LONG, 0),
+ ROCKSDB_FIELD_INFO("DATA_BLOCKS", sizeof(int64_t), MYSQL_TYPE_LONGLONG, 0),
+ ROCKSDB_FIELD_INFO("ENTRIES", sizeof(int64_t), MYSQL_TYPE_LONGLONG, 0),
+ ROCKSDB_FIELD_INFO("RAW_KEY_SIZE", sizeof(int64_t), MYSQL_TYPE_LONGLONG, 0),
+ ROCKSDB_FIELD_INFO("RAW_VALUE_SIZE", sizeof(int64_t), MYSQL_TYPE_LONGLONG,
+ 0),
+ ROCKSDB_FIELD_INFO("DATA_BLOCK_SIZE", sizeof(int64_t), MYSQL_TYPE_LONGLONG,
+ 0),
+ ROCKSDB_FIELD_INFO("INDEX_BLOCK_SIZE", sizeof(int64_t), MYSQL_TYPE_LONGLONG,
+ 0),
+ ROCKSDB_FIELD_INFO("INDEX_PARTITIONS", sizeof(uint32_t), MYSQL_TYPE_LONG,
+ 0),
+ ROCKSDB_FIELD_INFO("TOP_LEVEL_INDEX_SIZE", sizeof(int64_t),
+ MYSQL_TYPE_LONGLONG, 0),
+ ROCKSDB_FIELD_INFO("FILTER_BLOCK_SIZE", sizeof(int64_t),
+ MYSQL_TYPE_LONGLONG, 0),
+ ROCKSDB_FIELD_INFO("COMPRESSION_ALGO", NAME_LEN + 1, MYSQL_TYPE_STRING, 0),
+ ROCKSDB_FIELD_INFO("CREATION_TIME", sizeof(int64_t), MYSQL_TYPE_LONGLONG,
+ 0),
+ ROCKSDB_FIELD_INFO_END};
+
+static int rdb_i_s_sst_props_fill_table(
+ my_core::THD *const thd, my_core::TABLE_LIST *const tables,
+ my_core::Item *const cond MY_ATTRIBUTE((__unused__))) {
+ DBUG_ENTER_FUNC();
+
+ DBUG_ASSERT(thd != nullptr);
+ DBUG_ASSERT(tables != nullptr);
+ DBUG_ASSERT(tables->table != nullptr);
+
+ int ret = 0;
+ Field **field = tables->table->field;
+ DBUG_ASSERT(field != nullptr);
+
+ /* Iterate over all the column families */
+ rocksdb::DB *const rdb = rdb_get_rocksdb_db();
+
+ if (!rdb) {
+ DBUG_RETURN(ret);
+ }
+
+ const Rdb_cf_manager &cf_manager = rdb_get_cf_manager();
+
+ for (const auto &cf_handle : cf_manager.get_all_cf()) {
+ /* Grab the the properties of all the tables in the column family */
+ rocksdb::TablePropertiesCollection table_props_collection;
+ const rocksdb::Status s =
+ rdb->GetPropertiesOfAllTables(cf_handle, &table_props_collection);
+
+ if (!s.ok()) {
+ continue;
+ }
+
+ /* Iterate over all the items in the collection, each of which contains a
+ * name and the actual properties */
+ for (const auto &props : table_props_collection) {
+ /* Add the SST name into the output */
+ const std::string sst_name = rdb_filename_without_path(props.first);
+
+ field[RDB_SST_PROPS_FIELD::SST_NAME]->store(
+ sst_name.data(), sst_name.size(), system_charset_info);
+
+ field[RDB_SST_PROPS_FIELD::COLUMN_FAMILY]->store(
+ props.second->column_family_id, true);
+ field[RDB_SST_PROPS_FIELD::DATA_BLOCKS]->store(
+ props.second->num_data_blocks, true);
+ field[RDB_SST_PROPS_FIELD::ENTRIES]->store(props.second->num_entries,
+ true);
+ field[RDB_SST_PROPS_FIELD::RAW_KEY_SIZE]->store(
+ props.second->raw_key_size, true);
+ field[RDB_SST_PROPS_FIELD::RAW_VALUE_SIZE]->store(
+ props.second->raw_value_size, true);
+ field[RDB_SST_PROPS_FIELD::DATA_BLOCK_SIZE]->store(
+ props.second->data_size, true);
+ field[RDB_SST_PROPS_FIELD::INDEX_BLOCK_SIZE]->store(
+ props.second->index_size, true);
+ field[RDB_SST_PROPS_FIELD::INDEX_PARTITIONS]->store(
+ props.second->index_partitions, true);
+ field[RDB_SST_PROPS_FIELD::TOP_LEVEL_INDEX_SIZE]->store(
+ props.second->top_level_index_size, true);
+ field[RDB_SST_PROPS_FIELD::FILTER_BLOCK_SIZE]->store(
+ props.second->filter_size, true);
+ if (props.second->compression_name.empty()) {
+ field[RDB_SST_PROPS_FIELD::COMPRESSION_ALGO]->set_null();
+ } else {
+ field[RDB_SST_PROPS_FIELD::COMPRESSION_ALGO]->store(
+ props.second->compression_name.c_str(),
+ props.second->compression_name.size(), system_charset_info);
+ }
+ field[RDB_SST_PROPS_FIELD::CREATION_TIME]->store(
+ props.second->creation_time, true);
+
+ /* Tell MySQL about this row in the virtual table */
+ ret = static_cast<int>(
+ my_core::schema_table_store_record(thd, tables->table));
+
+ if (ret != 0) {
+ DBUG_RETURN(ret);
+ }
+ }
+ }
+
+ DBUG_RETURN(ret);
+}
+
+/* Initialize the information_schema.rocksdb_sst_props virtual table */
+static int rdb_i_s_sst_props_init(void *const p) {
+ DBUG_ENTER_FUNC();
+
+ DBUG_ASSERT(p != nullptr);
+
+ my_core::ST_SCHEMA_TABLE *schema;
+
+ schema = (my_core::ST_SCHEMA_TABLE *)p;
+
+ schema->fields_info = rdb_i_s_sst_props_fields_info;
+ schema->fill_table = rdb_i_s_sst_props_fill_table;
+
+ DBUG_RETURN(0);
+}
+
+/*
Support for INFORMATION_SCHEMA.ROCKSDB_INDEX_FILE_MAP dynamic table
*/
namespace RDB_INDEX_FILE_MAP_FIELD {
@@ -1519,19 +1663,21 @@ static int rdb_i_s_trx_info_init(void *const p) {
namespace RDB_DEADLOCK_FIELD {
enum {
DEADLOCK_ID = 0,
+ TIMESTAMP,
TRANSACTION_ID,
CF_NAME,
WAITING_KEY,
LOCK_TYPE,
INDEX_NAME,
TABLE_NAME,
- ROLLED_BACK
+ ROLLED_BACK,
};
} // namespace RDB_TRX_FIELD
static ST_FIELD_INFO rdb_i_s_deadlock_info_fields_info[] = {
ROCKSDB_FIELD_INFO("DEADLOCK_ID", sizeof(ulonglong), MYSQL_TYPE_LONGLONG,
0),
+ ROCKSDB_FIELD_INFO("TIMESTAMP", sizeof(ulonglong), MYSQL_TYPE_LONGLONG, 0),
ROCKSDB_FIELD_INFO("TRANSACTION_ID", sizeof(ulonglong), MYSQL_TYPE_LONGLONG,
0),
ROCKSDB_FIELD_INFO("CF_NAME", NAME_LEN + 1, MYSQL_TYPE_STRING, 0),
@@ -1568,8 +1714,11 @@ static int rdb_i_s_deadlock_info_fill_table(
ulonglong id = 0;
for (const auto &info : all_dl_info) {
+ auto deadlock_time = info.deadlock_time;
for (const auto &trx_info : info.path) {
tables->table->field[RDB_DEADLOCK_FIELD::DEADLOCK_ID]->store(id, true);
+ tables->table->field[RDB_DEADLOCK_FIELD::TIMESTAMP]->store(deadlock_time,
+ true);
tables->table->field[RDB_DEADLOCK_FIELD::TRANSACTION_ID]->store(
trx_info.trx_id, true);
tables->table->field[RDB_DEADLOCK_FIELD::CF_NAME]->store(
@@ -1760,6 +1909,22 @@ struct st_maria_plugin rdb_i_s_ddl = {
MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
};
+struct st_maria_plugin rdb_i_s_sst_props = {
+ MYSQL_INFORMATION_SCHEMA_PLUGIN,
+ &rdb_i_s_info,
+ "ROCKSDB_SST_PROPS",
+ "Facebook",
+ "RocksDB SST Properties",
+ PLUGIN_LICENSE_GPL,
+ rdb_i_s_sst_props_init,
+ rdb_i_s_deinit,
+ 0x0001, /* version number (0.1) */
+ nullptr, /* status variables */
+ nullptr, /* system variables */
+ nullptr, /* config options */
+ MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL
+};
+
struct st_maria_plugin rdb_i_s_index_file_map = {
MYSQL_INFORMATION_SCHEMA_PLUGIN,
&rdb_i_s_info,
diff --git a/storage/rocksdb/rdb_i_s.h b/storage/rocksdb/rdb_i_s.h
index d6a48bf3fec..f4c4b04a68d 100644
--- a/storage/rocksdb/rdb_i_s.h
+++ b/storage/rocksdb/rdb_i_s.h
@@ -29,6 +29,7 @@ extern struct st_maria_plugin rdb_i_s_cfoptions;
extern struct st_maria_plugin rdb_i_s_compact_stats;
extern struct st_maria_plugin rdb_i_s_global_info;
extern struct st_maria_plugin rdb_i_s_ddl;
+extern struct st_maria_plugin rdb_i_s_sst_props;
extern struct st_maria_plugin rdb_i_s_index_file_map;
extern struct st_maria_plugin rdb_i_s_lock_info;
extern struct st_maria_plugin rdb_i_s_trx_info;
diff --git a/storage/rocksdb/rdb_index_merge.cc b/storage/rocksdb/rdb_index_merge.cc
index 12777cf9302..ff3bfdc1f95 100644
--- a/storage/rocksdb/rdb_index_merge.cc
+++ b/storage/rocksdb/rdb_index_merge.cc
@@ -54,6 +54,11 @@ Rdb_index_merge::~Rdb_index_merge() {
}
my_sleep(m_merge_tmp_file_removal_delay * 1000);
+ // Not aborting on fsync error since the tmp file is not used anymore
+ if (mysql_file_sync(m_merge_file.m_fd, MYF(MY_WME))) {
+ // NO_LINT_DEBUG
+ sql_print_error("Error flushing truncated MyRocks merge buffer.");
+ }
curr_size -= m_merge_buf_size;
}
}
diff --git a/storage/rocksdb/rdb_perf_context.cc b/storage/rocksdb/rdb_perf_context.cc
index ed2b6557ac5..bc381b16716 100644
--- a/storage/rocksdb/rdb_perf_context.cc
+++ b/storage/rocksdb/rdb_perf_context.cc
@@ -180,8 +180,6 @@ static void harvest_diffs(Rdb_atomic_perf_counters *const counters) {
static Rdb_atomic_perf_counters rdb_global_perf_counters;
void rdb_get_global_perf_counters(Rdb_perf_counters *const counters) {
- DBUG_ASSERT(counters != nullptr);
-
counters->load(rdb_global_perf_counters);
}
diff --git a/storage/rocksdb/rdb_psi.cc b/storage/rocksdb/rdb_psi.cc
index b5309df5973..361a648bba4 100644
--- a/storage/rocksdb/rdb_psi.cc
+++ b/storage/rocksdb/rdb_psi.cc
@@ -38,22 +38,25 @@ my_core::PSI_stage_info stage_waiting_on_row_lock = {0, "Waiting for row lock",
my_core::PSI_stage_info *all_rocksdb_stages[] = {&stage_waiting_on_row_lock};
my_core::PSI_thread_key rdb_background_psi_thread_key,
- rdb_drop_idx_psi_thread_key;
+ rdb_drop_idx_psi_thread_key, rdb_mc_psi_thread_key;
my_core::PSI_thread_info all_rocksdb_threads[] = {
{&rdb_background_psi_thread_key, "background", PSI_FLAG_GLOBAL},
{&rdb_drop_idx_psi_thread_key, "drop index", PSI_FLAG_GLOBAL},
+ {&rdb_mc_psi_thread_key, "manual compaction", PSI_FLAG_GLOBAL},
};
my_core::PSI_mutex_key rdb_psi_open_tbls_mutex_key, rdb_signal_bg_psi_mutex_key,
- rdb_signal_drop_idx_psi_mutex_key, rdb_collation_data_mutex_key,
- rdb_mem_cmp_space_mutex_key, key_mutex_tx_list, rdb_sysvars_psi_mutex_key,
- rdb_cfm_mutex_key, rdb_sst_commit_key;
+ rdb_signal_drop_idx_psi_mutex_key, rdb_signal_mc_psi_mutex_key,
+ rdb_collation_data_mutex_key, rdb_mem_cmp_space_mutex_key,
+ key_mutex_tx_list, rdb_sysvars_psi_mutex_key, rdb_cfm_mutex_key,
+ rdb_sst_commit_key, rdb_block_cache_resize_mutex_key;
my_core::PSI_mutex_info all_rocksdb_mutexes[] = {
{&rdb_psi_open_tbls_mutex_key, "open tables", PSI_FLAG_GLOBAL},
{&rdb_signal_bg_psi_mutex_key, "stop background", PSI_FLAG_GLOBAL},
{&rdb_signal_drop_idx_psi_mutex_key, "signal drop index", PSI_FLAG_GLOBAL},
+ {&rdb_signal_mc_psi_mutex_key, "signal manual compaction", PSI_FLAG_GLOBAL},
{&rdb_collation_data_mutex_key, "collation data init", PSI_FLAG_GLOBAL},
{&rdb_mem_cmp_space_mutex_key, "collation space char data init",
PSI_FLAG_GLOBAL},
@@ -61,6 +64,8 @@ my_core::PSI_mutex_info all_rocksdb_mutexes[] = {
{&rdb_sysvars_psi_mutex_key, "setting sysvar", PSI_FLAG_GLOBAL},
{&rdb_cfm_mutex_key, "column family manager", PSI_FLAG_GLOBAL},
{&rdb_sst_commit_key, "sst commit", PSI_FLAG_GLOBAL},
+ {&rdb_block_cache_resize_mutex_key, "resizing block cache",
+ PSI_FLAG_GLOBAL},
};
my_core::PSI_rwlock_key key_rwlock_collation_exception_list,
@@ -75,12 +80,14 @@ my_core::PSI_rwlock_info all_rocksdb_rwlocks[] = {
};
my_core::PSI_cond_key rdb_signal_bg_psi_cond_key,
- rdb_signal_drop_idx_psi_cond_key;
+ rdb_signal_drop_idx_psi_cond_key, rdb_signal_mc_psi_cond_key;
my_core::PSI_cond_info all_rocksdb_conds[] = {
{&rdb_signal_bg_psi_cond_key, "cond signal background", PSI_FLAG_GLOBAL},
{&rdb_signal_drop_idx_psi_cond_key, "cond signal drop index",
PSI_FLAG_GLOBAL},
+ {&rdb_signal_mc_psi_cond_key, "cond signal manual compaction",
+ PSI_FLAG_GLOBAL},
};
void init_rocksdb_psi_keys() {
diff --git a/storage/rocksdb/rdb_psi.h b/storage/rocksdb/rdb_psi.h
index d4318ee3dba..e0d6e7e3a47 100644
--- a/storage/rocksdb/rdb_psi.h
+++ b/storage/rocksdb/rdb_psi.h
@@ -35,19 +35,19 @@ extern my_core::PSI_stage_info stage_waiting_on_row_lock;
#ifdef HAVE_PSI_INTERFACE
extern my_core::PSI_thread_key rdb_background_psi_thread_key,
- rdb_drop_idx_psi_thread_key;
+ rdb_drop_idx_psi_thread_key, rdb_mc_psi_thread_key;
extern my_core::PSI_mutex_key rdb_psi_open_tbls_mutex_key,
rdb_signal_bg_psi_mutex_key, rdb_signal_drop_idx_psi_mutex_key,
- rdb_collation_data_mutex_key, rdb_mem_cmp_space_mutex_key,
- key_mutex_tx_list, rdb_sysvars_psi_mutex_key, rdb_cfm_mutex_key,
- rdb_sst_commit_key;
+ rdb_signal_mc_psi_mutex_key, rdb_collation_data_mutex_key,
+ rdb_mem_cmp_space_mutex_key, key_mutex_tx_list, rdb_sysvars_psi_mutex_key,
+ rdb_cfm_mutex_key, rdb_sst_commit_key, rdb_block_cache_resize_mutex_key;
extern my_core::PSI_rwlock_key key_rwlock_collation_exception_list,
key_rwlock_read_free_rpl_tables, key_rwlock_skip_unique_check_tables;
extern my_core::PSI_cond_key rdb_signal_bg_psi_cond_key,
- rdb_signal_drop_idx_psi_cond_key;
+ rdb_signal_drop_idx_psi_cond_key, rdb_signal_mc_psi_cond_key;
#endif // HAVE_PSI_INTERFACE
void init_rocksdb_psi_keys();
diff --git a/storage/rocksdb/rdb_sst_info.cc b/storage/rocksdb/rdb_sst_info.cc
index bc3faaf010e..e7dd0c67a1f 100644
--- a/storage/rocksdb/rdb_sst_info.cc
+++ b/storage/rocksdb/rdb_sst_info.cc
@@ -83,7 +83,9 @@ rocksdb::Status Rdb_sst_file_ordered::Rdb_sst_file::open() {
const rocksdb::Options options(m_db_options, cf_descr.options);
m_sst_file_writer =
- new rocksdb::SstFileWriter(env_options, options, m_comparator, m_cf);
+ new rocksdb::SstFileWriter(env_options, options, m_comparator, m_cf, true,
+ rocksdb::Env::IOPriority::IO_TOTAL,
+ cf_descr.options.optimize_filters_for_hits);
s = m_sst_file_writer->Open(m_name);
if (m_tracing) {
diff --git a/storage/rocksdb/rdb_threads.h b/storage/rocksdb/rdb_threads.h
index a93e4fc93f2..3c2dd680d41 100644
--- a/storage/rocksdb/rdb_threads.h
+++ b/storage/rocksdb/rdb_threads.h
@@ -17,6 +17,7 @@
#pragma once
/* C++ standard header files */
+#include <map>
#include <string>
/* MySQL includes */
@@ -39,6 +40,7 @@
/* MyRocks header files */
#include "./rdb_utils.h"
+#include "rocksdb/db.h"
namespace myrocks {
@@ -118,8 +120,8 @@ public:
{
// NO_LINT_DEBUG
sql_print_warning(
- "MyRocks: Failed to set name (%s) for current thread, errno=%d",
- m_name.c_str(), errno);
+ "MyRocks: Failed to set name (%s) for current thread, errno=%d,%d",
+ m_name.c_str(), errno, err);
}
#endif
}
@@ -160,6 +162,31 @@ public:
}
};
+class Rdb_manual_compaction_thread : public Rdb_thread {
+ private:
+ struct Manual_compaction_request {
+ int mc_id;
+ enum mc_state { INITED = 0, RUNNING } state;
+ rocksdb::ColumnFamilyHandle *cf;
+ rocksdb::Slice *start;
+ rocksdb::Slice *limit;
+ int concurrency = 0;
+ };
+
+ int m_latest_mc_id;
+ mysql_mutex_t m_mc_mutex;
+ std::map<int, Manual_compaction_request> m_requests;
+
+ public:
+ virtual void run() override;
+ int request_manual_compaction(rocksdb::ColumnFamilyHandle *cf,
+ rocksdb::Slice *start, rocksdb::Slice *limit,
+ int concurrency = 0);
+ bool is_manual_compaction_finished(int mc_id);
+ void clear_manual_compaction_request(int mc_id, bool init_only = false);
+ void clear_all_manual_compaction_requests();
+};
+
/*
Drop index thread control
*/
diff --git a/storage/rocksdb/rdb_utils.cc b/storage/rocksdb/rdb_utils.cc
index 6cddfed64c9..bb6a503c656 100644
--- a/storage/rocksdb/rdb_utils.cc
+++ b/storage/rocksdb/rdb_utils.cc
@@ -49,9 +49,6 @@ namespace myrocks {
*/
const char *rdb_skip_spaces(const struct charset_info_st *const cs,
const char *str) {
- DBUG_ASSERT(cs != nullptr);
- DBUG_ASSERT(str != nullptr);
-
while (my_isspace(cs, *str)) {
str++;
}
@@ -65,9 +62,6 @@ const char *rdb_skip_spaces(const struct charset_info_st *const cs,
of characters in str2.
*/
bool rdb_compare_strings_ic(const char *const str1, const char *const str2) {
- DBUG_ASSERT(str1 != nullptr);
- DBUG_ASSERT(str2 != nullptr);
-
// Scan through the strings
size_t ii;
for (ii = 0; str2[ii]; ii++) {
@@ -89,10 +83,6 @@ const char *rdb_find_in_string(const char *str, const char *pattern,
char quote = '\0';
bool escape = false;
- DBUG_ASSERT(str != nullptr);
- DBUG_ASSERT(pattern != nullptr);
- DBUG_ASSERT(succeeded != nullptr);
-
*succeeded = false;
for (; *str; str++) {
@@ -136,11 +126,6 @@ const char *rdb_find_in_string(const char *str, const char *pattern,
const char *rdb_check_next_token(const struct charset_info_st *const cs,
const char *str, const char *const pattern,
bool *const succeeded) {
- DBUG_ASSERT(cs != nullptr);
- DBUG_ASSERT(str != nullptr);
- DBUG_ASSERT(pattern != nullptr);
- DBUG_ASSERT(succeeded != nullptr);
-
// Move past any spaces
str = rdb_skip_spaces(cs, str);
@@ -159,9 +144,6 @@ const char *rdb_check_next_token(const struct charset_info_st *const cs,
*/
const char *rdb_parse_id(const struct charset_info_st *const cs,
const char *str, std::string *const id) {
- DBUG_ASSERT(cs != nullptr);
- DBUG_ASSERT(str != nullptr);
-
// Move past any spaces
str = rdb_skip_spaces(cs, str);
@@ -221,9 +203,6 @@ const char *rdb_parse_id(const struct charset_info_st *const cs,
*/
const char *rdb_skip_id(const struct charset_info_st *const cs,
const char *str) {
- DBUG_ASSERT(cs != nullptr);
- DBUG_ASSERT(str != nullptr);
-
return rdb_parse_id(cs, str, nullptr);
}
@@ -254,8 +233,6 @@ static const std::array<char, 16> rdb_hexdigit = {{'0', '1', '2', '3', '4', '5',
*/
std::string rdb_hexdump(const char *data, const std::size_t data_len,
const std::size_t maxsize) {
- DBUG_ASSERT(data != nullptr);
-
// Count the elements in the string
std::size_t elems = data_len;
// Calculate the amount of output needed
diff --git a/storage/rocksdb/rocksdb b/storage/rocksdb/rocksdb
-Subproject ba295cda29daee3ffe58549542804efdfd96978
+Subproject 926f3a78a64b327475ee6c60b6c8ab4f3425320