summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD/Makefile.am3
-rwxr-xr-xBUILD/SETUP.sh13
-rwxr-xr-xBUILD/check-cpu23
-rw-r--r--Docs/Makefile.am3
-rw-r--r--Makefile.am5
-rw-r--r--client/Makefile.am3
-rw-r--r--client/mysql.cc4
-rw-r--r--client/mysql_upgrade.c65
-rw-r--r--client/mysqlcheck.c55
-rw-r--r--client/mysqlshow.c3
-rw-r--r--client/mysqltest.cc21
-rw-r--r--cmd-line-utils/Makefile.am3
-rw-r--r--cmd-line-utils/readline/Makefile.am2
-rw-r--r--cmd-line-utils/readline/input.c2
-rw-r--r--config/ac-macros/maintainer.m464
-rw-r--r--configure.in22
-rw-r--r--dbug/Makefile.am3
-rwxr-xr-xdbug/remove_function_from_trace.pl11
-rw-r--r--extra/Makefile.am3
-rw-r--r--extra/comp_err.c8
-rw-r--r--extra/replace.c12
-rw-r--r--extra/yassl/src/yassl_imp.cpp24
-rw-r--r--extra/yassl/taocrypt/include/blowfish.hpp6
-rw-r--r--extra/yassl/taocrypt/include/runtime.hpp16
-rw-r--r--extra/yassl/taocrypt/src/algebra.cpp6
-rw-r--r--extra/yassl/taocrypt/src/coding.cpp2
-rw-r--r--extra/yassl/taocrypt/src/integer.cpp32
-rw-r--r--extra/yassl/taocrypt/src/misc.cpp16
-rw-r--r--extra/yassl/testsuite/test.hpp5
-rw-r--r--include/Makefile.am8
-rw-r--r--include/m_string.h6
-rw-r--r--include/my_bitmap.h16
-rw-r--r--include/my_compiler.h129
-rw-r--r--include/my_global.h42
-rw-r--r--include/my_pthread.h7
-rw-r--r--include/mysql.h2
-rw-r--r--include/mysql.h.pp1
-rw-r--r--include/mysql_com.h4
-rw-r--r--include/mysys_err.h10
-rw-r--r--libmysql/Makefile.am3
-rw-r--r--libmysql/libmysql.c1
-rw-r--r--libmysql_r/Makefile.am3
-rw-r--r--libmysqld/Makefile.am3
-rw-r--r--libmysqld/examples/Makefile.am3
-rw-r--r--man/Makefile.am3
-rw-r--r--mysql-test/Makefile.am14
-rw-r--r--mysql-test/README.suites15
-rw-r--r--mysql-test/include/commit.inc4
-rw-r--r--mysql-test/include/diff_tables.inc18
-rw-r--r--mysql-test/include/have_archive.inc9
-rw-r--r--mysql-test/include/have_archive.opt2
-rw-r--r--mysql-test/include/have_blackhole.opt2
-rw-r--r--mysql-test/include/have_innodb.opt1
-rw-r--r--mysql-test/include/have_pbxt.inc9
-rw-r--r--mysql-test/include/percona_query_response_time_flush.inc1
-rw-r--r--mysql-test/include/percona_query_response_time_show.inc7
-rw-r--r--mysql-test/include/percona_query_response_time_sleep.inc19
-rw-r--r--mysql-test/include/rpl_diff_tables.inc35
-rw-r--r--mysql-test/lib/My/ConfigFactory.pm2
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process.cc2
-rw-r--r--mysql-test/lib/mtr_cases.pm136
-rwxr-xr-xmysql-test/lib/v1/mysql-test-run.pl2
-rwxr-xr-xmysql-test/mysql-test-run.pl25
-rw-r--r--mysql-test/r/archive.result12
-rw-r--r--mysql-test/r/commit_1innodb.result4
-rw-r--r--mysql-test/r/drop.result11
-rw-r--r--mysql-test/r/func_gconcat.result21
-rw-r--r--mysql-test/r/func_misc.result15
-rw-r--r--mysql-test/r/grant.result2
-rw-r--r--mysql-test/r/group_by.result35
-rw-r--r--mysql-test/r/having.result26
-rw-r--r--mysql-test/r/information_schema.result19
-rw-r--r--mysql-test/r/information_schema_all_engines.result22
-rw-r--r--mysql-test/r/loaddata.result29
-rw-r--r--mysql-test/r/log_tables_upgrade.result15
-rw-r--r--mysql-test/r/lowercase_table2.result3
-rw-r--r--mysql-test/r/lowercase_view.result17
-rw-r--r--mysql-test/r/mysql_client_test.result2
-rw-r--r--mysql-test/r/mysql_upgrade.result121
-rw-r--r--mysql-test/r/mysqlcheck.result8
-rw-r--r--mysql-test/r/not_partition.result26
-rw-r--r--mysql-test/r/show_check.result2
-rw-r--r--mysql-test/r/update.result14
-rw-r--r--mysql-test/r/upgrade.result8
-rw-r--r--mysql-test/std_data/archive_5_0.ARMbin0 -> 19 bytes
-rw-r--r--mysql-test/std_data/archive_5_0.ARZbin0 -> 138 bytes
-rw-r--r--mysql-test/std_data/archive_5_0.frmbin0 -> 8578 bytes
-rw-r--r--mysql-test/std_data/long_table_name.MYDbin0 -> 56 bytes
-rw-r--r--mysql-test/std_data/long_table_name.MYIbin0 -> 6144 bytes
-rw-r--r--mysql-test/std_data/long_table_name.frmbin0 -> 8650 bytes
-rw-r--r--mysql-test/std_data/server8k-cert.pem172
-rw-r--r--mysql-test/std_data/server8k-key.pem194
-rw-r--r--mysql-test/suite/binlog/t/binlog_row_binlog.test4
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_binlog.test2
-rw-r--r--mysql-test/suite/federated/federated_innodb-slave.opt1
-rw-r--r--mysql-test/suite/federated/federated_transactions-slave.opt1
-rw-r--r--mysql-test/suite/federated/my.cnf2
-rw-r--r--mysql-test/suite/federated/suite.opt2
-rw-r--r--mysql-test/suite/funcs_1/r/is_basics_mixed.result2
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_innodb.result12
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_is.result190
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_memory.result12
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_myisam.result12
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql.result12
-rw-r--r--mysql-test/suite/funcs_1/r/is_engines_innodb.result2
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_is.result46
-rw-r--r--mysql-test/suite/funcs_1/t/is_tables_is.test1
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug53756.result118
-rw-r--r--mysql-test/suite/innodb/r/innodb_mysql.result8
-rw-r--r--mysql-test/suite/innodb/t/disabled.def2
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug53756-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug53756.test184
-rw-r--r--mysql-test/suite/innodb/t/innodb_misc1.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb_mysql.test16
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_bug54453.result9
-rw-r--r--mysql-test/suite/innodb_plugin/t/disabled.def9
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb-autoinc-44030.test2
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb-autoinc.test2
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb-use-sys-malloc.test1
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb_bug54453.test15
-rw-r--r--mysql-test/suite/pbxt/r/mysqlshow.result6
-rw-r--r--mysql-test/suite/pbxt/r/range.result16
-rw-r--r--mysql-test/suite/pbxt/t/range.test5
-rw-r--r--mysql-test/suite/percona/disabled.def9
-rw-r--r--mysql-test/suite/percona/percona_innodb_buffer_pool_shm-master.opt1
-rw-r--r--mysql-test/suite/percona/percona_innodb_buffer_pool_shm.result6
-rw-r--r--mysql-test/suite/percona/percona_innodb_buffer_pool_shm.test18
-rw-r--r--mysql-test/suite/percona/percona_innodb_use_sys_stats_table-master.opt1
-rw-r--r--mysql-test/suite/percona/percona_innodb_use_sys_stats_table.result3
-rw-r--r--mysql-test/suite/percona/percona_innodb_use_sys_stats_table.test2
-rw-r--r--mysql-test/suite/percona/percona_log_connection_error-master.opt1
-rw-r--r--mysql-test/suite/percona/percona_log_connection_error.result15
-rw-r--r--mysql-test/suite/percona/percona_log_connection_error.test52
-rw-r--r--mysql-test/suite/percona/percona_query_response_time-replication.result60
-rw-r--r--mysql-test/suite/percona/percona_query_response_time-replication.test52
-rw-r--r--mysql-test/suite/percona/percona_query_response_time-stored.result310
-rw-r--r--mysql-test/suite/percona/percona_query_response_time-stored.test87
-rw-r--r--mysql-test/suite/percona/percona_query_response_time.result564
-rw-r--r--mysql-test/suite/percona/percona_query_response_time.test65
-rw-r--r--mysql-test/suite/percona/percona_server_variables.result340
-rw-r--r--mysql-test/suite/percona/percona_server_variables.test7
-rw-r--r--mysql-test/suite/percona/percona_slave_innodb_stats-master.opt1
-rw-r--r--mysql-test/suite/percona/percona_slave_innodb_stats-slave.opt1
-rw-r--r--mysql-test/suite/percona/percona_slave_innodb_stats.result21
-rw-r--r--mysql-test/suite/percona/percona_slave_innodb_stats.test43
-rw-r--r--mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.result35
-rw-r--r--mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.test21
-rw-r--r--mysql-test/suite/percona/percona_sql_no_fcache.result12
-rw-r--r--mysql-test/suite/percona/percona_sql_no_fcache.test11
-rw-r--r--mysql-test/suite/percona/percona_status_wait_query_cache_mutex.result27
-rw-r--r--mysql-test/suite/percona/percona_status_wait_query_cache_mutex.test37
-rw-r--r--mysql-test/suite/percona/percona_xtradb_bug317074.test3
-rw-r--r--mysql-test/suite/rpl/r/rpl_conditional_comments.result57
-rw-r--r--mysql-test/suite/rpl/r/rpl_current_user.result205
-rw-r--r--mysql-test/suite/rpl/r/rpl_drop.result24
-rw-r--r--mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_packet.result8
-rw-r--r--mysql-test/suite/rpl/t/rpl_conditional_comments.test74
-rw-r--r--mysql-test/suite/rpl/t/rpl_current_user.cnf9
-rw-r--r--mysql-test/suite/rpl/t/rpl_current_user.test238
-rw-r--r--mysql-test/suite/rpl/t/rpl_drop.test53
-rw-r--r--mysql-test/suite/rpl/t/rpl_packet.test39
-rw-r--r--mysql-test/t/archive.test13
-rw-r--r--mysql-test/t/bug46080-master.opt2
-rw-r--r--mysql-test/t/drop.test5
-rw-r--r--mysql-test/t/func_gconcat.test16
-rw-r--r--mysql-test/t/func_misc.test12
-rw-r--r--mysql-test/t/grant.test2
-rw-r--r--mysql-test/t/group_by.test14
-rw-r--r--mysql-test/t/having.test21
-rw-r--r--mysql-test/t/information_schema.test16
-rw-r--r--mysql-test/t/loaddata.test34
-rw-r--r--mysql-test/t/log_tables_upgrade.test2
-rw-r--r--mysql-test/t/lowercase_view.test22
-rw-r--r--mysql-test/t/mysql_client_test.test2
-rw-r--r--mysql-test/t/mysql_upgrade.test30
-rw-r--r--mysql-test/t/mysqltest_ps.test2
-rw-r--r--mysql-test/t/ssl_8k_key-master.opt1
-rw-r--r--mysql-test/t/update.test20
-rw-r--r--mysql-test/t/upgrade.test11
-rw-r--r--mysys/Makefile.am4
-rw-r--r--mysys/errors.c4
-rw-r--r--mysys/mf_iocache.c11
-rw-r--r--mysys/mf_pack.c12
-rw-r--r--mysys/my_bitmap.c2
-rw-r--r--mysys/my_copy.c33
-rw-r--r--mysys/my_gethwaddr.c2
-rw-r--r--mysys/my_getopt.c13
-rw-r--r--mysys/my_handler.c1
-rw-r--r--mysys/my_redel.c37
-rw-r--r--mysys/stacktrace.c4
-rw-r--r--mysys/thr_lock.c3
-rw-r--r--netware/Makefile.am3
-rw-r--r--plugin/Makefile.am3
-rw-r--r--plugin/daemon_example/Makefile.am8
-rw-r--r--plugin/fulltext/Makefile.am2
-rw-r--r--pstack/Makefile.am3
-rw-r--r--regex/Makefile.am3
-rw-r--r--regex/engine.c17
-rw-r--r--regex/main.c4
-rw-r--r--regex/regcomp.c7
-rw-r--r--scripts/Makefile.am4
-rw-r--r--scripts/mysql_install_db.sh12
-rwxr-xr-xscripts/mysql_secure_installation.pl.in2
-rw-r--r--scripts/mysql_secure_installation.sh39
-rw-r--r--scripts/mysql_system_tables_fix.sql4
-rw-r--r--server-tools/Makefile.am3
-rw-r--r--server-tools/instance-manager/instance_options.cc3
-rw-r--r--sql-bench/Makefile.am3
-rw-r--r--sql-common/Makefile.am5
-rw-r--r--sql/Makefile.am3
-rw-r--r--sql/field.cc8
-rw-r--r--sql/ha_partition.cc54
-rw-r--r--sql/ha_partition.h15
-rw-r--r--sql/handler.h18
-rw-r--r--sql/item.cc8
-rw-r--r--sql/item.h1
-rw-r--r--sql/item_buff.cc6
-rw-r--r--sql/item_create.cc26
-rw-r--r--sql/item_func.cc7
-rw-r--r--sql/item_sum.cc20
-rw-r--r--sql/item_timefunc.cc7
-rw-r--r--sql/log.cc106
-rw-r--r--sql/log.h2
-rw-r--r--sql/log_event.cc108
-rw-r--r--sql/log_event.h9
-rw-r--r--sql/log_event_old.cc6
-rw-r--r--sql/mysql_priv.h6
-rw-r--r--sql/mysqld.cc70
-rw-r--r--sql/opt_range.cc2
-rw-r--r--sql/partition_info.cc6
-rw-r--r--sql/protocol.cc15
-rw-r--r--sql/rpl_filter.cc4
-rw-r--r--sql/rpl_rli.cc3
-rw-r--r--sql/set_var.cc31
-rw-r--r--sql/set_var.h2
-rw-r--r--sql/slave.cc6
-rw-r--r--sql/sp.cc4
-rw-r--r--sql/sp_head.cc4
-rw-r--r--sql/spatial.cc44
-rw-r--r--sql/spatial.h26
-rw-r--r--sql/sql_acl.cc35
-rw-r--r--sql/sql_base.cc22
-rw-r--r--sql/sql_cache.cc3
-rw-r--r--sql/sql_class.cc46
-rw-r--r--sql/sql_class.h64
-rw-r--r--sql/sql_cursor.cc7
-rw-r--r--sql/sql_insert.cc11
-rw-r--r--sql/sql_lex.cc16
-rw-r--r--sql/sql_lex.h20
-rw-r--r--sql/sql_list.h2
-rw-r--r--sql/sql_load.cc64
-rw-r--r--sql/sql_parse.cc55
-rw-r--r--sql/sql_partition.cc2
-rw-r--r--sql/sql_partition.h2
-rw-r--r--sql/sql_prepare.cc15
-rw-r--r--sql/sql_repl.cc8
-rw-r--r--sql/sql_select.cc44
-rw-r--r--sql/sql_show.cc93
-rw-r--r--sql/sql_table.cc101
-rw-r--r--sql/sql_trigger.cc4
-rw-r--r--sql/sql_udf.cc4
-rw-r--r--sql/sql_update.cc13
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/table.cc18
-rw-r--r--sql/table.h3
-rw-r--r--sql/udf_example.c2
-rw-r--r--sql/unireg.h4
-rw-r--r--storage/Makefile.am3
-rw-r--r--storage/archive/Makefile.am6
-rw-r--r--storage/archive/azio.c11
-rw-r--r--storage/archive/ha_archive.cc42
-rw-r--r--storage/archive/ha_archive.h3
-rw-r--r--storage/blackhole/Makefile.am6
-rw-r--r--storage/csv/Makefile.am4
-rw-r--r--storage/csv/ha_tina.cc12
-rw-r--r--storage/example/Makefile.am7
-rw-r--r--storage/example/ha_example.cc2
-rw-r--r--storage/federated/Makefile.am7
-rw-r--r--storage/federated/ha_federated.cc17
-rw-r--r--storage/federatedx/Makefile.am7
-rw-r--r--storage/federatedx/ha_federatedx.cc5
-rw-r--r--storage/heap/hp_test2.c4
-rw-r--r--storage/ibmdb2i/Makefile.am4
-rw-r--r--storage/ibmdb2i/db2i_file.h1
-rw-r--r--storage/innobase/Makefile.am6
-rw-r--r--storage/innobase/dict/dict0load.c27
-rw-r--r--storage/innobase/os/os0file.c3
-rw-r--r--storage/innodb_plugin/ChangeLog24
-rw-r--r--storage/innodb_plugin/Makefile.am6
-rw-r--r--storage/innodb_plugin/btr/btr0cur.c14
-rw-r--r--storage/innodb_plugin/btr/btr0sea.c11
-rw-r--r--storage/innodb_plugin/ha/ha0ha.c15
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc1
-rw-r--r--storage/innodb_plugin/include/btr0cur.h2
-rw-r--r--storage/innodb_plugin/include/btr0sea.h8
-rw-r--r--storage/innodb_plugin/include/mem0pool.h12
-rw-r--r--storage/innodb_plugin/include/row0mysql.h6
-rw-r--r--storage/innodb_plugin/include/univ.i2
-rw-r--r--storage/innodb_plugin/mem/mem0mem.c12
-rw-r--r--storage/innodb_plugin/mem/mem0pool.c41
-rw-r--r--storage/innodb_plugin/row/row0merge.c5
-rw-r--r--storage/innodb_plugin/row/row0row.c8
-rw-r--r--storage/innodb_plugin/row/row0sel.c103
-rw-r--r--storage/innodb_plugin/row/row0undo.c18
-rw-r--r--storage/innodb_plugin/row/row0upd.c17
-rw-r--r--storage/innodb_plugin/srv/srv0start.c6
-rw-r--r--storage/maria/ha_maria.cc11
-rw-r--r--storage/maria/ma_bitmap.c23
-rw-r--r--storage/maria/ma_blockrec.c14
-rw-r--r--storage/maria/ma_check.c30
-rw-r--r--storage/maria/ma_delete.c223
-rw-r--r--storage/maria/ma_key_recover.c270
-rw-r--r--storage/maria/ma_key_recover.h13
-rw-r--r--storage/maria/ma_loghandler.h25
-rw-r--r--storage/maria/ma_open.c1
-rw-r--r--storage/maria/ma_page.c66
-rw-r--r--storage/maria/ma_recovery.c78
-rw-r--r--storage/maria/ma_rt_key.c3
-rw-r--r--storage/maria/ma_rt_split.c25
-rw-r--r--storage/maria/ma_unique.c3
-rw-r--r--storage/maria/ma_write.c179
-rw-r--r--storage/maria/maria_def.h6
-rw-r--r--storage/maria/trnman.c1
-rw-r--r--storage/myisam/mi_dynrec.c7
-rw-r--r--storage/myisam/mi_locking.c14
-rw-r--r--storage/myisam/mi_open.c3
-rw-r--r--storage/myisam/mi_page.c2
-rw-r--r--storage/myisam/mi_search.c6
-rw-r--r--storage/myisam/mi_test2.c22
-rw-r--r--storage/myisam/mi_unique.c2
-rw-r--r--storage/myisam/rt_split.c3
-rw-r--r--storage/myisammrg/ha_myisammrg.cc4
-rw-r--r--storage/myisammrg/myrg_open.c5
-rw-r--r--storage/ndb/src/common/portlib/NdbMutex.c21
-rw-r--r--storage/ndb/src/ndbapi/DictCache.cpp32
-rw-r--r--storage/pbxt/src/Makefile.am4
-rw-r--r--storage/xtradb/ChangeLog143
-rw-r--r--storage/xtradb/Makefile.am4
-rw-r--r--storage/xtradb/btr/btr0btr.c21
-rw-r--r--storage/xtradb/btr/btr0cur.c14
-rw-r--r--storage/xtradb/btr/btr0sea.c1
-rw-r--r--storage/xtradb/buf/buf0buddy.c16
-rw-r--r--storage/xtradb/buf/buf0buf.c449
-rw-r--r--storage/xtradb/buf/buf0flu.c27
-rw-r--r--storage/xtradb/buf/buf0lru.c2
-rw-r--r--storage/xtradb/dict/dict0boot.c107
-rw-r--r--storage/xtradb/dict/dict0crea.c224
-rw-r--r--storage/xtradb/dict/dict0dict.c384
-rw-r--r--storage/xtradb/dict/dict0load.c10
-rw-r--r--storage/xtradb/dict/dict0mem.c4
-rw-r--r--storage/xtradb/fil/fil0fil.c154
-rw-r--r--storage/xtradb/ha/hash0hash.c64
-rw-r--r--storage/xtradb/handler/ha_innodb.cc435
-rw-r--r--storage/xtradb/handler/ha_innodb.h4
-rw-r--r--storage/xtradb/handler/handler0alter.cc2
-rw-r--r--storage/xtradb/handler/i_s.cc216
-rw-r--r--storage/xtradb/handler/i_s.h2
-rw-r--r--storage/xtradb/handler/innodb_patch_info.h1
-rw-r--r--storage/xtradb/include/buf0buf.h15
-rw-r--r--storage/xtradb/include/buf0lru.h2
-rw-r--r--storage/xtradb/include/buf0rea.h3
-rw-r--r--storage/xtradb/include/db0err.h2
-rw-r--r--storage/xtradb/include/dict0boot.h20
-rw-r--r--storage/xtradb/include/dict0crea.h18
-rw-r--r--storage/xtradb/include/dict0dict.h8
-rw-r--r--storage/xtradb/include/dict0mem.h2
-rw-r--r--storage/xtradb/include/fil0fil.h24
-rw-r--r--storage/xtradb/include/ha_prototypes.h20
-rw-r--r--storage/xtradb/include/hash0hash.h49
-rw-r--r--storage/xtradb/include/lock0lock.h12
-rw-r--r--storage/xtradb/include/log0log.ic5
-rw-r--r--storage/xtradb/include/mach0data.ic23
-rw-r--r--storage/xtradb/include/mtr0log.ic2
-rw-r--r--storage/xtradb/include/os0proc.h28
-rw-r--r--storage/xtradb/include/page0page.h2
-rw-r--r--storage/xtradb/include/page0page.ic3
-rw-r--r--storage/xtradb/include/page0zip.h2
-rw-r--r--storage/xtradb/include/que0que.h2
-rw-r--r--storage/xtradb/include/rem0cmp.h4
-rw-r--r--storage/xtradb/include/row0mysql.h72
-rw-r--r--storage/xtradb/include/srv0srv.h6
-rw-r--r--storage/xtradb/include/sync0rw.h5
-rw-r--r--storage/xtradb/include/sync0sync.h2
-rw-r--r--storage/xtradb/include/trx0sys.h1
-rw-r--r--storage/xtradb/include/trx0trx.h4
-rw-r--r--storage/xtradb/include/univ.i16
-rw-r--r--storage/xtradb/include/ut0lst.h43
-rw-r--r--storage/xtradb/lock/lock0lock.c178
-rw-r--r--storage/xtradb/log/log0log.c5
-rw-r--r--storage/xtradb/log/log0recv.c5
-rw-r--r--storage/xtradb/os/os0file.c19
-rw-r--r--storage/xtradb/os/os0proc.c172
-rw-r--r--storage/xtradb/page/page0zip.c7
-rw-r--r--storage/xtradb/que/que0que.c14
-rw-r--r--storage/xtradb/rem/rem0cmp.c7
-rw-r--r--storage/xtradb/row/row0ins.c139
-rw-r--r--storage/xtradb/row/row0merge.c133
-rw-r--r--storage/xtradb/row/row0mysql.c134
-rw-r--r--storage/xtradb/row/row0purge.c11
-rw-r--r--storage/xtradb/row/row0sel.c173
-rw-r--r--storage/xtradb/row/row0uins.c13
-rw-r--r--storage/xtradb/row/row0umod.c82
-rw-r--r--storage/xtradb/row/row0undo.c4
-rw-r--r--storage/xtradb/row/row0upd.c16
-rw-r--r--storage/xtradb/srv/srv0srv.c14
-rw-r--r--storage/xtradb/srv/srv0start.c5
-rw-r--r--storage/xtradb/sync/sync0arr.c4
-rw-r--r--storage/xtradb/sync/sync0rw.c22
-rw-r--r--storage/xtradb/sync/sync0sync.c11
-rw-r--r--storage/xtradb/trx/trx0i_s.c38
-rw-r--r--storage/xtradb/trx/trx0purge.c3
-rw-r--r--storage/xtradb/trx/trx0sys.c12
-rw-r--r--storage/xtradb/trx/trx0trx.c57
-rw-r--r--storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c43
-rw-r--r--storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c54
-rw-r--r--storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c61
-rw-r--r--storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c39
-rw-r--r--storage/xtradb/ut/ut0auxconf_pause.c32
-rw-r--r--storage/xtradb/ut/ut0auxconf_sizeof_pthread_t.c35
-rwxr-xr-xstrings/CMakeLists.txt2
-rw-r--r--strings/Makefile.am4
-rw-r--r--strings/bzero.c10
-rw-r--r--strings/ctype-big5.c86
-rw-r--r--strings/ctype-cp932.c76
-rw-r--r--strings/ctype-euc_kr.c4
-rw-r--r--strings/ctype-eucjpms.c4
-rw-r--r--strings/ctype-gb2312.c4
-rw-r--r--strings/ctype-gbk.c86
-rw-r--r--strings/ctype-mb.c22
-rw-r--r--strings/ctype-sjis.c85
-rw-r--r--strings/ctype-uca.c4
-rw-r--r--strings/ctype-ujis.c4
-rw-r--r--strings/decimal.c3
-rwxr-xr-xstrings/make-ccc2
-rw-r--r--strings/strxmov.c1
-rw-r--r--strings/xml.c8
-rw-r--r--support-files/Makefile.am3
-rw-r--r--support-files/compiler_warnings.supp9
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/mysql_client_test.c59
-rw-r--r--unittest/Makefile.am7
-rw-r--r--unittest/mysys/Makefile.am7
-rw-r--r--unittest/strings/Makefile.am27
-rw-r--r--unittest/strings/strings-t.c116
-rw-r--r--vio/Makefile.am3
-rw-r--r--win/Makefile.am2
-rw-r--r--zlib/Makefile.am3
448 files changed, 9726 insertions, 3454 deletions
diff --git a/BUILD/Makefile.am b/BUILD/Makefile.am
index 6cf86f40535..3d9986ab548 100644
--- a/BUILD/Makefile.am
+++ b/BUILD/Makefile.am
@@ -83,6 +83,3 @@ EXTRA_DIST = FINISH.sh \
compile-solaris-x86-32-debug-forte \
compile-solaris-x86-forte-32 \
util.sh
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 33830fd9987..19d8938a09e 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -98,22 +98,19 @@ SSL_LIBRARY=--with-ssl
if [ "x$warning_mode" != "xpedantic" ]; then
# Both C and C++ warnings
- warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W"
- warnings="$warnings -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare"
- warnings="$warnings -Wwrite-strings -Wunused-function -Wunused-label -Wunused-value -Wunused-variable"
+ warnings="-Wall -Wextra -Wunused -Wwrite-strings"
# For more warnings, uncomment the following line
-# warnings="$global_warnings -Wshadow"
+# warnings="$warnings -Wshadow"
# C warnings
- c_warnings="$warnings -Wunused-parameter"
+ c_warnings="$warnings"
# C++ warnings
- cxx_warnings="$warnings"
+ cxx_warnings="$warnings -Wno-unused-parameter"
# cxx_warnings="$cxx_warnings -Woverloaded-virtual -Wsign-promo"
- cxx_warnings="$cxx_warnings -Wreorder"
cxx_warnings="$cxx_warnings -Wctor-dtor-privacy -Wnon-virtual-dtor"
# Added unless --with-debug=full
- debug_extra_cflags="-O0 -g3 -gdwarf-2" #1 -Wuninitialized"
+ debug_extra_cflags="-O0 -g3 -gdwarf-2"
else
warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -D_POSIX_SOURCE"
c_warnings="$warnings"
diff --git a/BUILD/check-cpu b/BUILD/check-cpu
index c0e87a675cb..390ba545405 100755
--- a/BUILD/check-cpu
+++ b/BUILD/check-cpu
@@ -181,14 +181,17 @@ check_cpu () {
cc=$CC
fi
- cc_ver=`$cc --version | sed 1q`
- cc_verno=`echo $cc_ver | sed -e 's/^.*(GCC)//g; s/[^0-9. ]//g; s/^ *//g; s/ .*//g'`
- set -- `echo $cc_verno | tr '.' ' '`
- cc_major=$1
- cc_minor=$2
- cc_patch=$3
- cc_comp=`expr $cc_major '*' 100 '+' $cc_minor`
-
+ # check if compiler is gcc and dump its version
+ cc_verno=`$cc -dumpversion 2>/dev/null`
+ if test "x$?" = "x0" ; then
+ set -- `echo $cc_verno | tr '.' ' '`
+ cc_ver="GCC"
+ cc_major=$1
+ cc_minor=$2
+ cc_patch=$3
+ cc_comp=`expr $cc_major '*' 100 '+' $cc_minor`
+ fi
+
case "$cc_ver--$cc_verno" in
*GCC*)
# different gcc backends (and versions) have different CPU flags
@@ -229,7 +232,7 @@ check_cpu () {
fi
while [ "$cpu_arg" ] ; do
printf "testing $cpu_arg ... " >&2
-
+
# compile check
eval "$cc -c $check_cpu_cflags __test.c" 2>/dev/null
if test "x$?" = "x0" ; then
@@ -243,5 +246,5 @@ check_cpu () {
done
rm __test.*
}
-
+
check_cpu
diff --git a/Docs/Makefile.am b/Docs/Makefile.am
index 24f921a4877..48030153a4e 100644
--- a/Docs/Makefile.am
+++ b/Docs/Makefile.am
@@ -37,6 +37,3 @@ uninstall-local:
@RM@ -f $(DESTDIR)$(infodir)/mysql.info ; \
@RM@ -f $(DESTDIR)$(pkgdatadir)/ChangeLog ; \
fi
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/Makefile.am b/Makefile.am
index 7474177f5f5..20733428f38 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -325,7 +325,7 @@ abi_check_all: $(TEST_PREPROCESSOR_HEADER)
do_abi_check:
set -ex; \
for file in $(abi_headers); do \
- @CC@ -E -nostdinc -dI \
+ @CC@ -E -nostdinc -dI -DMYSQL_ABI_CHECK \
-I$(top_srcdir)/include \
-I$(top_srcdir)/include/mysql \
-I$(top_srcdir)/sql \
@@ -341,6 +341,3 @@ do_abi_check:
@DIFF@ -w $$file.pp $(top_builddir)/abi_check.out; \
@RM@ $(top_builddir)/abi_check.out; \
done
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/client/Makefile.am b/client/Makefile.am
index bfca0ba4bb2..f4855a03797 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -123,6 +123,3 @@ link_sources:
rm -f $(srcdir)/my_user.c; \
@LN_CP_F@ $(top_srcdir)/sql-common/my_user.c my_user.c;
echo timestamp > link_sources;
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/client/mysql.cc b/client/mysql.cc
index 5d6018fd910..e72f27aeeff 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -3663,7 +3663,7 @@ xmlencode_print(const char *src, uint length)
tee_fputs("NULL", PAGER);
else
{
- for (const char *p = src; length; *p++, length--)
+ for (const char *p = src; length; p++, length--)
{
const char *t;
if ((t = array_value(xmlmeta, *p)))
@@ -4833,7 +4833,7 @@ static const char *construct_prompt()
struct tm *t = localtime(&lclock);
/* parse thru the settings for the prompt */
- for (char *c = current_prompt; *c ; *c++)
+ for (char *c = current_prompt; *c ; c++)
{
if (*c != PROMPT_CHAR)
processed_prompt.append(*c);
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index a61b67d67c8..c72f13eded6 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -1,4 +1,5 @@
/* Copyright (C) 2000 MySQL AB
+ Copyright (C) 2010 Monty Program Ab
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
@@ -17,7 +18,7 @@
#include <sslopt-vars.h>
#include "../scripts/mysql_fix_privilege_tables_sql.c"
-#define VER "1.1"
+#define VER "1.2"
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
@@ -34,8 +35,9 @@
static char mysql_path[FN_REFLEN];
static char mysqlcheck_path[FN_REFLEN];
-static my_bool opt_force, opt_verbose, debug_info_flag, debug_check_flag;
-static uint my_end_arg= 0;
+static my_bool opt_force, debug_info_flag, debug_check_flag, opt_silent;
+static my_bool opt_not_used; /* For compatiblity */
+static uint my_end_arg= 0, opt_verbose;
static char *opt_user= (char*)"root";
static DYNAMIC_STRING ds_args;
@@ -62,12 +64,14 @@ static struct my_option my_long_options[]=
{
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
- {"basedir", 'b', "Not used by mysql_upgrade. Only for backward compatibility.",
+ {"basedir", 'b',
+ "Not used by mysql_upgrade. Only for backward compatibility.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
- "Directory for character set files.", 0,
- 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"compress", OPT_COMPRESS, "Use compression in server/client protocol.",
+ "Not used by mysql_upgrade. Only for backward compatibility.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ {"compress", OPT_COMPRESS,
+ "Not used by mysql_upgrade. Only for backward compatibility.",
&not_used, &not_used, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"datadir", 'd',
"Not used by mysql_upgrade. Only for backward compatibility.",
@@ -80,18 +84,17 @@ static struct my_option my_long_options[]=
&default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
- &debug_check_flag, &debug_check_flag, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ &debug_check_flag, &debug_check_flag,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"debug-info", 'T', "Print some debug info at exit.", &debug_info_flag,
&debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"default-character-set", OPT_DEFAULT_CHARSET,
- "Set the default character set.", 0,
- 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "Not used by mysql_upgrade. Only for backward compatibility.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"force", 'f', "Force execution of mysqlcheck even if mysql_upgrade "
"has already been executed for the current version of MySQL.",
- &opt_force, &opt_force, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"host",'h', "Connect to host.", 0,
+ &opt_force, &opt_force, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host.", 0,
0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"password", 'p',
"Password to use when connecting to server. If password is not given,"
@@ -116,6 +119,8 @@ static struct my_option my_long_options[]=
"Base name of shared memory.", 0,
0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"silent", 's', "Print less information", &opt_silent,
+ &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"socket", 'S', "The socket file to use for connection.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include <sslopt-longopts.h>
@@ -124,8 +129,7 @@ static struct my_option my_long_options[]=
{"user", 'u', "User for login if not current user.", &opt_user,
&opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Display more output about the process.",
- &opt_verbose, &opt_verbose, 0,
- GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ &opt_not_used, &opt_not_used, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"write-binlog", OPT_WRITE_BINLOG,
"All commands including mysqlcheck are binlogged. Enabled by default;"
"use --skip-write-binlog when commands should not be sent to replication slaves.",
@@ -173,7 +177,7 @@ static void verbose(const char *fmt, ...)
{
va_list args;
- if (!opt_verbose)
+ if (opt_silent)
return;
/* Print the verbose message */
@@ -266,6 +270,18 @@ get_one_option(int optid, const struct my_option *opt,
/* FALLTHROUGH */
case 'v': /* --verbose */
+ opt_verbose++;
+ if (argument == disabled_my_option)
+ {
+ opt_verbose= 0;
+ opt_silent= 1;
+ }
+ add_option= 0;
+ break;
+ case 's':
+ opt_verbose= 0;
+ add_option= 0;
+ break;
case 'f': /* --force */
add_option= FALSE;
break;
@@ -426,7 +442,8 @@ static void find_tool(char *tool_executable_name, const char *tool_name,
len, self_name, FN_LIBCHAR, tool_name);
}
- verbose("Looking for '%s' as: %s", tool_name, tool_executable_name);
+ if (opt_verbose)
+ verbose("Looking for '%s' as: %s", tool_name, tool_executable_name);
/*
Make sure it can be executed
@@ -496,7 +513,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
"--database=mysql",
"--batch", /* Turns off pager etc. */
force ? "--force": "--skip-force",
- ds_res ? "--silent": "",
+ ds_res || opt_silent ? "--silent": "",
"<",
query_file_path,
"2>&1",
@@ -649,6 +666,8 @@ static void create_mysql_upgrade_info_file(void)
static void print_conn_args(const char *tool_name)
{
+ if (opt_verbose < 2)
+ return;
if (conn_args.str[0])
verbose("Running '%s' with connection arguments: %s", tool_name,
conn_args.str);
@@ -664,6 +683,7 @@ static void print_conn_args(const char *tool_name)
static int run_mysqlcheck_upgrade(void)
{
+ verbose("Phase 2/3: Checking and upgrading tables");
print_conn_args("mysqlcheck");
return run_tool(mysqlcheck_path,
NULL, /* Send output from mysqlcheck directly to screen */
@@ -672,6 +692,8 @@ static int run_mysqlcheck_upgrade(void)
"--check-upgrade",
"--all-databases",
"--auto-repair",
+ !opt_silent || opt_verbose ? "--verbose": "",
+ opt_silent ? "--silent": "",
opt_write_binlog ? "--write-binlog" : "--skip-write-binlog",
NULL);
}
@@ -679,6 +701,7 @@ static int run_mysqlcheck_upgrade(void)
static int run_mysqlcheck_fixnames(void)
{
+ verbose("Phase 1/3: Fixing table and database names");
print_conn_args("mysqlcheck");
return run_tool(mysqlcheck_path,
NULL, /* Send output from mysqlcheck directly to screen */
@@ -687,6 +710,8 @@ static int run_mysqlcheck_fixnames(void)
"--all-databases",
"--fix-db-names",
"--fix-table-names",
+ opt_verbose ? "--verbose": "",
+ opt_silent ? "--silent": "",
opt_write_binlog ? "--write-binlog" : "--skip-write-binlog",
NULL);
}
@@ -756,7 +781,7 @@ static int run_sql_fix_privilege_tables(void)
if (init_dynamic_string(&ds_result, "", 512, 512))
die("Out of memory");
- verbose("Running 'mysql_fix_privilege_tables'...");
+ verbose("Phase 3/3: Running 'mysql_fix_privilege_tables'...");
run_query(mysql_fix_privilege_tables,
&ds_result, /* Collect result */
TRUE);
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 62eab5bf6e4..41249949633 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000 MySQL AB & Jani Tolonen
+ Copyright (C) 2010 Monty Program Ab
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
@@ -15,7 +16,7 @@
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */
-#define CHECK_VERSION "2.5.0"
+#define CHECK_VERSION "2.6.0"
#include "client_priv.h"
#include <m_ctype.h>
@@ -222,24 +223,26 @@ static void usage(void)
{
print_version();
puts("By Jani Tolonen, 2001-04-20, MySQL Development Team.\n");
- puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,");
puts("and you are welcome to modify and redistribute it under the GPL license.\n");
+ printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
+ printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
+ my_progname);
+ printf("OR %s [OPTIONS] --all-databases\n\n", my_progname);
puts("This program can be used to CHECK (-c, -m, -C), REPAIR (-r), ANALYZE (-a),");
puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be");
puts("used at the same time. Not all options are supported by all storage engines.");
- puts("Please consult the MySQL manual for latest information about the");
- puts("above. The options -c, -r, -a, and -o are exclusive to each other, which");
+ puts("The options -c, -r, -a, and -o are exclusive to each other, which");
puts("means that the last option will be used, if several was specified.\n");
- puts("The option -c will be used by default, if none was specified. You");
- puts("can change the default behavior by making a symbolic link, or");
+ puts("The option -c (--check) will be used by default, if none was specified.");
+ puts("You can change the default behavior by making a symbolic link, or");
puts("copying this file somewhere with another name, the alternatives are:");
puts("mysqlrepair: The default option will be -r");
puts("mysqlanalyze: The default option will be -a");
puts("mysqloptimize: The default option will be -o\n");
- printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
- printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
- my_progname);
- printf("OR %s [OPTIONS] --all-databases\n", my_progname);
+ puts("Please consult the MariaDB/MySQL knowledgebase at");
+ puts("http://kb.askmonty.org/v/mysqlcheck for latest information about");
+ puts("this program.");
print_defaults("my", load_default_groups);
my_print_help(my_long_options);
my_print_variables(my_long_options);
@@ -416,6 +419,8 @@ static int process_all_databases()
MYF(0), mysql_error(sock));
return 1;
}
+ if (verbose)
+ printf("Processing databases\n");
while ((row = mysql_fetch_row(tableres)))
{
if (process_one_db(row[0]))
@@ -429,6 +434,8 @@ static int process_all_databases()
static int process_databases(char **db_names)
{
int result = 0;
+ if (verbose)
+ printf("Processing databases\n");
for ( ; *db_names ; db_names++)
{
if (process_one_db(*db_names))
@@ -521,6 +528,7 @@ static int process_all_tables_in_db(char *database)
MYSQL_RES *res;
MYSQL_ROW row;
uint num_columns;
+ my_bool system_database= 0;
LINT_INIT(res);
if (use_db(database))
@@ -534,6 +542,9 @@ static int process_all_tables_in_db(char *database)
return 1;
}
+ if (!strcmp(database, "mysql") || !strcmp(database, "MYSQL"))
+ system_database= 1;
+
num_columns= mysql_num_fields(res);
if (opt_all_in_1 && what_to_do != DO_UPGRADE)
@@ -576,6 +587,10 @@ static int process_all_tables_in_db(char *database)
/* Skip views if we don't perform renaming. */
if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
continue;
+ if (system_database &&
+ (!strcmp(row[0], "general_log") ||
+ !strcmp(row[0], "slow_log")))
+ continue; /* Skip logging tables */
handle_request_for_tables(row[0], fixed_name_length(row[0]));
}
@@ -624,6 +639,8 @@ static int fix_database_storage_name(const char *name)
static int process_one_db(char *database)
{
+ if (verbose)
+ puts(database);
if (what_to_do == DO_UPGRADE)
{
int rc= 0;
@@ -731,7 +748,7 @@ static void print_result()
{
MYSQL_RES *res;
MYSQL_ROW row;
- char prev[NAME_LEN*2+2];
+ char prev[(NAME_LEN+9)*2+2];
uint i;
my_bool found_error=0;
@@ -761,7 +778,15 @@ static void print_result()
printf("%-50s %s", row[0], row[3]);
else if (!status && changed)
{
- printf("%s\n%-9s: %s", row[0], row[2], row[3]);
+ /*
+ If the error message includes REPAIR TABLE, we assume it means
+ we have to run upgrade on it. In this case we write a nicer message
+ than "Please do "REPAIR TABLE""...
+ */
+ if (!strcmp(row[2],"error") && strinstr(row[3],"REPAIR TABLE") != 0)
+ printf("%-50s %s", row[0], "Needs upgrade");
+ else
+ printf("%s\n%-9s: %s", row[0], row[2], row[3]);
if (strcmp(row[2],"note"))
found_error=1;
}
@@ -780,7 +805,7 @@ static void print_result()
static int dbConnect(char *host, char *user, char *passwd)
{
DBUG_ENTER("dbConnect");
- if (verbose)
+ if (verbose > 1)
{
fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
}
@@ -813,7 +838,7 @@ static int dbConnect(char *host, char *user, char *passwd)
static void dbDisconnect(char *host)
{
- if (verbose)
+ if (verbose > 1)
fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
mysql_close(sock);
} /* dbDisconnect */
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 2c9a59a2d54..698516e0794 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -669,8 +669,7 @@ list_fields(MYSQL *mysql,const char *db,const char *table,
char query[1024],*end;
MYSQL_RES *result;
MYSQL_ROW row;
- ulong rows;
- LINT_INIT(rows);
+ ulong UNINIT_VAR(rows);
if (mysql_select_db(mysql,db))
{
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 0a7bf9b556d..9780317689a 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -5828,7 +5828,7 @@ int read_command(struct st_command** command_ptr)
(struct st_command*) my_malloc(sizeof(*command),
MYF(MY_WME|MY_ZEROFILL))) ||
insert_dynamic(&q_lines, (uchar*) &command))
- die(NullS);
+ die("Out of memory");
command->type= Q_UNKNOWN;
read_command_buf[0]= 0;
@@ -6325,7 +6325,7 @@ void init_win_path_patterns()
}
if (insert_dynamic(&patterns, (uchar*) &p))
- die(NullS);
+ die("Out of memory");
DBUG_PRINT("info", ("p: %s", p));
while (*p)
@@ -9405,8 +9405,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
for (i=1 ; i <= found_sets ; i++)
{
pos=from[found_set[i-1].table_offset];
- rep_str[i].found= !bcmp((const uchar*) pos,
- (const uchar*) "\\^", 3) ? 2 : 1;
+ rep_str[i].found= !memcmp(pos, "\\^", 3) ? 2 : 1;
rep_str[i].replace_string=to_array[found_set[i-1].table_offset];
rep_str[i].to_offset=found_set[i-1].found_offset-start_at_word(pos);
rep_str[i].from_offset=found_set[i-1].found_offset-replace_len(pos)+
@@ -9534,8 +9533,8 @@ void copy_bits(REP_SET *to,REP_SET *from)
int cmp_bits(REP_SET *set1,REP_SET *set2)
{
- return bcmp((uchar*) set1->bits,(uchar*) set2->bits,
- sizeof(uint) * set1->size_of_bits);
+ return memcmp(set1->bits, set2->bits,
+ sizeof(uint) * set1->size_of_bits);
}
@@ -9604,17 +9603,15 @@ int find_found(FOUND_SET *found_set,uint table_offset, int found_offset)
uint start_at_word(char * pos)
{
- return (((!bcmp((const uchar*) pos, (const uchar*) "\\b",2) && pos[2]) ||
- !bcmp((const uchar*) pos, (const uchar*) "\\^", 2)) ? 1 : 0);
+ return (((!memcmp(pos, "\\b",2) && pos[2]) ||
+ !memcmp(pos, "\\^", 2)) ? 1 : 0);
}
uint end_of_word(char * pos)
{
char * end=strend(pos);
- return ((end > pos+2 && !bcmp((const uchar*) end-2,
- (const uchar*) "\\b", 2)) ||
- (end >= pos+2 && !bcmp((const uchar*) end-2,
- (const uchar*) "\\$",2))) ? 1 : 0;
+ return ((end > pos+2 && !memcmp(end-2, "\\b", 2)) ||
+ (end >= pos+2 && !memcmp(end-2, "\\$",2))) ? 1 : 0;
}
/****************************************************************************
diff --git a/cmd-line-utils/Makefile.am b/cmd-line-utils/Makefile.am
index 1a84ce7af38..622aa72fd43 100644
--- a/cmd-line-utils/Makefile.am
+++ b/cmd-line-utils/Makefile.am
@@ -19,6 +19,3 @@
SUBDIRS= @readline_basedir@
DIST_SUBDIRS= libedit readline
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/cmd-line-utils/readline/Makefile.am b/cmd-line-utils/readline/Makefile.am
index e5f5717858d..e1e9645e238 100644
--- a/cmd-line-utils/readline/Makefile.am
+++ b/cmd-line-utils/readline/Makefile.am
@@ -31,7 +31,7 @@ noinst_HEADERS = readline.h chardefs.h keymaps.h \
EXTRA_DIST= emacs_keymap.c vi_keymap.c
-DEFS = -DMYSQL_CLIENT_NO_THREADS -DHAVE_CONFIG_H -DNO_KILL_INTR
+DEFS = -DMYSQL_CLIENT_NO_THREADS -DHAVE_CONFIG_H -DNO_KILL_INTR -D_GNU_SOURCE=1
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/cmd-line-utils/readline/input.c b/cmd-line-utils/readline/input.c
index 84c0422059a..af81d9cd3b0 100644
--- a/cmd-line-utils/readline/input.c
+++ b/cmd-line-utils/readline/input.c
@@ -318,7 +318,9 @@ _rl_input_available ()
return (_kbhit ());
#endif
+#if !defined (HAVE_SELECT)
return 0;
+#endif
}
int
diff --git a/config/ac-macros/maintainer.m4 b/config/ac-macros/maintainer.m4
new file mode 100644
index 00000000000..1b7df75d6f7
--- /dev/null
+++ b/config/ac-macros/maintainer.m4
@@ -0,0 +1,64 @@
+#
+# Control aspects of the development environment which are
+# specific to MySQL maintainers and developers.
+#
+AC_DEFUN([MY_MAINTAINER_MODE], [
+ AC_MSG_CHECKING([whether to enable the maintainer-specific development environment])
+ AC_ARG_ENABLE([mysql-maintainer-mode],
+ [AS_HELP_STRING([--enable-mysql-maintainer-mode],
+ [Enable a MySQL maintainer-specific development environment])],
+ [USE_MYSQL_MAINTAINER_MODE=$enableval],
+ [USE_MYSQL_MAINTAINER_MODE=no])
+ AC_MSG_RESULT([$USE_MYSQL_MAINTAINER_MODE])
+])
+
+# Set warning options required under maintainer mode.
+AC_DEFUN([MY_MAINTAINER_MODE_WARNINGS], [
+ # Setup GCC warning options.
+ AS_IF([test "$GCC" = "yes"], [
+ C_WARNINGS="-Wall -Wextra -Wunused -Wwrite-strings -Werror"
+ CXX_WARNINGS="${C_WARNINGS} -Wno-unused-parameter"
+ ])
+
+ # Test whether the warning options work.
+ # Test C options
+ AS_IF([test -n "$C_WARNINGS"], [
+ save_CFLAGS="$CFLAGS"
+ AC_MSG_CHECKING([whether to use C warning options ${C_WARNINGS}])
+ AC_LANG_PUSH(C)
+ CFLAGS="$CFLAGS ${C_WARNINGS}"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [myac_c_warning_flags=yes],
+ [myac_c_warning_flags=no])
+ AC_LANG_POP()
+ AC_MSG_RESULT([$myac_c_warning_flags])
+ CFLAGS="$save_CFLAGS"
+ ])
+
+ # Test C++ options
+ AS_IF([test -n "$CXX_WARNINGS"], [
+ save_CXXFLAGS="$CXXFLAGS"
+ AC_MSG_CHECKING([whether to use C++ warning options ${CXX_WARNINGS}])
+ AC_LANG_PUSH(C++)
+ CXXFLAGS="$CXXFLAGS ${CXX_WARNINGS}"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [myac_cxx_warning_flags=yes],
+ [myac_cxx_warning_flags=no])
+ AC_LANG_POP()
+ AC_MSG_RESULT([$myac_cxx_warning_flags])
+ CXXFLAGS="$save_CXXFLAGS"
+ ])
+
+ # Set compile flag variables.
+ AS_IF([test "$myac_c_warning_flags" = "yes"], [
+ AM_CFLAGS="${AM_CFLAGS} ${C_WARNINGS}"
+ AC_SUBST([AM_CFLAGS])])
+ AS_IF([test "$myac_cxx_warning_flags" = "yes"], [
+ AM_CXXFLAGS="${AM_CXXFLAGS} ${CXX_WARNINGS}"
+ AC_SUBST([AM_CXXFLAGS])])
+])
+
+
+# Set compiler flags required under maintainer mode.
+AC_DEFUN([MY_MAINTAINER_MODE_SETUP], [
+ AS_IF([test "$USE_MYSQL_MAINTAINER_MODE" = "yes"],
+ [MY_MAINTAINER_MODE_WARNINGS])
+])
diff --git a/configure.in b/configure.in
index d5e08b7a6c1..52fc8400c4c 100644
--- a/configure.in
+++ b/configure.in
@@ -11,13 +11,7 @@ dnl internals@lists.mysql.com in advance of pushing the change.
dnl
dnl When changing the major version number please also check the switch
dnl statement in mysqlbinlog::check_master_version(). You may also need
-dnl to update version.c in ndb.
-dnl
-dnl When merging new MariaDB releases, update the version number to match the
-dnl MariaDB version number.
-dnl
-dnl Note: the following line must be parseable by win/configure.js:GetVersion()
-AC_INIT([MariaDB Server], [5.2.1-MariaDB-beta], [], [mysql])
+AC_INIT([MariaDB Server], [5.2.2-MariaDB-gamma], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
@@ -70,6 +64,7 @@ MYSQL_TCP_PORT_DEFAULT=3306
MYSQL_UNIX_ADDR_DEFAULT="/tmp/mysql.sock"
dnl Include m4
+sinclude(config/ac-macros/maintainer.m4)
sinclude(config/ac-macros/alloca.m4)
sinclude(config/ac-macros/check_cpu.m4)
sinclude(config/ac-macros/character_sets.m4)
@@ -108,6 +103,8 @@ AC_SUBST(SHARED_LIB_MAJOR_VERSION)
AC_SUBST(SHARED_LIB_VERSION)
AC_SUBST(AVAILABLE_LANGUAGES)
+# Whether the maintainer mode should be enabled.
+MY_MAINTAINER_MODE
# Canonicalize the configuration name.
@@ -2907,7 +2904,13 @@ do
done
AC_SUBST(sql_union_dirs)
-# Some useful subst
+#
+# Setup maintainer mode options by the end to not disturb
+# system and other checks.
+#
+MY_MAINTAINER_MODE_SETUP
+
+# Some usefull subst
AC_SUBST(CC)
AC_SUBST(GXX)
@@ -2932,7 +2935,8 @@ fi
AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl
unittest/Makefile unittest/mytap/Makefile unittest/mytap/t/Makefile dnl
- unittest/mysys/Makefile unittest/examples/Makefile dnl
+ unittest/mysys/Makefile unittest/strings/Makefile dnl
+ unittest/examples/Makefile dnl
strings/Makefile regex/Makefile storage/Makefile dnl
man/Makefile BUILD/Makefile vio/Makefile dnl
libmysql/Makefile libmysql_r/Makefile client/Makefile dnl
diff --git a/dbug/Makefile.am b/dbug/Makefile.am
index 7e909f9154f..528a6a02fbf 100644
--- a/dbug/Makefile.am
+++ b/dbug/Makefile.am
@@ -65,6 +65,3 @@ output5.r: factorial
# a hack to have executable in builddir, not in srcdir
tests-t: tests-t.pl
cp -f $(srcdir)/tests-t.pl ./tests-t
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/dbug/remove_function_from_trace.pl b/dbug/remove_function_from_trace.pl
index 1da9e25f9ba..380df168caf 100755
--- a/dbug/remove_function_from_trace.pl
+++ b/dbug/remove_function_from_trace.pl
@@ -1,6 +1,5 @@
#!/usr/bin/perl
-
die <<EEE unless @ARGV;
Usage: $0 func1 [func2 [ ...] ]
@@ -11,16 +10,16 @@ DBUG_ENTER() and DBUG_POP(); right before DBUG_RETURN in every such a function.
EEE
$re=join('|', @ARGV);
-$skip='';
while(<STDIN>) {
- print unless $skip;
+ ($thd) = /^(T@\d+)/;
+ print unless $skip{$thd};
next unless /^(?:.*: )*((?:\| )*)([<>])($re)\n/o;
if ($2 eq '>') {
- $skip=$1.$3 unless $skip;
+ $skip{$thd}=$1.$3 unless $skip{$thd};
next;
}
- next if $skip ne $1.$3;
- $skip='';
+ next if $skip{$thd} ne $1.$3;
+ delete $skip{$thd};
print;
}
diff --git a/extra/Makefile.am b/extra/Makefile.am
index 742f39b6827..8d6d18f0031 100644
--- a/extra/Makefile.am
+++ b/extra/Makefile.am
@@ -55,6 +55,3 @@ EXTRA_DIST = CMakeLists.txt
perror.o: perror.c
$(COMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $<
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/extra/comp_err.c b/extra/comp_err.c
index 58395cd6344..adce6a6f5bd 100644
--- a/extra/comp_err.c
+++ b/extra/comp_err.c
@@ -640,9 +640,9 @@ static struct message *find_message(struct errors *err, const char *lang,
static ha_checksum checksum_format_specifier(const char* msg)
{
ha_checksum chksum= 0;
- const char* p= msg;
- const char* start= 0;
- int num_format_specifiers= 0;
+ const uchar* p= (const uchar*) msg;
+ const uchar* start= NULL;
+ uint32 num_format_specifiers= 0;
while (*p)
{
@@ -832,7 +832,6 @@ static struct message *parse_message_string(struct message *new_message,
static struct errors *parse_error_string(char *str, int er_count)
{
struct errors *new_error;
- char *start;
DBUG_ENTER("parse_error_string");
DBUG_PRINT("enter", ("str: %s", str));
@@ -843,7 +842,6 @@ static struct errors *parse_error_string(char *str, int er_count)
DBUG_RETURN(0); /* OOM: Fatal error */
/* getting the error name */
- start= str;
str= skip_delimiters(str);
if (!(new_error->er_name= get_word(&str)))
diff --git a/extra/replace.c b/extra/replace.c
index e254a5e7176..40bddf6d8fb 100644
--- a/extra/replace.c
+++ b/extra/replace.c
@@ -649,7 +649,7 @@ static REPLACE *init_replace(char * *from, char * *to,uint count,
for (i=1 ; i <= found_sets ; i++)
{
pos=from[found_set[i-1].table_offset];
- rep_str[i].found= (my_bool) (!bcmp(pos,"\\^",3) ? 2 : 1);
+ rep_str[i].found= (my_bool) (!memcmp(pos,"\\^",3) ? 2 : 1);
rep_str[i].replace_string=to_array[found_set[i-1].table_offset];
rep_str[i].to_offset=found_set[i-1].found_offset-start_at_word(pos);
rep_str[i].from_offset=found_set[i-1].found_offset-replace_len(pos)+
@@ -777,8 +777,8 @@ static void copy_bits(REP_SET *to,REP_SET *from)
static int cmp_bits(REP_SET *set1,REP_SET *set2)
{
- return bcmp((uchar*) set1->bits,(uchar*) set2->bits,
- sizeof(uint) * set1->size_of_bits);
+ return memcmp(set1->bits, set2->bits,
+ sizeof(uint) * set1->size_of_bits);
}
@@ -850,14 +850,14 @@ static short find_found(FOUND_SET *found_set,uint table_offset,
static uint start_at_word(char * pos)
{
- return (((!bcmp(pos,"\\b",2) && pos[2]) || !bcmp(pos,"\\^",2)) ? 1 : 0);
+ return (((!memcmp(pos,"\\b",2) && pos[2]) || !memcmp(pos,"\\^",2)) ? 1 : 0);
}
static uint end_of_word(char * pos)
{
char * end=strend(pos);
- return ((end > pos+2 && !bcmp(end-2,"\\b",2)) ||
- (end >= pos+2 && !bcmp(end-2,"\\$",2))) ?
+ return ((end > pos+2 && !memcmp(end-2,"\\b",2)) ||
+ (end >= pos+2 && !memcmp(end-2,"\\$",2))) ?
1 : 0;
}
diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp
index d0eabce7bc9..5128c00418e 100644
--- a/extra/yassl/src/yassl_imp.cpp
+++ b/extra/yassl/src/yassl_imp.cpp
@@ -884,21 +884,19 @@ void Alert::Process(input_buffer& input, SSL& ssl)
else
hmac(ssl, verify, data, aSz, alert, true);
- // read mac and fill
+ // read mac and skip fill
int digestSz = ssl.getCrypto().get_digest().get_digestSize();
opaque mac[SHA_LEN];
input.read(mac, digestSz);
if (ssl.getSecurity().get_parms().cipher_type_ == block) {
int ivExtra = 0;
- opaque fill;
if (ssl.isTLSv1_1())
ivExtra = ssl.getCrypto().get_cipher().get_blockSize();
int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra -
aSz - digestSz;
- for (int i = 0; i < padSz; i++)
- fill = input[AUTO];
+ input.set_current(input.get_current() + padSz);
}
// verify
@@ -981,17 +979,17 @@ output_buffer& operator<<(output_buffer& output, const Data& data)
void Data::Process(input_buffer& input, SSL& ssl)
{
int msgSz = ssl.getSecurity().get_parms().encrypt_size_;
- int pad = 0, padByte = 0;
+ int pad = 0, padSz = 0;
int ivExtra = 0;
if (ssl.getSecurity().get_parms().cipher_type_ == block) {
if (ssl.isTLSv1_1()) // IV
ivExtra = ssl.getCrypto().get_cipher().get_blockSize();
pad = *(input.get_buffer() + input.get_current() + msgSz -ivExtra - 1);
- padByte = 1;
+ padSz = 1;
}
int digestSz = ssl.getCrypto().get_digest().get_digestSize();
- int dataSz = msgSz - ivExtra - digestSz - pad - padByte;
+ int dataSz = msgSz - ivExtra - digestSz - pad - padSz;
opaque verify[SHA_LEN];
const byte* rawData = input.get_buffer() + input.get_current();
@@ -1020,14 +1018,10 @@ void Data::Process(input_buffer& input, SSL& ssl)
hmac(ssl, verify, rawData, dataSz, application_data, true);
}
- // read mac and fill
+ // read mac and skip fill
opaque mac[SHA_LEN];
- opaque fill;
input.read(mac, digestSz);
- for (int i = 0; i < pad; i++)
- fill = input[AUTO];
- if (padByte)
- fill = input[AUTO];
+ input.set_current(input.get_current() + pad + padSz);
// verify
if (dataSz) {
@@ -2072,11 +2066,9 @@ void Finished::Process(input_buffer& input, SSL& ssl)
if (ssl.isTLSv1_1())
ivExtra = ssl.getCrypto().get_cipher().get_blockSize();
- opaque fill;
int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra -
HANDSHAKE_HEADER - finishedSz - digestSz;
- for (int i = 0; i < padSz; i++)
- fill = input[AUTO];
+ input.set_current(input.get_current() + padSz);
// verify mac
if (memcmp(mac, verifyMAC, digestSz)) {
diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp
index 90d2c014b4c..94bbab7aea8 100644
--- a/extra/yassl/taocrypt/include/blowfish.hpp
+++ b/extra/yassl/taocrypt/include/blowfish.hpp
@@ -51,7 +51,7 @@ public:
enum { BLOCK_SIZE = BLOWFISH_BLOCK_SIZE, ROUNDS = 16 };
Blowfish(CipherDir DIR, Mode MODE)
- : Mode_BASE(BLOCK_SIZE, DIR, MODE) {}
+ : Mode_BASE(BLOCK_SIZE, DIR, MODE), sbox_(pbox_ + ROUNDS + 2) {}
#ifdef DO_BLOWFISH_ASM
void Process(byte*, const byte*, word32);
@@ -62,8 +62,8 @@ private:
static const word32 p_init_[ROUNDS + 2];
static const word32 s_init_[4 * 256];
- word32 pbox_[ROUNDS + 2];
- word32 sbox_[4 * 256];
+ word32 pbox_[ROUNDS + 2 + 4 * 256];
+ word32* sbox_;
void crypt_block(const word32 in[2], word32 out[2]) const;
void AsmProcess(const byte* in, byte* out) const;
diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp
index 99bbe3ac8a3..9d12b253dd6 100644
--- a/extra/yassl/taocrypt/include/runtime.hpp
+++ b/extra/yassl/taocrypt/include/runtime.hpp
@@ -35,10 +35,7 @@
// Handler for pure virtual functions
namespace __Crun {
- static void pure_error(void)
- {
- assert("Pure virtual method called." == "Aborted");
- }
+ void pure_error(void);
} // namespace __Crun
#endif // __sun
@@ -54,16 +51,7 @@ extern "C" {
#else
#include "kernelc.hpp"
#endif
-
-/* Disallow inline __cxa_pure_virtual() */
-static int __cxa_pure_virtual() __attribute__((noinline, used));
-static int __cxa_pure_virtual()
-{
- // oops, pure virtual called!
- assert("Pure virtual method called." == "Aborted");
- return 0;
-}
-
+ int __cxa_pure_virtual () __attribute__ ((weak));
} // extern "C"
#endif // __GNUC__ > 2
diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp
index 6e402da0117..437563b9093 100644
--- a/extra/yassl/taocrypt/src/algebra.cpp
+++ b/extra/yassl/taocrypt/src/algebra.cpp
@@ -185,10 +185,10 @@ Integer AbstractGroup::CascadeScalarMultiply(const Element &x,
struct WindowSlider
{
- WindowSlider(const Integer &exp, bool fastNegate,
+ WindowSlider(const Integer &expIn, bool fastNegateIn,
unsigned int windowSizeIn=0)
- : exp(exp), windowModulus(Integer::One()), windowSize(windowSizeIn),
- windowBegin(0), fastNegate(fastNegate), firstTime(true),
+ : exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn),
+ windowBegin(0), fastNegate(fastNegateIn), firstTime(true),
finished(false)
{
if (windowSize == 0)
diff --git a/extra/yassl/taocrypt/src/coding.cpp b/extra/yassl/taocrypt/src/coding.cpp
index 7a9d50aaac9..7fc681e1a05 100644
--- a/extra/yassl/taocrypt/src/coding.cpp
+++ b/extra/yassl/taocrypt/src/coding.cpp
@@ -185,7 +185,7 @@ void Base64Decoder::Decode()
{
word32 bytes = coded_.size();
word32 plainSz = bytes - ((bytes + (pemLineSz - 1)) / pemLineSz);
- plainSz = (plainSz * 3 + 3) / 4;
+ plainSz = ((plainSz * 3) / 4) + 3;
decoded_.New(plainSz);
word32 i = 0;
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index 85733b88aa9..b054e98bef4 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -283,21 +283,23 @@ DWord() {}
word GetHighHalfAsBorrow() const {return 0-halfs_.high;}
private:
+ struct dword_struct
+ {
+ #ifdef LITTLE_ENDIAN_ORDER
+ word low;
+ word high;
+ #else
+ word high;
+ word low;
+ #endif
+ };
+
union
{
#ifdef TAOCRYPT_NATIVE_DWORD_AVAILABLE
dword whole_;
#endif
- struct
- {
- #ifdef LITTLE_ENDIAN_ORDER
- word low;
- word high;
- #else
- word high;
- word low;
- #endif
- } halfs_;
+ struct dword_struct halfs_;
};
};
@@ -1214,20 +1216,24 @@ public:
#define AS1(x) #x ";"
#define AS2(x, y) #x ", " #y ";"
#define AddPrologue \
+ word res; \
__asm__ __volatile__ \
( \
"push %%ebx;" /* save this manually, in case of -fPIC */ \
- "mov %2, %%ebx;" \
+ "mov %3, %%ebx;" \
".intel_syntax noprefix;" \
"push ebp;"
#define AddEpilogue \
"pop ebp;" \
".att_syntax prefix;" \
"pop %%ebx;" \
- : \
+ "mov %%eax, %0;" \
+ : "=g" (res) \
: "c" (C), "d" (A), "m" (B), "S" (N) \
: "%edi", "memory", "cc" \
- );
+ ); \
+ return res;
+
#define MulPrologue \
__asm__ __volatile__ \
( \
diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp
index edbc678da3a..978665b2f7c 100644
--- a/extra/yassl/taocrypt/src/misc.cpp
+++ b/extra/yassl/taocrypt/src/misc.cpp
@@ -84,12 +84,23 @@ namespace STL = STL_NAMESPACE;
}
-#if defined(__ICC) || defined(__INTEL_COMPILER)
+#ifdef __sun
+
+// Handler for pure virtual functions
+namespace __Crun {
+ void pure_error() {
+ assert(!"Aborted: pure virtual method called.");
+ }
+}
+
+#endif
+
+#if defined(__ICC) || defined(__INTEL_COMPILER) || (__GNUC__ > 2)
extern "C" {
int __cxa_pure_virtual() {
- assert("Pure virtual method called." == "Aborted");
+ assert(!"Aborted: pure virtual method called.");
return 0;
}
@@ -176,7 +187,6 @@ word Crop(word value, unsigned int size)
#endif
#endif
-
bool HaveCpuId()
{
#ifdef _MSC_VER
diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp
index c921f8f9c69..970ba5bf367 100644
--- a/extra/yassl/testsuite/test.hpp
+++ b/extra/yassl/testsuite/test.hpp
@@ -160,6 +160,11 @@ inline void err_sys(const char* msg)
}
+extern "C" {
+ static int PasswordCallBack(char*, int, int, void*);
+}
+
+
static int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
{
strncpy(passwd, "12345678", sz);
diff --git a/include/Makefile.am b/include/Makefile.am
index 8a0b4610a90..fb5c746d129 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -43,8 +43,9 @@ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \
my_vle.h my_user.h my_atomic.h atomic/nolock.h \
atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \
atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \
- wqueue.h waiting_threads.h
-EXTRA_DIST = mysql.h.pp mysql/plugin_auth.h.pp mysql/client_plugin.h.pp
+ wqueue.h waiting_threads.h my_compiler.h
+
+EXTRA_DIST = mysql.h.pp mysql/plugin_auth.h.pp mysql/client_plugin.h.pp
# Remove built files and the symlinked directories
CLEANFILES = $(BUILT_SOURCES) readline openssl
@@ -71,6 +72,3 @@ my_config.h: config.h
# generated by configure from the .h.in files
dist-hook:
$(RM) -f $(distdir)/mysql_version.h $(distdir)/my_config.h
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/include/m_string.h b/include/m_string.h
index 61b7f41a61d..26fa41d9cc4 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -33,10 +33,6 @@
/* need by my_vsnprintf */
#include <stdarg.h>
-#ifdef _AIX
-#undef HAVE_BCMP
-#endif
-
/* This is needed for the definitions of bzero... on solaris */
#if defined(HAVE_STRINGS_H)
#include <strings.h>
@@ -114,7 +110,7 @@ extern void bfill(uchar *dst,size_t len,pchar fill);
#endif
#if !defined(bzero) && !defined(HAVE_BZERO)
-extern void bzero(uchar * dst,size_t len);
+extern void bzero(void * dst,size_t len);
#endif
#if !defined(bcmp) && !defined(HAVE_BCMP)
diff --git a/include/my_bitmap.h b/include/my_bitmap.h
index 2c50ca3ec75..994c5cb4299 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -161,22 +161,6 @@ static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2)
#define bitmap_set_all(MAP) \
(memset((MAP)->bitmap, 0xFF, 4*no_words_in_map((MAP))))
-/**
- check, set and clear a bit of interest of an integer.
-
- If the bit is out of range @retval -1. Otherwise
- bit_is_set @return 0 or 1 reflecting the bit is set or not;
- bit_do_set @return 1 (bit is set 1)
- bit_do_clear @return 0 (bit is cleared to 0)
-*/
-
-#define bit_is_set(I,B) (sizeof(I) * CHAR_BIT > (B) ? \
- (((I) & (ULL(1) << (B))) == 0 ? 0 : 1) : -1)
-#define bit_do_set(I,B) (sizeof(I) * CHAR_BIT > (B) ? \
- ((I) |= (ULL(1) << (B)), 1) : -1)
-#define bit_do_clear(I,B) (sizeof(I) * CHAR_BIT > (B) ? \
- ((I) &= ~(ULL(1) << (B)), 0) : -1)
-
#ifdef __cplusplus
}
#endif
diff --git a/include/my_compiler.h b/include/my_compiler.h
new file mode 100644
index 00000000000..1cd46ff4260
--- /dev/null
+++ b/include/my_compiler.h
@@ -0,0 +1,129 @@
+#ifndef MY_COMPILER_INCLUDED
+#define MY_COMPILER_INCLUDED
+
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/**
+ Header for compiler-dependent features.
+
+ Intended to contain a set of reusable wrappers for preprocessor
+ macros, attributes, pragmas, and any other features that are
+ specific to a target compiler.
+*/
+
+#include <my_global.h> /* stddef.h offsetof */
+
+/**
+ Compiler-dependent internal convenience macros.
+*/
+
+/* GNU C/C++ */
+#if defined __GNUC__
+/* Any after 2.95... */
+# define MY_ALIGN_EXT
+
+/* Microsoft Visual C++ */
+#elif defined _MSC_VER
+# define MY_ALIGNOF(type) __alignof(type)
+# define MY_ALIGNED(n) __declspec(align(n))
+
+/* Oracle Solaris Studio */
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# if __SUNPRO_C >= 0x590
+# define MY_ALIGN_EXT
+# endif
+
+/* IBM XL C/C++ */
+#elif defined __xlC__
+# if __xlC__ >= 0x0600
+# define MY_ALIGN_EXT
+# endif
+
+/* HP aCC */
+#elif defined(__HP_aCC) || defined(__HP_cc)
+# if (__HP_aCC >= 60000) || (__HP_cc >= 60000)
+# define MY_ALIGN_EXT
+# endif
+#endif
+
+#ifdef MY_ALIGN_EXT
+/** Specifies the minimum alignment of a type. */
+# define MY_ALIGNOF(type) __alignof__(type)
+/** Determine the alignment requirement of a type. */
+# define MY_ALIGNED(n) __attribute__((__aligned__((n))))
+#endif
+
+/**
+ Generic compiler-dependent features.
+*/
+#ifndef MY_ALIGNOF
+# ifdef __cplusplus
+ template<typename type> struct my_alignof_helper { char m1; type m2; };
+ /* Invalid for non-POD types, but most compilers give the right answer. */
+# define MY_ALIGNOF(type) offsetof(my_alignof_helper<type>, m2)
+# else
+# define MY_ALIGNOF(type) offsetof(struct { char m1; type m2; }, m2)
+# endif
+#endif
+
+/**
+ C++ Type Traits
+*/
+
+#ifdef __cplusplus
+
+/**
+ Opaque storage with a particular alignment.
+*/
+# if defined(MY_ALIGNED)
+/* Partial specialization used due to MSVC++. */
+template<size_t alignment> struct my_alignment_imp;
+template<> struct MY_ALIGNED(1) my_alignment_imp<1> {};
+template<> struct MY_ALIGNED(2) my_alignment_imp<2> {};
+template<> struct MY_ALIGNED(4) my_alignment_imp<4> {};
+template<> struct MY_ALIGNED(8) my_alignment_imp<8> {};
+template<> struct MY_ALIGNED(16) my_alignment_imp<16> {};
+/* ... expand as necessary. */
+# else
+template<size_t alignment>
+struct my_alignment_imp { double m1; };
+# endif
+
+/**
+ A POD type with a given size and alignment.
+
+ @remark If the compiler does not support a alignment attribute
+ (MY_ALIGN macro), the default alignment of a double is
+ used instead.
+
+ @tparam size The minimum size.
+ @tparam alignment The desired alignment: 1, 2, 4, 8 or 16.
+*/
+template <size_t size, size_t alignment>
+struct my_aligned_storage
+{
+ union
+ {
+ char data[size];
+ my_alignment_imp<alignment> align;
+ };
+};
+
+#endif /* __cplusplus */
+
+#include <my_attribute.h>
+
+#endif /* MY_COMPILER_INCLUDED */
diff --git a/include/my_global.h b/include/my_global.h
index 13802804f91..9281e9cc13e 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -567,18 +567,17 @@ int __void__;
#endif
#endif /* DONT_DEFINE_VOID */
-#if defined(_lint) || defined(FORCE_INIT_OF_VARS)
-#define LINT_INIT(var) var=0 /* No uninitialize-warning */
-#else
-#define LINT_INIT(var)
-#endif
-
-#include <my_valgrind.h>
+/*
+ Deprecated workaround for false-positive uninitialized variables
+ warnings. Those should be silenced using tool-specific heuristics.
-#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || defined(HAVE_valgrind)
-#define VALGRIND_OR_LINT_INIT(var) var=0
+ Enabled by default for g++ due to the bug referenced below.
+*/
+#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || \
+ (defined(__GNUC__) && defined(__cplusplus))
+#define LINT_INIT(var) var= 0
#else
-#define VALGRIND_OR_LINT_INIT(var)
+#define LINT_INIT(var)
#endif
#ifdef _WIN32
@@ -589,19 +588,22 @@ int __void__;
#define SO_EXT ".so"
#endif
-/*
+/*
Suppress uninitialized variable warning without generating code.
The _cplusplus is a temporary workaround for C++ code pending a fix
- for a g++ bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34772).
+ for a g++ bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34772).
*/
-#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || defined(__cplusplus) || \
- !defined(__GNUC__)
+#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || \
+ defined(__cplusplus) || !defined(__GNUC__)
#define UNINIT_VAR(x) x= 0
#else
+/* GCC specific self-initialization which inhibits the warning. */
#define UNINIT_VAR(x) x= x
#endif
+#include <my_valgrind.h>
+
/* Define some useful general macros */
#if !defined(max)
#define max(a, b) ((a) > (b) ? (a) : (b))
@@ -617,12 +619,12 @@ typedef unsigned short ushort;
#define CMP_NUM(a,b) (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1)
#define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0)
-#define swap_variables(t, a, b) { t swap_dummy; swap_dummy= a; a= b; b= swap_dummy; }
+#define swap_variables(t, a, b) { t dummy; dummy= a; a= b; b= dummy; }
#define test(a) ((a) ? 1 : 0)
#define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0)
#define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0)
-#define test_all_bits(a,b) (((a) & (b)) == (b))
#define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1))
+#define test_all_bits(a,b) (((a) & (b)) == (b))
#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))
/* Define some general constants */
@@ -643,7 +645,7 @@ typedef unsigned short ushort;
#define my_const_cast(A) (A)
#endif
-#include <my_attribute.h>
+#include <my_compiler.h>
/*
Wen using the embedded library, users might run into link problems,
@@ -679,7 +681,7 @@ C_MODE_END
# endif
#endif
-typedef char my_bool; /* Small bool */
+typedef char my_bool; /* Small bool; Needed by my_dbug.h */
#include <my_dbug.h>
#define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/
@@ -958,13 +960,11 @@ typedef long long my_ptrdiff_t;
#define ALIGN_MAX_UNIT (sizeof(double))
/* Size to make adressable obj. */
#define ALIGN_PTR(A, t) ((t*) MY_ALIGN((A), sizeof(double)))
+/* Offset of field f in structure t */
#define OFFSET(t, f) ((size_t)(char *)&((t *)0)->f)
#define ADD_TO_PTR(ptr,size,type) (type) ((uchar*) (ptr)+size)
#define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((uchar*) (A) - (uchar*) (B))
-#define MY_DIV_UP(A, B) (((A) + (B) - 1) / (B))
-#define MY_ALIGNED_BYTE_ARRAY(N, S, T) T N[MY_DIV_UP(S, sizeof(T))]
-
/*
Custom version of standard offsetof() macro which can be used to get
offsets of members in class for non-POD types (according to the current
diff --git a/include/my_pthread.h b/include/my_pthread.h
index ee5a77f0216..f7aad5dec64 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -276,13 +276,14 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
we want to make sure that no such flags are set.
*/
#if defined(HAVE_SIGACTION) && !defined(my_sigset)
-#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \
+#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; \
+ IF_DBUG(int l_rc); \
DBUG_ASSERT((A) != 0); \
sigemptyset(&l_set); \
l_s.sa_handler = (B); \
l_s.sa_mask = l_set; \
l_s.sa_flags = 0; \
- l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\
+ IF_DBUG(l_rc=) sigaction((A), &l_s, NULL); \
DBUG_ASSERT(l_rc == 0); \
} while (0)
#elif defined(HAVE_SIGSET) && !defined(my_sigset)
@@ -757,7 +758,7 @@ extern uint thd_lib_detected;
The implementation is guaranteed to be thread safe, on all platforms.
Note that the calling code should *not* assume the counter is protected
by the mutex given, as the implementation of these helpers may change
- to use my_atomic operations instead.
+ to use atomic operations instead.
*/
/*
diff --git a/include/mysql.h b/include/mysql.h
index 52475dbc0dd..cbdfb8387c6 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -44,7 +44,9 @@ extern "C" {
#endif
#ifndef _global_h /* If not standard header */
+#ifndef MYSQL_ABI_CHECK
#include <sys/types.h>
+#endif
#ifdef __LCC__
#include <winsock2.h> /* For windows */
#endif
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index 88a2dce1555..48d3b804dd9 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -1,4 +1,3 @@
-#include <sys/types.h>
typedef char my_bool;
typedef int my_socket;
#include "mysql_version.h"
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 093807a65cb..affd24a4636 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -27,6 +27,10 @@
#define NAME_LEN (NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN)
#define USERNAME_LENGTH (USERNAME_CHAR_LENGTH*SYSTEM_CHARSET_MBMAXLEN)
+#define MYSQL50_TABLE_NAME_PREFIX "#mysql50#"
+#define MYSQL50_TABLE_NAME_PREFIX_LENGTH (sizeof(MYSQL50_TABLE_NAME_PREFIX)-1)
+#define SAFE_NAME_LEN (NAME_LEN + MYSQL50_TABLE_NAME_PREFIX_LENGTH)
+
#define SERVER_VERSION_LENGTH 60
#define SQLSTATE_LENGTH 5
#define LIST_PROCESS_HOST_LEN 64
diff --git a/include/mysys_err.h b/include/mysys_err.h
index defdaa71fa3..bbb7f6de7d8 100644
--- a/include/mysys_err.h
+++ b/include/mysys_err.h
@@ -62,10 +62,12 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */
#define EE_UNKNOWN_COLLATION 28
#define EE_FILENOTFOUND 29
#define EE_FILE_NOT_CLOSED 30
-#define EE_CANT_CHMOD 31
-#define EE_CANT_SEEK 32
-#define EE_CANT_COPY_OWNERSHIP 33
-#define EE_ERROR_LAST 33 /* Copy last error nr */
+#define EE_CHANGE_OWNERSHIP 31
+#define EE_CHANGE_PERMISSIONS 32
+#define EE_CANT_CHMOD 33
+#define EE_CANT_SEEK 34
+#define EE_CANT_COPY_OWNERSHIP 35
+#define EE_ERROR_LAST 35 /* Copy last error nr */
/* Add error numbers before EE_ERROR_LAST and change it accordingly. */
/* exit codes for all MySQL programs */
diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am
index f67abfd8ac6..b628bff9a3f 100644
--- a/libmysql/Makefile.am
+++ b/libmysql/Makefile.am
@@ -111,6 +111,3 @@ do-lib-dist:
echo ' $$(AR) r $$@ $$?' >>$$dir/Makefile; \
gtar cvzf $$dir.tar.gz $$dir; \
cd $$dir; gmake
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 8ce7f0ee69b..53cb20cddc2 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -4373,6 +4373,7 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field)
case MYSQL_TYPE_TIME:
field->max_length= 15; /* 19:23:48.123456 */
param->skip_result= skip_result_with_length;
+ break;
case MYSQL_TYPE_DATE:
field->max_length= 10; /* 2003-11-11 */
param->skip_result= skip_result_with_length;
diff --git a/libmysql_r/Makefile.am b/libmysql_r/Makefile.am
index 4a37dcfdec9..85578c71066 100644
--- a/libmysql_r/Makefile.am
+++ b/libmysql_r/Makefile.am
@@ -42,6 +42,3 @@ link_sources:
done; \
done
echo timestamp > link_sources
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index 0fef36db6b3..b70b78241e1 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -232,6 +232,3 @@ link_sources:
clean-local:
rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlstoragesources) $(storagesources) | sed "s;\.lo;.c;g"`; \
rm -f client_settings.h
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am
index 109d33a85ae..fd37f362960 100644
--- a/libmysqld/examples/Makefile.am
+++ b/libmysqld/examples/Makefile.am
@@ -42,7 +42,8 @@ LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @LIBDL@ $(CXXLDFLAGS) \
mysqltest_embedded_LINK = $(CXXLINK)
nodist_mysqltest_embedded_SOURCES = mysqltest.cc
-mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a
+mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a \
+ @MYSQLD_EXTRA_LDFLAGS@
nodist_mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \
my_readline.h sql_string.h completion_hash.h
diff --git a/man/Makefile.am b/man/Makefile.am
index 72e67f7445f..4846213945f 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -24,6 +24,3 @@ EXTRA_DIST = $(man1_MANS) $(man8_MANS)
# "make_win_*" are not needed in Unix binary packages,
install-data-hook:
rm -f $(DESTDIR)$(mandir)/man1/make_win_*
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index c74a042cab0..e133a4648a1 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -84,6 +84,10 @@ TEST_DIRS = t r include std_data std_data/parts collections \
suite/binlog suite/binlog/t suite/binlog/r suite/binlog/std_data \
suite/bugs suite/bugs/data suite/bugs/t suite/bugs/r \
suite/federated \
+ suite/pbxt/t suite/pbxt/r suite/pbxt \
+ suite/vcol suite/vcol/t suite/vcol/r suite/vcol/inc \
+ suite/oqgraph suite/oqgraph/t suite/oqgraph/r suite/oqgraph/include \
+ suite/percona \
suite/funcs_1 suite/funcs_1/bitdata \
suite/funcs_1/include suite/funcs_1/lib suite/funcs_1/r \
suite/funcs_1/t suite/funcs_1/views suite/funcs_1/cursors \
@@ -102,12 +106,9 @@ TEST_DIRS = t r include std_data std_data/parts collections \
suite/ndb suite/ndb/t suite/ndb/r \
suite/rpl_ndb suite/rpl_ndb/t suite/rpl_ndb/r \
suite/parts suite/parts/t suite/parts/r suite/parts/inc \
- suite/pbxt/t suite/pbxt/r suite/pbxt \
suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \
- suite/vcol suite/vcol/t suite/vcol/r suite/vcol/inc \
- suite/oqgraph suite/oqgraph/t suite/oqgraph/r suite/oqgraph/include \
- suite/innodb_plugin suite/innodb_plugin/t suite/innodb_plugin/r suite/innodb_plugin/include \
- suite/percona \
+ suite/innodb_plugin suite/innodb_plugin/t suite/innodb_plugin/r \
+ suite/innodb_plugin/include \
suite/engines suite/engines/funcs suite/engines/iuds suite/engines/rr_trx \
suite/engines/funcs/r suite/engines/funcs/t suite/engines/iuds/r \
suite/engines/iuds/t suite/engines/rr_trx/include suite/engines/rr_trx/r \
@@ -148,6 +149,3 @@ mtr:
mysql-test-run:
$(RM) -f mysql-test-run
$(LN_S) mysql-test-run.pl mysql-test-run
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/mysql-test/README.suites b/mysql-test/README.suites
index 99155f37485..076fc216a0e 100644
--- a/mysql-test/README.suites
+++ b/mysql-test/README.suites
@@ -20,11 +20,18 @@ subdirectories under the suitedir or directly in the suitedir
(that is suitedir/t/*.test or suitedir/*.test, same for *.result))
==========================
-A suite can contain a suite.opt file - at the same location where .test
-files are. As usual, the .opt file can use $-substitutions for the
-environment variables.
+A suite can contain a suite.opt file - at the same location where .test files
+are or in the suite directory. As usual, the .opt file can use $-substitutions
+for the environment variables.
Usually, using my.cnf template (see below) is preferrable.
+
+But command line options (.opt files and combinations file) get special
+treatment - they can have special options that affect mtr behavior. cnf
+files cannot. Special options are
+ --timezone, --plugin-load, --result-file, --config-file-template,
+ --default-time-zone, --force-restart
+
==========================
A suite can have suite.pm file in the suitedir. It must declare a
package that inherits from My::Suite.
@@ -108,8 +115,8 @@ Most probably a suite my.cnf will need to start from
!include include/default_my.cnf
and then modify the configuration as necessary.
-==========================
+==========================
A suite can have combinations file in the suitedir. It uses my.cnf syntax
but it cannot use @-substitutions. Instead, it can use $-substitutions for
the environment variables. Because the combination options will not be
diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc
index d91ba8291fd..d412eae8364 100644
--- a/mysql-test/include/commit.inc
+++ b/mysql-test/include/commit.inc
@@ -725,9 +725,9 @@ call p_verify_status_increment(4, 4, 4, 4);
alter table t3 add column (b int);
call p_verify_status_increment(2, 0, 2, 0);
alter table t3 rename t4;
-call p_verify_status_increment(2, 2, 2, 2);
+call p_verify_status_increment(1, 0, 1, 0);
rename table t4 to t3;
-call p_verify_status_increment(2, 2, 2, 2);
+call p_verify_status_increment(1, 0, 1, 0);
truncate table t3;
call p_verify_status_increment(4, 4, 4, 4);
create view v1 as select * from t2;
diff --git a/mysql-test/include/diff_tables.inc b/mysql-test/include/diff_tables.inc
index d15dd56b35d..81362e8643b 100644
--- a/mysql-test/include/diff_tables.inc
+++ b/mysql-test/include/diff_tables.inc
@@ -64,17 +64,13 @@ let $_diff_table=$diff_table_2;
let $_diff_i=2;
while ($_diff_i) {
- # Parse out any leading "master:" or "slave:" from the table
- # specification and connect the appropriate server.
- let $_diff_conn_master=`SELECT SUBSTR('$_diff_table', 1, 7) = 'master:'`;
- if ($_diff_conn_master) {
- let $_diff_table=`SELECT SUBSTR('$_diff_table', 8)`;
- connection master;
- }
- let $_diff_conn_slave=`SELECT SUBSTR('$_diff_table', 1, 6) = 'slave:'`;
- if ($_diff_conn_slave) {
- let $_diff_table=`SELECT SUBSTR('$_diff_table', 7)`;
- connection slave;
+ # Parse out any leading "master:" or "slave:" from the table specification
+# and connect the appropriate server.
+ let $_pos= `SELECT LOCATE(':', '$_diff_table')`;
+ let $_diff_conn=`SELECT SUBSTR('$_diff_table', 1, $_pos-1)`;
+ if (`SELECT 'XX$_diff_conn' <> 'XX'`) {
+ let $_diff_table=`SELECT SUBSTR('$_diff_table', $_pos+1)`;
+ connection $_diff_conn;
}
# Sanity-check the input.
diff --git a/mysql-test/include/have_archive.inc b/mysql-test/include/have_archive.inc
index 82399ca4c6c..0fd85fa576f 100644
--- a/mysql-test/include/have_archive.inc
+++ b/mysql-test/include/have_archive.inc
@@ -1,4 +1,5 @@
---disable_query_log
---require r/true.require
-select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'archive';
---enable_query_log
+if (!`SELECT count(*) FROM information_schema.engines WHERE
+ (support = 'YES' OR support = 'DEFAULT') AND
+ engine = 'archive'`){
+ skip Need archive engine;
+}
diff --git a/mysql-test/include/have_archive.opt b/mysql-test/include/have_archive.opt
new file mode 100644
index 00000000000..cf9309d9fb0
--- /dev/null
+++ b/mysql-test/include/have_archive.opt
@@ -0,0 +1,2 @@
+--loose-archive
+--plugin-load=$HA_ARCHIVE_SO
diff --git a/mysql-test/include/have_blackhole.opt b/mysql-test/include/have_blackhole.opt
new file mode 100644
index 00000000000..b600b468390
--- /dev/null
+++ b/mysql-test/include/have_blackhole.opt
@@ -0,0 +1,2 @@
+--loose-blackhole
+--plugin-load=$HA_BLACKHOLE_SO
diff --git a/mysql-test/include/have_innodb.opt b/mysql-test/include/have_innodb.opt
index 48457b17309..4fb96229a7b 100644
--- a/mysql-test/include/have_innodb.opt
+++ b/mysql-test/include/have_innodb.opt
@@ -1 +1,2 @@
--loose-innodb
+--plugin-load=$HA_XTRADB_SO
diff --git a/mysql-test/include/have_pbxt.inc b/mysql-test/include/have_pbxt.inc
index a8afc2c8324..b11aee2617f 100644
--- a/mysql-test/include/have_pbxt.inc
+++ b/mysql-test/include/have_pbxt.inc
@@ -1,4 +1,5 @@
-disable_query_log;
---require r/true.require
-select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'pbxt';
-enable_query_log;
+if (!`SELECT count(*) FROM information_schema.engines WHERE
+ (support = 'YES' OR support = 'DEFAULT') AND
+ engine = 'pbxt'`){
+ skip Need PBXT engine;
+}
diff --git a/mysql-test/include/percona_query_response_time_flush.inc b/mysql-test/include/percona_query_response_time_flush.inc
new file mode 100644
index 00000000000..44bb320fe13
--- /dev/null
+++ b/mysql-test/include/percona_query_response_time_flush.inc
@@ -0,0 +1 @@
+FLUSH QUERY_RESPONSE_TIME;
diff --git a/mysql-test/include/percona_query_response_time_show.inc b/mysql-test/include/percona_query_response_time_show.inc
new file mode 100644
index 00000000000..761b2c6f0df
--- /dev/null
+++ b/mysql-test/include/percona_query_response_time_show.inc
@@ -0,0 +1,7 @@
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
diff --git a/mysql-test/include/percona_query_response_time_sleep.inc b/mysql-test/include/percona_query_response_time_sleep.inc
new file mode 100644
index 00000000000..40688b173b0
--- /dev/null
+++ b/mysql-test/include/percona_query_response_time_sleep.inc
@@ -0,0 +1,19 @@
+SELECT SLEEP(0.31);
+SELECT SLEEP(0.32);
+SELECT SLEEP(0.33);
+SELECT SLEEP(0.34);
+SELECT SLEEP(0.35);
+SELECT SLEEP(0.36);
+SELECT SLEEP(0.37);
+SELECT SLEEP(0.38);
+SELECT SLEEP(0.39);
+SELECT SLEEP(0.40);
+SELECT SLEEP(1.1);
+SELECT SLEEP(1.2);
+SELECT SLEEP(1.3);
+SELECT SLEEP(1.5);
+SELECT SLEEP(1.4);
+SELECT SLEEP(0.5);
+SELECT SLEEP(2.1);
+SELECT SLEEP(2.3);
+SELECT SLEEP(2.5);
diff --git a/mysql-test/include/rpl_diff_tables.inc b/mysql-test/include/rpl_diff_tables.inc
new file mode 100644
index 00000000000..c3a45578a79
--- /dev/null
+++ b/mysql-test/include/rpl_diff_tables.inc
@@ -0,0 +1,35 @@
+# #############################################################################
+# Check whether the given table is consistent between different master and
+# slaves
+#
+# Usage:
+# --let $diff_table= test.t1
+# --let $diff_server_list= master, slave, slave2
+# --source include/rpl_diff_tables.inc
+# #############################################################################
+
+if (`SELECT "XX$diff_table" = "XX"`)
+{
+ --die diff_table is null.
+}
+
+--let $_servers= master, slave
+if (`SELECT "XX$diff_server_list" <> "XX"`)
+{
+ --let $_servers= $diff_server_list
+}
+
+--let $_master= `SELECT SUBSTRING_INDEX('$_servers', ',', 1)`
+--let $_servers= `SELECT LTRIM(SUBSTRING('$_servers', LENGTH('$_master') + 2))`
+connection $_master;
+while (`SELECT "XX$_servers" <> "XX"`)
+{
+ --let $_slave= `SELECT SUBSTRING_INDEX('$_servers', ',', 1)`
+ --let $_servers= `SELECT LTRIM(SUBSTRING('$_servers', LENGTH('$_slave') + 2))`
+
+ --sync_slave_with_master $_slave
+ --let $diff_table_1= $_master:$diff_table
+ --let $diff_table_2= $_slave:$diff_table
+ --source include/diff_tables.inc
+ connection $_slave;
+}
diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm
index d5414713262..7725b025dd8 100644
--- a/mysql-test/lib/My/ConfigFactory.pm
+++ b/mysql-test/lib/My/ConfigFactory.pm
@@ -606,7 +606,7 @@ sub new_config {
# add auto-options
$config->insert('OPT', 'port' => sub { fix_port($self, $config) });
- $config->insert('OPT', 'vardir' => sub { shift->{ARGS}->{vardir} });
+ $config->insert('OPT', 'vardir' => sub { $self->{ARGS}->{vardir} });
{
# Run pre rules
diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc
index 71942565f8b..12b335ec444 100644
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc
@@ -160,7 +160,7 @@ int main(int argc, char* const argv[] )
signal(SIGCHLD, handle_signal);
signal(SIGABRT, handle_abort);
- sprintf(safe_process_name, "safe_process[%d]", (int) own_pid);
+ sprintf(safe_process_name, "safe_process[%ld]", (long) own_pid);
message("Started");
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index 88e078baa7f..fd4832d49a3 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -325,12 +325,8 @@ sub collect_one_suite
}
# Read suite.opt file
- my $suite_opt_file= "$testdir/suite.opt";
- my $suite_opts= [];
- if ( -f $suite_opt_file )
- {
- $suite_opts= opts_from_file($suite_opt_file);
- }
+ my $suite_opts= [ opts_from_file("$testdir/suite.opt") ];
+ $suite_opts = [ opts_from_file("$suitedir/suite.opt") ] unless @$suite_opts;
if ( @$opt_cases )
{
@@ -618,67 +614,81 @@ sub optimize_cases {
# Read options from the given opt file and append them as an array
# to $tinfo->{$opt_name}
#
-sub process_opts_file {
- my ($tinfo, $opt_file, $opt_name)= @_;
+sub process_opts {
+ my ($tinfo, $opt_name)= @_;
+
+ my @opts= @{$tinfo->{$opt_name}};
+ $tinfo->{$opt_name} = [];
+
+ my @plugins;
+ my %seen;
- if ( -f $opt_file )
+ foreach my $opt (@opts)
{
- my $opts= opts_from_file($opt_file);
+ my $value;
- foreach my $opt ( @$opts )
+ # The opt file is used both to send special options to the mysqld
+ # as well as pass special test case specific options to this
+ # script
+
+ $value= mtr_match_prefix($opt, "--timezone=");
+ if ( defined $value )
{
- my $value;
+ $tinfo->{'timezone'}= $value;
+ next;
+ }
- # The opt file is used both to send special options to the mysqld
- # as well as pass special test case specific options to this
- # script
+ $value= mtr_match_prefix($opt, "--plugin-load=");
+ if (defined $value)
+ {
+ push @plugins, $value unless $seen{$value};
+ $seen{$value}=1;
+ next;
+ }
- $value= mtr_match_prefix($opt, "--timezone=");
- if ( defined $value )
- {
- $tinfo->{'timezone'}= $value;
- next;
- }
+ $value= mtr_match_prefix($opt, "--result-file=");
+ if ( defined $value )
+ {
+ # Specifies the file mysqltest should compare
+ # output against
+ $tinfo->{'result_file'}= "r/$value.result";
+ next;
+ }
- $value= mtr_match_prefix($opt, "--result-file=");
- if ( defined $value )
- {
- # Specifies the file mysqltest should compare
- # output against
- $tinfo->{'result_file'}= "r/$value.result";
- next;
- }
+ $value= mtr_match_prefix($opt, "--config-file-template=");
+ if ( defined $value)
+ {
+ # Specifies the configuration file to use for this test
+ $tinfo->{'template_path'}= dirname($tinfo->{path})."/$value";
+ next;
+ }
- $value= mtr_match_prefix($opt, "--config-file-template=");
- if ( defined $value)
- {
- # Specifies the configuration file to use for this test
- $tinfo->{'template_path'}= dirname($tinfo->{path})."/$value";
- next;
- }
+ # If we set default time zone, remove the one we have
+ $value= mtr_match_prefix($opt, "--default-time-zone=");
+ if ( defined $value )
+ {
+ # Set timezone for this test case to something different
+ $tinfo->{'timezone'}= "GMT-8";
+ # Fallthrough, add the --default-time-zone option
+ }
- # If we set default time zone, remove the one we have
- $value= mtr_match_prefix($opt, "--default-time-zone=");
- if ( defined $value )
- {
- # Set timezone for this test case to something different
- $tinfo->{'timezone'}= "GMT-8";
- # Fallthrough, add the --default-time-zone option
- }
+ # The --restart option forces a restart even if no special
+ # option is set. If the options are the same as next testcase
+ # there is no need to restart after the testcase
+ # has completed
+ if ( $opt eq "--force-restart" )
+ {
+ $tinfo->{'force_restart'}= 1;
+ next;
+ }
- # The --restart option forces a restart even if no special
- # option is set. If the options are the same as next testcase
- # there is no need to restart after the testcase
- # has completed
- if ( $opt eq "--force-restart" )
- {
- $tinfo->{'force_restart'}= 1;
- next;
- }
+ # Ok, this was a real option, add it
+ push(@{$tinfo->{$opt_name}}, $opt);
+ }
- # Ok, this was a real option, add it
- push(@{$tinfo->{$opt_name}}, $opt);
- }
+ if (@plugins) {
+ my $sep = (IS_WINDOWS) ? ';' : ':';
+ push @{$tinfo->{$opt_name}}, "--plugin-load=" . join($sep, @plugins);
}
}
@@ -1019,15 +1029,17 @@ sub collect_one_test_case {
# ----------------------------------------------------------------------
for (@source_files) {
s/\.\w+$//;
- process_opts_file($tinfo, "$_.opt", 'master_opt');
- process_opts_file($tinfo, "$_.opt", 'slave_opt');
- process_opts_file($tinfo, "$_-master.opt", 'master_opt');
- process_opts_file($tinfo, "$_-slave.opt", 'slave_opt');
+ push @{$tinfo->{master_opt}}, opts_from_file("$_.opt");
+ push @{$tinfo->{slave_opt}}, opts_from_file("$_.opt");
+ push @{$tinfo->{master_opt}}, opts_from_file("$_-master.opt");
+ push @{$tinfo->{slave_opt}}, opts_from_file("$_-slave.opt");
}
push(@{$tinfo->{'master_opt'}}, @::opt_extra_mysqld_opt);
push(@{$tinfo->{'slave_opt'}}, @::opt_extra_mysqld_opt);
+ process_opts($tinfo, 'master_opt');
+ process_opts($tinfo, 'slave_opt');
return $tinfo;
}
@@ -1114,6 +1126,8 @@ sub opts_from_file ($) {
my $file= shift;
local $_;
+ return () unless -f $file;
+
open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!");
my @args;
while ( <FILE> )
@@ -1154,7 +1168,7 @@ sub opts_from_file ($) {
}
}
close FILE;
- return \@args;
+ return @args;
}
sub print_testcases {
diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl
index ddd6e6d936a..2b242954ce9 100755
--- a/mysql-test/lib/v1/mysql-test-run.pl
+++ b/mysql-test/lib/v1/mysql-test-run.pl
@@ -2959,7 +2959,7 @@ sub run_benchmarks ($) {
if ( ! $benchmark )
{
- mtr_add_arg($args, "--log");
+ mtr_add_arg($args, "--general-log");
mtr_run("$glob_mysql_bench_dir/run-all-tests", $args, "", "", "", "");
# FIXME check result code?!
}
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 0d673c87c4c..3f37fc5f285 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -3561,8 +3561,9 @@ sub timezone {
my ($tinfo)= @_;
local $_ = $tinfo->{timezone};
return 'DEFAULT' unless defined $_;
- s/\$\{(\w+)\}/envsubst($1)/ge;
- s/\$(\w+)/envsubst($1)/ge;
+ no warnings 'uninitialized';
+ s/\$\{(\w+)\}/$ENV{$1}/ge;
+ s/\$(\w+)/$ENV{$1}/ge;
$_;
}
@@ -4224,6 +4225,7 @@ sub extract_warning_lines ($) {
qr/slave SQL thread aborted/,
qr/unknown option '--loose[-_]/,
qr/unknown variable 'loose[-_]/,
+ qr/Invalid .*old.* table or database name/,
qr/Now setting lower_case_table_names to [02]/,
qr/Setting lower_case_table_names=2/,
qr/You have forced lower_case_table_names to 0/,
@@ -5068,18 +5070,6 @@ sub started { return grep(defined $_, map($_->{proc}, @_)); }
sub stopped { return grep(!defined $_, map($_->{proc}, @_)); }
-sub envsubst {
- my $string= shift;
-
- if ( ! defined $ENV{$string} )
- {
- mtr_error(".opt file references '$string' which is not set");
- }
-
- return $ENV{$string};
-}
-
-
sub get_extra_opts {
my ($mysqld, $tinfo)= @_;
@@ -5090,8 +5080,9 @@ sub get_extra_opts {
# Expand environment variables
foreach my $opt ( @$opts )
{
- $opt =~ s/\$\{(\w+)\}/envsubst($1)/ge;
- $opt =~ s/\$(\w+)/envsubst($1)/ge;
+ no warnings 'uninitialized';
+ $opt =~ s/\$\{(\w+)\}/$ENV{$1}/ge;
+ $opt =~ s/\$(\w+)/$ENV{$1}/ge;
}
return $opts;
}
@@ -5843,7 +5834,7 @@ sub time_format($) {
my $num_tests;
sub xterm_stat {
- if (-t STDOUT and $ENV{TERM} =~ /xterm/) {
+ if (-t STDOUT and defined $ENV{TERM} and $ENV{TERM} =~ /xterm/) {
my ($left) = @_;
# 2.5 -> best by test
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index f90bcb521e1..5a731e6476c 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -12725,8 +12725,7 @@ INSERT INTO t1 (col1, col2) VALUES (1, "value");
ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
REPAIR TABLE t1;
Table Op Msg_type Msg_text
-test.t1 repair Error Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
-test.t1 repair error Corrupt
+test.t1 repair status OK
DROP TABLE t1;
#
# BUG#48757 - missing .ARZ file causes server crash
@@ -12756,3 +12755,12 @@ a
1
2
DROP TABLE t1;
+select * from t1;
+ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+select sum(length(a)),sum(b) from t1;
+sum(length(a)) sum(b)
+8670 187
+drop table t1;
diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result
index 51c4ac3002c..1f0b2c8019b 100644
--- a/mysql-test/r/commit_1innodb.result
+++ b/mysql-test/r/commit_1innodb.result
@@ -841,11 +841,11 @@ call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
alter table t3 rename t4;
-call p_verify_status_increment(2, 2, 2, 2);
+call p_verify_status_increment(1, 0, 1, 0);
SUCCESS
rename table t4 to t3;
-call p_verify_status_increment(2, 2, 2, 2);
+call p_verify_status_increment(1, 0, 1, 0);
SUCCESS
truncate table t3;
diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result
index b798b49dd34..602b2d03d80 100644
--- a/mysql-test/r/drop.result
+++ b/mysql-test/r/drop.result
@@ -115,9 +115,14 @@ create table `#mysql50#abc``def` ( id int );
create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
ERROR 42000: Incorrect table name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
-create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
-create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
-ERROR 42000: Incorrect table name '#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1234` (a int);
+create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12345` (a int);
+ERROR 42000: Incorrect table name '#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12345'
+show tables;
+Tables_in_mysqltestbug26703
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1234
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+#mysql50#abc`def
use test;
drop database mysqltestbug26703;
End of 5.1 tests
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 766f3b6bfaa..ae48eb1e0ff 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -995,6 +995,7 @@ SELECT 1 FROM
1
1
DROP TABLE t1;
+End of 5.0 tests
#
# Bug #52397: another crash with explain extended and group_concat
#
@@ -1010,4 +1011,22 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select 1 AS `1` from (select group_concat(`test`.`t1`.`a` order by `test`.`t1`.`a` ASC separator ',') AS `GROUP_CONCAT(t1.a ORDER BY t1.a ASC)` from `test`.`t1` `t2` join `test`.`t1` group by `test`.`t1`.`a`) `d`
DROP TABLE t1;
-End of 5.0 tests
+#
+# Bug #54476: crash when group_concat and 'with rollup' in prepared statements
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+PREPARE stmt FROM "SELECT GROUP_CONCAT(t1.a ORDER BY t1.a) FROM t1 JOIN t1 t2 GROUP BY t1.a WITH ROLLUP";
+EXECUTE stmt;
+GROUP_CONCAT(t1.a ORDER BY t1.a)
+1,1
+2,2
+1,1,2,2
+EXECUTE stmt;
+GROUP_CONCAT(t1.a ORDER BY t1.a)
+1,1
+2,2
+1,1,2,2
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+End of 5.1 tests
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 828d4bafc53..2f768140b33 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -243,4 +243,19 @@ End of 5.0 tests
select connection_id() > 0;
connection_id() > 0
1
+#
+# Bug #54461: crash with longblob and union or update with subquery
+#
+CREATE TABLE t1 (a INT, b LONGBLOB);
+INSERT INTO t1 VALUES (1, '2'), (2, '3'), (3, '2');
+SELECT DISTINCT LEAST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
+LEAST(a, (SELECT b FROM t1 LIMIT 1))
+1
+2
+SELECT DISTINCT GREATEST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
+GREATEST(a, (SELECT b FROM t1 LIMIT 1))
+2
+3
+1
+DROP TABLE t1;
End of tests
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index f410b26a1fe..b3cab2f409a 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -1425,7 +1425,7 @@ ERROR 42S02: Table 'db1.../db2/tb2' doesn't exist
SELECT * FROM `../db2`.tb2;
ERROR 42000: SELECT command denied to user 'testbug'@'localhost' for table 'tb2'
SELECT * FROM `#mysql50#/../db2/tb2`;
-ERROR 42S02: Table 'db1.#mysql50#/../db2/tb2' doesn't exist
+ERROR 42000: Incorrect table name '#mysql50#/../db2/tb2'
DROP USER 'testbug'@localhost;
DROP TABLE db2.t1;
DROP DATABASE db1;
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index deda00364aa..e04819fcbf9 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -1827,4 +1827,39 @@ min(t2.key_col)+1
NULL
drop table t1,t2;
#
+# Bug#55188: GROUP BY, GROUP_CONCAT and TEXT - inconsistent results
+#
+CREATE TABLE t1 (a text, b varchar(10));
+INSERT INTO t1 VALUES (repeat('1', 1300),'one'), (repeat('1', 1300),'two');
+EXPLAIN
+SELECT SUBSTRING(a,1,10), LENGTH(a), GROUP_CONCAT(b) FROM t1 GROUP BY a;
+id 1
+select_type SIMPLE
+table t1
+type ALL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows 2
+Extra Using filesort
+SELECT SUBSTRING(a,1,10), LENGTH(a), GROUP_CONCAT(b) FROM t1 GROUP BY a;
+SUBSTRING(a,1,10) LENGTH(a) GROUP_CONCAT(b)
+1111111111 1300 one,two
+EXPLAIN
+SELECT SUBSTRING(a,1,10), LENGTH(a) FROM t1 GROUP BY a;
+id 1
+select_type SIMPLE
+table t1
+type ALL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows 2
+Extra Using temporary; Using filesort
+SELECT SUBSTRING(a,1,10), LENGTH(a) FROM t1 GROUP BY a;
+SUBSTRING(a,1,10) LENGTH(a)
+1111111111 1300
+DROP TABLE t1;
# End of 5.1 tests
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index 19c23df1e84..cd1b4ae0218 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -470,10 +470,9 @@ WHERE table2.f1 = 2
GROUP BY table1.f1, table2.f2
HAVING (table2.f2 = 8 AND table1.f1 >= 6);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE table2 const PRIMARY PRIMARY 4 const 1 100.00 Using filesort
-1 SIMPLE table1 ALL NULL NULL NULL NULL 4 100.00 Using where
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables
Warnings:
-Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having (('7' = 8) and (`test`.`table1`.`f1` >= 6))
+Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having 0
EXPLAIN EXTENDED
SELECT table1.f1, table2.f2
FROM t1 AS table1
@@ -482,10 +481,9 @@ WHERE table2.f1 = 2
GROUP BY table1.f1, table2.f2
HAVING (table2.f2 = 8);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE table2 const PRIMARY PRIMARY 4 const 1 100.00 Using filesort
-1 SIMPLE table1 ALL NULL NULL NULL NULL 4 100.00 Using where
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables
Warnings:
-Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having ('7' = 8)
+Note 1003 select `test`.`table1`.`f1` AS `f1`,'7' AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = '9')) group by `test`.`table1`.`f1`,'7' having 0
DROP TABLE t1;
#
# Bug#52336 Segfault / crash in 5.1 copy_fields (param=0x9872980) at sql_select.cc:15355
@@ -532,3 +530,19 @@ MAX(t2.f2)
NULL
DROP TABLE t1,t2;
End of 5.0 tests
+#
+# Bug#54416 MAX from JOIN with HAVING returning NULL with 5.1 and Empty set
+#
+CREATE TABLE t1 (f1 INT(11), f2 VARCHAR(1), PRIMARY KEY (f1));
+INSERT INTO t1 VALUES (1,'f');
+CREATE TABLE t2 (f1 INT(11), f2 VARCHAR(1));
+INSERT INTO t2 VALUES (2,'m');
+INSERT INTO t2 VALUES (3,'m');
+INSERT INTO t2 VALUES (11,NULL);
+INSERT INTO t2 VALUES (12,'k');
+SELECT MAX(t1.f1) field1
+FROM t1 JOIN t2 ON t2.f2 LIKE 'x'
+HAVING field1 < 7;
+field1
+DROP TABLE t1,t2;
+End of 5.1 tests
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index ee8b91631bb..8a2b258e356 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -68,6 +68,7 @@ INNODB_LOCKS
INNODB_LOCK_WAITS
INNODB_RSEG
INNODB_SYS_INDEXES
+INNODB_SYS_STATS
INNODB_SYS_TABLES
INNODB_TABLE_STATS
INNODB_TRX
@@ -871,7 +872,6 @@ COLUMNS TABLE_NAME select
COLUMN_PRIVILEGES TABLE_NAME select
FILES TABLE_NAME select
INDEX_STATISTICS TABLE_NAME select
-INNODB_BUFFER_POOL_PAGES_INDEX table_name select
INNODB_INDEX_STATS table_name select
INNODB_TABLE_STATS table_name select
KEY_COLUMN_USAGE TABLE_NAME select
@@ -1664,4 +1664,21 @@ WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = 'variables';
COLUMN_DEFAULT TABLE_NAME
NULL variables
DROP TABLE variables;
+#
+# Bug #53814: NUMERIC_PRECISION for unsigned bigint field is 19,
+# should be 20
+#
+CREATE TABLE ubig (a BIGINT, b BIGINT UNSIGNED);
+SELECT TABLE_NAME, COLUMN_NAME, NUMERIC_PRECISION
+FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='ubig';
+TABLE_NAME COLUMN_NAME NUMERIC_PRECISION
+ubig a 19
+ubig b 20
+INSERT INTO ubig VALUES (0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF);
+Warnings:
+Warning 1264 Out of range value for column 'a' at row 1
+SELECT length(CAST(b AS CHAR)) FROM ubig;
+length(CAST(b AS CHAR))
+20
+DROP TABLE ubig;
End of 5.1 tests.
diff --git a/mysql-test/r/information_schema_all_engines.result b/mysql-test/r/information_schema_all_engines.result
index dfe7570266c..7a2c548a329 100644
--- a/mysql-test/r/information_schema_all_engines.result
+++ b/mysql-test/r/information_schema_all_engines.result
@@ -44,13 +44,14 @@ XTRADB_ADMIN_COMMAND
INNODB_TRX
INNODB_SYS_TABLES
INNODB_LOCK_WAITS
-INNODB_CMPMEM_RESET
+INNODB_SYS_STATS
INNODB_LOCKS
INNODB_CMPMEM
INNODB_TABLE_STATS
INNODB_SYS_INDEXES
INNODB_CMP_RESET
INNODB_BUFFER_POOL_PAGES_BLOB
+INNODB_CMPMEM_RESET
INNODB_INDEX_STATS
SELECT t.table_name, c1.column_name
FROM information_schema.tables t
@@ -105,18 +106,19 @@ PBXT_STATISTICS ID
INNODB_CMP page_size
INNODB_RSEG rseg_id
XTRADB_ENHANCEMENTS name
-INNODB_BUFFER_POOL_PAGES_INDEX schema_name
+INNODB_BUFFER_POOL_PAGES_INDEX index_id
XTRADB_ADMIN_COMMAND result_message
INNODB_TRX trx_id
INNODB_SYS_TABLES SCHEMA
INNODB_LOCK_WAITS requesting_trx_id
-INNODB_CMPMEM_RESET page_size
+INNODB_SYS_STATS INDEX_ID
INNODB_LOCKS lock_id
INNODB_CMPMEM page_size
INNODB_TABLE_STATS table_schema
INNODB_SYS_INDEXES TABLE_ID
INNODB_CMP_RESET page_size
INNODB_BUFFER_POOL_PAGES_BLOB space_id
+INNODB_CMPMEM_RESET page_size
INNODB_INDEX_STATS table_schema
SELECT t.table_name, c1.column_name
FROM information_schema.tables t
@@ -171,18 +173,19 @@ PBXT_STATISTICS ID
INNODB_CMP page_size
INNODB_RSEG rseg_id
XTRADB_ENHANCEMENTS name
-INNODB_BUFFER_POOL_PAGES_INDEX schema_name
+INNODB_BUFFER_POOL_PAGES_INDEX index_id
XTRADB_ADMIN_COMMAND result_message
INNODB_TRX trx_id
INNODB_SYS_TABLES SCHEMA
INNODB_LOCK_WAITS requesting_trx_id
-INNODB_CMPMEM_RESET page_size
+INNODB_SYS_STATS INDEX_ID
INNODB_LOCKS lock_id
INNODB_CMPMEM page_size
INNODB_TABLE_STATS table_schema
INNODB_SYS_INDEXES TABLE_ID
INNODB_CMP_RESET page_size
INNODB_BUFFER_POOL_PAGES_BLOB space_id
+INNODB_CMPMEM_RESET page_size
INNODB_INDEX_STATS table_schema
select 1 as f1 from information_schema.tables where "CHARACTER_SETS"=
(select cast(table_name as char) from information_schema.tables
@@ -229,6 +232,7 @@ INNODB_LOCKS information_schema.INNODB_LOCKS 1
INNODB_LOCK_WAITS information_schema.INNODB_LOCK_WAITS 1
INNODB_RSEG information_schema.INNODB_RSEG 1
INNODB_SYS_INDEXES information_schema.INNODB_SYS_INDEXES 1
+INNODB_SYS_STATS information_schema.INNODB_SYS_STATS 1
INNODB_SYS_TABLES information_schema.INNODB_SYS_TABLES 1
INNODB_TABLE_STATS information_schema.INNODB_TABLE_STATS 1
INNODB_TRX information_schema.INNODB_TRX 1
@@ -302,13 +306,14 @@ Database: information_schema
| INNODB_TRX |
| INNODB_SYS_TABLES |
| INNODB_LOCK_WAITS |
-| INNODB_CMPMEM_RESET |
+| INNODB_SYS_STATS |
| INNODB_LOCKS |
| INNODB_CMPMEM |
| INNODB_TABLE_STATS |
| INNODB_SYS_INDEXES |
| INNODB_CMP_RESET |
| INNODB_BUFFER_POOL_PAGES_BLOB |
+| INNODB_CMPMEM_RESET |
| INNODB_INDEX_STATS |
+---------------------------------------+
Database: INFORMATION_SCHEMA
@@ -358,13 +363,14 @@ Database: INFORMATION_SCHEMA
| INNODB_TRX |
| INNODB_SYS_TABLES |
| INNODB_LOCK_WAITS |
-| INNODB_CMPMEM_RESET |
+| INNODB_SYS_STATS |
| INNODB_LOCKS |
| INNODB_CMPMEM |
| INNODB_TABLE_STATS |
| INNODB_SYS_INDEXES |
| INNODB_CMP_RESET |
| INNODB_BUFFER_POOL_PAGES_BLOB |
+| INNODB_CMPMEM_RESET |
| INNODB_INDEX_STATS |
+---------------------------------------+
Wildcard: inf_rmation_schema
@@ -375,5 +381,5 @@ Wildcard: inf_rmation_schema
+--------------------+
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA;
table_schema count(*)
-information_schema 51
+information_schema 52
mysql 22
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index 665e80b8ba2..40c278380b1 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -503,4 +503,33 @@ DROP TABLE t1;
CREATE TABLE t1 (id INT NOT NULL);
LOAD DATA LOCAL INFILE 'tb.txt' INTO TABLE t1;
DROP TABLE t1;
+#
+# Bug #51876 : crash/memory underrun when loading data with ucs2
+# and reverse() function
+#
+# Problem # 1 (original report): wrong parsing of ucs2 data
+SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt';
+CREATE TABLE t1(a INT);
+LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2
+(@b) SET a=REVERSE(@b);
+Warnings:
+Warning 1366 Incorrect integer value: '00' for column 'a' at row 1
+Warning 1366 Incorrect integer value: '10' for column 'a' at row 2
+# should return 2 zeroes (as the value is truncated)
+SELECT * FROM t1;
+a
+0
+0
+DROP TABLE t1;
+# Problem # 2 : if you write and read ucs2 data to a file they're lost
+SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2;
+CREATE TABLE t1(a INT);
+LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2
+(@b) SET a=REVERSE(@b);
+# should return 0 and 1 (10 reversed)
+SELECT * FROM t1;
+a
+0
+1
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/log_tables_upgrade.result b/mysql-test/r/log_tables_upgrade.result
index 5d9be85a48a..a9d1b41cf2c 100644
--- a/mysql-test/r/log_tables_upgrade.result
+++ b/mysql-test/r/log_tables_upgrade.result
@@ -11,15 +11,18 @@ Table Op Msg_type Msg_text
test.bug49823 repair status OK
RENAME TABLE general_log TO renamed_general_log;
RENAME TABLE test.bug49823 TO general_log;
+Phase 1/3: Fixing table and database names
+Phase 2/3: Checking and upgrading tables
+Processing databases
+information_schema
+mtr
mtr.global_suppressions OK
mtr.test_suppressions OK
+mysql
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
-mysql.general_log
-Error : You can't use locks with log tables.
-status : OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
@@ -31,9 +34,6 @@ mysql.proc OK
mysql.procs_priv OK
mysql.renamed_general_log OK
mysql.servers OK
-mysql.slow_log
-Error : You can't use locks with log tables.
-status : OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
@@ -41,6 +41,9 @@ mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
+test
+Phase 3/3: Running 'mysql_fix_privilege_tables'...
+OK
DROP TABLE general_log;
RENAME TABLE renamed_general_log TO general_log;
SET GLOBAL general_log = @saved_general_log;
diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result
index 51c2ac0faf5..c9a46b70fab 100644
--- a/mysql-test/r/lowercase_table2.result
+++ b/mysql-test/r/lowercase_table2.result
@@ -56,6 +56,7 @@ CREATE DATABASE `TEST_$1`;
SHOW DATABASES LIKE "TEST%";
Database (TEST%)
TEST_$1
+test
DROP DATABASE `test_$1`;
CREATE TABLE T1 (a int) engine=innodb;
INSERT INTO T1 VALUES (1);
@@ -171,6 +172,6 @@ create table myUC (i int);
select TABLE_SCHEMA,TABLE_NAME FROM information_schema.TABLES
where TABLE_SCHEMA ='mysqltest_LC2';
TABLE_SCHEMA TABLE_NAME
-mysqltest_LC2 myUC
+mysqltest_lc2 myUC
use test;
drop database mysqltest_LC2;
diff --git a/mysql-test/r/lowercase_view.result b/mysql-test/r/lowercase_view.result
index c37dc41c495..33c87ec101c 100644
--- a/mysql-test/r/lowercase_view.result
+++ b/mysql-test/r/lowercase_view.result
@@ -148,3 +148,20 @@ a
DROP VIEW v1;
DROP TABLE t1;
End of 5.0 tests.
+#
+# Bug #53095: SELECT column_name FROM INFORMATION_SCHEMA.STATISTICS
+# returns nothing
+#
+CREATE TABLE `ttt` (
+`f1` char(3) NOT NULL,
+PRIMARY KEY (`f1`)
+) ENGINE=myisam DEFAULT CHARSET=latin1;
+SELECT count(COLUMN_NAME) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME =
+'TTT';
+count(COLUMN_NAME)
+1
+SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'TTT';
+count(*)
+1
+DROP TABLE `ttt`;
+End of 5.0 tests.
diff --git a/mysql-test/r/mysql_client_test.result b/mysql-test/r/mysql_client_test.result
index 08d982c85e3..edda7980e97 100644
--- a/mysql-test/r/mysql_client_test.result
+++ b/mysql-test/r/mysql_client_test.result
@@ -1,3 +1,5 @@
SET @old_general_log= @@global.general_log;
+SET @old_slow_query_log= @@global.slow_query_log;
ok
SET @@global.general_log= @old_general_log;
+SET @@global.slow_query_log= @old_slow_query_log;
diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result
index 821ad31871f..ca23dc9cca1 100644
--- a/mysql-test/r/mysql_upgrade.result
+++ b/mysql-test/r/mysql_upgrade.result
@@ -1,13 +1,16 @@
Run mysql_upgrade once
+Phase 1/3: Fixing table and database names
+Phase 2/3: Checking and upgrading tables
+Processing databases
+information_schema
+mtr
mtr.global_suppressions OK
mtr.test_suppressions OK
+mysql
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
-mysql.general_log
-Error : You can't use locks with log tables.
-status : OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
@@ -18,9 +21,6 @@ mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.servers OK
-mysql.slow_log
-Error : You can't use locks with log tables.
-status : OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
@@ -28,18 +28,24 @@ mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
+test
+Phase 3/3: Running 'mysql_fix_privilege_tables'...
+OK
Run it again - should say already completed
This installation of MySQL is already upgraded to VERSION, use --force if you still need to run mysql_upgrade
Force should run it regardless of wether it's been run before
+Phase 1/3: Fixing table and database names
+Phase 2/3: Checking and upgrading tables
+Processing databases
+information_schema
+mtr
mtr.global_suppressions OK
mtr.test_suppressions OK
+mysql
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
-mysql.general_log
-Error : You can't use locks with log tables.
-status : OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
@@ -50,9 +56,6 @@ mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.servers OK
-mysql.slow_log
-Error : You can't use locks with log tables.
-status : OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
@@ -60,18 +63,24 @@ mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
+test
+Phase 3/3: Running 'mysql_fix_privilege_tables'...
+OK
CREATE USER mysqltest1@'%' IDENTIFIED by 'sakila';
GRANT ALL ON *.* TO mysqltest1@'%';
Run mysql_upgrade with password protected account
+Phase 1/3: Fixing table and database names
+Phase 2/3: Checking and upgrading tables
+Processing databases
+information_schema
+mtr
mtr.global_suppressions OK
mtr.test_suppressions OK
+mysql
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
-mysql.general_log
-Error : You can't use locks with log tables.
-status : OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
@@ -82,9 +91,6 @@ mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.servers OK
-mysql.slow_log
-Error : You can't use locks with log tables.
-status : OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
@@ -92,20 +98,27 @@ mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
+test
+Phase 3/3: Running 'mysql_fix_privilege_tables'...
+OK
DROP USER mysqltest1@'%';
Run mysql_upgrade with a non existing server socket
+Phase 1/3: Fixing table and database names
mysqlcheck: Got error: 2005: Unknown MySQL server host 'not_existing_host' (errno) when trying to connect
FATAL ERROR: Upgrade failed
set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE';
+Phase 1/3: Fixing table and database names
+Phase 2/3: Checking and upgrading tables
+Processing databases
+information_schema
+mtr
mtr.global_suppressions OK
mtr.test_suppressions OK
+mysql
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
-mysql.general_log
-Error : You can't use locks with log tables.
-status : OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
@@ -116,9 +129,6 @@ mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.servers OK
-mysql.slow_log
-Error : You can't use locks with log tables.
-status : OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
@@ -126,6 +136,9 @@ mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
+test
+Phase 3/3: Running 'mysql_fix_privilege_tables'...
+OK
set GLOBAL sql_mode=default;
#
# Bug #41569 mysql_upgrade (ver 5.1) add 3 fields to mysql.proc table
@@ -135,15 +148,18 @@ CREATE PROCEDURE testproc() BEGIN END;
UPDATE mysql.proc SET character_set_client = NULL WHERE name LIKE 'testproc';
UPDATE mysql.proc SET collation_connection = NULL WHERE name LIKE 'testproc';
UPDATE mysql.proc SET db_collation = NULL WHERE name LIKE 'testproc';
+Phase 1/3: Fixing table and database names
+Phase 2/3: Checking and upgrading tables
+Processing databases
+information_schema
+mtr
mtr.global_suppressions OK
mtr.test_suppressions OK
+mysql
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
-mysql.general_log
-Error : You can't use locks with log tables.
-status : OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
@@ -154,9 +170,6 @@ mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.servers OK
-mysql.slow_log
-Error : You can't use locks with log tables.
-status : OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
@@ -164,8 +177,56 @@ mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
+test
+Phase 3/3: Running 'mysql_fix_privilege_tables'...
+OK
CALL testproc();
DROP PROCEDURE testproc;
WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (latin1). Please verify if necessary.
WARNING: NULL values of the 'collation_connection' column ('mysql.proc' table) have been updated with a default value (latin1_swedish_ci). Please verify if necessary.
WARNING: NULL values of the 'db_collation' column ('mysql.proc' table) have been updated with default values. Please verify if necessary.
+#
+# Bug #53613: mysql_upgrade incorrectly revokes
+# TRIGGER privilege on given table
+#
+GRANT USAGE ON *.* TO 'user3'@'%';
+GRANT ALL PRIVILEGES ON `roelt`.`test2` TO 'user3'@'%';
+Run mysql_upgrade with all privileges on a user
+Phase 1/3: Fixing table and database names
+Phase 2/3: Checking and upgrading tables
+Processing databases
+information_schema
+mtr
+mtr.global_suppressions OK
+mtr.test_suppressions OK
+mysql
+mysql.columns_priv OK
+mysql.db OK
+mysql.event OK
+mysql.func OK
+mysql.help_category OK
+mysql.help_keyword OK
+mysql.help_relation OK
+mysql.help_topic OK
+mysql.host OK
+mysql.ndb_binlog_index OK
+mysql.plugin OK
+mysql.proc OK
+mysql.procs_priv OK
+mysql.servers OK
+mysql.tables_priv OK
+mysql.time_zone OK
+mysql.time_zone_leap_second OK
+mysql.time_zone_name OK
+mysql.time_zone_transition OK
+mysql.time_zone_transition_type OK
+mysql.user OK
+test
+Phase 3/3: Running 'mysql_fix_privilege_tables'...
+OK
+SHOW GRANTS FOR 'user3'@'%';
+Grants for user3@%
+GRANT USAGE ON *.* TO 'user3'@'%'
+GRANT ALL PRIVILEGES ON `roelt`.`test2` TO 'user3'@'%'
+DROP USER 'user3'@'%';
+End of 5.1 tests
diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result
index 5f1a0565b10..812fd12e197 100644
--- a/mysql-test/r/mysqlcheck.result
+++ b/mysql-test/r/mysqlcheck.result
@@ -7,8 +7,6 @@ mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
-mysql.general_log
-note : The storage engine for the table doesn't support optimize
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
@@ -19,8 +17,6 @@ mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.servers OK
-mysql.slow_log
-note : The storage engine for the table doesn't support optimize
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
@@ -32,8 +28,6 @@ mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
-mysql.general_log
-note : The storage engine for the table doesn't support optimize
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
@@ -44,8 +38,6 @@ mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.servers OK
-mysql.slow_log
-note : The storage engine for the table doesn't support optimize
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
diff --git a/mysql-test/r/not_partition.result b/mysql-test/r/not_partition.result
index f516f8634ce..b17594d0ded 100644
--- a/mysql-test/r/not_partition.result
+++ b/mysql-test/r/not_partition.result
@@ -1,47 +1,47 @@
DROP TABLE IF EXISTS t1;
FLUSH TABLES;
SELECT * FROM t1;
-ERROR 42000: Unknown table engine 'partition'
+ERROR 42000: Unknown table engine 'partition'
TRUNCATE TABLE t1;
-ERROR 42000: Unknown table engine 'partition'
+ERROR 42000: Unknown table engine 'partition'
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
-test.t1 analyze Error Unknown table engine 'partition'
+test.t1 analyze Error Unknown table engine 'partition'
test.t1 analyze error Corrupt
CHECK TABLE t1;
Table Op Msg_type Msg_text
-test.t1 check Error Unknown table engine 'partition'
+test.t1 check Error Unknown table engine 'partition'
test.t1 check error Corrupt
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
-test.t1 optimize Error Unknown table engine 'partition'
+test.t1 optimize Error Unknown table engine 'partition'
test.t1 optimize error Corrupt
REPAIR TABLE t1;
Table Op Msg_type Msg_text
-test.t1 repair Error Unknown table engine 'partition'
+test.t1 repair Error Unknown table engine 'partition'
test.t1 repair error Corrupt
ALTER TABLE t1 REPAIR PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 repair Error Unknown table engine 'partition'
+test.t1 repair Error Unknown table engine 'partition'
test.t1 repair error Corrupt
ALTER TABLE t1 CHECK PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 check Error Unknown table engine 'partition'
+test.t1 check Error Unknown table engine 'partition'
test.t1 check error Corrupt
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 optimize Error Unknown table engine 'partition'
+test.t1 optimize Error Unknown table engine 'partition'
test.t1 optimize error Corrupt
ALTER TABLE t1 ANALYZE PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 analyze Error Unknown table engine 'partition'
+test.t1 analyze Error Unknown table engine 'partition'
test.t1 analyze error Corrupt
ALTER TABLE t1 REBUILD PARTITION ALL;
-ERROR 42000: Unknown table engine 'partition'
+ERROR 42000: Unknown table engine 'partition'
ALTER TABLE t1 ENGINE Memory;
-ERROR 42000: Unknown table engine 'partition'
+ERROR 42000: Unknown table engine 'partition'
ALTER TABLE t1 ADD (new INT);
-ERROR 42000: Unknown table engine 'partition'
+ERROR 42000: Unknown table engine 'partition'
DROP TABLE t1;
CREATE TABLE t1 (
firstname VARCHAR(25) NOT NULL,
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index 4da176aa1a6..31c612500d9 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -977,7 +977,7 @@ NULL test t1 c NULL NO int NULL NULL int(11) PRI select,insert,update,reference
----------------------------------------------------------------
SHOW TABLES LIKE 't1';
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def TABLE_NAMES TABLE_NAME Tables_in_test (t1) 253 192 2 N 1 0 33
+def TABLE_NAMES TABLE_NAME Tables_in_test (t1) 253 219 2 N 1 0 33
Tables_in_test (t1)
t1
----------------------------------------------------------------
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index 006eaba4e69..63baf639487 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -527,3 +527,17 @@ ERROR HY000: You are using safe update mode and you tried to update a table with
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
+#
+# Bug#54734 assert in Diagnostics_area::set_ok_status
+#
+DROP TABLE IF EXISTS t1, not_exists;
+DROP FUNCTION IF EXISTS f1;
+DROP VIEW IF EXISTS v1;
+CREATE TABLE t1 (PRIMARY KEY(pk)) AS SELECT 1 AS pk;
+CREATE FUNCTION f1() RETURNS INTEGER RETURN (SELECT 1 FROM not_exists);
+CREATE VIEW v1 AS SELECT pk FROM t1 WHERE f1() = 13;
+UPDATE v1 SET pk = 7 WHERE pk > 0;
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+DROP VIEW v1;
+DROP FUNCTION f1;
+DROP TABLE t1;
diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result
index da2f55b5bb1..bdfac990a9a 100644
--- a/mysql-test/r/upgrade.result
+++ b/mysql-test/r/upgrade.result
@@ -139,4 +139,12 @@ USE `#mysql50#.`;
ERROR 42000: Incorrect database name '#mysql50#.'
USE `#mysql50#../blablabla`;
ERROR 42000: Incorrect database name '#mysql50#../blablabla'
+show full tables;
+Tables_in_test Table_type
+#mysql50#ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com BASE TABLE
+rename table `#mysql50#ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com` to `ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com`;
+show full tables;
+Tables_in_test Table_type
+ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com BASE TABLE
+drop table `ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com`;
# End of 5.1 tests
diff --git a/mysql-test/std_data/archive_5_0.ARM b/mysql-test/std_data/archive_5_0.ARM
new file mode 100644
index 00000000000..8f1111437d8
--- /dev/null
+++ b/mysql-test/std_data/archive_5_0.ARM
Binary files differ
diff --git a/mysql-test/std_data/archive_5_0.ARZ b/mysql-test/std_data/archive_5_0.ARZ
new file mode 100644
index 00000000000..d24e76884cc
--- /dev/null
+++ b/mysql-test/std_data/archive_5_0.ARZ
Binary files differ
diff --git a/mysql-test/std_data/archive_5_0.frm b/mysql-test/std_data/archive_5_0.frm
new file mode 100644
index 00000000000..827213d329d
--- /dev/null
+++ b/mysql-test/std_data/archive_5_0.frm
Binary files differ
diff --git a/mysql-test/std_data/long_table_name.MYD b/mysql-test/std_data/long_table_name.MYD
new file mode 100644
index 00000000000..2ff33451b5f
--- /dev/null
+++ b/mysql-test/std_data/long_table_name.MYD
Binary files differ
diff --git a/mysql-test/std_data/long_table_name.MYI b/mysql-test/std_data/long_table_name.MYI
new file mode 100644
index 00000000000..cffa158beae
--- /dev/null
+++ b/mysql-test/std_data/long_table_name.MYI
Binary files differ
diff --git a/mysql-test/std_data/long_table_name.frm b/mysql-test/std_data/long_table_name.frm
new file mode 100644
index 00000000000..6a812a8b137
--- /dev/null
+++ b/mysql-test/std_data/long_table_name.frm
Binary files differ
diff --git a/mysql-test/std_data/server8k-cert.pem b/mysql-test/std_data/server8k-cert.pem
index 06e118cf034..e71ba5722b9 100644
--- a/mysql-test/std_data/server8k-cert.pem
+++ b/mysql-test/std_data/server8k-cert.pem
@@ -1,125 +1,51 @@
-Certificate:
- Data:
- Version: 1 (0x0)
- Serial Number: 1048579 (0x100003)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB
- Validity
- Not Before: Jan 29 12:01:53 2010 GMT
- Not After : Jan 28 12:01:53 2015 GMT
- Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=server
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (8192 bit)
- Modulus:
- 00:ca:aa:1d:c4:11:ec:91:f0:c7:ff:5f:90:92:fc:
- 40:0c:5e:b7:3d:00:c5:20:d5:0f:89:31:07:d7:41:
- 4c:8b:60:80:aa:38:14:de:93:6b:9c:74:88:41:68:
- b5:02:41:01:2d:86:a2:7a:95:53:5e:7b:67:2f:6c:
- 1e:29:51:f9:44:fd:4a:80:be:b2:23:a1:3e:1b:38:
- cf:88:c4:71:ee:f8:6b:41:c5:2d:c0:c3:52:ac:59:
- 7d:81:34:19:95:32:b8:9a:51:b6:41:36:d4:c4:a1:
- ae:84:e6:38:b9:e8:bf:96:be:19:7a:6b:77:4d:e0:
- de:e6:b3:b6:6b:bc:3d:dd:68:bc:4b:c4:eb:f5:36:
- 93:ed:56:a2:15:50:8a:10:e8:d6:22:ed:6c:b1:cd:
- c3:18:c9:f6:0a:e1:de:61:65:62:d6:14:41:8c:b5:
- fb:14:68:c1:cf:12:5d:41:21:9d:57:11:43:7d:bb:
- 43:2c:21:bb:c3:44:7d:a8:cf:1f:c3:71:75:b5:47:
- c2:7d:ce:38:3c:73:64:9e:15:d8:a7:27:cf:bd:40:
- c8:45:08:e3:c8:39:a8:0b:8e:c2:5b:7b:f1:47:91:
- 12:91:cc:e1:00:e0:94:5b:bd:32:e4:0c:8d:c3:be:
- cc:76:32:52:12:69:b0:18:e0:b0:c2:76:34:5a:5f:
- 79:d9:f6:81:9d:02:0a:61:69:1c:33:ce:49:fa:76:
- 03:1e:07:5b:27:0b:bf:34:9e:34:96:b8:03:9b:50:
- 3a:6a:2f:17:7a:14:cf:65:63:00:37:52:a8:73:ce:
- 4b:14:40:f4:d2:9a:56:54:33:b8:77:2e:42:5b:8f:
- ec:1f:18:f4:ad:ab:8a:4a:8d:6d:70:25:f3:58:e7:
- cb:66:51:14:7d:16:f4:eb:6d:56:76:76:51:6e:d6:
- 1d:da:d3:8d:c0:64:5a:67:4e:af:e2:bf:33:d1:b8:
- f6:2a:fc:57:87:a7:35:5e:80:c9:ac:fc:87:c9:71:
- 17:91:bf:b7:4d:a3:ed:3c:1b:27:f4:66:a0:f9:46:
- 03:27:cc:ea:80:f6:4b:40:f6:41:94:cd:bd:0a:b3:
- ef:26:be:de:6f:69:ae:0f:3f:1c:55:63:33:90:9b:
- ed:ca:5a:12:4d:de:4b:06:c2:a2:92:b0:42:3d:31:
- af:a4:15:12:15:f8:8a:e9:88:8d:cf:fd:85:66:50:
- 6f:11:f1:9f:48:f3:b5:ba:9d:86:68:24:a2:5d:a8:
- 7c:54:42:fa:d8:b5:c5:f2:dd:0e:0f:d0:68:e4:54:
- 7e:c5:b9:a0:9b:65:2d:77:f4:8f:b9:30:0a:d5:86:
- 5c:ed:c9:7c:d1:da:9d:0d:63:50:ee:e5:1e:92:63:
- cc:a2:0c:e8:4a:96:02:4d:dc:8f:df:7c:8f:08:18:
- a8:30:88:d7:af:89:ad:fc:57:4b:10:f9:f1:cb:48:
- e8:b6:3b:c8:3f:fc:c2:d3:d1:4a:10:3c:1b:6b:64:
- dc:e5:65:1e:5b:b2:da:b1:e2:24:97:8f:ee:c0:4b:
- 8e:18:83:7c:17:a6:3c:45:b3:60:06:23:f2:2f:18:
- 13:9e:17:8a:c6:72:79:8c:4d:04:f3:9d:ea:e0:25:
- d3:33:8c:1e:11:47:63:1f:a5:45:3f:bd:85:b3:fe:
- a5:68:ee:48:b7:0c:a4:c9:7f:72:d0:75:66:9b:6a:
- f9:a0:50:f3:a8:59:6d:a3:dd:38:4f:70:2b:bb:ff:
- 92:2e:71:ab:ef:e9:00:ed:0d:d1:b4:6f:f0:8e:b2:
- 09:fb:4d:61:0d:d9:10:d5:54:11:cd:03:94:84:fd:
- a8:68:e4:45:6e:1e:6a:1e:2f:85:a1:6d:f5:b6:c0:
- f1:ee:f7:36:e9:fe:c2:f7:ad:cc:13:46:5b:88:42:
- f0:2d:1f:b5:0e:7e:b5:2b:e4:8d:ab:b9:87:30:6a:
- 3d:12:f4:ad:f3:1c:ac:cc:1a:48:29:2a:96:7b:80:
- 00:0b:6e:59:87:bf:a3:ca:70:99:1b:1c:fd:72:3d:
- b2:d3:94:4a:cf:55:75:be:1f:40:ec:55:35:48:2d:
- 55:f0:00:da:3c:b0:60:ba:11:32:66:54:0b:be:06:
- a4:5e:b7:c9:59:bb:4d:f4:92:06:26:48:6e:c2:12:
- d4:7c:f0:20:b8:a2:e1:bc:6a:b6:19:0e:37:47:55:
- c9:f2:49:0d:96:75:a2:84:64:bf:34:fc:be:b2:41:
- e4:f5:88:eb:e1:b7:26:a5:e5:41:c2:20:0c:f6:e2:
- a8:a5:e7:76:54:a5:fb:4b:80:05:7d:18:85:7a:ba:
- bc:b7:ad:c0:2f:60:85:cc:15:12:1c:2f:0a:9e:f3:
- 7c:40:cf:f4:3e:23:d2:95:ca:d0:06:58:52:f0:84:
- d8:0f:3d:eb:ff:12:68:94:79:8f:be:40:29:5f:98:
- c8:90:6c:05:2f:99:8c:2a:63:78:1f:23:b1:29:c5:
- e7:49:c9:b2:92:0f:53:0b:d5:71:28:17:c2:19:bf:
- 60:bf:7c:87:a8:ab:c1:f4:0a:c1:b8:d2:68:ee:c1:
- ce:a7:13:13:17:6d:24:5d:a2:37:a6:d7:7d:48:8b:
- 2b:74:2d:40:2e:ca:19:d5:b6:3e:6c:42:71:fa:cf:
- 85:87:f9:de:80:73:8b:89:f4:70:f0:d8:d7:ff:40:
- 41:9c:c7:15:6d:9b:6e:4c:b5:52:02:99:79:32:73:
- ca:26:a0:ac:31:6f:c4:b0:f5:da:bb:c2:1f:e0:9f:
- 44:ba:25:f7:9f
- Exponent: 65537 (0x10001)
- Signature Algorithm: md5WithRSAEncryption
- 08:75:dc:b9:3f:aa:b6:7e:81:7a:39:d1:ee:ed:44:b6:ce:1b:
- 37:c4:4c:19:d0:66:e6:eb:b5:4f:2a:ef:95:58:64:21:55:01:
- 12:30:ac:8a:95:d1:06:de:29:46:a4:f1:7d:7f:b0:1e:d2:4e:
- fb:f6:fa:9a:74:be:85:62:db:0b:82:90:58:62:c5:5f:f1:80:
- 02:9f:c5:fb:f3:6b:b0:b4:3b:04:b1:e5:53:c2:d0:00:a1:1a:
- 9d:65:60:6f:73:98:67:e0:9c:c8:12:94:79:59:bf:43:7b:f5:
- 77:c8:8f:df:b1:cd:11:1c:01:19:99:c2:22:42:f7:41:ae:b4:
- b8:1a
-----BEGIN CERTIFICATE-----
-MIIFfDCCBOUCAxAAAzANBgkqhkiG9w0BAQQFADBEMQswCQYDVQQGEwJTRTEQMA4G
-A1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwg
-QUIwHhcNMTAwMTI5MTIwMTUzWhcNMTUwMTI4MTIwMTUzWjBDMQswCQYDVQQGEwJT
-RTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxDzANBgNVBAMT
-BnNlcnZlcjCCBCIwDQYJKoZIhvcNAQEBBQADggQPADCCBAoCggQBAMqqHcQR7JHw
-x/9fkJL8QAxetz0AxSDVD4kxB9dBTItggKo4FN6Ta5x0iEFotQJBAS2GonqVU157
-Zy9sHilR+UT9SoC+siOhPhs4z4jEce74a0HFLcDDUqxZfYE0GZUyuJpRtkE21MSh
-roTmOLnov5a+GXprd03g3uaztmu8Pd1ovEvE6/U2k+1WohVQihDo1iLtbLHNwxjJ
-9grh3mFlYtYUQYy1+xRowc8SXUEhnVcRQ327Qywhu8NEfajPH8NxdbVHwn3OODxz
-ZJ4V2Kcnz71AyEUI48g5qAuOwlt78UeREpHM4QDglFu9MuQMjcO+zHYyUhJpsBjg
-sMJ2NFpfedn2gZ0CCmFpHDPOSfp2Ax4HWycLvzSeNJa4A5tQOmovF3oUz2VjADdS
-qHPOSxRA9NKaVlQzuHcuQluP7B8Y9K2rikqNbXAl81jny2ZRFH0W9OttVnZ2UW7W
-HdrTjcBkWmdOr+K/M9G49ir8V4enNV6Ayaz8h8lxF5G/t02j7TwbJ/RmoPlGAyfM
-6oD2S0D2QZTNvQqz7ya+3m9prg8/HFVjM5Cb7cpaEk3eSwbCopKwQj0xr6QVEhX4
-iumIjc/9hWZQbxHxn0jztbqdhmgkol2ofFRC+ti1xfLdDg/QaORUfsW5oJtlLXf0
-j7kwCtWGXO3JfNHanQ1jUO7lHpJjzKIM6EqWAk3cj998jwgYqDCI16+JrfxXSxD5
-8ctI6LY7yD/8wtPRShA8G2tk3OVlHluy2rHiJJeP7sBLjhiDfBemPEWzYAYj8i8Y
-E54XisZyeYxNBPOd6uAl0zOMHhFHYx+lRT+9hbP+pWjuSLcMpMl/ctB1Zptq+aBQ
-86hZbaPdOE9wK7v/ki5xq+/pAO0N0bRv8I6yCftNYQ3ZENVUEc0DlIT9qGjkRW4e
-ah4vhaFt9bbA8e73Nun+wvetzBNGW4hC8C0ftQ5+tSvkjau5hzBqPRL0rfMcrMwa
-SCkqlnuAAAtuWYe/o8pwmRsc/XI9stOUSs9Vdb4fQOxVNUgtVfAA2jywYLoRMmZU
-C74GpF63yVm7TfSSBiZIbsIS1HzwILii4bxqthkON0dVyfJJDZZ1ooRkvzT8vrJB
-5PWI6+G3JqXlQcIgDPbiqKXndlSl+0uABX0YhXq6vLetwC9ghcwVEhwvCp7zfEDP
-9D4j0pXK0AZYUvCE2A896/8SaJR5j75AKV+YyJBsBS+ZjCpjeB8jsSnF50nJspIP
-UwvVcSgXwhm/YL98h6irwfQKwbjSaO7BzqcTExdtJF2iN6bXfUiLK3QtQC7KGdW2
-PmxCcfrPhYf53oBzi4n0cPDY1/9AQZzHFW2bbky1UgKZeTJzyiagrDFvxLD12rvC
-H+CfRLol958CAwEAATANBgkqhkiG9w0BAQQFAAOBgQAIddy5P6q2foF6OdHu7US2
-zhs3xEwZ0Gbm67VPKu+VWGQhVQESMKyKldEG3ilGpPF9f7Ae0k779vqadL6FYtsL
-gpBYYsVf8YACn8X782uwtDsEseVTwtAAoRqdZWBvc5hn4JzIEpR5Wb9De/V3yI/f
-sc0RHAEZmcIiQvdBrrS4Gg==
+MIIJFDCCBPwCAQEwDQYJKoZIhvcNAQEEBQAwTjELMAkGA1UEBhMCU0UxEDAOBgNV
+BAgTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMQ0wCwYDVQQLEwRUZXN0MQsw
+CQYDVQQDEwJDQTAeFw0xMDA3MjgxNDA3MjhaFw0xODEwMTQxNDA3MjhaMFIxCzAJ
+BgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQjEN
+MAsGA1UECxMEVGVzdDEPMA0GA1UEAxMGc2VydmVyMIIEIjANBgkqhkiG9w0BAQEF
+AAOCBA8AMIIECgKCBAEA6h3v1OWb9I9U/Z8diBu/xYGS8NCTD3ZESboHxVI2qSEC
+PgxNNcG8Lh0ktQdgYcOe64MnDTZX0Bibm47hoDldrAlTSffFxQhylqBBoXxDF+Lr
+hXIqCz7K0PsK+bYusL9ezJ7PETDnCT7oy95q4GXbKsutbNsm9if4ZE41gs2KnoU2
+DA7kvMmkKojrMIL4+BqTXA20LLo0iSbgvUTvpSJw4u96BeyzMNnxK2wP5vvTtUo5
+hACbfU87YjaSKs+q2VXCzfyYGZk1L1xk5GUI0bP+jutf1dDzNttW2/q2Nf5rxx09
+Gh/GwmOnEk1O7cOZ8VQCsOHirIM39NuSARsY6Y3G5XM4k2W4nxyR/RtdG9bvs/33
+aGsZ5V5yp7WSs8s9HHwaCPSsUiLKckQ7uA0TTRgbeweMrrLKovG57jsbBBB8pQD4
+PRd31qgxCdstWXHiWwRyI8vOLWENPXPFqA/rJwwqNdWTogy38aqVXxGYR8PIwjA2
+OaIwFjwGZcsPNLqw6bgAN8O2UBqZHWiMF8mi7brvioDvAIufZuqa2SqT/At45H83
+psQ6R4FsxZt6SAK7EsdPo8OYTrY1i4iPZd/eKhnEu2srEZgsKRwY5H1mvDH5fWCc
+HSFu07sWmlmK6Or65Fsa0IaKLJiQDVVETd6xrI0wkM4AOcbKDrS7aywJ426dopbs
++LFdt4N0cdII4gBgJAfLuuA2yrDXRq4P6cgpVMy0R+0dEYE8zzm8zf1a+Ud273LS
+9+LB+LJKwqbW8nOPBoiekimIKfJYoOA4+C/mAjsYl1sVjjEhXJAs9S9L2UvnUk1P
+sZi4UKHI6eAIEl7VM1sQ4GbdZ0px2dF2Ax7pGkhD+DLpYyYkCprharKZdmuUNLUd
+NhXxi/HSEiE+Uy+o8RIzmH7LuROl/ZgnfHjJEiBLt2qPvwrwYd4c3XuXWs4YsWfV
+JTt8Mx2ihgVcdGy9//shCSmgJwR1oWrhgC10AEL2fKeRnYUal1i+IxFPp7nb8uwx
+UADgR0cY4A3qR/JP489QFIcxBTVs65De+Bq3ecnujk6yeGpD9iptonq4Y8uNZMc1
+kOE7GiFGwR4EufT5SEMh+tUkjth2r+842vmZZuxrVQaohDiATmIJA07W51zKH+nQ
+uw4qVKnAhPaDLCLc7YMIH9JcmkeQX0nf8/S2O2WYDH8glVDi5hfW08tCmV647vRY
+nTIywUTO0lFpz7M+VyMNaJ6yXU6biBV5hLAI8C5ldr/SWI789W2+ebBaJ9gfK+PT
+trohFSK37GcoSH4V6qSLJHCBASEsiddqHIHMLJZRYD+B6J3tLhjVUM43u+MEGbFT
+d33ZDke/WzLTExWkaOv36e67gDBmgDuj9yroq3wGfwIDAQABMA0GCSqGSIb3DQEB
+BAUAA4IEAQCc9RBhRbuWlmRZPZkqIdi5/+enyjoMmOa6ryJPxFSP8D2jrlHgQsk1
++GsJmPFT3rwWfoGAQu/aeSX4sp8OhKVJtqNA6MJrGYnZIMolgYa1wZPbkjJsdEfi
+UsZdIB0n2+KA0xwEdGPdkGCfNPBtOg557DkcyEvsIZ9ELp4Pp2XzWRhyFGasJZc4
+YwgD/3K2rpOPZoMkBKeKqV19j41OfLKGBVyuaqzitbu9+KT4RU1ibr2a+UuFCwdT
+oqyN7bfWXjcjXOMkxCsOmLfKmqQxs7TEOVrYPTdYjamDxLy/e5g5FgoCxGY8iil0
++YFLZyH6eEx/Os9DlG/M3O1MeRD9U97CdsphbDVZIDyWw5xeX8qQHJe0KSprAgiG
+TLhTZHeyrKujQCQS1oFFmNy4gSqXt0j1/6/9T80j6HeyjiiYEaEQK9YLTAjRoA7W
+VN8wtHI5F3RlNOVQEJks/bjdlpLL3VhaWtfewGh/mXRGcow84cgcsejMexmhreHm
+JfTUl9+X1IFFxGq2/606A9ROQ7kN/s4rXu7/TiMODXI/kZijoWd2SCc7Z0YWoNo7
+IRKkmZtrsflJbObEuK2Jk59uqzSxyQOBId8qtbPo8qJJyHGV5GCp34g4x67BxJBo
+h1iyVMamBAS5Ip1ejghuROrB8Hit8NhAZApXju62btJeXLX+mQayXb/wC/IXNJJD
+83tXiLfZgs6GzLAq7+KW/64sZSvj87CPiNtxkvjchAvyr+fhbBXCrf4rlOjJE6SH
+Je2/Jon7uqijncARGLBeYUT0Aa6k1slpXuSKxDNt7EIkP21kDZ5/OJ0Y1u587KVB
+dEhuDgNf2/8ij7gAQBwBoZMe1DrwddrxgLLBlyHpAZetNYFZNT+Cs/OlpqI0Jm59
+kK9pX0BY4AGOd23XM3K/uLawdmf67kkftim7aVaqXFHPiWsJVtlzmidKvNSmbmZe
+dOmMXp6PBoqcdusFVUS7vjd3KAes5wUX/CaTyOOPRu0LMSnpwEnaL76IC9x4Jd6d
+7QqY/OFTjpPH8nP57LwouiT6MgSUCWGaOkPuBJ9w9sENSbbINpgJJ42iAe2kE+R7
+qEIvf/2ETCTseeQUqm2nWiSPLkNagEh6kojmEoKrGyrv3YjrSXSOY1a70tDVy43+
+ueQDQzNZm3Q7inpke2ZKvWyY0LQmLzP2te+tnNBcdLyKJx7emPRTuMUlEdK7cLbt
+V3Sy9IKtyAXqqd66fPFj4NhJygyncj8M6CSqhG5L0GhDbkA8UJ8yK/gfKm3h5xe2
+utULK5VMtAhQt6cVahO59A9t/OI17y45bmlIgdlEQISzVFe9ZbIUJW44zBfPx74k
+/w8pMRr8gEuRqpL2WdJiKGG6lhMHLVFo
-----END CERTIFICATE-----
diff --git a/mysql-test/std_data/server8k-key.pem b/mysql-test/std_data/server8k-key.pem
index faf4b43fa56..99e7417733e 100644
--- a/mysql-test/std_data/server8k-key.pem
+++ b/mysql-test/std_data/server8k-key.pem
@@ -1,99 +1,99 @@
-----BEGIN RSA PRIVATE KEY-----
-MIISKgIBAAKCBAEAyqodxBHskfDH/1+QkvxADF63PQDFINUPiTEH10FMi2CAqjgU
-3pNrnHSIQWi1AkEBLYaiepVTXntnL2weKVH5RP1KgL6yI6E+GzjPiMRx7vhrQcUt
-wMNSrFl9gTQZlTK4mlG2QTbUxKGuhOY4uei/lr4Zemt3TeDe5rO2a7w93Wi8S8Tr
-9TaT7VaiFVCKEOjWIu1ssc3DGMn2CuHeYWVi1hRBjLX7FGjBzxJdQSGdVxFDfbtD
-LCG7w0R9qM8fw3F1tUfCfc44PHNknhXYpyfPvUDIRQjjyDmoC47CW3vxR5ESkczh
-AOCUW70y5AyNw77MdjJSEmmwGOCwwnY0Wl952faBnQIKYWkcM85J+nYDHgdbJwu/
-NJ40lrgDm1A6ai8XehTPZWMAN1Koc85LFED00ppWVDO4dy5CW4/sHxj0rauKSo1t
-cCXzWOfLZlEUfRb0621WdnZRbtYd2tONwGRaZ06v4r8z0bj2KvxXh6c1XoDJrPyH
-yXEXkb+3TaPtPBsn9Gag+UYDJ8zqgPZLQPZBlM29CrPvJr7eb2muDz8cVWMzkJvt
-yloSTd5LBsKikrBCPTGvpBUSFfiK6YiNz/2FZlBvEfGfSPO1up2GaCSiXah8VEL6
-2LXF8t0OD9Bo5FR+xbmgm2Utd/SPuTAK1YZc7cl80dqdDWNQ7uUekmPMogzoSpYC
-TdyP33yPCBioMIjXr4mt/FdLEPnxy0jotjvIP/zC09FKEDwba2Tc5WUeW7LaseIk
-l4/uwEuOGIN8F6Y8RbNgBiPyLxgTnheKxnJ5jE0E853q4CXTM4weEUdjH6VFP72F
-s/6laO5ItwykyX9y0HVmm2r5oFDzqFlto904T3Aru/+SLnGr7+kA7Q3RtG/wjrIJ
-+01hDdkQ1VQRzQOUhP2oaORFbh5qHi+FoW31tsDx7vc26f7C963ME0ZbiELwLR+1
-Dn61K+SNq7mHMGo9EvSt8xyszBpIKSqWe4AAC25Zh7+jynCZGxz9cj2y05RKz1V1
-vh9A7FU1SC1V8ADaPLBguhEyZlQLvgakXrfJWbtN9JIGJkhuwhLUfPAguKLhvGq2
-GQ43R1XJ8kkNlnWihGS/NPy+skHk9Yjr4bcmpeVBwiAM9uKoped2VKX7S4AFfRiF
-erq8t63AL2CFzBUSHC8KnvN8QM/0PiPSlcrQBlhS8ITYDz3r/xJolHmPvkApX5jI
-kGwFL5mMKmN4HyOxKcXnScmykg9TC9VxKBfCGb9gv3yHqKvB9ArBuNJo7sHOpxMT
-F20kXaI3ptd9SIsrdC1ALsoZ1bY+bEJx+s+Fh/negHOLifRw8NjX/0BBnMcVbZtu
-TLVSApl5MnPKJqCsMW/EsPXau8If4J9EuiX3nwIDAQABAoIEAElnTjqq502AsV+c
-hGfId4ZDdAjjU4LtyJ+/I4DihM/ilxeQEnb/XDWhu4w9WXpEgyGzJvxRQ43wElKJ
-zW7X4voK58Yzy5++EhmX/QsjY8TTMz3yJf0wgawtCZkXfsCcS2KRf/qk2nGRwf0e
-yaMEWwhFOEMv01lgvjs/Ei55Usrz2Wd0HqaFKxUGkNQ5hJhVTOH/rqPDzAsZc0VD
-w+Dw8NhrI8bMTvF4c+IFW8NwYmWbuh87CTxdx30VPJI82ttWJ/UN1bLtU08J2IKt
-lPgOIl8ArMjcTGxD/cqZ3Wl3Pc/XCqvGUiSYMwP7Rgh1R4+DdtjEpxdGMmMAVuVI
-HPQyqpa4gv+UMqBPish0yjSuM7jXnztINOvg9Vk1sxC5AT9eaRltmiS1s+lVxe+T
-43ulf0ccYXJD/WclWSGCwloNFuokPIV+Lgo1pKsp4XDgoxQfkXwH8Q4dEqebY9rT
-Tv9FGb1bMbdl22X1oSu2lBltBZaB/QnruV7L2GaQ0tqLKizgBRuvZFSE+DWdMb6d
-9mnEB8LWtca/nzogXb5qv4GEMUX4FUAmSf1FnGWZwwDi1DFfJ860RVKf0xokGGQ3
-cm3H/F4veds88Z1hsAu0bG8h/bEAim+Whvag995cFHDD4on41KXW8wX1on9VFA1W
-CkaGUPhLRytXDBVCSJkOYYFSJlb2wqONiWe4Tn5hsantCfliTj/GVkgDq2h7dAGR
-WyoqTntJAv/xJsUOV9WmGXnWNeZX8BSO3P5dnXnMzhCWQGoprXmWFyJ3TYCJ2+CO
-rzkZbtuKvTvGc3sDJgrSVmmg0BrOkH+GyYVlJdTDBmfzoORludDCFHECa8oK7NwY
-t3o0eNlG6IqTxl2HIoPneW9nXFQtCXv6tpJjljwjlz5WpJG+kBW6bDedcxZu7olZ
-fqtnyZTB2SjzzbGdQ4JvFup8MxNyPvYiqumQXJgkyXFVDl/UFhjWuGe04i8NBJgJ
-xORcjfgLrKH1XKVBWPJdh/2YeUKIIvQ9RB4WVqXgGmD/21tgv1bVEMYabh23e/HE
-Fe1U2XQPJKxGCEtG6b4zhFP+PeZACS+Vk5IVJYK9n4SepPBPgX/wbJLOcKGpsKjp
-yx5WjopMO6T+VUV8HIduuZ+E8+uAILHDmo2Bq+LHblaxd4SkM0+hL2H36imK5CUO
-5fLuvHW88LvFtQw6xhP20s+BnmgzE5ZvNG4Iedkjvwe9HmdNDew0UYT5vNJN0ehh
-OlraBC++JYwEclrBD9SRvprT63XKDG735pPvzLQi7WKDCBn1/JEgxDIO8nkMewOZ
-FU48Mdmkn9wqPeIigQciwl62fuAQCGRG+RXMQqra4A1apqMZQEauTK50VhHDGdbc
-ye9LHaECggIBAO9lAzoYS/Lu0ticMt24P8BSbGdxSNIpEyIlTTs+7A0UjpfXsoK9
-4EJWZ7lhgbQh+SCTS662SeC+s8M6bT+3mELxUC5S/N3aCPyfjcM3JaoACkI9+VMn
-9otJZjAEwH7cNpMN0Xa8fHCEma3l3XKiVxEJbuJC86S5mpkjeXVnDajAidBtevBd
-LWJ9n2yXk+ZKUyI0mjpqItwUxOgQ/MOIvqAu66xyjg08/I1QQTuIrReAA+oaVKhp
-c42Ufn26hUhNrQCBAtMAO3VC/chciet6vEMNEM13GqLp4+PcPhRX90gO4+bNrScD
-WgiW/jc24CGan8gAenBWC/3l/C6JUsMp+ZYmPozsa0zo6edgiO/f2KXe5nP87wZT
-MxaYJgnyXJxMefI79kUHPrhpXZxuiSCEWLhCBN34Lhpr2L491i2g/FJj9i6N3EzE
-N3ic5Q63o4QFusjqIm3taQQFoGP2Cgg9owz5WJ0uRz/gtOE3XQiQA7+ozoAXOlTw
-pJK5MMtVrEoOLIbVJIpxfDcKDp3yorR8QCQLHgDBmFeNCDmk+7YP33dRIc/AVNLF
-q7cecqEc7D8AkXX8Q53GfCEg+uqbdeMQXK4BUE9iwRK9RiFhas/RJe73+Iio3S0L
-ekLpnnOfvk744ws+JWsLpsfC/ZE7OxBLPtq2xvGl/RT2G7tCjmpX3CbPAoICAQDY
-uOEJks2T105EcMPJjzNHCCqjK6S7qZaWkF3KT1Z0Mu5oUZwwHamsMg4BQJ2mjMrL
-fRBKfXQLA6vgE7zysw3F300RDxE1RVow5+JLDQ4bqupp27/M0a8fuwksyOdKHqCV
-YHzuTCxbVIFZawTjfOxJVXDHKCFCilfY1LsA+V+oFe3Ej8YYxWXkXA9ZLigpmt3s
-Wu6eFcZgF3utzIGjI6eP6lL5bWp6Bh9Avp2xrOvpFwE2m02Y7/Zom6MT4DXvByY2
-KHHQLsasEMpeLuxQXjLeTocwcxBwBFKhX95yFuv31k00VydT+NExtaZeUYi9l19J
-WmM4GjFjAqa3uUwMNVv5JfWtKMyk4FOox2XftLvMiIhV95B8hAGxtYr3hPkGg80O
-AWPq6OKUD332COXRaHkmL5aQdN3gP5zh9+rH6icLrrZbrQidVRyDw03doRoGrH7i
-ixXLyYoW80PHgqUDPohd5bFkZpi2vwXMl1YQ2TfN9TvYFSGme9YCm9ZuypnqauW/
-aAf0FI1MNwS+XDREtzPdFi0me6WxpKL4a2Z3GGNxIFuBjQ/uydWpjxkny9qI3KAp
-SgjI3kBUDGq3gf0R+Xo/d4d/4asK9Nv2Fi0X+RfGqioFaTbQl/1zhNdvhP9IcwEJ
-DLVQ3UhMdfg285RarC2Sihui0M8Smi9od9Dj6rdWMQKCAgEAiQVRFoRnnDGz/wVQ
-W/Wkj6jdoUuG+btG10lwbhOyuj3k6+Yqp4iUfoPENKgpu/eiB1InhGWT3Y5ph7m+
-ZDTqco56bTlUwIqWkDmmw3CiHy6MsKOWPFFoXQry8VMW9sWGex7yoDp8I07SQ2WJ
-HZ7rpLW4gMr/d25AnZxfXaJRgCBMAT9YmZFLc88hW99aaPproO1oxTyQnVVJ6uYm
-NqjjKv4QKJEc21jn2N5xp+iv4f6Evw65G/fXitbOm5oRxXOoLNyqyCie35wrc+37
-hwumC97DmkasuUiUBoy9/5jl0ZmsOiPJEsZpVvdNpD7FhJZjE++qJPgrPvTPJbe1
-5jz1PUrAjJqZQ9kgYC2x01JVR4NQdlz0VrNyT2FgjFrrRQ7E0bAeYh4meRjd2rat
-yC3YNgabkI0HnlnSIfl0yIMXSPUsKDNMP6gjc+aheI4FioBZC7xvXmn/rKynw+9E
-iLj2xWtGnBir8VTlUu8EUe1UJ/Qv1cL1wT5HhC95TTjJN03rkHUYyCDyjvIzsZX6
-KMHhWIAAeUBVuO7hIVVcOTXWmw2WA7o7ErTPdy13QN40Hk9t8pEkBn9f9vpQg83d
-aMypr3LTC80jY11wcZS3tSEpzCCkYVv91FV4cioTZmytWbg9A+dbNWzi1f22ctTr
-FoVrAXaSYie2trOy5bjPmPCW8qMCggIBALQUKymBSkDmTqqf6I+65ajIKGWdBizJ
-Jc/F9aj9c6DqER+tcFKq0ym6DdkMj/KsWnXrXXYH+DyOuGpg/EfOcEtS2P6rvmi9
-T8wDYg1qs6ZZxp5fcmgGc7Wx/FWyOj1kZZq5qhV4RgM9nJ1oR4+fZdcpn6RcvAZG
-XehWG20byVgpoIAL11cN7zRpKne32rd3b5/NjyjcfxGpcaNgovej0L/MvVV0jV0H
-aUCrIu1X+k6cRu3Q7hF+kwkpCcCiNS6AikfGI4wQ0hR3fy/zXXkKTMpcBglEEwyB
-Cwf8WSID2d79uvka0hr8TRc5ERyeMzkWZp7U9EzRtufGdDGFTqN2Uw4bdKCFnkYC
-AIHl7ciMrN+vM1n7c5uDNMUtTGOPojy/l8tjbFrtWBgfJ1Mg4ZW3cbNBJ6Kw+Qw0
-z28USYoEDp2uduiGRvo0lpUF29Wk37Nb8bLcTygeNxgK2u8Up3iipT0gdt4uQgbX
-g0IVHfayB6SjeS57oJJto85XHz7AKlSWroD1OGagDSifLtneU7AlanryymGHrI6H
-dsNkuqeLJFYDxQVI6UxJebiCpyxiPxwp9wtX8SS3SEyOZL5GzLn6ypGiCH1CTpW0
-EHHSy3V4DUGOc4w7eMirAnbSkxCfOmBA70NNw/uFY2XlQHKow0T0fImfKIeJagbT
-B0GPDYvUpLKBAoICAQCzYnq8xupXK7lvTLaj936qGSe54OC2sj9+UpsFiPxglNY2
-sO5zKWKyY7+rjK6zG2ciGfPEDsZNIqKw1W/KBfR2kRLqkt4bC3fSCvUztx0vtGUe
-veXlqiwETdE7RJXoaGJrgJArYJvpOd8PtWGeM+sSJNNrUlGlJnSiZ0CcypqUZgZL
-WzGFfLOQYAXCykdB1iZkBqU2C5wktvCb9sVz6G3TmAwSKTENOWWZWmh+W0J4pZFV
-ZEyvsxViJRQbwxa0kC0F5J/UtWZknO79/ZFj1H4jiAR45EjWHE+UZAkFwG8BSl54
-EKOx7GDanuRILr0dtbyi4d31nCYXdjs3x2+1N3exw4oKQIvNuF54WoowbNPu0kEb
-G+7/kLwcJqRnSV4AiLuMz5aOte7JJSw5tzgZZlAQwJO7IDfrLqodivcXF5yirwiF
-dyBpzSDmupy/aTHnCpT+l0H96jRU2awxaeRHZUqZog8gMHsslNVZEFvUFDJ7AUN/
-yyfUzJYjH18pZt0hS7jNb1O7KxZCkWGMiEcxHkgF/UINab5qruNBVKOkJ5vqGhYi
-uNkgeGsQtXJcpqMRRiVXJE0kE+26gk+iaYnBJN9jnwy8OEAlYFUHsbCPObe/vPMQ
-3RLl+ZoKdFkN/gTiy70wUTRVw+tWk+iAZc7GPX1CqDFOqGZ2t+xdF8hpsMtEww==
+MIISKQIBAAKCBAEA6h3v1OWb9I9U/Z8diBu/xYGS8NCTD3ZESboHxVI2qSECPgxN
+NcG8Lh0ktQdgYcOe64MnDTZX0Bibm47hoDldrAlTSffFxQhylqBBoXxDF+LrhXIq
+Cz7K0PsK+bYusL9ezJ7PETDnCT7oy95q4GXbKsutbNsm9if4ZE41gs2KnoU2DA7k
+vMmkKojrMIL4+BqTXA20LLo0iSbgvUTvpSJw4u96BeyzMNnxK2wP5vvTtUo5hACb
+fU87YjaSKs+q2VXCzfyYGZk1L1xk5GUI0bP+jutf1dDzNttW2/q2Nf5rxx09Gh/G
+wmOnEk1O7cOZ8VQCsOHirIM39NuSARsY6Y3G5XM4k2W4nxyR/RtdG9bvs/33aGsZ
+5V5yp7WSs8s9HHwaCPSsUiLKckQ7uA0TTRgbeweMrrLKovG57jsbBBB8pQD4PRd3
+1qgxCdstWXHiWwRyI8vOLWENPXPFqA/rJwwqNdWTogy38aqVXxGYR8PIwjA2OaIw
+FjwGZcsPNLqw6bgAN8O2UBqZHWiMF8mi7brvioDvAIufZuqa2SqT/At45H83psQ6
+R4FsxZt6SAK7EsdPo8OYTrY1i4iPZd/eKhnEu2srEZgsKRwY5H1mvDH5fWCcHSFu
+07sWmlmK6Or65Fsa0IaKLJiQDVVETd6xrI0wkM4AOcbKDrS7aywJ426dopbs+LFd
+t4N0cdII4gBgJAfLuuA2yrDXRq4P6cgpVMy0R+0dEYE8zzm8zf1a+Ud273LS9+LB
++LJKwqbW8nOPBoiekimIKfJYoOA4+C/mAjsYl1sVjjEhXJAs9S9L2UvnUk1PsZi4
+UKHI6eAIEl7VM1sQ4GbdZ0px2dF2Ax7pGkhD+DLpYyYkCprharKZdmuUNLUdNhXx
+i/HSEiE+Uy+o8RIzmH7LuROl/ZgnfHjJEiBLt2qPvwrwYd4c3XuXWs4YsWfVJTt8
+Mx2ihgVcdGy9//shCSmgJwR1oWrhgC10AEL2fKeRnYUal1i+IxFPp7nb8uwxUADg
+R0cY4A3qR/JP489QFIcxBTVs65De+Bq3ecnujk6yeGpD9iptonq4Y8uNZMc1kOE7
+GiFGwR4EufT5SEMh+tUkjth2r+842vmZZuxrVQaohDiATmIJA07W51zKH+nQuw4q
+VKnAhPaDLCLc7YMIH9JcmkeQX0nf8/S2O2WYDH8glVDi5hfW08tCmV647vRYnTIy
+wUTO0lFpz7M+VyMNaJ6yXU6biBV5hLAI8C5ldr/SWI789W2+ebBaJ9gfK+PTtroh
+FSK37GcoSH4V6qSLJHCBASEsiddqHIHMLJZRYD+B6J3tLhjVUM43u+MEGbFTd33Z
+Dke/WzLTExWkaOv36e67gDBmgDuj9yroq3wGfwIDAQABAoIEAQCSt6YoZqigz/50
+XvYT6Uf6T6S1lBDFXNmY1qOuDkLBJTWRiwYMDViQEaWCaZgGTKDYeT3M8uR/Phyu
+lRFi5vCEMufmcAeZ3hxptw7KU+R8ILJ207/zgit6YglTys9h5txTIack39+6FJmx
+wbZ64HpETJZnpMO6+fuZaMXyLjuT8mmXjvHcOgXOvjWeFkZOveDhjJkAesUXuqyX
+EI+ajoXuQiPXeKonkD2qd7NTjzfy4gw/ZF4NXs0ZVJeviqtIPo2xp33udOw2vRFh
+bMvlF4cNLAbIKYVyOG0ruOfd2I7Unsc/CvD1u5vlRVuUd8OO0JZLIZR7hlRX+A58
+8O1g2H/wJZAsF1BnLnFzDGYCX2WjCCK3Zn85FkKGRa0lTdYDduad/C/N3Y2/pHFE
+e7U/2D7IkEei59tD2HcsDBB3MJnckkn/hyiL9qWcxqWZ61vurE+XjU6tc6fnfhk9
+pJQ6yU3epPU7Vfsk0UGA7bbgKpsyzyH8Zl76YC2mN2ZVJjZekfhY+ibT9odEPdOl
+yLB5iXA6/WhKkDWaOqZGOH+7MblWgT9wHINlcn+nKzOr00JHl26ac6aMlXXi9vbe
+4jgJbFK1HYlFIndyX/BdqRTsFemDoDrVqrEYsaONoVYDd9c5qrqYOeh34DhOksQW
+hNwWBfmMlfzgOGtCYhMeK+AajqTtUbMYQA6qp47KJd/Oa5Dvi3ZCpvZh3Ll5iIau
+rqCtmojsWCqmpWSu7P+Wu4+O3XkUMPdQUuQ5rJFESEBB3yEJcxqk/RItTcKNElNC
+PASrPrMD9cli7S/pJ+frbhu1Gna1ArXzXQE9pMozPaBpjCig7+15R0lL3pmOKO6e
+WK3dgSwrnW6TQdLPlSD4lbRoiIdTHVBczztDeUqVvFiV3/cuaEi1nvaVdAYLqjuL
+ogK4HwE/FQ54S0ijAsP52n25usoH6OTU3bSd/7NTp0vZCy3yf10x7HUdsh2DvhRO
+3+TSK5t0yz0Nt7hNwcI6pLmWUIYcZgpFc/WsiiGscTfhy8rh3kRHI8ylGq53KNF+
+yCVmjqnBRWs91ArxmeF1ctX2t3w5p7gf65hJWqoX/2DiSi5FBsr6HLxa5sUi4wRZ
+136aCNt5Wu7w+AzPDbQW6qKUGSyfHJAw4JZasZcaZLise5IWb1ks0DtFbWWdT3ux
+8r2AM7IO1WopnekrYCnx/aBvBAv4NjWozVA517ztVttPERt3AGb4nm387nYt5R2U
+NO2GBWcDyT8JQLKmffE1AkWolCR1GsvcNLQfLCbnNppgsnsLE/viTG4mq1wjnd8O
+2Q8nH1SVTuyGFREMp/zsiAEaGfdd0hI2r1J7OdNPBBCtmhITsy9ZYHqm5vrGvy3s
+vi2GuB2RAoICAQD/oWUsg4eTJxHifTJLz/tVSTXnw7DhfbFVa1K1rUV63/MRQAFW
+pabN4T6Yfp3CpdRkljCA8KPJZj7euwhm4OEg1ulpOouA+cfWlE9RFE8wyOK5SYwM
+k+nk31P9MUC866pZg/ghzBGDub91OW1+ZGEtqnLI/n/LhiAIWt0hJvgZclTc1cAL
+xffHVlFwoSyNl/nc3ueZCC95nOLst2XcuxZLLbOFtZCmDYsp49q/Jn6EFjn4Ge2o
+qp38z6eZgDMP1F4lb9nDqXPHfUSt2jxKlmpfXS+IPKdba67+EjhbtmUYzaR4EoPI
+zh+o6SrVWT6Yve7KGiYv06fuRz1m/lLQO/Arbd9ntSjgn+ZEXGOkbhnHUX3DJ4ny
+/6XEGB9NLQjern4uNTn0AaV+uvhncapFMaIBnVfq0Cw8eog0136PBYRaVX7T44j5
+HwIyGXWtYGA/SzDEQoksD0Y/T61BEGnLZaKeavNd82WwFvcYHZtE0J4aQGjCEE7N
++nijzCy+j5ETmme9KJvQHpEyXP3N4RBko1eWvyTwFZDdIXtoa6TTEI51lm+FXJ/b
+Y+BzMr6KRo29FB+7//1ptUoMvn5hzL0PwOv2ZSTQuoG5hLDEbxWXLNhd1VHcfznF
+3EZHwfD2F8aGQ3kz+fkMTNfK955KorDrmLgvmV9eZZ5yQxGZrs5H5YfKpwKCAgEA
+6nSUbzfSdVFUH89NM5FmEJgkD06vqCgHl2mpyF+VmDGcay4K06eA4QbRO5kns13+
+n6PcBl/YVW/rNE8iFi+WxfqUpAjdR1HlShvTuTRVqtFTfuN8XhbYU6VMjKyuE0kd
+LKe3KRdwubjVNhXRZLBknU+3Y/4hnIR7mcE3/M5Zv5hjb7XnwWg/SzxV9WojCKiu
+vQ7cXhH5/o7EuKcl1d6vueGhWsRylCG9RimwgViR2H7zD9kpkOc0nNym9cSpb0Gv
+Lui4cf/fVwIt2HfNEGBjbM/83e2MH6b8Xp1fFAy0aXCdRtOo4LVOzJVAxn5dERMX
+4JJ4d5cSFbssDN1bITOKzuytfBqRIQGNkOfizgQNWUiaFI0MhEN/icymjm1ybOIh
+Gc9tzqKI4wP2X9g+u3+Oof1QaBcZ4UbZEU9ITN87Pa6XVJmpNx7A81BafWoEPFeE
+ahoO4XDwlHZazDuSlOseEShxXcVwaIiqySy7OBEPBVuYdEd2Qw/z3JTx9Kw8MKnf
+hu+ar5tz5dPnJIsvLeYCcJDe/K6loiZuHTtPbWEy9p6It7qubQNPBvTSBN5eVDKc
+Q2bTQNCx8SAAA9C5gJiwWoQKsXJzbRFRY77P9JjuGpua3YJ2nYBHEJmF+fp1R33c
+uHIyMphPMkKC4GC3/43kkMr6tck8kZbXGSYsLsBr2GkCggIBAJvvrjILQianzKcm
+zAmnI6AQ+ssYesvyyrxaraeZvSqJdlLtgmOCxVANuQt5IW9djUSWwZvGL4Np1aw0
+15k6UNqhftzsE7FnrVneOsww4WXXBUcV8FKz4Bf3i9qFswILmGzmrfSf8YczRfGS
+SJKzVPxwX3jwlrBmbx/pnb7dcLbFIbNcyLvl1ZJJu4BDMVRmgssTRp/5eExtQZg4
+//A4SA8wH7TO3yAMXvn8vrGgH8kfbdlEp88d1SYk3g4rP/rGB3A63NIYikIEzmJn
+ICQ3wUfPJnGq3kRMWgEuyCZaCy2oNE3yrWVPJ8z3/2MJ/79ZDVNHxEeki2o1FuW+
++nGAPq+fZIp03iy4HdVRro7dgugtc9QaSHJtNId8V4vSjviX5Oz3FxUb9AJst58S
+nVV8Q2FMxBa/SlzSOkhRtCg2q1gXkzhaMnIVUleRZFGQ2uWBToxKMjcoUifIyN1J
+z999bkfI4hBLq5pRSAXz+YVu5SMKa10GaawIwJLat+i+1zboF6QyI2o/Wz8nrsNq
+KX/ajFGu5C94WFgsVoWKNI90KBLe48Ssje9c68waBlV/WHMg1YLvU3yqVDOV+K5c
+IHB9tPMnG+AgBYZPxSzuvnLrrkj/GeKx0WI7TrvzOLRGKJo6irMEJ8IzFegASRUq
+TVZKYQDYRG7m+lKlSxU+pyMAh2c9AoICAE4kavCip1eIssQjYLTGSkFPo/0iGbOv
+G9CgXAE3snFWX67tWphupKrbjdMSWcQTmPD2OTg6q6zWL4twsIi6dcMooHAHsFC7
+//LyUV/SDJdxSyXohiQJ8zH1zwy35RDydnHSuF5OvLh53T44iWDI1dAEqLgAFI3J
+LjTxzEpLMGiGTuYFt+ejai0WQAQayvBw4ESM9m+4CB2K0hBFTXv5y5HlnNTW0uWC
+VUZUUMrbjUieDz8B/zOXi9aYSGFzmZFGUDAPSqJcSMEELemPDF7f8WNr8vi42tIV
+4tlaFD1nep4F9bWMiCXU6B2RxVQi+7vcJEIqL1KUnGd3ydfD00K+ng4Xnj7Vz/cz
+QE7CqrpFaXmPlCMzW6+dm51/AyhHXDLkL2od05hiXcNkJ7KMLWRqwExHVIxM3shR
+x7lYNl3ArUsCrNd6m4aOjnrKFk7kjeLavHxskPccoGKrC9o0JMfTkWLgmuBJFQ0S
+N/HzIbcvIFWF0Ms4ojb50yp6ziXhXfJOO/0KUQEki71XIhvw89mVZszDzD5lqzjf
+HCZMBU4MbmL6NdEevFIDH0zPPkx3HPNtJt3kIJbit9wI8VhUMe+ldGnGxpWb8tKw
+SfM3vrHkYr+lizk26XfXMFhdAuVtT7dzQKSNEyP/1a2Hs307Xzgiv8JulJ8QIkrX
+/nsYWPOAGLG5AoICABmdW9Ppkvuhb1AEcjTWb+XCyopoBc6vit/uQWD9uO+CeX7a
+cfzq+iH01CAjyVMc4E1JDc5Lpi106U+GRGcAAaPJB2Sp5NznoxaOVrb71blu4Q4x
+bNjtKM/P/DXpO+yJYoOPdKtaSDhtnfNDM7H/jztJ3XIrOltKA7CcRDohbBWIx8Q0
+0uEpvfFpZZBco3yVmjP0RLgIVYn/ZDj9wGhSvFWIJ5vv6GXmtDrcHGMLxcfv7t76
+UVcMW/Yy4mYJRCzGOrWagyVijJ6MTVNciqadWcH1KcbB3EGoMFYMn61or2qJABPM
+xz89IlhnROU1Re3X/QRx5t86cw6oa+FqrWMOhSs31I0dNWSuS/xDympG27YIYSDd
+mv5seT78GjFmMJC5pPOLoXsbTPB0HpsX2/UL/w/eRAfilTOef/Cf9VE5MP/C2YR7
+NBxUU7/+21D6WvdtBTcZbrXWGroAo8zPP+PwX0+c6WoAvqDJvCPndp8xZhSgEJN/
+0kScptezi8n3ZHI95EA9U5mAHxHz0IhDDVzWw/z1f1SBPxKVX3+By3zaa3lrD2ch
+cHq7nBkX72veEevnHUY8Z2rHE2G2jdmRfOtwm4sjL0VBV9fRRoxzJWRduKyeOtDL
+EhhBhUoTrT48UnfW9hxnbNLB9P/hh+UJu9HrS2uAwHoGE1+8gcyundupGDBn
-----END RSA PRIVATE KEY-----
diff --git a/mysql-test/suite/binlog/t/binlog_row_binlog.test b/mysql-test/suite/binlog/t/binlog_row_binlog.test
index 8adc8eee5c1..2bf4f93f332 100644
--- a/mysql-test/suite/binlog/t/binlog_row_binlog.test
+++ b/mysql-test/suite/binlog/t/binlog_row_binlog.test
@@ -2,4 +2,6 @@
# For both statement and row based bin logs 9/19/2005 [jbm]
-- source include/have_binlog_format_row.inc
--- source extra/binlog_tests/binlog.test
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
+--source extra/binlog_tests/binlog.test
diff --git a/mysql-test/suite/binlog/t/binlog_stm_binlog.test b/mysql-test/suite/binlog/t/binlog_stm_binlog.test
index f5257f21434..682b0a3bfa7 100644
--- a/mysql-test/suite/binlog/t/binlog_stm_binlog.test
+++ b/mysql-test/suite/binlog/t/binlog_stm_binlog.test
@@ -1,5 +1,7 @@
-- source include/not_embedded.inc
-- source include/have_binlog_format_mixed.inc
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
--disable_warnings
drop table if exists t1;
diff --git a/mysql-test/suite/federated/federated_innodb-slave.opt b/mysql-test/suite/federated/federated_innodb-slave.opt
deleted file mode 100644
index 48457b17309..00000000000
--- a/mysql-test/suite/federated/federated_innodb-slave.opt
+++ /dev/null
@@ -1 +0,0 @@
---loose-innodb
diff --git a/mysql-test/suite/federated/federated_transactions-slave.opt b/mysql-test/suite/federated/federated_transactions-slave.opt
deleted file mode 100644
index 48457b17309..00000000000
--- a/mysql-test/suite/federated/federated_transactions-slave.opt
+++ /dev/null
@@ -1 +0,0 @@
---loose-innodb
diff --git a/mysql-test/suite/federated/my.cnf b/mysql-test/suite/federated/my.cnf
index 7556abad300..3962c2aca77 100644
--- a/mysql-test/suite/federated/my.cnf
+++ b/mysql-test/suite/federated/my.cnf
@@ -3,10 +3,8 @@
[mysqld.1]
log-bin= master-bin
-loose-federated
[mysqld.2]
-loose-federated
[ENV]
MASTER_MYPORT= @mysqld.1.port
diff --git a/mysql-test/suite/federated/suite.opt b/mysql-test/suite/federated/suite.opt
new file mode 100644
index 00000000000..2cce1887441
--- /dev/null
+++ b/mysql-test/suite/federated/suite.opt
@@ -0,0 +1,2 @@
+--federated
+--plugin-load=$HA_FEDERATEDX_SO
diff --git a/mysql-test/suite/funcs_1/r/is_basics_mixed.result b/mysql-test/suite/funcs_1/r/is_basics_mixed.result
index 2ae4f96c400..d20e5750403 100644
--- a/mysql-test/suite/funcs_1/r/is_basics_mixed.result
+++ b/mysql-test/suite/funcs_1/r/is_basics_mixed.result
@@ -328,7 +328,7 @@ ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_
SELECT table_schema,table_name FROM information_schema.tables
WHERE table_schema = 'information_schema' AND table_name = 'tables';
table_schema table_name
-information_schema tables
+information_schema TABLES
SELECT * FROM information_schema.table_privileges
WHERE table_schema = 'information_schema';
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
diff --git a/mysql-test/suite/funcs_1/r/is_columns_innodb.result b/mysql-test/suite/funcs_1/r/is_columns_innodb.result
index 73a74e4d7a2..61079b06666 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_innodb.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_innodb.result
@@ -450,9 +450,9 @@ NULL test tb1 f27 27 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zero
NULL test tb1 f28 28 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
NULL test tb1 f29 29 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
NULL test tb1 f3 3 NULL YES char 0 0 NULL NULL latin1 latin1_swedish_ci char(0) select,insert,update,references
-NULL test tb1 f30 30 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb1 f31 31 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb1 f32 32 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f30 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb1 f31 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f32 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
NULL test tb1 f33 33 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
NULL test tb1 f34 34 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
NULL test tb1 f35 35 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
@@ -565,9 +565,9 @@ NULL test tb3 f143 26 99999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned s
NULL test tb3 f144 27 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
NULL test tb3 f145 28 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
NULL test tb3 f146 29 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
-NULL test tb3 f147 30 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f147 30 999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
NULL test tb3 f150 33 1000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
NULL test tb3 f151 34 999 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
NULL test tb3 f152 35 0000001000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
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 89c0d29016f..d96e636dda2 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result
@@ -38,8 +38,8 @@ NULL information_schema COLLATIONS IS_DEFAULT 4 NO varchar 3 9 NULL NULL utf8 u
NULL information_schema COLLATIONS SORTLEN 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(3) select
NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME 1 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema COLUMNS CHARACTER_MAXIMUM_LENGTH 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema COLUMNS CHARACTER_OCTET_LENGTH 10 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS CHARACTER_MAXIMUM_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS CHARACTER_OCTET_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema COLUMNS CHARACTER_SET_NAME 13 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
NULL information_schema COLUMNS COLLATION_NAME 14 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
NULL information_schema COLUMNS COLUMN_COMMENT 19 NO varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255) select
@@ -50,9 +50,9 @@ NULL information_schema COLUMNS COLUMN_TYPE 15 NULL NO longtext 4294967295 42949
NULL information_schema COLUMNS DATA_TYPE 8 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema COLUMNS EXTRA 17 NO varchar 27 81 NULL NULL utf8 utf8_general_ci varchar(27) select
NULL information_schema COLUMNS IS_NULLABLE 7 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select
-NULL information_schema COLUMNS NUMERIC_PRECISION 11 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema COLUMNS NUMERIC_SCALE 12 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema COLUMNS ORDINAL_POSITION 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS NUMERIC_PRECISION 11 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS NUMERIC_SCALE 12 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema COLUMNS ORDINAL_POSITION 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema COLUMNS PRIVILEGES 18 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
NULL information_schema COLUMNS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
NULL information_schema COLUMNS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
@@ -94,14 +94,14 @@ NULL information_schema EVENTS SQL_MODE 12 NO varchar 8192 24576 NULL NULL utf8
NULL information_schema EVENTS STARTS 13 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
NULL information_schema EVENTS STATUS 15 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
NULL information_schema EVENTS TIME_ZONE 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES AUTOEXTEND_SIZE 19 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES AVG_ROW_LENGTH 28 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES CHECKSUM 36 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES AUTOEXTEND_SIZE 19 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES AVG_ROW_LENGTH 28 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES CHECKSUM 36 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema FILES CHECK_TIME 35 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
NULL information_schema FILES CREATE_TIME 33 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
NULL information_schema FILES CREATION_TIME 20 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema FILES DATA_FREE 32 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES DATA_LENGTH 29 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES DATA_FREE 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES DATA_LENGTH 29 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema FILES DELETED_ROWS 12 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
NULL information_schema FILES ENGINE 10 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema FILES EXTENT_SIZE 16 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4) select
@@ -111,27 +111,27 @@ NULL information_schema FILES FILE_NAME 2 NULL YES varchar 64 192 NULL NULL utf8
NULL information_schema FILES FILE_TYPE 3 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select
NULL information_schema FILES FREE_EXTENTS 14 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
NULL information_schema FILES FULLTEXT_KEYS 11 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES INDEX_LENGTH 31 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES INITIAL_SIZE 17 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES INDEX_LENGTH 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES INITIAL_SIZE 17 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema FILES LAST_ACCESS_TIME 22 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
NULL information_schema FILES LAST_UPDATE_TIME 21 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
NULL information_schema FILES LOGFILE_GROUP_NAME 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema FILES LOGFILE_GROUP_NUMBER 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
-NULL information_schema FILES MAXIMUM_SIZE 18 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema FILES MAX_DATA_LENGTH 30 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES MAXIMUM_SIZE 18 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES MAX_DATA_LENGTH 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema FILES RECOVER_TIME 23 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
NULL information_schema FILES ROW_FORMAT 26 NULL YES varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select
NULL information_schema FILES STATUS 37 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select
NULL information_schema FILES TABLESPACE_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema FILES TABLE_CATALOG 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema FILES TABLE_NAME 7 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema FILES TABLE_ROWS 27 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES TABLE_ROWS 27 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema FILES TABLE_SCHEMA 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema FILES TOTAL_EXTENTS 15 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
NULL information_schema FILES TRANSACTION_COUNTER 24 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
NULL information_schema FILES UPDATE_COUNT 13 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select
NULL information_schema FILES UPDATE_TIME 34 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema FILES VERSION 25 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema FILES VERSION 25 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema GLOBAL_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
NULL information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
@@ -140,35 +140,33 @@ NULL information_schema INDEX_STATISTICS INDEX_NAME 3 NO varchar 192 576 NULL N
NULL information_schema INDEX_STATISTICS ROWS_READ 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) select
NULL information_schema INDEX_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
NULL information_schema INDEX_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_BUFFER_POOL_PAGES fix_count 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES flush_type 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES lru_position 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES page_no 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES fix_count 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES flush_type 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES lru_position 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_BUFFER_POOL_PAGES page_type 1 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema INNODB_BUFFER_POOL_PAGES space_id 2 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB compressed 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB fix_count 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB flush_type 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB lru_position 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB next_page_no 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB page_no 2 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB part_len 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB space_id 1 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX access_time 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX data_size 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX dirty 11 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX fix_count 14 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX flush_type 15 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX hashed 8 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_name 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX lru_position 13 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX modified 10 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX n_recs 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX old 12 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX page_no 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX schema_name 1 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX space_id 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX table_name 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
+NULL information_schema INNODB_BUFFER_POOL_PAGES space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB compressed 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB fix_count 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB flush_type 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB lru_position 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB next_page_no 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB page_no 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB part_len 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB space_id 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX access_time 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX data_size 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX dirty 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX fix_count 12 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX flush_type 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX hashed 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_id 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX lru_position 11 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX modified 8 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX n_recs 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX old 10 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_CMP compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL int(11) select
NULL information_schema INNODB_CMP compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL int(11) select
NULL information_schema INNODB_CMP compress_time 4 0 NO int NULL NULL 10 0 NULL NULL int(11) select
@@ -191,10 +189,10 @@ NULL information_schema INNODB_CMP_RESET compress_time 4 0 NO int NULL NULL 10 0
NULL information_schema INNODB_CMP_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL int(5) select
NULL information_schema INNODB_CMP_RESET uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL int(11) select
NULL information_schema INNODB_CMP_RESET uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL int(11) select
-NULL information_schema INNODB_INDEX_STATS fields 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_INDEX_STATS fields 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_INDEX_STATS index_name 3 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_INDEX_STATS index_size 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_INDEX_STATS leaf_pages 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_INDEX_STATS index_size 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_INDEX_STATS leaf_pages 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_INDEX_STATS row_per_keys 5 NO varchar 256 768 NULL NULL utf8 utf8_general_ci varchar(256) select
NULL information_schema INNODB_INDEX_STATS table_name 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
NULL information_schema INNODB_INDEX_STATS table_schema 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
@@ -202,9 +200,9 @@ NULL information_schema INNODB_LOCKS lock_data 10 NULL YES varchar 8192 24576 NU
NULL information_schema INNODB_LOCKS lock_id 1 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
NULL information_schema INNODB_LOCKS lock_index 6 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
NULL information_schema INNODB_LOCKS lock_mode 3 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
-NULL information_schema INNODB_LOCKS lock_page 8 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_LOCKS lock_rec 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_LOCKS lock_space 7 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_LOCKS lock_page 8 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_LOCKS lock_rec 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_LOCKS lock_space 7 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_LOCKS lock_table 5 NO varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
NULL information_schema INNODB_LOCKS lock_trx_id 2 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
NULL information_schema INNODB_LOCKS lock_type 4 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
@@ -212,36 +210,39 @@ NULL information_schema INNODB_LOCK_WAITS blocking_lock_id 4 NO varchar 81 243
NULL information_schema INNODB_LOCK_WAITS blocking_trx_id 3 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
NULL information_schema INNODB_LOCK_WAITS requested_lock_id 2 NO varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
NULL information_schema INNODB_LOCK_WAITS requesting_trx_id 1 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
-NULL information_schema INNODB_RSEG curr_size 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_RSEG max_size 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_RSEG page_no 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_RSEG rseg_id 1 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_RSEG space_id 2 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_RSEG zip_size 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES ID 2 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG curr_size 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG max_size 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG page_no 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG rseg_id 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_RSEG zip_size 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES ID 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_SYS_INDEXES NAME 3 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_SYS_INDEXES N_FIELDS 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES PAGE_NO 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES SPACE 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES TABLE_ID 1 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_INDEXES TYPE 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES N_FIELDS 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES PAGE_NO 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES SPACE 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES TABLE_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_INDEXES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_STATS DIFF_VALS 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_STATS INDEX_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_STATS KEY_COLS 2 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_SYS_TABLES CLUSTER_NAME 8 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_SYS_TABLES ID 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_TABLES MIX_ID 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_TABLES MIX_LEN 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES ID 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES MIX_ID 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES MIX_LEN 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_SYS_TABLES NAME 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_SYS_TABLES N_COLS 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES N_COLS 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_SYS_TABLES SCHEMA 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
-NULL information_schema INNODB_SYS_TABLES SPACE 9 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_SYS_TABLES TYPE 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_TABLE_STATS clust_size 4 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_TABLE_STATS modified 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_TABLE_STATS other_size 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema INNODB_TABLE_STATS rows 3 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES SPACE 9 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_SYS_TABLES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TABLE_STATS clust_size 4 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TABLE_STATS modified 6 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TABLE_STATS other_size 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TABLE_STATS rows 3 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_TABLE_STATS table_name 2 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
NULL information_schema INNODB_TABLE_STATS table_schema 1 NO varchar 192 576 NULL NULL utf8 utf8_general_ci varchar(192) select
NULL information_schema INNODB_TRX trx_id 1 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select
-NULL information_schema INNODB_TRX trx_mysql_thread_id 7 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema INNODB_TRX trx_mysql_thread_id 7 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema INNODB_TRX trx_query 8 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select
NULL information_schema INNODB_TRX trx_requested_lock_id 4 NULL YES varchar 81 243 NULL NULL utf8 utf8_general_ci varchar(81) select
NULL information_schema INNODB_TRX trx_started 3 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL NULL NULL datetime select
@@ -272,29 +273,29 @@ NULL information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_SCHEMA 10 NULL YES var
NULL information_schema KEY_COLUMN_USAGE TABLE_CATALOG 4 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
NULL information_schema KEY_COLUMN_USAGE TABLE_NAME 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema KEY_COLUMN_USAGE TABLE_SCHEMA 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PARTITIONS AVG_ROW_LENGTH 14 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS CHECKSUM 22 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS AVG_ROW_LENGTH 14 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS CHECKSUM 22 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema PARTITIONS CHECK_TIME 21 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
NULL information_schema PARTITIONS CREATE_TIME 19 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema PARTITIONS DATA_FREE 18 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS DATA_LENGTH 15 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS INDEX_LENGTH 17 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema PARTITIONS MAX_DATA_LENGTH 16 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS DATA_FREE 18 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS DATA_LENGTH 15 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS INDEX_LENGTH 17 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS MAX_DATA_LENGTH 16 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema PARTITIONS NODEGROUP 24 NO varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select
NULL information_schema PARTITIONS PARTITION_COMMENT 23 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
NULL information_schema PARTITIONS PARTITION_DESCRIPTION 12 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
NULL information_schema PARTITIONS PARTITION_EXPRESSION 10 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
NULL information_schema PARTITIONS PARTITION_METHOD 8 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select
NULL information_schema PARTITIONS PARTITION_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PARTITIONS PARTITION_ORDINAL_POSITION 6 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS PARTITION_ORDINAL_POSITION 6 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema PARTITIONS SUBPARTITION_EXPRESSION 11 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select
NULL information_schema PARTITIONS SUBPARTITION_METHOD 9 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select
NULL information_schema PARTITIONS SUBPARTITION_NAME 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PARTITIONS SUBPARTITION_ORDINAL_POSITION 7 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS SUBPARTITION_ORDINAL_POSITION 7 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema PARTITIONS TABLESPACE_NAME 25 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema PARTITIONS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
NULL information_schema PARTITIONS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema PARTITIONS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema PARTITIONS UPDATE_TIME 20 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
NULL information_schema PBXT_STATISTICS ID 1 0 NO int NULL NULL 10 0 NULL NULL int(4) select
@@ -384,27 +385,27 @@ NULL information_schema STATISTICS SUB_PART 11 NULL YES bigint NULL NULL 19 0 NU
NULL information_schema STATISTICS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
NULL information_schema STATISTICS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema STATISTICS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLES AUTO_INCREMENT 14 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES AVG_ROW_LENGTH 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES CHECKSUM 19 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES AUTO_INCREMENT 14 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES AVG_ROW_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES CHECKSUM 19 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema TABLES CHECK_TIME 17 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
NULL information_schema TABLES CREATE_OPTIONS 20 NULL YES varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255) select
NULL information_schema TABLES CREATE_TIME 15 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema TABLES DATA_FREE 13 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES DATA_LENGTH 10 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES DATA_FREE 13 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES DATA_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema TABLES ENGINE 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLES INDEX_LENGTH 12 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
-NULL information_schema TABLES MAX_DATA_LENGTH 11 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES INDEX_LENGTH 12 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES MAX_DATA_LENGTH 11 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema TABLES ROW_FORMAT 7 NULL YES varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select
NULL information_schema TABLES TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
NULL information_schema TABLES TABLE_COLLATION 18 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select
NULL information_schema TABLES TABLE_COMMENT 21 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select
NULL information_schema TABLES TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
-NULL information_schema TABLES TABLE_ROWS 8 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES TABLE_ROWS 8 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema TABLES TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema TABLES TABLE_TYPE 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select
-NULL information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select
+NULL information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select
NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select
NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select
@@ -697,9 +698,7 @@ NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB next_page_no bigint NULL N
NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB lru_position bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB fix_count bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB flush_type bigint NULL NULL NULL NULL bigint(21) unsigned
-3.0000 information_schema INNODB_BUFFER_POOL_PAGES_INDEX schema_name varchar 64 192 utf8 utf8_general_ci varchar(64)
-3.0000 information_schema INNODB_BUFFER_POOL_PAGES_INDEX table_name varchar 64 192 utf8 utf8_general_ci varchar(64)
-3.0000 information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_name varchar 64 192 utf8 utf8_general_ci varchar(64)
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_id bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX space_id bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX page_no bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX n_recs bigint NULL NULL NULL NULL bigint(21) unsigned
@@ -768,6 +767,9 @@ NULL information_schema INNODB_SYS_INDEXES N_FIELDS bigint NULL NULL NULL NULL b
NULL information_schema INNODB_SYS_INDEXES TYPE bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_SYS_INDEXES SPACE bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_SYS_INDEXES PAGE_NO bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS INDEX_ID bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS KEY_COLS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS DIFF_VALS bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema INNODB_SYS_TABLES SCHEMA varchar 192 576 utf8 utf8_general_ci varchar(192)
3.0000 information_schema INNODB_SYS_TABLES NAME varchar 192 576 utf8 utf8_general_ci varchar(192)
NULL information_schema INNODB_SYS_TABLES ID bigint NULL NULL NULL NULL bigint(21) unsigned
diff --git a/mysql-test/suite/funcs_1/r/is_columns_memory.result b/mysql-test/suite/funcs_1/r/is_columns_memory.result
index 513d7bdfac6..60dea25e0e3 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_memory.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_memory.result
@@ -437,9 +437,9 @@ NULL test tb1 f27 19 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zero
NULL test tb1 f28 20 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
NULL test tb1 f29 21 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
NULL test tb1 f3 3 NULL YES char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb1 f30 22 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb1 f31 23 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb1 f32 24 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f30 22 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb1 f31 23 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f32 24 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
NULL test tb1 f33 25 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
NULL test tb1 f34 26 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
NULL test tb1 f35 27 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
@@ -540,9 +540,9 @@ NULL test tb3 f143 20 99999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned s
NULL test tb3 f144 21 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
NULL test tb3 f145 22 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
NULL test tb3 f146 23 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
-NULL test tb3 f147 24 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb3 f148 25 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb3 f149 26 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f147 24 999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb3 f148 25 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f149 26 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
NULL test tb3 f150 27 1000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
NULL test tb3 f151 28 999 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
NULL test tb3 f152 29 0000001000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
diff --git a/mysql-test/suite/funcs_1/r/is_columns_myisam.result b/mysql-test/suite/funcs_1/r/is_columns_myisam.result
index a95ca4f0ebf..6d0a44d2223 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_myisam.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_myisam.result
@@ -479,9 +479,9 @@ NULL test tb1 f27 27 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zero
NULL test tb1 f28 28 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
NULL test tb1 f29 29 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
NULL test tb1 f3 3 NULL YES char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references
-NULL test tb1 f30 30 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb1 f31 31 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb1 f32 32 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f30 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb1 f31 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb1 f32 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
NULL test tb1 f33 33 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
NULL test tb1 f34 34 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
NULL test tb1 f35 35 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
@@ -602,9 +602,9 @@ NULL test tb3 f143 26 99999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned s
NULL test tb3 f144 27 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
NULL test tb3 f145 28 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references
NULL test tb3 f146 29 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references
-NULL test tb3 f147 30 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
-NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f147 30 999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
+NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references
NULL test tb3 f150 33 1000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references
NULL test tb3 f151 34 999 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references
NULL test tb3 f152 35 0000001000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references
diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
index 630baeee74f..30a3d047bde 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
@@ -97,13 +97,13 @@ NULL mysql host Select_priv 3 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum(
NULL mysql host Show_view_priv 16 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql host Trigger_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
NULL mysql host Update_priv 5 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
-NULL mysql ndb_binlog_index deletes 6 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL mysql ndb_binlog_index epoch 3 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned PRI select,insert,update,references
+NULL mysql ndb_binlog_index deletes 6 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL mysql ndb_binlog_index epoch 3 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned PRI select,insert,update,references
NULL mysql ndb_binlog_index File 2 NULL NO varchar 255 255 NULL NULL latin1 latin1_swedish_ci varchar(255) select,insert,update,references
-NULL mysql ndb_binlog_index inserts 4 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL mysql ndb_binlog_index Position 1 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL mysql ndb_binlog_index schemaops 7 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
-NULL mysql ndb_binlog_index updates 5 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL mysql ndb_binlog_index inserts 4 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL mysql ndb_binlog_index Position 1 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL mysql ndb_binlog_index schemaops 7 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
+NULL mysql ndb_binlog_index updates 5 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references
NULL mysql plugin dl 2 NO char 128 384 NULL NULL utf8 utf8_bin char(128) select,insert,update,references
NULL mysql plugin name 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
NULL mysql proc body 11 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references
diff --git a/mysql-test/suite/funcs_1/r/is_engines_innodb.result b/mysql-test/suite/funcs_1/r/is_engines_innodb.result
index 5713b417cd1..6de31d3ad31 100644
--- a/mysql-test/suite/funcs_1/r/is_engines_innodb.result
+++ b/mysql-test/suite/funcs_1/r/is_engines_innodb.result
@@ -2,7 +2,7 @@ SELECT * FROM information_schema.engines
WHERE ENGINE = 'InnoDB';
ENGINE InnoDB
SUPPORT YES
-COMMENT Supports transactions, row-level locking, and foreign keys
+COMMENT Percona-XtraDB, Supports transactions, row-level locking, and foreign keys
TRANSACTIONS YES
XA YES
SAVEPOINTS YES
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 8419bfb7ebb..f4fe0a880e7 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_is.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_is.result
@@ -567,6 +567,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_STATS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+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#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME INNODB_SYS_TABLES
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1734,6 +1757,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_STATS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+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#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME INNODB_SYS_TABLES
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
diff --git a/mysql-test/suite/funcs_1/t/is_tables_is.test b/mysql-test/suite/funcs_1/t/is_tables_is.test
index 20ed93ddd07..6401f2d451a 100644
--- a/mysql-test/suite/funcs_1/t/is_tables_is.test
+++ b/mysql-test/suite/funcs_1/t/is_tables_is.test
@@ -13,6 +13,7 @@
#
--source include/not_embedded.inc
+--source include/have_innodb.inc
let $my_where = WHERE table_schema = 'information_schema'
AND table_name <> 'profiling';
--source suite/funcs_1/datadict/tables1.inc
diff --git a/mysql-test/suite/innodb/r/innodb_bug53756.result b/mysql-test/suite/innodb/r/innodb_bug53756.result
new file mode 100644
index 00000000000..37453be8201
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bug53756.result
@@ -0,0 +1,118 @@
+DROP TABLE IF EXISTS bug_53756 ;
+CREATE TABLE bug_53756 (pk INT, c1 INT) ENGINE=InnoDB;
+ALTER TABLE bug_53756 ADD PRIMARY KEY (pk);
+INSERT INTO bug_53756 VALUES(1, 11), (2, 22), (3, 33), (4, 44);
+
+# Select a less restrictive isolation level.
+SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+COMMIT;
+
+# Start a transaction in the default connection for isolation.
+START TRANSACTION;
+SELECT @@tx_isolation;
+@@tx_isolation
+READ-COMMITTED
+SELECT * FROM bug_53756;
+pk c1
+1 11
+2 22
+3 33
+4 44
+
+# connection con1 deletes row 1
+START TRANSACTION;
+SELECT @@tx_isolation;
+@@tx_isolation
+READ-COMMITTED
+DELETE FROM bug_53756 WHERE pk=1;
+
+# connection con2 deletes row 2
+START TRANSACTION;
+SELECT @@tx_isolation;
+@@tx_isolation
+READ-COMMITTED
+DELETE FROM bug_53756 WHERE pk=2;
+
+# connection con3 updates row 3
+START TRANSACTION;
+SELECT @@tx_isolation;
+@@tx_isolation
+READ-COMMITTED
+UPDATE bug_53756 SET c1=77 WHERE pk=3;
+
+# connection con4 updates row 4
+START TRANSACTION;
+SELECT @@tx_isolation;
+@@tx_isolation
+READ-COMMITTED
+UPDATE bug_53756 SET c1=88 WHERE pk=4;
+
+# connection con5 inserts row 5
+START TRANSACTION;
+SELECT @@tx_isolation;
+@@tx_isolation
+READ-COMMITTED
+INSERT INTO bug_53756 VALUES(5, 55);
+
+# connection con6 inserts row 6
+START TRANSACTION;
+SELECT @@tx_isolation;
+@@tx_isolation
+READ-COMMITTED
+INSERT INTO bug_53756 VALUES(6, 66);
+
+# connection con1 commits.
+COMMIT;
+
+# connection con3 commits.
+COMMIT;
+
+# connection con4 rolls back.
+ROLLBACK;
+
+# connection con6 rolls back.
+ROLLBACK;
+
+# The connections 2 and 5 stay open.
+
+# connection default selects resulting data.
+# Delete of row 1 was committed.
+# Update of row 3 was committed.
+# Due to isolation level read committed, these should be included.
+# All other changes should not be included.
+SELECT * FROM bug_53756;
+pk c1
+2 22
+3 77
+4 44
+
+# connection default
+#
+# Crash server.
+START TRANSACTION;
+INSERT INTO bug_53756 VALUES (666,666);
+SET SESSION debug="+d,crash_commit_before";
+COMMIT;
+ERROR HY000: Lost connection to MySQL server during query
+
+#
+# disconnect con1, con2, con3, con4, con5, con6.
+#
+# Restart server.
+
+#
+# Select recovered data.
+# Delete of row 1 was committed.
+# Update of row 3 was committed.
+# These should be included.
+# All other changes should not be included.
+# Delete of row 2 and insert of row 5 should be rolled back
+SELECT * FROM bug_53756;
+pk c1
+2 22
+3 77
+4 44
+
+# Clean up.
+DROP TABLE bug_53756;
diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result
index d018cace759..fa19dee7d26 100644
--- a/mysql-test/suite/innodb/r/innodb_mysql.result
+++ b/mysql-test/suite/innodb/r/innodb_mysql.result
@@ -2507,4 +2507,12 @@ ORDER BY f1 DESC LIMIT 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range f2,f4 f4 1 NULL 11 Using where
DROP TABLE t1;
+#
+# Bug#54117 crash in thr_multi_unlock, temporary table
+#
+CREATE TEMPORARY TABLE t1(a INT) ENGINE = InnoDB;
+LOCK TABLES t1 READ;
+ALTER TABLE t1 COMMENT 'test';
+UNLOCK TABLES;
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/suite/innodb/t/disabled.def b/mysql-test/suite/innodb/t/disabled.def
index cae02f606d6..15f02571509 100644
--- a/mysql-test/suite/innodb/t/disabled.def
+++ b/mysql-test/suite/innodb/t/disabled.def
@@ -11,4 +11,4 @@
##############################################################################
#innodb : Bug#53306 2010-04-30 VasilDimov valgrind warnings
-innodb_bug48024 : Waiting for merge with Percona Server; bug fixed in innodb_plugin in MySQL 5.1.48
+innodb_bug53756 : Waiting for merge with Percona Server; bug fixed in innodb_plugin in MySQL 5.1.50
diff --git a/mysql-test/suite/innodb/t/innodb_bug53756-master.opt b/mysql-test/suite/innodb/t/innodb_bug53756-master.opt
new file mode 100644
index 00000000000..425fda95086
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bug53756-master.opt
@@ -0,0 +1 @@
+--skip-stack-trace --skip-core-file
diff --git a/mysql-test/suite/innodb/t/innodb_bug53756.test b/mysql-test/suite/innodb/t/innodb_bug53756.test
new file mode 100644
index 00000000000..8324f2640a2
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bug53756.test
@@ -0,0 +1,184 @@
+# This is the test case for bug #53756. Alter table operation could
+# leave a deleted record for the temp table (later renamed to the altered
+# table) in the SYS_TABLES secondary index, we should ignore this row and
+# find the first non-deleted row for the specified table_id when load table
+# metadata in the function dict_load_table_on_id() during crash recovery.
+
+#
+# innobackup needs to connect to the server. Not supported in embedded.
+--source include/not_embedded.inc
+#
+# This test case needs to crash the server. Needs a debug server.
+--source include/have_debug.inc
+#
+# Don't test this under valgrind, memory leaks will occur.
+--source include/not_valgrind.inc
+#
+# This test case needs InnoDB.
+--source include/have_innodb.inc
+
+#
+# Precautionary clean up.
+#
+--disable_warnings
+DROP TABLE IF EXISTS bug_53756 ;
+--enable_warnings
+
+#
+# Create test data.
+#
+CREATE TABLE bug_53756 (pk INT, c1 INT) ENGINE=InnoDB;
+ALTER TABLE bug_53756 ADD PRIMARY KEY (pk);
+INSERT INTO bug_53756 VALUES(1, 11), (2, 22), (3, 33), (4, 44);
+
+--echo
+--echo # Select a less restrictive isolation level.
+# Don't use user variables. They won't survive server crash.
+--let $global_isolation= `SELECT @@global.tx_isolation`;
+--let $session_isolation= `SELECT @@session.tx_isolation`;
+SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+COMMIT;
+
+--echo
+--echo # Start a transaction in the default connection for isolation.
+START TRANSACTION;
+SELECT @@tx_isolation;
+SELECT * FROM bug_53756;
+
+--echo
+--echo # connection con1 deletes row 1
+--connect (con1,localhost,root,,)
+START TRANSACTION;
+SELECT @@tx_isolation;
+DELETE FROM bug_53756 WHERE pk=1;
+
+--echo
+--echo # connection con2 deletes row 2
+--connect (con2,localhost,root,,)
+START TRANSACTION;
+SELECT @@tx_isolation;
+DELETE FROM bug_53756 WHERE pk=2;
+
+--echo
+--echo # connection con3 updates row 3
+--connect (con3,localhost,root,,)
+START TRANSACTION;
+SELECT @@tx_isolation;
+UPDATE bug_53756 SET c1=77 WHERE pk=3;
+
+--echo
+--echo # connection con4 updates row 4
+--connect (con4,localhost,root,,)
+START TRANSACTION;
+SELECT @@tx_isolation;
+UPDATE bug_53756 SET c1=88 WHERE pk=4;
+
+--echo
+--echo # connection con5 inserts row 5
+--connect (con5,localhost,root,,)
+START TRANSACTION;
+SELECT @@tx_isolation;
+INSERT INTO bug_53756 VALUES(5, 55);
+
+--echo
+--echo # connection con6 inserts row 6
+--connect (con6,localhost,root,,)
+START TRANSACTION;
+SELECT @@tx_isolation;
+INSERT INTO bug_53756 VALUES(6, 66);
+
+--echo
+--echo # connection con1 commits.
+--connection con1
+COMMIT;
+
+--echo
+--echo # connection con3 commits.
+--connection con3
+COMMIT;
+
+--echo
+--echo # connection con4 rolls back.
+--connection con4
+ROLLBACK;
+
+--echo
+--echo # connection con6 rolls back.
+--connection con6
+ROLLBACK;
+
+--echo
+--echo # The connections 2 and 5 stay open.
+
+--echo
+--echo # connection default selects resulting data.
+--echo # Delete of row 1 was committed.
+--echo # Update of row 3 was committed.
+--echo # Due to isolation level read committed, these should be included.
+--echo # All other changes should not be included.
+--connection default
+SELECT * FROM bug_53756;
+
+--echo
+--echo # connection default
+--connection default
+--echo #
+--echo # Crash server.
+#
+# Write file to make mysql-test-run.pl expect the "crash", but don't start
+# it until it's told to
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+#
+START TRANSACTION;
+INSERT INTO bug_53756 VALUES (666,666);
+#
+# Request a crash on next execution of commit.
+SET SESSION debug="+d,crash_commit_before";
+#
+# Execute the statement that causes the crash.
+--error 2013
+COMMIT;
+--echo
+--echo #
+--echo # disconnect con1, con2, con3, con4, con5, con6.
+--disconnect con1
+--disconnect con2
+--disconnect con3
+--disconnect con4
+--disconnect con5
+--disconnect con6
+--echo #
+--echo # Restart server.
+#
+# Write file to make mysql-test-run.pl start up the server again
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+#
+# Turn on reconnect
+--enable_reconnect
+#
+# Call script that will poll the server waiting for it to be back online again
+--source include/wait_until_connected_again.inc
+#
+# Turn off reconnect again
+--disable_reconnect
+--echo
+
+--echo #
+--echo # Select recovered data.
+--echo # Delete of row 1 was committed.
+--echo # Update of row 3 was committed.
+--echo # These should be included.
+--echo # All other changes should not be included.
+--echo # Delete of row 2 and insert of row 5 should be rolled back
+SELECT * FROM bug_53756;
+
+--echo
+--echo # Clean up.
+DROP TABLE bug_53756;
+
+--disable_query_log
+eval SET GLOBAL tx_isolation= '$global_isolation';
+eval SET SESSION tx_isolation= '$session_isolation';
+--enable_query_log
+
diff --git a/mysql-test/suite/innodb/t/innodb_misc1.test b/mysql-test/suite/innodb/t/innodb_misc1.test
index 1bebd5411bc..295b9ec464c 100644
--- a/mysql-test/suite/innodb/t/innodb_misc1.test
+++ b/mysql-test/suite/innodb/t/innodb_misc1.test
@@ -14,6 +14,8 @@
#######################################################################
-- source include/have_innodb.inc
+let collation=utf8_unicode_ci;
+--source include/have_collation.inc
let $MYSQLD_DATADIR= `select @@datadir`;
diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test
index 8d3af2b3a5d..1171eaa899c 100644
--- a/mysql-test/suite/innodb/t/innodb_mysql.test
+++ b/mysql-test/suite/innodb/t/innodb_mysql.test
@@ -8,6 +8,8 @@
# Slow test, don't run during staging part
-- source include/not_staging.inc
-- source include/have_innodb.inc
+-- source include/have_query_cache.inc
+
let $engine_type= InnoDB;
let $other_engine_type= MEMORY;
# InnoDB does support FOREIGN KEYFOREIGN KEYs
@@ -752,4 +754,18 @@ ORDER BY f1 DESC LIMIT 5;
DROP TABLE t1;
+
+--echo #
+--echo # Bug#54117 crash in thr_multi_unlock, temporary table
+--echo #
+
+CREATE TEMPORARY TABLE t1(a INT) ENGINE = InnoDB;
+
+LOCK TABLES t1 READ;
+ALTER TABLE t1 COMMENT 'test';
+UNLOCK TABLES;
+
+DROP TABLE t1;
+
+
--echo End of 5.1 tests
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug54453.result b/mysql-test/suite/innodb_plugin/r/innodb_bug54453.result
new file mode 100644
index 00000000000..e623989a9d4
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/r/innodb_bug54453.result
@@ -0,0 +1,9 @@
+#
+# Bug#54453: Failing assertion: trx->active_trans when renaming a table with active trx
+#
+DROP TABLE IF EXISTS bug54453;
+CREATE TABLE bug54453(a INT) ENGINE=InnoDB;
+ALTER TABLE bug54453 RENAME TO bug54453_2;
+SELECT * FROM bug54453_2;
+a
+DROP TABLE bug54453_2;
diff --git a/mysql-test/suite/innodb_plugin/t/disabled.def b/mysql-test/suite/innodb_plugin/t/disabled.def
index 158dd7e7f67..4c37bbc87ed 100644
--- a/mysql-test/suite/innodb_plugin/t/disabled.def
+++ b/mysql-test/suite/innodb_plugin/t/disabled.def
@@ -10,11 +10,4 @@
#
##############################################################################
-innodb_bug48024 : Waiting for merge/fix from XtraDB
-innodb_bug53590 : Waiting for merge/fix from XtraDB
-innodb_bug53591 : Waiting for merge/fix from XtraDB
-innodb_bug53592 : Waiting for merge/fix from XtraDB
-innodb-use-sys-malloc : Waiting for bugfix from Percona for LP#612600
-innodb_bug53290 : Waiting for merge/fix from XtraDB
-innodb_bug54679 : Waiting for merge/fix from XtraDB
-innodb_bug52745 : Waiting for merge/fix from XtraDB
+innodb_bug52745: Disabled as this has valgrind failures (also in MySQL 5.1.50)
diff --git a/mysql-test/suite/innodb_plugin/t/innodb-autoinc-44030.test b/mysql-test/suite/innodb_plugin/t/innodb-autoinc-44030.test
index 99cdac72e2e..5e4cf9dcb4c 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb-autoinc-44030.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb-autoinc-44030.test
@@ -1,6 +1,8 @@
-- source include/have_innodb_plugin.inc
# embedded server ignores 'delayed', so skip this
-- source include/not_embedded.inc
+# remove the next line after bug #55503 is fixed
+-- source include/not_valgrind.inc
let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
diff --git a/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test b/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test
index 5a83ffe3617..49394a019d0 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test
@@ -1,6 +1,8 @@
-- source include/have_innodb_plugin.inc
# embedded server ignores 'delayed', so skip this
-- source include/not_embedded.inc
+# remove the next line after bug #55503 is fixed
+-- source include/not_valgrind.inc
let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
diff --git a/mysql-test/suite/innodb_plugin/t/innodb-use-sys-malloc.test b/mysql-test/suite/innodb_plugin/t/innodb-use-sys-malloc.test
index bc042587287..af08e1c9812 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb-use-sys-malloc.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb-use-sys-malloc.test
@@ -1,4 +1,5 @@
-- source include/have_innodb_plugin.inc
+-- source include/not_valgrind.inc
#display current value of innodb_use_sys_malloc
SELECT @@GLOBAL.innodb_use_sys_malloc;
diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug54453.test b/mysql-test/suite/innodb_plugin/t/innodb_bug54453.test
new file mode 100644
index 00000000000..486695d326d
--- /dev/null
+++ b/mysql-test/suite/innodb_plugin/t/innodb_bug54453.test
@@ -0,0 +1,15 @@
+--source include/have_innodb_plugin.inc
+--source include/have_log_bin.inc
+
+--echo #
+--echo # Bug#54453: Failing assertion: trx->active_trans when renaming a table with active trx
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS bug54453;
+--enable_warnings
+
+CREATE TABLE bug54453(a INT) ENGINE=InnoDB;
+ALTER TABLE bug54453 RENAME TO bug54453_2;
+SELECT * FROM bug54453_2;
+DROP TABLE bug54453_2;
diff --git a/mysql-test/suite/pbxt/r/mysqlshow.result b/mysql-test/suite/pbxt/r/mysqlshow.result
index 8588b332b00..674ec1a7cda 100644
--- a/mysql-test/suite/pbxt/r/mysqlshow.result
+++ b/mysql-test/suite/pbxt/r/mysqlshow.result
@@ -122,13 +122,14 @@ Database: information_schema
| INNODB_TRX |
| INNODB_SYS_TABLES |
| INNODB_LOCK_WAITS |
-| INNODB_CMPMEM_RESET |
+| INNODB_SYS_STATS |
| INNODB_LOCKS |
| INNODB_CMPMEM |
| INNODB_TABLE_STATS |
| INNODB_SYS_INDEXES |
| INNODB_CMP_RESET |
| INNODB_BUFFER_POOL_PAGES_BLOB |
+| INNODB_CMPMEM_RESET |
| INNODB_INDEX_STATS |
+---------------------------------------+
Database: INFORMATION_SCHEMA
@@ -178,13 +179,14 @@ Database: INFORMATION_SCHEMA
| INNODB_TRX |
| INNODB_SYS_TABLES |
| INNODB_LOCK_WAITS |
-| INNODB_CMPMEM_RESET |
+| INNODB_SYS_STATS |
| INNODB_LOCKS |
| INNODB_CMPMEM |
| INNODB_TABLE_STATS |
| INNODB_SYS_INDEXES |
| INNODB_CMP_RESET |
| INNODB_BUFFER_POOL_PAGES_BLOB |
+| INNODB_CMPMEM_RESET |
| INNODB_INDEX_STATS |
+---------------------------------------+
Wildcard: inf_rmation_schema
diff --git a/mysql-test/suite/pbxt/r/range.result b/mysql-test/suite/pbxt/r/range.result
index 2439489581a..a8e97d1c725 100644
--- a/mysql-test/suite/pbxt/r/range.result
+++ b/mysql-test/suite/pbxt/r/range.result
@@ -422,20 +422,20 @@ test.t1 analyze status OK
test.t2 analyze status OK
explain select straight_join * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 1 Using where
-1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 1
+1 SIMPLE t1 range uid_index uid_index 4 NULL # Using where
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid #
explain select straight_join * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 1 Using where
-1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 1
+1 SIMPLE t1 range uid_index uid_index 4 NULL # Using where
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid #
explain select straight_join * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 2 Using where
-1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 1
+1 SIMPLE t1 range uid_index uid_index 4 NULL # Using where
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid #
explain select straight_join * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 2 Using where
-1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 1
+1 SIMPLE t1 range uid_index uid_index 4 NULL # Using where
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid #
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
id name uid id name uid
1001 A 1 1001 A 1
diff --git a/mysql-test/suite/pbxt/t/range.test b/mysql-test/suite/pbxt/t/range.test
index 2e4e2b7da12..8d02089ee1b 100644
--- a/mysql-test/suite/pbxt/t/range.test
+++ b/mysql-test/suite/pbxt/t/range.test
@@ -383,9 +383,14 @@ analyze table t1,t2;
# This part doesn't make sense for pbxt as the result may vary becasue
# records_in_range() gives same results for t1 and t2.
# Added straight_join to get predictable results
+
+--replace_column 9 #
explain select straight_join * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
+--replace_column 9 #
explain select straight_join * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0;
+--replace_column 9 #
explain select straight_join * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
+--replace_column 9 #
explain select straight_join * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0;
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
diff --git a/mysql-test/suite/percona/disabled.def b/mysql-test/suite/percona/disabled.def
index 4f35807b7a1..a99b952a5eb 100644
--- a/mysql-test/suite/percona/disabled.def
+++ b/mysql-test/suite/percona/disabled.def
@@ -8,6 +8,15 @@ percona_query_cache_with_comments_prepared_statements: Feature not merged int
percona_show_temp_tables: Feature not merged into MariaDB
percona_slow_query_log-use_global_long_query_time: Feature not merged into MariaDB
percona_query_cache_with_comments_disable: Feature not merged into MariaDB
+percona_log_connection_error: Feature not merged into MariaDB
+percona_query_response_time: Feature not merged into MariaDB
+percona_query_response_time-stored: Feature not merged into MariaDB
+percona_sql_no_fcache: Feature not merged into MariaDB
+percona_status_wait_query_cache_mutex: Feature not merged into MariaDB
+percona_slave_innodb_stats: Feature not merged into MariaDB
+percona_query_response_time-replication: Feature not merged into MariaDB
+percona_server_variables: Feature not merged into MariaDB
percona_slow_query_log-log_slow_verbosity: InnoDB filtering information not fully merged into MariaDB
+percona_innodb_buffer_pool_shm: Requires big shmmax not default on many systems
diff --git a/mysql-test/suite/percona/percona_innodb_buffer_pool_shm-master.opt b/mysql-test/suite/percona/percona_innodb_buffer_pool_shm-master.opt
new file mode 100644
index 00000000000..5974ef6e2be
--- /dev/null
+++ b/mysql-test/suite/percona/percona_innodb_buffer_pool_shm-master.opt
@@ -0,0 +1 @@
+--innodb_buffer_pool_shm_key=123456
diff --git a/mysql-test/suite/percona/percona_innodb_buffer_pool_shm.result b/mysql-test/suite/percona/percona_innodb_buffer_pool_shm.result
new file mode 100644
index 00000000000..08ece8fb9a9
--- /dev/null
+++ b/mysql-test/suite/percona/percona_innodb_buffer_pool_shm.result
@@ -0,0 +1,6 @@
+show variables like 'innodb_buffer_pool_shm%';
+Variable_name Value
+innodb_buffer_pool_shm_key 123456
+show variables like 'innodb_buffer_pool_shm%';
+Variable_name Value
+innodb_buffer_pool_shm_key 123456
diff --git a/mysql-test/suite/percona/percona_innodb_buffer_pool_shm.test b/mysql-test/suite/percona/percona_innodb_buffer_pool_shm.test
new file mode 100644
index 00000000000..7b81bb8d54b
--- /dev/null
+++ b/mysql-test/suite/percona/percona_innodb_buffer_pool_shm.test
@@ -0,0 +1,18 @@
+--source include/have_innodb.inc
+show variables like 'innodb_buffer_pool_shm%';
+
+#clean shutdown (restart_mysqld.inc is not clean if over 10 sec...)
+--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+wait
+EOF
+shutdown_server 120;
+--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+restart
+EOF
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+
+show variables like 'innodb_buffer_pool_shm%';
+--sleep 1
+--system ipcrm -M 123456
diff --git a/mysql-test/suite/percona/percona_innodb_use_sys_stats_table-master.opt b/mysql-test/suite/percona/percona_innodb_use_sys_stats_table-master.opt
new file mode 100644
index 00000000000..c6865f5704c
--- /dev/null
+++ b/mysql-test/suite/percona/percona_innodb_use_sys_stats_table-master.opt
@@ -0,0 +1 @@
+--innodb_use_sys_stats_table
diff --git a/mysql-test/suite/percona/percona_innodb_use_sys_stats_table.result b/mysql-test/suite/percona/percona_innodb_use_sys_stats_table.result
new file mode 100644
index 00000000000..cb64de41901
--- /dev/null
+++ b/mysql-test/suite/percona/percona_innodb_use_sys_stats_table.result
@@ -0,0 +1,3 @@
+show variables like 'innodb_use_sys_stats%';
+Variable_name Value
+innodb_use_sys_stats_table ON
diff --git a/mysql-test/suite/percona/percona_innodb_use_sys_stats_table.test b/mysql-test/suite/percona/percona_innodb_use_sys_stats_table.test
new file mode 100644
index 00000000000..02791137f08
--- /dev/null
+++ b/mysql-test/suite/percona/percona_innodb_use_sys_stats_table.test
@@ -0,0 +1,2 @@
+--source include/have_innodb.inc
+show variables like 'innodb_use_sys_stats%';
diff --git a/mysql-test/suite/percona/percona_log_connection_error-master.opt b/mysql-test/suite/percona/percona_log_connection_error-master.opt
new file mode 100644
index 00000000000..32a891789f3
--- /dev/null
+++ b/mysql-test/suite/percona/percona_log_connection_error-master.opt
@@ -0,0 +1 @@
+--log-error \ No newline at end of file
diff --git a/mysql-test/suite/percona/percona_log_connection_error.result b/mysql-test/suite/percona/percona_log_connection_error.result
new file mode 100644
index 00000000000..3c6c67f770c
--- /dev/null
+++ b/mysql-test/suite/percona/percona_log_connection_error.result
@@ -0,0 +1,15 @@
+SET @old_max_connections = @@max_connections;
+SET @old_log_warnings = @@log_warnings;
+SET GLOBAL max_connections=2;
+SET GLOBAL LOG_WARNINGS = 0;
+connect(localhost,root,,test,port,socket);
+ERROR HY000: Too many connections
+SET GLOBAL LOG_WARNINGS = 1;
+connect(localhost,root,,test,port,socket);
+ERROR HY000: Too many connections
+SET GLOBAL LOG_WARNINGS = 0;
+connect(localhost,root,,test,port,socket);
+ERROR HY000: Too many connections
+SET GLOBAL max_connections = @old_max_connections;
+SET GLOBAL log_warnings = @old_log_warnings;
+1
diff --git a/mysql-test/suite/percona/percona_log_connection_error.test b/mysql-test/suite/percona/percona_log_connection_error.test
new file mode 100644
index 00000000000..57cd652bd24
--- /dev/null
+++ b/mysql-test/suite/percona/percona_log_connection_error.test
@@ -0,0 +1,52 @@
+--source include/not_embedded.inc
+
+connect (main,localhost,root,,);
+connection main;
+SET @old_max_connections = @@max_connections;
+SET @old_log_warnings = @@log_warnings;
+SET GLOBAL max_connections=2;
+let $port=`SELECT Variable_value FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE Variable_name LIKE 'port'`;
+let $socket=`SELECT Variable_value FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE Variable_name LIKE 'socket'`;
+
+SET GLOBAL LOG_WARNINGS = 0;
+--connect (conn0,localhost,root,,)
+connection conn0;
+replace_result $port port $socket socket;
+--error 1040
+--connect(conn1,localhost,root,,)
+disconnect conn0;
+SLEEP 0.1; # tsarev: hack, but i don't know (and didn't find) how right
+
+connection main;
+SET GLOBAL LOG_WARNINGS = 1;
+--connect (conn1,localhost,root,,)
+replace_result $port port $socket socket;
+--error 1040
+--connect (conn0,localhost,root,,)
+disconnect conn1;
+SLEEP 0.1; # tsarev: hack, but i don't know (and didn't find) how right
+
+connection main;
+SET GLOBAL LOG_WARNINGS = 0;
+--connect (conn0,localhost,root,,)
+replace_result $port port $socket socket;
+--error 1040
+--connect(conn1,localhost,root,,)
+disconnect conn0;
+SLEEP 0.1; # tsarev: hack, but i don't know (and didn't find) how right
+
+connection main;
+SET GLOBAL max_connections = @old_max_connections;
+SET GLOBAL log_warnings = @old_log_warnings;
+let $log_error_= `SELECT @@GLOBAL.log_error`;
+if(!`select LENGTH('$log_error_')`)
+{
+ # MySQL Server on windows is started with --console and thus
+ # does not know the location of its .err log, use default location
+ let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err;
+}
+# Assign env variable LOG_ERROR
+let LOG_ERROR=$log_error_;
+
+let cmd=cat $log_error | grep "Too many connections" | wc -l;
+exec $cmd;
diff --git a/mysql-test/suite/percona/percona_query_response_time-replication.result b/mysql-test/suite/percona/percona_query_response_time-replication.result
new file mode 100644
index 00000000000..df5c73812df
--- /dev/null
+++ b/mysql-test/suite/percona/percona_query_response_time-replication.result
@@ -0,0 +1,60 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP TABLE IF EXISTS t;
+CREATE TABLE t(id INT);
+SELECT * from t;
+id
+SELECT * from t;
+id
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1;
+Warnings:
+Warning 1292 Truncated incorrect query_response_time_range_base value: '1'
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 2
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 10;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 10
+FLUSH QUERY_RESPONSE_TIME;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=ON;
+INSERT INTO t VALUES(0);
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count)
+0
+INSERT INTO t VALUES(1);
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count)
+0
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count)
+2
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count)
+3
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 2;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 2
+FLUSH QUERY_RESPONSE_TIME;
+INSERT INTO t VALUES(0);
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count)
+0
+INSERT INTO t VALUES(1);
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count)
+0
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count)
+2
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count)
+3
+DROP TABLE IF EXISTS t;
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 10;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=OFF;
diff --git a/mysql-test/suite/percona/percona_query_response_time-replication.test b/mysql-test/suite/percona/percona_query_response_time-replication.test
new file mode 100644
index 00000000000..4f674c2fd19
--- /dev/null
+++ b/mysql-test/suite/percona/percona_query_response_time-replication.test
@@ -0,0 +1,52 @@
+--source include/master-slave.inc
+
+connection master;
+-- disable_warnings
+DROP TABLE IF EXISTS t;
+-- enable_warnings
+CREATE TABLE t(id INT);
+SELECT * from t;
+
+sync_slave_with_master;
+
+connection slave;
+SELECT * from t;
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 10;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+source include/percona_query_response_time_flush.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=ON;
+
+connection master;
+INSERT INTO t VALUES(0);
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+INSERT INTO t VALUES(1);
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+sync_slave_with_master;
+
+connection slave;
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 2;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+source include/percona_query_response_time_flush.inc;
+
+connection master;
+INSERT INTO t VALUES(0);
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+INSERT INTO t VALUES(1);
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+sync_slave_with_master;
+
+connection slave;
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+SELECT SUM(INFORMATION_SCHEMA.QUERY_RESPONSE_TIME.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+
+connection master;
+DROP TABLE IF EXISTS t;
+sync_slave_with_master;
+connection slave;
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 10;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=OFF;
diff --git a/mysql-test/suite/percona/percona_query_response_time-stored.result b/mysql-test/suite/percona/percona_query_response_time-stored.result
new file mode 100644
index 00000000000..386180c791a
--- /dev/null
+++ b/mysql-test/suite/percona/percona_query_response_time-stored.result
@@ -0,0 +1,310 @@
+CREATE FUNCTION test_f()
+RETURNS CHAR(30) DETERMINISTIC
+BEGIN
+DECLARE first VARCHAR(5);
+DECLARE second VARCHAR(5);
+DECLARE result VARCHAR(20);
+SELECT SLEEP(1.11) INTO first;
+SET first= 'Hello';
+SET second=', ';
+SET result= CONCAT(first,second);
+SET result= CONCAT(result,'world!');
+RETURN result;
+END/
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1;
+Warnings:
+Warning 1292 Truncated incorrect query_response_time_range_base value: '1'
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 2
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 2;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 2
+FLUSH QUERY_RESPONSE_TIME;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+44
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000001
+ 0.000003
+ 0.000007
+ 0.000015
+ 0.000030
+ 0.000061
+ 0.000122
+ 0.000244
+ 0.000488
+ 0.000976
+ 0.001953
+ 0.003906
+ 0.007812
+ 0.015625
+ 0.031250
+ 0.062500
+ 0.125000
+ 0.250000
+ 0.500000
+ 1.000000
+ 2.000000
+ 4.000000
+ 8.000000
+ 16.000000
+ 32.000000
+ 64.000000
+ 128.000000
+ 256.000000
+ 512.000000
+ 1024.000000
+ 2048.000000
+ 4096.000000
+ 8192.000000
+ 16384.000000
+ 32768.000000
+ 65536.000000
+ 131072.000000
+ 262144.000000
+ 524288.000000
+ 1048576.00000
+ 2097152.00000
+ 4194304.00000
+ 8388608.00000
+TOO LONG QUERY
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT test_f();
+test_f()
+Hello, world!
+SELECT test_f();
+test_f()
+Hello, world!
+SELECT test_f();
+test_f()
+Hello, world!
+SELECT test_f();
+test_f()
+Hello, world!
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+1 5 2 44
+4 5 2 44
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+44
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000001
+ 0.000003
+ 0.000007
+ 0.000015
+ 0.000030
+ 0.000061
+ 0.000122
+ 0.000244
+ 0.000488
+ 0.000976
+ 0.001953
+ 0.003906
+ 0.007812
+ 0.015625
+ 0.031250
+ 0.062500
+ 0.125000
+ 0.250000
+ 0.500000
+ 1.000000
+ 2.000000
+ 4.000000
+ 8.000000
+ 16.000000
+ 32.000000
+ 64.000000
+ 128.000000
+ 256.000000
+ 512.000000
+ 1024.000000
+ 2048.000000
+ 4096.000000
+ 8192.000000
+ 16384.000000
+ 32768.000000
+ 65536.000000
+ 131072.000000
+ 262144.000000
+ 524288.000000
+ 1048576.00000
+ 2097152.00000
+ 4194304.00000
+ 8388608.00000
+TOO LONG QUERY
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 2
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 10;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 10
+FLUSH QUERY_RESPONSE_TIME;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT test_f();
+test_f()
+Hello, world!
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+1 2 2 14
+1 2 2 14
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+14
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000001
+ 0.000010
+ 0.000100
+ 0.001000
+ 0.010000
+ 0.100000
+ 1.000000
+ 10.000000
+ 100.000000
+ 1000.000000
+ 10000.000000
+ 100000.000000
+ 1000000.00000
+TOO LONG QUERY
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 10
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 7;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 7
+FLUSH QUERY_RESPONSE_TIME;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT test_f();
+test_f()
+Hello, world!
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+1 2 2 17
+1 2 2 17
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+17
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000001
+ 0.000008
+ 0.000059
+ 0.000416
+ 0.002915
+ 0.020408
+ 0.142857
+ 1.000000
+ 7.000000
+ 49.000000
+ 343.000000
+ 2401.000000
+ 16807.000000
+ 117649.000000
+ 823543.000000
+ 5764801.00000
+TOO LONG QUERY
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 7
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 156;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 156
+FLUSH QUERY_RESPONSE_TIME;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT test_f();
+test_f()
+Hello, world!
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+1 2 2 7
+1 2 2 7
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+7
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000041
+ 0.006410
+ 1.000000
+ 156.000000
+ 24336.000000
+ 3796416.00000
+TOO LONG QUERY
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 156
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1000;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 1000
+FLUSH QUERY_RESPONSE_TIME;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT test_f();
+test_f()
+Hello, world!
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+1 2 2 6
+1 2 2 6
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+6
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000001
+ 0.001000
+ 1.000000
+ 1000.000000
+ 1000000.00000
+TOO LONG QUERY
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 1000
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1001;
+Warnings:
+Warning 1292 Truncated incorrect query_response_time_range_base value: '1001'
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 1000
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE =10;
+DROP FUNCTION test_f;
diff --git a/mysql-test/suite/percona/percona_query_response_time-stored.test b/mysql-test/suite/percona/percona_query_response_time-stored.test
new file mode 100644
index 00000000000..f761dd7d01c
--- /dev/null
+++ b/mysql-test/suite/percona/percona_query_response_time-stored.test
@@ -0,0 +1,87 @@
+source include/have_innodb.inc;
+
+delimiter /;
+CREATE FUNCTION test_f()
+RETURNS CHAR(30) DETERMINISTIC
+BEGIN
+ DECLARE first VARCHAR(5);
+ DECLARE second VARCHAR(5);
+ DECLARE result VARCHAR(20);
+ SELECT SLEEP(1.11) INTO first;
+ SET first= 'Hello';
+ SET second=', ';
+ SET result= CONCAT(first,second);
+ SET result= CONCAT(result,'world!');
+ RETURN result;
+END/
+delimiter ;/
+
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 2;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+source include/percona_query_response_time_flush.inc;
+source include/percona_query_response_time_show.inc;
+
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT test_f();
+SELECT test_f();
+SELECT test_f();
+SELECT test_f();
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+
+source include/percona_query_response_time_show.inc;
+
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 10;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+source include/percona_query_response_time_flush.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT test_f();
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+
+source include/percona_query_response_time_show.inc;
+
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 7;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+source include/percona_query_response_time_flush.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT test_f();
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+
+source include/percona_query_response_time_show.inc;
+
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 156;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+source include/percona_query_response_time_flush.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT test_f();
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+
+source include/percona_query_response_time_show.inc;
+
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1000;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+source include/percona_query_response_time_flush.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT test_f();
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+
+source include/percona_query_response_time_show.inc;
+
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1001;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE =10;
+
+DROP FUNCTION test_f; \ No newline at end of file
diff --git a/mysql-test/suite/percona/percona_query_response_time.result b/mysql-test/suite/percona/percona_query_response_time.result
new file mode 100644
index 00000000000..3c12284a525
--- /dev/null
+++ b/mysql-test/suite/percona/percona_query_response_time.result
@@ -0,0 +1,564 @@
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1;
+Warnings:
+Warning 1292 Truncated incorrect query_response_time_range_base value: '1'
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 2
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 2;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 2
+FLUSH QUERY_RESPONSE_TIME;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+44
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000001
+ 0.000003
+ 0.000007
+ 0.000015
+ 0.000030
+ 0.000061
+ 0.000122
+ 0.000244
+ 0.000488
+ 0.000976
+ 0.001953
+ 0.003906
+ 0.007812
+ 0.015625
+ 0.031250
+ 0.062500
+ 0.125000
+ 0.250000
+ 0.500000
+ 1.000000
+ 2.000000
+ 4.000000
+ 8.000000
+ 16.000000
+ 32.000000
+ 64.000000
+ 128.000000
+ 256.000000
+ 512.000000
+ 1024.000000
+ 2048.000000
+ 4096.000000
+ 8192.000000
+ 16384.000000
+ 32768.000000
+ 65536.000000
+ 131072.000000
+ 262144.000000
+ 524288.000000
+ 1048576.00000
+ 2097152.00000
+ 4194304.00000
+ 8388608.00000
+TOO LONG QUERY
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT SLEEP(0.31);
+SLEEP(0.31)
+0
+SELECT SLEEP(0.32);
+SLEEP(0.32)
+0
+SELECT SLEEP(0.33);
+SLEEP(0.33)
+0
+SELECT SLEEP(0.34);
+SLEEP(0.34)
+0
+SELECT SLEEP(0.35);
+SLEEP(0.35)
+0
+SELECT SLEEP(0.36);
+SLEEP(0.36)
+0
+SELECT SLEEP(0.37);
+SLEEP(0.37)
+0
+SELECT SLEEP(0.38);
+SLEEP(0.38)
+0
+SELECT SLEEP(0.39);
+SLEEP(0.39)
+0
+SELECT SLEEP(0.40);
+SLEEP(0.40)
+0
+SELECT SLEEP(1.1);
+SLEEP(1.1)
+0
+SELECT SLEEP(1.2);
+SLEEP(1.2)
+0
+SELECT SLEEP(1.3);
+SLEEP(1.3)
+0
+SELECT SLEEP(1.5);
+SLEEP(1.5)
+0
+SELECT SLEEP(1.4);
+SLEEP(1.4)
+0
+SELECT SLEEP(0.5);
+SLEEP(0.5)
+0
+SELECT SLEEP(2.1);
+SLEEP(2.1)
+0
+SELECT SLEEP(2.3);
+SLEEP(2.3)
+0
+SELECT SLEEP(2.5);
+SLEEP(2.5)
+0
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+1 20 5 44
+10 20 5 44
+1 20 5 44
+5 20 5 44
+3 20 5 44
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+44
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000001
+ 0.000003
+ 0.000007
+ 0.000015
+ 0.000030
+ 0.000061
+ 0.000122
+ 0.000244
+ 0.000488
+ 0.000976
+ 0.001953
+ 0.003906
+ 0.007812
+ 0.015625
+ 0.031250
+ 0.062500
+ 0.125000
+ 0.250000
+ 0.500000
+ 1.000000
+ 2.000000
+ 4.000000
+ 8.000000
+ 16.000000
+ 32.000000
+ 64.000000
+ 128.000000
+ 256.000000
+ 512.000000
+ 1024.000000
+ 2048.000000
+ 4096.000000
+ 8192.000000
+ 16384.000000
+ 32768.000000
+ 65536.000000
+ 131072.000000
+ 262144.000000
+ 524288.000000
+ 1048576.00000
+ 2097152.00000
+ 4194304.00000
+ 8388608.00000
+TOO LONG QUERY
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 2
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 10;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 10
+FLUSH QUERY_RESPONSE_TIME;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT SLEEP(0.31);
+SLEEP(0.31)
+0
+SELECT SLEEP(0.32);
+SLEEP(0.32)
+0
+SELECT SLEEP(0.33);
+SLEEP(0.33)
+0
+SELECT SLEEP(0.34);
+SLEEP(0.34)
+0
+SELECT SLEEP(0.35);
+SLEEP(0.35)
+0
+SELECT SLEEP(0.36);
+SLEEP(0.36)
+0
+SELECT SLEEP(0.37);
+SLEEP(0.37)
+0
+SELECT SLEEP(0.38);
+SLEEP(0.38)
+0
+SELECT SLEEP(0.39);
+SLEEP(0.39)
+0
+SELECT SLEEP(0.40);
+SLEEP(0.40)
+0
+SELECT SLEEP(1.1);
+SLEEP(1.1)
+0
+SELECT SLEEP(1.2);
+SLEEP(1.2)
+0
+SELECT SLEEP(1.3);
+SLEEP(1.3)
+0
+SELECT SLEEP(1.5);
+SLEEP(1.5)
+0
+SELECT SLEEP(1.4);
+SLEEP(1.4)
+0
+SELECT SLEEP(0.5);
+SLEEP(0.5)
+0
+SELECT SLEEP(2.1);
+SLEEP(2.1)
+0
+SELECT SLEEP(2.3);
+SLEEP(2.3)
+0
+SELECT SLEEP(2.5);
+SLEEP(2.5)
+0
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+1 20 3 14
+11 20 3 14
+8 20 3 14
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+14
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000001
+ 0.000010
+ 0.000100
+ 0.001000
+ 0.010000
+ 0.100000
+ 1.000000
+ 10.000000
+ 100.000000
+ 1000.000000
+ 10000.000000
+ 100000.000000
+ 1000000.00000
+TOO LONG QUERY
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 10
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 7;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 7
+FLUSH QUERY_RESPONSE_TIME;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT SLEEP(0.31);
+SLEEP(0.31)
+0
+SELECT SLEEP(0.32);
+SLEEP(0.32)
+0
+SELECT SLEEP(0.33);
+SLEEP(0.33)
+0
+SELECT SLEEP(0.34);
+SLEEP(0.34)
+0
+SELECT SLEEP(0.35);
+SLEEP(0.35)
+0
+SELECT SLEEP(0.36);
+SLEEP(0.36)
+0
+SELECT SLEEP(0.37);
+SLEEP(0.37)
+0
+SELECT SLEEP(0.38);
+SLEEP(0.38)
+0
+SELECT SLEEP(0.39);
+SLEEP(0.39)
+0
+SELECT SLEEP(0.40);
+SLEEP(0.40)
+0
+SELECT SLEEP(1.1);
+SLEEP(1.1)
+0
+SELECT SLEEP(1.2);
+SLEEP(1.2)
+0
+SELECT SLEEP(1.3);
+SLEEP(1.3)
+0
+SELECT SLEEP(1.5);
+SLEEP(1.5)
+0
+SELECT SLEEP(1.4);
+SLEEP(1.4)
+0
+SELECT SLEEP(0.5);
+SLEEP(0.5)
+0
+SELECT SLEEP(2.1);
+SLEEP(2.1)
+0
+SELECT SLEEP(2.3);
+SLEEP(2.3)
+0
+SELECT SLEEP(2.5);
+SLEEP(2.5)
+0
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+1 20 3 17
+11 20 3 17
+8 20 3 17
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+17
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000001
+ 0.000008
+ 0.000059
+ 0.000416
+ 0.002915
+ 0.020408
+ 0.142857
+ 1.000000
+ 7.000000
+ 49.000000
+ 343.000000
+ 2401.000000
+ 16807.000000
+ 117649.000000
+ 823543.000000
+ 5764801.00000
+TOO LONG QUERY
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 7
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 156;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 156
+FLUSH QUERY_RESPONSE_TIME;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT SLEEP(0.31);
+SLEEP(0.31)
+0
+SELECT SLEEP(0.32);
+SLEEP(0.32)
+0
+SELECT SLEEP(0.33);
+SLEEP(0.33)
+0
+SELECT SLEEP(0.34);
+SLEEP(0.34)
+0
+SELECT SLEEP(0.35);
+SLEEP(0.35)
+0
+SELECT SLEEP(0.36);
+SLEEP(0.36)
+0
+SELECT SLEEP(0.37);
+SLEEP(0.37)
+0
+SELECT SLEEP(0.38);
+SLEEP(0.38)
+0
+SELECT SLEEP(0.39);
+SLEEP(0.39)
+0
+SELECT SLEEP(0.40);
+SLEEP(0.40)
+0
+SELECT SLEEP(1.1);
+SLEEP(1.1)
+0
+SELECT SLEEP(1.2);
+SLEEP(1.2)
+0
+SELECT SLEEP(1.3);
+SLEEP(1.3)
+0
+SELECT SLEEP(1.5);
+SLEEP(1.5)
+0
+SELECT SLEEP(1.4);
+SLEEP(1.4)
+0
+SELECT SLEEP(0.5);
+SLEEP(0.5)
+0
+SELECT SLEEP(2.1);
+SLEEP(2.1)
+0
+SELECT SLEEP(2.3);
+SLEEP(2.3)
+0
+SELECT SLEEP(2.5);
+SLEEP(2.5)
+0
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+1 20 3 7
+11 20 3 7
+8 20 3 7
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+7
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000041
+ 0.006410
+ 1.000000
+ 156.000000
+ 24336.000000
+ 3796416.00000
+TOO LONG QUERY
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 156
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1000;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 1000
+FLUSH QUERY_RESPONSE_TIME;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+SELECT SLEEP(0.31);
+SLEEP(0.31)
+0
+SELECT SLEEP(0.32);
+SLEEP(0.32)
+0
+SELECT SLEEP(0.33);
+SLEEP(0.33)
+0
+SELECT SLEEP(0.34);
+SLEEP(0.34)
+0
+SELECT SLEEP(0.35);
+SLEEP(0.35)
+0
+SELECT SLEEP(0.36);
+SLEEP(0.36)
+0
+SELECT SLEEP(0.37);
+SLEEP(0.37)
+0
+SELECT SLEEP(0.38);
+SLEEP(0.38)
+0
+SELECT SLEEP(0.39);
+SLEEP(0.39)
+0
+SELECT SLEEP(0.40);
+SLEEP(0.40)
+0
+SELECT SLEEP(1.1);
+SLEEP(1.1)
+0
+SELECT SLEEP(1.2);
+SLEEP(1.2)
+0
+SELECT SLEEP(1.3);
+SLEEP(1.3)
+0
+SELECT SLEEP(1.5);
+SLEEP(1.5)
+0
+SELECT SLEEP(1.4);
+SLEEP(1.4)
+0
+SELECT SLEEP(0.5);
+SLEEP(0.5)
+0
+SELECT SLEEP(2.1);
+SLEEP(2.1)
+0
+SELECT SLEEP(2.3);
+SLEEP(2.3)
+0
+SELECT SLEEP(2.5);
+SLEEP(2.5)
+0
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SELECT c.count,
+(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a WHERE a.count != 0) as query_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b WHERE b.count != 0) as not_zero_region_count,
+(SELECT COUNT(*) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
+FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c WHERE c.count > 0;
+count query_count not_zero_region_count region_count
+1 20 3 6
+11 20 3 6
+8 20 3 6
+SELECT COUNT(*) as region_count FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+region_count
+6
+SELECT time FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+time
+ 0.000001
+ 0.001000
+ 1.000000
+ 1000.000000
+ 1000000.00000
+TOO LONG QUERY
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 1000
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1001;
+Warnings:
+Warning 1292 Truncated incorrect query_response_time_range_base value: '1001'
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+Variable_name Value
+query_response_time_range_base 1000
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE =10;
diff --git a/mysql-test/suite/percona/percona_query_response_time.test b/mysql-test/suite/percona/percona_query_response_time.test
new file mode 100644
index 00000000000..a58cafc8d01
--- /dev/null
+++ b/mysql-test/suite/percona/percona_query_response_time.test
@@ -0,0 +1,65 @@
+source include/have_innodb.inc;
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 2;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+source include/percona_query_response_time_flush.inc;
+source include/percona_query_response_time_show.inc;
+
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+source include/percona_query_response_time_sleep.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+
+source include/percona_query_response_time_show.inc;
+
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 10;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+source include/percona_query_response_time_flush.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+source include/percona_query_response_time_sleep.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+
+source include/percona_query_response_time_show.inc;
+
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 7;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+source include/percona_query_response_time_flush.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+source include/percona_query_response_time_sleep.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+
+source include/percona_query_response_time_show.inc;
+
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 156;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+source include/percona_query_response_time_flush.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+source include/percona_query_response_time_sleep.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+
+source include/percona_query_response_time_show.inc;
+
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1000;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+source include/percona_query_response_time_flush.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=1;
+source include/percona_query_response_time_sleep.inc;
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+
+source include/percona_query_response_time_show.inc;
+
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE = 1001;
+SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE';
+
+SET GLOBAL ENABLE_QUERY_RESPONSE_TIME_STATS=0;
+SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE =10;
diff --git a/mysql-test/suite/percona/percona_server_variables.result b/mysql-test/suite/percona/percona_server_variables.result
new file mode 100644
index 00000000000..25f961b201f
--- /dev/null
+++ b/mysql-test/suite/percona/percona_server_variables.result
@@ -0,0 +1,340 @@
+show variables;
+Variable_name Value
+auto_increment_increment Value
+auto_increment_offset Value
+autocommit Value
+automatic_sp_privileges Value
+back_log Value
+basedir Value
+big_tables Value
+binlog_cache_size Value
+binlog_direct_non_transactional_updates Value
+binlog_format Value
+bulk_insert_buffer_size Value
+character_set_client Value
+character_set_connection Value
+character_set_database Value
+character_set_filesystem Value
+character_set_results Value
+character_set_server Value
+character_set_system Value
+character_sets_dir Value
+collation_connection Value
+collation_database Value
+collation_server Value
+completion_type Value
+concurrent_insert Value
+connect_timeout Value
+datadir Value
+date_format Value
+datetime_format Value
+debug Value
+debug_sync Value
+default_week_format Value
+delay_key_write Value
+delayed_insert_limit Value
+delayed_insert_timeout Value
+delayed_queue_size Value
+div_precision_increment Value
+enable_query_response_time_stats Value
+engine_condition_pushdown Value
+error_count Value
+event_scheduler Value
+expire_logs_days Value
+fast_index_creation Value
+flush Value
+flush_time Value
+foreign_key_checks Value
+ft_boolean_syntax Value
+ft_max_word_len Value
+ft_min_word_len Value
+ft_query_expansion_limit Value
+ft_stopword_file Value
+general_log Value
+general_log_file Value
+group_concat_max_len Value
+have_community_features Value
+have_compress Value
+have_crypt Value
+have_csv Value
+have_dynamic_loading Value
+have_geometry Value
+have_innodb Value
+have_ndbcluster Value
+have_openssl Value
+have_partitioning Value
+have_query_cache Value
+have_rtree_keys Value
+have_ssl Value
+have_symlink Value
+hostname Value
+identity Value
+ignore_builtin_innodb Value
+init_connect Value
+init_file Value
+init_slave Value
+innodb_adaptive_checkpoint Value
+innodb_adaptive_flushing Value
+innodb_adaptive_hash_index Value
+innodb_additional_mem_pool_size Value
+innodb_autoextend_increment Value
+innodb_autoinc_lock_mode Value
+innodb_buffer_pool_shm_key Value
+innodb_buffer_pool_size Value
+innodb_change_buffering Value
+innodb_checkpoint_age_target Value
+innodb_checksums Value
+innodb_commit_concurrency Value
+innodb_concurrency_tickets Value
+innodb_data_file_path Value
+innodb_data_home_dir Value
+innodb_dict_size_limit Value
+innodb_doublewrite Value
+innodb_doublewrite_file Value
+innodb_enable_unsafe_group_commit Value
+innodb_expand_import Value
+innodb_extra_rsegments Value
+innodb_extra_undoslots Value
+innodb_fast_checksum Value
+innodb_fast_recovery Value
+innodb_fast_shutdown Value
+innodb_file_format Value
+innodb_file_format_check Value
+innodb_file_per_table Value
+innodb_flush_log_at_trx_commit Value
+innodb_flush_log_at_trx_commit_session Value
+innodb_flush_method Value
+innodb_flush_neighbor_pages Value
+innodb_force_recovery Value
+innodb_ibuf_accel_rate Value
+innodb_ibuf_active_contract Value
+innodb_ibuf_max_size Value
+innodb_io_capacity Value
+innodb_lock_wait_timeout Value
+innodb_locks_unsafe_for_binlog Value
+innodb_log_buffer_size Value
+innodb_log_file_size Value
+innodb_log_files_in_group Value
+innodb_log_group_home_dir Value
+innodb_max_dirty_pages_pct Value
+innodb_max_purge_lag Value
+innodb_mirrored_log_groups Value
+innodb_old_blocks_pct Value
+innodb_old_blocks_time Value
+innodb_open_files Value
+innodb_overwrite_relay_log_info Value
+innodb_page_size Value
+innodb_pass_corrupt_table Value
+innodb_read_ahead Value
+innodb_read_ahead_threshold Value
+innodb_read_io_threads Value
+innodb_recovery_stats Value
+innodb_replication_delay Value
+innodb_rollback_on_timeout Value
+innodb_show_locks_held Value
+innodb_show_verbose_locks Value
+innodb_spin_wait_delay Value
+innodb_stats_auto_update Value
+innodb_stats_method Value
+innodb_stats_on_metadata Value
+innodb_stats_sample_pages Value
+innodb_stats_update_need_lock Value
+innodb_strict_mode Value
+innodb_support_xa Value
+innodb_sync_spin_loops Value
+innodb_table_locks Value
+innodb_thread_concurrency Value
+innodb_thread_concurrency_timer_based Value
+innodb_thread_sleep_delay Value
+innodb_use_purge_thread Value
+innodb_use_sys_malloc Value
+innodb_use_sys_stats_table Value
+innodb_version Value
+innodb_write_io_threads Value
+insert_id Value
+interactive_timeout Value
+join_buffer_size Value
+keep_files_on_create Value
+key_buffer_size Value
+key_cache_age_threshold Value
+key_cache_block_size Value
+key_cache_division_limit Value
+language Value
+large_files_support Value
+large_page_size Value
+large_pages Value
+last_insert_id Value
+lc_time_names Value
+license Value
+local_infile Value
+locked_in_memory Value
+log Value
+log_bin Value
+log_bin_trust_function_creators Value
+log_bin_trust_routine_creators Value
+log_error Value
+log_output Value
+log_queries_not_using_indexes Value
+log_slave_updates Value
+log_slow_filter Value
+log_slow_queries Value
+log_slow_rate_limit Value
+log_slow_slave_statements Value
+log_slow_sp_statements Value
+log_slow_timestamp_every Value
+log_slow_verbosity Value
+log_warnings Value
+long_query_time Value
+low_priority_updates Value
+lower_case_file_system Value
+lower_case_table_names Value
+max_allowed_packet Value
+max_binlog_cache_size Value
+max_binlog_size Value
+max_connect_errors Value
+max_connections Value
+max_delayed_threads Value
+max_error_count Value
+max_heap_table_size Value
+max_insert_delayed_threads Value
+max_join_size Value
+max_length_for_sort_data Value
+max_prepared_stmt_count Value
+max_relay_log_size Value
+max_seeks_for_key Value
+max_sort_length Value
+max_sp_recursion_depth Value
+max_tmp_tables Value
+max_user_connections Value
+max_write_lock_count Value
+min_examined_row_limit Value
+multi_range_count Value
+myisam_data_pointer_size Value
+myisam_max_sort_file_size Value
+myisam_mmap_size Value
+myisam_recover_options Value
+myisam_repair_threads Value
+myisam_sort_buffer_size Value
+myisam_stats_method Value
+myisam_use_mmap Value
+net_buffer_length Value
+net_read_timeout Value
+net_retry_count Value
+net_write_timeout Value
+new Value
+old Value
+old_alter_table Value
+old_passwords Value
+open_files_limit Value
+optimizer_fix Value
+optimizer_prune_level Value
+optimizer_search_depth Value
+optimizer_switch Value
+pid_file Value
+plugin_dir Value
+port Value
+preload_buffer_size Value
+profiling Value
+profiling_history_size Value
+profiling_server Value
+profiling_use_getrusage Value
+protocol_version Value
+pseudo_thread_id Value
+query_alloc_block_size Value
+query_cache_limit Value
+query_cache_min_res_unit Value
+query_cache_size Value
+query_cache_strip_comments Value
+query_cache_type Value
+query_cache_wlock_invalidate Value
+query_prealloc_size Value
+query_response_time_range_base Value
+rand_seed1 Value
+rand_seed2 Value
+range_alloc_block_size Value
+read_buffer_size Value
+read_only Value
+read_rnd_buffer_size Value
+relay_log Value
+relay_log_index Value
+relay_log_info_file Value
+relay_log_purge Value
+relay_log_space_limit Value
+report_host Value
+report_password Value
+report_port Value
+report_user Value
+rpl_recovery_rank Value
+secure_auth Value
+secure_file_priv Value
+server_id Value
+skip_external_locking Value
+skip_name_resolve Value
+skip_networking Value
+skip_show_database Value
+slave_compressed_protocol Value
+slave_exec_mode Value
+slave_load_tmpdir Value
+slave_net_timeout Value
+slave_skip_errors Value
+slave_transaction_retries Value
+slow_launch_time Value
+slow_query_log Value
+slow_query_log_file Value
+slow_query_log_microseconds_timestamp Value
+socket Value
+sort_buffer_size Value
+sql_auto_is_null Value
+sql_big_selects Value
+sql_big_tables Value
+sql_buffer_result Value
+sql_log_bin Value
+sql_log_off Value
+sql_log_update Value
+sql_low_priority_updates Value
+sql_max_join_size Value
+sql_mode Value
+sql_notes Value
+sql_quote_show_create Value
+sql_safe_updates Value
+sql_select_limit Value
+sql_slave_skip_counter Value
+sql_warnings Value
+ssl_ca Value
+ssl_capath Value
+ssl_cert Value
+ssl_cipher Value
+ssl_key Value
+storage_engine Value
+suppress_log_warning_1592 Value
+sync_binlog Value
+sync_frm Value
+system_time_zone Value
+table_definition_cache Value
+table_lock_wait_timeout Value
+table_open_cache Value
+table_type Value
+thread_cache_size Value
+thread_handling Value
+thread_stack Value
+thread_statistics Value
+time_format Value
+time_zone Value
+timed_mutexes Value
+timestamp Value
+tmp_table_size Value
+tmpdir Value
+transaction_alloc_block_size Value
+transaction_prealloc_size Value
+tx_isolation Value
+unique_checks Value
+updatable_views_with_limit Value
+use_global_log_slow_control Value
+use_global_long_query_time Value
+userstat_running Value
+version Value
+version_comment Value
+version_compile_machine Value
+version_compile_os Value
+wait_timeout Value
+warning_count Value
diff --git a/mysql-test/suite/percona/percona_server_variables.test b/mysql-test/suite/percona/percona_server_variables.test
new file mode 100644
index 00000000000..232cbb15e25
--- /dev/null
+++ b/mysql-test/suite/percona/percona_server_variables.test
@@ -0,0 +1,7 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+#check the list of variable names
+--replace_column 2 Value
+show variables;
+
diff --git a/mysql-test/suite/percona/percona_slave_innodb_stats-master.opt b/mysql-test/suite/percona/percona_slave_innodb_stats-master.opt
new file mode 100644
index 00000000000..286a9c4484d
--- /dev/null
+++ b/mysql-test/suite/percona/percona_slave_innodb_stats-master.opt
@@ -0,0 +1 @@
+--long_query_time=0 --log_slow_verbosity=innodb --log_slow_slave_statements
diff --git a/mysql-test/suite/percona/percona_slave_innodb_stats-slave.opt b/mysql-test/suite/percona/percona_slave_innodb_stats-slave.opt
new file mode 100644
index 00000000000..286a9c4484d
--- /dev/null
+++ b/mysql-test/suite/percona/percona_slave_innodb_stats-slave.opt
@@ -0,0 +1 @@
+--long_query_time=0 --log_slow_verbosity=innodb --log_slow_slave_statements
diff --git a/mysql-test/suite/percona/percona_slave_innodb_stats.result b/mysql-test/suite/percona/percona_slave_innodb_stats.result
new file mode 100644
index 00000000000..c2406bdfd85
--- /dev/null
+++ b/mysql-test/suite/percona/percona_slave_innodb_stats.result
@@ -0,0 +1,21 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP TABLE IF EXISTS t;
+CREATE TABLE t(id INT,data CHAR(30)) ENGINE=InnoDB;
+INSERT INTO t VALUES
+(1,"aaaaabbbbbcccccdddddeeeeefffff"),
+(2,"aaaaabbbbbcccccdddddeeeeefffff"),
+(3,"aaaaabbbbbcccccdddddeeeeefffff"),
+(4,"aaaaabbbbbcccccdddddeeeeefffff"),
+(5,"aaaaabbbbbcccccdddddeeeeefffff");
+INSERT INTO t SELECT t2.id,t2.data from t as t1, t as t2;
+INSERT INTO t SELECT t2.id,t2.data from t as t1, t as t2;
+STOP SLAVE;
+START SLAVE;
+INSERT INTO t SELECT t.id,t.data from t;
+DROP TABLE IF EXISTS t;
+4
diff --git a/mysql-test/suite/percona/percona_slave_innodb_stats.test b/mysql-test/suite/percona/percona_slave_innodb_stats.test
new file mode 100644
index 00000000000..defcd1fc406
--- /dev/null
+++ b/mysql-test/suite/percona/percona_slave_innodb_stats.test
@@ -0,0 +1,43 @@
+source include/have_innodb.inc;
+source include/master-slave.inc;
+
+connection master;
+-- disable_warnings
+DROP TABLE IF EXISTS t;
+-- enable_warnings
+CREATE TABLE t(id INT,data CHAR(30)) ENGINE=InnoDB;
+INSERT INTO t VALUES
+(1,"aaaaabbbbbcccccdddddeeeeefffff"),
+(2,"aaaaabbbbbcccccdddddeeeeefffff"),
+(3,"aaaaabbbbbcccccdddddeeeeefffff"),
+(4,"aaaaabbbbbcccccdddddeeeeefffff"),
+(5,"aaaaabbbbbcccccdddddeeeeefffff");
+INSERT INTO t SELECT t2.id,t2.data from t as t1, t as t2;
+INSERT INTO t SELECT t2.id,t2.data from t as t1, t as t2;
+sync_slave_with_master;
+
+connection slave;
+STOP SLAVE;
+-- source include/wait_for_slave_to_stop.inc
+--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+wait
+EOF
+--shutdown_server 10
+--source include/wait_until_disconnected.inc
+--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+restart
+EOF
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+START SLAVE;
+-- source include/wait_for_slave_to_start.inc
+
+connection master;
+INSERT INTO t SELECT t.id,t.data from t;
+sync_slave_with_master;
+
+connection master;
+DROP TABLE IF EXISTS t;
+sync_slave_with_master;
+
+exec cat var/mysqld.2/mysqld-slow.log | grep InnoDB_IO_r_ops | wc -l;
diff --git a/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.result b/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.result
index 759f0636b5c..e294525fdd2 100644
--- a/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.result
+++ b/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.result
@@ -22,3 +22,38 @@ set global long_query_time=2;
set global use_global_long_query_time=0;
cat MYSQLD_DATADIR/percona_slow_query_log-use_global_long_query_time.log | grep -c Query_time
3
+show global variables like 'use_global_log_slow_control';
+Variable_name Value
+use_global_log_slow_control none
+show global variables like 'use_global_long_query_time';
+Variable_name Value
+use_global_long_query_time OFF
+set global use_global_log_slow_control = long_query_time;
+show global variables like 'use_global_log_slow_control';
+Variable_name Value
+use_global_log_slow_control long_query_time
+show global variables like 'use_global_long_query_time';
+Variable_name Value
+use_global_long_query_time ON
+set global use_global_log_slow_control = log_slow_filter;
+show global variables like 'use_global_log_slow_control';
+Variable_name Value
+use_global_log_slow_control log_slow_filter
+show global variables like 'use_global_long_query_time';
+Variable_name Value
+use_global_long_query_time OFF
+set global use_global_long_query_time = ON;
+show global variables like 'use_global_log_slow_control';
+Variable_name Value
+use_global_log_slow_control log_slow_filter,long_query_time
+show global variables like 'use_global_long_query_time';
+Variable_name Value
+use_global_long_query_time ON
+set global use_global_long_query_time = OFF;
+show global variables like 'use_global_log_slow_control';
+Variable_name Value
+use_global_log_slow_control log_slow_filter
+show global variables like 'use_global_long_query_time';
+Variable_name Value
+use_global_long_query_time OFF
+set global use_global_log_slow_control = none;
diff --git a/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.test b/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.test
index 70021da1e4c..da627ae72b0 100644
--- a/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.test
+++ b/mysql-test/suite/percona/percona_slow_query_log-use_global_long_query_time.test
@@ -20,3 +20,24 @@ let $cmd = cat $MYSQLD_DATADIR/percona_slow_query_log-use_global_long_query_time
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
exec echo '$cmd';
exec $cmd;
+
+show global variables like 'use_global_log_slow_control';
+show global variables like 'use_global_long_query_time';
+
+set global use_global_log_slow_control = long_query_time;
+show global variables like 'use_global_log_slow_control';
+show global variables like 'use_global_long_query_time';
+
+set global use_global_log_slow_control = log_slow_filter;
+show global variables like 'use_global_log_slow_control';
+show global variables like 'use_global_long_query_time';
+
+set global use_global_long_query_time = ON;
+show global variables like 'use_global_log_slow_control';
+show global variables like 'use_global_long_query_time';
+
+set global use_global_long_query_time = OFF;
+show global variables like 'use_global_log_slow_control';
+show global variables like 'use_global_long_query_time';
+
+set global use_global_log_slow_control = none;
diff --git a/mysql-test/suite/percona/percona_sql_no_fcache.result b/mysql-test/suite/percona/percona_sql_no_fcache.result
new file mode 100644
index 00000000000..bc1413fb96d
--- /dev/null
+++ b/mysql-test/suite/percona/percona_sql_no_fcache.result
@@ -0,0 +1,12 @@
+drop table if exists t1;
+create table t (a int not null);
+insert into t values (1),(2),(3);
+SELECT SQL_NO_FCACHE SLEEP(0);
+SLEEP(0)
+0
+SELECT /*!40001 SQL_NO_CACHE */ /*!50084 SQL_NO_FCACHE */ * FROM t;
+a
+1
+2
+3
+DROP TABLE t;
diff --git a/mysql-test/suite/percona/percona_sql_no_fcache.test b/mysql-test/suite/percona/percona_sql_no_fcache.test
new file mode 100644
index 00000000000..da0c2ecef7d
--- /dev/null
+++ b/mysql-test/suite/percona/percona_sql_no_fcache.test
@@ -0,0 +1,11 @@
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t (a int not null);
+insert into t values (1),(2),(3);
+
+SELECT SQL_NO_FCACHE SLEEP(0);
+SELECT /*!40001 SQL_NO_CACHE */ /*!50084 SQL_NO_FCACHE */ * FROM t;
+
+DROP TABLE t; \ No newline at end of file
diff --git a/mysql-test/suite/percona/percona_status_wait_query_cache_mutex.result b/mysql-test/suite/percona/percona_status_wait_query_cache_mutex.result
new file mode 100644
index 00000000000..348dcef4d30
--- /dev/null
+++ b/mysql-test/suite/percona/percona_status_wait_query_cache_mutex.result
@@ -0,0 +1,27 @@
+set GLOBAL query_cache_size=1355776;
+flush query cache;
+flush query cache;
+reset query cache;
+flush status;
+DROP TABLE IF EXISTS t;
+CREATE TABLE t(id INT, number INT);
+INSERT INTO t VALUES (0,1);
+INSERT INTO t VALUES (1,2);
+INSERT INTO t VALUES (2,3);
+SELECT number from t where id > 0;
+number
+2
+3
+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
+SELECT number from t where id > 0;
+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
+SELECT number from t where id > 0;
+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
+SHOW PROCESSLIST;
+Id User Host db Command Time State Info
+Id root localhost test Sleep Time NULL
+Id root localhost test Query Time Waiting on query cache mutex SELECT number from t where id > 0
+Id root localhost test Query Time Waiting on query cache mutex SELECT number from t where id > 0
+Id root localhost test Query Time NULL SHOW PROCESSLIST
+DROP TABLE t;
+set GLOBAL query_cache_size=0;
diff --git a/mysql-test/suite/percona/percona_status_wait_query_cache_mutex.test b/mysql-test/suite/percona/percona_status_wait_query_cache_mutex.test
new file mode 100644
index 00000000000..64a9fe7db71
--- /dev/null
+++ b/mysql-test/suite/percona/percona_status_wait_query_cache_mutex.test
@@ -0,0 +1,37 @@
+--source include/have_query_cache.inc
+--source include/have_debug.inc
+set GLOBAL query_cache_size=1355776;
+--source include/percona_query_cache_with_comments_clear.inc
+
+-- disable_warnings
+DROP TABLE IF EXISTS t;
+-- enable_warnings
+CREATE TABLE t(id INT, number INT);
+INSERT INTO t VALUES (0,1);
+INSERT INTO t VALUES (1,2);
+INSERT INTO t VALUES (2,3);
+SELECT number from t where id > 0;
+--connect (conn0,localhost,root,,)
+--connect (conn1,localhost,root,,)
+--connect (conn2,localhost,root,,)
+
+--connection conn0
+--error 0, ER_UNKNOWN_SYSTEM_VARIABLE
+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
+SEND SELECT number from t where id > 0;
+SLEEP 1.0;
+
+--connection conn1
+--error 0, ER_UNKNOWN_SYSTEM_VARIABLE
+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
+SEND SELECT number from t where id > 0;
+SLEEP 1.0;
+
+--connection conn2
+--error 0, ER_UNKNOWN_SYSTEM_VARIABLE
+SET SESSION debug="+d,status_wait_query_cache_mutex_sleep";
+--replace_column 1 Id 6 Time
+SHOW PROCESSLIST;
+
+DROP TABLE t;
+set GLOBAL query_cache_size=0; \ No newline at end of file
diff --git a/mysql-test/suite/percona/percona_xtradb_bug317074.test b/mysql-test/suite/percona/percona_xtradb_bug317074.test
index 91c59cefb73..abf5d8ee1f6 100644
--- a/mysql-test/suite/percona/percona_xtradb_bug317074.test
+++ b/mysql-test/suite/percona/percona_xtradb_bug317074.test
@@ -22,15 +22,18 @@ CREATE PROCEDURE insert_many(p1 int)
BEGIN
SET @x = 0;
SET @y = 0;
+start transaction;
REPEAT
insert into test1 set b=1;
SET @x = @x + 1;
SET @y = @y + 1;
IF @y >= 1000 THEN
commit;
+ start transaction;
SET @y = 0;
END IF;
UNTIL @x >= p1 END REPEAT;
+commit;
END|
delimiter ;|
call insert_many(100000);
diff --git a/mysql-test/suite/rpl/r/rpl_conditional_comments.result b/mysql-test/suite/rpl/r/rpl_conditional_comments.result
new file mode 100644
index 00000000000..105d3bc59f3
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_conditional_comments.result
@@ -0,0 +1,57 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1(c1 INT);
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
+
+# Case 1:
+# ------------------------------------------------------------------
+# In a statement, some CCs are applied while others are not. The CCs
+# which are not applied on master will be binlogged as common comments.
+/*!99999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /*!99999 ,(11)*/;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; /* 99999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /* 99999 ,(11)*/
+Comparing tables master:test.t1 and slave:test.t1
+
+# Case 2:
+# -----------------------------------------------------------------
+# Verify whether it can be binlogged correctly when executing prepared
+# statement.
+PREPARE stmt FROM 'INSERT INTO /*!99999 blabla*/ t1 VALUES(60) /*!99999 ,(61)*/';
+EXECUTE stmt;
+DROP TABLE t1;
+CREATE TABLE t1(c1 INT);
+EXECUTE stmt;
+Comparing tables master:test.t1 and slave:test.t1
+
+SET @value=62;
+PREPARE stmt FROM 'INSERT INTO /*!99999 blabla */ t1 VALUES(?) /*!99999 ,(63)*/';
+EXECUTE stmt USING @value;
+DROP TABLE t1;
+CREATE TABLE t1(c1 INT);
+EXECUTE stmt USING @value;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla*/ t1 VALUES(60) /* 99999 ,(61)*/
+master-bin.000001 # Query # # use `test`; DROP TABLE t1
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
+master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla*/ t1 VALUES(60) /* 99999 ,(61)*/
+master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla */ t1 VALUES(62) /* 99999 ,(63)*/
+master-bin.000001 # Query # # use `test`; DROP TABLE t1
+master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
+master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla */ t1 VALUES(62) /* 99999 ,(63)*/
+Comparing tables master:test.t1 and slave:test.t1
+
+# Case 3:
+# -----------------------------------------------------------------
+# Verify it can restore the '!', if the it is an uncomplete conditional
+# comments
+SELECT c1 FROM /*!99999 t1 WHEREN;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*!99999 t1 WHEREN' at line 1
+DROP TABLE t1;
diff --git a/mysql-test/suite/rpl/r/rpl_current_user.result b/mysql-test/suite/rpl/r/rpl_current_user.result
new file mode 100644
index 00000000000..85490c2571c
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_current_user.result
@@ -0,0 +1,205 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+
+# On slave2
+# Connect slave2 to slave
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=SLAVE_MYPORT;,
+MASTER_LOG_FILE='slave-bin.000001', MASTER_USER='root';
+START SLAVE;
+
+# [On master]
+DROP VIEW IF EXISTS v_user;
+DROP VIEW IF EXISTS v_tables_priv;
+DROP VIEW IF EXISTS v_procs_priv;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS my_grant;
+DROP PROCEDURE IF EXISTS my_revoke;
+DROP FUNCTION IF EXISTS my_user;
+DROP EVENT IF EXISTS e1;
+CREATE TABLE t1(c1 char(100));
+CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%';
+CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%';
+CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%';
+CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1';
+CREATE PROCEDURE p1() SELECT 1;
+# bug48321_1-01234 has the max length(16) of user.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION;
+
+# Make sure the max lengths of user and host
+# the user name is too lengh
+GRANT CREATE USER ON *.* TO '01234567890123456'@'fakehost';
+ERROR HY000: String '01234567890123456' is too long for user name (should be no longer than 16)
+# the host name is too lengh
+GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890';
+ERROR HY000: String '0123456789012345678901234567890123456789012345678901234567890' is too long for host name (should be no longer than 60)
+
+# User 'bug48321_1-01234' connects to master by conn1
+# [On conn1]
+# Verify 'REVOKE ALL' statement
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER();
+Comparing tables master:test.v_user and slave:test.v_user
+Comparing tables master:test.v_user and slave2:test.v_user
+
+# Verify 'GRANT ... ON TABLE ...' statement
+GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER();
+Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv
+Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv
+
+# Verify 'GRANT ... ON PROCEDURE...' statement
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER();
+Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv
+Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv
+
+# Verify 'GRANT ... ON *.* ...' statement
+GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION;
+Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv
+Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv
+
+# Verify 'REVOKE ... ON TABLE ...' statement
+REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER();
+Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv
+Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv
+
+# Verify 'REVOKE ... ON PROCEDURE...' statement
+REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER();
+Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv
+Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv
+
+# Verify 'REVOKE ... ON *.* ...' statement
+REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER();
+Comparing tables master:test.v_user and slave:test.v_user
+Comparing tables master:test.v_user and slave2:test.v_user
+
+# Verify 'GRANT ...' statement in the procedure
+CREATE PROCEDURE my_grant()
+GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER();
+call my_grant;
+Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv
+Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv
+
+# Verify 'REVOKE ... ON TABLE ...' statement in the procedure
+CREATE PROCEDURE my_revoke()
+REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER();
+call my_revoke;
+Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv
+Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv
+
+# Verify 'RENAME USER ...' statement
+RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost';
+Comparing tables master:test.v_user and slave:test.v_user
+Comparing tables master:test.v_user and slave2:test.v_user
+
+# Verify 'DROP USER ...' statement
+GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost';
+DROP USER CURRENT_USER();
+Comparing tables master:test.v_user and slave:test.v_user
+Comparing tables master:test.v_user and slave2:test.v_user
+
+# Verify 'ALTER EVENT...' statement
+CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1;
+# Explicitly assign CURRENT_USER() to definer
+ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE;
+Comparing tables master:test.v_event and slave:test.v_event
+Comparing tables master:test.v_event and slave2:test.v_event
+
+# Session user will be set as definer, if the statement does not assign
+# a definer
+ALTER EVENT e1 ENABLE;
+Comparing tables master:test.v_event and slave:test.v_event
+Comparing tables master:test.v_event and slave2:test.v_event
+
+# Verify that this patch does not affect the calling of CURRENT_USER()
+# in the other statements
+# [On master]
+INSERT INTO t1 VALUES(CURRENT_USER()), ('1234');
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+SELECT * FROM t1;
+c1
+root@localhost
+1234
+# [On slave]
+SELECT * FROM t1;
+c1
+@
+1234
+# [On slave2]
+SELECT * FROM t1;
+c1
+@
+1234
+# [On master]
+UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234';
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+SELECT * FROM t1;
+c1
+root@localhost
+root@localhost
+# [On slave]
+SELECT * FROM t1;
+c1
+@
+@
+# [On slave2]
+SELECT * FROM t1;
+c1
+@
+@
+# [On master]
+DELETE FROM t1 WHERE c1=CURRENT_USER();
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+SELECT * FROM t1;
+c1
+# [On slave]
+SELECT * FROM t1;
+c1
+# [On slave2]
+SELECT * FROM t1;
+c1
+# [On master]
+CREATE TABLE t2(c1 char(100));
+CREATE FUNCTION my_user() RETURNS VARCHAR(64)
+SQL SECURITY INVOKER
+BEGIN
+INSERT INTO t2 VALUES(CURRENT_USER());
+RETURN CURRENT_USER();
+END |
+INSERT INTO t1 VALUES(my_user());
+Warnings:
+Note 1592 Statement may not be safe to log in statement format.
+Note 1592 Statement may not be safe to log in statement format.
+SELECT * FROM t1;
+c1
+root@localhost
+SELECT * FROM t2;
+c1
+root@localhost
+# [On slave]
+SELECT * FROM t1;
+c1
+@
+SELECT * FROM t2;
+c1
+@
+# [On slave2]
+SELECT * FROM t1;
+c1
+@
+SELECT * FROM t2;
+c1
+@
+
+# END
+DROP TABLE t1, t2;
+DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event;
+DROP PROCEDURE p1;
+DROP PROCEDURE my_grant;
+DROP PROCEDURE my_revoke;
+DROP FUNCTION my_user;
+DROP EVENT e1;
diff --git a/mysql-test/suite/rpl/r/rpl_drop.result b/mysql-test/suite/rpl/r/rpl_drop.result
index b83594c9bb1..5ebbc4f9ce7 100644
--- a/mysql-test/suite/rpl/r/rpl_drop.result
+++ b/mysql-test/suite/rpl/r/rpl_drop.result
@@ -8,3 +8,27 @@ drop table if exists t1, t2;
create table t1 (a int);
drop table t1, t2;
ERROR 42S02: Unknown table 't2'
+include/stop_slave.inc
+SET @old_binlog_format= @@global.binlog_format;
+SET GLOBAL binlog_format = ROW;
+include/start_slave.inc
+SET @old_binlog_format= @@global.binlog_format;
+SET binlog_format = ROW;
+CREATE TABLE t2(a INT) ENGINE=MYISAM;
+CREATE TABLE t3(a INT) ENGINE=INNODB;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+insert into t2 values(1);
+insert into t3 values(1);
+return 1;
+END|
+CREATE TABLE t1(UNIQUE(a)) ENGINE=MYISAM SELECT 1 AS a UNION ALL SELECT f1();
+ERROR 23000: Duplicate entry '1' for key 'a'
+CREATE TABLE t1(UNIQUE(a)) ENGINE=INNODB SELECT 1 AS a UNION ALL SELECT f1();
+ERROR 23000: Duplicate entry '1' for key 'a'
+show binlog events in 'master-bin.000001' from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+DROP FUNCTION f1;
+DROP TABLE t2, t3;
+SET @@global.binlog_format= @old_binlog_format;
+SET @@global.binlog_format= @old_binlog_format;
diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result
index 26f2545dd72..35f4cd3ecbb 100644
--- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result
+++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result
@@ -750,7 +750,7 @@ test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 latin1 lat
USE test_rpl;
SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
-test_rpl e2 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
+test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
==========MASTER==========
SELECT COUNT(*) FROM t1;
COUNT(*)
diff --git a/mysql-test/suite/rpl/r/rpl_packet.result b/mysql-test/suite/rpl/r/rpl_packet.result
index 0a9495751fe..1ec9259a1fb 100644
--- a/mysql-test/suite/rpl/r/rpl_packet.result
+++ b/mysql-test/suite/rpl/r/rpl_packet.result
@@ -49,6 +49,14 @@ Slave_IO_Running = No (expect No)
SELECT "Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master'" AS Last_IO_Error;
Last_IO_Error
Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master'
+STOP SLAVE;
+RESET SLAVE;
+RESET MASTER;
+SET @max_allowed_packet_0= @@session.max_allowed_packet;
+SHOW BINLOG EVENTS;
+SET @max_allowed_packet_1= @@session.max_allowed_packet;
+SHOW BINLOG EVENTS;
+SET @max_allowed_packet_2= @@session.max_allowed_packet;
==== clean up ====
DROP TABLE t1;
SET @@global.max_allowed_packet= 1024;
diff --git a/mysql-test/suite/rpl/t/rpl_conditional_comments.test b/mysql-test/suite/rpl/t/rpl_conditional_comments.test
new file mode 100644
index 00000000000..14251d5eb37
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_conditional_comments.test
@@ -0,0 +1,74 @@
+###############################################################################
+# After the patch for BUG#49124:
+# - Use ' ' instead of '!' in the conditional comments which are not applied on
+# master. So they become common comments and will not be applied on slave.
+#
+# - Example:
+# 'INSERT INTO t1 VALUES (1) /*!10000, (2)*/ /*!99999 ,(3)*/
+# will be binlogged as
+# 'INSERT INTO t1 VALUES (1) /*!10000, (2)*/ /* 99999 ,(3)*/'.
+###############################################################################
+source include/master-slave.inc;
+source include/have_binlog_format_statement.inc;
+
+CREATE TABLE t1(c1 INT);
+source include/show_binlog_events.inc;
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+--echo
+--echo # Case 1:
+--echo # ------------------------------------------------------------------
+--echo # In a statement, some CCs are applied while others are not. The CCs
+--echo # which are not applied on master will be binlogged as common comments.
+
+/*!99999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /*!99999 ,(11)*/;
+
+source include/show_binlog_events.inc;
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+sync_slave_with_master;
+let $diff_table_1=master:test.t1;
+let $diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+
+--echo
+--echo # Case 2:
+--echo # -----------------------------------------------------------------
+--echo # Verify whether it can be binlogged correctly when executing prepared
+--echo # statement.
+PREPARE stmt FROM 'INSERT INTO /*!99999 blabla*/ t1 VALUES(60) /*!99999 ,(61)*/';
+EXECUTE stmt;
+DROP TABLE t1;
+CREATE TABLE t1(c1 INT);
+EXECUTE stmt;
+
+sync_slave_with_master;
+let $diff_table_1=master:test.t1;
+let $diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+
+--echo
+SET @value=62;
+PREPARE stmt FROM 'INSERT INTO /*!99999 blabla */ t1 VALUES(?) /*!99999 ,(63)*/';
+EXECUTE stmt USING @value;
+DROP TABLE t1;
+CREATE TABLE t1(c1 INT);
+EXECUTE stmt USING @value;
+
+source include/show_binlog_events.inc;
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+sync_slave_with_master;
+let $diff_table_1=master:test.t1;
+let $diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+
+--echo
+--echo # Case 3:
+--echo # -----------------------------------------------------------------
+--echo # Verify it can restore the '!', if the it is an uncomplete conditional
+--echo # comments
+--error 1064
+SELECT c1 FROM /*!99999 t1 WHEREN;
+
+DROP TABLE t1;
+source include/master-slave-end.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_current_user.cnf b/mysql-test/suite/rpl/t/rpl_current_user.cnf
new file mode 100644
index 00000000000..999ee727a88
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_current_user.cnf
@@ -0,0 +1,9 @@
+!include ../my.cnf
+
+[mysqld.3]
+server-id=3
+log-bin=slave-bin
+
+[ENV]
+SLAVE_MYPORT1= @mysqld.3.port
+SLAVE_MYSOCK1= @mysqld.3.socket
diff --git a/mysql-test/suite/rpl/t/rpl_current_user.test b/mysql-test/suite/rpl/t/rpl_current_user.test
new file mode 100644
index 00000000000..72581ed7049
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_current_user.test
@@ -0,0 +1,238 @@
+##############################################################################
+# BUG#48321 CURRENT_USER() incorrectly replicated for DROP/RENAME USER,
+# REVOKE, GRANT, ALTER EVENT
+#
+# Calling CURRENT_USER() results into inconsistency between slave and master,
+# as the slave SQL thread has different user with common users.
+#
+# After the patch for bug#48321, session's user will be written into query log
+# event if CURRENT_USER() is called in 'DROP/RENAME USER', 'REVOKE', 'GRANT',
+# 'ALTER EVENT'.
+#
+##############################################################################
+source include/master-slave.inc;
+source include/have_binlog_format_statement.inc;
+
+--echo
+--echo # On slave2
+connect (slave2,127.0.0.1,root,,test,$SLAVE_MYPORT1,);
+connection slave2;
+
+--echo # Connect slave2 to slave
+--replace_result $SLAVE_MYPORT SLAVE_MYPORT;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SLAVE_MYPORT,
+ MASTER_LOG_FILE='slave-bin.000001', MASTER_USER='root';
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+
+--echo
+--echo # [On master]
+connection master;
+--disable_warnings
+DROP VIEW IF EXISTS v_user;
+DROP VIEW IF EXISTS v_tables_priv;
+DROP VIEW IF EXISTS v_procs_priv;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS my_grant;
+DROP PROCEDURE IF EXISTS my_revoke;
+DROP FUNCTION IF EXISTS my_user;
+DROP EVENT IF EXISTS e1;
+--enable_warnings
+CREATE TABLE t1(c1 char(100));
+CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%';
+CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%';
+CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%';
+CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1';
+CREATE PROCEDURE p1() SELECT 1;
+--echo # bug48321_1-01234 has the max length(16) of user.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION;
+
+--echo
+--echo # Make sure the max lengths of user and host
+--echo # the user name is too lengh
+--error 1470
+GRANT CREATE USER ON *.* TO '01234567890123456'@'fakehost';
+--echo # the host name is too lengh
+--error 1470
+GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890';
+
+--echo
+--echo # User 'bug48321_1-01234' connects to master by conn1
+connect (conn1, 127.0.0.1, 'bug48321_1-01234'@'localhost',,);
+connection conn1;
+--echo # [On conn1]
+--echo # Verify 'REVOKE ALL' statement
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER();
+let $diff_table= test.v_user;
+let $diff_server_list= master, slave, slave2;
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify 'GRANT ... ON TABLE ...' statement
+connection conn1;
+GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER();
+let $diff_table= test.v_tables_priv;
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify 'GRANT ... ON PROCEDURE...' statement
+connection conn1;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER();
+let $diff_table= test.v_procs_priv;
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify 'GRANT ... ON *.* ...' statement
+connection conn1;
+GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION;
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify 'REVOKE ... ON TABLE ...' statement
+connection conn1;
+REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER();
+let $diff_table= test.v_tables_priv;
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify 'REVOKE ... ON PROCEDURE...' statement
+connection conn1;
+REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER();
+let $diff_table= test.v_procs_priv;
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify 'REVOKE ... ON *.* ...' statement
+connection conn1;
+REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER();
+let $diff_table= test.v_user;
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify 'GRANT ...' statement in the procedure
+connection conn1;
+CREATE PROCEDURE my_grant()
+ GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER();
+call my_grant;
+let $diff_table= test.v_tables_priv;
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify 'REVOKE ... ON TABLE ...' statement in the procedure
+connection conn1;
+CREATE PROCEDURE my_revoke()
+ REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER();
+call my_revoke;
+let $diff_table= test.v_tables_priv;
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify 'RENAME USER ...' statement
+connection conn1;
+RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost';
+let $diff_table= test.v_user;
+source include/rpl_diff_tables.inc;
+
+disconnect conn1;
+
+--echo
+--echo # Verify 'DROP USER ...' statement
+connection master;
+GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost';
+connect (conn1, 127.0.0.1, 'bug48321_2'@'localhost',,);
+connection conn1;
+DROP USER CURRENT_USER();
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify 'ALTER EVENT...' statement
+connection master;
+CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1;
+
+--echo # Explicitly assign CURRENT_USER() to definer
+ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE;
+let $diff_table= test.v_event;
+source include/rpl_diff_tables.inc;
+
+connection master;
+--echo
+--echo # Session user will be set as definer, if the statement does not assign
+--echo # a definer
+ALTER EVENT e1 ENABLE;
+sync_slave_with_master;
+source include/rpl_diff_tables.inc;
+
+--echo
+--echo # Verify that this patch does not affect the calling of CURRENT_USER()
+--echo # in the other statements
+connection master;
+--echo # [On master]
+INSERT INTO t1 VALUES(CURRENT_USER()), ('1234');
+SELECT * FROM t1;
+sync_slave_with_master;
+--echo # [On slave]
+SELECT * FROM t1;
+--echo # [On slave2]
+sync_slave_with_master slave2;
+SELECT * FROM t1;
+
+connection master;
+--echo # [On master]
+UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234';
+SELECT * FROM t1;
+sync_slave_with_master;
+--echo # [On slave]
+SELECT * FROM t1;
+sync_slave_with_master slave2;
+--echo # [On slave2]
+SELECT * FROM t1;
+
+connection master;
+--echo # [On master]
+DELETE FROM t1 WHERE c1=CURRENT_USER();
+SELECT * FROM t1;
+sync_slave_with_master;
+--echo # [On slave]
+SELECT * FROM t1;
+sync_slave_with_master slave2;
+--echo # [On slave2]
+SELECT * FROM t1;
+
+connection master;
+--echo # [On master]
+CREATE TABLE t2(c1 char(100));
+
+DELIMITER |;
+CREATE FUNCTION my_user() RETURNS VARCHAR(64)
+ SQL SECURITY INVOKER
+BEGIN
+ INSERT INTO t2 VALUES(CURRENT_USER());
+ RETURN CURRENT_USER();
+END |
+DELIMITER ;|
+
+INSERT INTO t1 VALUES(my_user());
+SELECT * FROM t1;
+SELECT * FROM t2;
+sync_slave_with_master;
+--echo # [On slave]
+SELECT * FROM t1;
+SELECT * FROM t2;
+sync_slave_with_master slave2;
+--echo # [On slave2]
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+--echo
+--echo # END
+connection master;
+DROP TABLE t1, t2;
+DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event;
+DROP PROCEDURE p1;
+DROP PROCEDURE my_grant;
+DROP PROCEDURE my_revoke;
+DROP FUNCTION my_user;
+DROP EVENT e1;
+sync_slave_with_master;
+sync_slave_with_master slave2;
+source include/master-slave-end.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_drop.test b/mysql-test/suite/rpl/t/rpl_drop.test
index b38007a755f..336edad6fc5 100644
--- a/mysql-test/suite/rpl/t/rpl_drop.test
+++ b/mysql-test/suite/rpl/t/rpl_drop.test
@@ -1,6 +1,7 @@
# Testcase for BUG#4552 (DROP on two tables, one of which does not
# exist, must be binlogged with a non-zero error code)
source include/master-slave.inc;
+source include/have_innodb.inc;
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
@@ -10,7 +11,57 @@ drop table t1, t2;
save_master_pos;
connection slave;
sync_with_master;
-
# End of 4.1 tests
+# BUG#55625 RBR breaks on failing 'CREATE TABLE'
+# A CREATE...SELECT that fails is written to the binary log if a non-transactional
+# statement is updated. If the logging format is ROW, the CREATE statement and the
+# changes are written to the binary log as distinct events and by consequence the
+# created table is not rolled back in the slave.
+# To fix the problem, we do not write a CREATE...SELECT that fails to the binary
+# log. Howerver, the changes to non-transactional tables are not replicated and
+# thus the slave goes out of sync. This should be fixed after BUG#47899.
+#
+# In the test case, we verify if the binary log contains no information for a
+# CREATE...SELECT that fails.
+connection slave;
+
+--source include/stop_slave.inc
+SET @old_binlog_format= @@global.binlog_format;
+SET GLOBAL binlog_format = ROW;
+--source include/start_slave.inc
+
+connection master;
+SET @old_binlog_format= @@global.binlog_format;
+SET binlog_format = ROW;
+
+CREATE TABLE t2(a INT) ENGINE=MYISAM;
+CREATE TABLE t3(a INT) ENGINE=INNODB;
+
+delimiter |;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+ insert into t2 values(1);
+ insert into t3 values(1);
+ return 1;
+END|
+delimiter ;|
+
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+let $binlog_file= query_get_value("SHOW MASTER STATUS", File, 1);
+
+--error 1062
+CREATE TABLE t1(UNIQUE(a)) ENGINE=MYISAM SELECT 1 AS a UNION ALL SELECT f1();
+--error 1062
+CREATE TABLE t1(UNIQUE(a)) ENGINE=INNODB SELECT 1 AS a UNION ALL SELECT f1();
+
+--source include/show_binlog_events.inc
+
+DROP FUNCTION f1;
+DROP TABLE t2, t3;
+SET @@global.binlog_format= @old_binlog_format;
+
+--sync_slave_with_master
+SET @@global.binlog_format= @old_binlog_format;
+# End of 5.1 tests
diff --git a/mysql-test/suite/rpl/t/rpl_packet.test b/mysql-test/suite/rpl/t/rpl_packet.test
index bfc144c759b..08a533e22ca 100644
--- a/mysql-test/suite/rpl/t/rpl_packet.test
+++ b/mysql-test/suite/rpl/t/rpl_packet.test
@@ -1,7 +1,12 @@
+# ==== Purpose ====
#
# Check replication protocol packet size handling
-# Bug#19402 SQL close to the size of the max_allowed_packet fails on slave
#
+# ==== Related bugs ====
+# Bug#19402 SQL close to the size of the max_allowed_packet fails on slave
+# BUG#23755: Replicated event larger that max_allowed_packet infinitely re-transmits
+# BUG#42914: No LAST_IO_ERROR for max_allowed_packet errors
+# BUG#55322: SHOW BINLOG EVENTS increases @@SESSION.MAX_ALLOWED_PACKET
# max-out size db name
source include/master-slave.inc;
@@ -119,6 +124,38 @@ let $slave_io_running= query_get_value(SHOW SLAVE STATUS, Slave_IO_Running, 1);
let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
eval SELECT "$last_io_error" AS Last_IO_Error;
+# Remove the bad binlog and clear error status on slave.
+STOP SLAVE;
+RESET SLAVE;
+--connection master
+RESET MASTER;
+
+
+#
+# BUG#55322: SHOW BINLOG EVENTS increases @@SESSION.MAX_ALLOWED_PACKET
+#
+# In BUG#55322, @@session.max_allowed_packet increased each time SHOW
+# BINLOG EVENTS was issued. To verify that this bug is fixed, we
+# execute SHOW BINLOG EVENTS twice and check that max_allowed_packet
+# never changes. We turn off the result log because we don't care
+# about the contents of the binlog.
+
+--disable_result_log
+SET @max_allowed_packet_0= @@session.max_allowed_packet;
+SHOW BINLOG EVENTS;
+SET @max_allowed_packet_1= @@session.max_allowed_packet;
+SHOW BINLOG EVENTS;
+SET @max_allowed_packet_2= @@session.max_allowed_packet;
+--enable_result_log
+if (`SELECT NOT(@max_allowed_packet_0 = @max_allowed_packet_1 AND @max_allowed_packet_1 = @max_allowed_packet_2)`)
+{
+ --echo ERROR: max_allowed_packet changed after executing SHOW BINLOG EVENTS
+ --source include/show_rpl_debug_info.inc
+ SELECT @max_allowed_packet_0, @max_allowed_packet_1, @max_allowed_packet_2;
+ --die @max_allowed_packet changed after executing SHOW BINLOG EVENTS
+}
+
+
--echo ==== clean up ====
connection master;
DROP TABLE t1;
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index 6704257f9af..7478c7dcdce 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1680,3 +1680,16 @@ SELECT * FROM t1;
REPAIR TABLE t1 EXTENDED;
SELECT * FROM t1;
DROP TABLE t1;
+
+#
+# Bug #47012 archive tables are not upgradeable, and server crashes on
+# any access
+#
+copy_file std_data/archive_5_0.frm $MYSQLD_DATADIR/test/t1.frm;
+copy_file std_data/archive_5_0.ARZ $MYSQLD_DATADIR/test/t1.ARZ;
+copy_file std_data/archive_5_0.ARM $MYSQLD_DATADIR/test/t1.ARM;
+--error ER_TABLE_NEEDS_UPGRADE
+select * from t1;
+repair table t1;
+select sum(length(a)),sum(b) from t1;
+drop table t1;
diff --git a/mysql-test/t/bug46080-master.opt b/mysql-test/t/bug46080-master.opt
index dacdab53a4b..ff809c0cc69 100644
--- a/mysql-test/t/bug46080-master.opt
+++ b/mysql-test/t/bug46080-master.opt
@@ -1 +1 @@
---skip-grant-tables --skip-name-resolve --safemalloc-mem-limit=20000000
+--skip-grant-tables --skip-name-resolve --safemalloc-mem-limit=20000000 --loose-maria-pagecache-buffer-size=1M
diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test
index bb4dd3e11f9..66fe3bb03b2 100644
--- a/mysql-test/t/drop.test
+++ b/mysql-test/t/drop.test
@@ -195,9 +195,10 @@ create table `#mysql50#abc``def` ( id int );
--error ER_WRONG_TABLE_NAME
create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
-create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
+create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1234` (a int);
--error ER_WRONG_TABLE_NAME
-create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
+create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12345` (a int);
+show tables;
use test;
drop database mysqltestbug26703;
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index e832ea316eb..926c1f92855 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -708,6 +708,7 @@ SELECT 1 FROM
DROP TABLE t1;
+--echo End of 5.0 tests
--echo #
--echo # Bug #52397: another crash with explain extended and group_concat
@@ -719,5 +720,18 @@ EXPLAIN EXTENDED SELECT 1 FROM
t1 t2, t1 GROUP BY t1.a) AS d;
DROP TABLE t1;
+--echo #
+--echo # Bug #54476: crash when group_concat and 'with rollup' in prepared statements
+--echo #
---echo End of 5.0 tests
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+
+PREPARE stmt FROM "SELECT GROUP_CONCAT(t1.a ORDER BY t1.a) FROM t1 JOIN t1 t2 GROUP BY t1.a WITH ROLLUP";
+EXECUTE stmt;
+EXECUTE stmt;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index afce01cac5c..363221f38d8 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -279,4 +279,16 @@ select NAME_CONST('_id',1234) as id;
select connection_id() > 0;
+--echo #
+--echo # Bug #54461: crash with longblob and union or update with subquery
+--echo #
+
+CREATE TABLE t1 (a INT, b LONGBLOB);
+INSERT INTO t1 VALUES (1, '2'), (2, '3'), (3, '2');
+
+SELECT DISTINCT LEAST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
+SELECT DISTINCT GREATEST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
+
+DROP TABLE t1;
+
--echo End of tests
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index 5bdb3ebe9bf..65e987dfa24 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -1541,7 +1541,7 @@ connect (con1,localhost,testbug,,db1);
SELECT * FROM `../db2/tb2`;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM `../db2`.tb2;
---error ER_NO_SUCH_TABLE
+--error ER_WRONG_TABLE_NAME
SELECT * FROM `#mysql50#/../db2/tb2`;
connection default;
disconnect con1;
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index c640a58d597..bfef611d686 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -1238,5 +1238,19 @@ select min(t2.key_col)+1 from t1,t2 where t1.a> 1000;
drop table t1,t2;
--echo #
+--echo # Bug#55188: GROUP BY, GROUP_CONCAT and TEXT - inconsistent results
+--echo #
+
+CREATE TABLE t1 (a text, b varchar(10));
+INSERT INTO t1 VALUES (repeat('1', 1300),'one'), (repeat('1', 1300),'two');
+
+query_vertical EXPLAIN
+SELECT SUBSTRING(a,1,10), LENGTH(a), GROUP_CONCAT(b) FROM t1 GROUP BY a;
+SELECT SUBSTRING(a,1,10), LENGTH(a), GROUP_CONCAT(b) FROM t1 GROUP BY a;
+query_vertical EXPLAIN
+SELECT SUBSTRING(a,1,10), LENGTH(a) FROM t1 GROUP BY a;
+SELECT SUBSTRING(a,1,10), LENGTH(a) FROM t1 GROUP BY a;
+DROP TABLE t1;
+
--echo # End of 5.1 tests
diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test
index 65bf9518a5c..c808e747523 100644
--- a/mysql-test/t/having.test
+++ b/mysql-test/t/having.test
@@ -544,3 +544,24 @@ ORDER BY t1.f2;
DROP TABLE t1,t2;
--echo End of 5.0 tests
+
+--echo #
+--echo # Bug#54416 MAX from JOIN with HAVING returning NULL with 5.1 and Empty set
+--echo #
+
+CREATE TABLE t1 (f1 INT(11), f2 VARCHAR(1), PRIMARY KEY (f1));
+INSERT INTO t1 VALUES (1,'f');
+
+CREATE TABLE t2 (f1 INT(11), f2 VARCHAR(1));
+INSERT INTO t2 VALUES (2,'m');
+INSERT INTO t2 VALUES (3,'m');
+INSERT INTO t2 VALUES (11,NULL);
+INSERT INTO t2 VALUES (12,'k');
+
+SELECT MAX(t1.f1) field1
+FROM t1 JOIN t2 ON t2.f2 LIKE 'x'
+HAVING field1 < 7;
+
+DROP TABLE t1,t2;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 4cef8615cd2..e78b180caf7 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -1423,6 +1423,22 @@ FROM INFORMATION_SCHEMA.COLUMNS
WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = 'variables';
DROP TABLE variables;
+--echo #
+--echo # Bug #53814: NUMERIC_PRECISION for unsigned bigint field is 19,
+--echo # should be 20
+--echo #
+
+CREATE TABLE ubig (a BIGINT, b BIGINT UNSIGNED);
+
+SELECT TABLE_NAME, COLUMN_NAME, NUMERIC_PRECISION
+ FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='ubig';
+
+INSERT INTO ubig VALUES (0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF);
+SELECT length(CAST(b AS CHAR)) FROM ubig;
+
+DROP TABLE ubig;
+
+
--echo End of 5.1 tests.
# Wait till all disconnects are completed
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
index e24f0b16705..53eae4fdfaa 100644
--- a/mysql-test/t/loaddata.test
+++ b/mysql-test/t/loaddata.test
@@ -2,6 +2,8 @@
# Some simple test of load data
#
+-- source include/have_ucs2.inc
+
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
@@ -580,4 +582,36 @@ DROP TABLE t1;
connection default;
disconnect con1;
+
+--echo #
+--echo # Bug #51876 : crash/memory underrun when loading data with ucs2
+--echo # and reverse() function
+--echo #
+
+--echo # Problem # 1 (original report): wrong parsing of ucs2 data
+SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt';
+CREATE TABLE t1(a INT);
+LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2
+(@b) SET a=REVERSE(@b);
+--echo # should return 2 zeroes (as the value is truncated)
+SELECT * FROM t1;
+
+DROP TABLE t1;
+let $MYSQLD_DATADIR= `select @@datadir`;
+remove_file $MYSQLD_DATADIR/test/tmpp.txt;
+
+
+--echo # Problem # 2 : if you write and read ucs2 data to a file they're lost
+SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2;
+CREATE TABLE t1(a INT);
+LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2
+(@b) SET a=REVERSE(@b);
+--echo # should return 0 and 1 (10 reversed)
+SELECT * FROM t1;
+
+DROP TABLE t1;
+let $MYSQLD_DATADIR= `select @@datadir`;
+remove_file $MYSQLD_DATADIR/test/tmpp2.txt;
+
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/log_tables_upgrade.test b/mysql-test/t/log_tables_upgrade.test
index 5d1b2b5aed6..a638a27c9d1 100644
--- a/mysql-test/t/log_tables_upgrade.test
+++ b/mysql-test/t/log_tables_upgrade.test
@@ -25,7 +25,7 @@ FLUSH TABLES;
REPAIR TABLE test.bug49823;
RENAME TABLE general_log TO renamed_general_log;
RENAME TABLE test.bug49823 TO general_log;
---exec $MYSQL_UPGRADE --skip-verbose --force 2>&1
+--exec $MYSQL_UPGRADE --force 2>&1
DROP TABLE general_log;
RENAME TABLE renamed_general_log TO general_log;
SET GLOBAL general_log = @saved_general_log;
diff --git a/mysql-test/t/lowercase_view.test b/mysql-test/t/lowercase_view.test
index d6612b3e6b9..52be911cde0 100644
--- a/mysql-test/t/lowercase_view.test
+++ b/mysql-test/t/lowercase_view.test
@@ -160,4 +160,26 @@ SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
+
+--echo End of 5.0 tests.
+
+
+--echo #
+--echo # Bug #53095: SELECT column_name FROM INFORMATION_SCHEMA.STATISTICS
+--echo # returns nothing
+--echo #
+
+CREATE TABLE `ttt` (
+ `f1` char(3) NOT NULL,
+ PRIMARY KEY (`f1`)
+) ENGINE=myisam DEFAULT CHARSET=latin1;
+
+SELECT count(COLUMN_NAME) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME =
+'TTT';
+SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'TTT';
+
+DROP TABLE `ttt`;
+
+
--echo End of 5.0 tests.
+
diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test
index 15c0cd4ac84..41670117c7c 100644
--- a/mysql-test/t/mysql_client_test.test
+++ b/mysql-test/t/mysql_client_test.test
@@ -2,6 +2,7 @@
-- source include/not_embedded.inc
SET @old_general_log= @@global.general_log;
+SET @old_slow_query_log= @@global.slow_query_log;
# We run with different binaries for normal and --embedded-server
#
@@ -17,3 +18,4 @@ SET @old_general_log= @@global.general_log;
echo ok;
SET @@global.general_log= @old_general_log;
+SET @@global.slow_query_log= @old_slow_query_log;
diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test
index 485302600c1..ea127fbcc6d 100644
--- a/mysql-test/t/mysql_upgrade.test
+++ b/mysql-test/t/mysql_upgrade.test
@@ -33,7 +33,7 @@ if (`SELECT $VALGRIND_TEST`)
# expected binaries it uses.
#
--echo Run mysql_upgrade once
---exec $MYSQL_UPGRADE --skip-verbose --force 2>&1
+--exec $MYSQL_UPGRADE --force 2>&1
# It should have created a file in the MySQL Servers datadir
let $MYSQLD_DATADIR= `select @@datadir`;
@@ -42,13 +42,13 @@ file_exists $MYSQLD_DATADIR/mysql_upgrade_info;
--echo Run it again - should say already completed
--replace_result $MYSQL_SERVER_VERSION VERSION
--error 1
---exec $MYSQL_UPGRADE --skip-verbose 2>&1
+--exec $MYSQL_UPGRADE 2>&1
# It should have created a file in the MySQL Servers datadir
file_exists $MYSQLD_DATADIR/mysql_upgrade_info;
--echo Force should run it regardless of wether it's been run before
---exec $MYSQL_UPGRADE --skip-verbose --force 2>&1
+--exec $MYSQL_UPGRADE --force 2>&1
# It should have created a file in the MySQL Servers datadir
file_exists $MYSQLD_DATADIR/mysql_upgrade_info;
@@ -63,7 +63,7 @@ file_exists $MYSQLD_DATADIR/mysql_upgrade_info;
CREATE USER mysqltest1@'%' IDENTIFIED by 'sakila';
GRANT ALL ON *.* TO mysqltest1@'%';
--echo Run mysql_upgrade with password protected account
---exec $MYSQL_UPGRADE --skip-verbose --force --user=mysqltest1 --password=sakila 2>&1
+--exec $MYSQL_UPGRADE --force --user=mysqltest1 --password=sakila 2>&1
DROP USER mysqltest1@'%';
@@ -76,7 +76,7 @@ DROP USER mysqltest1@'%';
--replace_result $MYSQLTEST_VARDIR var
--replace_regex /.*mysqlcheck.*: Got/mysqlcheck: Got/ /\([0-9]*\)/(errno)/
--error 1
---exec $MYSQL_UPGRADE --skip-verbose --force --host=not_existing_host 2>&1
+--exec $MYSQL_UPGRADE --force --host=not_existing_host 2>&1
#
# Bug #28401 mysql_upgrade Failed with STRICT_ALL_TABLES, ANSI_QUOTES and NO_ZERO_DATE
@@ -88,7 +88,7 @@ DROP USER mysqltest1@'%';
# Test by setting sql_mode before running mysql_upgrade
set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE';
---exec $MYSQL_UPGRADE --skip-verbose --force 2>&1
+--exec $MYSQL_UPGRADE --force 2>&1
eval set GLOBAL sql_mode=default;
@@ -104,8 +104,24 @@ CREATE PROCEDURE testproc() BEGIN END;
UPDATE mysql.proc SET character_set_client = NULL WHERE name LIKE 'testproc';
UPDATE mysql.proc SET collation_connection = NULL WHERE name LIKE 'testproc';
UPDATE mysql.proc SET db_collation = NULL WHERE name LIKE 'testproc';
---exec $MYSQL_UPGRADE --skip-verbose --force 2> $MYSQLTEST_VARDIR/tmp/41569.txt
+--exec $MYSQL_UPGRADE --force 2> $MYSQLTEST_VARDIR/tmp/41569.txt
CALL testproc();
DROP PROCEDURE testproc;
--cat_file $MYSQLTEST_VARDIR/tmp/41569.txt
--remove_file $MYSQLTEST_VARDIR/tmp/41569.txt
+
+
+--echo #
+--echo # Bug #53613: mysql_upgrade incorrectly revokes
+--echo # TRIGGER privilege on given table
+--echo #
+
+GRANT USAGE ON *.* TO 'user3'@'%';
+GRANT ALL PRIVILEGES ON `roelt`.`test2` TO 'user3'@'%';
+--echo Run mysql_upgrade with all privileges on a user
+--exec $MYSQL_UPGRADE --force 2>&1
+SHOW GRANTS FOR 'user3'@'%';
+
+DROP USER 'user3'@'%';
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/mysqltest_ps.test b/mysql-test/t/mysqltest_ps.test
index c91f6dcb409..c5a332f691f 100644
--- a/mysql-test/t/mysqltest_ps.test
+++ b/mysql-test/t/mysqltest_ps.test
@@ -4,7 +4,7 @@
if (`SELECT $PS_PROTOCOL = 0`)
{
- --skip Need prepared statement protocol
+ --skip Need ps-protocol
}
#
diff --git a/mysql-test/t/ssl_8k_key-master.opt b/mysql-test/t/ssl_8k_key-master.opt
new file mode 100644
index 00000000000..b58ca7f39f0
--- /dev/null
+++ b/mysql-test/t/ssl_8k_key-master.opt
@@ -0,0 +1 @@
+--loose-ssl-key=$MYSQL_TEST_DIR/std_data/server8k-key.pem --loose-ssl-cert=$MYSQL_TEST_DIR/std_data/server8k-cert.pem
diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test
index f6708828a6b..c515f8873d8 100644
--- a/mysql-test/t/update.test
+++ b/mysql-test/t/update.test
@@ -483,3 +483,23 @@ UPDATE IGNORE v1 SET a = 1;
SET SESSION sql_safe_updates = DEFAULT;
DROP TABLE t1;
DROP VIEW v1;
+
+--echo #
+--echo # Bug#54734 assert in Diagnostics_area::set_ok_status
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, not_exists;
+DROP FUNCTION IF EXISTS f1;
+DROP VIEW IF EXISTS v1;
+--enable_warnings
+
+CREATE TABLE t1 (PRIMARY KEY(pk)) AS SELECT 1 AS pk;
+CREATE FUNCTION f1() RETURNS INTEGER RETURN (SELECT 1 FROM not_exists);
+CREATE VIEW v1 AS SELECT pk FROM t1 WHERE f1() = 13;
+--error ER_VIEW_INVALID
+UPDATE v1 SET pk = 7 WHERE pk > 0;
+
+DROP VIEW v1;
+DROP FUNCTION f1;
+DROP TABLE t1;
diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test
index a7b9a1531ff..8e6eed60242 100644
--- a/mysql-test/t/upgrade.test
+++ b/mysql-test/t/upgrade.test
@@ -169,5 +169,16 @@ USE `#mysql50#.`;
--error ER_WRONG_DB_NAME
USE `#mysql50#../blablabla`;
+#
+# Test of Bug #56441: mysql_upgrade 5.0->5.1 fails for tables with long names
+#
+copy_file $MYSQL_TEST_DIR/std_data/long_table_name.MYI $MYSQLD_DATADIR/test/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYI;
+copy_file $MYSQL_TEST_DIR/std_data/long_table_name.MYD $MYSQLD_DATADIR/test/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYD;
+copy_file $MYSQL_TEST_DIR/std_data/long_table_name.frm $MYSQLD_DATADIR/test/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.frm;
+show full tables;
+rename table `#mysql50#ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com` to `ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com`;
+show full tables;
+drop table `ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com`;
+
--echo # End of 5.1 tests
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 337fc86c12e..95358883f4e 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -147,7 +147,3 @@ test_base64$(EXEEXT): base64.c $(LIBRARIES)
test_thr_mutex$(EXEEXT): test_thr_mutex.c $(LIBRARIES)
$(LINK) $(FLAGS) $(srcdir)/test_thr_mutex.c $(LDADD) $(LIBS)
-
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/mysys/errors.c b/mysys/errors.c
index fc63ac9d936..4c568952ee3 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -50,6 +50,8 @@ const char * NEAR globerrs[GLOBERRS]=
"Collation '%s' is not a compiled collation and is not specified in the '%s' file",
"File '%s' not found (Errcode: %d)",
"File '%s' (fileno: %d) was not closed",
+ "Can't change ownership of the file '%s' (Errcode: %d)",
+ "Can't change permissions of the file '%s' (Errcode: %d)",
"Can't change mode for file '%s' to 0x%lx (Error: %d)",
"Can't do seek on file '%s' (Errcode: %d)",
"Warning: Can't copy ownership for file '%s' (Error: %d)"
@@ -93,6 +95,8 @@ void init_glob_errs()
EE(EE_UNKNOWN_COLLATION)= "Collation '%s' is not a compiled collation and is not specified in the %s file";
EE(EE_FILENOTFOUND) = "File '%s' not found (Errcode: %d)";
EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed";
+ EE(EE_CHANGE_OWNERSHIP) = "Can't change ownership of the file '%s' (Errcode: %d)";
+ EE(EE_CHANGE_PERMISSIONS) = "Can't change permissions of the file '%s' (Errcode: %d)";
EE(EE_CANT_CHMOD) = "Can't change mode for file '%s' to 0x%lx (Error: %d)";
EE(EE_CANT_SEEK) = "Can't do seek on file '%s' (Errcode: %d)";
EE(EE_CANT_COPY_OWNERSHIP)= "Warning: Can't copy ownership for file '%s' (Error: %d)";
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 59872961523..3824669365f 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1701,16 +1701,19 @@ int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
#endif
-int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
+int my_b_flush_io_cache(IO_CACHE *info,
+ int need_append_buffer_lock __attribute__((unused)))
{
size_t length;
- my_bool append_cache;
my_off_t pos_in_file;
+ my_bool append_cache= (info->type == SEQ_READ_APPEND);
DBUG_ENTER("my_b_flush_io_cache");
DBUG_PRINT("enter", ("cache: 0x%lx", (long) info));
- if (!(append_cache = (info->type == SEQ_READ_APPEND)))
- need_append_buffer_lock=0;
+#ifdef THREAD
+ if (!append_cache)
+ need_append_buffer_lock= 0;
+#endif
if (info->type == WRITE_CACHE || append_cache)
{
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index 4f7cd90e8aa..86fd61537e7 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -52,7 +52,7 @@ void pack_dirname(char * to, const char *from)
buff_length= strlen(buff);
d_length= (size_t) (start-to);
if ((start == to ||
- (buff_length == d_length && !bcmp(buff,start,d_length))) &&
+ (buff_length == d_length && !memcmp(buff,start,d_length))) &&
*start != FN_LIBCHAR && *start)
{ /* Put current dir before */
bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1);
@@ -70,7 +70,7 @@ void pack_dirname(char * to, const char *from)
}
if (length > 1 && length < d_length)
{ /* test if /xx/yy -> ~/yy */
- if (bcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR)
+ if (memcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR)
{
to[0]=FN_HOMELIB; /* Filename begins with ~ */
(void) strmov_overlapp(to+1,to+length);
@@ -80,7 +80,7 @@ void pack_dirname(char * to, const char *from)
{ /* Test if cwd is ~/... */
if (length > 1 && length < buff_length)
{
- if (bcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR)
+ if (memcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR)
{
buff[0]=FN_HOMELIB;
(void) strmov_overlapp(buff+1,buff+length);
@@ -166,7 +166,7 @@ size_t cleanup_dirname(register char *to, const char *from)
*pos = FN_LIBCHAR;
if (*pos == FN_LIBCHAR)
{
- if ((size_t) (pos-start) > length && bcmp(pos-length,parent,length) == 0)
+ if ((size_t) (pos-start) > length && memcmp(pos-length,parent,length) == 0)
{ /* If .../../; skip prev */
pos-=length;
if (pos != start)
@@ -197,7 +197,7 @@ size_t cleanup_dirname(register char *to, const char *from)
end_parentdir=pos;
while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */
pos--;
- if (pos[1] == FN_HOMELIB || bcmp(pos,parent,length) == 0)
+ if (pos[1] == FN_HOMELIB || memcmp(pos,parent,length) == 0)
{ /* Don't remove ~user/ */
pos=strmov(end_parentdir+1,parent);
*pos=FN_LIBCHAR;
@@ -206,7 +206,7 @@ size_t cleanup_dirname(register char *to, const char *from)
}
}
else if ((size_t) (pos-start) == length-1 &&
- !bcmp(start,parent+1,length-1))
+ !memcmp(start,parent+1,length-1))
start=pos; /* Starts with "../" */
else if (pos-start > 0 && pos[-1] == FN_LIBCHAR)
{
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index 69e0ca18cb8..e7e5f75f486 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -550,7 +550,7 @@ uint bitmap_get_first(const MY_BITMAP *map)
{
byte_ptr= (uchar*)data_ptr;
for (j=0; ; j++, byte_ptr++)
- {
+ {
if (*byte_ptr != 0xFF)
{
for (k=0; ; k++)
diff --git a/mysys/my_copy.c b/mysys/my_copy.c
index adc891358d4..8ea9620b20b 100644
--- a/mysys/my_copy.c
+++ b/mysys/my_copy.c
@@ -17,6 +17,7 @@
#include "mysys_err.h"
#include <my_dir.h> /* for stat */
#include <m_string.h>
+#include "mysys_err.h"
#if defined(HAVE_UTIME_H)
#include <utime.h>
#elif defined(HAVE_SYS_UTIME_H)
@@ -57,7 +58,7 @@ int my_copy(const char *from, const char *to, myf MyFlags)
File from_file,to_file;
uchar buff[IO_SIZE];
MY_STAT stat_buff,new_stat_buff;
- int res;
+ my_bool file_created= 0;
DBUG_ENTER("my_copy");
DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
@@ -82,6 +83,7 @@ int my_copy(const char *from, const char *to, myf MyFlags)
MyFlags)) < 0)
goto err;
+ file_created= 1;
while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0)
{
if (Count == (uint) -1 ||
@@ -99,15 +101,30 @@ int my_copy(const char *from, const char *to, myf MyFlags)
if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags))
DBUG_RETURN(-1); /* Error on close */
+ from_file=to_file= -1; /* Files are closed */
+
/* Copy modes if possible */
if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
DBUG_RETURN(0); /* File copyed but not stat */
- res= chmod(to, stat_buff.st_mode & 07777); /* Copy modes */
+ /* Copy modes */
+ if (chmod(to, stat_buff.st_mode & 07777))
+ {
+ my_errno= errno;
+ if (MyFlags & MY_WME)
+ my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno);
+ if (MyFlags & MY_FAE)
+ goto err;
+ }
#if !defined(__WIN__) && !defined(__NETWARE__)
+ /* Copy ownership */
if (chown(to, stat_buff.st_uid,stat_buff.st_gid))
{
- my_error(EE_CANT_COPY_OWNERSHIP, MYF(ME_JUST_WARNING), to);
+ my_errno= errno;
+ if (MyFlags & MY_WME)
+ my_error(EE_CANT_COPY_OWNERSHIP, MYF(ME_JUST_WARNING), to, errno);
+ if (MyFlags & MY_FAE)
+ goto err;
}
#endif
#if !defined(VMS) && !defined(__ZTC__)
@@ -124,11 +141,11 @@ int my_copy(const char *from, const char *to, myf MyFlags)
err:
if (from_file >= 0) VOID(my_close(from_file,MyFlags));
- if (to_file >= 0)
- {
- VOID(my_close(to_file, MyFlags));
- /* attempt to delete the to-file we've partially written */
+ if (to_file >= 0) VOID(my_close(to_file, MyFlags));
+
+ /* attempt to delete the to-file we've partially written */
+ if (file_created)
VOID(my_delete(to, MyFlags));
- }
+
DBUG_RETURN(-1);
} /* my_copy */
diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c
index c7f138c7337..00e0e90f1e4 100644
--- a/mysys/my_gethwaddr.c
+++ b/mysys/my_gethwaddr.c
@@ -47,7 +47,7 @@ my_bool my_gethwaddr(uchar *to)
uchar *buf, *next, *end, *addr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
- int i, res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
+ int res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
goto err;
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index b8a5c5d14bd..d4e548611de 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -30,7 +30,7 @@ my_error_reporter my_getopt_error_reporter= &default_reporter;
static int findopt(char *optpat, uint length,
const struct my_option **opt_res,
- char **ffname);
+ const char **ffname);
my_bool getopt_compare_strings(const char *s,
const char *t,
uint length);
@@ -115,8 +115,8 @@ int handle_options(int *argc, char ***argv,
uint opt_found, argvpos= 0, length;
my_bool end_of_options= 0, must_be_var, set_maximum_value,
option_is_loose;
- char **pos, **pos_end, *optend, *UNINIT_VAR(prev_found),
- *opt_str, key_name[FN_REFLEN];
+ char **pos, **pos_end, *optend, *opt_str, key_name[FN_REFLEN];
+ const char *prev_found;
const struct my_option *optp;
void *value;
int error, i;
@@ -711,10 +711,10 @@ static int setval(const struct my_option *opts, void *value, char *argument,
static int findopt(char *optpat, uint length,
const struct my_option **opt_res,
- char **ffname)
+ const char **ffname)
{
uint count;
- struct my_option *opt= (struct my_option *) *opt_res;
+ const struct my_option *opt= *opt_res;
for (count= 0; opt->name; opt++)
{
@@ -725,8 +725,9 @@ static int findopt(char *optpat, uint length,
return 1;
if (!count)
{
+ /* We only need to know one prev */
count= 1;
- *ffname= (char *) opt->name; /* We only need to know one prev */
+ *ffname= opt->name;
}
else if (strcmp(*ffname, opt->name))
{
diff --git a/mysys/my_handler.c b/mysys/my_handler.c
index 7c13149cb27..efee04194f7 100644
--- a/mysys/my_handler.c
+++ b/mysys/my_handler.c
@@ -277,7 +277,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register const uchar *a,
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
a+=a_length;
b+=b_length;
- break;
}
break;
case HA_KEYTYPE_INT8:
diff --git a/mysys/my_redel.c b/mysys/my_redel.c
index 598a728393d..cf0986a7821 100644
--- a/mysys/my_redel.c
+++ b/mysys/my_redel.c
@@ -71,14 +71,28 @@ end:
} /* my_redel */
- /* Copy stat from one file to another */
- /* Return -1 if can't get stat, 1 if wrong type of file */
+/**
+ Copy stat from one file to another
+ @fn my_copystat()
+ @param from Copy stat from this file
+ @param to Copy stat to this file
+ @param MyFlags Flags:
+ MY_WME Give error if something goes wrong
+ MY_FAE Abort operation if something goes wrong
+ If MY_FAE is not given, we don't return -1 for
+ errors from chown (which normally require root
+ privilege)
+
+ @return 0 ok
+ -1 if can't get stat,
+ 1 if wrong type of file
+*/
int my_copystat(const char *from, const char *to, int MyFlags)
{
struct stat statbuf;
- if (stat((char*) from, &statbuf))
+ if (stat(from, &statbuf))
{
my_errno=errno;
if (MyFlags & (MY_FAE+MY_WME))
@@ -87,7 +101,15 @@ int my_copystat(const char *from, const char *to, int MyFlags)
}
if ((statbuf.st_mode & S_IFMT) != S_IFREG)
return 1;
- VOID(chmod(to, statbuf.st_mode & 07777)); /* Copy modes */
+
+ /* Copy modes */
+ if (chmod(to, statbuf.st_mode & 07777))
+ {
+ my_errno= errno;
+ if (MyFlags & (MY_FAE+MY_WME))
+ my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno);
+ return -1;
+ }
#if !defined(__WIN__) && !defined(__NETWARE__)
if (statbuf.st_nlink > 1 && MyFlags & MY_LINK_WARNING)
@@ -95,9 +117,14 @@ int my_copystat(const char *from, const char *to, int MyFlags)
if (MyFlags & MY_LINK_WARNING)
my_error(EE_LINK_WARNING,MYF(ME_BELL+ME_WAITTANG),from,statbuf.st_nlink);
}
+ /* Copy ownership */
if (chown(to, statbuf.st_uid, statbuf.st_gid))
{
- my_error(EE_CANT_COPY_OWNERSHIP, MYF(ME_JUST_WARNING), to);
+ my_errno= errno;
+ if (MyFlags & MY_WME)
+ my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno);
+ if (MyFlags & MY_FAE)
+ return -1;
}
#endif /* !__WIN__ && !__NETWARE__ */
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 80122a4e70f..7bac8017324 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -86,7 +86,9 @@ void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)),
#if BACKTRACE_DEMANGLE
-char __attribute__ ((weak)) *my_demangle(const char *mangled_name __attribute__((unused)), int *status __attribute__((unused)))
+char __attribute__ ((weak)) *
+my_demangle(const char *mangled_name __attribute__((unused)),
+ int *status __attribute__((unused)))
{
return NULL;
}
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index c830c4ed0cc..b8aa9e5fcc0 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -131,8 +131,7 @@ static int check_lock(struct st_lock_list *list, const char* lock_type,
{
THR_LOCK_DATA *data,**prev;
uint count=0;
- THR_LOCK_OWNER *first_owner;
- LINT_INIT(first_owner);
+ THR_LOCK_OWNER *UNINIT_VAR(first_owner);
prev= &list->data;
if (list->data)
diff --git a/netware/Makefile.am b/netware/Makefile.am
index 3d0402ce714..f537022495b 100644
--- a/netware/Makefile.am
+++ b/netware/Makefile.am
@@ -115,6 +115,3 @@ test_db.sql: init_db.sql $(top_srcdir)/scripts/mysql_test_data_timezone.sql
@echo "Building $@";
@cat init_db.sql \
$(top_srcdir)/scripts/mysql_test_data_timezone.sql > $@;
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/plugin/Makefile.am b/plugin/Makefile.am
index 68f1f939836..e6d9ee4d823 100644
--- a/plugin/Makefile.am
+++ b/plugin/Makefile.am
@@ -23,6 +23,3 @@ EXTRA_DIST = fulltext/configure.in
SUBDIRS = @mysql_pg_dirs@
DIST_SUBDIRS = @mysql_pg_distdirs@
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/plugin/daemon_example/Makefile.am b/plugin/daemon_example/Makefile.am
index fce67285a5f..7bfaf5ac79f 100644
--- a/plugin/daemon_example/Makefile.am
+++ b/plugin/daemon_example/Makefile.am
@@ -27,16 +27,12 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
EXTRA_LTLIBRARIES = libdaemon_example.la
pkgplugin_LTLIBRARIES = @plugin_daemon_example_shared_target@
libdaemon_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
-
-libdaemon_example_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-libdaemon_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+libdaemon_example_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
libdaemon_example_la_SOURCES = daemon_example.cc
-
EXTRA_LIBRARIES = libdaemon_example.a
noinst_LIBRARIES = @plugin_daemon_example_static_target@
-libdaemon_example_a_CXXFLAGS = $(AM_CFLAGS)
-libdaemon_example_a_CFLAGS = $(AM_CFLAGS)
+libdaemon_example_a_CXXFLAGS = $(AM_CXXFLAGS)
libdaemon_example_a_SOURCES= daemon_example.cc
# Don't update the files from bitkeeper
diff --git a/plugin/fulltext/Makefile.am b/plugin/fulltext/Makefile.am
index 343416072dd..45565e9fdb2 100644
--- a/plugin/fulltext/Makefile.am
+++ b/plugin/fulltext/Makefile.am
@@ -21,7 +21,7 @@ INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include
pkgplugin_LTLIBRARIES= mypluglib.la
mypluglib_la_SOURCES= plugin_example.c
mypluglib_la_LDFLAGS= -module -rpath $(pkgplugindir)
-mypluglib_la_CFLAGS= -DMYSQL_DYNAMIC_PLUGIN
+mypluglib_la_CFLAGS= -shared -DMYSQL_DYNAMIC_PLUGIN
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/pstack/Makefile.am b/pstack/Makefile.am
index 870fed6ceeb..25feadf9d06 100644
--- a/pstack/Makefile.am
+++ b/pstack/Makefile.am
@@ -27,6 +27,3 @@ libpstack_a_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c \
debug.c ieee.c pstack.c stabs.c
noinst_HEADERS = bucomm.h debug.h ieee.h budbg.h demangle.h \
linuxthreads.h pstack.h pstacktrace.h
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/regex/Makefile.am b/regex/Makefile.am
index e2304ff7309..0fd62a777f6 100644
--- a/regex/Makefile.am
+++ b/regex/Makefile.am
@@ -31,6 +31,3 @@ test: re tests
./re < tests
./re -el < tests
./re -er < tests
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/regex/engine.c b/regex/engine.c
index a099cfb891d..5db8df210bd 100644
--- a/regex/engine.c
+++ b/regex/engine.c
@@ -256,7 +256,6 @@ sopno stopst;
register const char *ssp; /* start of string matched by subsubRE */
register const char *sep; /* end of string matched by subsubRE */
register const char *oldssp; /* previous ssp */
- register const char *dp; /* used in debug mode to check asserts */
AT("diss", start, stop, startst, stopst);
sp = start;
@@ -314,11 +313,9 @@ sopno stopst;
ssub = ss + 1;
esub = es - 1;
/* did innards match? */
- if (slow(charset, m, sp, rest, ssub, esub) != NULL) {
- dp = dissect(charset, m, sp, rest, ssub, esub);
- assert(dp == rest);
- } else /* no */
- assert(sp == rest);
+ if (slow(charset, m, sp, rest, ssub, esub) != NULL)
+ sp = dissect(charset, m, sp, rest, ssub, esub);
+ assert(sp == rest);
sp = rest;
break;
case OPLUS_:
@@ -353,8 +350,8 @@ sopno stopst;
}
assert(sep == rest); /* must exhaust substring */
assert(slow(charset, m, ssp, sep, ssub, esub) == rest);
- dp = dissect(charset, m, ssp, sep, ssub, esub);
- assert(dp == sep);
+ sp = dissect(charset, m, ssp, sep, ssub, esub);
+ assert(sp == sep);
sp = rest;
break;
case OCH_:
@@ -388,8 +385,8 @@ sopno stopst;
else
assert(OP(m->g->strip[esub]) == O_CH);
}
- dp = dissect(charset, m, sp, rest, ssub, esub);
- assert(dp == rest);
+ sp = dissect(charset, m, sp, rest, ssub, esub);
+ assert(sp == rest);
sp = rest;
break;
case O_PLUS:
diff --git a/regex/main.c b/regex/main.c
index fa97ca89047..e8277053382 100644
--- a/regex/main.c
+++ b/regex/main.c
@@ -17,8 +17,8 @@ regoff_t startoff = 0;
regoff_t endoff = 0;
-extern int split();
-extern void regprint();
+extern int split(char *string, char **fields, int nfields, const char *sep);
+extern void regprint(my_regex_t *r, FILE *d);
/*
- main - do the simple case, hand off to regress() for regression
diff --git a/regex/regcomp.c b/regex/regcomp.c
index b203d4941e1..81c435ed552 100644
--- a/regex/regcomp.c
+++ b/regex/regcomp.c
@@ -690,7 +690,6 @@ register cset *cs;
case '-':
SETERROR(REG_ERANGE);
return; /* NOTE RETURN */
- break;
default:
c = '\0';
break;
@@ -1564,13 +1563,13 @@ struct parse *p;
register struct re_guts *g;
{
register sop *scan;
- sop *start;
- register sop *newstart;
+ sop *UNINIT_VAR(start);
+ register sop *UNINIT_VAR(newstart);
register sopno newlen;
register sop s;
register char *cp;
register sopno i;
- LINT_INIT(start); LINT_INIT(newstart);
+
/* avoid making error situations worse */
if (p->error != 0)
return;
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index be9354bd628..015b664c87d 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -196,7 +196,3 @@ SUFFIXES = .sh
$< > $@-t
@CHMOD@ +x $@-t
@MV@ $@-t $@
-
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 8bae2ec9db1..2d3775afb3a 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -408,20 +408,16 @@ else
echo " shell> $bindir/mysql -u root mysql"
echo " mysql> show tables"
echo
- echo "Try 'mysqld --help' if you have problems with paths. Using --log"
- echo "gives you a log in $ldata that may be helpful."
+ echo "Try 'mysqld --help' if you have problems with paths. Using"
+ echo "--general-log gives you a log in $ldata that may be helpful."
echo
- echo "The latest information about MariaDB is available on the web at"
- echo "http://askmonty.org/wiki/index.php/MariaDB".
- echo "If you have a problem, you can consult the MySQL manual section"
- echo "'Problems running mysql_install_db', and the manual section that"
- echo "describes problems on your OS at http://dev.mysql.com/doc/"
+ echo "The latest information about mysql_install_db is available at"
+ echo "http://kb.askmonty.org/v/installing-system-tables-mysql_install_db."
echo "MariaDB is hosted on launchpad; You can find the latest source and"
echo "email lists at http://launchpad.net/maria"
echo
echo "Please check all of the above before mailing us! And remember, if"
echo "you do mail us, you should use the $scriptdir/mysqlbug script!"
- echo
exit 1
fi
diff --git a/scripts/mysql_secure_installation.pl.in b/scripts/mysql_secure_installation.pl.in
index 25339f9b916..0cd99267cdb 100755
--- a/scripts/mysql_secure_installation.pl.in
+++ b/scripts/mysql_secure_installation.pl.in
@@ -208,7 +208,7 @@ sub remove_anonymous_users {
}
sub remove_remote_root {
- if (do_query("DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';")) {
+ if (do_query("DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');")) {
print " ... Success!\n";
} else {
print " ... Failed!\n";
diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh
index 94472169c2a..fe93522aa87 100644
--- a/scripts/mysql_secure_installation.sh
+++ b/scripts/mysql_secure_installation.sh
@@ -68,7 +68,8 @@ parse_arguments()
# release or installed source directory and return the path.
find_in_basedir()
{
- return_dir=
+ return_dir=0
+ found=0
case "$1" in
--dir)
return_dir=1; shift
@@ -81,7 +82,8 @@ find_in_basedir()
do
if test -f "$basedir/$dir/$file"
then
- if test -n "$return_dir"
+ found=1
+ if test $return_dir -eq 1
then
echo "$basedir/$dir"
else
@@ -90,6 +92,17 @@ find_in_basedir()
break
fi
done
+
+ if test $found -eq 0
+ then
+ # Test if command is in PATH
+ $file --no-defaults --version > /dev/null 2>&1
+ status=$?
+ if test $status -eq 0
+ then
+ echo $file
+ fi
+ fi
}
cannot_find_file()
@@ -298,7 +311,7 @@ remove_anonymous_users() {
}
remove_remote_root() {
- do_query "DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';"
+ do_query "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');"
if [ $? -eq 0 ]; then
echo " ... Success!"
else
@@ -355,14 +368,15 @@ cleanup() {
# The actual script starts here
prepare
+find_mysql_client
set_echo_compat
echo
-echo "NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL"
+echo "NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB"
echo " SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!"
echo
-echo "In order to log into MySQL to secure it, we'll need the current"
-echo "password for the root user. If you've just installed MySQL, and"
+echo "In order to log into MariaDB to secure it, we'll need the current"
+echo "password for the root user. If you've just installed MariaDB, and"
echo "you haven't set the root password yet, the password will be blank,"
echo "so you should just press enter here."
echo
@@ -374,7 +388,7 @@ get_root_password
# Set the root password
#
-echo "Setting the root password ensures that nobody can log into the MySQL"
+echo "Setting the root password ensures that nobody can log into the MariaDB"
echo "root user without the proper authorisation."
echo
@@ -403,8 +417,8 @@ echo
# Remove anonymous users
#
-echo "By default, a MySQL installation has an anonymous user, allowing anyone"
-echo "to log into MySQL without having to have a user account created for"
+echo "By default, a MariaDB installation has an anonymous user, allowing anyone"
+echo "to log into MariaDB without having to have a user account created for"
echo "them. This is intended only for testing, and to make the installation"
echo "go a bit smoother. You should remove them before moving into a"
echo "production environment."
@@ -443,7 +457,7 @@ echo
# Remove test database
#
-echo "By default, MySQL comes with a database named 'test' that anyone can"
+echo "By default, MariaDB comes with a database named 'test' that anyone can"
echo "access. This is also intended only for testing, and should be removed"
echo "before moving into a production environment."
echo
@@ -478,8 +492,7 @@ echo
cleanup
echo
-echo "All done! If you've completed all of the above steps, your MySQL"
+echo "All done! If you've completed all of the above steps, your MariaDB"
echo "installation should now be secure."
echo
-echo "Thanks for using MySQL!"
-
+echo "Thanks for using MariaDB!"
diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql
index 69fc1b8a052..44fadcc6e00 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -58,7 +58,7 @@ ALTER TABLE tables_priv
COLLATE utf8_general_ci DEFAULT '' NOT NULL,
MODIFY Table_priv set('Select','Insert','Update','Delete','Create',
'Drop','Grant','References','Index','Alter',
- 'Create View','Show view')
+ 'Create View','Show view','Trigger')
COLLATE utf8_general_ci DEFAULT '' NOT NULL,
COMMENT='Table privileges';
@@ -584,8 +584,6 @@ ALTER TABLE host MODIFY Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAU
ALTER TABLE db ADD Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
ALTER TABLE db MODIFY Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
-ALTER TABLE tables_priv MODIFY Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL;
-
UPDATE user SET Trigger_priv=Super_priv WHERE @hadTriggerPriv = 0;
ALTER TABLE user ADD plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, ADD auth_string TEXT NOT NULL;
diff --git a/server-tools/Makefile.am b/server-tools/Makefile.am
index 96e9d5a946e..80103d195f5 100644
--- a/server-tools/Makefile.am
+++ b/server-tools/Makefile.am
@@ -15,6 +15,3 @@
SUBDIRS = . instance-manager
DIST_SUBDIRS = . instance-manager
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc
index 8b96d6f0f96..725089e2f42 100644
--- a/server-tools/instance-manager/instance_options.cc
+++ b/server-tools/instance-manager/instance_options.cc
@@ -303,7 +303,6 @@ bool Instance_options::fill_log_options()
enum { MAX_LOG_OPTION_LENGTH= 256 };
char datadir[MAX_LOG_OPTION_LENGTH];
char hostname[MAX_LOG_OPTION_LENGTH];
- uint hostname_length;
struct log_files_st
{
const char *name;
@@ -335,8 +334,6 @@ bool Instance_options::fill_log_options()
strmov(hostname, "mysql");
hostname[MAX_LOG_OPTION_LENGTH - 1]= 0; /* Safety */
- hostname_length= strlen(hostname);
-
for (log_files= logs_st; log_files->name; log_files++)
{
diff --git a/sql-bench/Makefile.am b/sql-bench/Makefile.am
index a7aff83e7aa..93f9a61d9d4 100644
--- a/sql-bench/Makefile.am
+++ b/sql-bench/Makefile.am
@@ -81,6 +81,3 @@ SUFFIXES = .sh
$< > $@-t
@CHMOD@ +x $@-t
@MV@ $@-t $@
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/sql-common/Makefile.am b/sql-common/Makefile.am
index 7b883ec2457..3193efee754 100644
--- a/sql-common/Makefile.am
+++ b/sql-common/Makefile.am
@@ -14,7 +14,4 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to create Makefile.in
-EXTRA_DIST = client.c pack.c my_time.c my_user.c client_plugin.c
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
+EXTRA_DIST = client.c pack.c my_time.c my_user.c
diff --git a/sql/Makefile.am b/sql/Makefile.am
index b738565f818..ba91f94d72d 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -194,6 +194,3 @@ install-exec-hook:
test ! -x mysqld-debug$(EXEEXT) || $(INSTALL_PROGRAM) mysqld-debug$(EXEEXT) $(DESTDIR)$(libexecdir)
test ! -f mysqld-debug.sym.gz || $(INSTALL_DATA) mysqld-debug.sym.gz $(DESTDIR)$(pkglibdir)
test ! -f mysqld.sym.gz || $(INSTALL_DATA) mysqld.sym.gz $(DESTDIR)$(pkglibdir)
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/sql/field.cc b/sql/field.cc
index 597ec4f68d0..633c0d96f2c 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -8696,7 +8696,13 @@ int Field_set::store(longlong nr, bool unsigned_val)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
int error= 0;
- ulonglong max_nr= set_bits(ulonglong, typelib->count);
+ ulonglong max_nr;
+
+ if (sizeof(ulonglong)*8 <= typelib->count)
+ max_nr= ULONGLONG_MAX;
+ else
+ max_nr= (ULL(1) << typelib->count) - 1;
+
if ((ulonglong) nr > max_nr)
{
nr&= max_nr;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 2bd2eabb58b..a46df40a5ed 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -997,7 +997,7 @@ static bool print_admin_msg(THD* thd, const char* msg_type,
Protocol *protocol= thd->protocol;
uint length, msg_length;
char msgbuf[HA_MAX_MSG_BUF];
- char name[NAME_LEN*2+2];
+ char name[SAFE_NAME_LEN*2+2];
va_start(args, fmt);
msg_length= my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
@@ -4195,6 +4195,58 @@ int ha_partition::common_first_last(uchar *buf)
/*
+ Optimization of the default implementation to take advantage of dynamic
+ partition pruning.
+*/
+int ha_partition::index_read_idx_map(uchar *buf, uint index,
+ const uchar *key,
+ key_part_map keypart_map,
+ enum ha_rkey_function find_flag)
+{
+ int error= HA_ERR_KEY_NOT_FOUND;
+ DBUG_ENTER("ha_partition::index_read_idx_map");
+
+ if (find_flag == HA_READ_KEY_EXACT)
+ {
+ uint part;
+ m_start_key.key= key;
+ m_start_key.keypart_map= keypart_map;
+ m_start_key.flag= find_flag;
+ m_start_key.length= calculate_key_len(table, index, m_start_key.key,
+ m_start_key.keypart_map);
+
+ get_partition_set(table, buf, index, &m_start_key, &m_part_spec);
+
+ /* How can it be more than one partition with the current use? */
+ DBUG_ASSERT(m_part_spec.start_part == m_part_spec.end_part);
+
+ for (part= m_part_spec.start_part; part <= m_part_spec.end_part; part++)
+ {
+ if (bitmap_is_set(&(m_part_info->used_partitions), part))
+ {
+ error= m_file[part]->index_read_idx_map(buf, index, key,
+ keypart_map, find_flag);
+ if (error != HA_ERR_KEY_NOT_FOUND &&
+ error != HA_ERR_END_OF_FILE)
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*
+ If not only used with READ_EXACT, we should investigate if possible
+ to optimize for other find_flag's as well.
+ */
+ DBUG_ASSERT(0);
+ /* fall back on the default implementation */
+ error= handler::index_read_idx_map(buf, index, key, keypart_map, find_flag);
+ }
+ DBUG_RETURN(error);
+}
+
+
+/*
Read next record in a forward index scan
SYNOPSIS
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index c8c45d72b26..1a9ec5bbf70 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -53,8 +53,7 @@ typedef struct st_ha_data_partition
HA_CAN_FULLTEXT | \
HA_DUPLICATE_POS | \
HA_CAN_SQL_HANDLER | \
- HA_CAN_INSERT_DELAYED | \
- HA_PRIMARY_KEY_REQUIRED_FOR_POSITION)
+ HA_CAN_INSERT_DELAYED)
class ha_partition :public handler
{
private:
@@ -448,6 +447,15 @@ public:
virtual int index_init(uint idx, bool sorted);
virtual int index_end();
+ /**
+ @breif
+ Positions an index cursor to the index specified in the hanlde. Fetches the
+ row if available. If the key value is null, begin at first key of the
+ index.
+ */
+ virtual int index_read_idx_map(uchar *buf, uint index, const uchar *key,
+ key_part_map keypart_map,
+ enum ha_rkey_function find_flag);
/*
These methods are used to jump to next or previous entry in the index
scan. There are also methods to jump to first and last entry.
@@ -764,9 +772,6 @@ public:
HA_PRIMARY_KEY_REQUIRED_FOR_POSITION:
Does the storage engine need a PK for position?
- Used with hidden primary key in InnoDB.
- Hidden primary keys cannot be supported by partitioning, since the
- partitioning expressions columns must be a part of the primary key.
(InnoDB)
HA_FILE_BASED is always set for partition handler since we use a
diff --git a/sql/handler.h b/sql/handler.h
index 0306f8aec61..7767a48bae9 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -100,7 +100,10 @@
#define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
/*
If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
- uses a primary key. Without primary key, we can't call position().
+ uses a primary key given by the record argument.
+ Without primary key, we can't call position().
+ If not set, the position is returned as the current rows position
+ regardless of what argument is given.
*/
#define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16)
#define HA_CAN_RTREEKEYS (1 << 17)
@@ -1612,10 +1615,9 @@ private:
virtual int rnd_next(uchar *buf)=0;
virtual int rnd_pos(uchar * buf, uchar *pos)=0;
/**
- One has to use this method when to find
- random position by record as the plain
- position() call doesn't work for some
- handlers for random position.
+ This function only works for handlers having
+ HA_PRIMARY_KEY_REQUIRED_FOR_POSITION set.
+ It will return the row with the PK given in the record argument.
*/
virtual int rnd_pos_by_record(uchar *record)
{
@@ -1646,6 +1648,12 @@ public:
virtual ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key)
{ return (ha_rows) 10; }
+ /*
+ If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
+ (reference to the row, aka position, with the primary key given in
+ the record).
+ Otherwise it set ref to the current row.
+ */
virtual void position(const uchar *record)=0;
virtual int info(uint)=0; // see my_base.h for full description
virtual void get_dynamic_partition_info(PARTITION_INFO *stat_info,
diff --git a/sql/item.cc b/sql/item.cc
index 2edeb4c0ee0..2dc65c5fb17 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -255,8 +255,9 @@ my_decimal *Item::val_decimal_from_int(my_decimal *decimal_value)
my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value)
{
String *res;
+
if (!(res= val_str(&str_value)))
- return 0; // NULL or EOM
+ return 0;
if (str2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_BAD_NUM,
res->ptr(), res->length(), res->charset(),
@@ -3742,7 +3743,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
int found_match_degree= 0;
Item_ident *cur_field;
int cur_match_degree= 0;
- char name_buff[NAME_LEN+1];
+ char name_buff[SAFE_NAME_LEN+1];
if (find_item->type() == Item::FIELD_ITEM ||
find_item->type() == Item::REF_ITEM)
@@ -4154,8 +4155,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
context->first_name_resolution_table,
context->last_name_resolution_table,
reference, REPORT_ALL_ERRORS,
- !any_privileges &&
- TRUE, TRUE);
+ !any_privileges, TRUE);
}
return -1;
}
diff --git a/sql/item.h b/sql/item.h
index 94a25d7eaea..3d0f35f5984 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -2892,6 +2892,7 @@ public:
class Cached_item_str :public Cached_item
{
Item *item;
+ uint32 value_max_length;
String value,tmp_value;
public:
Cached_item_str(THD *thd, Item *arg);
diff --git a/sql/item_buff.cc b/sql/item_buff.cc
index 2f45d0a17c2..0ac4edb3656 100644
--- a/sql/item_buff.cc
+++ b/sql/item_buff.cc
@@ -58,7 +58,9 @@ Cached_item::~Cached_item() {}
*/
Cached_item_str::Cached_item_str(THD *thd, Item *arg)
- :item(arg), value(min(arg->max_length, thd->variables.max_sort_length))
+ :item(arg),
+ value_max_length(min(arg->max_length, thd->variables.max_sort_length)),
+ value(value_max_length)
{}
bool Cached_item_str::cmp(void)
@@ -67,7 +69,7 @@ bool Cached_item_str::cmp(void)
bool tmp;
if ((res=item->val_str(&tmp_value)))
- res->length(min(res->length(), value.alloced_length()));
+ res->length(min(res->length(), value_max_length));
if (null_value != item->null_value)
{
if ((null_value= item->null_value))
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 2e72ab24fb0..eade395a229 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -5054,8 +5054,6 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
CHARSET_INFO *cs)
{
Item *UNINIT_VAR(res);
- ulong len;
- uint dec;
switch (cast_type) {
case ITEM_CAST_BINARY:
@@ -5078,11 +5076,10 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
break;
case ITEM_CAST_DECIMAL:
{
- if (c_len == NULL)
- {
- len= 0;
- }
- else
+ ulong len= 0;
+ uint dec= 0;
+
+ if (c_len)
{
ulong decoded_size;
errno= 0;
@@ -5096,11 +5093,7 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
len= decoded_size;
}
- if (c_dec == NULL)
- {
- dec= 0;
- }
- else
+ if (c_dec)
{
ulong decoded_size;
errno= 0;
@@ -5136,12 +5129,9 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
}
case ITEM_CAST_CHAR:
{
+ int len= -1;
CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection);
- if (c_len == NULL)
- {
- len= (ulong) -1L;
- }
- else
+ if (c_len)
{
ulong decoded_size;
errno= 0;
@@ -5151,7 +5141,7 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), "cast as char", MAX_FIELD_BLOBLENGTH);
return NULL;
}
- len= decoded_size;
+ len= (int) decoded_size;
}
res= new (thd->mem_root) Item_char_typecast(a, len, real_cs);
break;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 3cb9d4724b9..a139968ae37 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2244,6 +2244,8 @@ void Item_func_min_max::fix_length_and_dec()
max_length= my_decimal_precision_to_length_no_truncation(max_int_part +
decimals, decimals,
unsigned_flag);
+ else if (cmp_type == REAL_RESULT)
+ max_length= float_length(decimals);
cached_field_type= agg_field_type(args, arg_count);
}
@@ -4740,6 +4742,7 @@ bool Item_func_get_user_var::set_value(THD *thd,
bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
+ DBUG_ASSERT(thd->lex->exchange);
if (Item::fix_fields(thd, ref) ||
!(entry= get_variable(&thd->user_vars, name, 1)))
return TRUE;
@@ -4749,7 +4752,9 @@ bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
of fields in LOAD DATA INFILE.
(Since Item_user_var_as_out_param is used only there).
*/
- entry->collation.set(thd->variables.collation_database);
+ entry->collation.set(thd->lex->exchange->cs ?
+ thd->lex->exchange->cs :
+ thd->variables.collation_database);
entry->update_query_id= thd->query_id;
return FALSE;
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index b3b07119066..45c3ee3cd20 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -3043,7 +3043,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
tree(item->tree),
unique_filter(item->unique_filter),
table(item->table),
- order(item->order),
context(item->context),
arg_count_order(item->arg_count_order),
arg_count_field(item->arg_count_field),
@@ -3056,8 +3055,25 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
{
quick_group= item->quick_group;
result.set_charset(collation.collation);
-}
+ /*
+ Since the ORDER structures pointed to by the elements of the 'order' array
+ may be modified in find_order_in_list() called from
+ Item_func_group_concat::setup(), create a copy of those structures so that
+ such modifications done in this object would not have any effect on the
+ object being copied.
+ */
+ ORDER *tmp;
+ if (!(tmp= (ORDER *) thd->alloc(sizeof(ORDER *) * arg_count_order +
+ sizeof(ORDER) * arg_count_order)))
+ return;
+ order= (ORDER **)(tmp + arg_count_order);
+ for (uint i= 0; i < arg_count_order; i++, tmp++)
+ {
+ memcpy(tmp, item->order[i], sizeof(ORDER));
+ order[i]= tmp;
+ }
+}
void Item_func_group_concat::cleanup()
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index d91ccee1575..57656f30294 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -288,11 +288,6 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
CHARSET_INFO *cs= &my_charset_bin;
DBUG_ENTER("extract_date_time");
- LINT_INIT(strict_week_number);
- /* Remove valgrind varnings when using gcc 3.3 and -O1 */
- VALGRIND_OR_LINT_INIT(strict_week_number_year_type);
- VALGRIND_OR_LINT_INIT(sunday_first_n_first_week_non_iso);
-
if (!sub_pattern_end)
bzero((char*) l_time, sizeof(*l_time));
@@ -2996,7 +2991,7 @@ String *Item_func_maketime::val_str(String *str)
buf, len, MYSQL_TIMESTAMP_TIME,
NullS);
}
-
+
if (make_time_with_warn((DATE_TIME_FORMAT *) 0, &ltime, str))
{
null_value= 1;
diff --git a/sql/log.cc b/sql/log.cc
index 9cbf33d9890..8173b44c21f 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1663,6 +1663,19 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
DBUG_RETURN(error);
}
+/**
+ Cleanup the cache.
+
+ @param thd The client thread that wants to clean up the cache.
+*/
+void MYSQL_BIN_LOG::reset_gathered_updates(THD *thd)
+{
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
+
+ trx_data->reset();
+}
+
void MYSQL_BIN_LOG::set_write_error(THD *thd)
{
DBUG_ENTER("MYSQL_BIN_LOG::set_write_error");
@@ -1771,17 +1784,17 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
int check_binlog_magic(IO_CACHE* log, const char** errmsg)
{
- char magic[4];
+ uchar magic[4];
DBUG_ASSERT(my_b_tell(log) == 0);
- if (my_b_read(log, (uchar*) magic, sizeof(magic)))
+ if (my_b_read(log, magic, sizeof(magic)))
{
*errmsg = "I/O error reading the header from the binary log";
sql_print_error("%s, errno=%d, io cache code=%d", *errmsg, my_errno,
log->error);
return 1;
}
- if (memcmp(magic, BINLOG_MAGIC, sizeof(magic)))
+ if (bcmp(magic, BINLOG_MAGIC, sizeof(magic)))
{
*errmsg = "Binlog has bad magic number; It's not a binary log file that can be used by this version of MySQL";
return 1;
@@ -1898,7 +1911,7 @@ static int find_uniq_filename(char *name)
file_info= dir_info->dir_entry;
for (i=dir_info->number_off_files ; i-- ; file_info++)
{
- if (bcmp((uchar*) file_info->name, (uchar*) start, length) == 0 &&
+ if (memcmp(file_info->name, start, length) == 0 &&
test_if_number(file_info->name+length, &number,0))
{
set_if_bigger(max_found,(ulong) number);
@@ -2676,7 +2689,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
an extension for the binary log files.
In this case we write a standard header to it.
*/
- if (my_b_safe_write(&log_file, (uchar*) BINLOG_MAGIC,
+ if (my_b_safe_write(&log_file, BINLOG_MAGIC,
BIN_LOG_HEADER_SIZE))
goto err;
bytes_written+= BIN_LOG_HEADER_SIZE;
@@ -5126,6 +5139,22 @@ void sql_perror(const char *message)
}
+/*
+ Unfortunately, there seems to be no good way
+ to restore the original streams upon failure.
+*/
+static bool redirect_std_streams(const char *file)
+{
+ if (freopen(file, "a+", stdout) && freopen(file, "a+", stderr))
+ {
+ setbuf(stderr, NULL);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
bool flush_error_log()
{
bool result=0;
@@ -5154,11 +5183,7 @@ bool flush_error_log()
setbuf(stderr, NULL);
(void) my_delete(err_renamed, MYF(0));
my_rename(log_error_file,err_renamed,MYF(0));
- if (freopen(log_error_file,"a+",stdout))
- {
- freopen(log_error_file,"a+",stderr);
- setbuf(stderr, NULL);
- }
+ redirect_std_streams(log_error_file);
if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
{
@@ -5173,13 +5198,7 @@ bool flush_error_log()
result= 1;
#else
my_rename(log_error_file,err_renamed,MYF(0));
- if (freopen(log_error_file,"a+",stdout))
- {
- FILE *reopen;
- reopen= freopen(log_error_file,"a+",stderr);
- setbuf(stderr, NULL);
- }
- else
+ if (redirect_std_streams(log_error_file))
result= 1;
#endif
VOID(pthread_mutex_unlock(&LOCK_error_log));
@@ -5230,25 +5249,9 @@ static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
#endif /* __NT__ */
-/**
- Prints a printf style message to the error log and, under NT, to the
- Windows event log.
-
- This function prints the message into a buffer and then sends that buffer
- to other functions to write that message to other logging sources.
-
- @param event_type Type of event to write (Error, Warning, or Info)
- @param format Printf style format of message
- @param args va_list list of arguments for the message
-
- @returns
- The function always returns 0. The return value is present in the
- signature to be compatible with other logging routines, which could
- return an error (e.g. logging to the log tables)
-*/
-
#ifndef EMBEDDED_LIBRARY
-static void print_buffer_to_file(enum loglevel level, const char *buffer)
+static void print_buffer_to_file(enum loglevel level, const char *buffer,
+ size_t length)
{
time_t skr;
struct tm tm_tmp;
@@ -5262,7 +5265,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer)
localtime_r(&skr, &tm_tmp);
start=&tm_tmp;
- fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n",
+ fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %.*s\n",
start->tm_year % 100,
start->tm_mon+1,
start->tm_mday,
@@ -5271,7 +5274,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer)
start->tm_sec,
(level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ?
"Warning" : "Note"),
- buffer);
+ (int) length, buffer);
fflush(stderr);
@@ -5279,17 +5282,30 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer)
DBUG_VOID_RETURN;
}
+/**
+ Prints a printf style message to the error log and, under NT, to the
+ Windows event log.
+
+ This function prints the message into a buffer and then sends that buffer
+ to other functions to write that message to other logging sources.
+
+ @param level The level of the msg significance
+ @param format Printf style format of message
+ @param args va_list list of arguments for the message
+ @returns
+ The function always returns 0. The return value is present in the
+ signature to be compatible with other logging routines, which could
+ return an error (e.g. logging to the log tables)
+*/
int vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
{
char buff[1024];
+ size_t length;
DBUG_ENTER("vprint_msg_to_log");
-#ifdef __NT__
- size_t length=
-#endif
- my_vsnprintf(buff, sizeof(buff), format, args);
- print_buffer_to_file(level, buff);
+ length= my_vsnprintf(buff, sizeof(buff), format, args);
+ print_buffer_to_file(level, buff, length);
#ifdef __NT__
print_buffer_to_nt_eventlog(level, buff, length, sizeof(buff));
@@ -5297,7 +5313,7 @@ int vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
DBUG_RETURN(0);
}
-#endif /*EMBEDDED_LIBRARY*/
+#endif /* EMBEDDED_LIBRARY */
void sql_print_error(const char *format, ...)
@@ -5383,7 +5399,7 @@ ulong tc_log_page_waits= 0;
#define TC_LOG_HEADER_SIZE (sizeof(tc_log_magic)+1)
-static const char tc_log_magic[]={(char) 254, 0x23, 0x05, 0x74};
+static const uchar tc_log_magic[]={(uchar) 254, 0x23, 0x05, 0x74};
ulong opt_tc_log_size= TC_LOG_MIN_SIZE;
ulong tc_log_max_pages_used=0, tc_log_page_size=0, tc_log_cur_pages_used=0;
@@ -5783,7 +5799,7 @@ int TC_LOG_MMAP::recover()
HASH xids;
PAGE *p=pages, *end_p=pages+npages;
- if (memcmp(data, tc_log_magic, sizeof(tc_log_magic)))
+ if (bcmp(data, tc_log_magic, sizeof(tc_log_magic)))
{
sql_print_error("Bad magic header in tc log");
goto err1;
diff --git a/sql/log.h b/sql/log.h
index 1cfd7ce9ae5..8ee94ab5807 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -356,10 +356,10 @@ public:
/* Use this to start writing a new log file */
void new_file();
+ void reset_gathered_updates(THD *thd);
bool write(Log_event* event_info); // binary log write
bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
bool write_incident(THD *thd, bool lock);
-
int write_cache(THD *thd, IO_CACHE *cache, bool lock_log,
bool flush_and_sync);
void set_write_error(THD *thd);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index a1ecb79ff56..fa7bb01077d 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1673,7 +1673,7 @@ beg:
precision, decimals);
return bin_size;
}
-
+
case MYSQL_TYPE_FLOAT:
{
float fl;
@@ -2306,6 +2306,53 @@ bool Query_log_event::write(IO_CACHE* file)
start+= 4;
}
+ if (thd && thd->is_current_user_used())
+ {
+ LEX_STRING user;
+ LEX_STRING host;
+ memset(&user, 0, sizeof(user));
+ memset(&host, 0, sizeof(host));
+
+ if (thd->slave_thread && thd->has_invoker())
+ {
+ /* user will be null, if master is older than this patch */
+ user= thd->get_invoker_user();
+ host= thd->get_invoker_host();
+ }
+ else if (thd->security_ctx->priv_user)
+ {
+ Security_context *ctx= thd->security_ctx;
+
+ user.length= strlen(ctx->priv_user);
+ user.str= ctx->priv_user;
+ if (ctx->priv_host[0] != '\0')
+ {
+ host.str= ctx->priv_host;
+ host.length= strlen(ctx->priv_host);
+ }
+ }
+
+ if (user.length > 0)
+ {
+ *start++= Q_INVOKER;
+
+ /*
+ Store user length and user. The max length of use is 16, so 1 byte is
+ enough to store the user's length.
+ */
+ *start++= (uchar)user.length;
+ memcpy(start, user.str, user.length);
+ start+= user.length;
+
+ /*
+ Store host length and host. The max length of host is 60, so 1 byte is
+ enough to store the host's length.
+ */
+ *start++= (uchar)host.length;
+ memcpy(start, host.str, host.length);
+ start+= host.length;
+ }
+ }
/*
NOTE: When adding new status vars, please don't forget to update
the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function
@@ -2348,6 +2395,8 @@ bool Query_log_event::write(IO_CACHE* file)
Query_log_event::Query_log_event()
:Log_event(), data_buf(0)
{
+ memset(&user, 0, sizeof(user));
+ memset(&host, 0, sizeof(host));
}
@@ -2390,6 +2439,9 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
{
time_t end_time;
+ memset(&user, 0, sizeof(user));
+ memset(&host, 0, sizeof(host));
+
error_code= errcode;
time(&end_time);
@@ -2574,6 +2626,8 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
bool catalog_nz= 1;
DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
+ memset(&user, 0, sizeof(user));
+ memset(&host, 0, sizeof(host));
common_header_len= description_event->common_header_len;
post_header_len= description_event->post_header_len[event_type-1];
DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
@@ -2728,6 +2782,20 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
data_written= master_data_written= uint4korr(pos);
pos+= 4;
break;
+ case Q_INVOKER:
+ {
+ CHECK_SPACE(pos, end, 1);
+ user.length= *pos++;
+ CHECK_SPACE(pos, end, user.length);
+ user.str= (char *)pos;
+ pos+= user.length;
+
+ CHECK_SPACE(pos, end, 1);
+ host.length= *pos++;
+ CHECK_SPACE(pos, end, host.length);
+ host.str= (char *)pos;
+ pos+= host.length;
+ }
default:
/* That's why you must write status vars in growing order of code */
DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
@@ -2741,12 +2809,16 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
time_zone_len + 1 +
data_len + 1 +
QUERY_CACHE_FLAGS_SIZE +
+ user.length + 1 +
+ host.length + 1 +
db_len + 1,
MYF(MY_WME))))
#else
if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 +
time_zone_len + 1 +
- data_len + 1,
+ data_len + 1 +
+ user.length + 1 +
+ host.length + 1,
MYF(MY_WME))))
#endif
DBUG_VOID_RETURN;
@@ -2769,6 +2841,11 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
if (time_zone_len)
copy_str_and_move(&time_zone_str, &start, time_zone_len);
+ if (user.length > 0)
+ copy_str_and_move((const char **)&(user.str), &start, user.length);
+ if (host.length > 0)
+ copy_str_and_move((const char **)&(host.str), &start, host.length);
+
/**
if time_zone_len or catalog_len are 0, then time_zone and catalog
are uninitialized at this point. shouldn't they point to the
@@ -2904,7 +2981,7 @@ void Query_log_event::print_query_header(IO_CACHE* file,
if (likely(charset_inited) &&
(unlikely(!print_event_info->charset_inited ||
- bcmp((uchar*) print_event_info->charset, (uchar*) charset, 6))))
+ memcmp(print_event_info->charset, charset, 6))))
{
CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
if (cs_info)
@@ -2927,8 +3004,8 @@ void Query_log_event::print_query_header(IO_CACHE* file,
}
if (time_zone_len)
{
- if (bcmp((uchar*) print_event_info->time_zone_str,
- (uchar*) time_zone_str, time_zone_len+1))
+ if (memcmp(print_event_info->time_zone_str,
+ time_zone_str, time_zone_len+1))
{
my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
time_zone_str, print_event_info->delimiter);
@@ -3177,7 +3254,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
thd->variables.collation_database= thd->db_charset;
thd->table_map_for_update= (table_map)table_map_for_update;
-
+ thd->set_invoker(&user, &host);
/* Execute the query (note that we bypass dispatch_command()) */
const char* found_semicolon= NULL;
mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
@@ -5588,7 +5665,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
double real_val;
char real_buf[FMT_G_BUFSIZE(14)];
float8get(real_val, val);
- my_sprintf(real_buf, (real_buf, "%.14g", real_val));
+ sprintf(real_buf, "%.14g", real_val);
my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
break;
case INT_RESULT:
@@ -6157,7 +6234,7 @@ void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
void Create_file_log_event::pack_info(Protocol *protocol)
{
- char buf[NAME_LEN*2 + 30 + 21*2], *pos;
+ char buf[SAFE_NAME_LEN*2 + 30 + 21*2], *pos;
pos= strmov(buf, "db=");
memcpy(pos, db, db_len);
pos= strmov(pos + db_len, ";table=");
@@ -7505,8 +7582,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
{
int actual_error= convert_handler_error(error, thd, table);
bool idempotent_error= (idempotent_error_code(error) &&
- ((bit_is_set(slave_exec_mode,
- SLAVE_EXEC_MODE_IDEMPOTENT)) == 1));
+ (slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT));
bool ignored_error= (idempotent_error == 0 ?
ignored_error_code(actual_error) : 0);
@@ -8439,7 +8515,7 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability
todo: to introduce a property for the event (handler?) which forces
applying the event in the replace (idempotent) fashion.
*/
- if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 ||
+ if ((slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT) ||
m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
{
/*
@@ -8518,7 +8594,7 @@ Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *
int local_error= 0;
m_table->next_number_field=0;
m_table->auto_increment_field_not_null= FALSE;
- if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 ||
+ if ((slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT) ||
m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
{
m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
@@ -8621,7 +8697,7 @@ Rows_log_event::write_row(const Relay_log_info *const rli,
TABLE *table= m_table; // pointer to event's table
int error;
- int keynum;
+ int UNINIT_VAR(keynum);
auto_afree_ptr<char> key(NULL);
/* fill table->record[0] with default values */
@@ -8819,10 +8895,8 @@ int
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
{
DBUG_ASSERT(m_table != NULL);
- int error=
- write_row(rli, /* if 1 then overwrite */
- bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1);
-
+ int error= write_row(rli, (slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT));
+
if (error && !thd->is_error())
{
DBUG_ASSERT(0);
diff --git a/sql/log_event.h b/sql/log_event.h
index d82fc385d86..3c7ba766545 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -264,7 +264,8 @@ struct sql_ex_info
1 + 2 /* type, lc_time_names_number */ + \
1 + 2 /* type, charset_database_number */ + \
1 + 8 /* type, table_map_for_update */ + \
- 1 + 4 /* type, master_data_written */)
+ 1 + 4 /* type, master_data_written */ + \
+ 1 + 16 + 1 + 60/* type, user_len, user, host_len, host */)
#define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \
LOG_EVENT_HEADER_LEN + /* write_header */ \
QUERY_HEADER_LEN + /* write_data */ \
@@ -333,6 +334,8 @@ struct sql_ex_info
#define Q_MASTER_DATA_WRITTEN_CODE 10
+#define Q_INVOKER 11
+
/* Intvar event post-header */
/* Intvar event data */
@@ -395,7 +398,7 @@ struct sql_ex_info
#define ELQ_DUP_HANDLING_OFFSET ELQ_FILE_ID_OFFSET + 12
/* 4 bytes which all binlogs should begin with */
-#define BINLOG_MAGIC "\xfe\x62\x69\x6e"
+#define BINLOG_MAGIC (const uchar*) "\xfe\x62\x69\x6e"
/*
The 2 flags below were useless :
@@ -1558,6 +1561,8 @@ protected:
*/
class Query_log_event: public Log_event
{
+ LEX_STRING user;
+ LEX_STRING host;
protected:
Log_event::Byte* data_buf;
public:
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index b96d1684d77..5d3ab1f17d5 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -441,7 +441,7 @@ copy_extra_record_fields(TABLE *table,
DBUG_ASSERT(master_reclength <= table->s->reclength);
if (master_reclength < table->s->reclength)
- bmove_align(table->record[0] + master_reclength,
+ memcpy(table->record[0] + master_reclength,
table->record[1] + master_reclength,
table->s->reclength - master_reclength);
@@ -720,7 +720,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key)
rnd_pos() returns the record in table->record[0], so we have to
move it to table->record[1].
*/
- bmove_align(table->record[1], table->record[0], table->s->reclength);
+ memcpy(table->record[1], table->record[0], table->s->reclength);
DBUG_RETURN(error);
}
@@ -1218,7 +1218,7 @@ int Update_rows_log_event_old::do_exec_row(TABLE *table)
overwriting the default values that where put there by the
unpack_row() function.
*/
- bmove_align(table->record[0], m_after_image, table->s->reclength);
+ memcpy(table->record[0], m_after_image, table->s->reclength);
copy_extra_record_fields(table, m_master_reclength, m_width);
/*
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 299597632dd..8815f60d9e2 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1056,7 +1056,7 @@ bool mysql_opt_change_db(THD *thd,
bool force_switch,
bool *cur_db_changed);
-void mysql_parse(THD *thd, const char *inBuf, uint length,
+void mysql_parse(THD *thd, char *rawbuf, uint length,
const char ** semicolon);
bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
@@ -2302,6 +2302,7 @@ char *fn_rext(char *name);
/* Conversion functions */
#endif /* MYSQL_SERVER */
+
#if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
uint strconvert(CHARSET_INFO *from_cs, const char *from,
CHARSET_INFO *to_cs, char *to, uint to_length, uint *errors);
@@ -2326,9 +2327,6 @@ uint build_table_filename(char *buff, size_t bufflen, const char *db,
const char *get_canonical_filename(handler *file, const char *path,
char *tmp_path);
-#define MYSQL50_TABLE_NAME_PREFIX "#mysql50#"
-#define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9
-
uint build_table_shadow_filename(char *buff, size_t bufflen,
ALTER_PARTITION_PARAM_TYPE *lpt);
/* Flags for conversion functions. */
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index ccbc7fd3ba1..e89c6b0ab85 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -188,7 +188,7 @@ typedef fp_except fp_except_t;
# define fpu_control_t unsigned int
# define _FPU_EXTENDED 0x300
# define _FPU_DOUBLE 0x200
-# if defined(__GNUC__) || defined(__SUNPRO_CC)
+# if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
# define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw))
# define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw))
# else
@@ -586,7 +586,7 @@ ulong query_buff_size, slow_launch_time, slave_open_temp_tables;
ulong open_files_limit, max_binlog_size, max_relay_log_size;
ulong slave_net_timeout, slave_trans_retries;
ulong slave_exec_mode_options;
-const char *slave_exec_mode_str= "STRICT";
+static const char *slave_exec_mode_str= "STRICT";
ulong thread_cache_size=0, thread_pool_size= 0;
ulong binlog_cache_size=0;
ulonglong max_binlog_cache_size=0;
@@ -2579,7 +2579,9 @@ extern "C" sig_handler handle_segfault(int sig)
{
time_t curr_time;
struct tm tm;
+#ifdef HAVE_STACKTRACE
THD *thd=current_thd;
+#endif
/*
Strictly speaking, one needs a mutex here
@@ -2646,13 +2648,14 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
#endif /* HAVE_LINUXTHREADS */
#ifdef HAVE_STACKTRACE
+
if (!(test_flags & TEST_NO_STACKTRACE))
{
- fprintf(stderr,"thd: 0x%lx\n",(long) thd);
- fprintf(stderr,"\
-Attempting backtrace. You can use the following information to find out\n\
-where mysqld died. If you see no messages after this, something went\n\
-terribly wrong...\n");
+ fprintf(stderr, "thd: 0x%lx\n",(long) thd);
+ fprintf(stderr, "Attempting backtrace. You can use the following "
+ "information to find out\nwhere mysqld died. If "
+ "you see no messages after this, something went\n"
+ "terribly wrong...\n");
my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL,
my_thread_stack_size);
}
@@ -3097,7 +3100,20 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
}
else
{
- if (! thd->main_da.is_error()) // Return only first message
+ if (thd->main_da.is_ok() && !thd->main_da.can_overwrite_status)
+ {
+ /*
+ Client has already got ok packet and we are not in net_flush(), so
+ we write a message to error log.
+ This could happen if we get an error in implicit commit.
+ This should never happen in normal operation, so lets
+ assert here in debug builds.
+ */
+ DBUG_ASSERT(0);
+ func= sql_print_error;
+ MyFlags|= ME_NOREFRESH;
+ }
+ else if (! thd->main_da.is_error()) // Return only first message
{
thd->main_da.set_error_status(thd, error, str);
}
@@ -4226,7 +4242,6 @@ a file name for --log-bin-index option", opt_binlog_index_name);
unireg_abort(1);
}
-#ifdef WITH_CSV_STORAGE_ENGINE
if (opt_bootstrap)
log_output_options= LOG_FILE;
else
@@ -4260,10 +4275,6 @@ a file name for --log-bin-index option", opt_binlog_index_name);
logger.set_handlers(LOG_FILE, opt_slow_log ? log_output_options:LOG_NONE,
opt_log ? log_output_options:LOG_NONE);
}
-#else
- logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
- opt_log ? LOG_FILE:LOG_NONE);
-#endif
/*
Check that the default storage engine is actually available.
@@ -6004,6 +6015,7 @@ enum options_mysqld
#if defined(ENABLED_DEBUG_SYNC)
OPT_DEBUG_SYNC_TIMEOUT,
#endif /* defined(ENABLED_DEBUG_SYNC) */
+ OPT_DEPRECATED_OPTION,
OPT_SLAVE_EXEC_MODE,
OPT_DEADLOCK_SEARCH_DEPTH_SHORT,
OPT_DEADLOCK_SEARCH_DEPTH_LONG,
@@ -6344,13 +6356,11 @@ each time the SQL thread starts.",
"Log some extra information to update log. Please note that this option "
"is deprecated; see --log-short-format option.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef WITH_CSV_STORAGE_ENGINE
{"log-output", OPT_LOG_OUTPUT,
"Syntax: log-output[=value[,value...]], where \"value\" could be TABLE, "
"FILE or NONE.",
&log_output_str, &log_output_str, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-#endif
{"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES,
"Log queries that are executed without benefit of any index to the slow log if it is open.",
&opt_log_queries_not_using_indexes, &opt_log_queries_not_using_indexes,
@@ -6782,6 +6792,9 @@ thread is in the relay logs.",
"Show user and password in SHOW SLAVE HOSTS on this master.",
&opt_show_slave_auth_info, &opt_show_slave_auth_info, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-bdb", OPT_DEPRECATED_OPTION,
+ "Deprecated option; Exist only for compatiblity with old my.cnf files",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DISABLE_GRANT_OPTIONS
{"skip-grant-tables", OPT_SKIP_GRANT,
"Start without grant tables. This gives all users FULL ACCESS to all tables.",
@@ -8222,10 +8235,11 @@ static int mysql_init_variables(void)
/* Things with default values that are not zero */
delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
- slave_exec_mode_options= 0;
- slave_exec_mode_options= (uint)
- find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL,
- &error);
+ slave_exec_mode_options= find_bit_type_or_exit(slave_exec_mode_str,
+ &slave_exec_mode_typelib,
+ NULL, &error);
+ /* Default mode string must not yield a error. */
+ DBUG_ASSERT(!error);
if (error)
return 1;
opt_specialflag= SPECIAL_ENGLISH;
@@ -8473,6 +8487,10 @@ mysqld_get_one_option(int optid,
case '0':
WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-long-format", "--log-short-format");
break;
+ case OPT_DEPRECATED_OPTION:
+ sql_print_warning("'%s' is deprecated and exists only for compatiblity with old my.cnf files; Please remove this option from all your my.cnf files!",
+ opt->name);
+ break;
case 'a':
global_system_variables.sql_mode= fix_sql_mode(MODE_ANSI);
global_system_variables.tx_isolation= ISO_SERIALIZABLE;
@@ -8516,8 +8534,9 @@ mysqld_get_one_option(int optid,
init_slave_skip_errors(argument);
break;
case OPT_SLAVE_EXEC_MODE:
- slave_exec_mode_options= (uint)
- find_bit_type_or_exit(argument, &slave_exec_mode_typelib, "", &error);
+ slave_exec_mode_options= find_bit_type_or_exit(argument,
+ &slave_exec_mode_typelib,
+ "", &error);
if (error)
return 1;
break;
@@ -8622,7 +8641,7 @@ mysqld_get_one_option(int optid,
*val= 0;
val+= 2;
while (*val && my_isspace(mysqld_charset, *val))
- *val++;
+ val++;
if (!*val)
{
sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n");
@@ -8695,7 +8714,6 @@ mysqld_get_one_option(int optid,
WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--log-slow-file'");
opt_slow_log= 1;
break;
-#ifdef WITH_CSV_STORAGE_ENGINE
case OPT_LOG_OUTPUT:
{
if (!argument || !argument[0])
@@ -8713,7 +8731,6 @@ mysqld_get_one_option(int optid,
}
break;
}
-#endif
case OPT_EVENT_SCHEDULER:
#ifndef HAVE_EVENT_SCHEDULER
sql_perror("Event scheduler is not supported in embedded build.");
@@ -8838,8 +8855,7 @@ mysqld_get_one_option(int optid,
if (!slave_warning_issued) //only show the warning once
{
slave_warning_issued = true;
- WARN_DEPRECATED(NULL, "6.0", "for replication startup options",
- "'CHANGE MASTER'");
+ WARN_DEPRECATED(NULL, "6.0", opt->name, "'CHANGE MASTER'");
}
break;
case OPT_CONSOLE:
@@ -9215,7 +9231,7 @@ static int get_options(int *argc,char **argv)
/* Set global MyISAM variables from delay_key_write_options */
fix_delay_key_write((THD*) 0, OPT_GLOBAL);
/* Set global slave_exec_mode from its option */
- fix_slave_exec_mode(OPT_GLOBAL);
+ fix_slave_exec_mode();
global_system_variables.log_slow_filter=
fix_log_slow_filter(global_system_variables.log_slow_filter);
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 044f1ce1391..5fdd2de49d3 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -7589,7 +7589,7 @@ check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree,
if (unlikely(param->thd->killed != 0))
return HA_POS_ERROR;
-
+
keynr=param->real_keynr[idx];
param->range_count++;
if (!tmp_min_flag && ! tmp_max_flag &&
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 1bf137011ab..9e07d735598 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -103,8 +103,8 @@ char *partition_info::create_default_partition_names(uint part_no,
{
do
{
- my_sprintf(move_ptr, (move_ptr,"p%u", (start_no + i)));
- move_ptr+=MAX_PART_NAME_SIZE;
+ sprintf(move_ptr, "p%u", (start_no + i));
+ move_ptr+= MAX_PART_NAME_SIZE;
} while (++i < no_parts_arg);
}
else
@@ -135,7 +135,7 @@ char *partition_info::create_subpartition_name(uint subpart_no,
if (likely(ptr != NULL))
{
- my_sprintf(ptr, (ptr, "%ssp%u", part_name, subpart_no));
+ my_snprintf(ptr, size_alloc, "%ssp%u", part_name, subpart_no);
}
else
{
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 7721d43f936..786d6ef8544 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -578,7 +578,11 @@ void Protocol::end_partial_result_set(THD *thd_arg)
bool Protocol::flush()
{
#ifndef EMBEDDED_LIBRARY
- return net_flush(&thd->net);
+ bool error;
+ thd->main_da.can_overwrite_status= TRUE;
+ error= net_flush(&thd->net);
+ thd->main_da.can_overwrite_status= FALSE;
+ return error;
#else
return 0;
#endif
@@ -618,7 +622,8 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
if (flags & SEND_NUM_ROWS)
{ // Packet with number of elements
uchar *pos= net_store_length(buff, list->elements);
- (void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
+ if (my_net_write(&thd->net, buff, (size_t) (pos-buff)))
+ DBUG_RETURN(1);
}
#ifndef DBUG_OFF
@@ -742,7 +747,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
if (flags & SEND_DEFAULTS)
item->send(&prot, &tmp); // Send default value
if (prot.write())
- break; /* purecov: inspected */
+ DBUG_RETURN(1);
#ifndef DBUG_OFF
field_types[count++]= field.type;
#endif
@@ -755,7 +760,9 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
to show that there is no cursor.
Send no warning information, as it will be sent at statement end.
*/
- write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
+ if (write_eof_packet(thd, &thd->net, thd->server_status,
+ thd->total_warn_count))
+ DBUG_RETURN(1);
}
DBUG_RETURN(prepare_for_send(list));
diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc
index ffae94f733a..8c0523f6766 100644
--- a/sql/rpl_filter.cc
+++ b/sql/rpl_filter.cc
@@ -92,7 +92,7 @@ Rpl_filter::tables_ok(const char* db, TABLE_LIST* tables)
for (; tables; tables= tables->next_global)
{
- char hash_key[2*NAME_LEN+2];
+ char hash_key[SAFE_NAME_LEN*2+2];
char *end;
uint len;
@@ -227,7 +227,7 @@ Rpl_filter::db_ok_with_wild_table(const char *db)
{
DBUG_ENTER("Rpl_filter::db_ok_with_wild_table");
- char hash_key[NAME_LEN+2];
+ char hash_key[SAFE_NAME_LEN+2];
char *end;
int len;
end= strmov(hash_key, db);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 46ae057f97e..c37c4735e37 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1115,8 +1115,7 @@ bool Relay_log_info::cached_charset_compare(char *charset) const
{
DBUG_ENTER("Relay_log_info::cached_charset_compare");
- if (bcmp((uchar*) cached_charset, (uchar*) charset,
- sizeof(cached_charset)))
+ if (memcmp(cached_charset, charset, sizeof(cached_charset)))
{
memcpy(const_cast<char*>(cached_charset), charset, sizeof(cached_charset));
DBUG_RETURN(1);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 3e2d27a012d..f521ab6d6aa 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -95,14 +95,13 @@ TYPELIB delay_key_write_typelib=
delay_key_write_type_names, NULL
};
-const char *slave_exec_mode_names[]=
-{ "STRICT", "IDEMPOTENT", NullS };
-static const unsigned int slave_exec_mode_names_len[]=
-{ sizeof("STRICT") - 1, sizeof("IDEMPOTENT") - 1, 0 };
+static const char *slave_exec_mode_names[]= { "STRICT", "IDEMPOTENT", NullS };
+static unsigned int slave_exec_mode_names_len[]= { sizeof("STRICT") - 1,
+ sizeof("IDEMPOTENT") - 1, 0 };
TYPELIB slave_exec_mode_typelib=
{
array_elements(slave_exec_mode_names)-1, "",
- slave_exec_mode_names, (unsigned int *) slave_exec_mode_names_len
+ slave_exec_mode_names, slave_exec_mode_names_len
};
static int sys_check_ftb_syntax(THD *thd, set_var *var);
@@ -1275,7 +1274,7 @@ uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type,
void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
{
- slave_exec_mode_options= (ULL(1) << SLAVE_EXEC_MODE_STRICT);
+ slave_exec_mode_options= SLAVE_EXEC_MODE_STRICT;
}
bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
@@ -1283,8 +1282,7 @@ bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
bool rc= sys_var_set::check(thd, var);
if (!rc &&
test_all_bits(var->save_result.ulong_value,
- ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
- (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
+ SLAVE_EXEC_MODE_STRICT | SLAVE_EXEC_MODE_IDEMPOTENT))
{
rc= true;
my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
@@ -1301,21 +1299,18 @@ bool sys_var_set_slave_mode::update(THD *thd, set_var *var)
return rc;
}
-void fix_slave_exec_mode(enum_var_type type)
+void fix_slave_exec_mode(void)
{
DBUG_ENTER("fix_slave_exec_mode");
- compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT
- > SLAVE_EXEC_MODE_LAST_BIT - 1);
+
if (test_all_bits(slave_exec_mode_options,
- ((ULL(1) << SLAVE_EXEC_MODE_STRICT) |
- (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT))))
+ SLAVE_EXEC_MODE_STRICT | SLAVE_EXEC_MODE_IDEMPOTENT))
{
- sql_print_error("Ambiguous slave modes combination."
- " STRICT will be used");
- slave_exec_mode_options&= ~(ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT);
+ sql_print_error("Ambiguous slave modes combination. STRICT will be used");
+ slave_exec_mode_options&= ~SLAVE_EXEC_MODE_IDEMPOTENT;
}
- if (!(slave_exec_mode_options & (ULL(1) << SLAVE_EXEC_MODE_IDEMPOTENT)))
- slave_exec_mode_options|= (ULL(1)<< SLAVE_EXEC_MODE_STRICT);
+ if (!(slave_exec_mode_options & SLAVE_EXEC_MODE_IDEMPOTENT))
+ slave_exec_mode_options|= SLAVE_EXEC_MODE_STRICT;
DBUG_VOID_RETURN;
}
diff --git a/sql/set_var.h b/sql/set_var.h
index 54e4ac7e2f1..653f9b5155d 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -1452,7 +1452,7 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length=0);
int sql_set_variables(THD *thd, List<set_var_base> *var_list);
bool not_all_support_one_shot(List<set_var_base> *var_list);
void fix_delay_key_write(THD *thd, enum_var_type type);
-void fix_slave_exec_mode(enum_var_type type);
+void fix_slave_exec_mode(void);
ulong fix_sql_mode(ulong sql_mode);
extern sys_var_const_str sys_charset_system;
extern sys_var_str sys_init_connect;
diff --git a/sql/slave.cc b/sql/slave.cc
index 1421f300804..55bfcceeb47 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2073,7 +2073,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
FLAGSTR(thd->options, OPTION_BEGIN),
- rli->last_event_start_time));
+ (ulong) rli->last_event_start_time));
/*
Execute the event to change the database and update the binary
@@ -2846,8 +2846,8 @@ pthread_handler_t handle_slave_sql(void *arg)
char llbuff[22],llbuff1[22];
char saved_log_name[FN_REFLEN];
char saved_master_log_name[FN_REFLEN];
- my_off_t saved_log_pos;
- my_off_t saved_master_log_pos;
+ my_off_t UNINIT_VAR(saved_log_pos);
+ my_off_t UNINIT_VAR(saved_master_log_pos);
my_off_t saved_skip= 0;
Relay_log_info* rli = &((Master_info*)arg)->rli;
const char *errmsg;
diff --git a/sql/sp.cc b/sql/sp.cc
index e2e7583b901..ebf2b3c360d 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -719,7 +719,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
{
LEX *old_lex= thd->lex, newlex;
String defstr;
- char saved_cur_db_name_buf[NAME_LEN+1];
+ char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
LEX_STRING saved_cur_db_name=
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
bool cur_db_changed;
@@ -1932,7 +1932,7 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
Hence, the overrun happens only if the name is in length > 32 and
uses multibyte (cyrillic, greek, etc.)
*/
- char n[NAME_LEN*2+2];
+ char n[SAFE_NAME_LEN*2+2];
/* m_qname.str is not always \0 terminated */
memcpy(n, name.m_qname.str, name.m_qname.length);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 9f9219566d7..2f1aa042c61 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1087,7 +1087,7 @@ bool
sp_head::execute(THD *thd)
{
DBUG_ENTER("sp_head::execute");
- char saved_cur_db_name_buf[NAME_LEN+1];
+ char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
LEX_STRING saved_cur_db_name=
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
bool cur_db_changed= FALSE;
@@ -3856,7 +3856,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
for (; table ; table= table->next_global)
if (!table->derived && !table->schema_table)
{
- char tname[(NAME_LEN + 1) * 3]; // db\0table\0alias\0
+ char tname[(SAFE_NAME_LEN + 1) * 3]; // db\0table\0alias\0
uint tlen, alen;
tlen= table->db_length;
diff --git a/sql/spatial.cc b/sql/spatial.cc
index a23e8ec0d90..2305a8eb97d 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -53,7 +53,7 @@ static Geometry::Class_info **ci_collection_end=
Geometry::ci_collection+Geometry::wkb_last + 1;
Geometry::Class_info::Class_info(const char *name, int type_id,
- void(*create_func)(void *)):
+ create_geom_t create_func):
m_type_id(type_id), m_create_func(create_func)
{
m_name.str= (char *) name;
@@ -62,39 +62,39 @@ Geometry::Class_info::Class_info(const char *name, int type_id,
ci_collection[type_id]= this;
}
-static void create_point(void *buffer)
+static Geometry *create_point(char *buffer)
{
- new(buffer) Gis_point;
+ return new (buffer) Gis_point;
}
-static void create_linestring(void *buffer)
+static Geometry *create_linestring(char *buffer)
{
- new(buffer) Gis_line_string;
+ return new (buffer) Gis_line_string;
}
-static void create_polygon(void *buffer)
+static Geometry *create_polygon(char *buffer)
{
- new(buffer) Gis_polygon;
+ return new (buffer) Gis_polygon;
}
-static void create_multipoint(void *buffer)
+static Geometry *create_multipoint(char *buffer)
{
- new(buffer) Gis_multi_point;
+ return new (buffer) Gis_multi_point;
}
-static void create_multipolygon(void *buffer)
+static Geometry *create_multipolygon(char *buffer)
{
- new(buffer) Gis_multi_polygon;
+ return new (buffer) Gis_multi_polygon;
}
-static void create_multilinestring(void *buffer)
+static Geometry *create_multilinestring(char *buffer)
{
- new(buffer) Gis_multi_line_string;
+ return new (buffer) Gis_multi_line_string;
}
-static void create_geometrycollection(void *buffer)
+static Geometry *create_geometrycollection(char *buffer)
{
- new(buffer) Gis_geometry_collection;
+ return new (buffer) Gis_geometry_collection;
}
@@ -145,6 +145,15 @@ Geometry::Class_info *Geometry::find_class(const char *name, uint32 len)
}
+Geometry *Geometry::create_by_typeid(Geometry_buffer *buffer, int type_id)
+{
+ Class_info *ci;
+ if (!(ci= find_class(type_id)))
+ return NULL;
+ return (*ci->m_create_func)(buffer->data);
+}
+
+
Geometry *Geometry::construct(Geometry_buffer *buffer,
const char *data, uint32 data_len)
{
@@ -153,6 +162,7 @@ Geometry *Geometry::construct(Geometry_buffer *buffer,
if (data_len < SRID_SIZE + WKB_HEADER_SIZE) // < 4 + (1 + 4)
return NULL;
+ /* + 1 to skip the byte order (stored in position SRID_SIZE). */
geom_type= uint4korr(data + SRID_SIZE + 1);
if (!(result= create_by_typeid(buffer, (int) geom_type)))
return NULL;
@@ -177,9 +187,7 @@ Geometry *Geometry::create_from_wkt(Geometry_buffer *buffer,
if (!(ci= find_class(name.str, name.length)) ||
wkt->reserve(1 + 4, 512))
return NULL;
- (*ci->m_create_func)((void *)buffer);
- Geometry *result= (Geometry *)buffer;
-
+ Geometry *result= (*ci->m_create_func)(buffer->data);
wkt->q_append((char) wkb_ndr);
wkt->q_append((uint32) result->get_class_info()->m_type_id);
if (trs->check_next_symbol('(') ||
diff --git a/sql/spatial.h b/sql/spatial.h
index 86c2ed8c197..f778acd6c34 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -225,15 +225,18 @@ public:
{
wkb_xdr= 0, /* Big Endian */
wkb_ndr= 1 /* Little Endian */
- };
+ };
+
+ /** Callback which creates Geometry objects on top of a given placement. */
+ typedef Geometry *(*create_geom_t)(char *);
class Class_info
{
public:
LEX_STRING m_name;
int m_type_id;
- void (*m_create_func)(void *);
- Class_info(const char *name, int type_id, void(*create_func)(void *));
+ create_geom_t m_create_func;
+ Class_info(const char *name, int type_id, create_geom_t create_func);
};
virtual const Class_info *get_class_info() const=0;
@@ -263,15 +266,7 @@ public:
virtual int geometry_n(uint32 num, String *result) const { return -1; }
public:
- static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id)
- {
- Class_info *ci;
- if (!(ci= find_class((int) type_id)))
- return NULL;
- (*ci->m_create_func)((void *)buffer);
- return my_reinterpret_cast(Geometry *)(buffer);
- }
-
+ static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id);
static Geometry *construct(Geometry_buffer *buffer,
const char *data, uint32 data_len);
static Geometry *create_from_wkt(Geometry_buffer *buffer,
@@ -528,11 +523,8 @@ public:
const Class_info *get_class_info() const;
};
-const int geometry_buffer_size= sizeof(Gis_point);
-struct Geometry_buffer
-{
- void *arr[(geometry_buffer_size - 1)/sizeof(void *) + 1];
-};
+struct Geometry_buffer : public
+ my_aligned_storage<sizeof(Gis_point), MY_ALIGNOF(Gis_point)> {};
#endif /*HAVE_SPATAIAL*/
#endif
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index be093b8738e..496e8c310dd 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -294,6 +294,7 @@ static bool compare_hostname(const acl_host_and_ip *host,const char *hostname,
const char *ip);
static my_bool acl_load(THD *thd, TABLE_LIST *tables);
static my_bool grant_load(THD *thd, TABLE_LIST *tables);
+static inline void get_grantor(THD *thd, char* grantor);
/*
Convert scrambled password to binary form, according to scramble type,
@@ -467,7 +468,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
READ_RECORD read_record_info;
my_bool return_val= TRUE;
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
- char tmp_name[NAME_LEN+1];
+ char tmp_name[SAFE_NAME_LEN+1];
int password_length;
ulong old_sql_mode= thd->variables.sql_mode;
DBUG_ENTER("acl_load");
@@ -2481,7 +2482,7 @@ static GRANT_NAME *name_hash_search(HASH *name_hash,
const char *user, const char *tname,
bool exact, bool name_tolower)
{
- char helping [NAME_LEN*2+USERNAME_LENGTH+3], *name_ptr;
+ char helping [SAFE_NAME_LEN*2+USERNAME_LENGTH+3], *name_ptr;
uint len;
GRANT_NAME *grant_name,*found=0;
HASH_SEARCH_STATE state;
@@ -2734,6 +2735,20 @@ end:
DBUG_RETURN(result);
}
+static inline void get_grantor(THD *thd, char *grantor)
+{
+ const char *user= thd->security_ctx->user;
+ const char *host= thd->security_ctx->host_or_ip;
+
+#if defined(HAVE_REPLICATION)
+ if (thd->slave_thread && thd->has_invoker())
+ {
+ user= thd->get_invoker_user().str;
+ host= thd->get_invoker_host().str;
+ }
+#endif
+ strxmov(grantor, user, "@", host, NullS);
+}
static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
TABLE *table, const LEX_USER &combo,
@@ -2748,9 +2763,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
uchar user_key[MAX_KEY_LENGTH];
DBUG_ENTER("replace_table_table");
- strxmov(grantor, thd->security_ctx->user, "@",
- thd->security_ctx->host_or_ip, NullS);
-
+ get_grantor(thd, grantor);
/*
The following should always succeed as new users are created before
this function is called!
@@ -2880,9 +2893,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name,
DBUG_RETURN(-1);
}
- strxmov(grantor, thd->security_ctx->user, "@",
- thd->security_ctx->host_or_ip, NullS);
-
+ get_grantor(thd, grantor);
/*
New users are created before this function is called.
@@ -3449,7 +3460,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
{
List_iterator <LEX_USER> str_list (list);
LEX_USER *Str, *tmp_Str;
- char tmp_db[NAME_LEN+1];
+ char tmp_db[SAFE_NAME_LEN+1];
bool create_new_users=0;
TABLE_LIST tables[2];
bool save_binlog_row_based;
@@ -4336,7 +4347,7 @@ static bool check_grant_db_routine(THD *thd, const char *db, HASH *hash)
bool check_grant_db(THD *thd,const char *db)
{
Security_context *sctx= thd->security_ctx;
- char helping [NAME_LEN+USERNAME_LENGTH+2];
+ char helping [SAFE_NAME_LEN + USERNAME_LENGTH+2];
uint len;
bool error= TRUE;
@@ -7281,7 +7292,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
char *passwd= strend(user)+1;
uint user_len= passwd - user - 1;
char *db= passwd;
- char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
+ char db_buff[SAFE_NAME_LEN + 1]; // buffer to store db in utf8
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
uint dummy_errors;
@@ -7480,7 +7491,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
char *passwd= strend(user)+1;
uint user_len= passwd - user - 1, db_len;
char *db= passwd;
- char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
+ char db_buff[SAFE_NAME_LEN + 1]; // buffer to store db in utf8
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
uint dummy_errors;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 66a4f7694f9..0dd1ef73463 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -613,7 +613,7 @@ void release_table_share(TABLE_SHARE *share, enum release_type type)
TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name)
{
- char key[NAME_LEN*2+2];
+ char key[SAFE_NAME_LEN*2+2];
TABLE_LIST table_list;
uint key_length;
safe_mutex_assert_owner(&LOCK_open);
@@ -5709,7 +5709,7 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
DBUG_ENTER("update_field_dependencies");
if (thd->mark_used_columns != MARK_COLUMNS_NONE)
{
- MY_BITMAP *current_bitmap;
+ MY_BITMAP *bitmap;
/*
We always want to register the used keys, as the column bitmap may have
@@ -5723,9 +5723,9 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
table->mark_virtual_col(field);
if (thd->mark_used_columns == MARK_COLUMNS_READ)
- current_bitmap= table->read_set;
+ bitmap= table->read_set;
else
- current_bitmap= table->write_set;
+ bitmap= table->write_set;
/*
The test-and-set mechanism in the bitmap is not reliable during
@@ -5734,7 +5734,7 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
only those columns that are used in the SET clause. I.e they are being
set here. See multi_update::prepare()
*/
- if (bitmap_fast_test_and_set(current_bitmap, field->field_index))
+ if (bitmap_fast_test_and_set(bitmap, field->field_index))
{
if (thd->mark_used_columns == MARK_COLUMNS_WRITE)
{
@@ -6327,7 +6327,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
const char *table_name= item->table_name;
const char *name= item->field_name;
uint length=(uint) strlen(name);
- char name_buff[NAME_LEN+1];
+ char name_buff[SAFE_NAME_LEN+1];
TABLE_LIST *cur_table= first_table;
TABLE_LIST *actual_table;
bool allow_rowid;
@@ -6484,7 +6484,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
(report_error == REPORT_ALL_ERRORS ||
report_error == REPORT_EXCEPT_NON_UNIQUE))
{
- char buff[NAME_LEN*2 + 2];
+ char buff[SAFE_NAME_LEN*2 + 2];
if (db && db[0])
{
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
@@ -7870,7 +7870,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
{
Field_iterator_table_ref field_iterator;
bool found;
- char name_buff[NAME_LEN+1];
+ char name_buff[SAFE_NAME_LEN+1];
DBUG_ENTER("insert_fields");
DBUG_PRINT("arena", ("stmt arena: 0x%lx", (ulong)thd->stmt_arena));
@@ -8569,15 +8569,15 @@ my_bool mysql_rm_tmp_tables(void)
(file->name[1] == '.' && !file->name[2])))
continue;
- if (!bcmp((uchar*) file->name, (uchar*) tmp_file_prefix,
- tmp_file_prefix_length))
+ if (!memcmp(file->name, tmp_file_prefix,
+ tmp_file_prefix_length))
{
char *ext= fn_ext(file->name);
uint ext_len= strlen(ext);
uint filePath_len= my_snprintf(filePath, sizeof(filePath),
"%s%c%s", tmpdir, FN_LIBCHAR,
file->name);
- if (!bcmp((uchar*) reg_ext, (uchar*) ext, ext_len))
+ if (!strcmp(reg_ext, ext))
{
handler *handler_file= 0;
/* We should cut file extention before deleting of table */
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 302d5e95a28..cde040a88a4 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1679,7 +1679,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
thd->limit_found_rows = query->found_rows();
thd->status_var.last_query_cost= 0.0;
thd->query_plan_flags= (thd->query_plan_flags & ~QPLAN_QC_NO) | QPLAN_QC;
- thd->main_da.disable_status();
+ if (!thd->main_da.is_set())
+ thd->main_da.disable_status();
BLOCK_UNLOCK_RD(query_block);
DBUG_RETURN(1); // Result sent to client
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index b4e34fc1890..cac9b624bae 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -802,8 +802,10 @@ THD::THD()
thr_lock_owner_init(&main_lock_id, &lock_info);
m_internal_handler= NULL;
-
arena_for_cached_items= 0;
+ current_user_used= FALSE;
+ memset(&invoker_user, 0, sizeof(invoker_user));
+ memset(&invoker_host, 0, sizeof(invoker_host));
}
@@ -1216,13 +1218,13 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
while (to != end)
*(to++)+= *(from++) - *(dec++);
- to_var->bytes_received= (from_var->bytes_received -
- dec_var->bytes_received);
- to_var->bytes_sent+= from_var->bytes_sent - dec_var->bytes_sent;
- to_var->binlog_bytes_written= (from_var->binlog_bytes_written -
- dec_var->binlog_bytes_written);
- to_var->cpu_time+= from_var->cpu_time - dec_var->cpu_time;
- to_var->busy_time+= from_var->busy_time - dec_var->busy_time;
+ to_var->bytes_received+= from_var->bytes_received -
+ dec_var->bytes_received;
+ to_var->bytes_sent+= from_var->bytes_sent - dec_var->bytes_sent;
+ to_var->binlog_bytes_written+= from_var->binlog_bytes_written -
+ dec_var->binlog_bytes_written;
+ to_var->cpu_time+= from_var->cpu_time - dec_var->cpu_time;
+ to_var->busy_time+= from_var->busy_time - dec_var->busy_time;
}
#define SECONDS_TO_WAIT_FOR_KILL 2
@@ -1429,6 +1431,7 @@ void THD::cleanup_after_query()
where= THD::DEFAULT_WHERE;
/* reset table map for multi-table update */
table_map_for_update= 0;
+ clean_current_user_used();
}
@@ -3455,6 +3458,23 @@ void THD::set_query(char *query_arg, uint32 query_length_arg)
pthread_mutex_unlock(&LOCK_thd_data);
}
+void THD::get_definer(LEX_USER *definer)
+{
+ set_current_user_used();
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ if (slave_thread && has_invoker())
+ {
+ definer->user = invoker_user;
+ definer->host= invoker_host;
+ definer->password= null_lex_str;
+ definer->plugin= empty_lex_str;
+ definer->auth= empty_lex_str;
+ }
+ else
+#endif
+ get_default_definer(this, definer);
+}
+
/**
Mark transaction to rollback and mark error as fatal to a sub-statement.
@@ -3553,9 +3573,13 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
bool xid_cache_insert(XID_STATE *xid_state)
{
pthread_mutex_lock(&LOCK_xid_cache);
- DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(),
- xid_state->xid.key_length())==0);
- my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
+ if (hash_search(&xid_cache, xid_state->xid.key(), xid_state->xid.key_length()))
+ {
+ pthread_mutex_unlock(&LOCK_xid_cache);
+ my_error(ER_XAER_DUPID, MYF(0));
+ return TRUE;
+ }
+ my_bool res= my_hash_insert(&xid_cache, (uchar*)xid_state);
pthread_mutex_unlock(&LOCK_xid_cache);
return res;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 2240236a0e5..20f34bacca7 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -86,9 +86,10 @@ enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME };
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE };
enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
DELAY_KEY_WRITE_ALL };
-enum enum_slave_exec_mode { SLAVE_EXEC_MODE_STRICT,
- SLAVE_EXEC_MODE_IDEMPOTENT,
- SLAVE_EXEC_MODE_LAST_BIT};
+
+#define SLAVE_EXEC_MODE_STRICT (1U << 0)
+#define SLAVE_EXEC_MODE_IDEMPOTENT (1U << 1)
+
enum enum_mark_columns
{ MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE};
@@ -418,7 +419,11 @@ struct system_variables
};
-/* per thread status variables */
+/**
+ Per thread status variables.
+ Must be long/ulong up to last_system_status_var so that
+ add_to_status/add_diff_to_status can work.
+*/
typedef struct system_status_var
{
@@ -479,17 +484,15 @@ typedef struct system_status_var
Number of statements sent from the client
*/
ulong questions;
- ulong empty_queries;
- ulong access_denied_errors; /* Can only be 0 or 1 */
- ulong lost_connections;
/*
IMPORTANT!
SEE last_system_status_var DEFINITION BELOW.
- Below 'last_system_status_var' are all variables which doesn't make any
- sense to add to the /global/ status variable counter.
- Status variables which it does not make sense to add to
- global status variable counter
+ Below 'last_system_status_var' are all variables that cannot be handled
+ automatically by add_to_status()/add_diff_to_status().
*/
+ ulong empty_queries;
+ ulong access_denied_errors; /* Can only be 0 or 1 */
+ ulong lost_connections;
ulonglong bytes_received;
ulonglong bytes_sent;
ulonglong binlog_bytes_written;
@@ -2391,6 +2394,18 @@ public:
Protected with LOCK_thd_data mutex.
*/
void set_query(char *query_arg, uint32 query_length_arg);
+ void set_current_user_used() { current_user_used= TRUE; }
+ bool is_current_user_used() { return current_user_used; }
+ void clean_current_user_used() { current_user_used= FALSE; }
+ void get_definer(LEX_USER *definer);
+ void set_invoker(const LEX_STRING *user, const LEX_STRING *host)
+ {
+ invoker_user= *user;
+ invoker_host= *host;
+ }
+ LEX_STRING get_invoker_user() { return invoker_user; }
+ LEX_STRING get_invoker_host() { return invoker_host; }
+ bool has_invoker() { return invoker_user.length > 0; }
private:
/*
@@ -2431,6 +2446,25 @@ private:
tree itself is reused between executions and thus is stored elsewhere.
*/
MEM_ROOT main_mem_root;
+
+ /**
+ It will be set TURE if CURRENT_USER() is called in account management
+ statements or default definer is set in CREATE/ALTER SP, SF, Event,
+ TRIGGER or VIEW statements.
+
+ Current user will be binlogged into Query_log_event if current_user_used
+ is TRUE; It will be stored into invoker_host and invoker_user by SQL thread.
+ */
+ bool current_user_used;
+
+ /**
+ It points to the invoker in the Query_log_event.
+ SQL thread use it as the default definer in CREATE/ALTER SP, SF, Event,
+ TRIGGER or VIEW statements or current user in account management
+ statements if it is not NULL.
+ */
+ LEX_STRING invoker_user;
+ LEX_STRING invoker_host;
};
/** A short cut for thd->main_da.set_ok_status(). */
@@ -2489,7 +2523,7 @@ class select_result :public Sql_alloc {
protected:
THD *thd;
SELECT_LEX_UNIT *unit;
- uint nest_level;
+ int nest_level;
public:
select_result();
virtual ~select_result() {};
@@ -2630,7 +2664,7 @@ public:
Creates a select_export to represent INTO OUTFILE <filename> with a
defined level of subquery nesting.
*/
- select_export(sql_exchange *ex, uint nest_level_arg) :select_to_file(ex)
+ select_export(sql_exchange *ex, int nest_level_arg) :select_to_file(ex)
{
nest_level= nest_level_arg;
}
@@ -2647,7 +2681,7 @@ public:
Creates a select_export to represent INTO DUMPFILE <filename> with a
defined level of subquery nesting.
*/
- select_dump(sql_exchange *ex, uint nest_level_arg) :
+ select_dump(sql_exchange *ex, int nest_level_arg) :
select_to_file(ex)
{
nest_level= nest_level_arg;
@@ -3124,7 +3158,7 @@ public:
Creates a select_dumpvar to represent INTO <variable> with a defined
level of subquery nesting.
*/
- select_dumpvar(uint nest_level_arg)
+ select_dumpvar(int nest_level_arg)
{
var_list.empty();
row_count= 0;
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index e9ef5ef0cf3..77be6eaff34 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -658,7 +658,12 @@ void Materialized_cursor::fetch(ulong num_rows)
if ((res= table->file->ha_rnd_next(table->record[0])))
break;
/* Send data only if the read was successful. */
- result->send_data(item_list);
+ /*
+ If network write failed (i.e. due to a closed socked),
+ the error has already been set. Just return.
+ */
+ if (result->send_data(item_list))
+ return;
}
switch (res) {
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index ea138807122..f6549858a9d 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -3924,6 +3924,17 @@ void select_create::abort()
if (table)
{
+ if (thd->lex->sql_command == SQLCOM_CREATE_TABLE &&
+ thd->current_stmt_binlog_row_based &&
+ !(thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
+ mysql_bin_log.is_open())
+ {
+ /*
+ This should be removed after BUG#47899.
+ */
+ mysql_bin_log.reset_gathered_updates(thd);
+ }
+
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
if (!create_info->table_existed)
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 33121e5301d..524206d0af1 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -111,7 +111,7 @@ st_parsing_options::reset()
}
-bool Lex_input_stream::init(THD *thd, const char *buff, unsigned int length)
+bool Lex_input_stream::init(THD *thd, char *buff, unsigned int length)
{
DBUG_EXECUTE_IF("bug42064_simulate_oom",
DBUG_SET("+d,simulate_out_of_memory"););
@@ -1303,11 +1303,10 @@ int MYSQLlex(void *arg, void *yythd)
ulong version;
version=strtol(version_str, NULL, 10);
- /* Accept 'M' 'm' 'm' 'd' 'd' */
- lip->yySkipn(5);
-
if (version <= MYSQL_VERSION_ID)
{
+ /* Accept 'M' 'm' 'm' 'd' 'd' */
+ lip->yySkipn(5);
/* Expand the content of the special comment as real code */
lip->set_echo(TRUE);
state=MY_LEX_START;
@@ -1315,7 +1314,16 @@ int MYSQLlex(void *arg, void *yythd)
}
else
{
+ /*
+ Patch and skip the conditional comment to avoid it
+ being propagated infinitely (eg. to a slave).
+ */
+ char *pcom= lip->yyUnput(' ');
comment_closed= ! consume_comment(lip, 1);
+ if (! comment_closed)
+ {
+ *pcom= '!';
+ }
/* version allowed to have one level of comment inside. */
}
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 2f14f3eb575..020e2b4e76e 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1190,7 +1190,7 @@ public:
@retval FALSE OK
@retval TRUE Error
*/
- bool init(THD *thd, const char *buff, unsigned int length);
+ bool init(THD *thd, char *buff, unsigned int length);
/**
Set the echo mode.
@@ -1305,6 +1305,20 @@ public:
}
/**
+ Puts a character back into the stream, canceling
+ the effect of the last yyGet() or yySkip().
+ Note that the echo mode should not change between calls
+ to unput, get, or skip from the stream.
+ */
+ char *yyUnput(char ch)
+ {
+ *--m_ptr= ch;
+ if (m_echo)
+ m_cpp_ptr--;
+ return m_ptr;
+ }
+
+ /**
End of file indicator for the query text to parse.
@return true if there are no more characters to parse
*/
@@ -1450,7 +1464,7 @@ public:
private:
/** Pointer to the current position in the raw input stream. */
- const char *m_ptr;
+ char *m_ptr;
/** Starting position of the last token parsed, in the raw buffer. */
const char *m_tok_start;
@@ -1996,7 +2010,7 @@ public:
@retval FALSE OK
@retval TRUE Error
*/
- bool init(THD *thd, const char *buff, unsigned int length)
+ bool init(THD *thd, char *buff, unsigned int length)
{
return m_lip.init(thd, buff, length);
}
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 15eb85ab52c..dc840cefc66 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -74,7 +74,7 @@ public:
SQL_I_List() { empty(); }
- SQL_I_List(const SQL_I_List &tmp) :Sql_alloc()
+ SQL_I_List(const SQL_I_List &tmp) : Sql_alloc()
{
elements= tmp.elements;
first= tmp.first;
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index d0506d75925..1b7f690259a 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -128,6 +128,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
bool is_fifo=0;
#ifndef EMBEDDED_LIBRARY
LOAD_FILE_INFO lf_info;
+ THD::killed_state killed_status;
#endif
char *db = table_list->db; // This is never null
/*
@@ -138,7 +139,6 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
char *tdb= thd->db ? thd->db : db; // Result is never null
ulong skip_lines= ex->skip_lines;
bool transactional_table;
- THD::killed_state killed_status= THD::NOT_KILLED;
DBUG_ENTER("mysql_load");
#ifdef EMBEDDED_LIBRARY
@@ -455,7 +455,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
error=1;
thd->killed= THD::KILL_QUERY;
};);
- killed_status= (error == 0)? THD::NOT_KILLED : thd->killed;
+
+#ifndef EMBEDDED_LIBRARY
+ killed_status= (error == 0) ? THD::NOT_KILLED : thd->killed;
+#endif
+
/*
We must invalidate the table in query cache before binlog writing and
ha_autocommit_...
@@ -1202,29 +1206,6 @@ int READ_INFO::read_field()
while ( to < end_of_buff)
{
chr = GET;
-#ifdef USE_MB
- if ((my_mbcharlen(read_charset, chr) > 1) &&
- to+my_mbcharlen(read_charset, chr) <= end_of_buff)
- {
- uchar* p = (uchar*)to;
- *to++ = chr;
- int ml = my_mbcharlen(read_charset, chr);
- int i;
- for (i=1; i<ml; i++) {
- chr = GET;
- if (chr == my_b_EOF)
- goto found_eof;
- *to++ = chr;
- }
- if (my_ismbchar(read_charset,
- (const char *)p,
- (const char *)to))
- continue;
- for (i=0; i<ml; i++)
- PUSH((uchar) *--to);
- chr = GET;
- }
-#endif
if (chr == my_b_EOF)
goto found_eof;
if (chr == escape_char)
@@ -1309,6 +1290,39 @@ int READ_INFO::read_field()
return 0;
}
}
+#ifdef USE_MB
+ if (my_mbcharlen(read_charset, chr) > 1 &&
+ to + my_mbcharlen(read_charset, chr) <= end_of_buff)
+ {
+ uchar* p= (uchar*) to;
+ int ml, i;
+ *to++ = chr;
+
+ ml= my_mbcharlen(read_charset, chr);
+
+ for (i= 1; i < ml; i++)
+ {
+ chr= GET;
+ if (chr == my_b_EOF)
+ {
+ /*
+ Need to back up the bytes already ready from illformed
+ multi-byte char
+ */
+ to-= i;
+ goto found_eof;
+ }
+ *to++ = chr;
+ }
+ if (my_ismbchar(read_charset,
+ (const char *)p,
+ (const char *)to))
+ continue;
+ for (i= 0; i < ml; i++)
+ PUSH((uchar) *--to);
+ chr= GET;
+ }
+#endif
*to++ = (uchar) chr;
}
/*
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index af66c9447b0..407c2f5bb93 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -476,6 +476,7 @@ static void handle_bootstrap_impl(THD *thd)
buff= (char*) thd->net.buff;
if (!fgets(buff + length, thd->net.max_packet - length, file))
{
+ net_end_statement(thd);
bootstrap_error= 1;
break;
}
@@ -1000,7 +1001,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
NET *net= &thd->net;
bool error= 0;
DBUG_ENTER("dispatch_command");
- DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
+ DBUG_PRINT("info", ("command: %d", command));
thd->command=command;
/*
@@ -1264,7 +1265,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char *fields, *packet_end= packet + packet_length, *wildcard;
/* Locked closure of all tables */
TABLE_LIST table_list;
- char db_buff[NAME_LEN+1];
+ char db_buff[SAFE_NAME_LEN+1];
uint32 db_length;
uint dummy_errors, query_length;
@@ -1283,7 +1284,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
db_length= wildcard - packet;
wildcard++;
query_length= (uint) (packet_end - wildcard); // Don't count end \0
- if (db_length > NAME_LEN || query_length > NAME_LEN)
+ if (db_length > SAFE_NAME_LEN || query_length > NAME_LEN)
{
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break;
@@ -1533,13 +1534,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
(sf_malloc_max_memory+1023L)/1024L);
}
#endif
-#ifdef EMBEDDED_LIBRARY
- /* Store the buffer in permanent memory */
- my_ok(thd, 0, 0, buff);
-#else
+#ifndef EMBEDDED_LIBRARY
VOID(my_net_write(net, (uchar*) buff, length));
VOID(net_flush(net));
thd->main_da.disable_status();
+#else
+ /* Store the buffer in permanent memory */
+ my_ok(thd, 0, 0, buff);
#endif
break;
}
@@ -4741,7 +4742,7 @@ create_sp_error:
my_error(ER_XAER_NOTA, MYF(0));
break;
}
- thd->transaction.xid_state.xa_state=XA_ACTIVE;
+ thd->transaction.xid_state.xa_state= XA_ACTIVE;
my_ok(thd);
break;
}
@@ -4761,16 +4762,16 @@ create_sp_error:
my_error(ER_XAER_OUTSIDE, MYF(0));
break;
}
- if (xid_cache_search(thd->lex->xid))
- {
- my_error(ER_XAER_DUPID, MYF(0));
- break;
- }
DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
- thd->transaction.xid_state.xa_state=XA_ACTIVE;
+ thd->transaction.xid_state.xa_state= XA_ACTIVE;
thd->transaction.xid_state.rm_error= 0;
thd->transaction.xid_state.xid.set(thd->lex->xid);
- xid_cache_insert(&thd->transaction.xid_state);
+ if (xid_cache_insert(&thd->transaction.xid_state))
+ {
+ thd->transaction.xid_state.xa_state= XA_NOTR;
+ thd->transaction.xid_state.xid.null();
+ break;
+ }
thd->transaction.all.modified_non_trans_table= FALSE;
thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
thd->server_status|= SERVER_STATUS_IN_TRANS;
@@ -4824,6 +4825,16 @@ create_sp_error:
case SQLCOM_XA_COMMIT:
if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
{
+ /*
+ xid_state.in_thd is always true beside of xa recovery
+ procedure. Note, that there is no race condition here
+ between xid_cache_search and xid_cache_delete, since we're always
+ deleting our own XID (thd->lex->xid == thd->transaction.xid_state.xid).
+ The only case when thd->lex->xid != thd->transaction.xid_state.xid
+ and xid_state->in_thd == 0 is in ha_recover() functionality,
+ which is called before starting client connections, and thus is
+ always single-threaded.
+ */
XID_STATE *xs=xid_cache_search(thd->lex->xid);
if (!xs || xs->in_thd)
my_error(ER_XAER_NOTA, MYF(0));
@@ -5970,13 +5981,13 @@ void mysql_init_multi_delete(LEX *lex)
Parse a query.
@param thd Current thread
- @param inBuf Begining of the query text
+ @param rawbuf Begining of the query text
@param length Length of the query text
@param[out] found_semicolon For multi queries, position of the character of
the next query in the query text.
*/
-void mysql_parse(THD *thd, const char *inBuf, uint length,
+void mysql_parse(THD *thd, char *rawbuf, uint length,
const char ** found_semicolon)
{
DBUG_ENTER("mysql_parse");
@@ -6001,7 +6012,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
lex_start(thd);
mysql_reset_thd_for_next_command(thd, opt_userstat_running);
- if (query_cache_send_result_to_client(thd, (char*) inBuf, length) <= 0)
+ if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
{
LEX *lex= thd->lex;
@@ -6010,7 +6021,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
Parser_state parser_state;
bool err;
- if (!(err= parser_state.init(thd, inBuf, length)))
+ if (!(err= parser_state.init(thd, rawbuf, length)))
{
err= parse_sql(thd, & parser_state, NULL);
*found_semicolon= parser_state.m_lip.found_semicolon;
@@ -6097,14 +6108,14 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
1 can be ignored
*/
-bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
+bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length)
{
LEX *lex= thd->lex;
bool error= 0;
DBUG_ENTER("mysql_test_parse_for_slave");
Parser_state parser_state;
- if (!(error= parser_state.init(thd, inBuf, length)))
+ if (!(error= parser_state.init(thd, rawbuf, length)))
{
lex_start(thd);
mysql_reset_thd_for_next_command(thd, opt_userstat_running);
@@ -7732,7 +7743,7 @@ LEX_USER *create_default_definer(THD *thd)
if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
return 0;
- get_default_definer(thd, definer);
+ thd->get_definer(definer);
return definer;
}
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 6058db4aad4..551f19694ef 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -3877,7 +3877,7 @@ void get_partition_set(const TABLE *table, uchar *buf, const uint index,
*/
bool mysql_unpack_partition(THD *thd,
- const char *part_buf, uint part_info_len,
+ char *part_buf, uint part_info_len,
const char *part_state, uint part_state_len,
TABLE* table, bool is_create_table_ind,
handlerton *default_db_type,
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index b9efbf25a00..02a5ead1117 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -78,7 +78,7 @@ void get_full_part_id_from_key(const TABLE *table, uchar *buf,
KEY *key_info,
const key_range *key_spec,
part_id_range *part_spec);
-bool mysql_unpack_partition(THD *thd, const char *part_buf,
+bool mysql_unpack_partition(THD *thd, char *part_buf,
uint part_info_len,
const char *part_state, uint part_state_len,
TABLE *table, bool is_create_table_ind,
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 600c140c776..d5e53651e18 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -263,8 +263,11 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns)
&stmt->lex->param_list,
Protocol::SEND_EOF);
}
- /* Flag that a response has already been sent */
- thd->main_da.disable_status();
+
+ if (!error)
+ /* Flag that a response has already been sent */
+ thd->main_da.disable_status();
+
DBUG_RETURN(error);
}
#else
@@ -790,7 +793,7 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
type (the types are supplied at execute). Check that the
supplied type of placeholder can accept a data stream.
*/
- else if (!is_param_long_data_type(param))
+ else if (! is_param_long_data_type(param))
DBUG_RETURN(1);
res= param->query_val_str(&str);
if (param->convert_str_value(thd))
@@ -836,7 +839,7 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
type (the types are supplied at execute). Check that the
supplied type of placeholder can accept a data stream.
*/
- else if (is_param_long_data_type(param))
+ else if (! is_param_long_data_type(param))
DBUG_RETURN(1);
if (param->convert_str_value(stmt->thd))
DBUG_RETURN(1); /* out of memory */
@@ -3336,7 +3339,7 @@ reexecute:
bool
Prepared_statement::reprepare()
{
- char saved_cur_db_name_buf[NAME_LEN+1];
+ char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
LEX_STRING saved_cur_db_name=
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
LEX_STRING stmt_db_name= { db, db_length };
@@ -3497,7 +3500,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
Query_arena *old_stmt_arena;
bool error= TRUE;
- char saved_cur_db_name_buf[NAME_LEN+1];
+ char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
LEX_STRING saved_cur_db_name=
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
bool cur_db_changed;
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 1970287b06e..95e48c531be 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -218,8 +218,7 @@ bool log_in_use(const char* log_name)
if ((linfo = tmp->current_linfo))
{
pthread_mutex_lock(&linfo->lock);
- result = !bcmp((uchar*) log_name, (uchar*) linfo->log_file_name,
- log_name_len);
+ result = !memcmp(log_name, linfo->log_file_name, log_name_len);
pthread_mutex_unlock(&linfo->lock);
if (result)
break;
@@ -357,6 +356,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
#ifndef DBUG_OFF
int left_events = max_binlog_dump_events;
#endif
+ int old_max_allowed_packet= thd->variables.max_allowed_packet;
DBUG_ENTER("mysql_binlog_send");
DBUG_PRINT("enter",("log_ident: '%s' pos: %ld", log_ident, (long) pos));
@@ -762,6 +762,7 @@ end:
pthread_mutex_lock(&LOCK_thread_count);
thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count);
+ thd->variables.max_allowed_packet= old_max_allowed_packet;
DBUG_VOID_RETURN;
err:
@@ -779,6 +780,7 @@ err:
pthread_mutex_unlock(&LOCK_thread_count);
if (file >= 0)
(void) my_close(file, MYF(MY_WME));
+ thd->variables.max_allowed_packet= old_max_allowed_packet;
my_message(my_errno, errmsg, MYF(0));
DBUG_VOID_RETURN;
@@ -1419,6 +1421,7 @@ bool mysql_show_binlog_events(THD* thd)
bool ret = TRUE;
IO_CACHE log;
File file = -1;
+ int old_max_allowed_packet= thd->variables.max_allowed_packet;
DBUG_ENTER("mysql_show_binlog_events");
Log_event::init_show_field_list(&field_list);
@@ -1557,6 +1560,7 @@ err:
pthread_mutex_lock(&LOCK_thread_count);
thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count);
+ thd->variables.max_allowed_packet= old_max_allowed_packet;
DBUG_RETURN(ret);
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2e966dbdde3..d7f92392c5e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1128,6 +1128,30 @@ JOIN::optimize()
{
conds=new Item_int((longlong) 0,1); // Always false
}
+
+ /*
+ It's necessary to check const part of HAVING cond as there is a
+ chance that some cond parts may become const items after
+ make_join_statistics() (for example when Item is a reference to
+ cost table field from outer join).
+
+ This check is performed only for those conditions which do not use
+ aggregate functions. In such case temporary table may not be used
+ and const condition elements may be lost during further having
+ condition transformation in JOIN::exec.
+ */
+ if (having && const_table_map && !having->with_sum_func)
+ {
+ having->update_used_tables();
+ having= remove_eq_conds(thd, having, &having_value);
+ if (having_value == Item::COND_FALSE)
+ {
+ having= new Item_int((longlong) 0,1);
+ zero_result_cause= "Impossible HAVING noticed after reading const tables";
+ DBUG_RETURN(0);
+ }
+ }
+
if (make_join_select(this, select, conds))
{
zero_result_cause=
@@ -11888,6 +11912,7 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
enum_nested_loop_state rc= NESTED_LOOP_OK;
int error;
READ_RECORD *info;
+ SQL_SELECT *select;
join_tab->table->null_row= 0;
if (!join_tab->cache.records)
@@ -11902,7 +11927,7 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
join_tab->select->quick=0;
}
}
- /* read through all records */
+ /* read through all records */
if ((error=join_init_read_record(join_tab)))
{
reset_cache_write(&join_tab->cache);
@@ -11916,15 +11941,16 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
}
info= &join_tab->read_record;
+ select= join_tab->select;
+
do
{
+ int err= 0;
if (join->thd->killed)
{
join->thd->send_kill_message();
return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
}
- int err= 0;
- SQL_SELECT *select=join_tab->select;
if (rc == NESTED_LOOP_OK)
update_virtual_fields(join->thd, join_tab->table);
if (rc == NESTED_LOOP_OK &&
@@ -11932,8 +11958,11 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
(err= join_tab->cache.select->skip_record(join->thd)) != 0 ))
{
if (err < 0)
+ {
+ reset_cache_write(&join_tab->cache);
return NESTED_LOOP_ERROR;
- rc= NESTED_LOOP_OK;
+ }
+
reset_cache_read(&join_tab->cache);
for (uint i= (join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
{
@@ -11942,7 +11971,10 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
if (!select || (err= select->skip_record(join->thd)) != 0)
{
if (err < 0)
+ {
+ reset_cache_write(&join_tab->cache);
return NESTED_LOOP_ERROR;
+ }
rc= (join_tab->next_select)(join,join_tab+1,0);
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
{
@@ -16695,7 +16727,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
the UNION to provide precise EXPLAIN information will hardly be
appreciated :)
*/
- char table_name_buffer[NAME_LEN];
+ char table_name_buffer[SAFE_NAME_LEN];
item_list.empty();
/* id */
item_list.push_back(new Item_null);
@@ -16768,7 +16800,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
char buff1[512], buff2[512], buff3[512];
char keylen_str_buf[64];
String extra(buff, sizeof(buff),cs);
- char table_name_buffer[NAME_LEN];
+ char table_name_buffer[SAFE_NAME_LEN];
String tmp1(buff1,sizeof(buff1),cs);
String tmp2(buff2,sizeof(buff2),cs);
String tmp3(buff3,sizeof(buff3),cs);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index a2290cf0758..cc1e956939c 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright 2000, 2010 Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -9,9 +9,9 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
/* Function with list databases, tables or fields */
@@ -511,8 +511,6 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
wild_length= strlen(wild);
}
-
-
bzero((char*) &table_list,sizeof(table_list));
if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
@@ -526,7 +524,7 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
for (i=0 ; i < (uint) dirp->number_off_files ; i++)
{
- char uname[NAME_LEN + 1]; /* Unencoded name */
+ char uname[SAFE_NAME_LEN + 1]; /* Unencoded name */
file=dirp->dir_entry+i;
if (dir)
{ /* Return databases */
@@ -554,9 +552,20 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
continue;
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
- if (wild && wild_compare(uname, wild, 0))
- continue;
- if (!(file_name=
+ if (wild)
+ {
+ if (lower_case_table_names)
+ {
+ if (my_wildcmp(files_charset_info,
+ uname, uname + file_name_len,
+ wild, wild + wild_length,
+ wild_prefix, wild_one, wild_many))
+ continue;
+ }
+ else if (wild_compare(uname, wild, 0))
+ continue;
+ }
+ if (!(file_name=
thd->make_lex_string(file_name, uname, file_name_len, TRUE)))
{
my_dirend(dirp);
@@ -2319,8 +2328,8 @@ static bool show_status_array(THD *thd, const char *wild,
bool ucase_names,
COND *cond)
{
- MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
- char * const buff= (char *) &buff_data;
+ my_aligned_storage<SHOW_VAR_FUNC_BUFF_SIZE, MY_ALIGNOF(long)> buffer;
+ char * const buff= buffer.data;
char *prefix_end;
/* the variable name should not be longer than 64 characters */
char name_buffer[64];
@@ -3124,36 +3133,54 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
{
LEX *lex= thd->lex;
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
+ bool rc= 0;
+
bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES));
switch (lex->sql_command) {
case SQLCOM_SHOW_DATABASES:
if (wild)
{
- lookup_field_values->db_value.str= (char*) wild;
- lookup_field_values->db_value.length= strlen(wild);
+ thd->make_lex_string(&lookup_field_values->db_value,
+ wild, strlen(wild), 0);
lookup_field_values->wild_db_value= 1;
}
- return 0;
+ break;
case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_TABLE_STATUS:
case SQLCOM_SHOW_TRIGGERS:
case SQLCOM_SHOW_EVENTS:
- lookup_field_values->db_value.str= lex->select_lex.db;
- lookup_field_values->db_value.length=strlen(lex->select_lex.db);
+ thd->make_lex_string(&lookup_field_values->db_value,
+ lex->select_lex.db, strlen(lex->select_lex.db), 0);
if (wild)
{
- lookup_field_values->table_value.str= (char*)wild;
- lookup_field_values->table_value.length= strlen(wild);
+ thd->make_lex_string(&lookup_field_values->table_value,
+ wild, strlen(wild), 0);
lookup_field_values->wild_table_value= 1;
}
- return 0;
+ break;
default:
/*
The "default" is for queries over I_S.
All previous cases handle SHOW commands.
*/
- return calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
+ rc= calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
+ break;
}
+
+ if (lower_case_table_names && !rc)
+ {
+ /*
+ We can safely do in-place upgrades here since all of the above cases
+ are allocating a new memory buffer for these strings.
+ */
+ if (lookup_field_values->db_value.str && lookup_field_values->db_value.str[0])
+ my_casedn_str(system_charset_info, lookup_field_values->db_value.str);
+ if (lookup_field_values->table_value.str &&
+ lookup_field_values->table_value.str[0])
+ my_casedn_str(system_charset_info, lookup_field_values->table_value.str);
+ }
+
+ return rc;
}
@@ -3355,11 +3382,15 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
{
if (with_i_schema)
{
+ LEX_STRING *name;
ST_SCHEMA_TABLE *schema_table=
find_schema_table(thd, lookup_field_vals->table_value.str);
if (schema_table && !schema_table->hidden)
{
- if (table_names->push_back(&lookup_field_vals->table_value))
+ if (!(name=
+ thd->make_lex_string(NULL, schema_table->table_name,
+ strlen(schema_table->table_name), TRUE)) ||
+ table_names->push_back(name))
return 1;
}
}
@@ -3398,7 +3429,7 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
*/
if (res == FIND_FILES_DIR)
{
- if (lex->sql_command != SQLCOM_SELECT)
+ if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
return 1;
thd->clear_error();
return 2;
@@ -3758,6 +3789,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
error= 0;
goto err;
}
+
DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
STR_OR_NIL(lookup_field_vals.db_value.str),
STR_OR_NIL(lookup_field_vals.table_value.str)));
@@ -4285,7 +4317,6 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
uint flags=field->flags;
char tmp[MAX_FIELD_WIDTH];
String type(tmp,sizeof(tmp), system_charset_info);
- char *end;
int decimals, field_length;
if (wild && wild[0] &&
@@ -4306,7 +4337,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
field->field_name) & COL_ACLS;
if (!tables->schema_table && !col_access)
continue;
- end= tmp;
+ char *end= tmp;
for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
{
if (col_access & 1)
@@ -4382,10 +4413,13 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_LONG:
- case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_INT24:
field_length= field->max_display_length() - 1;
break;
+ case MYSQL_TYPE_LONGLONG:
+ field_length= field->max_display_length() -
+ ((field->flags & UNSIGNED_FLAG) ? 0 : 1);
+ break;
case MYSQL_TYPE_BIT:
field_length= field->max_display_length();
decimals= -1; // return NULL
@@ -4429,7 +4463,6 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
table->field[15]->store((const char*) pos,
strlen((const char*) pos), cs);
- end= tmp;
if (field->unireg_check == Field::NEXT_NUMBER)
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
if (show_table->timestamp_field == field &&
@@ -4640,7 +4673,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
MYSQL_TIME time;
LEX *lex= thd->lex;
CHARSET_INFO *cs= system_charset_info;
- char sp_db_buff[NAME_LEN + 1], sp_name_buff[NAME_LEN + 1],
+ char sp_db_buff[SAFE_NAME_LEN + 1], sp_name_buff[SAFE_NAME_LEN + 1],
definer_buff[USERNAME_LENGTH + HOSTNAME_LENGTH + 2];
String sp_db(sp_db_buff, sizeof(sp_db_buff), cs);
String sp_name(sp_name_buff, sizeof(sp_name_buff), cs);
@@ -7134,8 +7167,8 @@ ST_FIELD_INFO table_names_fields_info[]=
{
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
- {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_",
- SKIP_OPEN_TABLE},
+ {"TABLE_NAME", NAME_CHAR_LEN + MYSQL50_TABLE_NAME_PREFIX_LENGTH,
+ MYSQL_TYPE_STRING, 0, 0, "Tables_in_", SKIP_OPEN_TABLE},
{"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type",
OPEN_FRM_ONLY},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index b9b5ff47cf6..3cec6c3b915 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -48,6 +48,7 @@ static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *,
bool, uint *, handler *, KEY **, uint *, int);
static bool mysql_prepare_alter_table(THD *, TABLE *, HA_CREATE_INFO *,
Alter_info *);
+static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list);
#ifndef DBUG_OFF
@@ -4219,7 +4220,7 @@ mysql_rename_table(handlerton *base, const char *old_db,
char from[FN_REFLEN + 1], to[FN_REFLEN + 1],
lc_from[FN_REFLEN + 1], lc_to[FN_REFLEN + 1];
char *from_base= from, *to_base= to;
- char tmp_name[NAME_LEN+1];
+ char tmp_name[SAFE_NAME_LEN+1];
handler *file;
int error=0;
DBUG_ENTER("mysql_rename_table");
@@ -4614,6 +4615,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
Protocol *protocol= thd->protocol;
LEX *lex= thd->lex;
int result_code;
+ bool need_repair_or_alter= 0;
DBUG_ENTER("mysql_admin_table");
if (end_active_trans(thd))
@@ -4634,7 +4636,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
for (table= tables; table; table= table->next_local)
{
- char table_name[NAME_LEN*2+2];
+ char table_name[SAFE_NAME_LEN*2+2];
char* db = table->db;
bool fatal_error=0;
@@ -4842,32 +4844,38 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (operator_func == &handler::ha_repair &&
!(check_opt->sql_flags & TT_USEFRM))
{
- if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
- (table->table->file->ha_check_for_upgrade(check_opt) ==
- HA_ADMIN_NEEDS_ALTER))
+ handler *file= table->table->file;
+ int check_old_types= file->check_old_types();
+ int check_for_upgrade= file->ha_check_for_upgrade(check_opt);
+
+ if (check_old_types == HA_ADMIN_NEEDS_ALTER ||
+ check_for_upgrade == HA_ADMIN_NEEDS_ALTER)
{
- DBUG_PRINT("admin", ("recreating table"));
- ha_autocommit_or_rollback(thd, 1);
- close_thread_tables(thd);
- tmp_disable_binlog(thd); // binlogging is done by caller if wanted
- result_code= mysql_recreate_table(thd, table);
- reenable_binlog(thd);
- /*
- mysql_recreate_table() can push OK or ERROR.
- Clear 'OK' status. If there is an error, keep it:
- we will store the error message in a result set row
- and then clear.
- */
- if (thd->main_da.is_ok())
- thd->main_da.reset_diagnostics_area();
+ /* We use extra_open_options to be able to open crashed tables */
+ thd->open_options|= extra_open_options;
+ result_code= admin_recreate_table(thd, table);
+ thd->open_options= ~extra_open_options;
goto send_result;
}
+ if (check_old_types || check_for_upgrade)
+ {
+ /* If repair is not implemented for the engine, run ALTER TABLE */
+ need_repair_or_alter= 1;
+ }
}
DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name));
result_code = (table->table->file->*operator_func)(thd, check_opt);
DBUG_PRINT("admin", ("operator_func returned: %d", result_code));
+ if (result_code == HA_ADMIN_NOT_IMPLEMENTED && need_repair_or_alter)
+ {
+ /*
+ repair was not implemented and we need to upgrade the table
+ to a new version so we recreate the table with ALTER TABLE
+ */
+ result_code= admin_recreate_table(thd, table);
+ }
send_result:
lex->cleanup_after_one_table_open();
@@ -4967,23 +4975,13 @@ send_result_message:
system_charset_info);
if (protocol->write())
goto err;
- ha_autocommit_or_rollback(thd, 0);
- close_thread_tables(thd);
DBUG_PRINT("info", ("HA_ADMIN_TRY_ALTER, trying analyze..."));
TABLE_LIST *save_next_local= table->next_local,
*save_next_global= table->next_global;
table->next_local= table->next_global= 0;
- tmp_disable_binlog(thd); // binlogging is done by caller if wanted
- result_code= mysql_recreate_table(thd, table);
- reenable_binlog(thd);
- /*
- mysql_recreate_table() can push OK or ERROR.
- Clear 'OK' status. If there is an error, keep it:
- we will store the error message in a result set row
- and then clear.
- */
- if (thd->main_da.is_ok())
- thd->main_da.reset_diagnostics_area();
+
+ result_code= admin_recreate_table(thd, table);
+
ha_autocommit_or_rollback(thd, 0);
close_thread_tables(thd);
if (!result_code) // recreation went ok
@@ -6973,6 +6971,14 @@ view_err:
if (!error && (new_name != table_name || new_db != db))
{
thd_proc_info(thd, "rename");
+
+ /*
+ Workaround InnoDB ending the transaction when the table instance
+ is unlocked/closed (close_cached_table below), otherwise the trx
+ state will differ between the server and storage engine layers.
+ */
+ ha_autocommit_or_rollback(thd, 0);
+
/*
Then do a 'simple' rename of the table. First we need to close all
instances of 'source' table.
@@ -7520,6 +7526,11 @@ view_err:
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
+ /*
+ If LOCK TABLES list is not empty and contains this table,
+ unlock the table and remove the table from this list.
+ */
+ mysql_lock_remove(thd, thd->locked_tables, table, FALSE);
/* Remove link to old table and rename the new one */
close_temporary_table(thd, table, 1, 1);
/* Should pass the 'new_name' as we store table name in the cache */
@@ -8019,6 +8030,30 @@ err:
}
+/* Prepare, run and cleanup for mysql_recreate_table() */
+
+static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
+{
+ bool result_code;
+ DBUG_ENTER("admin_recreate_table");
+
+ ha_autocommit_or_rollback(thd, 1);
+ close_thread_tables(thd);
+ tmp_disable_binlog(thd); // binlogging is done by caller if wanted
+ result_code= mysql_recreate_table(thd, table_list);
+ reenable_binlog(thd);
+ /*
+ mysql_recreate_table() can push OK or ERROR.
+ Clear 'OK' status. If there is an error, keep it:
+ we will store the error message in a result set row
+ and then clear.
+ */
+ if (thd->main_da.is_ok())
+ thd->main_da.reset_diagnostics_area();
+ DBUG_RETURN(result_code);
+}
+
+
/*
Recreates tables by calling mysql_alter_table().
@@ -8075,7 +8110,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
/* Open one table after the other to keep lock time as short as possible. */
for (table= tables; table; table= table->next_local)
{
- char table_name[NAME_LEN*2+2];
+ char table_name[SAFE_NAME_LEN*2+2];
TABLE *t;
strxmov(table_name, table->db ,".", table->table_name, NullS);
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index bf4a46a4c67..e8a382ca8f6 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1391,7 +1391,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
To remove this prefix we use check_n_cut_mysql50_prefix().
*/
- char fname[NAME_LEN + 1];
+ char fname[SAFE_NAME_LEN + 1];
DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) ||
(check_n_cut_mysql50_prefix(db, fname, sizeof(fname)) &&
!my_strcasecmp(table_alias_charset, lex.query_tables->db, fname))) &&
@@ -1917,7 +1917,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
*/
if (my_strcasecmp(table_alias_charset, db, new_db))
{
- char dbname[NAME_LEN + 1];
+ char dbname[SAFE_NAME_LEN + 1];
if (check_n_cut_mysql50_prefix(db, dbname, sizeof(dbname)) &&
!my_strcasecmp(table_alias_charset, dbname, new_db))
{
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 7aa7571d5ee..754a6f18536 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -215,7 +215,7 @@ void udf_init()
}
tmp->dlhandle = dl;
{
- char buf[NAME_LEN+16], *missing;
+ char buf[SAFE_NAME_LEN+16], *missing;
if ((missing= init_syms(tmp, buf)))
{
sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), missing);
@@ -469,7 +469,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
}
udf->dlhandle=dl;
{
- char buf[NAME_LEN+16], *missing;
+ char buf[SAFE_NAME_LEN+16], *missing;
if ((missing= init_syms(udf, buf)))
{
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), missing);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 15251e956be..60bbd0d886a 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -470,12 +470,11 @@ int mysql_update(THD *thd,
thd_proc_info(thd, "Searching rows for update");
ha_rows tmp_limit= limit;
- while (!(error=info.read_record(&info)) &&
- !thd->killed && !thd->is_error())
+ while (!(error=info.read_record(&info)) && !thd->killed)
{
update_virtual_fields(thd, table);
thd->examined_row_count++;
- if (!select || select->skip_record(thd) > 0)
+ if (!select || (error= select->skip_record(thd)) > 0)
{
if (table->file->was_semi_consistent_read())
continue; /* repeat the read of the same row if it still exists */
@@ -494,7 +493,15 @@ int mysql_update(THD *thd,
}
}
else
+ {
table->file->unlock_row();
+ if (error < 0)
+ {
+ /* Fatal error from select->skip_record() */
+ error= 1;
+ break;
+ }
+ }
}
if (thd->killed && !error)
error= 1; // Aborted
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 2112d9b1e1c..204100f6034 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1189,7 +1189,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
table->view= lex= thd->lex= (LEX*) new(thd->mem_root) st_lex_local;
{
- char old_db_buf[NAME_LEN+1];
+ char old_db_buf[SAFE_NAME_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
Parser_state parser_state;
diff --git a/sql/table.cc b/sql/table.cc
index 81353514872..8b0d02407c9 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -878,7 +878,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
/* Read extra data segment */
uchar *next_chunk, *buff_end;
DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
- if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
+ if (!(next_chunk= buff= (uchar*) my_malloc(n_length+1, MYF(MY_WME))))
goto err;
if (my_pread(file, buff, n_length, record_offset + share->reclength,
MYF(MY_NABP)))
@@ -953,6 +953,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
{
/* purecov: begin inspected */
error= 8;
+ name.str[name.length]= 0;
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
goto free_and_err;
/* purecov: end */
@@ -3157,15 +3158,15 @@ bool check_db_name(LEX_STRING *org_name)
uint name_length= org_name->length;
bool check_for_path_chars;
- if (!name_length || name_length > NAME_LEN)
- return 1;
-
if ((check_for_path_chars= check_mysql50_prefix(name)))
{
name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
name_length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
}
+ if (!name_length || name_length > NAME_LEN)
+ return 1;
+
if (lower_case_table_names && name != any_db)
my_casedn_str(files_charset_info, name);
@@ -3183,6 +3184,15 @@ bool check_table_name(const char *name, uint length, bool check_for_path_chars)
{
uint name_length= 0; // name length in symbols
const char *end= name+length;
+
+
+ if (!check_for_path_chars &&
+ (check_for_path_chars= check_mysql50_prefix(name)))
+ {
+ name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
+ length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
+ }
+
if (!length || length > NAME_LEN)
return 1;
#if defined(USE_MB) && defined(USE_MB_IDENT)
diff --git a/sql/table.h b/sql/table.h
index 9f6006c9adc..b8df0d8c0c4 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -58,7 +58,6 @@ typedef struct st_order {
struct st_order *next;
Item **item; /* Point at item in select fields */
Item *item_ptr; /* Storage for initial item */
- Item **item_copy; /* For SPs; the original item ptr */
int counter; /* position in SELECT list, correct
only if counter_used is true*/
bool asc; /* true if ascending */
@@ -461,7 +460,7 @@ typedef struct st_table_share
#ifdef WITH_PARTITION_STORAGE_ENGINE
/** @todo: Move into *ha_data for partitioning */
bool auto_partitioned;
- const char *partition_info;
+ char *partition_info;
uint partition_info_len;
uint partition_info_buffer_size;
const char *part_state;
diff --git a/sql/udf_example.c b/sql/udf_example.c
index 788582e32b6..979aebd4b23 100644
--- a/sql/udf_example.c
+++ b/sql/udf_example.c
@@ -1067,7 +1067,7 @@ char *myfunc_argument_name(UDF_INIT *initid __attribute__((unused)),
{
if (!args->attributes[0])
{
- null_value= 0;
+ *null_value= 1;
return 0;
}
(*length)--; /* space for ending \0 (for debugging purposes) */
diff --git a/sql/unireg.h b/sql/unireg.h
index ec4ecf6a10f..57a9038d5f7 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -129,8 +129,8 @@
#define SPECIAL_LOG_QUERIES_NOT_USING_INDEXES 4096 /* Obsolete */
/* Extern defines */
-#define store_record(A,B) bmove_align((A)->B,(A)->record[0],(size_t) (A)->s->reclength)
-#define restore_record(A,B) bmove_align((A)->record[0],(A)->B,(size_t) (A)->s->reclength)
+#define store_record(A,B) memcpy((A)->B,(A)->record[0],(size_t) (A)->s->reclength)
+#define restore_record(A,B) memcpy((A)->record[0],(A)->B,(size_t) (A)->s->reclength)
#define cmp_record(A,B) memcmp((A)->record[0],(A)->B,(size_t) (A)->s->reclength)
#define empty_record(A) { \
restore_record((A),s->default_values); \
diff --git a/storage/Makefile.am b/storage/Makefile.am
index 8aa1e4f7dc6..e232547139d 100644
--- a/storage/Makefile.am
+++ b/storage/Makefile.am
@@ -21,6 +21,3 @@ AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = mysql_storage_engine.cmake
SUBDIRS = @mysql_se_dirs@
DIST_SUBDIRS = @mysql_se_distdirs@
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/storage/archive/Makefile.am b/storage/archive/Makefile.am
index d092f091798..254c95bf68b 100644
--- a/storage/archive/Makefile.am
+++ b/storage/archive/Makefile.am
@@ -36,14 +36,14 @@ noinst_PROGRAMS = archive_test archive_reader
EXTRA_LTLIBRARIES = ha_archive.la
pkgplugin_LTLIBRARIES = @plugin_archive_shared_target@
ha_archive_la_LDFLAGS = -module -rpath $(pkgplugindir)
-ha_archive_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_archive_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_archive_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_archive_la_CFLAGS = -shared $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_archive_la_SOURCES = ha_archive.cc azio.c
EXTRA_LIBRARIES = libarchive.a
noinst_LIBRARIES = @plugin_archive_static_target@
-libarchive_a_CXXFLAGS = $(AM_CFLAGS)
+libarchive_a_CXXFLAGS = $(AM_CXXFLAGS)
libarchive_a_CFLAGS = $(AM_CFLAGS)
libarchive_a_SOURCES = ha_archive.cc azio.c
diff --git a/storage/archive/azio.c b/storage/archive/azio.c
index a24350dd454..fc54d98ab15 100644
--- a/storage/archive/azio.c
+++ b/storage/archive/azio.c
@@ -150,6 +150,17 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd)
}
else
{
+ /* Reset values in case of old version of archive file */
+ s->rows= 0;
+ s->forced_flushes= 0;
+ s->shortest_row= 0;
+ s->longest_row= 0;
+ s->auto_increment= 0;
+ s->check_point= 0;
+ s->comment_start_pos= 0;
+ s->comment_length= 0;
+ s->frm_start_pos= 0;
+ s->frm_length= 0;
check_header(s); /* skip the .az header */
}
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 922db30c9d9..f3f5788360a 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -293,7 +293,7 @@ int ha_archive::read_data_header(azio_stream *file_to_read)
DBUG_PRINT("ha_archive", ("Version %u", data_buffer[1]));
if ((data_buffer[0] != (uchar)ARCHIVE_CHECK_HEADER) &&
- (data_buffer[1] != (uchar)ARCHIVE_VERSION))
+ (data_buffer[1] == 1 || data_buffer[1] == 2))
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
DBUG_RETURN(0);
@@ -360,9 +360,19 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc)
my_free(share, MYF(0));
DBUG_RETURN(NULL);
}
- stats.auto_increment_value= archive_tmp.auto_increment + 1;
- share->rows_recorded= (ha_rows)archive_tmp.rows;
- share->crashed= archive_tmp.dirty;
+ share->version= archive_tmp.version;
+ if (archive_tmp.version == ARCHIVE_VERSION)
+ {
+ stats.auto_increment_value= archive_tmp.auto_increment + 1;
+ share->rows_recorded= (ha_rows)archive_tmp.rows;
+ share->crashed= archive_tmp.dirty;
+ }
+ else
+ {
+ /* Used by repair */
+ share->rows_recorded= ~(ha_rows) 0;
+ stats.auto_increment_value= 0;
+ }
/*
If archive version is less than 3, It should be upgraded before
use.
@@ -512,10 +522,19 @@ int ha_archive::open(const char *name, int mode, uint open_options)
case 0:
break;
case HA_ERR_CRASHED_ON_USAGE:
+ DBUG_PRINT("ha_archive", ("archive table was crashed"));
if (open_options & HA_OPEN_FOR_REPAIR)
+ {
+ rc= 0;
break;
+ }
/* fall through */
case HA_ERR_TABLE_NEEDS_UPGRADE:
+ if (open_options & HA_OPEN_FOR_REPAIR)
+ {
+ rc= 0;
+ break;
+ }
free_share();
/* fall through */
default:
@@ -535,13 +554,6 @@ int ha_archive::open(const char *name, int mode, uint open_options)
thr_lock_data_init(&share->lock, &lock, NULL);
- DBUG_PRINT("ha_archive", ("archive table was crashed %s",
- rc == HA_ERR_CRASHED_ON_USAGE ? "yes" : "no"));
- if (rc == HA_ERR_CRASHED_ON_USAGE && open_options & HA_OPEN_FOR_REPAIR)
- {
- DBUG_RETURN(0);
- }
-
DBUG_RETURN(rc);
}
@@ -1267,6 +1279,14 @@ int ha_archive::rnd_pos(uchar * buf, uchar *pos)
DBUG_RETURN(get_row(&archive, buf));
}
+int ha_archive::check_for_upgrade(HA_CHECK_OPT *check_opt)
+{
+ if (share->version < ARCHIVE_VERSION)
+ return HA_ADMIN_NEEDS_ALTER;
+ return 0;
+}
+
+
/*
This method repairs the meta file. It does this by walking the datafile and
rewriting the meta file. If EXTENDED repair is requested, we attempt to
diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h
index ab630ed22fd..653a13b242d 100644
--- a/storage/archive/ha_archive.h
+++ b/storage/archive/ha_archive.h
@@ -35,7 +35,7 @@ typedef struct st_archive_record_buffer {
typedef struct st_archive_share {
char *table_name;
char data_file_name[FN_REFLEN];
- uint table_name_length,use_count;
+ uint table_name_length,use_count, version;
pthread_mutex_t mutex;
THR_LOCK lock;
azio_stream archive_write; /* Archive file we are working with */
@@ -133,6 +133,7 @@ public:
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
int repair(THD* thd, HA_CHECK_OPT* check_opt);
+ int check_for_upgrade(HA_CHECK_OPT *check_opt);
void start_bulk_insert(ha_rows rows);
int end_bulk_insert();
enum row_type get_row_type() const
diff --git a/storage/blackhole/Makefile.am b/storage/blackhole/Makefile.am
index db4f67cf847..148746a9336 100644
--- a/storage/blackhole/Makefile.am
+++ b/storage/blackhole/Makefile.am
@@ -35,15 +35,13 @@ noinst_HEADERS = ha_blackhole.h
EXTRA_LTLIBRARIES = ha_blackhole.la
pkgplugin_LTLIBRARIES = @plugin_blackhole_shared_target@
ha_blackhole_la_LDFLAGS=-module -rpath $(pkgplugindir)
-ha_blackhole_la_CXXFLAGS=$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_blackhole_la_CFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_blackhole_la_CXXFLAGS=-shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_blackhole_la_SOURCES=ha_blackhole.cc
EXTRA_LIBRARIES = libblackhole.a
noinst_LIBRARIES = @plugin_blackhole_static_target@
-libblackhole_a_CXXFLAGS=$(AM_CFLAGS)
-libblackhole_a_CFLAGS = $(AM_CFLAGS)
+libblackhole_a_CXXFLAGS=$(AM_CXXFLAGS)
libblackhole_a_SOURCES= ha_blackhole.cc
diff --git a/storage/csv/Makefile.am b/storage/csv/Makefile.am
index 07ffac88a96..75ad9062984 100644
--- a/storage/csv/Makefile.am
+++ b/storage/csv/Makefile.am
@@ -32,12 +32,12 @@ noinst_HEADERS = ha_tina.h transparent_file.h
EXTRA_LTLIBRARIES = ha_csv.la
pkglib_LTLIBRARIES = @plugin_csv_shared_target@
ha_csv_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
-ha_csv_la_CXXFLAGS = $(AM_CFLAGS) -DMYSQL_PLUGIN
+ha_csv_la_CXXFLAGS = -shared $(AM_CXXFLAGS) -DMYSQL_PLUGIN
ha_csv_la_SOURCES = transparent_file.cc ha_tina.cc
EXTRA_LIBRARIES = libcsv.a
noinst_LIBRARIES = @plugin_csv_static_target@
-libcsv_a_CXXFLAGS = $(AM_CFLAGS)
+libcsv_a_CXXFLAGS = $(AM_CXXFLAGS)
libcsv_a_SOURCES = transparent_file.cc ha_tina.cc
EXTRA_DIST = CMakeLists.txt plug.in
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index 4ca3e029cbc..8ba425c86cb 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -468,7 +468,7 @@ int ha_tina::encode_quote(uchar *buf)
const char *ptr;
const char *end_ptr;
const bool was_null= (*field)->is_null();
-
+
/*
assistance for backwards compatibility in production builds.
note: this will not work for ENUM columns.
@@ -480,7 +480,7 @@ int ha_tina::encode_quote(uchar *buf)
}
(*field)->val_str(&attribute,&attribute);
-
+
if (was_null)
(*field)->set_null();
@@ -498,34 +498,30 @@ int ha_tina::encode_quote(uchar *buf)
buffer.append('"');
- while (ptr < end_ptr)
+ for (; ptr < end_ptr; ptr++)
{
if (*ptr == '"')
{
buffer.append('\\');
buffer.append('"');
- *ptr++;
}
else if (*ptr == '\r')
{
buffer.append('\\');
buffer.append('r');
- *ptr++;
}
else if (*ptr == '\\')
{
buffer.append('\\');
buffer.append('\\');
- *ptr++;
}
else if (*ptr == '\n')
{
buffer.append('\\');
buffer.append('n');
- *ptr++;
}
else
- buffer.append(*ptr++);
+ buffer.append(*ptr);
}
buffer.append('"');
}
diff --git a/storage/example/Makefile.am b/storage/example/Makefile.am
index 10163e307b1..dc499e2f9dd 100644
--- a/storage/example/Makefile.am
+++ b/storage/example/Makefile.am
@@ -35,15 +35,12 @@ noinst_HEADERS = ha_example.h
EXTRA_LTLIBRARIES = ha_example.la
pkgplugin_LTLIBRARIES = @plugin_example_shared_target@
ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
-ha_example_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_example_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_example_la_SOURCES = ha_example.cc
-
EXTRA_LIBRARIES = libexample.a
noinst_LIBRARIES = @plugin_example_static_target@
-libexample_a_CXXFLAGS = $(AM_CFLAGS)
-libexample_a_CFLAGS = $(AM_CFLAGS)
+libexample_a_CXXFLAGS = $(AM_CXXFLAGS)
libexample_a_SOURCES= ha_example.cc
diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc
index e8ef0b72bc8..f2aee1de70c 100644
--- a/storage/example/ha_example.cc
+++ b/storage/example/ha_example.cc
@@ -225,7 +225,7 @@ static int example_done_func(void *p)
hash_free(&example_open_tables);
pthread_mutex_destroy(&example_mutex);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
diff --git a/storage/federated/Makefile.am b/storage/federated/Makefile.am
index 26786ee48cb..414fb5b7d5f 100644
--- a/storage/federated/Makefile.am
+++ b/storage/federated/Makefile.am
@@ -33,15 +33,14 @@ noinst_HEADERS = ha_federated.h
EXTRA_LTLIBRARIES = ha_federated.la
pkgplugin_LTLIBRARIES = @plugin_federated_shared_target@
ha_federated_la_LDFLAGS = -module -rpath $(pkgplugindir)
-ha_federated_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_federated_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_federated_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_federated_la_CFLAGS = -shared $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_federated_la_SOURCES = ha_federated.cc $(top_srcdir)/mysys/string.c
EXTRA_LIBRARIES = libfederated.a
noinst_LIBRARIES = @plugin_federated_static_target@
-libfederated_a_CXXFLAGS = $(AM_CFLAGS)
-libfederated_a_CFLAGS = $(AM_CFLAGS)
+libfederated_a_CXXFLAGS = $(AM_CXXFLAGS)
libfederated_a_SOURCES= ha_federated.cc
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index 4d597d6d7a9..fcc178b09a6 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -561,7 +561,6 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num)
int get_connection(MEM_ROOT *mem_root, FEDERATED_SHARE *share)
{
int error_num= ER_FOREIGN_SERVER_DOESNT_EXIST;
- char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
FOREIGN_SERVER *server, server_buffer;
DBUG_ENTER("ha_federated::get_connection");
@@ -613,10 +612,8 @@ int get_connection(MEM_ROOT *mem_root, FEDERATED_SHARE *share)
DBUG_RETURN(0);
error:
- my_sprintf(error_buffer,
- (error_buffer, "server name: '%s' doesn't exist!",
- share->connection_string));
- my_error(error_num, MYF(0), error_buffer);
+ my_printf_error(error_num, "server name: '%s' doesn't exist!",
+ MYF(0), share->connection_string);
DBUG_RETURN(error_num);
}
@@ -2405,8 +2402,8 @@ int ha_federated::index_read_idx_with_result_set(uchar *buf, uint index,
if (real_query(sql_query.ptr(), sql_query.length()))
{
- my_sprintf(error_buffer, (error_buffer, "error: %d '%s'",
- mysql_errno(mysql), mysql_error(mysql)));
+ sprintf(error_buffer, "error: %d '%s'",
+ mysql_errno(mysql), mysql_error(mysql));
retval= ER_QUERY_ON_FOREIGN_DATA_SOURCE;
goto error;
}
@@ -2775,7 +2772,6 @@ int ha_federated::rnd_pos(uchar *buf, uchar *pos)
int ha_federated::info(uint flag)
{
- char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
char status_buf[FEDERATED_QUERY_BUFFER_SIZE];
int error;
uint error_code;
@@ -2859,9 +2855,8 @@ error:
mysql_free_result(result);
if (mysql)
{
- my_sprintf(error_buffer, (error_buffer, ": %d : %s",
- mysql_errno(mysql), mysql_error(mysql)));
- my_error(error_code, MYF(0), error_buffer);
+ my_printf_error(error_code, ": %d : %s", MYF(0),
+ mysql_errno(mysql), mysql_error(mysql));
}
else
if (remote_error_number != -1 /* error already reported */)
diff --git a/storage/federatedx/Makefile.am b/storage/federatedx/Makefile.am
index 1781a53a0b6..1e76ac15266 100644
--- a/storage/federatedx/Makefile.am
+++ b/storage/federatedx/Makefile.am
@@ -20,14 +20,13 @@ noinst_HEADERS = ha_federatedx.h federatedx_probes.h
EXTRA_LTLIBRARIES = ha_federatedx.la
pkgplugin_LTLIBRARIES = @plugin_federatedx_shared_target@
ha_federatedx_la_LDFLAGS = -module -rpath $(pkgplugindir)
-ha_federatedx_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-ha_federatedx_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_federatedx_la_CXXFLAGS= -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_federatedx_la_CFLAGS = -shared $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
EXTRA_LIBRARIES = libfederatedx.a
noinst_LIBRARIES = @plugin_federatedx_static_target@
-libfederatedx_a_CXXFLAGS = $(AM_CFLAGS)
-libfederatedx_a_CFLAGS = $(AM_CFLAGS)
+libfederatedx_a_CXXFLAGS = $(AM_CXXFLAGS)
libfederatedx_a_SOURCES= ha_federatedx.cc federatedx_txn.cc \
federatedx_io.cc federatedx_io_null.cc \
federatedx_io_mysql.cc
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index 8735e5625e6..2749034cba2 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -2967,10 +2967,13 @@ int ha_federatedx::rnd_pos(uchar *buf, uchar *pos)
DBUG_ENTER("ha_federatedx::rnd_pos");
ha_statistic_increment(&SSV::ha_read_rnd_count);
+ /* We have to move this to 'ref' to get things aligned */
+ bmove(ref, pos, ref_length);
+
if ((retval= txn->acquire(share, TRUE, &io)))
goto error;
- if ((retval= io->seek_position(&result, pos)))
+ if ((retval= io->seek_position(&result, ref)))
goto error;
retval= read_next(buf, result);
diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c
index 5c548b6be74..bf06cf03035 100644
--- a/storage/heap/hp_test2.c
+++ b/storage/heap/hp_test2.c
@@ -406,7 +406,7 @@ int main(int argc, char *argv[])
bmove(record2,record,reclength);
if (heap_rsame(file,record,-1) || heap_rsame(file,record2,2))
goto err;
- if (bcmp(record2,record,reclength))
+ if (memcmp(record2,record,reclength))
{
puts("heap_rsame didn't find right record");
goto end;
@@ -415,7 +415,7 @@ int main(int argc, char *argv[])
puts("- Test of read through position");
if (heap_rrnd(file,record,position))
goto err;
- if (bcmp(record3,record,reclength))
+ if (memcmp(record3,record,reclength))
{
puts("heap_frnd didn't find right record");
goto end;
diff --git a/storage/ibmdb2i/Makefile.am b/storage/ibmdb2i/Makefile.am
index 768ca15f4cf..b9602e392e0 100644
--- a/storage/ibmdb2i/Makefile.am
+++ b/storage/ibmdb2i/Makefile.am
@@ -34,7 +34,7 @@ EXTRA_LTLIBRARIES = ha_ibmdb2i.la
pkgplugin_LTLIBRARIES = @plugin_ibmdb2i_shared_target@
ha_ibmdb2i_la_LIBADD = -liconv
ha_ibmdb2i_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
-ha_ibmdb2i_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+ha_ibmdb2i_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_ibmdb2i_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
ha_ibmdb2i_la_SOURCES = ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc \
db2i_blobCollection.cc db2i_file.cc db2i_charsetSupport.cc \
@@ -44,7 +44,7 @@ ha_ibmdb2i_la_SOURCES = ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc \
EXTRA_LIBRARIES = libibmdb2i.a
noinst_LIBRARIES = @plugin_ibmdb2i_static_target@
-libibmdb2i_a_CXXFLAGS = $(AM_CFLAGS)
+libibmdb2i_a_CXXFLAGS = $(AM_CXXFLAGS)
libibmdb2i_a_CFLAGS = $(AM_CFLAGS)
libibmdb2i_a_SOURCES= $(ha_ibmdb2i_la_SOURCES)
diff --git a/storage/ibmdb2i/db2i_file.h b/storage/ibmdb2i/db2i_file.h
index ff35a473b05..7b63b18c315 100644
--- a/storage/ibmdb2i/db2i_file.h
+++ b/storage/ibmdb2i/db2i_file.h
@@ -40,7 +40,6 @@ OF SUCH DAMAGE.
#include "db2i_global.h"
#include "db2i_ileBridge.h"
#include "db2i_validatedPointer.h"
-#include "my_atomic.h"
#include "db2i_iconv.h"
#include "db2i_charsetSupport.h"
diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am
index a597e3c24e4..29ba83c0668 100644
--- a/storage/innobase/Makefile.am
+++ b/storage/innobase/Makefile.am
@@ -156,15 +156,15 @@ libinnobase_a_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \
handler/ha_innodb.cc
-libinnobase_a_CXXFLAGS= $(AM_CFLAGS)
+libinnobase_a_CXXFLAGS= $(AM_CXXFLAGS)
libinnobase_a_CFLAGS= $(AM_CFLAGS)
EXTRA_LTLIBRARIES= ha_innodb.la
pkgplugin_LTLIBRARIES= @plugin_innobase_shared_target@
ha_innodb_la_LDFLAGS= -module -rpath $(pkgplugindir)
-ha_innodb_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
-ha_innodb_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+ha_innodb_la_CXXFLAGS= -shared $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+ha_innodb_la_CFLAGS= -shared $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
ha_innodb_la_SOURCES= $(libinnobase_a_SOURCES)
EXTRA_DIST= CMakeLists.txt plug.in \
diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
index 65f1c9536bd..d5e7600f4d0 100644
--- a/storage/innobase/dict/dict0load.c
+++ b/storage/innobase/dict/dict0load.c
@@ -927,6 +927,8 @@ dict_load_table_on_id(
ut_ad(mutex_own(&(dict_sys->mutex)));
+ table = NULL;
+
/* NOTE that the operation of this function is protected by
the dictionary mutex, and therefore no deadlocks can occur
with other dictionary operations. */
@@ -953,15 +955,17 @@ dict_load_table_on_id(
BTR_SEARCH_LEAF, &pcur, &mtr);
rec = btr_pcur_get_rec(&pcur);
- if (!btr_pcur_is_on_user_rec(&pcur, &mtr)
- || rec_get_deleted_flag(rec, 0)) {
+ if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) {
/* Not found */
+ goto func_exit;
+ }
- btr_pcur_close(&pcur);
- mtr_commit(&mtr);
- mem_heap_free(heap);
-
- return(NULL);
+ /* Find the first record that is not delete marked */
+ while (rec_get_deleted_flag(rec, 0)) {
+ if (!btr_pcur_move_to_next_user_rec(&pcur, &mtr)) {
+ goto func_exit;
+ }
+ rec = btr_pcur_get_rec(&pcur);
}
/*---------------------------------------------------*/
@@ -974,19 +978,14 @@ dict_load_table_on_id(
/* Check if the table id in record is the one searched for */
if (ut_dulint_cmp(table_id, mach_read_from_8(field)) != 0) {
-
- btr_pcur_close(&pcur);
- mtr_commit(&mtr);
- mem_heap_free(heap);
-
- return(NULL);
+ goto func_exit;
}
/* Now we get the table name from the record */
field = rec_get_nth_field_old(rec, 1, &len);
/* Load the table definition to memory */
table = dict_load_table(mem_heap_strdupl(heap, (char*) field, len));
-
+func_exit:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
mem_heap_free(heap);
diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
index 7373a97cfb0..3396d1adf2f 100644
--- a/storage/innobase/os/os0file.c
+++ b/storage/innobase/os/os0file.c
@@ -3974,6 +3974,9 @@ os_aio_simulated_handle(
ulint n;
ulint i;
+ /* Fix compiler warning */
+ *consecutive_ios = NULL;
+
segment = os_aio_get_array_and_local_segment(&array, global_segment);
restart:
diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog
index 5ebcf1e87a2..3e802360d23 100644
--- a/storage/innodb_plugin/ChangeLog
+++ b/storage/innodb_plugin/ChangeLog
@@ -1,3 +1,27 @@
+2010-07-27 The InnoDB Team
+
+ * include/mem0pool.h, mem/mem0mem.c, mem/mem0pool.c, srv/srv0start.c:
+ Fix Bug#55581 shutdown with innodb-use-sys-malloc=0: assert
+ mutex->magic_n == MUTEX_MAGIC_N.
+
+2010-06-30 The InnoDB Team
+
+ * btr/btr0sea.c, ha/ha0ha.c, handler/ha_innodb.cc, include/btr0sea.h:
+ Fix Bug#54311 Crash on CHECK PARTITION after concurrent LOAD DATA
+ and adaptive_hash_index=OFF
+
+2010-06-29 The InnoDB Team
+ * row/row0row.c, row/row0undo.c, row/row0upd.c:
+ Fix Bug#54408 txn rollback after recovery: row0umod.c:673
+ dict_table_get_format(index->table)
+
+2010-06-29 The InnoDB Team
+
+ * btr/btr0cur.c, include/btr0cur.h,
+ include/row0mysql.h, row/row0merge.c, row/row0sel.c:
+ Fix Bug#54358 READ UNCOMMITTED access failure of off-page DYNAMIC
+ or COMPRESSED columns
+
2010-06-24 The InnoDB Team
* handler/ha_innodb.cc:
diff --git a/storage/innodb_plugin/Makefile.am b/storage/innodb_plugin/Makefile.am
index 807be18b2a2..1bed796f0d4 100644
--- a/storage/innodb_plugin/Makefile.am
+++ b/storage/innodb_plugin/Makefile.am
@@ -325,15 +325,15 @@ libinnobase_a_SOURCES= \
ut/ut0vec.c \
ut/ut0wqueue.c
-libinnobase_a_CXXFLAGS= $(AM_CFLAGS)
+libinnobase_a_CXXFLAGS= $(AM_CXXFLAGS)
libinnobase_a_CFLAGS= $(AM_CFLAGS)
EXTRA_LTLIBRARIES= ha_innodb_plugin.la
pkgplugin_LTLIBRARIES= @plugin_innodb_plugin_shared_target@
ha_innodb_plugin_la_LDFLAGS= -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
-ha_innodb_plugin_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
-ha_innodb_plugin_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+ha_innodb_plugin_la_CXXFLAGS= -shared $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+ha_innodb_plugin_la_CFLAGS= -shared $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
ha_innodb_plugin_la_SOURCES= $(libinnobase_a_SOURCES)
EXTRA_DIST= CMakeLists.txt plug.in \
diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c
index 50531ad3bd7..7fa7d42320a 100644
--- a/storage/innodb_plugin/btr/btr0cur.c
+++ b/storage/innodb_plugin/btr/btr0cur.c
@@ -4814,7 +4814,7 @@ btr_copy_externally_stored_field(
/*******************************************************************//**
Copies an externally stored field of a record to mem heap.
-@return the field copied to heap */
+@return the field copied to heap, or NULL if the field is incomplete */
UNIV_INTERN
byte*
btr_rec_copy_externally_stored_field(
@@ -4844,6 +4844,18 @@ btr_rec_copy_externally_stored_field(
data = rec_get_nth_field(rec, offsets, no, &local_len);
+ ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
+
+ if (UNIV_UNLIKELY
+ (!memcmp(data + local_len - BTR_EXTERN_FIELD_REF_SIZE,
+ field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE))) {
+ /* The externally stored field was not written yet.
+ This record should only be seen by
+ recv_recovery_rollback_active() or any
+ TRX_ISO_READ_UNCOMMITTED transactions. */
+ return(NULL);
+ }
+
return(btr_copy_externally_stored_field(len, data,
zip_size, local_len, heap));
}
diff --git a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c
index c91afa31bf0..ac7248fef20 100644
--- a/storage/innodb_plugin/btr/btr0sea.c
+++ b/storage/innodb_plugin/btr/btr0sea.c
@@ -46,6 +46,7 @@ Created 2/17/1996 Heikki Tuuri
/** Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
UNIV_INTERN char btr_search_enabled = TRUE;
+UNIV_INTERN ibool btr_search_fully_disabled = FALSE;
/** Mutex protecting btr_search_enabled */
static mutex_t btr_search_enabled_mutex;
@@ -201,12 +202,19 @@ btr_search_disable(void)
mutex_enter(&btr_search_enabled_mutex);
rw_lock_x_lock(&btr_search_latch);
+ /* Disable access to hash index, also tell ha_insert_for_fold()
+ stop adding new nodes to hash index, but still allow updating
+ existing nodes */
btr_search_enabled = FALSE;
/* Clear all block->is_hashed flags and remove all entries
from btr_search_sys->hash_index. */
buf_pool_drop_hash_index();
+ /* hash index has been cleaned up, disallow any operation to
+ the hash index */
+ btr_search_fully_disabled = TRUE;
+
/* btr_search_enabled_mutex should guarantee this. */
ut_ad(!btr_search_enabled);
@@ -225,6 +233,7 @@ btr_search_enable(void)
rw_lock_x_lock(&btr_search_latch);
btr_search_enabled = TRUE;
+ btr_search_fully_disabled = FALSE;
rw_lock_x_unlock(&btr_search_latch);
mutex_exit(&btr_search_enabled_mutex);
@@ -1363,7 +1372,7 @@ btr_search_build_page_hash_index(
rw_lock_x_lock(&btr_search_latch);
- if (UNIV_UNLIKELY(!btr_search_enabled)) {
+ if (UNIV_UNLIKELY(btr_search_fully_disabled)) {
goto exit_func;
}
diff --git a/storage/innodb_plugin/ha/ha0ha.c b/storage/innodb_plugin/ha/ha0ha.c
index 9d9d341ad39..f9e798012f8 100644
--- a/storage/innodb_plugin/ha/ha0ha.c
+++ b/storage/innodb_plugin/ha/ha0ha.c
@@ -31,9 +31,7 @@ Created 8/22/1994 Heikki Tuuri
#ifdef UNIV_DEBUG
# include "buf0buf.h"
#endif /* UNIV_DEBUG */
-#ifdef UNIV_SYNC_DEBUG
-# include "btr0sea.h"
-#endif /* UNIV_SYNC_DEBUG */
+#include "btr0sea.h"
#include "page0page.h"
/*************************************************************//**
@@ -127,7 +125,8 @@ ha_clear(
/*************************************************************//**
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
-is inserted.
+is inserted. If btr_search_enabled is set to FALSE, we will only allow
+updating existing nodes, but no new node is allowed to be added.
@return TRUE if succeed, FALSE if no more memory could be allocated */
UNIV_INTERN
ibool
@@ -174,6 +173,7 @@ ha_insert_for_fold_func(
prev_block->n_pointers--;
block->n_pointers++;
}
+ ut_ad(!btr_search_fully_disabled);
# endif /* !UNIV_HOTBACKUP */
prev_node->block = block;
@@ -186,6 +186,13 @@ ha_insert_for_fold_func(
prev_node = prev_node->next;
}
+ /* We are in the process of disabling hash index, do not add
+ new chain node */
+ if (!btr_search_enabled) {
+ ut_ad(!btr_search_fully_disabled);
+ return(TRUE);
+ }
+
/* We have to allocate a new chain node */
node = mem_heap_alloc(hash_get_heap(table, fold), sizeof(ha_node_t));
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 4d4fd185567..37ce69b9933 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -2270,6 +2270,7 @@ innobase_change_buffering_inited_ok:
/* Get the current high water mark format. */
innobase_file_format_check = (char*) trx_sys_file_format_max_get();
+ btr_search_fully_disabled = (!btr_search_enabled);
DBUG_RETURN(FALSE);
error:
DBUG_RETURN(TRUE);
diff --git a/storage/innodb_plugin/include/btr0cur.h b/storage/innodb_plugin/include/btr0cur.h
index 716f15c4267..7dc2eb63cf5 100644
--- a/storage/innodb_plugin/include/btr0cur.h
+++ b/storage/innodb_plugin/include/btr0cur.h
@@ -570,7 +570,7 @@ btr_copy_externally_stored_field_prefix(
ulint local_len);/*!< in: length of data, in bytes */
/*******************************************************************//**
Copies an externally stored field of a record to mem heap.
-@return the field copied to heap */
+@return the field copied to heap, or NULL if the field is incomplete */
UNIV_INTERN
byte*
btr_rec_copy_externally_stored_field(
diff --git a/storage/innodb_plugin/include/btr0sea.h b/storage/innodb_plugin/include/btr0sea.h
index f98ba386f9c..20a2be7f877 100644
--- a/storage/innodb_plugin/include/btr0sea.h
+++ b/storage/innodb_plugin/include/btr0sea.h
@@ -190,7 +190,13 @@ btr_search_validate(void);
/** Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
-extern char btr_search_enabled;
+extern char btr_search_enabled;
+
+/** Flag: whether the search system has completed its disabling process,
+It is set to TRUE right after buf_pool_drop_hash_index() in
+btr_search_disable(), indicating hash index entries are cleaned up.
+Protected by btr_search_latch and btr_search_enabled_mutex. */
+extern ibool btr_search_fully_disabled;
/** The search info struct in an index */
struct btr_search_struct{
diff --git a/storage/innodb_plugin/include/mem0pool.h b/storage/innodb_plugin/include/mem0pool.h
index 5e93bf88a47..fa8be296ec9 100644
--- a/storage/innodb_plugin/include/mem0pool.h
+++ b/storage/innodb_plugin/include/mem0pool.h
@@ -100,18 +100,6 @@ mem_pool_get_reserved(
/*==================*/
mem_pool_t* pool); /*!< in: memory pool */
/********************************************************************//**
-Reserves the mem pool mutex. */
-UNIV_INTERN
-void
-mem_pool_mutex_enter(void);
-/*======================*/
-/********************************************************************//**
-Releases the mem pool mutex. */
-UNIV_INTERN
-void
-mem_pool_mutex_exit(void);
-/*=====================*/
-/********************************************************************//**
Validates a memory pool.
@return TRUE if ok */
UNIV_INTERN
diff --git a/storage/innodb_plugin/include/row0mysql.h b/storage/innodb_plugin/include/row0mysql.h
index 39ea240772c..b69e657361b 100644
--- a/storage/innodb_plugin/include/row0mysql.h
+++ b/storage/innodb_plugin/include/row0mysql.h
@@ -622,7 +622,11 @@ struct row_prebuilt_struct {
the secondary index, then this is
set to TRUE */
unsigned templ_contains_blob:1;/*!< TRUE if the template contains
- BLOB column(s) */
+ a column with DATA_BLOB ==
+ get_innobase_type_from_mysql_type();
+ not to be confused with InnoDB
+ externally stored columns
+ (VARCHAR can be off-page too) */
mysql_row_templ_t* mysql_template;/*!< template used to transform
rows fast between MySQL and Innobase
formats; memory for this template
diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i
index ff62c3e53c1..991625d6a8a 100644
--- a/storage/innodb_plugin/include/univ.i
+++ b/storage/innodb_plugin/include/univ.i
@@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
-#define INNODB_VERSION_BUGFIX 10
+#define INNODB_VERSION_BUGFIX 11
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
diff --git a/storage/innodb_plugin/mem/mem0mem.c b/storage/innodb_plugin/mem/mem0mem.c
index c0ce8a3e1ac..1dd4db30841 100644
--- a/storage/innodb_plugin/mem/mem0mem.c
+++ b/storage/innodb_plugin/mem/mem0mem.c
@@ -367,7 +367,7 @@ mem_heap_create_block(
block->line = line;
#ifdef MEM_PERIODIC_CHECK
- mem_pool_mutex_enter();
+ mutex_enter(&(mem_comm_pool->mutex));
if (!mem_block_list_inited) {
mem_block_list_inited = TRUE;
@@ -376,7 +376,7 @@ mem_heap_create_block(
UT_LIST_ADD_LAST(mem_block_list, mem_block_list, block);
- mem_pool_mutex_exit();
+ mutex_exit(&(mem_comm_pool->mutex));
#endif
mem_block_set_len(block, len);
mem_block_set_type(block, type);
@@ -479,11 +479,11 @@ mem_heap_block_free(
UT_LIST_REMOVE(list, heap->base, block);
#ifdef MEM_PERIODIC_CHECK
- mem_pool_mutex_enter();
+ mutex_enter(&(mem_comm_pool->mutex));
UT_LIST_REMOVE(mem_block_list, mem_block_list, block);
- mem_pool_mutex_exit();
+ mutex_exit(&(mem_comm_pool->mutex));
#endif
ut_ad(heap->total_size >= block->len);
@@ -556,7 +556,7 @@ mem_validate_all_blocks(void)
{
mem_block_t* block;
- mem_pool_mutex_enter();
+ mutex_enter(&(mem_comm_pool->mutex));
block = UT_LIST_GET_FIRST(mem_block_list);
@@ -568,6 +568,6 @@ mem_validate_all_blocks(void)
block = UT_LIST_GET_NEXT(mem_block_list, block);
}
- mem_pool_mutex_exit();
+ mutex_exit(&(mem_comm_pool->mutex));
}
#endif
diff --git a/storage/innodb_plugin/mem/mem0pool.c b/storage/innodb_plugin/mem/mem0pool.c
index c4f8af607e0..3291453eeb5 100644
--- a/storage/innodb_plugin/mem/mem0pool.c
+++ b/storage/innodb_plugin/mem/mem0pool.c
@@ -34,6 +34,7 @@ Created 5/12/1997 Heikki Tuuri
#include "ut0lst.h"
#include "ut0byte.h"
#include "mem0mem.h"
+#include "srv0start.h"
/* We would like to use also the buffer frames to allocate memory. This
would be desirable, because then the memory consumption of the database
@@ -121,23 +122,33 @@ mysql@lists.mysql.com */
UNIV_INTERN ulint mem_n_threads_inside = 0;
/********************************************************************//**
-Reserves the mem pool mutex. */
-UNIV_INTERN
+Reserves the mem pool mutex if we are not in server shutdown. Use
+this function only in memory free functions, since only memory
+free functions are used during server shutdown. */
+UNIV_INLINE
void
-mem_pool_mutex_enter(void)
-/*======================*/
+mem_pool_mutex_enter(
+/*=================*/
+ mem_pool_t* pool) /*!< in: memory pool */
{
- mutex_enter(&(mem_comm_pool->mutex));
+ if (srv_shutdown_state < SRV_SHUTDOWN_EXIT_THREADS) {
+ mutex_enter(&(pool->mutex));
+ }
}
/********************************************************************//**
-Releases the mem pool mutex. */
-UNIV_INTERN
+Releases the mem pool mutex if we are not in server shutdown. As
+its corresponding mem_pool_mutex_enter() function, use it only
+in memory free functions */
+UNIV_INLINE
void
-mem_pool_mutex_exit(void)
-/*=====================*/
+mem_pool_mutex_exit(
+/*================*/
+ mem_pool_t* pool) /*!< in: memory pool */
{
- mutex_exit(&(mem_comm_pool->mutex));
+ if (srv_shutdown_state < SRV_SHUTDOWN_EXIT_THREADS) {
+ mutex_exit(&(pool->mutex));
+ }
}
/********************************************************************//**
@@ -567,7 +578,7 @@ mem_area_free(
n = ut_2_log(size);
- mutex_enter(&(pool->mutex));
+ mem_pool_mutex_enter(pool);
mem_n_threads_inside++;
ut_a(mem_n_threads_inside == 1);
@@ -595,7 +606,7 @@ mem_area_free(
pool->reserved += ut_2_exp(n);
mem_n_threads_inside--;
- mutex_exit(&(pool->mutex));
+ mem_pool_mutex_exit(pool);
mem_area_free(new_ptr, pool);
@@ -611,7 +622,7 @@ mem_area_free(
}
mem_n_threads_inside--;
- mutex_exit(&(pool->mutex));
+ mem_pool_mutex_exit(pool);
ut_ad(mem_pool_validate(pool));
}
@@ -630,7 +641,7 @@ mem_pool_validate(
ulint free;
ulint i;
- mutex_enter(&(pool->mutex));
+ mem_pool_mutex_enter(pool);
free = 0;
@@ -658,7 +669,7 @@ mem_pool_validate(
ut_a(free + pool->reserved == pool->size);
- mutex_exit(&(pool->mutex));
+ mem_pool_mutex_exit(pool);
return(TRUE);
}
diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c
index 70cc7912fad..56a68b58225 100644
--- a/storage/innodb_plugin/row/row0merge.c
+++ b/storage/innodb_plugin/row/row0merge.c
@@ -1780,6 +1780,11 @@ row_merge_copy_blobs(
(below). */
data = btr_rec_copy_externally_stored_field(
mrec, offsets, zip_size, i, &len, heap);
+ /* Because we have locked the table, any records
+ written by incomplete transactions must have been
+ rolled back already. There must not be any incomplete
+ BLOB columns. */
+ ut_a(data);
dfield_set_data(field, data, len);
}
diff --git a/storage/innodb_plugin/row/row0row.c b/storage/innodb_plugin/row/row0row.c
index cb7dfa2b7c9..8e806a14a98 100644
--- a/storage/innodb_plugin/row/row0row.c
+++ b/storage/innodb_plugin/row/row0row.c
@@ -294,7 +294,13 @@ row_build(
ut_ad(dtuple_check_typed(row));
- if (j) {
+ if (!ext) {
+ /* REDUNDANT and COMPACT formats store a local
+ 768-byte prefix of each externally stored
+ column. No cache is needed. */
+ ut_ad(dict_table_get_format(index->table)
+ < DICT_TF_FORMAT_ZIP);
+ } else if (j) {
*ext = row_ext_create(j, ext_cols, row,
dict_table_zip_size(index->table),
heap);
diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c
index 2861235a995..76c144e5a8c 100644
--- a/storage/innodb_plugin/row/row0sel.c
+++ b/storage/innodb_plugin/row/row0sel.c
@@ -416,7 +416,7 @@ row_sel_fetch_columns(
field_no))) {
/* Copy an externally stored field to the
- temporary heap */
+ temporary heap, if possible. */
heap = mem_heap_create(1);
@@ -425,6 +425,17 @@ row_sel_fetch_columns(
dict_table_zip_size(index->table),
field_no, &len, heap);
+ /* data == NULL means that the
+ externally stored field was not
+ written yet. This record
+ should only be seen by
+ recv_recovery_rollback_active() or any
+ TRX_ISO_READ_UNCOMMITTED
+ transactions. The InnoDB SQL parser
+ (the sole caller of this function)
+ does not implement READ UNCOMMITTED,
+ and it is not involved during rollback. */
+ ut_a(data);
ut_a(len != UNIV_SQL_NULL);
needs_copy = TRUE;
@@ -926,6 +937,7 @@ row_sel_get_clust_rec(
when plan->clust_pcur was positioned. The latch will not be
released until mtr_commit(mtr). */
+ ut_ad(!rec_get_deleted_flag(clust_rec, rec_offs_comp(offsets)));
row_sel_fetch_columns(index, clust_rec, offsets,
UT_LIST_GET_FIRST(plan->columns));
*out_rec = clust_rec;
@@ -1628,6 +1640,13 @@ skip_lock:
}
if (old_vers == NULL) {
+ /* The record does not exist
+ in our read view. Skip it, but
+ first attempt to determine
+ whether the index segment we
+ are searching through has been
+ exhausted. */
+
offsets = rec_get_offsets(
rec, index, offsets,
ULINT_UNDEFINED, &heap);
@@ -2647,9 +2666,8 @@ Convert a row in the Innobase format to a row in the MySQL format.
Note that the template in prebuilt may advise us to copy only a few
columns to mysql_rec, other columns are left blank. All columns may not
be needed in the query.
-@return TRUE if success, FALSE if could not allocate memory for a BLOB
-(though we may also assert in that case) */
-static
+@return TRUE on success, FALSE if not all columns could be retrieved */
+static __attribute__((warn_unused_result))
ibool
row_sel_store_mysql_rec(
/*====================*/
@@ -2672,6 +2690,7 @@ row_sel_store_mysql_rec(
ut_ad(prebuilt->mysql_template);
ut_ad(prebuilt->default_rec);
ut_ad(rec_offs_validate(rec, NULL, offsets));
+ ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
mem_heap_free(prebuilt->blob_heap);
@@ -2719,6 +2738,21 @@ row_sel_store_mysql_rec(
dict_table_zip_size(prebuilt->table),
templ->rec_field_no, &len, heap);
+ if (UNIV_UNLIKELY(!data)) {
+ /* The externally stored field
+ was not written yet. This
+ record should only be seen by
+ recv_recovery_rollback_active()
+ or any TRX_ISO_READ_UNCOMMITTED
+ transactions. */
+
+ if (extern_field_heap) {
+ mem_heap_free(extern_field_heap);
+ }
+
+ return(FALSE);
+ }
+
ut_a(len != UNIV_SQL_NULL);
} else {
/* Field is stored in the row. */
@@ -3136,9 +3170,10 @@ row_sel_pop_cached_row_for_mysql(
}
/********************************************************************//**
-Pushes a row for MySQL to the fetch cache. */
-UNIV_INLINE
-void
+Pushes a row for MySQL to the fetch cache.
+@return TRUE on success, FALSE if the record contains incomplete BLOBs */
+UNIV_INLINE __attribute__((warn_unused_result))
+ibool
row_sel_push_cache_row_for_mysql(
/*=============================*/
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
@@ -3180,10 +3215,11 @@ row_sel_push_cache_row_for_mysql(
prebuilt->fetch_cache[
prebuilt->n_fetch_cached],
prebuilt, rec, offsets))) {
- ut_error;
+ return(FALSE);
}
prebuilt->n_fetch_cached++;
+ return(TRUE);
}
/*********************************************************************//**
@@ -3578,11 +3614,21 @@ row_search_for_mysql(
if (!row_sel_store_mysql_rec(buf, prebuilt,
rec, offsets)) {
- err = DB_TOO_BIG_RECORD;
-
- /* We let the main loop to do the
- error handling */
- goto shortcut_fails_too_big_rec;
+ /* Only fresh inserts may contain
+ incomplete externally stored
+ columns. Pretend that such
+ records do not exist. Such
+ records may only be accessed
+ at the READ UNCOMMITTED
+ isolation level or when
+ rolling back a recovered
+ transaction. Rollback happens
+ at a lower level, not here. */
+ ut_a(trx->isolation_level
+ == TRX_ISO_READ_UNCOMMITTED);
+
+ /* Proceed as in case SEL_RETRY. */
+ break;
}
mtr_commit(&mtr);
@@ -3622,7 +3668,7 @@ release_search_latch_if_needed:
default:
ut_ad(0);
}
-shortcut_fails_too_big_rec:
+
mtr_commit(&mtr);
mtr_start(&mtr);
}
@@ -4357,9 +4403,18 @@ requires_clust_rec:
not cache rows because there the cursor is a scrollable
cursor. */
- row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
- offsets);
- if (prebuilt->n_fetch_cached == MYSQL_FETCH_CACHE_SIZE) {
+ if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
+ offsets)) {
+ /* Only fresh inserts may contain incomplete
+ externally stored columns. Pretend that such
+ records do not exist. Such records may only be
+ accessed at the READ UNCOMMITTED isolation
+ level or when rolling back a recovered
+ transaction. Rollback happens at a lower
+ level, not here. */
+ ut_a(trx->isolation_level == TRX_ISO_READ_UNCOMMITTED);
+ } else if (prebuilt->n_fetch_cached
+ == MYSQL_FETCH_CACHE_SIZE) {
goto got_row;
}
@@ -4375,9 +4430,17 @@ requires_clust_rec:
} else {
if (!row_sel_store_mysql_rec(buf, prebuilt,
result_rec, offsets)) {
- err = DB_TOO_BIG_RECORD;
-
- goto lock_wait_or_error;
+ /* Only fresh inserts may contain
+ incomplete externally stored
+ columns. Pretend that such records do
+ not exist. Such records may only be
+ accessed at the READ UNCOMMITTED
+ isolation level or when rolling back a
+ recovered transaction. Rollback
+ happens at a lower level, not here. */
+ ut_a(trx->isolation_level
+ == TRX_ISO_READ_UNCOMMITTED);
+ goto next_rec;
}
}
diff --git a/storage/innodb_plugin/row/row0undo.c b/storage/innodb_plugin/row/row0undo.c
index 9ef842b5114..fd28a4f6520 100644
--- a/storage/innodb_plugin/row/row0undo.c
+++ b/storage/innodb_plugin/row/row0undo.c
@@ -199,8 +199,24 @@ row_undo_search_clust_to_pcur(
ret = FALSE;
} else {
+ row_ext_t** ext;
+
+ if (dict_table_get_format(node->table) >= DICT_TF_FORMAT_ZIP) {
+ /* In DYNAMIC or COMPRESSED format, there is
+ no prefix of externally stored columns in the
+ clustered index record. Build a cache of
+ column prefixes. */
+ ext = &node->ext;
+ } else {
+ /* REDUNDANT and COMPACT formats store a local
+ 768-byte prefix of each externally stored
+ column. No cache is needed. */
+ ext = NULL;
+ node->ext = NULL;
+ }
+
node->row = row_build(ROW_COPY_DATA, clust_index, rec,
- offsets, NULL, &node->ext, node->heap);
+ offsets, NULL, ext, node->heap);
if (node->update) {
node->undo_row = dtuple_copy(node->row, node->heap);
row_upd_replace(node->undo_row, &node->undo_ext,
diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c
index d0aaecd3dae..397b117c067 100644
--- a/storage/innodb_plugin/row/row0upd.c
+++ b/storage/innodb_plugin/row/row0upd.c
@@ -1398,6 +1398,7 @@ row_upd_store_row(
dict_index_t* clust_index;
rec_t* rec;
mem_heap_t* heap = NULL;
+ row_ext_t** ext;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
const ulint* offsets;
rec_offs_init(offsets_);
@@ -1414,8 +1415,22 @@ row_upd_store_row(
offsets = rec_get_offsets(rec, clust_index, offsets_,
ULINT_UNDEFINED, &heap);
+
+ if (dict_table_get_format(node->table) >= DICT_TF_FORMAT_ZIP) {
+ /* In DYNAMIC or COMPRESSED format, there is no prefix
+ of externally stored columns in the clustered index
+ record. Build a cache of column prefixes. */
+ ext = &node->ext;
+ } else {
+ /* REDUNDANT and COMPACT formats store a local
+ 768-byte prefix of each externally stored column.
+ No cache is needed. */
+ ext = NULL;
+ node->ext = NULL;
+ }
+
node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,
- NULL, &node->ext, node->heap);
+ NULL, ext, node->heap);
if (node->is_delete) {
node->upd_row = NULL;
node->upd_ext = NULL;
diff --git a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c
index e517b9a86b0..ba9fc831b39 100644
--- a/storage/innodb_plugin/srv/srv0start.c
+++ b/storage/innodb_plugin/srv/srv0start.c
@@ -2018,9 +2018,13 @@ innobase_shutdown_for_mysql(void)
pars_lexer_close();
log_mem_free();
buf_pool_free();
- ut_free_all_mem();
mem_close();
+ /* ut_free_all_mem() frees all allocated memory not freed yet
+ in shutdown, and it will also free the ut_list_mutex, so it
+ should be the last one for all operation */
+ ut_free_all_mem();
+
if (os_thread_count != 0
|| os_event_count != 0
|| os_mutex_count != 0
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 1475cd52488..95ddde42e07 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -786,8 +786,11 @@ static int maria_create_trn_for_mysql(MARIA_HA *info)
thd->query_length());
}
else
+ {
DBUG_PRINT("info", ("lock_type: %d trnman_flags: %u",
- info->lock_type, trnman_get_flags(trn))); /* QQ */
+ info->lock_type, trnman_get_flags(trn)));
+ }
+
#endif
DBUG_RETURN(0);
}
@@ -2383,6 +2386,12 @@ int ha_maria::extra(enum ha_extra_function operation)
int ha_maria::reset(void)
{
+ if (file->trn)
+ {
+ /* Next statement is a new statement. Ensure it's logged */
+ trnman_set_flags(file->trn,
+ trnman_get_flags(file->trn) & ~TRN_STATE_INFO_LOGGED);
+ }
return maria_reset(file);
}
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index a76b36e1115..4f37d7b9a1f 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -147,6 +147,12 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
DBUG_ASSERT(bitmap->file.write_callback != 0);
DBUG_PRINT("info", ("bitmap->non_flushable: %u", bitmap->non_flushable));
+ /*
+ Mark that a bitmap page has been written to page cache and we have
+ to flush it during checkpoint.
+ */
+ bitmap->changed_not_flushed= 1;
+
if ((bitmap->non_flushable == 0)
#ifdef WRONG_BITMAP_FLUSH
|| 1
@@ -347,7 +353,7 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
MARIA_FILE_BITMAP *bitmap= &share->bitmap;
DBUG_ENTER("_ma_bitmap_flush_all");
pthread_mutex_lock(&bitmap->bitmap_lock);
- if (bitmap->changed)
+ if (bitmap->changed || bitmap->changed_not_flushed)
{
bitmap->flush_all_requested= TRUE;
#ifndef WRONG_BITMAP_FLUSH
@@ -384,6 +390,7 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
&bitmap->pages_covered) &
PCFLUSH_PINNED_AND_ERROR)
res= TRUE;
+ bitmap->changed_not_flushed= FALSE;
bitmap->flush_all_requested= FALSE;
/*
Some well-behaved threads may be waiting for flush_all_requested to
@@ -1875,6 +1882,7 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
uint offset_page, offset, tmp, org_tmp;
uchar *data;
DBUG_ENTER("set_page_bits");
+ DBUG_ASSERT(fill_pattern <= 7);
bitmap_page= page - page % bitmap->pages_covered;
if (bitmap_page != bitmap->page &&
@@ -2296,9 +2304,16 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
The page has all bits set; The following test is an optimization
to not set the bits to the same value as before.
*/
- if (bits != current_bitmap_value &&
- set_page_bits(info, bitmap, block->page, bits))
- goto err;
+ if (bits != current_bitmap_value)
+ {
+ if (set_page_bits(info, bitmap, block->page, bits))
+ goto err;
+ }
+ else
+ {
+ DBUG_ASSERT(current_bitmap_value ==
+ _ma_bitmap_get_page_bits(info, bitmap, block->page));
+ }
}
else if (!(block->used & BLOCKUSED_USED) &&
_ma_bitmap_reset_full_page_bits(info, bitmap,
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 0779564c8af..e3cb8d14eeb 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -1716,7 +1716,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,
MARIA_PINNED_PAGE page_link;
MARIA_SHARE *share= info->s;
DBUG_ENTER("get_head_or_tail_page");
- DBUG_PRINT("enter", ("length: %u", length));
+ DBUG_PRINT("enter", ("page_type: %u length: %u", page_type, length));
block_size= share->block_size;
if (block->org_bitmap_value == 0) /* Empty block */
@@ -1990,7 +1990,8 @@ static my_bool write_tail(MARIA_HA *info,
block->empty_space= (enough_free_entries(row_pos.buff, share->block_size,
1 + share->base.blobs) ?
empty_space : 0);
- block->used= BLOCKUSED_USED | BLOCKUSED_TAIL;
+ /* Keep BLOCKUSED_USE_ORG_BITMAP */
+ block->used|= BLOCKUSED_USED | BLOCKUSED_TAIL;
/* Increase data file size, if extended */
position= (my_off_t) block->page * block_size;
@@ -6237,7 +6238,10 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
/* Skip errors when reading outside of file and uninitialized pages */
if (!new_page || (my_errno != HA_ERR_FILE_TOO_SHORT &&
my_errno != HA_ERR_WRONG_CRC))
+ {
+ DBUG_PRINT("error", ("Error %d when reading page", (int) my_errno));
goto err;
+ }
/* Create new page */
buff= pagecache_block_link_to_buffer(page_link.link);
buff[PAGE_TYPE_OFFSET]= UNALLOCATED_PAGE;
@@ -6265,7 +6269,13 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
changed to new type.
*/
if (!new_page)
+ {
+ DBUG_PRINT("error",
+ ("Found page of wrong type: %u, should have been %u",
+ (uint) (buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK),
+ page_type));
goto crashed_file;
+ }
make_empty_page(info, buff, page_type, 0);
empty_space= block_size - PAGE_HEADER_SIZE - PAGE_SUFFIX_SIZE;
(void) extend_directory(page_type == HEAD_PAGE ? info: 0, buff,
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 086cff67dab..ed3a7a46344 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -136,11 +136,13 @@ void maria_chk_init_for_check(HA_CHECK *param, MARIA_HA *info)
Set up transaction handler so that we can see all rows. When rows is read
we will check the found id against param->max_tried
*/
- if (!ma_control_file_inited())
- param->max_trid= 0; /* Give warning for first trid found */
- else
- param->max_trid= max_trid_in_system();
-
+ if (param->max_trid == 0)
+ {
+ if (!ma_control_file_inited())
+ param->max_trid= 0; /* Give warning for first trid found */
+ else
+ param->max_trid= max_trid_in_system();
+ }
maria_ignore_trids(info);
}
@@ -867,7 +869,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
llstr(anc_page->pos, llbuff));
}
- if (anc_page->size > (uint) keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)
+ if (anc_page->size > share->max_index_block_size)
{
_ma_check_print_error(param,
"Page at %s has impossible (too big) pagelength",
@@ -1758,7 +1760,7 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, uchar *record,
_ma_check_print_error(param,
"Page %9s: Row: %3d has an extent with "
"wrong information in bitmap: "
- "Page %9s Page_type: %d Bitmap: %d",
+ "Page: %9s Page_type: %d Bitmap: %d",
llstr(page, llbuff), row,
llstr(extent_page, llbuff2),
page_type, bitmap_pattern);
@@ -2325,11 +2327,13 @@ static int initialize_variables_for_repair(HA_CHECK *param,
}
/* Set up transaction handler so that we can see all rows */
- if (!ma_control_file_inited())
- param->max_trid= 0; /* Give warning for first trid found */
- else
- param->max_trid= max_trid_in_system();
-
+ if (param->max_trid == 0)
+ {
+ if (!ma_control_file_inited())
+ param->max_trid= 0; /* Give warning for first trid found */
+ else
+ param->max_trid= max_trid_in_system();
+ }
maria_ignore_trids(info);
/* Don't write transid's during repair */
maria_versioning(info, 0);
@@ -5609,7 +5613,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
a_length+=t_length;
_ma_store_page_used(share, anc_buff, a_length);
key_block->end_pos+=t_length;
- if (a_length <= (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
+ if (a_length <= share->max_index_block_size)
{
MARIA_KEY tmp_key2;
tmp_key2.data= key_block->lastkey;
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index 0e9e5caafbf..2420cac0e93 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -1,4 +1,5 @@
/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ Copyright (C) 2009-2010 Monty Program Ab
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
@@ -180,7 +181,11 @@ my_bool _ma_ck_delete(MARIA_HA *info, MARIA_KEY *key)
key->data= key_buff;
}
- res= _ma_ck_real_delete(info, key, &new_root);
+ if ((res= _ma_ck_real_delete(info, key, &new_root)))
+ {
+ /* We have to mark the table crashed before unpin_all_pages() */
+ maria_mark_crashed(info);
+ }
key->data= save_key_data;
if (!res && share->now_transactional)
@@ -218,7 +223,8 @@ my_bool _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEY *key,
my_errno=ENOMEM;
DBUG_RETURN(1);
}
- DBUG_PRINT("info",("root_page: %ld", (long) old_root));
+ DBUG_PRINT("info",("root_page: %lu",
+ (ulong) (old_root / keyinfo->block_length)));
if (_ma_fetch_keypage(&page, info, keyinfo, old_root,
PAGECACHE_LOCK_WRITE, DFLT_INIT_HITS, root_buff, 0))
{
@@ -435,7 +441,8 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
*/
if (share->now_transactional &&
_ma_log_delete(anc_page, s_temp.key_pos,
- s_temp.changed_length, s_temp.move_length))
+ s_temp.changed_length, s_temp.move_length,
+ 0, KEY_OP_DEBUG_LOG_DEL_CHANGE_1))
DBUG_RETURN(-1);
if (!nod_flag)
@@ -458,7 +465,7 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
}
if (ret_value >0)
{
- save_flag=1;
+ save_flag= 2;
if (ret_value == 1)
ret_value= underflow(info, keyinfo, anc_page, &leaf_page, keypos);
else
@@ -474,17 +481,20 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
ret_value= _ma_insert(info, key, anc_page, keypos,
last_key.data,
(MARIA_PAGE*) 0, (uchar*) 0, (my_bool) 0);
+
+ if (_ma_write_keypage(&leaf_page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
+ ret_value= -1;
}
}
- if (ret_value == 0 && anc_page->size >
- (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
+ if (ret_value == 0 && anc_page->size > share->max_index_block_size)
{
/* parent buffer got too big ; We have to split the page */
- save_flag=1;
+ save_flag= 3;
ret_value= _ma_split_page(info, key, anc_page,
- (uint) (keyinfo->block_length -
- KEYPAGE_CHECKSUM_SIZE),
+ share->max_index_block_size,
(uchar*) 0, 0, 0, lastkey, 0) | 2;
+ DBUG_ASSERT(anc_page->org_size == anc_page->size);
}
if (save_flag && ret_value != 1)
{
@@ -550,7 +560,8 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
MARIA_KEY ret_key;
MARIA_PAGE next_page;
DBUG_ENTER("del");
- DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx", (long) leaf_page,
+ DBUG_PRINT("enter",("leaf_page: %lu keypos: 0x%lx",
+ (ulong) (leaf_page->pos / share->block_size),
(ulong) keypos));
DBUG_DUMP("leaf_buff", leaf_page->buff, leaf_page->size);
@@ -587,11 +598,10 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
ret_value= underflow(info, keyinfo, leaf_page, &next_page,
endpos);
if (ret_value == 0 && leaf_page->size >
- (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
+ share->max_index_block_size)
{
ret_value= (_ma_split_page(info, key, leaf_page,
- (uint) (keyinfo->block_length -
- KEYPAGE_CHECKSUM_SIZE),
+ share->max_index_block_size,
(uchar*) 0, 0, 0,
ret_key_buff, 0) | 2);
}
@@ -708,8 +718,7 @@ err:
@fn underflow()
@param anc_buff Anchestor page data
- @param leaf_page Page number of leaf page
- @param leaf_buff Leaf page (page that underflowed)
+ @param leaf_page Leaf page (page that underflowed)
@param leaf_page_link Pointer to pin information about leaf page
@param keypos Position after current key in anc_buff
@@ -743,7 +752,8 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
MARIA_KEY tmp_key, anc_key, leaf_key;
MARIA_PAGE next_page;
DBUG_ENTER("underflow");
- DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx",(long) leaf_page->pos,
+ DBUG_PRINT("enter",("leaf_page: %lu keypos: 0x%lx",
+ (ulong) (leaf_page->pos / share->block_size),
(ulong) keypos));
DBUG_DUMP("anc_buff", anc_page->buff, anc_page->size);
DBUG_DUMP("leaf_buff", leaf_page->buff, leaf_page->size);
@@ -841,7 +851,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
anc_page->size= new_anc_length;
page_store_size(share, anc_page);
- if (buff_length <= (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
+ if (buff_length <= share->max_index_block_size)
{
/* All keys fitted into one page */
page_mark_changed(info, &next_page);
@@ -854,10 +864,15 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (share->now_transactional)
{
- /* Log changes to parent page */
+ /*
+ Log changes to parent page. Note that this page may have been
+ temporarily bigger than block_size.
+ */
if (_ma_log_delete(anc_page, key_deleted.key_pos,
key_deleted.changed_length,
- key_deleted.move_length))
+ key_deleted.move_length,
+ anc_length - anc_page->org_size,
+ KEY_OP_DEBUG_LOG_DEL_CHANGE_2))
goto err;
/*
Log changes to leaf page. Data for leaf page is in leaf_buff
@@ -986,7 +1001,8 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
*/
DBUG_ASSERT(new_buff_length <= next_buff_length);
if (_ma_log_prefix(&next_page, key_inserted.changed_length,
- (int) (new_buff_length - next_buff_length)))
+ (int) (new_buff_length - next_buff_length),
+ KEY_OP_DEBUG_LOG_PREFIX_1))
goto err;
}
page_mark_changed(info, &next_page);
@@ -1044,11 +1060,19 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/* Remember for logging how many bytes of leaf_buff that are not changed */
DBUG_ASSERT((int) key_inserted.changed_length >= key_inserted.move_length);
- unchanged_leaf_length= leaf_length - (key_inserted.changed_length -
- key_inserted.move_length);
+ unchanged_leaf_length= (leaf_length - p_length -
+ (key_inserted.changed_length -
+ key_inserted.move_length));
new_buff_length= buff_length + leaf_length - p_length + t_length;
+#ifdef EXTRA_DEBUG
+ /* Ensure that unchanged_leaf_length is correct */
+ DBUG_ASSERT(bcmp(next_page.buff + new_buff_length - unchanged_leaf_length,
+ leaf_buff + leaf_length - unchanged_leaf_length,
+ unchanged_leaf_length) == 0);
+#endif
+
page_flag= next_page.flag | leaf_page->flag;
if (anc_key.flag & (SEARCH_USER_KEY_HAS_TRANSID |
SEARCH_PAGE_KEY_HAS_TRANSID))
@@ -1069,8 +1093,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
anc_page->size= new_anc_length;
page_store_size(share, anc_page);
- if (new_buff_length <= (uint) (keyinfo->block_length -
- KEYPAGE_CHECKSUM_SIZE))
+ if (new_buff_length <= share->max_index_block_size)
{
/* All keys fitted into one page */
page_mark_changed(info, leaf_page);
@@ -1079,10 +1102,14 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (share->now_transactional)
{
- /* Log changes to parent page */
+ /*
+ Log changes to parent page. Note that this page may have been
+ temporarily bigger than block_size.
+ */
if (_ma_log_delete(anc_page, key_deleted.key_pos,
- key_deleted.changed_length, key_deleted.move_length))
-
+ key_deleted.changed_length, key_deleted.move_length,
+ anc_length - anc_page->org_size,
+ KEY_OP_DEBUG_LOG_DEL_CHANGE_3))
goto err;
/*
Log changes to next page. Data for leaf page is in buff
@@ -1192,8 +1219,10 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
This contains original data with new data added first
*/
DBUG_ASSERT(leaf_length <= new_leaf_length);
+ DBUG_ASSERT(new_leaf_length >= unchanged_leaf_length);
if (_ma_log_prefix(leaf_page, new_leaf_length - unchanged_leaf_length,
- (int) (new_leaf_length - leaf_length)))
+ (int) (new_leaf_length - leaf_length),
+ KEY_OP_DEBUG_LOG_PREFIX_2))
goto err;
/*
Log changes to next page
@@ -1395,7 +1424,9 @@ static uint remove_key(MARIA_KEYDEF *keyinfo, uint page_flag, uint nod_flag,
****************************************************************************/
/**
- @brief log entry where some parts are deleted and some things are changed
+ @brief
+ log entry where some parts are deleted and some things are changed
+ and some data could be added last.
@fn _ma_log_delete()
@param info Maria handler
@@ -1404,74 +1435,148 @@ static uint remove_key(MARIA_KEYDEF *keyinfo, uint page_flag, uint nod_flag,
@param key_pos Start of change area
@param changed_length How many bytes where changed at key_pos
@param move_length How many bytes where deleted at key_pos
+ @param append_length Length of data added last
+ This is taken from end of ma_page->buff
+ This is mainly used when a key is deleted. The append happens
+ when we delete a key from a page with data > block_size kept in
+ memory and we have to add back the data that was stored > block_size
*/
my_bool _ma_log_delete(MARIA_PAGE *ma_page, const uchar *key_pos,
- uint changed_length, uint move_length)
+ uint changed_length, uint move_length,
+ uint append_length __attribute__((unused)),
+ enum en_key_debug debug_marker __attribute__((unused)))
{
LSN lsn;
- uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 9 + 7], *log_pos;
- LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
- uint translog_parts;
+ uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 2 + 3 + 3 + 6 + 3 + 7];
+ uchar *log_pos;
+ LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 7];
+ uint translog_parts, current_size, extra_length;
uint offset= (uint) (key_pos - ma_page->buff);
MARIA_HA *info= ma_page->info;
MARIA_SHARE *share= info->s;
my_off_t page;
DBUG_ENTER("_ma_log_delete");
DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
- (ulong) ma_page->pos, changed_length, move_length));
+ (ulong) (ma_page->pos / share->block_size),
+ changed_length, move_length));
DBUG_ASSERT(share->now_transactional && move_length);
DBUG_ASSERT(offset + changed_length <= ma_page->size);
+ DBUG_ASSERT(ma_page->org_size - move_length + append_length == ma_page->size);
+ DBUG_ASSERT(move_length <= ma_page->org_size - share->keypage_header);
/* Store address of new root page */
page= ma_page->pos / share->block_size;
page_store(log_data + FILEID_STORE_SIZE, page);
log_pos= log_data+ FILEID_STORE_SIZE + PAGE_STORE_SIZE;
+ current_size= ma_page->org_size;
+
+#ifdef EXTRA_DEBUG_KEY_CHANGES
+ *log_pos++= KEY_OP_DEBUG;
+ *log_pos++= debug_marker;
+#endif
+
+ /* Store keypage_flag */
+ *log_pos++= KEY_OP_SET_PAGEFLAG;
+ *log_pos++= ma_page->buff[KEYPAGE_TRANSFLAG_OFFSET];
+
log_pos[0]= KEY_OP_OFFSET;
int2store(log_pos+1, offset);
- log_pos[3]= KEY_OP_SHIFT;
- int2store(log_pos+4, -(int) move_length);
- log_pos+= 6;
- translog_parts= 1;
+ log_pos+= 3;
+ translog_parts= TRANSLOG_INTERNAL_PARTS + 1;
+ extra_length= 0;
+
if (changed_length)
{
+ if (offset + changed_length >= share->max_index_block_size)
+ {
+ changed_length= share->max_index_block_size - offset;
+ move_length= 0; /* Nothing to move */
+ current_size= share->max_index_block_size;
+ }
+
log_pos[0]= KEY_OP_CHANGE;
int2store(log_pos+1, changed_length);
log_pos+= 3;
- translog_parts= 2;
- log_array[TRANSLOG_INTERNAL_PARTS + 1].str= ma_page->buff + offset;
- log_array[TRANSLOG_INTERNAL_PARTS + 1].length= changed_length;
+ log_array[translog_parts].str= ma_page->buff + offset;
+ log_array[translog_parts].length= changed_length;
+ translog_parts++;
+
+ /* We only have to move things after offset+changed_length */
+ offset+= changed_length;
}
-#ifdef EXTRA_DEBUG_KEY_CHANGES
+ log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
+ log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data);
+
+ if (move_length)
{
- int page_length= ma_page->size;
- ha_checksum crc;
- crc= my_checksum(0, ma_page->buff + LSN_STORE_SIZE,
- page_length - LSN_STORE_SIZE);
- log_pos[0]= KEY_OP_CHECK;
- int2store(log_pos+1, page_length);
- int4store(log_pos+3, crc);
-
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
- changed_length+= 7;
+ uint log_length;
+ if (offset + move_length < share->max_index_block_size)
+ {
+ /*
+ Move down things that is on page.
+ page_offset in apply_redo_inxed() will be at original offset
+ + changed_length.
+ */
+ log_pos[0]= KEY_OP_SHIFT;
+ int2store(log_pos+1, - (int) move_length);
+ log_length= 3;
+ current_size-= move_length;
+ }
+ else
+ {
+ /* Delete to end of page */
+ uint tmp= current_size - offset;
+ current_size= offset;
+ log_pos[0]= KEY_OP_DEL_SUFFIX;
+ int2store(log_pos+1, tmp);
+ log_length= 3;
+ }
+ log_array[translog_parts].str= log_pos;
+ log_array[translog_parts].length= log_length;
translog_parts++;
+ log_pos+= log_length;
+ extra_length+= log_length;
}
-#endif
- log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
- log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data);
+ if (current_size != ma_page->size &&
+ current_size != share->max_index_block_size)
+ {
+ /* Append data that didn't fit on the page before */
+ uint length= (min(ma_page->size, share->max_index_block_size) -
+ current_size);
+ uchar *data= ma_page->buff + current_size;
+
+ DBUG_ASSERT(length <= append_length);
+
+ log_pos[0]= KEY_OP_ADD_SUFFIX;
+ int2store(log_pos+1, length);
+ log_array[translog_parts].str= log_pos;
+ log_array[translog_parts].length= 3;
+ log_array[translog_parts + 1].str= data;
+ log_array[translog_parts + 1].length= length;
+ log_pos+= 3;
+ translog_parts+= 2;
+ current_size+= length;
+ extra_length+= 3 + length;
+ }
+
+ _ma_log_key_changes(ma_page,
+ log_array + translog_parts,
+ log_pos, &extra_length, &translog_parts);
+ /* Remember new page length for future log entires for same page */
+ ma_page->org_size= current_size;
if (translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
(translog_size_t)
- log_array[TRANSLOG_INTERNAL_PARTS + 0].length +
- changed_length,
- TRANSLOG_INTERNAL_PARTS + translog_parts,
+ log_array[TRANSLOG_INTERNAL_PARTS].length +
+ changed_length + extra_length, translog_parts,
log_array, log_data, NULL))
DBUG_RETURN(1);
+
DBUG_RETURN(0);
}
diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c
index 82f8099fe6a..1a61731e817 100644
--- a/storage/maria/ma_key_recover.c
+++ b/storage/maria/ma_key_recover.c
@@ -312,24 +312,33 @@ my_bool write_hook_for_undo_key_delete(enum translog_record_type type,
*/
my_bool _ma_log_prefix(MARIA_PAGE *ma_page, uint changed_length,
- int move_length)
+ int move_length,
+ enum en_key_debug debug_marker __attribute__((unused)))
{
uint translog_parts;
LSN lsn;
- uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 7 + 7 + 2], *log_pos;
+ uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 7 + 7 + 2 + 2];
+ uchar *log_pos;
uchar *buff= ma_page->buff;
- LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
+ LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
pgcache_page_no_t page;
MARIA_HA *info= ma_page->info;
DBUG_ENTER("_ma_log_prefix");
DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
(ulong) ma_page->pos, changed_length, move_length));
+ DBUG_ASSERT(ma_page->size == ma_page->org_size + move_length);
+
page= ma_page->pos / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
+#ifdef EXTRA_DEBUG_KEY_CHANGES
+ (*log_pos++)= KEY_OP_DEBUG;
+ (*log_pos++)= debug_marker;
+#endif
+
/* Store keypage_flag */
*log_pos++= KEY_OP_SET_PAGEFLAG;
*log_pos++= buff[KEYPAGE_TRANSFLAG_OFFSET];
@@ -373,21 +382,11 @@ my_bool _ma_log_prefix(MARIA_PAGE *ma_page, uint changed_length,
translog_parts= 2;
}
-#ifdef EXTRA_DEBUG_KEY_CHANGES
- {
- int page_length= ma_page->size;
- ha_checksum crc;
- crc= my_checksum(0, buff + LSN_STORE_SIZE, page_length - LSN_STORE_SIZE);
- log_pos[0]= KEY_OP_CHECK;
- int2store(log_pos+1, page_length);
- int4store(log_pos+3, crc);
-
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
- changed_length+= 7;
- translog_parts++;
- }
-#endif
+ _ma_log_key_changes(ma_page, log_array + TRANSLOG_INTERNAL_PARTS +
+ translog_parts, log_pos, &changed_length,
+ &translog_parts);
+ /* Remember new page length for future log entires for same page */
+ ma_page->org_size= ma_page->size;
DBUG_RETURN(translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
@@ -407,7 +406,7 @@ my_bool _ma_log_prefix(MARIA_PAGE *ma_page, uint changed_length,
my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length)
{
LSN lsn;
- LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
+ LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 10 + 7 + 2], *log_pos;
uchar *buff= ma_page->buff;
int diff;
@@ -417,6 +416,8 @@ my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length)
DBUG_ENTER("_ma_log_suffix");
DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u",
(ulong) ma_page->pos, org_length, new_length));
+ DBUG_ASSERT(ma_page->size == new_length);
+ DBUG_ASSERT(ma_page->org_size == org_length);
page= ma_page->pos / info->s->block_size;
@@ -451,20 +452,11 @@ my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length)
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos -
log_data);
-#ifdef EXTRA_DEBUG_KEY_CHANGES
- {
- ha_checksum crc;
- crc= my_checksum(0, buff + LSN_STORE_SIZE, new_length - LSN_STORE_SIZE);
- log_pos[0]= KEY_OP_CHECK;
- int2store(log_pos+1, new_length);
- int4store(log_pos+3, crc);
-
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
- extra_length+= 7;
- translog_parts++;
- }
-#endif
+ _ma_log_key_changes(ma_page,
+ log_array + TRANSLOG_INTERNAL_PARTS + translog_parts,
+ log_pos, &extra_length, &translog_parts);
+ /* Remember new page length for future log entires for same page */
+ ma_page->org_size= ma_page->size;
DBUG_RETURN(translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
@@ -481,37 +473,45 @@ my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length)
@param ma_page Changed page
@param org_page_length Length of data in page before key was added
+ Final length in ma_page->size
@note
If handle_overflow is set, then we have to protect against
logging changes that is outside of the page.
This may happen during underflow() handling where the buffer
in memory temporary contains more data than block_size
+
+ ma_page may be a page that was previously logged and cuted down
+ becasue it's too big. (org_page_length > ma_page->org_size)
*/
my_bool _ma_log_add(MARIA_PAGE *ma_page,
- uint org_page_length, uchar *key_pos,
- uint changed_length, int move_length,
+ uint org_page_length __attribute__ ((unused)),
+ uchar *key_pos, uint changed_length, int move_length,
my_bool handle_overflow __attribute__ ((unused)))
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 3 + 3 + 3 + 3 + 7 +
- 2];
+ 3 + 2];
uchar *log_pos;
uchar *buff= ma_page->buff;
- LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
+ LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 6];
MARIA_HA *info= ma_page->info;
uint offset= (uint) (key_pos - buff);
- uint page_length= info->s->block_size - KEYPAGE_CHECKSUM_SIZE;
- uint translog_parts;
+ uint max_page_size= info->s->max_index_block_size;
+ uint translog_parts, current_size;
pgcache_page_no_t page_pos;
DBUG_ENTER("_ma_log_add");
DBUG_PRINT("enter", ("page: %lu org_page_length: %u changed_length: %u "
"move_length: %d",
- (ulong) ma_page->pos, org_page_length, changed_length,
+ (ulong) (ma_page->pos / info->s->block_size),
+ org_page_length, changed_length,
move_length));
DBUG_ASSERT(info->s->now_transactional);
DBUG_ASSERT(move_length <= (int) changed_length);
+ DBUG_ASSERT(ma_page->org_size == min(org_page_length, max_page_size));
+ DBUG_ASSERT(ma_page->size == org_page_length + move_length);
+ DBUG_ASSERT(offset < max_page_size);
/*
Write REDO entry that contains the logical operations we need
@@ -520,6 +520,7 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page,
log_pos= log_data + FILEID_STORE_SIZE;
page_pos= ma_page->pos / info->s->block_size;
page_store(log_pos, page_pos);
+ current_size= ma_page->org_size;
log_pos+= PAGE_STORE_SIZE;
#ifdef EXTRA_DEBUG_KEY_CHANGES
@@ -531,40 +532,41 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page,
*log_pos++= KEY_OP_SET_PAGEFLAG;
*log_pos++= buff[KEYPAGE_TRANSFLAG_OFFSET];
- if (org_page_length + move_length > page_length)
+ /*
+ Don't overwrite page boundary
+ It's ok to cut this as we will append the data at end of page
+ in the next log entry
+ */
+ if (offset + changed_length > max_page_size)
+ {
+ DBUG_ASSERT(handle_overflow);
+ changed_length= max_page_size - offset; /* Update to end of page */
+ move_length= 0; /* Nothing to move */
+ /* Extend the page to max length on recovery */
+ *log_pos++= KEY_OP_MAX_PAGELENGTH;
+ current_size= max_page_size;
+ }
+
+ /* Check if adding the key made the page overflow */
+ if (current_size + move_length > max_page_size)
{
/*
- Overflow. Cut either key or data from page end so that key fits
- The code that splits the too big page will ignore logging any
- data over org_page_length
+ Adding the key caused an overflow. Cut away the part of the
+ page that doesn't fit.
*/
+ uint diff;
DBUG_ASSERT(handle_overflow);
- if (offset + changed_length > page_length)
- {
- /* Log that data changed to end of page */
- changed_length= page_length - offset;
- move_length= 0;
- /* Set page to max length */
- org_page_length= page_length;
- *log_pos++= KEY_OP_MAX_PAGELENGTH;
- }
- else
- {
- /* They key will not be part of the page ; Don't log it */
- uint diff= org_page_length + move_length - page_length;
- log_pos[0]= KEY_OP_DEL_SUFFIX;
- int2store(log_pos+1, diff);
- log_pos+= 3;
- org_page_length-= diff;
- DBUG_ASSERT(org_page_length == page_length - move_length);
- }
- DBUG_ASSERT(offset != org_page_length);
+ diff= current_size + move_length - max_page_size;
+ log_pos[0]= KEY_OP_DEL_SUFFIX;
+ int2store(log_pos+1, diff);
+ log_pos+= 3;
+ current_size= max_page_size - move_length;
}
- if (offset == org_page_length)
+ if (offset == current_size)
{
- DBUG_ASSERT(move_length == (int) changed_length);
log_pos[0]= KEY_OP_ADD_SUFFIX;
+ current_size+= changed_length;
}
else
{
@@ -576,51 +578,104 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page,
log_pos[0]= KEY_OP_SHIFT;
int2store(log_pos+1, move_length);
log_pos+= 3;
+ current_size+= move_length;
}
log_pos[0]= KEY_OP_CHANGE;
}
int2store(log_pos+1, changed_length);
log_pos+= 3;
- translog_parts= 2;
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos -
log_data);
log_array[TRANSLOG_INTERNAL_PARTS + 1].str= key_pos;
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= changed_length;
+ translog_parts= TRANSLOG_INTERNAL_PARTS + 2;
-#ifdef EXTRA_DEBUG_KEY_CHANGES
+ /*
+ If page was originally > block_size before operation and now all data
+ fits, append the end data that was not part of the previous logged
+ page to it.
+ */
+ DBUG_ASSERT(current_size <= max_page_size && current_size <= ma_page->size);
+ if (current_size != ma_page->size && current_size != max_page_size)
{
- MARIA_SHARE *share= info->s;
- ha_checksum crc;
- uint save_page_length= ma_page->size;
- uint new_length= org_page_length + move_length;
- _ma_store_page_used(share, buff, new_length);
- crc= my_checksum(0, buff + LSN_STORE_SIZE, new_length - LSN_STORE_SIZE);
- log_pos[0]= KEY_OP_CHECK;
- int2store(log_pos+1, new_length);
- int4store(log_pos+3, crc);
-
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
- changed_length+= 7;
- translog_parts++;
- _ma_store_page_used(share, buff, save_page_length);
+ uint length= min(ma_page->size, max_page_size) - current_size;
+ uchar *data= ma_page->buff + current_size;
+
+ log_pos[0]= KEY_OP_ADD_SUFFIX;
+ int2store(log_pos+1, length);
+ log_array[translog_parts].str= log_pos;
+ log_array[translog_parts].length= 3;
+ log_array[translog_parts+1].str= data;
+ log_array[translog_parts+1].length= length;
+ log_pos+= 3;
+ translog_parts+= 2;
+ current_size+= length;
+ changed_length+= length + 3;
}
-#endif
+
+ _ma_log_key_changes(ma_page, log_array + translog_parts,
+ log_pos, &changed_length, &translog_parts);
+ /*
+ Remember new page length for future log entries for same page
+ Note that this can be different from ma_page->size in case of page
+ overflow!
+ */
+ ma_page->org_size= current_size;
+ DBUG_ASSERT(ma_page->org_size == min(ma_page->size, max_page_size));
if (translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
(translog_size_t)
log_array[TRANSLOG_INTERNAL_PARTS + 0].length +
- changed_length,
- TRANSLOG_INTERNAL_PARTS + translog_parts,
+ changed_length, translog_parts,
log_array, log_data, NULL))
DBUG_RETURN(-1);
DBUG_RETURN(0);
}
+#ifdef EXTRA_DEBUG_KEY_CHANGES
+
+/* Log checksum and optionally key page to log */
+
+void _ma_log_key_changes(MARIA_PAGE *ma_page, LEX_CUSTRING *log_array,
+ uchar *log_pos, uint *changed_length,
+ uint *translog_parts)
+{
+ MARIA_SHARE *share= ma_page->info->s;
+ int page_length= min(ma_page->size, share->max_index_block_size);
+ uint org_length;
+ ha_checksum crc;
+
+ DBUG_ASSERT(ma_page->flag == (uint) ma_page->buff[KEYPAGE_TRANSFLAG_OFFSET]);
+
+ /* We have to change length as the page may have been shortened */
+ org_length= _ma_get_page_used(share, ma_page->buff);
+ _ma_store_page_used(share, ma_page->buff, page_length);
+ crc= my_checksum(0, ma_page->buff + LSN_STORE_SIZE,
+ page_length - LSN_STORE_SIZE);
+ _ma_store_page_used(share, ma_page->buff, org_length);
+
+ log_pos[0]= KEY_OP_CHECK;
+ int2store(log_pos+1, page_length);
+ int4store(log_pos+3, crc);
+
+ log_array[0].str= log_pos;
+ log_array[0].length= 7;
+ (*changed_length)+= 7;
+ (*translog_parts)++;
+#ifdef EXTRA_STORE_FULL_PAGE_IN_KEY_CHANGES
+ log_array[1].str= ma_page->buff;
+ log_array[1].length= page_length;
+ (*changed_length)+= page_length;
+ (*translog_parts)++;
+#endif /* EXTRA_STORE_FULL_PAGE_IN_KEY_CHANGES */
+}
+
+#endif /* EXTRA_DEBUG_KEY_CHANGES */
+
/****************************************************************************
Redo of key pages
****************************************************************************/
@@ -716,7 +771,7 @@ uint _ma_apply_redo_index_new_page(MARIA_HA *info, LSN lsn,
bzero(buff, LSN_STORE_SIZE);
memcpy(buff + LSN_STORE_SIZE, header, length);
bzero(buff + LSN_STORE_SIZE + length,
- share->block_size - LSN_STORE_SIZE - KEYPAGE_CHECKSUM_SIZE - length);
+ share->max_index_block_size - LSN_STORE_SIZE - length);
bfill(buff + share->block_size - KEYPAGE_CHECKSUM_SIZE,
KEYPAGE_CHECKSUM_SIZE, (uchar) 255);
@@ -847,7 +902,9 @@ err:
KEY_OP_ADD_SUFFIX 2 length, data Add data to end of page
KEY_OP_DEL_SUFFIX 2 length Reduce page length with this
Sets position to start of page
- KEY_OP_CHECK 6 page_length[2},CRC Used only when debugging
+ KEY_OP_CHECK 6 page_length[2],CRC Used only when debugging
+ This may be followed by page_length
+ of data (until end of log record)
KEY_OP_COMPACT_PAGE 6 transid
KEY_OP_SET_PAGEFLAG 1 flag for page
KEY_OP_MAX_PAGELENGTH 0 Set page to max length
@@ -870,7 +927,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
const uchar *header_end= header + head_length;
uint page_offset= 0, org_page_length;
uint nod_flag, page_length, keypage_header, keynr;
- uint max_page_length= share->block_size - KEYPAGE_CHECKSUM_SIZE;
+ uint max_page_size= share->max_index_block_size;
int result;
MARIA_PAGE page;
DBUG_ENTER("_ma_apply_redo_index");
@@ -919,11 +976,14 @@ uint _ma_apply_redo_index(MARIA_HA *info,
header+= 2;
DBUG_PRINT("redo", ("key_op_shift: %d", length));
DBUG_ASSERT(page_offset != 0 && page_offset <= page_length &&
- page_length + length <= max_page_length);
+ page_length + length <= max_page_size);
if (length < 0)
+ {
+ DBUG_ASSERT(page_offset - length <= page_length);
bmove(buff + page_offset, buff + page_offset - length,
page_length - page_offset + length);
+ }
else if (page_length != page_offset)
bmove_upp(buff + page_length + length, buff + page_length,
page_length - page_offset);
@@ -937,6 +997,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
DBUG_ASSERT(page_offset != 0 && page_offset + length <= page_length);
memcpy(buff + page_offset, header + 2 , length);
+ page_offset+= length; /* Put offset after changed length */
header+= 2 + length;
break;
}
@@ -948,7 +1009,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
insert_length, changed_length));
DBUG_ASSERT(insert_length <= changed_length &&
- page_length + changed_length <= max_page_length);
+ page_length + changed_length <= max_page_size);
bmove_upp(buff + page_length + insert_length, buff + page_length,
page_length - keypage_header);
@@ -974,8 +1035,8 @@ uint _ma_apply_redo_index(MARIA_HA *info,
case KEY_OP_ADD_SUFFIX: /* 6 */
{
uint insert_length= uint2korr(header);
- DBUG_PRINT("redo", ("key_op_add_prefix: %u", insert_length));
- DBUG_ASSERT(page_length + insert_length <= max_page_length);
+ DBUG_PRINT("redo", ("key_op_add_suffix: %u", insert_length));
+ DBUG_ASSERT(page_length + insert_length <= max_page_size);
memcpy(buff + page_length, header+2, insert_length);
page_length+= insert_length;
@@ -1003,13 +1064,22 @@ uint _ma_apply_redo_index(MARIA_HA *info,
if (crc != (uint32) my_checksum(0, buff + LSN_STORE_SIZE,
page_length - LSN_STORE_SIZE))
{
- DBUG_PRINT("error", ("page_length %u",page_length));
- DBUG_DUMP("KEY_OP_CHECK bad page", buff, max_page_length);
- DBUG_ASSERT("crc" == "failure in REDO_INDEX");
+ DBUG_DUMP("KEY_OP_CHECK bad page", buff, page_length);
+ if (header + 6 + page_length <= header_end)
+ {
+ DBUG_DUMP("KEY_OP_CHECK org page", header + 6, page_length);
+ }
+ DBUG_ASSERT("crc failure in REDO_INDEX" == 0);
}
#endif
DBUG_PRINT("redo", ("key_op_check"));
- header+= 6;
+ /*
+ This is the last entry in the block and it can contain page_length
+ data or not
+ */
+ DBUG_ASSERT(header + 6 == header_end ||
+ header + 6 + page_length == header_end);
+ header= header_end;
break;
}
case KEY_OP_DEBUG:
@@ -1018,7 +1088,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
break;
case KEY_OP_MAX_PAGELENGTH:
DBUG_PRINT("redo", ("key_op_max_page_length"));
- page_length= max_page_length;
+ page_length= max_page_size;
break;
case KEY_OP_MULTI_COPY: /* 9 */
{
@@ -1040,7 +1110,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
log_memcpy_length= uint2korr(header);
header+= 2;
log_memcpy_end= header + log_memcpy_length;
- DBUG_ASSERT(full_length <= max_page_length);
+ DBUG_ASSERT(full_length <= max_page_size);
while (header < log_memcpy_end)
{
uint to, from;
@@ -1049,7 +1119,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
from= uint2korr(header);
header+= 2;
/* "from" is a place in the existing page */
- DBUG_ASSERT(max(from, to) < max_page_length);
+ DBUG_ASSERT(max(from, to) < max_page_size);
memcpy(buff + to, buff + from, full_length);
}
break;
diff --git a/storage/maria/ma_key_recover.h b/storage/maria/ma_key_recover.h
index 30830f7d82c..3fdb045ee40 100644
--- a/storage/maria/ma_key_recover.h
+++ b/storage/maria/ma_key_recover.h
@@ -64,17 +64,26 @@ extern my_bool write_hook_for_undo_key_delete(enum translog_record_type type,
TRN *trn, MARIA_HA *tbl_info,
LSN *lsn, void *hook_arg);
-my_bool _ma_log_prefix(MARIA_PAGE *page, uint changed_length, int move_length);
+my_bool _ma_log_prefix(MARIA_PAGE *page, uint changed_length, int move_length,
+ enum en_key_debug debug_marker);
my_bool _ma_log_suffix(MARIA_PAGE *page, uint org_length,
uint new_length);
my_bool _ma_log_add(MARIA_PAGE *page, uint buff_length, uchar *key_pos,
uint changed_length, int move_length,
my_bool handle_overflow);
my_bool _ma_log_delete(MARIA_PAGE *page, const uchar *key_pos,
- uint changed_length, uint move_length);
+ uint changed_length, uint move_length,
+ uint append_length, enum en_key_debug debug_marker);
my_bool _ma_log_change(MARIA_PAGE *page, const uchar *key_pos, uint length,
enum en_key_debug debug_marker);
my_bool _ma_log_new(MARIA_PAGE *page, my_bool root_page);
+#ifdef EXTRA_DEBUG_KEY_CHANGES
+void _ma_log_key_changes(MARIA_PAGE *ma_page, LEX_CUSTRING *log_array,
+ uchar *log_pos, uint *changed_length,
+ uint *translog_parts);
+#else
+#define _ma_log_key_changes(A,B,C,D,E)
+#endif
uint _ma_apply_redo_index_new_page(MARIA_HA *info, LSN lsn,
const uchar *header, uint length);
diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h
index 5ef98244b76..7bb38e628da 100644
--- a/storage/maria/ma_loghandler.h
+++ b/storage/maria/ma_loghandler.h
@@ -172,13 +172,24 @@ enum en_key_op
enum en_key_debug
{
- KEY_OP_DEBUG_RTREE_COMBINE,
- KEY_OP_DEBUG_RTREE_SPLIT,
- KEY_OP_DEBUG_RTREE_SET_KEY,
- KEY_OP_DEBUG_FATHER_CHANGED_1,
- KEY_OP_DEBUG_FATHER_CHANGED_2,
- KEY_OP_DEBUG_LOG_SPLIT,
- KEY_OP_DEBUG_LOG_ADD
+ KEY_OP_DEBUG_RTREE_COMBINE, /* 0 */
+ KEY_OP_DEBUG_RTREE_SPLIT, /* 1 */
+ KEY_OP_DEBUG_RTREE_SET_KEY, /* 2 */
+ KEY_OP_DEBUG_FATHER_CHANGED_1, /* 3 */
+ KEY_OP_DEBUG_FATHER_CHANGED_2, /* 4 */
+ KEY_OP_DEBUG_LOG_SPLIT, /* 5 */
+ KEY_OP_DEBUG_LOG_ADD, /* 6 */
+ KEY_OP_DEBUG_LOG_PREFIX_1, /* 7 */
+ KEY_OP_DEBUG_LOG_PREFIX_2, /* 8 */
+ KEY_OP_DEBUG_LOG_PREFIX_3, /* 9 */
+ KEY_OP_DEBUG_LOG_PREFIX_4, /* 10 */
+ KEY_OP_DEBUG_LOG_PREFIX_5, /* 11 */
+ KEY_OP_DEBUG_LOG_DEL_CHANGE_1, /* 12 */
+ KEY_OP_DEBUG_LOG_DEL_CHANGE_2, /* 13 */
+ KEY_OP_DEBUG_LOG_DEL_CHANGE_3, /* 14 */
+ KEY_OP_DEBUG_LOG_DEL_CHANGE_RT, /* 15 */
+ KEY_OP_DEBUG_LOG_DEL_PREFIX, /* 16 */
+ KEY_OP_DEBUG_LOG_MIDDLE /* 17 */
};
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index a43513cfaa0..39c13e27e15 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -550,6 +550,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
strmov(share->open_file_name.str, name);
share->block_size= share->base.block_size; /* Convenience */
+ share->max_index_block_size= share->block_size - KEYPAGE_CHECKSUM_SIZE;
{
HA_KEYSEG *pos=share->keyparts;
uint32 ftkey_nr= 1;
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index acbee2a6f07..a4423133270 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -59,6 +59,7 @@ void _ma_page_setup(MARIA_PAGE *page, MARIA_HA *info,
page->buff= buff;
page->pos= pos;
page->size= _ma_get_page_used(share, buff);
+ page->org_size= page->size;
page->flag= _ma_get_keypage_flag(share, buff);
page->node= ((page->flag & KEYPAGE_FLAG_ISNOD) ?
share->base.key_reflength : 0);
@@ -68,7 +69,7 @@ void _ma_page_setup(MARIA_PAGE *page, MARIA_HA *info,
void page_cleanup(MARIA_SHARE *share, MARIA_PAGE *page)
{
uint length= page->size;
- DBUG_ASSERT(length <= block_size - KEYPAGE_CHECKSUM_SIZE);
+ DBUG_ASSERT(length <= share->max_index_block_size);
bzero(page->buff + length, share->block_size - length);
}
#endif
@@ -103,7 +104,7 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
MARIA_SHARE *share= info->s;
uint block_size= share->block_size;
DBUG_ENTER("_ma_fetch_keypage");
- DBUG_PRINT("enter",("pos: %ld", (long) pos));
+ DBUG_PRINT("enter",("page: %lu", (ulong) (pos / block_size)));
tmp= pagecache_read(share->pagecache, &share->kfile,
(pgcache_page_no_t) (pos / block_size), level, buff,
@@ -142,6 +143,7 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
page->buff= tmp;
page->pos= pos;
page->size= _ma_get_page_used(share, tmp);
+ page->org_size= page->size; /* For debugging */
page->flag= _ma_get_keypage_flag(share, tmp);
page->node= ((page->flag & KEYPAGE_FLAG_ISNOD) ?
share->base.key_reflength : 0);
@@ -149,7 +151,7 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
#ifdef EXTRA_DEBUG
{
uint page_size= page->size;
- if (page_size < 4 || page_size > block_size ||
+ 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",
@@ -159,7 +161,7 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
info->last_keypage = HA_OFFSET_ERROR;
maria_print_error(share, HA_ERR_CRASHED);
my_errno= HA_ERR_CRASHED;
- tmp= 0;
+ DBUG_RETURN(1);
}
}
#endif
@@ -179,6 +181,13 @@ my_bool _ma_write_keypage(MARIA_PAGE *page, enum pagecache_page_lock lock,
MARIA_PINNED_PAGE page_link;
DBUG_ENTER("_ma_write_keypage");
+ /*
+ The following ensures that for transactional tables we have logged
+ all changes that changes the page size (as the logging code sets
+ page->org_size)
+ */
+ DBUG_ASSERT(!share->now_transactional || page->size == page->org_size);
+
#ifdef EXTRA_DEBUG /* Safety check */
{
uint page_length, nod_flag;
@@ -193,7 +202,7 @@ my_bool _ma_write_keypage(MARIA_PAGE *page, enum pagecache_page_lock lock,
(page->pos & (maria_block_size-1)))
{
DBUG_PRINT("error",("Trying to write inside key status region: "
- "key_start: %lu length: %lu page: %lu",
+ "key_start: %lu length: %lu page_pos: %lu",
(long) share->base.keystart,
(long) share->state.state.key_file_length,
(long) page->pos));
@@ -201,7 +210,7 @@ my_bool _ma_write_keypage(MARIA_PAGE *page, enum pagecache_page_lock lock,
DBUG_ASSERT(0);
DBUG_RETURN(1);
}
- DBUG_PRINT("page",("write page at: %lu",(long) page->pos));
+ DBUG_PRINT("page",("write page at: %lu",(ulong) (page->pos / block_size)));
DBUG_DUMP("buff", buff, page_length);
DBUG_ASSERT(page_length >= share->keypage_header + nod_flag +
page->keyinfo->minlength || maria_in_recovery);
@@ -274,7 +283,7 @@ int _ma_dispose(register MARIA_HA *info, my_off_t pos, my_bool page_not_read)
enum pagecache_page_lock lock_method;
enum pagecache_page_pin pin_method;
DBUG_ENTER("_ma_dispose");
- DBUG_PRINT("enter",("pos: %ld", (long) pos));
+ DBUG_PRINT("enter",("page: %lu", (ulong) (pos / block_size)));
DBUG_ASSERT(pos % block_size == 0);
(void) _ma_lock_key_del(info, 0);
@@ -423,8 +432,7 @@ my_off_t _ma_new(register MARIA_HA *info, int level,
share->key_del_current= mi_sizekorr(buff+share->keypage_header);
#ifndef DBUG_OFF
key_del_current= share->key_del_current;
- DBUG_ASSERT(key_del_current != share->state.key_del &&
- (key_del_current != 0) &&
+ DBUG_ASSERT((key_del_current != 0) &&
((key_del_current == HA_OFFSET_ERROR) ||
(key_del_current <=
(share->state.state.key_file_length - block_size))));
@@ -453,32 +461,48 @@ my_off_t _ma_new(register MARIA_HA *info, int level,
Log compactation of a index page
*/
-static my_bool _ma_log_compact_keypage(MARIA_HA *info, my_off_t page,
+static my_bool _ma_log_compact_keypage(MARIA_PAGE *ma_page,
TrID min_read_from)
{
LSN lsn;
- uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 1 + TRANSID_SIZE];
+ uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 1 + 7 + TRANSID_SIZE];
+ uchar *log_pos;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
+ MARIA_HA *info= ma_page->info;
MARIA_SHARE *share= info->s;
+ uint translog_parts, extra_length;
+ my_off_t page= ma_page->pos;
DBUG_ENTER("_ma_log_compact_keypage");
- DBUG_PRINT("enter", ("page: %lu", (ulong) page));
+ DBUG_PRINT("enter", ("page: %lu", (ulong) (page / share->block_size)));
/* Store address of new root page */
page/= share->block_size;
page_store(log_data + FILEID_STORE_SIZE, page);
- log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE]= KEY_OP_COMPACT_PAGE;
- transid_store(log_data + FILEID_STORE_SIZE + PAGE_STORE_SIZE +1,
- min_read_from);
+ log_pos= log_data + FILEID_STORE_SIZE + PAGE_STORE_SIZE;
+
+ log_pos[0]= KEY_OP_COMPACT_PAGE;
+ transid_store(log_pos + 1, min_read_from);
+ log_pos+= 1 + TRANSID_SIZE;
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
- log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
+ log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos -
+ log_data);
+ translog_parts= 1;
+ extra_length= 0;
+
+ _ma_log_key_changes(ma_page,
+ log_array + TRANSLOG_INTERNAL_PARTS + translog_parts,
+ log_pos, &extra_length, &translog_parts);
+ /* Remember new page length for future log entires for same page */
+ ma_page->org_size= ma_page->size;
if (translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
- (translog_size_t) sizeof(log_data),
- TRANSLOG_INTERNAL_PARTS + 1, log_array,
- log_data, NULL))
+ log_array[TRANSLOG_INTERNAL_PARTS +
+ 0].length + extra_length,
+ TRANSLOG_INTERNAL_PARTS + translog_parts,
+ log_array, log_data, NULL))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
@@ -526,7 +550,7 @@ my_bool _ma_compact_keypage(MARIA_PAGE *ma_page, TrID min_read_from)
{
if (!(page= (*ma_page->keyinfo->skip_key)(&key, 0, 0, page)))
{
- DBUG_PRINT("error",("Couldn't find last key: page: 0x%lx",
+ DBUG_PRINT("error",("Couldn't find last key: page_pos: 0x%lx",
(long) page));
maria_print_error(share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
@@ -588,7 +612,7 @@ my_bool _ma_compact_keypage(MARIA_PAGE *ma_page, TrID min_read_from)
if (share->now_transactional)
{
- if (_ma_log_compact_keypage(info, ma_page->pos, min_read_from))
+ if (_ma_log_compact_keypage(ma_page, min_read_from))
DBUG_RETURN(1);
}
DBUG_RETURN(0);
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index a10fac9a15d..b4fe96ae168 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -332,6 +332,8 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn,
if (end_lsn != LSN_IMPOSSIBLE)
{
abort_message_printed= 1;
+ if (!trace_file)
+ fputc('\n', stderr);
my_message(HA_ERR_INITIALIZATION,
"Maria recovery aborted as end_lsn/end of file was reached",
MYF(0));
@@ -502,9 +504,13 @@ end:
}
if (error && !abort_message_printed)
+ {
+ if (!trace_file)
+ fputc('\n', stderr);
my_message(HA_ERR_INITIALIZATION,
"Maria recovery failed. Please run maria_chk -r on all maria "
"tables and delete all maria_log.######## files", MYF(0));
+ }
procent_printed= 0;
/*
We don't cleanly close tables if we hit some error (may corrupt them by
@@ -545,7 +551,7 @@ static int display_and_apply_record(const LOG_DESC *log_desc,
if (log_desc->record_execute_in_redo_phase == NULL)
{
/* die on all not-yet-handled records :) */
- DBUG_ASSERT("one more hook" == "to write");
+ DBUG_ASSERT("one more hook to write" == 0);
return 1;
}
if ((error= (*log_desc->record_execute_in_redo_phase)(rec)))
@@ -638,6 +644,20 @@ prototype_redo_exec_hook(INCOMPLETE_LOG)
/* no such table, don't need to warn */
return 0;
}
+
+ if (maria_is_crashed(info))
+ return 0;
+
+ if (info->s->state.is_of_horizon > rec->lsn)
+ {
+ /*
+ This table was repaired at a time after this log entry.
+ We can assume that all rows was inserted sucessfully and we don't
+ have to warn about that the inserted data was not logged
+ */
+ return 0;
+ }
+
/*
Example of what can go wrong when replaying DDLs:
CREATE TABLE t (logged); INSERT INTO t VALUES(1) (logged);
@@ -658,10 +678,15 @@ prototype_redo_exec_hook(INCOMPLETE_LOG)
there was a crash during a DDL (see comment in execution of
REDO_RENAME_TABLE ).
*/
- tprint(tracef, "***WARNING: MySQL server currently logs no records"
- " about insertion of data by ALTER TABLE and CREATE SELECT,"
- " as they are not necessary for recovery;"
- " present applying of log records may well not work.***\n");
+
+ eprint(tracef, "***WARNING: Aria engine currently logs no records "
+ "about insertion of data by ALTER TABLE and CREATE SELECT, "
+ "as they are not necessary for recovery; "
+ "present applying of log records to table '%s' may well not work."
+ "***", info->s->index_file_name.str);
+
+ /* Prevent using the table for anything else than undo repair */
+ _ma_mark_file_crashed(info->s);
recovery_warnings++;
return 0;
}
@@ -1052,7 +1077,11 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE)
}
if ((info= get_MARIA_HA_from_REDO_record(rec)) == NULL)
DBUG_RETURN(0);
-
+ if (maria_is_crashed(info))
+ {
+ tprint(tracef, "we skip repairing crashed table\n");
+ DBUG_RETURN(0);
+ }
/*
Otherwise, the mapping is newer than the table, and our record is newer
than the mapping, so we can repair.
@@ -1063,6 +1092,7 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE)
param.isam_file_name= name= info->s->open_file_name.str;
param.testflag= uint8korr(rec->header + FILEID_STORE_SIZE);
param.tmpdir= maria_tmpdir;
+ param.max_trid= max_long_trid;
DBUG_ASSERT(maria_tmpdir);
info->s->state.key_map= uint8korr(rec->header + FILEID_STORE_SIZE + 8);
@@ -1366,7 +1396,8 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_HEAD)
int error= 1;
uchar *buff= NULL;
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
+
{
/*
Table was skipped at open time (because later dropped/renamed, not
@@ -1432,7 +1463,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_TAIL)
int error= 1;
uchar *buff;
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
return 0;
enlarge_buffer(rec);
if (log_record_buffer.str == NULL ||
@@ -1473,7 +1504,7 @@ prototype_redo_exec_hook(REDO_INSERT_ROW_BLOBS)
pgcache_page_no_t first_page, last_page;
char llbuf1[22], llbuf2[22];
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
return 0;
enlarge_buffer(rec);
if (log_record_buffer.str == NULL ||
@@ -1507,7 +1538,7 @@ prototype_redo_exec_hook(REDO_PURGE_ROW_HEAD)
{
int error= 1;
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
return 0;
if (_ma_apply_redo_purge_row_head_or_tail(info, current_group_end_lsn,
HEAD_PAGE,
@@ -1523,7 +1554,7 @@ prototype_redo_exec_hook(REDO_PURGE_ROW_TAIL)
{
int error= 1;
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
return 0;
if (_ma_apply_redo_purge_row_head_or_tail(info, current_group_end_lsn,
TAIL_PAGE,
@@ -1540,7 +1571,7 @@ prototype_redo_exec_hook(REDO_FREE_BLOCKS)
int error= 1;
uchar *buff;
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
return 0;
enlarge_buffer(rec);
@@ -1567,7 +1598,7 @@ prototype_redo_exec_hook(REDO_FREE_HEAD_OR_TAIL)
{
int error= 1;
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
return 0;
if (_ma_apply_redo_free_head_or_tail(info, current_group_end_lsn,
@@ -1599,7 +1630,7 @@ prototype_redo_exec_hook(REDO_INDEX)
{
int error= 1;
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
return 0;
enlarge_buffer(rec);
@@ -1625,7 +1656,7 @@ prototype_redo_exec_hook(REDO_INDEX_NEW_PAGE)
{
int error= 1;
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
return 0;
enlarge_buffer(rec);
@@ -1652,7 +1683,7 @@ prototype_redo_exec_hook(REDO_INDEX_FREE_PAGE)
{
int error= 1;
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
return 0;
if (_ma_apply_redo_index_free_page(info, current_group_end_lsn,
@@ -1668,7 +1699,7 @@ prototype_redo_exec_hook(REDO_BITMAP_NEW_PAGE)
{
int error= 1;
MARIA_HA *info= get_MARIA_HA_from_REDO_record(rec);
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
return 0;
enlarge_buffer(rec);
@@ -2114,7 +2145,7 @@ prototype_undo_exec_hook(UNDO_ROW_INSERT)
MARIA_SHARE *share;
const uchar *record_ptr;
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
{
/*
Unlike for REDOs, if the table was skipped it is abnormal; we have a
@@ -2170,7 +2201,7 @@ prototype_undo_exec_hook(UNDO_ROW_DELETE)
LSN previous_undo_lsn= lsn_korr(rec->header);
MARIA_SHARE *share;
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
{
skip_undo_record(previous_undo_lsn, trn);
return 0;
@@ -2209,7 +2240,7 @@ prototype_undo_exec_hook(UNDO_ROW_UPDATE)
LSN previous_undo_lsn= lsn_korr(rec->header);
MARIA_SHARE *share;
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
{
skip_undo_record(previous_undo_lsn, trn);
return 0;
@@ -2248,7 +2279,7 @@ prototype_undo_exec_hook(UNDO_KEY_INSERT)
LSN previous_undo_lsn= lsn_korr(rec->header);
MARIA_SHARE *share;
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
{
skip_undo_record(previous_undo_lsn, trn);
return 0;
@@ -2289,7 +2320,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE)
LSN previous_undo_lsn= lsn_korr(rec->header);
MARIA_SHARE *share;
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
{
skip_undo_record(previous_undo_lsn, trn);
return 0;
@@ -2330,7 +2361,7 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT)
LSN previous_undo_lsn= lsn_korr(rec->header);
MARIA_SHARE *share;
- if (info == NULL)
+ if (info == NULL || maria_is_crashed(info))
{
skip_undo_record(previous_undo_lsn, trn);
return 0;
@@ -2371,6 +2402,7 @@ prototype_undo_exec_hook(UNDO_BULK_INSERT)
LSN previous_undo_lsn= lsn_korr(rec->header);
MARIA_SHARE *share;
+ /* Here we don't check for crashed as we can undo the bulk insert */
if (info == NULL)
{
skip_undo_record(previous_undo_lsn, trn);
diff --git a/storage/maria/ma_rt_key.c b/storage/maria/ma_rt_key.c
index bc2c8f71f5d..2e204990a3b 100644
--- a/storage/maria/ma_rt_key.c
+++ b/storage/maria/ma_rt_key.c
@@ -91,7 +91,8 @@ int maria_rtree_delete_key(MARIA_PAGE *page, uchar *key, uint key_length)
page->size-= key_length_with_nod_flag;
page_store_size(share, page);
if (share->now_transactional &&
- _ma_log_delete(page, key_start, 0, key_length_with_nod_flag))
+ _ma_log_delete(page, key_start, 0, key_length_with_nod_flag,
+ 0, KEY_OP_DEBUG_LOG_DEL_CHANGE_RT))
return -1;
return 0;
}
diff --git a/storage/maria/ma_rt_split.c b/storage/maria/ma_rt_split.c
index 8f137c2e0cf..856edc60490 100644
--- a/storage/maria/ma_rt_split.c
+++ b/storage/maria/ma_rt_split.c
@@ -308,7 +308,7 @@ static my_bool _ma_log_rt_split(MARIA_PAGE *page,
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 1 + 2 + 1 + 2 + 2 + 7],
*log_pos;
- LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 5];
+ LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 6];
uint translog_parts, extra_length= 0;
my_off_t page_pos;
DBUG_ENTER("_ma_log_rt_split");
@@ -344,24 +344,11 @@ static my_bool _ma_log_rt_split(MARIA_PAGE *page,
translog_parts+= 2;
}
-#ifdef EXTRA_DEBUG_KEY_CHANGES
- {
- int page_length= page->size;
- ha_checksum crc;
- uchar *check_start= log_pos;
- crc= my_checksum(0, page->buff + LSN_STORE_SIZE,
- page_length - LSN_STORE_SIZE);
- log_pos[0]= KEY_OP_CHECK;
- log_pos++;
- int2store(log_pos, page_length);
- log_pos+= 2;
- int4store(log_pos, crc);
- log_pos+= 4;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= check_start;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
- translog_parts++;
- }
-#endif
+ _ma_log_key_changes(page,
+ log_array + TRANSLOG_INTERNAL_PARTS + translog_parts,
+ log_pos, &extra_length, &translog_parts);
+ /* Remember new page length for future log entires for same page */
+ page->org_size= page->size;
if (translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
diff --git a/storage/maria/ma_unique.c b/storage/maria/ma_unique.c
index bae58fd70cd..a90578c2162 100644
--- a/storage/maria/ma_unique.c
+++ b/storage/maria/ma_unique.c
@@ -68,8 +68,7 @@ my_bool _ma_check_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def, uchar *record,
DBUG_ASSERT(info->last_key.data_length == MARIA_UNIQUE_HASH_LENGTH);
if (_ma_search_next(info, &info->last_key, SEARCH_BIGGER,
info->s->state.key_root[def->key]) ||
- bcmp((char*) info->last_key.data, (char*) key_buff,
- MARIA_UNIQUE_HASH_LENGTH))
+ bcmp(info->last_key.data, key_buff, MARIA_UNIQUE_HASH_LENGTH))
{
info->page_changed= 1; /* Can't optimize read next */
info->cur_row.lastpos= lastpos;
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 6a5c2995ae5..c6718299d17 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -613,7 +613,7 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key,
MARIA_KEYDEF *keyinfo= key->keyinfo;
MARIA_PAGE page;
DBUG_ENTER("w_search");
- DBUG_PRINT("enter",("page: %ld", (long) page_pos));
+ DBUG_PRINT("enter", ("page: %lu", (ulong) (page_pos/keyinfo->block_length)));
if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
MARIA_MAX_KEY_BUFF*2)))
@@ -823,9 +823,9 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key,
Check if the new key fits totally into the the page
(anc_buff is big enough to contain a full page + one key)
*/
- if (a_length <= (uint) keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)
+ if (a_length <= share->max_index_block_size)
{
- if (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE - a_length < 32 &&
+ if (share->max_index_block_size - a_length < 32 &&
(keyinfo->flag & HA_FULLTEXT) && key_pos == endpos &&
share->base.key_reflength <= share->base.rec_reflength &&
share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))
@@ -885,9 +885,9 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0
}
else
{
- if (share->now_transactional &&
+ if (share->now_transactional &&
_ma_log_add(anc_page, org_anc_length,
- key_pos, s_temp.changed_length, t_length, 0))
+ key_pos, s_temp.changed_length, t_length, 1))
DBUG_RETURN(-1);
}
DBUG_RETURN(0); /* There is room on page */
@@ -1265,7 +1265,7 @@ static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
curr_keylength);
if ((right ? right_length : left_length) + curr_keylength <=
- (uint) keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)
+ share->max_index_block_size)
{
/* Enough space to hold all keys in the two buffers ; Balance bufferts */
new_left_length= share->keypage_header+nod_flag+(keys/2)*curr_keylength;
@@ -1320,7 +1320,8 @@ static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
start of page
*/
if (_ma_log_prefix(&next_page, 0,
- ((int) new_right_length - (int) right_length)))
+ ((int) new_right_length - (int) right_length),
+ KEY_OP_DEBUG_LOG_PREFIX_3))
goto err;
}
else
@@ -1383,7 +1384,8 @@ static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
*/
if (_ma_log_prefix(&next_page,
(uint) (new_right_length - right_length),
- (int) (new_right_length - right_length)))
+ (int) (new_right_length - right_length),
+ KEY_OP_DEBUG_LOG_PREFIX_4))
goto err;
}
else
@@ -1545,7 +1547,8 @@ static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
This contains the last 'extra_buff' from 'buff'
*/
if (_ma_log_prefix(&extra_page,
- 0, (int) (extra_buff_length - right_length)))
+ 0, (int) (extra_buff_length - right_length),
+ KEY_OP_DEBUG_LOG_PREFIX_5))
goto err;
/*
@@ -1891,6 +1894,9 @@ my_bool _ma_log_new(MARIA_PAGE *ma_page, my_bool root_page)
log_array[TRANSLOG_INTERNAL_PARTS + 1].str= ma_page->buff + LSN_STORE_SIZE;
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= page_length;
+ /* Remember new page length for future log entires for same page */
+ ma_page->org_size= ma_page->size;
+
if (translog_write_record(&lsn, LOGREC_REDO_INDEX_NEW_PAGE,
info->trn, info,
(translog_size_t)
@@ -1912,7 +1918,7 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length,
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 6 + 7], *log_pos;
- LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
+ LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
uint offset= (uint) (key_pos - ma_page->buff), translog_parts;
my_off_t page;
MARIA_HA *info= ma_page->info;
@@ -1921,6 +1927,7 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length,
DBUG_ASSERT(info->s->now_transactional);
DBUG_ASSERT(offset + length <= ma_page->size);
+ DBUG_ASSERT(ma_page->org_size == ma_page->size);
/* Store address of new root page */
page= ma_page->pos / info->s->block_size;
@@ -1944,21 +1951,9 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length,
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= length;
translog_parts= 2;
-#ifdef EXTRA_DEBUG_KEY_CHANGES
- {
- int page_length= ma_page->size;
- ha_checksum crc;
- crc= my_checksum(0, ma_page->buff + LSN_STORE_SIZE,
- page_length - LSN_STORE_SIZE);
- log_pos[0]= KEY_OP_CHECK;
- int2store(log_pos+1, page_length);
- int4store(log_pos+3, crc);
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
- log_pos+= 7;
- translog_parts++;
- }
-#endif
+ _ma_log_key_changes(ma_page,
+ log_array + TRANSLOG_INTERNAL_PARTS + translog_parts,
+ log_pos, &length, &translog_parts);
if (translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
@@ -1994,8 +1989,6 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length,
- Page is shortened from end
- Data is added to end of page
- Data added at front of page
-
-
*/
static my_bool _ma_log_split(MARIA_PAGE *ma_page,
@@ -2006,9 +1999,9 @@ static my_bool _ma_log_split(MARIA_PAGE *ma_page,
uint changed_length)
{
LSN lsn;
- uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 3+3+3+3+3+2 +7];
+ uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 2 + 3+3+3+3+3+2 +7];
uchar *log_pos;
- LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
+ LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 6];
uint offset= (uint) (key_pos - ma_page->buff);
uint translog_parts, extra_length;
MARIA_HA *info= ma_page->info;
@@ -2018,6 +2011,7 @@ static my_bool _ma_log_split(MARIA_PAGE *ma_page,
(ulong) ma_page->pos, org_length, new_length));
DBUG_ASSERT(changed_length >= data_length);
+ DBUG_ASSERT(org_length <= info->s->max_index_block_size);
log_pos= log_data + FILEID_STORE_SIZE;
page= ma_page->pos / info->s->block_size;
@@ -2029,6 +2023,10 @@ static my_bool _ma_log_split(MARIA_PAGE *ma_page,
(*log_pos++)= KEY_OP_DEBUG_LOG_SPLIT;
#endif
+ /* Store keypage_flag */
+ *log_pos++= KEY_OP_SET_PAGEFLAG;
+ *log_pos++= ma_page->buff[KEYPAGE_TRANSFLAG_OFFSET];
+
if (new_length <= offset || !key_pos)
{
/*
@@ -2053,6 +2051,11 @@ static my_bool _ma_log_split(MARIA_PAGE *ma_page,
*/
max_key_length= new_length - offset;
extra_length= min(key_length, max_key_length);
+ if (offset + move_length > new_length)
+ {
+ /* This is true when move_length includes changes for next packed key */
+ move_length= new_length - offset;
+ }
if ((int) new_length < (int) (org_length + move_length + data_length))
{
@@ -2115,21 +2118,12 @@ static my_bool _ma_log_split(MARIA_PAGE *ma_page,
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos -
log_data);
-#ifdef EXTRA_DEBUG_KEY_CHANGES
- {
- int page_length= ma_page->size;
- ha_checksum crc;
- crc= my_checksum(0, ma_page->buff + LSN_STORE_SIZE,
- page_length - LSN_STORE_SIZE);
- log_pos[0]= KEY_OP_CHECK;
- int2store(log_pos+1, page_length);
- int4store(log_pos+3, crc);
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
- extra_length+= 7;
- translog_parts++;
- }
-#endif
+
+ _ma_log_key_changes(ma_page,
+ log_array + TRANSLOG_INTERNAL_PARTS + translog_parts,
+ log_pos, &extra_length, &translog_parts);
+ /* Remember new page length for future log entires for same page */
+ ma_page->org_size= ma_page->size;
DBUG_RETURN(translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
@@ -2168,8 +2162,9 @@ static my_bool _ma_log_del_prefix(MARIA_PAGE *ma_page,
int move_length)
{
LSN lsn;
- uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 12 + 7], *log_pos;
- LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
+ uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 2 + 12 + 7];
+ uchar *log_pos;
+ LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
uint offset= (uint) (key_pos - ma_page->buff);
uint diff_length= org_length + move_length - new_length;
uint translog_parts, extra_length;
@@ -2180,6 +2175,7 @@ static my_bool _ma_log_del_prefix(MARIA_PAGE *ma_page,
(ulong) ma_page->pos, org_length, new_length));
DBUG_ASSERT((int) diff_length > 0);
+ DBUG_ASSERT(ma_page->size == new_length);
log_pos= log_data + FILEID_STORE_SIZE;
page= ma_page->pos / info->s->block_size;
@@ -2189,6 +2185,15 @@ static my_bool _ma_log_del_prefix(MARIA_PAGE *ma_page,
translog_parts= 1;
extra_length= 0;
+#ifdef EXTRA_DEBUG_KEY_CHANGES
+ *log_pos++= KEY_OP_DEBUG;
+ *log_pos++= KEY_OP_DEBUG_LOG_DEL_PREFIX;
+#endif
+
+ /* Store keypage_flag */
+ *log_pos++= KEY_OP_SET_PAGEFLAG;
+ *log_pos++= ma_page->buff[KEYPAGE_TRANSFLAG_OFFSET];
+
if (offset < diff_length + info->s->keypage_header)
{
/*
@@ -2236,21 +2241,11 @@ static my_bool _ma_log_del_prefix(MARIA_PAGE *ma_page,
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos -
log_data);
-#ifdef EXTRA_DEBUG_KEY_CHANGES
- {
- int page_length= ma_page->size;
- ha_checksum crc;
- crc= my_checksum(0, ma_page->buff + LSN_STORE_SIZE,
- page_length - LSN_STORE_SIZE);
- log_pos[0]= KEY_OP_CHECK;
- int2store(log_pos+1, page_length);
- int4store(log_pos+3, crc);
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
- extra_length+= 7;
- translog_parts++;
- }
-#endif
+ _ma_log_key_changes(ma_page,
+ log_array + TRANSLOG_INTERNAL_PARTS + translog_parts,
+ log_pos, &extra_length, &translog_parts);
+ /* Remember new page length for future log entires for same page */
+ ma_page->org_size= ma_page->size;
DBUG_RETURN(translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
@@ -2277,9 +2272,9 @@ static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page,
uint key_length, int move_length)
{
LSN lsn;
- uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3+5+3+3+3 + 7];
+ uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 2 + 3+5+3+3+3 + 7];
uchar *log_pos;
- LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 5];
+ LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 6];
uint key_offset;
uint translog_parts, extra_length;
my_off_t page;
@@ -2287,6 +2282,8 @@ static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page,
DBUG_ENTER("_ma_log_key_middle");
DBUG_PRINT("enter", ("page: %lu", (ulong) ma_page->pos));
+ DBUG_ASSERT(ma_page->size == new_length);
+
/* new place of key after changes */
key_pos+= data_added_first;
key_offset= (uint) (key_pos - ma_page->buff);
@@ -2314,6 +2311,15 @@ static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page,
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
+#ifdef EXTRA_DEBUG_KEY_CHANGES
+ *log_pos++= KEY_OP_DEBUG;
+ *log_pos++= KEY_OP_DEBUG_LOG_MIDDLE;
+#endif
+
+ /* Store keypage_flag */
+ *log_pos++= KEY_OP_SET_PAGEFLAG;
+ *log_pos++= ma_page->buff[KEYPAGE_TRANSFLAG_OFFSET];
+
log_pos[0]= KEY_OP_DEL_SUFFIX;
int2store(log_pos+1, data_deleted_last);
log_pos+= 3;
@@ -2362,21 +2368,11 @@ static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page,
key_length);
}
-#ifdef EXTRA_DEBUG_KEY_CHANGES
- {
- int page_length= ma_page->size;
- ha_checksum crc;
- crc= my_checksum(0, ma_page->buff + LSN_STORE_SIZE,
- page_length - LSN_STORE_SIZE);
- log_pos[0]= KEY_OP_CHECK;
- int2store(log_pos+1, page_length);
- int4store(log_pos+3, crc);
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
- extra_length+= 7;
- translog_parts++;
- }
-#endif
+ _ma_log_key_changes(ma_page,
+ log_array + TRANSLOG_INTERNAL_PARTS + translog_parts,
+ log_pos, &extra_length, &translog_parts);
+ /* Remember new page length for future log entires for same page */
+ ma_page->org_size= ma_page->size;
DBUG_RETURN(translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
@@ -2401,14 +2397,17 @@ static my_bool _ma_log_middle(MARIA_PAGE *ma_page,
uint data_deleted_last)
{
LSN lsn;
- LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
- uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3 + 5], *log_pos;
+ LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
+ uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3 + 5 + 7], *log_pos;
MARIA_HA *info= ma_page->info;
my_off_t page;
uint translog_parts, extra_length;
DBUG_ENTER("_ma_log_middle");
DBUG_PRINT("enter", ("page: %lu", (ulong) page));
+ DBUG_ASSERT(ma_page->org_size + data_added_first - data_deleted_last ==
+ ma_page->size);
+
page= ma_page->page / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
@@ -2434,21 +2433,11 @@ static my_bool _ma_log_middle(MARIA_PAGE *ma_page,
translog_parts= 2;
extra_length= data_changed_first;
-#ifdef EXTRA_DEBUG_KEY_CHANGES
- {
- int page_length= ma_page->size;
- ha_checksum crc;
- crc= my_checksum(0, ma_page->buff + LSN_STORE_SIZE,
- page_length - LSN_STORE_SIZE);
- log_pos[0]= KEY_OP_CHECK;
- int2store(log_pos+1, page_length);
- int4store(log_pos+3, crc);
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].str= log_pos;
- log_array[TRANSLOG_INTERNAL_PARTS + translog_parts].length= 7;
- extra_length+= 7;
- translog_parts++;
- }
-#endif
+ _ma_log_key_changes(ma_page,
+ log_array + TRANSLOG_INTERNAL_PARTS + translog_parts,
+ log_pos, &extra_length, &translog_parts);
+ /* Remember new page length for future log entires for same page */
+ ma_page->org_size= ma_page->size;
DBUG_RETURN(translog_write_record(&lsn, LOGREC_REDO_INDEX,
info->trn, info,
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index f1454502bb1..6be34aae98c 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -39,6 +39,7 @@
#define SANITY_CHECKS 1
#ifdef EXTRA_DEBUG
#define EXTRA_DEBUG_KEY_CHANGES
+#define EXTRA_STORE_FULL_PAGE_IN_KEY_CHANGES
#endif
#define MAX_NONMAPPED_INSERTS 1000
@@ -243,7 +244,8 @@ typedef struct st_maria_file_bitmap
uchar *map;
pgcache_page_no_t page; /* Page number for current bitmap */
uint used_size; /* Size of bitmap head that is not 0 */
- my_bool changed; /* 1 if page needs to be flushed */
+ my_bool changed; /* 1 if page needs to be written */
+ my_bool changed_not_flushed; /* 1 if some bitmap is not flushed */
my_bool flush_all_requested; /**< If _ma_bitmap_flush_all waiting */
uint non_flushable; /**< 0 if bitmap and log are in sync */
PAGECACHE_FILE file; /* datafile where bitmap is stored */
@@ -361,6 +363,7 @@ typedef struct st_maria_share
uint in_trans; /* Number of references by trn */
uint w_locks, r_locks, tot_locks; /* Number of read/write locks */
uint block_size; /* block_size of keyfile & data file*/
+ uint max_index_block_size; /* block_size - end_of_page_info */
/* Fixed length part of a packed row in BLOCK_RECORD format */
uint base_length;
myf write_flag;
@@ -833,6 +836,7 @@ typedef struct st_maria_page
uchar *buff; /* Data for page */
my_off_t pos; /* Disk address to page */
uint size; /* Size of data on page */
+ uint org_size; /* Size of page at read or after log */
uint node; /* 0 or share->base.key_reflength */
uint flag; /* Page flag */
uint link_offset;
diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c
index 0dbc8ed7fb3..a87b2f0e55b 100644
--- a/storage/maria/trnman.c
+++ b/storage/maria/trnman.c
@@ -363,6 +363,7 @@ TRN *trnman_new_trn(WT_THD *wt)
trn->used_tables= 0;
trn->locked_tables= 0;
+ trn->flags= 0;
/*
only after the following function TRN is considered initialized,
diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c
index dae8fbe50a8..f08e9f32a3f 100644
--- a/storage/myisam/mi_dynrec.c
+++ b/storage/myisam/mi_dynrec.c
@@ -66,9 +66,12 @@ static int _mi_cmp_buffer(File file, const uchar *buff, my_off_t filepos,
my_bool mi_dynmap_file(MI_INFO *info, my_off_t size)
{
DBUG_ENTER("mi_dynmap_file");
- if (size > (my_off_t) (~((size_t) 0)))
+ if (size == 0 || size > (my_off_t) (~((size_t) 0)))
{
- DBUG_PRINT("warning", ("File is too large for mmap"));
+ if (size)
+ DBUG_PRINT("warning", ("File is too large for mmap"));
+ else
+ DBUG_PRINT("warning", ("Do not mmap zero-length"));
DBUG_RETURN(1);
}
/*
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index 860c9c57889..741b9b01986 100644
--- a/storage/myisam/mi_locking.c
+++ b/storage/myisam/mi_locking.c
@@ -29,7 +29,6 @@ int mi_lock_database(MI_INFO *info, int lock_type)
int error;
uint count;
MYISAM_SHARE *share=info->s;
- uint flag;
DBUG_ENTER("mi_lock_database");
DBUG_PRINT("enter",("lock_type: %d old lock %d r_locks: %u w_locks: %u "
"global_changed: %d open_count: %u name: '%s'",
@@ -48,7 +47,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
DBUG_RETURN(0);
}
- flag=error=0;
+ error= 0;
pthread_mutex_lock(&share->intern_lock);
if (share->kfile >= 0) /* May only be false on windows */
{
@@ -128,14 +127,12 @@ int mi_lock_database(MI_INFO *info, int lock_type)
{
if (share->r_locks)
{ /* Only read locks left */
- flag=1;
if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
error=my_errno;
}
else if (!share->w_locks)
{ /* No more locks */
- flag=1;
if (my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
error=my_errno;
@@ -156,7 +153,6 @@ int mi_lock_database(MI_INFO *info, int lock_type)
*/
if (share->w_locks == 1)
{
- flag=1;
if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
MYF(MY_SEEK_NOT_DONE)))
{
@@ -171,7 +167,6 @@ int mi_lock_database(MI_INFO *info, int lock_type)
}
if (!share->r_locks && !share->w_locks)
{
- flag=1;
if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
info->lock_wait | MY_SEEK_NOT_DONE))
{
@@ -196,7 +191,6 @@ int mi_lock_database(MI_INFO *info, int lock_type)
{ /* Change READONLY to RW */
if (share->r_locks == 1)
{
- flag=1;
if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
MYF(info->lock_wait | MY_SEEK_NOT_DONE)))
{
@@ -213,7 +207,6 @@ int mi_lock_database(MI_INFO *info, int lock_type)
{
if (!share->w_locks)
{
- flag=1;
if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
info->lock_wait | MY_SEEK_NOT_DONE))
{
@@ -260,11 +253,6 @@ int mi_lock_database(MI_INFO *info, int lock_type)
}
#endif
pthread_mutex_unlock(&share->intern_lock);
-#if defined(FULL_LOG) || defined(_lint)
- lock_type|=(int) (flag << 8); /* Set bit to set if real lock */
- myisam_log_command(MI_LOG_LOCK,info,(uchar*) &lock_type,sizeof(lock_type),
- error);
-#endif
DBUG_RETURN(error);
} /* mi_lock_database */
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 7436548c7e1..e4240dec90c 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -139,8 +139,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
my_errno= HA_ERR_NOT_A_TABLE;
goto err;
}
- if (memcmp((uchar*) share->state.header.file_version,
- (uchar*) myisam_file_magic, 4))
+ if (bcmp(share->state.header.file_version, myisam_file_magic, 4))
{
DBUG_PRINT("error",("Wrong header in %s",name_buff));
DBUG_DUMP("error_dump", share->state.header.file_version,
diff --git a/storage/myisam/mi_page.c b/storage/myisam/mi_page.c
index 17a5820d768..82acb801c90 100644
--- a/storage/myisam/mi_page.c
+++ b/storage/myisam/mi_page.c
@@ -49,7 +49,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
{
DBUG_PRINT("error",("page %lu had wrong page length: %u",
(ulong) page, page_size));
- DBUG_DUMP("page",tmp, keyinfo->block_length);
+ DBUG_DUMP("page", tmp, keyinfo->block_length);
info->last_keypage = HA_OFFSET_ERROR;
mi_print_error(info->s, HA_ERR_CRASHED);
my_errno = HA_ERR_CRASHED;
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index 03e0c72d7e0..52e28f8a5e9 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -819,7 +819,7 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
DBUG_PRINT("error",
("Found too long null packed key: %u of %u at 0x%lx",
length, keyseg->length, (long) *page_pos));
- DBUG_DUMP("key",*page_pos,16);
+ DBUG_DUMP("key", *page_pos, 16);
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
return 0;
@@ -876,7 +876,7 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
{
DBUG_PRINT("error",("Found too long packed key: %u of %u at 0x%lx",
length, keyseg->length, (long) *page_pos));
- DBUG_DUMP("key",*page_pos,16);
+ DBUG_DUMP("key", *page_pos, 16);
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
return 0; /* Error */
@@ -948,7 +948,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
DBUG_PRINT("error",
("Found too long binary packed key: %u of %u at 0x%lx",
length, keyinfo->maxlength, (long) *page_pos));
- DBUG_DUMP("key",*page_pos,16);
+ DBUG_DUMP("key", *page_pos, 16);
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0); /* Wrong key */
diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c
index 67da89e55ef..527c5e03a27 100644
--- a/storage/myisam/mi_test2.c
+++ b/storage/myisam/mi_test2.c
@@ -410,7 +410,7 @@ int main(int argc, char *argv[])
}
ant=0;
while (mi_rprev(file,read_record3,0) == 0 &&
- bcmp(read_record3+start,key,length) == 0) ant++;
+ memcmp(read_record3+start,key,length) == 0) ant++;
if (ant != dupp_keys)
{
printf("prev: Found: %d records of %d\n",ant,dupp_keys);
@@ -448,7 +448,7 @@ int main(int argc, char *argv[])
goto end;
}
if (mi_rlast(file,read_record2,0) ||
- bcmp(read_record2,read_record3,reclength))
+ memcmp(read_record2,read_record3,reclength))
{
printf("Can't find last record\n");
DBUG_DUMP("record2",(uchar*) read_record2,reclength);
@@ -463,7 +463,7 @@ int main(int argc, char *argv[])
printf("prev: I found: %d records of %d\n",ant,write_count);
goto end;
}
- if (bcmp(read_record,read_record3,reclength))
+ if (memcmp(read_record,read_record3,reclength))
{
printf("Can't find first record\n");
goto end;
@@ -478,7 +478,7 @@ int main(int argc, char *argv[])
mi_rprev(file,read_record3,0) == 0 ||
mi_rnext(file,read_record3,0))
goto err;
- if (bcmp(read_record,read_record3,reclength) != 0)
+ if (memcmp(read_record,read_record3,reclength) != 0)
printf("Can't find first record\n");
if (!silent)
@@ -490,7 +490,7 @@ int main(int argc, char *argv[])
mi_rnext(file,read_record3,0) == 0 ||
mi_rprev(file,read_record3,0))
goto err;
- if (bcmp(read_record2,read_record3,reclength))
+ if (memcmp(read_record2,read_record3,reclength))
printf("Can't find last record\n");
#ifdef NOT_ANYMORE
if (!silent)
@@ -504,7 +504,7 @@ int main(int argc, char *argv[])
bzero((char*) file->lastkey,file->s->base.max_key_length*2);
if (mi_rkey(file,read_record,0,key2,(uint) i,HA_READ_PREFIX))
goto err;
- if (bcmp(read_record+start,key,(uint) i))
+ if (memcmp(read_record+start,key,(uint) i))
{
puts("Didn't find right record");
goto end;
@@ -523,7 +523,7 @@ int main(int argc, char *argv[])
opt_delete++;
ant=1;
while (mi_rnext(file,read_record3,0) == 0 &&
- bcmp(read_record3+start,key,length) == 0) ant++;
+ memcmp(read_record3+start,key,length) == 0) ant++;
if (ant != dupp_keys-1)
{
printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-1);
@@ -541,7 +541,7 @@ int main(int argc, char *argv[])
opt_delete++;
ant=1;
while (mi_rprev(file,read_record3,0) == 0 &&
- bcmp(read_record3+start,key,length) == 0) ant++;
+ memcmp(read_record3+start,key,length) == 0) ant++;
if (ant != dupp_keys-2)
{
printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-2);
@@ -561,7 +561,7 @@ int main(int argc, char *argv[])
if (mi_rnext(file,read_record,0))
goto err; /* Skall finnas poster */
while (mi_rnext(file,read_record3,0) == 0 &&
- bcmp(read_record3+start,key,length) == 0) ant++;
+ memcmp(read_record3+start,key,length) == 0) ant++;
if (ant != dupp_keys-3)
{
printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-3);
@@ -576,7 +576,7 @@ int main(int argc, char *argv[])
opt_delete++;
ant=0;
while (mi_rprev(file,read_record3,0) == 0 &&
- bcmp(read_record3+start,key,length) == 0) ant++;
+ memcmp(read_record3+start,key,length) == 0) ant++;
if (ant != dupp_keys-4)
{
printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-4);
@@ -599,7 +599,7 @@ int main(int argc, char *argv[])
for (i=min(2,keys) ; i-- > 0 ;)
{
if (mi_rsame(file,read_record2,(int) i)) goto err;
- if (bcmp(read_record,read_record2,reclength) != 0)
+ if (memcmp(read_record,read_record2,reclength) != 0)
{
printf("mi_rsame didn't find same record\n");
goto end;
diff --git a/storage/myisam/mi_unique.c b/storage/myisam/mi_unique.c
index 02fcd9289dd..fdba84a2e67 100644
--- a/storage/myisam/mi_unique.c
+++ b/storage/myisam/mi_unique.c
@@ -56,7 +56,7 @@ my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, uchar *record,
if (_mi_search_next(info,info->s->keyinfo+def->key, info->lastkey,
MI_UNIQUE_HASH_LENGTH, SEARCH_BIGGER,
info->s->state.key_root[def->key]) ||
- bcmp((char*) info->lastkey, (char*) key_buff, MI_UNIQUE_HASH_LENGTH))
+ memcmp(info->lastkey, key_buff, MI_UNIQUE_HASH_LENGTH))
{
info->page_changed=1; /* Can't optimize read next */
info->lastpos=lastpos;
diff --git a/storage/myisam/rt_split.c b/storage/myisam/rt_split.c
index 88cf643faf9..03d22de68fa 100644
--- a/storage/myisam/rt_split.c
+++ b/storage/myisam/rt_split.c
@@ -255,7 +255,6 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
SplitStruct *stop;
double *coord_buf;
double *next_coord;
- double *old_coord;
int n_dim;
uchar *source_cur, *cur1, *cur2;
uchar *new_page= info->buff;
@@ -293,8 +292,6 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
rtree_d_mbr(keyinfo->seg, key, key_length, cur->coords);
cur->key = key;
- old_coord = next_coord;
-
if (split_rtree_node(task, max_keys + 1,
mi_getint(page) + full_length + 2, full_length,
rt_PAGE_MIN_SIZE(keyinfo->block_length),
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index c6e5c24590a..be3f0ca4813 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -295,8 +295,8 @@ static int myisammrg_parent_open_callback(void *callback_param,
}
}
- DBUG_PRINT("myrg", ("open: '%.*s'.'%.*s'", (int)(child_l->db_length),
- child_l->db, (int)(child_l->table_name_length),
+ DBUG_PRINT("myrg", ("open: '%.*s'.'%.*s'", (int) child_l->db_length,
+ child_l->db, (int) child_l->table_name_length,
child_l->table_name));
/* Convert to lowercase if required. */
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index ea306c5ba9c..17c9b4ba4d1 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -227,9 +227,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name,
int save_errno;
int insert_method;
uint length;
- uint dir_length;
uint child_count;
- size_t name_buff_length;
File fd;
IO_CACHE file_cache;
char parent_name_buff[FN_REFLEN * 2];
@@ -300,7 +298,6 @@ MYRG_INFO *myrg_parent_open(const char *parent_name,
}
/* Call callback for each child. */
- dir_length= dirname_part(parent_name_buff, parent_name, &name_buff_length);
my_b_seek(&file_cache, 0);
while ((length= my_b_gets(&file_cache, child_name_buff, FN_REFLEN - 1)))
{
@@ -380,7 +377,6 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
{
ulonglong file_offset;
MI_INFO *myisam;
- int rc;
int errpos;
int save_errno;
uint idx;
@@ -399,7 +395,6 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
here and in ha_myisammrg::store_lock() forces consistent data.
*/
pthread_mutex_lock(&m_info->mutex);
- rc= 1;
errpos= 0;
file_offset= 0;
min_keys= 0;
diff --git a/storage/ndb/src/common/portlib/NdbMutex.c b/storage/ndb/src/common/portlib/NdbMutex.c
index c9184e5d1f2..5595baba7c4 100644
--- a/storage/ndb/src/common/portlib/NdbMutex.c
+++ b/storage/ndb/src/common/portlib/NdbMutex.c
@@ -24,36 +24,31 @@ NdbMutex* NdbMutex_Create(void)
{
NdbMutex* pNdbMutex;
int result;
- DBUG_ENTER("NdbMutex_Create");
-
+
pNdbMutex = (NdbMutex*)NdbMem_Allocate(sizeof(NdbMutex));
- DBUG_PRINT("info",("NdbMem_Allocate 0x%lx", (long) pNdbMutex));
-
+
if (pNdbMutex == NULL)
- DBUG_RETURN(NULL);
-
+ return NULL;
+
result = pthread_mutex_init(pNdbMutex, NULL);
assert(result == 0);
-
- DBUG_RETURN(pNdbMutex);
+
+ return pNdbMutex;
}
int NdbMutex_Destroy(NdbMutex* p_mutex)
{
int result;
- DBUG_ENTER("NdbMutex_Destroy");
if (p_mutex == NULL)
- DBUG_RETURN(-1);
+ return -1;
result = pthread_mutex_destroy(p_mutex);
- DBUG_PRINT("info",("NdbMem_Free 0x%lx", (long) p_mutex));
NdbMem_Free(p_mutex);
-
- DBUG_RETURN(result);
+ return result;
}
diff --git a/storage/ndb/src/ndbapi/DictCache.cpp b/storage/ndb/src/ndbapi/DictCache.cpp
index 04be3711847..9c66b2be9d2 100644
--- a/storage/ndb/src/ndbapi/DictCache.cpp
+++ b/storage/ndb/src/ndbapi/DictCache.cpp
@@ -20,8 +20,10 @@
#include <NdbCondition.h>
#include <NdbSleep.h>
-static NdbTableImpl f_invalid_table;
-static NdbTableImpl f_altered_table;
+static NdbTableImpl * f_invalid_table = 0;
+static NdbTableImpl * f_altered_table = 0;
+
+static int ndb_dict_cache_count = 0;
Ndb_local_table_info *
Ndb_local_table_info::create(NdbTableImpl *table_impl, Uint32 sz)
@@ -93,11 +95,29 @@ GlobalDictCache::GlobalDictCache(){
DBUG_ENTER("GlobalDictCache::GlobalDictCache");
m_tableHash.createHashTable();
m_waitForTableCondition = NdbCondition_Create();
+ if (f_invalid_table == NULL)
+ f_invalid_table = new NdbTableImpl();
+ if (f_altered_table == NULL)
+ f_altered_table = new NdbTableImpl();
+ ndb_dict_cache_count++;
DBUG_VOID_RETURN;
}
GlobalDictCache::~GlobalDictCache(){
DBUG_ENTER("GlobalDictCache::~GlobalDictCache");
+ if (--ndb_dict_cache_count == 0)
+ {
+ if (f_invalid_table)
+ {
+ delete f_invalid_table;
+ f_invalid_table = 0;
+ }
+ if (f_altered_table)
+ {
+ delete f_altered_table;
+ f_altered_table = 0;
+ }
+ }
NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
while(curr != 0){
Vector<TableVersion> * vers = curr->theData;
@@ -254,7 +274,7 @@ GlobalDictCache::put(const char * name, NdbTableImpl * tab)
TableVersion & ver = vers->back();
if(ver.m_status != RETREIVING ||
!(ver.m_impl == 0 ||
- ver.m_impl == &f_invalid_table || ver.m_impl == &f_altered_table) ||
+ ver.m_impl == f_invalid_table || ver.m_impl == f_altered_table) ||
ver.m_version != 0 ||
ver.m_refCount == 0){
abort();
@@ -271,7 +291,7 @@ GlobalDictCache::put(const char * name, NdbTableImpl * tab)
ver.m_version = tab->m_version;
ver.m_status = OK;
}
- else if (ver.m_impl == &f_invalid_table)
+ else if (ver.m_impl == f_invalid_table)
{
DBUG_PRINT("info", ("Table DROPPED invalid"));
ver.m_impl = tab;
@@ -279,7 +299,7 @@ GlobalDictCache::put(const char * name, NdbTableImpl * tab)
ver.m_status = DROPPED;
ver.m_impl->m_status = NdbDictionary::Object::Invalid;
}
- else if(ver.m_impl == &f_altered_table)
+ else if(ver.m_impl == f_altered_table)
{
DBUG_PRINT("info", ("Table DROPPED altered"));
ver.m_impl = tab;
@@ -440,7 +460,7 @@ GlobalDictCache::alter_table_rep(const char * name,
if(i == sz - 1 && ver.m_status == RETREIVING)
{
- ver.m_impl = altered ? &f_altered_table : &f_invalid_table;
+ ver.m_impl = altered ? f_altered_table : f_invalid_table;
DBUG_VOID_RETURN;
}
}
diff --git a/storage/pbxt/src/Makefile.am b/storage/pbxt/src/Makefile.am
index fc4c4ef8f1e..20399aee484 100644
--- a/storage/pbxt/src/Makefile.am
+++ b/storage/pbxt/src/Makefile.am
@@ -40,8 +40,8 @@ libpbxt_la_LDFLAGS = -module
# These are the warning Drizzle uses:
# DRIZZLE_WARNINGS = -W -Wall -Wextra -pedantic -Wundef -Wredundant-decls -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter
-libpbxt_la_CXXFLAGS = $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
-libpbxt_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN -std=c99
+libpbxt_la_CXXFLAGS = -shared $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+libpbxt_la_CFLAGS = -shared $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN -std=c99
EXTRA_LIBRARIES = libpbxt.a
noinst_LIBRARIES = libpbxt.a
diff --git a/storage/xtradb/ChangeLog b/storage/xtradb/ChangeLog
index bc69aaca96a..5ebcf1e87a2 100644
--- a/storage/xtradb/ChangeLog
+++ b/storage/xtradb/ChangeLog
@@ -1,3 +1,128 @@
+2010-06-24 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#54679 alter table causes compressed row_format to revert
+ to compact
+
+2010-06-22 The InnoDB Team
+
+ * dict/dict0dict.c, dict/dict0mem.c, include/dict0mem.h,
+ include/univ.i, page/page0zip.c, row/row0merge.c:
+ Fix Bug#47991 InnoDB Dictionary Cache memory usage increases
+ indefinitely when renaming tables
+
+2010-06-22 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#54686: "field->col->mtype == type" assertion error at
+ row/row0sel.c
+
+2010-06-22 The InnoDB Team
+
+ * handler/ha_innodb.cc, innodb_bug54044.result, innodb_bug54044.test:
+ Fix Bug#54044 Create temporary tables and using innodb crashes.
+
+2010-06-21 The InnoDB Team
+
+ * dict/dict0load.c, fil/fil0fil.c:
+ Fix Bug#54658: InnoDB: Warning: allocated tablespace %lu,
+ old maximum was 0 (introduced in Bug #53578 fix)
+
+2010-06-16 The InnoDB Team
+
+ * row/row0merge.c:
+ Fix Bug#54330 Broken fast index creation
+
+2010-06-10 The InnoDB Team
+
+ * include/log0log.ic, row/row0ins.c, row/row0purge.c,
+ row/row0uins.c, row/row0umod.c, row/row0upd.c:
+ Fix Bug#39168 ERROR: the age of the last checkpoint ... exceeds
+ the log group capacity
+
+2010-06-08 The InnoDB Team
+
+ * dict/dict0load.c:
+ Fix Bug#54009 Server crashes when data is selected from non backed
+ up table for InnoDB plugin
+
+2010-06-02 The InnoDB Team
+
+ * include/db0err.h, include/lock0lock.h, include/row0mysql.h,
+ lock/lock0lock.c, row/row0ins.c, row/row0mysql.c, row/row0sel.c:
+ Fix Bug#53674 InnoDB: Error: unlock row could not find a
+ 4 mode lock on the record
+
+2010-06-01 The InnoDB Team
+
+ * include/sync0rw.h, sync/sync0rw.c:
+ Fix Bug#48197 Concurrent rw_lock_free may cause assertion failure
+
+2010-06-01 The InnoDB Team
+
+ * row/row0umod.c:
+ Fix Bug#53812 assert row/row0umod.c line 660 in txn rollback
+ after crash recovery
+
+2010-05-25 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c:
+ Fix Bug#53592: crash replacing duplicates into table after fast
+ alter table added unique key
+
+2010-05-24 The InnoDB Team
+
+ * dict/dict0boot.c, dict/dict0crea.c, fil/fil0fil.c,
+ include/dict0boot.h, include/fil0fil.h, row/row0mysql.c:
+ Fix Bug#53578: assert on invalid page access, in fil_io()
+
+2010-05-14 The InnoDB Team
+ * mysql-test/innodb_bug48024.test, mysql-test/innodb_bug48024.result,
+ dict/dict0dict.c, handler/ha_innodb.cc, handler/ha_innodb.h,
+ include/dict0dict.h, include/ha_prototypes.h, include/row0mysql.h,
+ include/trx0trx.h, row/row0mysql.c, trx/trx0i_s.c, trx/trx0trx.c:
+ Fix Bug#48024 Innodb doesn't work with multi-statements
+ Fix Bug#53644 InnoDB thinks that /*/ starts and ends a comment
+
+2010-05-12 The InnoDB Team
+
+ * handler/handler0alter.cc:
+ Fix Bug#53591 crash with fast alter table and text/blob prefix
+ primary key
+
+2010-05-12 The InnoDB Team
+
+ * row/row0merge.c:
+ Fix Bug#53471 row_merge_drop_temp_indexes() refers freed memory, SEGVs
+
+2010-05-11 The InnoDB Team
+
+ * mysql-test/innodb_bug53290.test, mysql-test/innodb_bug53290.result,
+ include/rem0cmp.h, rem/rem0cmp.c, row/row0merge.c:
+ Fix Bug#53290 wrong duplicate key error when adding a unique index
+ via fast alter table
+
+2010-05-11 The InnoDB Team
+ * buf/buf0lru.c, include/buf0buf.ic:
+ Fix Bug#53307 valgrind: warnings in main.partition_innodb_plugin
+
+2010-05-05 The InnoDB Team
+
+ * row/row0merge.c:
+ Fix Bug#53256 in a stress test, assert dict/dict0dict.c:815
+ table2 == NULL
+
+2010-05-05 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#53165 Setting innodb_change_buffering=DEFAULT produces
+ incorrect result
+
+2010-05-04 The InnoDB Team
+
+ * fsp/fsp0fsp.c:
+ Fix Bug#53306 valgrind: warnings in innodb.innodb
+
2010-05-03 The InnoDB Team
* buf0buf.c:
@@ -48,12 +173,6 @@
Only check the record size at index creation time when
innodb_strict_mode is set or when ROW_FORMAT is DYNAMIC or COMPRESSED.
-2010-04-20 The InnoDB Team
-
- * btr/btr0btr.c, include/univ.i:
- Implement UNIV_BTR_AVOID_COPY, for avoiding writes when a B-tree
- node is split at the first or last record.
-
2010-04-15 The InnoDB Team
* trx/trx0rec.c:
@@ -72,6 +191,10 @@
* mysql-test/innodb_bug38231.test:
Remove non-determinism in the test case.
+2010-03-29 The InnoDB Team
+
+ InnoDB Plugin 1.0.7 released
+
2010-03-18 The InnoDB Team
* CMakeLists.txt:
@@ -194,6 +317,14 @@
Fix Bug#49497 Error 1467 (ER_AUTOINC_READ_FAILED) on inserting
a negative value
+2010-01-28 The InnoDB Team
+ * handler/ha_innodb.h, handler/ha_innodb.cc,
+ handler/handler0alter.cc,
+ mysql-test/innodb_bug47622.test,
+ mysql-test/innodb_bug47622.result:
+ Fix Bug#47622 the new index is added before the existing ones
+ in MySQL, but after one in SE
+
2010-01-27 The InnoDB Team
* include/row0mysql.h, log/log0recv.c, row/row0mysql.c:
diff --git a/storage/xtradb/Makefile.am b/storage/xtradb/Makefile.am
index 172b9099568..3813b6602b8 100644
--- a/storage/xtradb/Makefile.am
+++ b/storage/xtradb/Makefile.am
@@ -333,8 +333,8 @@ EXTRA_LTLIBRARIES= ha_xtradb.la
pkgplugin_LTLIBRARIES= @plugin_xtradb_shared_target@
ha_xtradb_la_LDFLAGS= -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
-ha_xtradb_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
-ha_xtradb_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+ha_xtradb_la_CXXFLAGS= -shared $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+ha_xtradb_la_CFLAGS= -shared $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
ha_xtradb_la_SOURCES= $(libxtradb_a_SOURCES)
EXTRA_DIST= CMakeLists.txt plug.in \
diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c
index 12e57dcc490..ff047095aa4 100644
--- a/storage/xtradb/btr/btr0btr.c
+++ b/storage/xtradb/btr/btr0btr.c
@@ -2030,6 +2030,7 @@ func_start:
goto insert_empty;
}
} else if (UNIV_UNLIKELY(insert_left)) {
+ ut_a(n_iterations > 0);
first_rec = page_rec_get_next(page_get_infimum_rec(page));
move_limit = page_rec_get_next(btr_cur_get_rec(cursor));
} else {
@@ -2076,17 +2077,7 @@ insert_empty:
}
/* 5. Move then the records to the new page */
- if (direction == FSP_DOWN
-#ifdef UNIV_BTR_AVOID_COPY
- && page_rec_is_supremum(move_limit)) {
- /* Instead of moving all records, make the new page
- the empty page. */
-
- left_block = block;
- right_block = new_block;
- } else if (direction == FSP_DOWN
-#endif /* UNIV_BTR_AVOID_COPY */
- ) {
+ if (direction == FSP_DOWN) {
/* fputs("Split left\n", stderr); */
if (0
@@ -2129,14 +2120,6 @@ insert_empty:
right_block = block;
lock_update_split_left(right_block, left_block);
-#ifdef UNIV_BTR_AVOID_COPY
- } else if (!split_rec) {
- /* Instead of moving all records, make the new page
- the empty page. */
-
- left_block = new_block;
- right_block = block;
-#endif /* UNIV_BTR_AVOID_COPY */
} else {
/* fputs("Split right\n", stderr); */
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index 0e75b4e8442..9b87d969a64 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -2136,9 +2136,8 @@ any_extern:
err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
thr, mtr, &roll_ptr);
if (err != DB_SUCCESS) {
-err_exit:
- mem_heap_free(heap);
- return(err);
+
+ goto err_exit;
}
/* Ok, we may do the replacement. Store on the page infimum the
@@ -2184,9 +2183,10 @@ err_exit:
page_cur_move_to_next(page_cursor);
+ err = DB_SUCCESS;
+err_exit:
mem_heap_free(heap);
-
- return(DB_SUCCESS);
+ return(err);
}
/*************************************************************//**
@@ -4259,6 +4259,8 @@ btr_store_big_rec_extern_fields(
field_ref += local_len;
}
extern_len = big_rec_vec->fields[i].len;
+ UNIV_MEM_ASSERT_RW(big_rec_vec->fields[i].data,
+ extern_len);
ut_a(extern_len > 0);
@@ -4895,6 +4897,7 @@ btr_copy_blob_prefix(
mtr_commit(&mtr);
if (page_no == FIL_NULL || copy_len != part_len) {
+ UNIV_MEM_ASSERT_RW(buf, copied_len);
return(copied_len);
}
@@ -5078,6 +5081,7 @@ btr_copy_externally_stored_field_prefix_low(
space_id, page_no, offset);
inflateEnd(&d_stream);
mem_heap_free(heap);
+ UNIV_MEM_ASSERT_RW(buf, d_stream.total_out);
return(d_stream.total_out);
} else {
return(btr_copy_blob_prefix(buf, len, space_id,
diff --git a/storage/xtradb/btr/btr0sea.c b/storage/xtradb/btr/btr0sea.c
index 61909903a67..36dadd47e69 100644
--- a/storage/xtradb/btr/btr0sea.c
+++ b/storage/xtradb/btr/btr0sea.c
@@ -182,6 +182,7 @@ void
btr_search_sys_free(void)
/*=====================*/
{
+ rw_lock_free(&btr_search_latch);
mem_free(btr_search_latch_temp);
btr_search_latch_temp = NULL;
mem_heap_free(btr_search_sys->hash_index->heap);
diff --git a/storage/xtradb/buf/buf0buddy.c b/storage/xtradb/buf/buf0buddy.c
index e4a79026d3a..e6b80bcda55 100644
--- a/storage/xtradb/buf/buf0buddy.c
+++ b/storage/xtradb/buf/buf0buddy.c
@@ -452,6 +452,8 @@ buf_buddy_relocate(
buf_page_t* bpage;
const ulint size = BUF_BUDDY_LOW << i;
ullint usec = ut_time_us(NULL);
+ ulint space;
+ ulint page_no;
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&zip_free_mutex));
@@ -490,11 +492,15 @@ buf_buddy_relocate(
pool), so there is nothing wrong about this. The
mach_read_from_4() calls here will only trigger bogus
Valgrind memcheck warnings in UNIV_DEBUG_VALGRIND builds. */
- bpage = buf_page_hash_get(
- mach_read_from_4((const byte*) src
- + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID),
- mach_read_from_4((const byte*) src
- + FIL_PAGE_OFFSET));
+ space = mach_read_from_4(
+ (const byte*) src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ page_no = mach_read_from_4(
+ (const byte*) src + FIL_PAGE_OFFSET);
+ /* Suppress Valgrind warnings about conditional jump
+ on uninitialized value. */
+ UNIV_MEM_VALID(&space, sizeof space);
+ UNIV_MEM_VALID(&page_no, sizeof page_no);
+ bpage = buf_page_hash_get(space, page_no);
if (!bpage || bpage->zip.data != src) {
/* The block has probably been freshly
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index a5a9e1d9004..94a67c1759c 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -53,6 +53,10 @@ Created 11/5/1995 Heikki Tuuri
#include "page0zip.h"
#include "trx0trx.h"
#include "srv0start.h"
+#include "que0que.h"
+#include "read0read.h"
+#include "row0row.h"
+#include "ha_prototypes.h"
/* prototypes for new functions added to ha_innodb.cc */
trx_t* innobase_get_trx();
@@ -78,9 +82,9 @@ inline void _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
block_hash_byte = block_hash >> 3;
block_hash_offset = (byte) block_hash & 0x07;
if (block_hash_byte >= DPAH_SIZE)
- fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %lu !!!\n", (unsigned long) block_hash_byte, (unsigned long) block_hash_offset);
+ fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %d !!!\n", block_hash_byte, block_hash_offset);
if (block_hash_offset > 7)
- fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %lu !!!\n", (unsigned long) block_hash_byte, (unsigned long) block_hash_offset);
+ fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %d !!!\n", block_hash_byte, block_hash_offset);
if ((trx->distinct_page_access_hash[block_hash_byte] & ((byte) 0x01 << block_hash_offset)) == 0)
trx->distinct_page_access++;
trx->distinct_page_access_hash[block_hash_byte] |= (byte) 0x01 << block_hash_offset;
@@ -310,14 +314,30 @@ read-ahead or flush occurs */
UNIV_INTERN ibool buf_debug_prints = FALSE;
#endif /* UNIV_DEBUG */
-/** A chunk of buffers. The buffer pool is allocated in chunks. */
-struct buf_chunk_struct{
- ulint mem_size; /*!< allocated size of the chunk */
- ulint size; /*!< size of frames[] and blocks[] */
- void* mem; /*!< pointer to the memory area which
- was allocated for the frames */
- buf_block_t* blocks; /*!< array of buffer control blocks */
+/* Buffer pool shared memory segment information */
+typedef struct buf_shm_info_struct buf_shm_info_t;
+
+struct buf_shm_info_struct {
+ char head_str[8];
+ ulint binary_id;
+ ibool is_new; /* during initializing */
+ ibool clean; /* clean shutdowned and free */
+ ibool reusable; /* reusable */
+ ulint buf_pool_size; /* backup value */
+ ulint page_size; /* backup value */
+ ulint frame_offset; /* offset of the first frame based on chunk->mem */
+ ulint zip_hash_offset;
+ ulint zip_hash_n;
+
+ ulint checksum;
+
+ buf_pool_t buf_pool_backup;
+ buf_chunk_t chunk_backup;
+
+ ib_uint64_t dummy;
};
+
+#define BUF_SHM_INFO_HEAD "XTRA_SHM"
#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
@@ -764,6 +784,45 @@ buf_block_init(
#endif /* UNIV_SYNC_DEBUG */
}
+static
+void
+buf_block_reuse(
+/*============*/
+ buf_block_t* block,
+ ptrdiff_t frame_offset)
+{
+ /* block_init */
+ block->frame = ((byte*)(block->frame) + frame_offset);
+
+ UNIV_MEM_DESC(block->frame, UNIV_PAGE_SIZE, block);
+
+ block->index = NULL;
+
+#ifdef UNIV_DEBUG
+ /* recreate later */
+ block->page.in_page_hash = FALSE;
+ block->page.in_zip_hash = FALSE;
+#endif /* UNIV_DEBUG */
+
+#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+ block->n_pointers = 0;
+#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+
+ if (block->page.zip.data)
+ block->page.zip.data = ((byte*)(block->page.zip.data) + frame_offset);
+
+ block->is_hashed = FALSE;
+
+ mutex_create(&block->mutex, SYNC_BUF_BLOCK);
+
+ rw_lock_create(&block->lock, SYNC_LEVEL_VARYING);
+ ut_ad(rw_lock_validate(&(block->lock)));
+
+#ifdef UNIV_SYNC_DEBUG
+ rw_lock_create(&block->debug_latch, SYNC_NO_ORDER_CHECK);
+#endif /* UNIV_SYNC_DEBUG */
+}
+
/********************************************************************//**
Allocates a chunk of buffer frames.
@return chunk, or NULL on failure */
@@ -776,26 +835,167 @@ buf_chunk_init(
{
buf_block_t* block;
byte* frame;
+ ulint zip_hash_n = 0;
+ ulint zip_hash_mem_size = 0;
+ hash_table_t* zip_hash_tmp = NULL;
ulint i;
+ buf_shm_info_t* shm_info = NULL;
/* Round down to a multiple of page size,
although it already should be. */
mem_size = ut_2pow_round(mem_size, UNIV_PAGE_SIZE);
+
+ if (srv_buffer_pool_shm_key) {
+ /* zip_hash size */
+ zip_hash_n = (mem_size / UNIV_PAGE_SIZE) * 2;
+ zip_hash_mem_size = ut_2pow_round(hash_create_needed(zip_hash_n)
+ + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
+ }
+
/* Reserve space for the block descriptors. */
mem_size += ut_2pow_round((mem_size / UNIV_PAGE_SIZE) * (sizeof *block)
+ (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
+ if (srv_buffer_pool_shm_key) {
+ mem_size += ut_2pow_round(sizeof(buf_shm_info_t)
+ + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
+ mem_size += zip_hash_mem_size;
+ }
chunk->mem_size = mem_size;
+
+ if (srv_buffer_pool_shm_key) {
+ ulint binary_id;
+ ibool is_new;
+
+ ut_a(buf_pool->n_chunks == 1);
+
+ fprintf(stderr,
+ "InnoDB: Notice: innodb_buffer_pool_shm_key option is specified.\n"
+ "InnoDB: This option may not be safe to keep consistency of datafiles.\n"
+ "InnoDB: Because InnoDB cannot lock datafiles when shutdown until reusing shared memory segment.\n"
+ "InnoDB: You should ensure no change of InnoDB files while using innodb_buffer_pool_shm_key.\n");
+
+ /* FIXME: This is vague id still */
+ binary_id = (ulint) ((char*)mtr_commit - (char *)btr_root_get)
+ + (ulint) ((char *)os_get_os_version - (char *)buf_calc_page_new_checksum)
+ + (ulint) ((char *)page_dir_find_owner_slot - (char *)dfield_data_is_binary_equal)
+ + (ulint) ((char *)que_graph_publish - (char *)dict_casedn_str)
+ + (ulint) ((char *)read_view_oldest_copy_or_open_new - (char *)fil_space_get_version)
+ + (ulint) ((char *)rec_get_n_extern_new - (char *)fsp_get_size_low)
+ + (ulint) ((char *)row_get_trx_id_offset - (char *)ha_create_func)
+ + (ulint) ((char *)srv_set_io_thread_op_info - (char *)thd_is_replication_slave_thread)
+ + (ulint) ((char *)mutex_create_func - (char *)ibuf_inside)
+ + (ulint) ((char *)trx_set_detailed_error - (char *)lock_check_trx_id_sanity)
+ + (ulint) ((char *)ut_time - (char *)mem_heap_strdup);
+
+ chunk->mem = os_shm_alloc(&chunk->mem_size, srv_buffer_pool_shm_key, &is_new);
+
+ if (UNIV_UNLIKELY(chunk->mem == NULL)) {
+ return(NULL);
+ }
+
+#ifdef UNIV_SET_MEM_TO_ZERO
+ if (is_new) {
+ memset(chunk->mem, '\0', chunk->mem_size);
+ }
+#endif
+
+ shm_info = chunk->mem;
+
+ zip_hash_tmp = (hash_table_t*)((char *)chunk->mem + chunk->mem_size - zip_hash_mem_size);
+
+ if (is_new) {
+ strncpy(shm_info->head_str, BUF_SHM_INFO_HEAD, 8);
+ shm_info->binary_id = binary_id;
+ shm_info->is_new = TRUE; /* changed to FALSE when the initialization is finished */
+ shm_info->clean = FALSE; /* changed to TRUE when free the segment. */
+ shm_info->reusable = FALSE; /* changed to TRUE when validation is finished. */
+ shm_info->buf_pool_size = srv_buf_pool_size;
+ shm_info->page_size = srv_page_size;
+ shm_info->zip_hash_offset = chunk->mem_size - zip_hash_mem_size;
+ shm_info->zip_hash_n = zip_hash_n;
+ } else {
+ ulint checksum;
+
+ if (strncmp(shm_info->head_str, BUF_SHM_INFO_HEAD, 8)) {
+ fprintf(stderr,
+ "InnoDB: Error: The shared memory segment seems not to be for buffer pool.\n");
+ return(NULL);
+ }
+ if (shm_info->binary_id != binary_id) {
+ fprintf(stderr,
+ "InnoDB: Error: The shared memory segment seems not to be for this binary.\n");
+ return(NULL);
+ }
+ if (shm_info->is_new) {
+ fprintf(stderr,
+ "InnoDB: Error: The shared memory was not initialized yet.\n");
+ return(NULL);
+ }
+ if (!shm_info->clean) {
+ fprintf(stderr,
+ "InnoDB: Error: The shared memory was not shut down cleanly.\n");
+ return(NULL);
+ }
+ if (!shm_info->reusable) {
+ fprintf(stderr,
+ "InnoDB: Error: The shared memory has unrecoverable contents.\n");
+ return(NULL);
+ }
+ if (shm_info->buf_pool_size != srv_buf_pool_size) {
+ fprintf(stderr,
+ "InnoDB: Error: srv_buf_pool_size is different (shm=%lu current=%lu).\n",
+ shm_info->buf_pool_size, srv_buf_pool_size);
+ return(NULL);
+ }
+ if (shm_info->page_size != srv_page_size) {
+ fprintf(stderr,
+ "InnoDB: Error: srv_page_size is different (shm=%lu current=%lu).\n",
+ shm_info->page_size, srv_page_size);
+ return(NULL);
+ }
+
+ ut_a(shm_info->zip_hash_offset == chunk->mem_size - zip_hash_mem_size);
+ ut_a(shm_info->zip_hash_n == zip_hash_n);
+
+ /* check checksum */
+ checksum = ut_fold_binary((byte*)chunk->mem + sizeof(buf_shm_info_t),
+ chunk->mem_size - sizeof(buf_shm_info_t));
+ if (shm_info->checksum != checksum) {
+ fprintf(stderr,
+ "InnoDB: Error: checksum of the shared memory is not match. "
+ "(stored=%lu calculated=%lu)\n",
+ shm_info->checksum, checksum);
+ return(NULL);
+ }
+
+ /* flag to use the segment. */
+ shm_info->clean = FALSE; /* changed to TRUE when free the segment. */
+ }
+
+ /* init zip_hash contents */
+ if (is_new) {
+ hash_create_init(zip_hash_tmp, zip_hash_n);
+ } else {
+ /* adjust offset is done later */
+ hash_create_reuse(zip_hash_tmp);
+ }
+ } else {
chunk->mem = os_mem_alloc_large(&chunk->mem_size);
if (UNIV_UNLIKELY(chunk->mem == NULL)) {
return(NULL);
}
+ }
/* Allocate the block descriptors from
the start of the memory block. */
+ if (srv_buffer_pool_shm_key) {
+ chunk->blocks = (buf_block_t*)((char*)chunk->mem + sizeof(buf_shm_info_t));
+ } else {
chunk->blocks = chunk->mem;
+ }
/* Align a pointer to the first frame. Note that when
os_large_page_size is smaller than UNIV_PAGE_SIZE,
@@ -803,8 +1003,13 @@ buf_chunk_init(
it is bigger, we may allocate more blocks than requested. */
frame = ut_align(chunk->mem, UNIV_PAGE_SIZE);
+ if (srv_buffer_pool_shm_key) {
+ /* reserve zip_hash space and always -1 for reproductibity */
+ chunk->size = (chunk->mem_size - zip_hash_mem_size) / UNIV_PAGE_SIZE - 1;
+ } else {
chunk->size = chunk->mem_size / UNIV_PAGE_SIZE
- (frame != chunk->mem);
+ }
/* Subtract the space needed for block descriptors. */
{
@@ -818,6 +1023,98 @@ buf_chunk_init(
chunk->size = size;
}
+ if (shm_info && !(shm_info->is_new)) {
+ /* convert the shared memory segment for reuse */
+ ptrdiff_t phys_offset;
+ ptrdiff_t logi_offset;
+ ptrdiff_t blocks_offset;
+ byte* previous_frame_address;
+
+ if (chunk->size < shm_info->chunk_backup.size) {
+ fprintf(stderr,
+ "InnoDB: Error: The buffer pool became smaller because of allocated address.\n"
+ "InnoDB: Retrying may avoid this situation.\n");
+ shm_info->clean = TRUE; /* release the flag for retrying */
+ return(NULL);
+ }
+
+ chunk->size = shm_info->chunk_backup.size;
+ phys_offset = (char*)frame - ((char*)chunk->mem + shm_info->frame_offset);
+ logi_offset = (char *)frame - (char *)chunk->blocks[0].frame;
+ previous_frame_address = chunk->blocks[0].frame;
+ blocks_offset = (char *)chunk->blocks - (char *)shm_info->chunk_backup.blocks;
+
+ if (phys_offset || logi_offset || blocks_offset) {
+ fprintf(stderr,
+ "InnoDB: Buffer pool in the shared memory segment should be converted.\n"
+ "InnoDB: Previous frames in address : %p\n"
+ "InnoDB: Previous frames were located : %p\n"
+ "InnoDB: Current frames should be located: %p\n"
+ "InnoDB: Pysical offset : %ld (%#lx)\n"
+ "InnoDB: Logical offset (frames) : %ld (%#lx)\n"
+ "InnoDB: Logical offset (blocks) : %ld (%#lx)\n",
+ (char *)chunk->mem + shm_info->frame_offset,
+ chunk->blocks[0].frame, frame,
+ (ulong) phys_offset, (ulong) phys_offset, (ulong) logi_offset, (ulong) logi_offset,
+ (ulong) blocks_offset, (ulong) blocks_offset);
+ } else {
+ fprintf(stderr,
+ "InnoDB: Buffer pool in the shared memory segment can be used as it is.\n");
+ }
+
+ if (phys_offset) {
+ fprintf(stderr,
+ "InnoDB: Aligning physical offset...");
+
+ memmove(frame, ((char*)chunk->mem + shm_info->frame_offset),
+ chunk->size * UNIV_PAGE_SIZE);
+
+ fprintf(stderr,
+ " Done.\n");
+ }
+
+ if (logi_offset || blocks_offset) {
+ fprintf(stderr,
+ "InnoDB: Aligning logical offset...");
+
+ /* buf_block_t */
+ block = chunk->blocks;
+
+ for (i = chunk->size; i--; ) {
+ buf_block_reuse(block, logi_offset);
+ block++;
+ }
+
+ /* buf_pool_t buf_pool_backup */
+ UT_LIST_OFFSET(flush_list, buf_page_t, shm_info->buf_pool_backup.flush_list,
+ previous_frame_address, logi_offset, blocks_offset);
+ UT_LIST_OFFSET(free, buf_page_t, shm_info->buf_pool_backup.free,
+ previous_frame_address, logi_offset, blocks_offset);
+ UT_LIST_OFFSET(LRU, buf_page_t, shm_info->buf_pool_backup.LRU,
+ previous_frame_address, logi_offset, blocks_offset);
+ if (shm_info->buf_pool_backup.LRU_old)
+ shm_info->buf_pool_backup.LRU_old =
+ (buf_page_t*)((char*)(shm_info->buf_pool_backup.LRU_old)
+ + (((byte*)shm_info->buf_pool_backup.LRU_old > previous_frame_address)
+ ? logi_offset : blocks_offset));
+
+ UT_LIST_OFFSET(unzip_LRU, buf_block_t, shm_info->buf_pool_backup.unzip_LRU,
+ previous_frame_address, logi_offset, blocks_offset);
+
+ UT_LIST_OFFSET(zip_list, buf_page_t, shm_info->buf_pool_backup.zip_clean,
+ previous_frame_address, logi_offset, blocks_offset);
+ for (i = 0; i < BUF_BUDDY_SIZES_MAX; i++) {
+ UT_LIST_OFFSET(zip_list, buf_page_t, shm_info->buf_pool_backup.zip_free[i],
+ previous_frame_address, logi_offset, blocks_offset);
+ }
+
+ HASH_OFFSET(zip_hash_tmp, buf_page_t, hash,
+ previous_frame_address, logi_offset, blocks_offset);
+
+ fprintf(stderr,
+ " Done.\n");
+ }
+ } else {
/* Init block structs and assign frames for them. Then we
assign the frames to the first blocks (we already mapped the
memory above). */
@@ -841,6 +1138,11 @@ buf_chunk_init(
block++;
frame += UNIV_PAGE_SIZE;
}
+ }
+
+ if (shm_info) {
+ shm_info->frame_offset = (char*)chunk->blocks[0].frame - (char*)chunk->mem;
+ }
return(chunk);
}
@@ -940,6 +1242,11 @@ buf_chunk_not_freed(
ready = buf_flush_ready_for_replace(&block->page);
mutex_exit(&block->mutex);
+ if (block->page.is_corrupt) {
+ /* corrupt page may remain, it can be skipped */
+ break;
+ }
+
if (!ready) {
return(block);
@@ -1017,6 +1324,8 @@ buf_chunk_free(
UNIV_MEM_UNDESC(block);
}
+ ut_a(!srv_buffer_pool_shm_key);
+
os_mem_free_large(chunk->mem, chunk->mem_size);
}
@@ -1066,7 +1375,10 @@ buf_pool_init(void)
srv_buf_pool_curr_size = buf_pool->curr_size * UNIV_PAGE_SIZE;
buf_pool->page_hash = hash_create(2 * buf_pool->curr_size);
+ /* zip_hash is allocated to shm when srv_buffer_pool_shm_key is enabled */
+ if (!srv_buffer_pool_shm_key) {
buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size);
+ }
buf_pool->last_printout_time = time(NULL);
@@ -1081,6 +1393,86 @@ buf_pool_init(void)
--------------------------- */
/* All fields are initialized by mem_zalloc(). */
+ if (srv_buffer_pool_shm_key) {
+ buf_shm_info_t* shm_info;
+
+ ut_a((char*)chunk->blocks == (char*)chunk->mem + sizeof(buf_shm_info_t));
+ shm_info = chunk->mem;
+
+ buf_pool->zip_hash = (hash_table_t*)((char*)chunk->mem + shm_info->zip_hash_offset);
+
+ if(shm_info->is_new) {
+ shm_info->is_new = FALSE; /* initialization was finished */
+ } else {
+ buf_block_t* block = chunk->blocks;
+ buf_page_t* b;
+
+ /* shm_info->buf_pool_backup should be converted */
+ /* at buf_chunk_init(). So copy simply. */
+ buf_pool->flush_list = shm_info->buf_pool_backup.flush_list;
+ buf_pool->freed_page_clock = shm_info->buf_pool_backup.freed_page_clock;
+ buf_pool->free = shm_info->buf_pool_backup.free;
+ buf_pool->LRU = shm_info->buf_pool_backup.LRU;
+ buf_pool->LRU_old = shm_info->buf_pool_backup.LRU_old;
+ buf_pool->LRU_old_len = shm_info->buf_pool_backup.LRU_old_len;
+ buf_pool->unzip_LRU = shm_info->buf_pool_backup.unzip_LRU;
+ buf_pool->zip_clean = shm_info->buf_pool_backup.zip_clean;
+ for (i = 0; i < BUF_BUDDY_SIZES_MAX; i++) {
+ buf_pool->zip_free[i] = shm_info->buf_pool_backup.zip_free[i];
+ }
+
+ for (i = 0; i < chunk->size; i++, block++) {
+ if (buf_block_get_state(block)
+ == BUF_BLOCK_FILE_PAGE) {
+ ut_d(block->page.in_page_hash = TRUE);
+ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
+ buf_page_address_fold(
+ block->page.space,
+ block->page.offset),
+ &block->page);
+ }
+ }
+
+ for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
+ b = UT_LIST_GET_NEXT(zip_list, b)) {
+ ut_ad(!b->in_flush_list);
+ ut_ad(b->in_LRU_list);
+
+ ut_d(b->in_page_hash = TRUE);
+ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
+ buf_page_address_fold(b->space, b->offset), b);
+ }
+
+ for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
+ b = UT_LIST_GET_NEXT(flush_list, b)) {
+ ut_ad(b->in_flush_list);
+ ut_ad(b->in_LRU_list);
+
+ switch (buf_page_get_state(b)) {
+ case BUF_BLOCK_ZIP_DIRTY:
+ ut_d(b->in_page_hash = TRUE);
+ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
+ buf_page_address_fold(b->space,
+ b->offset), b);
+ break;
+ case BUF_BLOCK_FILE_PAGE:
+ /* uncompressed page */
+ break;
+ case BUF_BLOCK_ZIP_FREE:
+ case BUF_BLOCK_ZIP_PAGE:
+ case BUF_BLOCK_NOT_USED:
+ case BUF_BLOCK_READY_FOR_USE:
+ case BUF_BLOCK_MEMORY:
+ case BUF_BLOCK_REMOVE_HASH:
+ ut_error;
+ break;
+ }
+ }
+
+
+ }
+ }
+
mutex_exit(&LRU_list_mutex);
rw_lock_x_unlock(&page_hash_latch);
buf_pool_mutex_exit();
@@ -1105,6 +1497,30 @@ buf_pool_free(void)
buf_chunk_t* chunk;
buf_chunk_t* chunks;
+ if (srv_buffer_pool_shm_key) {
+ buf_shm_info_t* shm_info;
+
+ ut_a(buf_pool->n_chunks == 1);
+
+ chunk = buf_pool->chunks;
+ shm_info = chunk->mem;
+ ut_a((char*)chunk->blocks == (char*)chunk->mem + sizeof(buf_shm_info_t));
+
+ /* validation the shared memory segment doesn't have unrecoverable contents. */
+ /* Currently, validation became not needed */
+ shm_info->reusable = TRUE;
+
+ memcpy(&(shm_info->buf_pool_backup), buf_pool, sizeof(buf_pool_t));
+ memcpy(&(shm_info->chunk_backup), chunk, sizeof(buf_chunk_t));
+
+ if (srv_fast_shutdown < 2) {
+ shm_info->checksum = ut_fold_binary((byte*)chunk->mem + sizeof(buf_shm_info_t),
+ chunk->mem_size - sizeof(buf_shm_info_t));
+ shm_info->clean = TRUE;
+ }
+
+ os_shm_free(chunk->mem, chunk->mem_size);
+ } else {
chunks = buf_pool->chunks;
chunk = chunks + buf_pool->n_chunks;
@@ -1113,10 +1529,13 @@ buf_pool_free(void)
would fail at shutdown. */
os_mem_free_large(chunk->mem, chunk->mem_size);
}
+ }
mem_free(buf_pool->chunks);
hash_table_free(buf_pool->page_hash);
+ if (!srv_buffer_pool_shm_key) {
hash_table_free(buf_pool->zip_hash);
+ }
mem_free(buf_pool);
buf_pool = NULL;
}
@@ -1311,6 +1730,11 @@ try_again:
//buf_pool_mutex_enter();
mutex_enter(&LRU_list_mutex);
+ if (srv_buffer_pool_shm_key) {
+ /* Cannot support shrink */
+ goto func_done;
+ }
+
shrink_again:
if (buf_pool->n_chunks <= 1) {
@@ -1554,6 +1978,11 @@ void
buf_pool_resize(void)
/*=================*/
{
+ if (srv_buffer_pool_shm_key) {
+ /* Cannot support resize */
+ return;
+ }
+
//buf_pool_mutex_enter();
mutex_enter(&LRU_list_mutex);
@@ -2458,7 +2887,7 @@ wait_until_unfixed:
block->page.buf_fix_count = 1;
buf_block_set_io_fix(block, BUF_IO_READ);
- rw_lock_x_lock(&block->lock);
+ rw_lock_x_lock_func(&block->lock, 0, file, line);
UNIV_MEM_INVALID(bpage, sizeof *bpage);
diff --git a/storage/xtradb/buf/buf0flu.c b/storage/xtradb/buf/buf0flu.c
index 17588475bbf..0a03d583549 100644
--- a/storage/xtradb/buf/buf0flu.c
+++ b/storage/xtradb/buf/buf0flu.c
@@ -257,6 +257,17 @@ buf_flush_insert_into_flush_list(
ut_d(block->page.in_flush_list = TRUE);
UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
+#ifdef UNIV_DEBUG_VALGRIND
+ {
+ ulint zip_size = buf_block_get_zip_size(block);
+
+ if (UNIV_UNLIKELY(zip_size)) {
+ UNIV_MEM_ASSERT_RW(block->page.zip.data, zip_size);
+ } else {
+ UNIV_MEM_ASSERT_RW(block->frame, UNIV_PAGE_SIZE);
+ }
+ }
+#endif /* UNIV_DEBUG_VALGRIND */
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(buf_flush_validate_low());
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
@@ -286,6 +297,18 @@ buf_flush_insert_sorted_into_flush_list(
ut_ad(!block->page.in_flush_list);
ut_d(block->page.in_flush_list = TRUE);
+#ifdef UNIV_DEBUG_VALGRIND
+ {
+ ulint zip_size = buf_block_get_zip_size(block);
+
+ if (UNIV_UNLIKELY(zip_size)) {
+ UNIV_MEM_ASSERT_RW(block->page.zip.data, zip_size);
+ } else {
+ UNIV_MEM_ASSERT_RW(block->frame, UNIV_PAGE_SIZE);
+ }
+ }
+#endif /* UNIV_DEBUG_VALGRIND */
+
prev_b = NULL;
/* For the most part when this function is called the flush_rbt
@@ -830,6 +853,7 @@ try_again:
zip_size = buf_page_get_zip_size(bpage);
if (UNIV_UNLIKELY(zip_size)) {
+ UNIV_MEM_ASSERT_RW(bpage->zip.data, zip_size);
/* Copy the compressed page and clear the rest. */
memcpy(trx_doublewrite->write_buf
+ UNIV_PAGE_SIZE * trx_doublewrite->first_free,
@@ -839,6 +863,8 @@ try_again:
+ zip_size, 0, UNIV_PAGE_SIZE - zip_size);
} else {
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
+ UNIV_MEM_ASSERT_RW(((buf_block_t*) bpage)->frame,
+ UNIV_PAGE_SIZE);
memcpy(trx_doublewrite->write_buf
+ UNIV_PAGE_SIZE * trx_doublewrite->first_free,
@@ -1533,6 +1559,7 @@ retry:
} else if (!have_LRU_mutex) {
/* confirm it again with LRU_mutex for exactness */
have_LRU_mutex = TRUE;
+ distance = 0;
goto retry;
}
diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c
index 7b01c4aec50..14ec1720873 100644
--- a/storage/xtradb/buf/buf0lru.c
+++ b/storage/xtradb/buf/buf0lru.c
@@ -1455,7 +1455,7 @@ buf_LRU_make_block_old(
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.
-NOTE: If this function returns BUF_LRU_FREED, it will not temporarily
+NOTE: If this function returns BUF_LRU_FREED, it will temporarily
release buf_pool_mutex. Furthermore, the page frame will no longer be
accessible via bpage.
diff --git a/storage/xtradb/dict/dict0boot.c b/storage/xtradb/dict/dict0boot.c
index 0a713f0deaa..43cfced65a0 100644
--- a/storage/xtradb/dict/dict0boot.c
+++ b/storage/xtradb/dict/dict0boot.c
@@ -62,32 +62,47 @@ dict_hdr_get(
}
/**********************************************************************//**
-Returns a new table, index, or tree id.
-@return the new id */
+Returns a new table, index, or space id. */
UNIV_INTERN
-dulint
+void
dict_hdr_get_new_id(
/*================*/
- ulint type) /*!< in: DICT_HDR_ROW_ID, ... */
+ dulint* table_id, /*!< out: table id (not assigned if NULL) */
+ dulint* index_id, /*!< out: index id (not assigned if NULL) */
+ ulint* space_id) /*!< out: space id (not assigned if NULL) */
{
dict_hdr_t* dict_hdr;
dulint id;
mtr_t mtr;
- ut_ad((type == DICT_HDR_TABLE_ID) || (type == DICT_HDR_INDEX_ID));
-
mtr_start(&mtr);
dict_hdr = dict_hdr_get(&mtr);
- id = mtr_read_dulint(dict_hdr + type, &mtr);
- id = ut_dulint_add(id, 1);
+ if (table_id) {
+ id = mtr_read_dulint(dict_hdr + DICT_HDR_TABLE_ID, &mtr);
+ id = ut_dulint_add(id, 1);
+ mlog_write_dulint(dict_hdr + DICT_HDR_TABLE_ID, id, &mtr);
+ *table_id = id;
+ }
- mlog_write_dulint(dict_hdr + type, id, &mtr);
+ if (index_id) {
+ id = mtr_read_dulint(dict_hdr + DICT_HDR_INDEX_ID, &mtr);
+ id = ut_dulint_add(id, 1);
+ mlog_write_dulint(dict_hdr + DICT_HDR_INDEX_ID, id, &mtr);
+ *index_id = id;
+ }
- mtr_commit(&mtr);
+ if (space_id) {
+ *space_id = mtr_read_ulint(dict_hdr + DICT_HDR_MAX_SPACE_ID,
+ MLOG_4BYTES, &mtr);
+ if (fil_assign_new_space_id(space_id)) {
+ mlog_write_ulint(dict_hdr + DICT_HDR_MAX_SPACE_ID,
+ *space_id, MLOG_4BYTES, &mtr);
+ }
+ }
- return(id);
+ mtr_commit(&mtr);
}
/**********************************************************************//**
@@ -151,9 +166,12 @@ dict_hdr_create(
mlog_write_dulint(dict_header + DICT_HDR_INDEX_ID,
ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
- /* Obsolete, but we must initialize it to 0 anyway. */
- mlog_write_dulint(dict_header + DICT_HDR_MIX_ID,
- ut_dulint_create(0, DICT_HDR_FIRST_ID), mtr);
+ mlog_write_ulint(dict_header + DICT_HDR_MAX_SPACE_ID,
+ 0, MLOG_4BYTES, mtr);
+
+ /* Obsolete, but we must initialize it anyway. */
+ mlog_write_ulint(dict_header + DICT_HDR_MIX_ID_LOW,
+ DICT_HDR_FIRST_ID, MLOG_4BYTES, mtr);
/* Create the B-tree roots for the clustered indexes of the basic
system tables */
@@ -245,6 +263,29 @@ dict_boot(void)
/* Get the dictionary header */
dict_hdr = dict_hdr_get(&mtr);
+ if (ut_dulint_cmp(mtr_read_dulint(dict_hdr + DICT_HDR_XTRADB_MARK, &mtr),
+ DICT_HDR_XTRADB_FLAG) != 0) {
+ /* not extended yet by XtraDB, need to be extended */
+ ulint root_page_no;
+
+ root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
+ DICT_HDR_SPACE, 0, DICT_STATS_ID,
+ dict_ind_redundant, &mtr);
+ if (root_page_no == FIL_NULL) {
+ fprintf(stderr, "InnoDB: Warning: failed to create SYS_STATS btr.\n");
+ srv_use_sys_stats_table = FALSE;
+ } else {
+ mlog_write_ulint(dict_hdr + DICT_HDR_STATS, root_page_no,
+ MLOG_4BYTES, &mtr);
+ mlog_write_dulint(dict_hdr + DICT_HDR_XTRADB_MARK,
+ DICT_HDR_XTRADB_FLAG, &mtr);
+ }
+ mtr_commit(&mtr);
+ /* restart mtr */
+ mtr_start(&mtr);
+ dict_hdr = dict_hdr_get(&mtr);
+ }
+
/* Because we only write new row ids to disk-based data structure
(dictionary header) when it is divisible by
DICT_HDR_ROW_ID_WRITE_MARGIN, in recovery we will not recover
@@ -406,7 +447,7 @@ dict_boot(void)
table->id = DICT_FIELDS_ID;
dict_table_add_to_cache(table, heap);
dict_sys->sys_fields = table;
- mem_heap_free(heap);
+ mem_heap_empty(heap);
index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
DICT_HDR_SPACE,
@@ -423,6 +464,41 @@ dict_boot(void)
FALSE);
ut_a(error == DB_SUCCESS);
+ /*-------------------------*/
+ table = dict_mem_table_create("SYS_STATS", DICT_HDR_SPACE, 3, 0);
+ table->n_mysql_handles_opened = 1; /* for pin */
+
+ dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, heap, "KEY_COLS", DATA_INT, 0, 4);
+ dict_mem_table_add_col(table, heap, "DIFF_VALS", DATA_BINARY, 0, 0);
+
+ /* The '+ 2' below comes from the fields DB_TRX_ID, DB_ROLL_PTR */
+#if DICT_SYS_STATS_DIFF_VALS_FIELD != 2 + 2
+#error "DICT_SYS_STATS_DIFF_VALS_FIELD != 2 + 2"
+#endif
+
+ table->id = DICT_STATS_ID;
+ dict_table_add_to_cache(table, heap);
+ dict_sys->sys_stats = table;
+ mem_heap_empty(heap);
+
+ index = dict_mem_index_create("SYS_STATS", "CLUST_IND",
+ DICT_HDR_SPACE,
+ DICT_UNIQUE | DICT_CLUSTERED, 2);
+
+ dict_mem_index_add_field(index, "INDEX_ID", 0);
+ dict_mem_index_add_field(index, "KEY_COLS", 0);
+
+ index->id = DICT_STATS_ID;
+ error = dict_index_add_to_cache(table, index,
+ mtr_read_ulint(dict_hdr
+ + DICT_HDR_STATS,
+ MLOG_4BYTES, &mtr),
+ FALSE);
+ ut_a(error == DB_SUCCESS);
+
+ mem_heap_free(heap);
+
mtr_commit(&mtr);
/*-------------------------*/
@@ -436,6 +512,7 @@ dict_boot(void)
dict_load_sys_table(dict_sys->sys_columns);
dict_load_sys_table(dict_sys->sys_indexes);
dict_load_sys_table(dict_sys->sys_fields);
+ dict_load_sys_table(dict_sys->sys_stats);
mutex_exit(&(dict_sys->mutex));
}
diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c
index d4e735c73ca..258bf77d1fc 100644
--- a/storage/xtradb/dict/dict0crea.c
+++ b/storage/xtradb/dict/dict0crea.c
@@ -239,16 +239,34 @@ dict_build_table_def_step(
const char* path_or_name;
ibool is_path;
mtr_t mtr;
+ ulint space = 0;
+ ibool file_per_table;
ut_ad(mutex_own(&(dict_sys->mutex)));
table = node->table;
- table->id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
+ /* Cache the global variable "srv_file_per_table" to
+ a local variable before using it. Please note
+ "srv_file_per_table" is not under dict_sys mutex
+ protection, and could be changed while executing
+ this function. So better to cache the current value
+ to a local variable, and all future reference to
+ "srv_file_per_table" should use this local variable. */
+ file_per_table = srv_file_per_table;
+
+ dict_hdr_get_new_id(&table->id, NULL, NULL);
thr_get_trx(thr)->table_id = table->id;
- if (srv_file_per_table) {
+ if (file_per_table) {
+ /* Get a new space id if srv_file_per_table is set */
+ dict_hdr_get_new_id(NULL, NULL, &space);
+
+ if (UNIV_UNLIKELY(space == ULINT_UNDEFINED)) {
+ return(DB_ERROR);
+ }
+
/* We create a new single-table tablespace for the table.
We initially let it be 4 pages:
- page 0 is the fsp header and an extent descriptor page,
@@ -257,8 +275,6 @@ dict_build_table_def_step(
- page 3 will contain the root of the clustered index of the
table we create here. */
- ulint space = 0; /* reset to zero for the call below */
-
if (table->dir_path_of_temp_table) {
/* We place tables created with CREATE TEMPORARY
TABLE in the tmp dir of mysqld server */
@@ -276,7 +292,7 @@ dict_build_table_def_step(
flags = table->flags & ~(~0 << DICT_TF_BITS);
error = fil_create_new_single_table_tablespace(
- &space, path_or_name, is_path,
+ space, path_or_name, is_path,
flags == DICT_TF_COMPACT ? 0 : flags,
FIL_IBD_FILE_INITIAL_SIZE);
table->space = (unsigned int) space;
@@ -492,6 +508,51 @@ dict_create_sys_fields_tuple(
}
/*****************************************************************//**
+Based on an index object, this function builds the entry to be inserted
+in the SYS_STATS system table.
+@return the tuple which should be inserted */
+static
+dtuple_t*
+dict_create_sys_stats_tuple(
+/*========================*/
+ const dict_index_t* index,
+ ulint i,
+ mem_heap_t* heap)
+{
+ dict_table_t* sys_stats;
+ dtuple_t* entry;
+ dfield_t* dfield;
+ byte* ptr;
+
+ ut_ad(index);
+ ut_ad(heap);
+
+ sys_stats = dict_sys->sys_stats;
+
+ entry = dtuple_create(heap, 3 + DATA_N_SYS_COLS);
+
+ dict_table_copy_types(entry, sys_stats);
+
+ /* 0: INDEX_ID -----------------------*/
+ dfield = dtuple_get_nth_field(entry, 0/*INDEX_ID*/);
+ ptr = mem_heap_alloc(heap, 8);
+ mach_write_to_8(ptr, index->id);
+ dfield_set_data(dfield, ptr, 8);
+ /* 1: KEY_COLS -----------------------*/
+ dfield = dtuple_get_nth_field(entry, 1/*KEY_COLS*/);
+ ptr = mem_heap_alloc(heap, 4);
+ mach_write_to_4(ptr, i);
+ dfield_set_data(dfield, ptr, 4);
+ /* 4: DIFF_VALS ----------------------*/
+ dfield = dtuple_get_nth_field(entry, 2/*DIFF_VALS*/);
+ ptr = mem_heap_alloc(heap, 8);
+ mach_write_to_8(ptr, ut_dulint_zero); /* initial value is 0 */
+ dfield_set_data(dfield, ptr, 8);
+
+ return(entry);
+}
+
+/*****************************************************************//**
Creates the tuple with which the index entry is searched for writing the index
tree root page number, if such a tree is created.
@return the tuple for search */
@@ -561,7 +622,7 @@ dict_build_index_def_step(
ut_ad((UT_LIST_GET_LEN(table->indexes) > 0)
|| dict_index_is_clust(index));
- index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
+ dict_hdr_get_new_id(NULL, &index->id, NULL);
/* Inherit the space id from the table; we store all indexes of a
table in the same tablespace */
@@ -601,6 +662,27 @@ dict_build_field_def_step(
}
/***************************************************************//**
+Builds a row for storing stats to insert.
+@return DB_SUCCESS */
+static
+ulint
+dict_build_stats_def_step(
+/*======================*/
+ ind_node_t* node)
+{
+ dict_index_t* index;
+ dtuple_t* row;
+
+ index = node->index;
+
+ row = dict_create_sys_stats_tuple(index, node->stats_no, node->heap);
+
+ ins_node_set_new_row(node->stats_def, row);
+
+ return(DB_SUCCESS);
+}
+
+/***************************************************************//**
Creates an index tree for the index if it is not a member of a cluster.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
@@ -924,6 +1006,49 @@ ind_create_graph_create(
dict_sys->sys_fields, heap);
node->field_def->common.parent = node;
+ if (srv_use_sys_stats_table) {
+ node->stats_def = ins_node_create(INS_DIRECT,
+ dict_sys->sys_stats, heap);
+ node->stats_def->common.parent = node;
+ } else {
+ node->stats_def = NULL;
+ }
+
+ node->commit_node = commit_node_create(heap);
+ node->commit_node->common.parent = node;
+
+ return(node);
+}
+
+/*********************************************************************//**
+*/
+UNIV_INTERN
+ind_node_t*
+ind_insert_stats_graph_create(
+/*==========================*/
+ dict_index_t* index,
+ mem_heap_t* heap)
+{
+ ind_node_t* node;
+
+ node = mem_heap_alloc(heap, sizeof(ind_node_t));
+
+ node->common.type = QUE_NODE_INSERT_STATS;
+
+ node->index = index;
+
+ node->state = INDEX_BUILD_STATS_COLS;
+ node->page_no = FIL_NULL;
+ node->heap = mem_heap_create(256);
+
+ node->ind_def = NULL;
+ node->field_def = NULL;
+
+ node->stats_def = ins_node_create(INS_DIRECT,
+ dict_sys->sys_stats, heap);
+ node->stats_def->common.parent = node;
+ node->stats_no = 0;
+
node->commit_node = commit_node_create(heap);
node->commit_node->common.parent = node;
@@ -1074,6 +1199,7 @@ dict_create_index_step(
node->state = INDEX_BUILD_FIELD_DEF;
node->field_no = 0;
+ node->stats_no = 0;
thr->run_node = node->ind_def;
@@ -1119,7 +1245,31 @@ dict_create_index_step(
goto function_exit;
}
- node->state = INDEX_CREATE_INDEX_TREE;
+ if (srv_use_sys_stats_table) {
+ node->state = INDEX_BUILD_STATS_COLS;
+ } else {
+ node->state = INDEX_CREATE_INDEX_TREE;
+ }
+ }
+
+ if (node->state == INDEX_BUILD_STATS_COLS) {
+ if (node->stats_no <= dict_index_get_n_unique(node->index)) {
+
+ err = dict_build_stats_def_step(node);
+
+ if (err != DB_SUCCESS) {
+
+ goto function_exit;
+ }
+
+ node->stats_no++;
+
+ thr->run_node = node->stats_def;
+
+ return(thr);
+ } else {
+ node->state = INDEX_CREATE_INDEX_TREE;
+ }
}
if (node->state == INDEX_CREATE_INDEX_TREE) {
@@ -1171,6 +1321,66 @@ function_exit:
}
/****************************************************************//**
+*/
+UNIV_INTERN
+que_thr_t*
+dict_insert_stats_step(
+/*===================*/
+ que_thr_t* thr) /*!< in: query thread */
+{
+ ind_node_t* node;
+ ulint err = DB_ERROR;
+ trx_t* trx;
+
+ ut_ad(thr);
+
+ trx = thr_get_trx(thr);
+
+ node = thr->run_node;
+
+ if (thr->prev_node == que_node_get_parent(node)) {
+ node->state = INDEX_BUILD_STATS_COLS;
+ }
+
+ if (node->state == INDEX_BUILD_STATS_COLS) {
+ if (node->stats_no <= dict_index_get_n_unique(node->index)) {
+
+ err = dict_build_stats_def_step(node);
+
+ if (err != DB_SUCCESS) {
+
+ goto function_exit;
+ }
+
+ node->stats_no++;
+
+ thr->run_node = node->stats_def;
+
+ return(thr);
+ } else {
+ node->state = INDEX_COMMIT_WORK;
+ }
+ }
+
+ if (node->state == INDEX_COMMIT_WORK) {
+
+ /* do not commit transaction here for now */
+ }
+
+function_exit:
+ trx->error_state = err;
+
+ if (err == DB_SUCCESS) {
+ } else {
+ return(NULL);
+ }
+
+ thr->run_node = que_node_get_parent(node);
+
+ return(thr);
+}
+
+/****************************************************************//**
Creates the foreign key constraints system tables inside InnoDB
at database creation or database start if they are not found or are
not of the right form.
diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 1d088b2e02b..51ee7f9246f 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -83,7 +83,7 @@ static char dict_ibfk[] = "_ibfk_";
/** array of mutexes protecting dict_index_t::stat_n_diff_key_vals[] */
#define DICT_INDEX_STAT_MUTEX_SIZE 32
-mutex_t dict_index_stat_mutex[DICT_INDEX_STAT_MUTEX_SIZE];
+static mutex_t dict_index_stat_mutex[DICT_INDEX_STAT_MUTEX_SIZE];
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
@@ -571,13 +571,11 @@ dict_table_get_on_id(
if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0
|| trx->dict_operation_lock_mode == RW_X_LATCH) {
- /* It is a system table which will always exist in the table
- cache: we avoid acquiring the dictionary mutex, because
- if we are doing a rollback to handle an error in TABLE
- CREATE, for example, we already have the mutex! */
- ut_ad(mutex_own(&(dict_sys->mutex))
- || trx->dict_operation_lock_mode == RW_X_LATCH);
+ /* Note: An X latch implies that the transaction
+ already owns the dictionary mutex. */
+
+ ut_ad(mutex_own(&dict_sys->mutex));
return(dict_table_get_on_id_low(table_id));
}
@@ -712,7 +710,7 @@ dict_table_get(
/* If table->ibd_file_missing == TRUE, this will
print an error message and return without doing
anything. */
- dict_update_statistics(table);
+ dict_update_statistics(table, FALSE);
}
}
@@ -855,7 +853,8 @@ dict_table_add_to_cache(
/* Add table to LRU list of tables */
UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table);
- dict_sys->size += mem_heap_get_size(table->heap);
+ dict_sys->size += mem_heap_get_size(table->heap)
+ + strlen(table->name) + 1;
}
/**********************************************************************//**
@@ -909,14 +908,21 @@ dict_table_rename_in_cache(
dict_foreign_t* foreign;
dict_index_t* index;
ulint fold;
- ulint old_size;
- const char* old_name;
+ char old_name[MAX_TABLE_NAME_LEN + 1];
ut_ad(table);
ut_ad(mutex_own(&(dict_sys->mutex)));
- old_size = mem_heap_get_size(table->heap);
- old_name = table->name;
+ /* store the old/current name to an automatic variable */
+ if (strlen(table->name) + 1 <= sizeof(old_name)) {
+ memcpy(old_name, table->name, strlen(table->name) + 1);
+ } else {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, "InnoDB: too long table name: '%s', "
+ "max length is %d\n", table->name,
+ MAX_TABLE_NAME_LEN);
+ ut_error;
+ }
fold = ut_fold_string(new_name);
@@ -962,12 +968,22 @@ dict_table_rename_in_cache(
/* Remove table from the hash tables of tables */
HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash,
ut_fold_string(old_name), table);
- table->name = mem_heap_strdup(table->heap, new_name);
+
+ if (strlen(new_name) > strlen(table->name)) {
+ /* We allocate MAX_TABLE_NAME_LEN+1 bytes here to avoid
+ memory fragmentation, we assume a repeated calls of
+ ut_realloc() with the same size do not cause fragmentation */
+ ut_a(strlen(new_name) <= MAX_TABLE_NAME_LEN);
+ table->name = ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1);
+ }
+ memcpy(table->name, new_name, strlen(new_name) + 1);
/* Add table to hash table of tables */
HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold,
table);
- dict_sys->size += (mem_heap_get_size(table->heap) - old_size);
+
+ dict_sys->size += strlen(new_name) - strlen(old_name);
+ ut_a(dict_sys->size > 0);
/* Update the table_name field in indexes */
index = dict_table_get_first_index(table);
@@ -1192,7 +1208,7 @@ dict_table_remove_from_cache(
/* Remove table from LRU list of tables */
UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
- size = mem_heap_get_size(table->heap);
+ size = mem_heap_get_size(table->heap) + strlen(table->name) + 1;
ut_ad(dict_sys->size >= size);
@@ -3076,25 +3092,28 @@ static
char*
dict_strip_comments(
/*================*/
- const char* sql_string) /*!< in: SQL string */
+ const char* sql_string, /*!< in: SQL string */
+ size_t sql_length) /*!< in: length of sql_string */
{
char* str;
const char* sptr;
+ const char* eptr = sql_string + sql_length;
char* ptr;
/* unclosed quote character (0 if none) */
char quote = 0;
- str = mem_alloc(strlen(sql_string) + 1);
+ str = mem_alloc(sql_length + 1);
sptr = sql_string;
ptr = str;
for (;;) {
scan_more:
- if (*sptr == '\0') {
+ if (sptr >= eptr || *sptr == '\0') {
+end_of_string:
*ptr = '\0';
- ut_a(ptr <= str + strlen(sql_string));
+ ut_a(ptr <= str + sql_length);
return(str);
}
@@ -3113,30 +3132,35 @@ scan_more:
|| (sptr[0] == '-' && sptr[1] == '-'
&& sptr[2] == ' ')) {
for (;;) {
+ if (++sptr >= eptr) {
+ goto end_of_string;
+ }
+
/* In Unix a newline is 0x0A while in Windows
it is 0x0D followed by 0x0A */
- if (*sptr == (char)0x0A
- || *sptr == (char)0x0D
- || *sptr == '\0') {
-
+ switch (*sptr) {
+ case (char) 0X0A:
+ case (char) 0x0D:
+ case '\0':
goto scan_more;
}
-
- sptr++;
}
} else if (!quote && *sptr == '/' && *(sptr + 1) == '*') {
+ sptr += 2;
for (;;) {
- if (*sptr == '*' && *(sptr + 1) == '/') {
-
- sptr += 2;
-
- goto scan_more;
+ if (sptr >= eptr) {
+ goto end_of_string;
}
- if (*sptr == '\0') {
-
+ switch (*sptr) {
+ case '\0':
goto scan_more;
+ case '*':
+ if (sptr[1] == '/') {
+ sptr += 2;
+ goto scan_more;
+ }
}
sptr++;
@@ -3817,6 +3841,7 @@ dict_create_foreign_constraints(
name before it: test.table2; the
default database id the database of
parameter name */
+ size_t sql_length, /*!< in: length of sql_string */
const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
@@ -3831,7 +3856,7 @@ dict_create_foreign_constraints(
ut_a(trx);
ut_a(trx->mysql_thd);
- str = dict_strip_comments(sql_string);
+ str = dict_strip_comments(sql_string, sql_length);
heap = mem_heap_create(10000);
err = dict_create_foreign_constraints_low(
@@ -3864,6 +3889,7 @@ dict_foreign_parse_drop_constraints(
dict_foreign_t* foreign;
ibool success;
char* str;
+ size_t len;
const char* ptr;
const char* id;
FILE* ef = dict_foreign_err_file;
@@ -3878,7 +3904,10 @@ dict_foreign_parse_drop_constraints(
*constraints_to_drop = mem_heap_alloc(heap, 1000 * sizeof(char*));
- str = dict_strip_comments(*(trx->mysql_query_str));
+ ptr = innobase_get_stmt(trx->mysql_thd, &len);
+
+ str = dict_strip_comments(ptr, len);
+
ptr = str;
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -4219,6 +4248,259 @@ dict_index_calc_min_rec_len(
}
/*********************************************************************//**
+functions to use SYS_STATS system table. */
+static
+ibool
+dict_reload_statistics(
+/*===================*/
+ dict_table_t* table,
+ ulint* sum_of_index_sizes)
+{
+ dict_index_t* index;
+ ulint size;
+ mem_heap_t* heap;
+
+ index = dict_table_get_first_index(table);
+
+ if (index == NULL) {
+ /* Table definition is corrupt */
+
+ return(FALSE);
+ }
+
+ heap = mem_heap_create(1000);
+
+ while (index) {
+ if (table->is_corrupt) {
+ ut_a(srv_pass_corrupt_table);
+ mem_heap_free(heap);
+ return(FALSE);
+ }
+
+ size = btr_get_size(index, BTR_TOTAL_SIZE);
+
+ index->stat_index_size = size;
+
+ *sum_of_index_sizes += size;
+
+ size = btr_get_size(index, BTR_N_LEAF_PAGES);
+
+ if (size == 0) {
+ /* The root node of the tree is a leaf */
+ size = 1;
+ }
+
+ index->stat_n_leaf_pages = size;
+
+/*===========================================*/
+{
+ dict_table_t* sys_stats;
+ dict_index_t* sys_index;
+ btr_pcur_t pcur;
+ dtuple_t* tuple;
+ dfield_t* dfield;
+ ulint key_cols;
+ ulint n_cols;
+ const rec_t* rec;
+ const byte* field;
+ ulint len;
+ ib_int64_t* stat_n_diff_key_vals_tmp;
+ byte* buf;
+ ulint i;
+ mtr_t mtr;
+
+ n_cols = dict_index_get_n_unique(index);
+ stat_n_diff_key_vals_tmp = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
+
+ sys_stats = dict_sys->sys_stats;
+ sys_index = UT_LIST_GET_FIRST(sys_stats->indexes);
+ ut_a(!dict_table_is_comp(sys_stats));
+
+ tuple = dtuple_create(heap, 1);
+ dfield = dtuple_get_nth_field(tuple, 0);
+
+ buf = mem_heap_alloc(heap, 8);
+ mach_write_to_8(buf, index->id);
+
+ dfield_set_data(dfield, buf, 8);
+ dict_index_copy_types(tuple, sys_index, 1);
+
+ mtr_start(&mtr);
+
+ btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
+ BTR_SEARCH_LEAF, &pcur, &mtr);
+ for (i = 0; i <= n_cols; i++) {
+ rec = btr_pcur_get_rec(&pcur);
+
+ if (!btr_pcur_is_on_user_rec(&pcur)
+ || ut_dulint_cmp(mach_read_from_8(rec_get_nth_field_old(rec, 0, &len)),
+ index->id)) {
+ /* not found: even 1 if not found should not be alowed */
+ fprintf(stderr, "InnoDB: Warning: stats for %s/%s (%lu/%lu)"
+ " not fonund in SYS_STATS\n",
+ index->table_name, index->name, i, n_cols);
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+ mem_heap_free(heap);
+ return(FALSE);
+ }
+
+ if (rec_get_deleted_flag(rec, 0)) {
+ goto next_rec;
+ }
+
+ field = rec_get_nth_field_old(rec, 1, &len);
+ ut_a(len == 4);
+
+ key_cols = mach_read_from_4(field);
+
+ ut_a(i == key_cols);
+
+ field = rec_get_nth_field_old(rec, DICT_SYS_STATS_DIFF_VALS_FIELD, &len);
+ ut_a(len == 8);
+
+ stat_n_diff_key_vals_tmp[i] = ut_conv_dulint_to_longlong(mach_read_from_8(field));
+next_rec:
+ btr_pcur_move_to_next_user_rec(&pcur, &mtr);
+ }
+
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+
+ dict_index_stat_mutex_enter(index);
+ for (i = 0; i <= n_cols; i++) {
+ index->stat_n_diff_key_vals[i] = stat_n_diff_key_vals_tmp[i];
+ }
+ dict_index_stat_mutex_exit(index);
+}
+/*===========================================*/
+
+ index = dict_table_get_next_index(index);
+ }
+
+ mem_heap_free(heap);
+ return(TRUE);
+}
+
+static
+void
+dict_store_statistics(
+/*==================*/
+ dict_table_t* table)
+{
+ dict_index_t* index;
+ mem_heap_t* heap;
+
+ index = dict_table_get_first_index(table);
+
+ ut_a(index);
+
+ heap = mem_heap_create(1000);
+
+ while (index) {
+ if (table->is_corrupt) {
+ ut_a(srv_pass_corrupt_table);
+ mem_heap_free(heap);
+ return;
+ }
+
+/*===========================================*/
+{
+ dict_table_t* sys_stats;
+ dict_index_t* sys_index;
+ btr_pcur_t pcur;
+ dtuple_t* tuple;
+ dfield_t* dfield;
+ ulint key_cols;
+ ulint n_cols;
+ ulint rests;
+ const rec_t* rec;
+ const byte* field;
+ ulint len;
+ ib_int64_t* stat_n_diff_key_vals_tmp;
+ byte* buf;
+ ulint i;
+ mtr_t mtr;
+
+ n_cols = dict_index_get_n_unique(index);
+ stat_n_diff_key_vals_tmp = mem_heap_zalloc(heap, (n_cols + 1) * sizeof(ib_int64_t));
+
+ dict_index_stat_mutex_enter(index);
+ for (i = 0; i <= n_cols; i++) {
+ stat_n_diff_key_vals_tmp[i] = index->stat_n_diff_key_vals[i];
+ }
+ dict_index_stat_mutex_exit(index);
+
+ sys_stats = dict_sys->sys_stats;
+ sys_index = UT_LIST_GET_FIRST(sys_stats->indexes);
+ ut_a(!dict_table_is_comp(sys_stats));
+
+ tuple = dtuple_create(heap, 1);
+ dfield = dtuple_get_nth_field(tuple, 0);
+
+ buf = mem_heap_alloc(heap, 8);
+ mach_write_to_8(buf, index->id);
+
+ dfield_set_data(dfield, buf, 8);
+ dict_index_copy_types(tuple, sys_index, 1);
+
+ mtr_start(&mtr);
+
+ btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
+ BTR_MODIFY_LEAF, &pcur, &mtr);
+ rests = n_cols + 1;
+ for (i = 0; i <= n_cols; i++) {
+ rec = btr_pcur_get_rec(&pcur);
+
+ if (!btr_pcur_is_on_user_rec(&pcur)
+ || ut_dulint_cmp(mach_read_from_8(rec_get_nth_field_old(rec, 0, &len)),
+ index->id)) {
+ /* not found */
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+ break;
+ }
+
+ if (rec_get_deleted_flag(rec, 0)) {
+ goto next_rec;
+ }
+
+ field = rec_get_nth_field_old(rec, 1, &len);
+ ut_a(len == 4);
+
+ key_cols = mach_read_from_4(field);
+
+ field = rec_get_nth_field_old(rec, DICT_SYS_STATS_DIFF_VALS_FIELD, &len);
+ ut_a(len == 8);
+
+ mlog_write_dulint((byte*)field,
+ ut_dulint_create((ulint) (stat_n_diff_key_vals_tmp[key_cols] >> 32),
+ (ulint) stat_n_diff_key_vals_tmp[key_cols] & 0xFFFFFFFF),
+ &mtr);
+
+ rests--;
+
+next_rec:
+ btr_pcur_move_to_next_user_rec(&pcur, &mtr);
+ }
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+
+ if (rests) {
+ fprintf(stderr, "InnoDB: Warning: failed to store %lu stats entries"
+ " of %s/%s to SYS_STATS system table.\n",
+ rests, index->table_name, index->name);
+ }
+}
+/*===========================================*/
+
+ index = dict_table_get_next_index(index);
+ }
+
+ mem_heap_free(heap);
+}
+
+/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
@@ -4226,9 +4508,10 @@ void
dict_update_statistics_low(
/*=======================*/
dict_table_t* table, /*!< in/out: table */
- ibool has_dict_mutex __attribute__((unused)))
+ ibool has_dict_mutex __attribute__((unused)),
/*!< in: TRUE if the caller has the
dictionary mutex */
+ ibool sync) /*!< in: TRUE if must update SYS_STATS */
{
dict_index_t* index;
ulint size;
@@ -4254,6 +4537,23 @@ dict_update_statistics_low(
return;
}
+ if (srv_use_sys_stats_table && !sync) {
+ /* reload statistics from SYS_STATS table */
+ if (dict_reload_statistics(table, &sum_of_index_sizes)) {
+ /* success */
+#ifdef UNIV_DEBUG
+ fprintf(stderr, "InnoDB: DEBUG: reload_statistics is scceeded for %s.\n",
+ table->name);
+#endif
+ goto end;
+ }
+ }
+#ifdef UNIV_DEBUG
+ fprintf(stderr, "InnoDB: DEBUG: update_statistics for %s.\n",
+ table->name);
+#endif
+ sum_of_index_sizes = 0;
+
/* Find out the sizes of the indexes and how many different values
for the key they approximately have */
@@ -4291,6 +4591,11 @@ dict_update_statistics_low(
index = dict_table_get_next_index(index);
}
+ if (srv_use_sys_stats_table) {
+ /* store statistics to SYS_STATS table */
+ dict_store_statistics(table);
+ }
+end:
index = dict_table_get_first_index(table);
dict_index_stat_mutex_enter(index);
@@ -4317,9 +4622,10 @@ UNIV_INTERN
void
dict_update_statistics(
/*===================*/
- dict_table_t* table) /*!< in/out: table */
+ dict_table_t* table, /*!< in/out: table */
+ ibool sync)
{
- dict_update_statistics_low(table, FALSE);
+ dict_update_statistics_low(table, FALSE, sync);
}
/**********************************************************************//**
@@ -4400,7 +4706,7 @@ dict_table_print_low(
ut_ad(mutex_own(&(dict_sys->mutex)));
if (srv_stats_auto_update)
- dict_update_statistics_low(table, TRUE);
+ dict_update_statistics_low(table, TRUE, FALSE);
fprintf(stderr,
"--------------------------------------\n"
diff --git a/storage/xtradb/dict/dict0load.c b/storage/xtradb/dict/dict0load.c
index 528c3786254..0d8292cc2bf 100644
--- a/storage/xtradb/dict/dict0load.c
+++ b/storage/xtradb/dict/dict0load.c
@@ -223,7 +223,7 @@ loop:
is no index */
if (srv_stats_auto_update && dict_table_get_first_index(table)) {
- dict_update_statistics_low(table, TRUE);
+ dict_update_statistics_low(table, TRUE, FALSE);
}
dict_table_print_low(table);
@@ -317,7 +317,7 @@ dict_check_tablespaces_and_store_max_id(
dict_index_t* sys_index;
btr_pcur_t pcur;
const rec_t* rec;
- ulint max_space_id = 0;
+ ulint max_space_id;
mtr_t mtr;
mutex_enter(&(dict_sys->mutex));
@@ -328,6 +328,11 @@ dict_check_tablespaces_and_store_max_id(
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
ut_a(!dict_table_is_comp(sys_tables));
+ max_space_id = mtr_read_ulint(dict_hdr_get(&mtr)
+ + DICT_HDR_MAX_SPACE_ID,
+ MLOG_4BYTES, &mtr);
+ fil_set_max_space_id_if_bigger(max_space_id);
+
btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur,
TRUE, &mtr);
loop:
@@ -974,6 +979,7 @@ err_exit:
/* Try to open the tablespace */
if (!fil_open_single_table_tablespace(
TRUE, space,
+ flags == DICT_TF_COMPACT ? 0 :
flags & ~(~0 << DICT_TF_BITS), name)) {
/* We failed to find a sensible
tablespace file */
diff --git a/storage/xtradb/dict/dict0mem.c b/storage/xtradb/dict/dict0mem.c
index 388d46568ac..f2d219bfd4f 100644
--- a/storage/xtradb/dict/dict0mem.c
+++ b/storage/xtradb/dict/dict0mem.c
@@ -68,7 +68,8 @@ dict_mem_table_create(
table->heap = heap;
table->flags = (unsigned int) flags;
- table->name = mem_heap_strdup(heap, name);
+ table->name = ut_malloc(strlen(name) + 1);
+ memcpy(table->name, name, strlen(name) + 1);
table->space = (unsigned int) space;
table->n_cols = (unsigned int) (n_cols + DATA_N_SYS_COLS);
@@ -108,6 +109,7 @@ dict_mem_table_free(
#ifndef UNIV_HOTBACKUP
mutex_free(&(table->autoinc_mutex));
#endif /* UNIV_HOTBACKUP */
+ ut_free(table->name);
mem_heap_free(table->heap);
}
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index 189c0e706f9..0139fa0cce5 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -43,8 +43,8 @@ Created 10/25/1995 Heikki Tuuri
#include "trx0trx.h"
#include "trx0sys.h"
#include "pars0pars.h"
-#include "row0row.h"
#include "row0mysql.h"
+#include "row0row.h"
#include "que0que.h"
#ifndef UNIV_HOTBACKUP
# include "buf0lru.h"
@@ -286,6 +286,10 @@ struct fil_system_struct {
request */
UT_LIST_BASE_NODE_T(fil_space_t) space_list;
/*!< list of all file spaces */
+ ibool space_id_reuse_warned;
+ /* !< TRUE if fil_space_create()
+ has issued a warning about
+ potential space_id reuse */
};
/** The tablespace memory cache. This variable is NULL before the module is
@@ -1200,7 +1204,19 @@ try_again:
space->tablespace_version = fil_system->tablespace_version;
space->mark = FALSE;
- if (purpose == FIL_TABLESPACE && id > fil_system->max_assigned_id) {
+ if (UNIV_LIKELY(purpose == FIL_TABLESPACE && !recv_recovery_on)
+ && UNIV_UNLIKELY(id > fil_system->max_assigned_id)) {
+ if (!fil_system->space_id_reuse_warned) {
+ fil_system->space_id_reuse_warned = TRUE;
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Warning: allocated tablespace %lu,"
+ " old maximum was %lu\n",
+ (ulong) id,
+ (ulong) fil_system->max_assigned_id);
+ }
+
fil_system->max_assigned_id = id;
}
@@ -1240,19 +1256,25 @@ try_again:
Assigns a new space id for a new single-table tablespace. This works simply by
incrementing the global counter. If 4 billion id's is not enough, we may need
to recycle id's.
-@return new tablespace id; ULINT_UNDEFINED if could not assign an id */
-static
-ulint
-fil_assign_new_space_id(void)
-/*=========================*/
+@return TRUE if assigned, FALSE if not */
+UNIV_INTERN
+ibool
+fil_assign_new_space_id(
+/*====================*/
+ ulint* space_id) /*!< in/out: space id */
{
- ulint id;
+ ulint id;
+ ibool success;
mutex_enter(&fil_system->mutex);
- fil_system->max_assigned_id++;
+ id = *space_id;
- id = fil_system->max_assigned_id;
+ if (id < fil_system->max_assigned_id) {
+ id = fil_system->max_assigned_id;
+ }
+
+ id++;
if (id > (SRV_LOG_SPACE_FIRST_ID / 2) && (id % 1000000UL == 0)) {
ut_print_timestamp(stderr);
@@ -1268,7 +1290,11 @@ fil_assign_new_space_id(void)
(ulong) SRV_LOG_SPACE_FIRST_ID);
}
- if (id >= SRV_LOG_SPACE_FIRST_ID) {
+ success = (id < SRV_LOG_SPACE_FIRST_ID);
+
+ if (success) {
+ *space_id = fil_system->max_assigned_id = id;
+ } else {
ut_print_timestamp(stderr);
fprintf(stderr,
"InnoDB: You have run out of single-table"
@@ -1278,14 +1304,12 @@ fil_assign_new_space_id(void)
" have to dump all your tables and\n"
"InnoDB: recreate the whole InnoDB installation.\n",
(ulong) id);
- fil_system->max_assigned_id--;
-
- id = ULINT_UNDEFINED;
+ *space_id = ULINT_UNDEFINED;
}
mutex_exit(&fil_system->mutex);
- return(id);
+ return(success);
}
/*******************************************************************//**
@@ -1521,7 +1545,7 @@ fil_init(
ut_a(hash_size > 0);
ut_a(max_n_open > 0);
- fil_system = mem_alloc(sizeof(fil_system_t));
+ fil_system = mem_zalloc(sizeof(fil_system_t));
mutex_create(&fil_system->mutex, SYNC_ANY_LATCH);
@@ -1530,16 +1554,9 @@ fil_init(
UT_LIST_INIT(fil_system->LRU);
- fil_system->n_open = 0;
fil_system->max_n_open = max_n_open;
- fil_system->modification_counter = 0;
fil_system->max_assigned_id = TRX_SYS_SPACE_MAX;
-
- fil_system->tablespace_version = 0;
-
- UT_LIST_INIT(fil_system->unflushed_spaces);
- UT_LIST_INIT(fil_system->space_list);
}
/*******************************************************************//**
@@ -2124,7 +2141,7 @@ fil_op_log_parse_or_replay(
fil_create_directory_for_tablename(name);
if (fil_create_new_single_table_tablespace(
- &space_id, name, FALSE, flags,
+ space_id, name, FALSE, flags,
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
ut_error;
}
@@ -2571,9 +2588,7 @@ UNIV_INTERN
ulint
fil_create_new_single_table_tablespace(
/*===================================*/
- ulint* space_id, /*!< in/out: space id; if this is != 0,
- then this is an input parameter,
- otherwise output */
+ ulint space_id, /*!< in: space id */
const char* tablename, /*!< in: the table name in the usual
databasename/tablename format
of InnoDB, or a dir path to a temp
@@ -2593,6 +2608,8 @@ fil_create_new_single_table_tablespace(
ibool success;
char* path;
+ ut_a(space_id > 0);
+ ut_a(space_id < SRV_LOG_SPACE_FIRST_ID);
ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
ROW_FORMAT=COMPACT
@@ -2649,38 +2666,21 @@ fil_create_new_single_table_tablespace(
return(DB_ERROR);
}
- buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
- /* Align the memory for file i/o if we might have O_DIRECT set */
- page = ut_align(buf2, UNIV_PAGE_SIZE);
-
ret = os_file_set_size(path, file, size * UNIV_PAGE_SIZE, 0);
if (!ret) {
- ut_free(buf2);
- os_file_close(file);
- os_file_delete(path);
-
- mem_free(path);
- return(DB_OUT_OF_FILE_SPACE);
- }
-
- if (*space_id == 0) {
- *space_id = fil_assign_new_space_id();
- }
-
- /* printf("Creating tablespace %s id %lu\n", path, *space_id); */
-
- if (*space_id == ULINT_UNDEFINED) {
- ut_free(buf2);
+ err = DB_OUT_OF_FILE_SPACE;
error_exit:
os_file_close(file);
error_exit2:
os_file_delete(path);
mem_free(path);
- return(DB_ERROR);
+ return(err);
}
+ /* printf("Creating tablespace %s id %lu\n", path, space_id); */
+
/* We have to write the space id to the file immediately and flush the
file to disk. This is because in crash recovery we must be aware what
tablespaces exist and what are their space id's, so that we can apply
@@ -2690,10 +2690,14 @@ error_exit2:
with zeros from the call of os_file_set_size(), until a buffer pool
flush would write to it. */
+ buf2 = ut_malloc(3 * UNIV_PAGE_SIZE);
+ /* Align the memory for file i/o if we might have O_DIRECT set */
+ page = ut_align(buf2, UNIV_PAGE_SIZE);
+
memset(page, '\0', UNIV_PAGE_SIZE);
- fsp_header_init_fields(page, *space_id, flags);
- mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, *space_id);
+ fsp_header_init_fields(page, space_id, flags);
+ mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id);
if (!(flags & DICT_TF_ZSSIZE_MASK)) {
buf_flush_init_for_writing(page, NULL, 0);
@@ -2724,6 +2728,7 @@ error_exit2:
" to tablespace ", stderr);
ut_print_filename(stderr, path);
putc('\n', stderr);
+ err = DB_ERROR;
goto error_exit;
}
@@ -2733,22 +2738,20 @@ error_exit2:
fputs("InnoDB: Error: file flush of tablespace ", stderr);
ut_print_filename(stderr, path);
fputs(" failed\n", stderr);
+ err = DB_ERROR;
goto error_exit;
}
os_file_close(file);
- if (*space_id == ULINT_UNDEFINED) {
- goto error_exit2;
- }
-
- success = fil_space_create(path, *space_id, flags, FIL_TABLESPACE);
+ success = fil_space_create(path, space_id, flags, FIL_TABLESPACE);
if (!success) {
+ err = DB_ERROR;
goto error_exit2;
}
- fil_node_create(path, size, *space_id, FALSE);
+ fil_node_create(path, size, space_id, FALSE);
#ifndef UNIV_HOTBACKUP
{
@@ -2759,7 +2762,7 @@ error_exit2:
fil_op_write_log(flags
? MLOG_FILE_CREATE2
: MLOG_FILE_CREATE,
- *space_id,
+ space_id,
is_temp ? MLOG_FILE_FLAG_TEMP : 0,
flags,
tablename, NULL, &mtr);
@@ -3124,7 +3127,7 @@ fil_open_single_table_tablespace(
for (i = 0; i < n_index; i++) {
new_id[i] =
dict_table_get_index_on_name(table,
- (page + (i + 1) * 512 + 12))->id;
+ (char*)(page + (i + 1) * 512 + 12))->id;
old_id[i] = mach_read_from_8(page + (i + 1) * 512);
root_page[i] = mach_read_from_4(page + (i + 1) * 512 + 8);
}
@@ -3148,7 +3151,7 @@ skip_info:
/* over write space id of all pages */
rec_offs_init(offsets_);
- fprintf(stderr, "%s", "InnoDB: Progress in %:");
+ fprintf(stderr, "InnoDB: Progress in %%:");
for (offset = 0; offset < size_bytes; offset += UNIV_PAGE_SIZE) {
ulint checksum_field;
@@ -3890,39 +3893,6 @@ next_datadir_item:
return(err);
}
-/********************************************************************//**
-If we need crash recovery, and we have called
-fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(),
-we can call this function to print an error message of orphaned .ibd files
-for which there is not a data dictionary entry with a matching table name
-and space id. */
-UNIV_INTERN
-void
-fil_print_orphaned_tablespaces(void)
-/*================================*/
-{
- fil_space_t* space;
-
- mutex_enter(&fil_system->mutex);
-
- space = UT_LIST_GET_FIRST(fil_system->space_list);
-
- while (space) {
- if (space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(space->id)
- && !space->mark) {
- fputs("InnoDB: Warning: tablespace ", stderr);
- ut_print_filename(stderr, space->name);
- fprintf(stderr, " of id %lu has no matching table in\n"
- "InnoDB: the InnoDB data dictionary.\n",
- (ulong) space->id);
- }
-
- space = UT_LIST_GET_NEXT(space_list, space);
- }
-
- mutex_exit(&fil_system->mutex);
-}
-
/*******************************************************************//**
Returns TRUE if a single-table tablespace does not exist in the memory cache,
or is being deleted there.
diff --git a/storage/xtradb/ha/hash0hash.c b/storage/xtradb/ha/hash0hash.c
index 30c304dafcd..70516deb005 100644
--- a/storage/xtradb/ha/hash0hash.c
+++ b/storage/xtradb/ha/hash0hash.c
@@ -128,6 +128,70 @@ hash_create(
}
/*************************************************************//**
+*/
+UNIV_INTERN
+ulint
+hash_create_needed(
+/*===============*/
+ ulint n)
+{
+ ulint prime;
+ ulint offset;
+
+ prime = ut_find_prime(n);
+
+ offset = (sizeof(hash_table_t) + 7) / 8;
+ offset *= 8;
+
+ return(offset + sizeof(hash_cell_t) * prime);
+}
+
+UNIV_INTERN
+void
+hash_create_init(
+/*=============*/
+ hash_table_t* table,
+ ulint n)
+{
+ ulint prime;
+ ulint offset;
+
+ prime = ut_find_prime(n);
+
+ offset = (sizeof(hash_table_t) + 7) / 8;
+ offset *= 8;
+
+ table->array = (hash_cell_t*)(((char*)table) + offset);
+ table->n_cells = prime;
+# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+ table->adaptive = FALSE;
+# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+ table->n_mutexes = 0;
+ table->mutexes = NULL;
+ table->heaps = NULL;
+ table->heap = NULL;
+ ut_d(table->magic_n = HASH_TABLE_MAGIC_N);
+
+ /* Initialize the cell array */
+ hash_table_clear(table);
+}
+
+UNIV_INTERN
+void
+hash_create_reuse(
+/*==============*/
+ hash_table_t* table)
+{
+ ulint offset;
+
+ offset = (sizeof(hash_table_t) + 7) / 8;
+ offset *= 8;
+
+ table->array = (hash_cell_t*)(((char*)table) + offset);
+ ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
+}
+
+/*************************************************************//**
Frees a hash table. */
UNIV_INTERN
void
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 68da379b841..5b1ab98ea03 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -193,6 +193,7 @@ static my_bool innobase_overwrite_relay_log_info = FALSE;
static my_bool innobase_rollback_on_timeout = FALSE;
static my_bool innobase_create_status_file = FALSE;
static my_bool innobase_stats_on_metadata = TRUE;
+static my_bool innobase_use_sys_stats_table = FALSE;
static char* internal_innobase_data_file_path = NULL;
@@ -336,6 +337,12 @@ static MYSQL_THDVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
"Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
+static MYSQL_THDVAR_ULONG(flush_log_at_trx_commit_session, PLUGIN_VAR_RQCMDARG,
+ "Control innodb_flush_log_at_trx_commit for each sessions. "
+ "The value 0~2 are same meanings to innodb_flush_log_at_trx_commit. "
+ "The value 3 regards innodb_flush_log_at_trx_commit (default).",
+ NULL, NULL, 3, 0, 3, 0);
+
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
@@ -716,6 +723,17 @@ thd_lock_wait_timeout(
return(THDVAR((THD*) thd, lock_wait_timeout));
}
+/******************************************************************//**
+*/
+extern "C" UNIV_INTERN
+ulong
+thd_flush_log_at_trx_commit_session(
+/*================================*/
+ void* thd)
+{
+ return(THDVAR((THD*) thd, flush_log_at_trx_commit_session));
+}
+
/********************************************************************//**
Obtain the InnoDB transaction of a MySQL thread.
@return reference to transaction pointer */
@@ -1031,6 +1049,29 @@ innobase_get_charset(
return(thd_charset((THD*) mysql_thd));
}
+/**********************************************************************//**
+Determines the current SQL statement.
+@return SQL statement string */
+extern "C" UNIV_INTERN
+const char*
+innobase_get_stmt(
+/*==============*/
+ void* mysql_thd, /*!< in: MySQL thread handle */
+ size_t* length) /*!< out: length of the SQL statement */
+{
+#if MYSQL_VERSION_ID >= 50142
+ LEX_STRING* stmt;
+
+ stmt = thd_query_string((THD*) mysql_thd);
+ *length = stmt->length;
+ return(stmt->str);
+#else
+ const char* stmt_str = thd_query((THD*) mysql_thd);
+ *length = strlen(stmt_str);
+ return(stmt_str);
+#endif
+}
+
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
/*******************************************************************//**
@@ -1351,7 +1392,6 @@ innobase_trx_allocate(
trx = trx_allocate_for_mysql();
trx->mysql_thd = thd;
- trx->mysql_query_str = thd_query(thd);
innobase_trx_init(thd, trx);
@@ -2035,12 +2075,12 @@ innobase_init(
srv_page_size_shift = 0;
if (innobase_page_size != (1 << 14)) {
- int n_shift;
+ uint n_shift;
fprintf(stderr,
"InnoDB: Warning: innodb_page_size has been changed from default value 16384. (###EXPERIMENTAL### operation)\n");
for (n_shift = 12; n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX; n_shift++) {
- if (innobase_page_size == (1u << n_shift)) {
+ if (innobase_page_size == ((ulong)1 << n_shift)) {
srv_page_size_shift = n_shift;
srv_page_size = (1 << srv_page_size_shift);
fprintf(stderr,
@@ -2231,6 +2271,8 @@ mem_free_and_error:
srv_extra_undoslots = (ibool) innobase_extra_undoslots;
+ srv_use_sys_stats_table = (ibool) innobase_use_sys_stats_table;
+
/* -------------- Log files ---------------------------*/
/* The default dir for log files is the datadir of MySQL */
@@ -5710,6 +5752,9 @@ ha_innobase::index_read(
prebuilt->index_usable = FALSE;
DBUG_RETURN(HA_ERR_CRASHED);
}
+ if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
+ DBUG_RETURN(HA_ERR_TABLE_DEF_CHANGED);
+ }
/* Note that if the index for which the search template is built is not
necessarily prebuilt->index, but can also be the clustered index */
@@ -6825,6 +6870,9 @@ ha_innobase::create(
/* Cache the value of innodb_file_format, in case it is
modified by another thread while the table is being created. */
const ulint file_format = srv_file_format;
+ const char* stmt;
+ size_t stmt_len;
+ enum row_type row_type;
DBUG_ENTER("ha_innobase::create");
@@ -6945,94 +6993,94 @@ ha_innobase::create(
}
}
- if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) {
- if (flags) {
- /* KEY_BLOCK_SIZE was specified. */
- if (form->s->row_type != ROW_TYPE_COMPRESSED) {
- /* ROW_FORMAT other than COMPRESSED
- ignores KEY_BLOCK_SIZE. It does not
- make sense to reject conflicting
- KEY_BLOCK_SIZE and ROW_FORMAT, because
- such combinations can be obtained
- with ALTER TABLE anyway. */
- push_warning_printf(
- thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ignoring KEY_BLOCK_SIZE=%lu"
- " unless ROW_FORMAT=COMPRESSED.",
- create_info->key_block_size);
- flags = 0;
- }
- } else {
- /* No KEY_BLOCK_SIZE */
- if (form->s->row_type == ROW_TYPE_COMPRESSED) {
- /* ROW_FORMAT=COMPRESSED without
- KEY_BLOCK_SIZE implies half the
- maximum KEY_BLOCK_SIZE. */
- flags = (DICT_TF_ZSSIZE_MAX - 1)
- << DICT_TF_ZSSIZE_SHIFT
- | DICT_TF_COMPACT
- | DICT_TF_FORMAT_ZIP
- << DICT_TF_FORMAT_SHIFT;
+ row_type = form->s->row_type;
+
+ if (flags) {
+ /* KEY_BLOCK_SIZE was specified. */
+ if (!(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) {
+ /* ROW_FORMAT was not specified;
+ default to ROW_FORMAT=COMPRESSED */
+ row_type = ROW_TYPE_COMPRESSED;
+ } else if (row_type != ROW_TYPE_COMPRESSED) {
+ /* ROW_FORMAT other than COMPRESSED
+ ignores KEY_BLOCK_SIZE. It does not
+ make sense to reject conflicting
+ KEY_BLOCK_SIZE and ROW_FORMAT, because
+ such combinations can be obtained
+ with ALTER TABLE anyway. */
+ push_warning_printf(
+ thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: ignoring KEY_BLOCK_SIZE=%lu"
+ " unless ROW_FORMAT=COMPRESSED.",
+ create_info->key_block_size);
+ flags = 0;
+ }
+ } else {
+ /* No KEY_BLOCK_SIZE */
+ if (row_type == ROW_TYPE_COMPRESSED) {
+ /* ROW_FORMAT=COMPRESSED without
+ KEY_BLOCK_SIZE implies half the
+ maximum KEY_BLOCK_SIZE. */
+ flags = (DICT_TF_ZSSIZE_MAX - 1)
+ << DICT_TF_ZSSIZE_SHIFT
+ | DICT_TF_COMPACT
+ | DICT_TF_FORMAT_ZIP
+ << DICT_TF_FORMAT_SHIFT;
//#if DICT_TF_ZSSIZE_MAX < 1
//# error "DICT_TF_ZSSIZE_MAX < 1"
//#endif
- }
}
+ }
- switch (form->s->row_type) {
- const char* row_format_name;
- case ROW_TYPE_REDUNDANT:
- break;
- case ROW_TYPE_COMPRESSED:
- case ROW_TYPE_DYNAMIC:
- row_format_name
- = form->s->row_type == ROW_TYPE_COMPRESSED
- ? "COMPRESSED"
- : "DYNAMIC";
-
- if (!srv_file_per_table) {
- push_warning_printf(
- thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ROW_FORMAT=%s"
- " requires innodb_file_per_table.",
- row_format_name);
- } else if (file_format < DICT_TF_FORMAT_ZIP) {
- push_warning_printf(
- thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ROW_FORMAT=%s"
- " requires innodb_file_format >"
- " Antelope.",
- row_format_name);
- } else {
- flags |= DICT_TF_COMPACT
- | (DICT_TF_FORMAT_ZIP
- << DICT_TF_FORMAT_SHIFT);
- break;
- }
+ switch (row_type) {
+ const char* row_format_name;
+ case ROW_TYPE_REDUNDANT:
+ break;
+ case ROW_TYPE_COMPRESSED:
+ case ROW_TYPE_DYNAMIC:
+ row_format_name
+ = row_type == ROW_TYPE_COMPRESSED
+ ? "COMPRESSED"
+ : "DYNAMIC";
- /* fall through */
- case ROW_TYPE_NOT_USED:
- case ROW_TYPE_FIXED:
- default:
- push_warning(thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: assuming ROW_FORMAT=COMPACT.");
- case ROW_TYPE_DEFAULT:
- case ROW_TYPE_COMPACT:
- flags = DICT_TF_COMPACT;
+ if (!srv_file_per_table) {
+ push_warning_printf(
+ thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: ROW_FORMAT=%s"
+ " requires innodb_file_per_table.",
+ row_format_name);
+ } else if (file_format < DICT_TF_FORMAT_ZIP) {
+ push_warning_printf(
+ thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: ROW_FORMAT=%s"
+ " requires innodb_file_format >"
+ " Antelope.",
+ row_format_name);
+ } else {
+ flags |= DICT_TF_COMPACT
+ | (DICT_TF_FORMAT_ZIP
+ << DICT_TF_FORMAT_SHIFT);
break;
}
- } else if (!flags) {
- /* No KEY_BLOCK_SIZE or ROW_FORMAT specified:
- use ROW_FORMAT=COMPACT by default. */
+
+ /* fall through */
+ case ROW_TYPE_NOT_USED:
+ case ROW_TYPE_FIXED:
+ default:
+ push_warning(thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: assuming ROW_FORMAT=COMPACT.");
+ case ROW_TYPE_DEFAULT:
+ case ROW_TYPE_COMPACT:
flags = DICT_TF_COMPACT;
+ break;
}
/* Look for a primary key */
@@ -7041,7 +7089,7 @@ ha_innobase::create(
(int) form->s->primary_key :
-1);
- /* Our function row_get_mysql_key_number_for_index assumes
+ /* Our function innobase_get_mysql_key_number_for_index assumes
the primary key is always number 0, if it exists */
ut_a(primary_key_no == -1 || primary_key_no == 0);
@@ -7101,9 +7149,11 @@ ha_innobase::create(
}
}
- if (*trx->mysql_query_str) {
- error = row_table_add_foreign_constraints(trx,
- *trx->mysql_query_str, norm_name,
+ stmt = innobase_get_stmt(thd, &stmt_len);
+
+ if (stmt) {
+ error = row_table_add_foreign_constraints(
+ trx, stmt, stmt_len, norm_name,
create_info->options & HA_LEX_CREATE_TMP_TABLE);
error = convert_error_code_to_mysql(error, flags, NULL);
@@ -7396,7 +7446,6 @@ innobase_drop_database(
/* In the Windows plugin, thd = current_thd is always NULL */
trx = trx_allocate_for_mysql();
trx->mysql_thd = NULL;
- trx->mysql_query_str = NULL;
#else
trx = innobase_trx_allocate(thd);
#endif
@@ -7598,6 +7647,10 @@ ha_innobase::records_in_range(
n_rows = HA_POS_ERROR;
goto func_exit;
}
+ if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) {
+ n_rows = HA_ERR_TABLE_DEF_CHANGED;
+ goto func_exit;
+ }
heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
+ sizeof(dtuple_t)));
@@ -7777,6 +7830,86 @@ ha_innobase::is_corrupt() const
}
/*********************************************************************//**
+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
+@return the key number used inside MySQL */
+static
+unsigned int
+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
+ dictionary */
+ const dict_index_t* index) /*!< in: index */
+{
+ const dict_index_t* ind;
+ unsigned int i;
+
+ ut_ad(index);
+ ut_ad(ib_table);
+ ut_ad(table);
+ ut_ad(share);
+
+ /* If index does not belong to the table of share structure. Search
+ index->table instead */
+ if (index->table != ib_table) {
+ i = 0;
+ ind = dict_table_get_first_index(index->table);
+
+ while (index != ind) {
+ ind = dict_table_get_next_index(ind);
+ i++;
+ }
+
+ if (row_table_got_default_clust_index(index->table)) {
+ ut_a(i > 0);
+ i--;
+ }
+
+ 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) {
+ 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". */
+ 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 in the 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);
+
+ if (index == ind) {
+ return(i);
+ }
+ }
+
+ sql_print_error("Cannot find matching index number for index %s "
+ "in InnoDB index list.", index->name);
+
+ return(0);
+}
+/*********************************************************************//**
Returns statistics information of the table to the MySQL interpreter,
in various fields of the handle object. */
UNIV_INTERN
@@ -7833,9 +7966,30 @@ ha_innobase::info(
/* In sql_show we call with this flag: update
then statistics so that they are up-to-date */
+ if (srv_use_sys_stats_table
+ && thd_sql_command(user_thd) == SQLCOM_ANALYZE) {
+ /* If the indexes on the table don't have enough rows in SYS_STATS system table, */
+ /* they need to be created. */
+ dict_index_t* index;
+
+ prebuilt->trx->op_info = "confirming rows of SYS_STATS to store statistics";
+
+ ut_a(prebuilt->trx->conc_state == TRX_NOT_STARTED);
+
+ for (index = dict_table_get_first_index(ib_table);
+ index != NULL;
+ index = dict_table_get_next_index(index)) {
+ row_insert_stats_for_mysql(index, prebuilt->trx);
+ innobase_commit_low(prebuilt->trx);
+ }
+
+ ut_a(prebuilt->trx->conc_state == TRX_NOT_STARTED);
+ }
+
prebuilt->trx->op_info = "updating table statistics";
- dict_update_statistics(ib_table);
+ dict_update_statistics(ib_table,
+ (thd_sql_command(user_thd) == SQLCOM_ANALYZE)?TRUE:FALSE);
prebuilt->trx->op_info = "returning various info to MySQL";
}
@@ -8047,8 +8201,8 @@ ha_innobase::info(
err_index = trx_get_error_info(prebuilt->trx);
if (err_index) {
- errkey = (unsigned int)
- row_get_mysql_key_number_for_index(err_index);
+ errkey = innobase_get_mysql_key_number_for_index(
+ share, table, ib_table, err_index);
} else {
errkey = (unsigned int) prebuilt->trx->error_key_num;
}
@@ -10815,7 +10969,35 @@ innodb_old_blocks_pct_update(
}
/*************************************************************//**
-Check if it is a valid value of innodb_change_buffering. This function is
+Find the corresponding ibuf_use_t value that indexes into
+innobase_change_buffering_values[] array for the input
+change buffering option name.
+@return corresponding IBUF_USE_* value for the input variable
+name, or IBUF_USE_COUNT if not able to find a match */
+static
+ibuf_use_t
+innodb_find_change_buffering_value(
+/*===============================*/
+ const char* input_name) /*!< in: input change buffering
+ option name */
+{
+ ulint use;
+
+ for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
+ use++) {
+ /* found a match */
+ if (!innobase_strcasecmp(
+ input_name, innobase_change_buffering_values[use])) {
+ return((ibuf_use_t)use);
+ }
+ }
+
+ /* Did not find any match */
+ return(IBUF_USE_COUNT);
+}
+
+/*************************************************************//**
+Check if it is a valid value of innodb_change_buffering. This function is
registered as a callback with MySQL.
@return 0 for valid innodb_change_buffering */
static
@@ -10839,19 +11021,22 @@ innodb_change_buffering_validate(
change_buffering_input = value->val_str(value, buff, &len);
if (change_buffering_input != NULL) {
- ulint use;
+ ibuf_use_t use;
- for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
- use++) {
- if (!innobase_strcasecmp(
- change_buffering_input,
- innobase_change_buffering_values[use])) {
- *(ibuf_use_t*) save = (ibuf_use_t) use;
- return(0);
- }
+ use = innodb_find_change_buffering_value(
+ change_buffering_input);
+
+ if (use != IBUF_USE_COUNT) {
+ /* Find a matching change_buffering option value. */
+ *static_cast<const char**>(save) =
+ innobase_change_buffering_values[use];
+
+ return(0);
}
}
+ /* No corresponding change buffering option for user supplied
+ "change_buffering_input" */
return(1);
}
@@ -10862,21 +11047,27 @@ static
void
innodb_change_buffering_update(
/*===========================*/
- THD* thd, /*!< in: thread handle */
- struct st_mysql_sys_var* var, /*!< in: pointer to
- system variable */
- void* var_ptr, /*!< out: where the
- formal string goes */
- const void* save) /*!< in: immediate result
- from check function */
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
+ system variable */
+ void* var_ptr,/*!< out: where the
+ formal string goes */
+ const void* save) /*!< in: immediate result
+ from check function */
{
+ ibuf_use_t use;
+
ut_a(var_ptr != NULL);
ut_a(save != NULL);
- ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
- ibuf_use = *(const ibuf_use_t*) save;
+ use = innodb_find_change_buffering_value(
+ *static_cast<const char*const*>(save));
+
+ ut_a(use < IBUF_USE_COUNT);
- *(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
+ ibuf_use = use;
+ *static_cast<const char**>(var_ptr) =
+ *static_cast<const char*const*>(save);
}
static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
@@ -11142,6 +11333,14 @@ static MYSQL_SYSVAR_ULINT(stats_update_need_lock, srv_stats_update_need_lock,
"e.g. Data_free.",
NULL, NULL, 1, 0, 1, 0);
+static MYSQL_SYSVAR_BOOL(use_sys_stats_table, innobase_use_sys_stats_table,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Enable to use SYS_STATS system table to store statistics statically, "
+ "And avoids to calculate statistics at every first open of the tables. "
+ "This option may make the opportunities of update statistics less. "
+ "So you should use ANALYZE TABLE command intentionally.",
+ NULL, NULL, FALSE);
+
static MYSQL_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
PLUGIN_VAR_OPCMDARG,
"Enable InnoDB adaptive hash index (enabled by default). "
@@ -11167,7 +11366,12 @@ static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment,
static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
- NULL, NULL, 128*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L);
+ NULL, NULL, 128*1024*1024L, 32*1024*1024L, LONGLONG_MAX, 1024*1024L);
+
+static MYSQL_SYSVAR_UINT(buffer_pool_shm_key, srv_buffer_pool_shm_key,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "[experimental] The key value of shared memory segment for the buffer pool. 0 means disable the feature (default).",
+ NULL, NULL, 0, 0, INT_MAX32, 0);
static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
PLUGIN_VAR_RQCMDARG,
@@ -11298,7 +11502,7 @@ static MYSQL_SYSVAR_STR(change_buffering, innobase_change_buffering,
"Buffer changes to reduce random access: "
"OFF, ON, none, inserts.",
innodb_change_buffering_validate,
- innodb_change_buffering_update, NULL);
+ innodb_change_buffering_update, "inserts");
static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
PLUGIN_VAR_RQCMDARG,
@@ -11428,6 +11632,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
MYSQL_SYSVAR(buffer_pool_size),
+ MYSQL_SYSVAR(buffer_pool_shm_key),
MYSQL_SYSVAR(checksums),
MYSQL_SYSVAR(fast_checksum),
MYSQL_SYSVAR(commit_concurrency),
@@ -11472,6 +11677,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(stats_method),
MYSQL_SYSVAR(stats_auto_update),
MYSQL_SYSVAR(stats_update_need_lock),
+ MYSQL_SYSVAR(use_sys_stats_table),
MYSQL_SYSVAR(stats_sample_pages),
MYSQL_SYSVAR(adaptive_hash_index),
MYSQL_SYSVAR(replication_delay),
@@ -11495,6 +11701,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(flush_neighbor_pages),
MYSQL_SYSVAR(read_ahead),
MYSQL_SYSVAR(adaptive_checkpoint),
+ MYSQL_SYSVAR(flush_log_at_trx_commit_session),
MYSQL_SYSVAR(enable_unsafe_group_commit),
MYSQL_SYSVAR(expand_import),
MYSQL_SYSVAR(extra_rsegments),
@@ -11514,7 +11721,7 @@ mysql_declare_plugin(xtradb)
&innobase_storage_engine,
innobase_hton_name,
"Percona",
- "XtraDB engine based on InnoDB plugin. Supports transactions, row-level locking, and foreign keys",
+ "Percona-XtraDB, Supports transactions, row-level locking, and foreign keys",
PLUGIN_LICENSE_GPL,
innobase_init, /* Plugin Init */
NULL, /* Plugin Deinit */
@@ -11539,6 +11746,7 @@ i_s_innodb_index_stats,
i_s_innodb_admin_command,
i_s_innodb_sys_tables,
i_s_innodb_sys_indexes,
+i_s_innodb_sys_stats,
i_s_innodb_patches
mysql_declare_plugin_end;
maria_declare_plugin(xtradb)
@@ -11573,6 +11781,7 @@ i_s_innodb_index_stats_maria,
i_s_innodb_admin_command_maria,
i_s_innodb_sys_tables_maria,
i_s_innodb_sys_indexes_maria,
+i_s_innodb_sys_stats_maria,
i_s_innodb_patches_maria
maria_declare_plugin_end;
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index 5f5f6de98ba..2c14549cbfc 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -234,7 +234,11 @@ the definitions are bracketed with #ifdef INNODB_COMPATIBILITY_HOOKS */
extern "C" {
struct charset_info_st *thd_charset(MYSQL_THD thd);
+#if MYSQL_VERSION_ID >= 50142
+LEX_STRING *thd_query_string(MYSQL_THD thd);
+#else
char **thd_query(MYSQL_THD thd);
+#endif
/** Get the file name of the MySQL binlog.
* @return the name of the binlog file
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 2eb9c9f474c..3a32ed9cf36 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -894,6 +894,8 @@ error:
prebuilt->trx->error_info = NULL;
/* fall through */
default:
+ trx->error_state = DB_SUCCESS;
+
if (new_primary) {
if (indexed_table != innodb_table) {
row_merge_drop_table(trx, indexed_table);
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 7cb4a7ac718..0f656528315 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -43,20 +43,11 @@ extern "C" {
#include "ha_prototypes.h" /* for innobase_convert_name() */
#include "srv0start.h" /* for srv_was_started */
#include "btr0btr.h" /* for btr_page_get_index_id */
-#include "dict0dict.h" /* for dict_index_get_if_in_cache */
#include "trx0rseg.h" /* for trx_rseg_struct */
#include "trx0sys.h" /* for trx_sys */
#include "dict0dict.h" /* for dict_sys */
#include "btr0pcur.h"
#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
-/* from buf0buf.c */
-struct buf_chunk_struct{
- ulint mem_size; /* allocated size of the chunk */
- ulint size; /* size of frames[] and blocks[] */
- void* mem; /* pointer to the memory area which
- was allocated for the frames */
- buf_block_t* blocks; /* array of buffer control blocks */
-};
}
static const char plugin_author[] = "Innobase Oy";
@@ -503,27 +494,11 @@ static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_fields_info[] =
static ST_FIELD_INFO i_s_innodb_buffer_pool_pages_index_fields_info[] =
{
- {STRUCT_FLD(field_name, "schema_name"),
- STRUCT_FLD(field_length, 64),
- STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
- STRUCT_FLD(value, 0),
- STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
- STRUCT_FLD(old_name, ""),
- STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
-
- {STRUCT_FLD(field_name, "table_name"),
- STRUCT_FLD(field_length, 64),
- STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
- STRUCT_FLD(value, 0),
- STRUCT_FLD(field_flags, 0),
- STRUCT_FLD(old_name, ""),
- STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
-
- {STRUCT_FLD(field_name, "index_name"),
- STRUCT_FLD(field_length, 64),
- STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ {STRUCT_FLD(field_name, "index_id"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
- STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
@@ -724,7 +699,6 @@ i_s_innodb_buffer_pool_pages_fill(
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
buf_pool_mutex_enter();
- mutex_enter(&(dict_sys->mutex));
chunk = buf_pool->chunks;
@@ -796,7 +770,6 @@ i_s_innodb_buffer_pool_pages_fill(
}
}
- mutex_exit(&(dict_sys->mutex));
buf_pool_mutex_exit();
DBUG_RETURN(status);
@@ -817,13 +790,8 @@ i_s_innodb_buffer_pool_pages_index_fill(
int status = 0;
ulint n_chunks, n_blocks;
- dict_index_t* index;
dulint index_id;
- const char *p;
- char db_name_raw[NAME_LEN*5+1], db_name[NAME_LEN+1];
- char table_name_raw[NAME_LEN*5+1], table_name[NAME_LEN+1];
-
buf_chunk_t* chunk;
DBUG_ENTER("i_s_innodb_buffer_pool_pages_index_fill");
@@ -837,7 +805,6 @@ i_s_innodb_buffer_pool_pages_index_fill(
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
buf_pool_mutex_enter();
- mutex_enter(&(dict_sys->mutex));
chunk = buf_pool->chunks;
@@ -849,48 +816,28 @@ i_s_innodb_buffer_pool_pages_index_fill(
if (fil_page_get_type(frame) == FIL_PAGE_INDEX) {
index_id = btr_page_get_index_id(frame);
- index = dict_index_get_if_in_cache_low(index_id);
- if(index)
- {
- if((p = (char*) strchr(index->table_name, '/')))
- {
- strncpy(db_name_raw, index->table_name, p-index->table_name);
- db_name_raw[p-index->table_name] = 0;
- filename_to_tablename(db_name_raw, db_name, sizeof(db_name));
- field_store_string(table->field[0], db_name);
- p++;
- } else {
- field_store_string(table->field[0], NULL);
- p = index->table_name;
- }
- strcpy(table_name_raw, (const char*)p);
- filename_to_tablename(table_name_raw, table_name, sizeof(table_name));
- field_store_string(table->field[1], table_name);
- field_store_string(table->field[2], index->name);
-
- table->field[3]->store(block->page.space);
- table->field[4]->store(block->page.offset);
- table->field[5]->store(page_get_n_recs(frame));
- table->field[6]->store(page_get_data_size(frame));
- table->field[7]->store(block->is_hashed);
- table->field[8]->store(block->page.access_time);
- table->field[9]->store(block->page.newest_modification != 0);
- table->field[10]->store(block->page.oldest_modification != 0);
- table->field[11]->store(block->page.old);
- table->field[12]->store(0);
- table->field[13]->store(block->page.buf_fix_count);
- table->field[14]->store(block->page.flush_type);
+ table->field[0]->store(ut_conv_dulint_to_longlong(index_id));
+ table->field[1]->store(block->page.space);
+ table->field[2]->store(block->page.offset);
+ table->field[3]->store(page_get_n_recs(frame));
+ table->field[4]->store(page_get_data_size(frame));
+ table->field[5]->store(block->is_hashed);
+ table->field[6]->store(block->page.access_time);
+ table->field[7]->store(block->page.newest_modification != 0);
+ table->field[8]->store(block->page.oldest_modification != 0);
+ table->field[9]->store(block->page.old);
+ table->field[10]->store(0);
+ table->field[11]->store(block->page.buf_fix_count);
+ table->field[12]->store(block->page.flush_type);
- if (schema_table_store_record(thd, table)) {
- status = 1;
- break;
- }
+ if (schema_table_store_record(thd, table)) {
+ status = 1;
+ break;
}
}
}
}
- mutex_exit(&(dict_sys->mutex));
buf_pool_mutex_exit();
DBUG_RETURN(status);
@@ -928,7 +875,6 @@ i_s_innodb_buffer_pool_pages_blob_fill(
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
buf_pool_mutex_enter();
- mutex_enter(&(dict_sys->mutex));
chunk = buf_pool->chunks;
@@ -984,7 +930,6 @@ i_s_innodb_buffer_pool_pages_blob_fill(
}
}
- mutex_exit(&(dict_sys->mutex));
buf_pool_mutex_exit();
DBUG_RETURN(status);
@@ -3998,6 +3943,35 @@ static ST_FIELD_INFO i_s_innodb_sys_indexes_info[] =
END_OF_ST_FIELD_INFO
};
+static ST_FIELD_INFO i_s_innodb_sys_stats_info[] =
+{
+ {STRUCT_FLD(field_name, "INDEX_ID"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ {STRUCT_FLD(field_name, "KEY_COLS"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ {STRUCT_FLD(field_name, "DIFF_VALS"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ END_OF_ST_FIELD_INFO
+};
+
static
int
copy_string_field(
@@ -4254,6 +4228,40 @@ copy_sys_indexes_rec(
static
int
+copy_sys_stats_rec(
+/*===============*/
+ TABLE* table,
+ const dict_index_t* index,
+ const rec_t* rec
+)
+{
+ int status;
+ int field;
+
+ /* INDEX_ID */
+ field = dict_index_get_nth_col_pos(index, 0);
+ status = copy_id_field(table, 0, rec, field);
+ if (status) {
+ return status;
+ }
+ /* KEY_COLS */
+ field = dict_index_get_nth_col_pos(index, 1);
+ status = copy_int_field(table, 1, rec, field);
+ if (status) {
+ return status;
+ }
+ /* DIFF_VALS */
+ field = dict_index_get_nth_col_pos(index, 2);
+ status = copy_id_field(table, 2, rec, field);
+ if (status) {
+ return status;
+ }
+
+ return 0;
+}
+
+static
+int
i_s_innodb_schema_table_fill(
/*=========================*/
THD* thd,
@@ -4281,6 +4289,8 @@ i_s_innodb_schema_table_fill(
id = 0;
} else if (innobase_strcasecmp(table_name, "innodb_sys_indexes") == 0) {
id = 1;
+ } else if (innobase_strcasecmp(table_name, "innodb_sys_stats") == 0) {
+ id = 2;
} else {
DBUG_RETURN(1);
}
@@ -4294,8 +4304,10 @@ i_s_innodb_schema_table_fill(
if (id == 0) {
innodb_table = dict_table_get_low("SYS_TABLES");
- } else {
+ } else if (id == 1) {
innodb_table = dict_table_get_low("SYS_INDEXES");
+ } else {
+ innodb_table = dict_table_get_low("SYS_STATS");
}
index = UT_LIST_GET_FIRST(innodb_table->indexes);
@@ -4320,8 +4332,10 @@ i_s_innodb_schema_table_fill(
if (id == 0) {
status = copy_sys_tables_rec(table, index, rec);
- } else {
+ } else if (id == 1) {
status = copy_sys_indexes_rec(table, index, rec);
+ } else {
+ status = copy_sys_stats_rec(table, index, rec);
}
if (status) {
btr_pcur_close(&pcur);
@@ -4386,6 +4400,21 @@ i_s_innodb_sys_indexes_init(
DBUG_RETURN(0);
}
+static
+int
+i_s_innodb_sys_stats_init(
+/*======================*/
+ void* p)
+{
+ DBUG_ENTER("i_s_innodb_sys_stats_init");
+ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
+
+ schema->fields_info = i_s_innodb_sys_stats_info;
+ schema->fill_table = i_s_innodb_schema_table_fill;
+
+ DBUG_RETURN(0);
+}
+
UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_tables =
{
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
@@ -4452,3 +4481,36 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_indexes_maria =
STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA)
};
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_stats =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_SYS_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB SYS_STATS table"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_sys_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(__reserved1, NULL)
+};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_stats_maria =
+{
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+ STRUCT_FLD(info, &i_s_info),
+ STRUCT_FLD(name, "INNODB_SYS_STATS"),
+ STRUCT_FLD(author, plugin_author),
+ STRUCT_FLD(descr, "InnoDB SYS_STATS table"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_sys_stats_init),
+ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, NULL),
+ STRUCT_FLD(system_vars, NULL),
+ STRUCT_FLD(version_info, "1.0"),
+ STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA)
+};
+
diff --git a/storage/xtradb/handler/i_s.h b/storage/xtradb/handler/i_s.h
index 8252c6d1fa2..7a5c3ead5ed 100644
--- a/storage/xtradb/handler/i_s.h
+++ b/storage/xtradb/handler/i_s.h
@@ -43,6 +43,7 @@ extern struct st_mysql_plugin i_s_innodb_index_stats;
extern struct st_mysql_plugin i_s_innodb_admin_command;
extern struct st_mysql_plugin i_s_innodb_sys_tables;
extern struct st_mysql_plugin i_s_innodb_sys_indexes;
+extern struct st_mysql_plugin i_s_innodb_sys_stats;
extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria;
extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria;
@@ -61,5 +62,6 @@ extern struct st_maria_plugin i_s_innodb_index_stats_maria;
extern struct st_maria_plugin i_s_innodb_admin_command_maria;
extern struct st_maria_plugin i_s_innodb_sys_tables_maria;
extern struct st_maria_plugin i_s_innodb_sys_indexes_maria;
+extern struct st_maria_plugin i_s_innodb_sys_stats_maria;
#endif /* i_s_h */
diff --git a/storage/xtradb/handler/innodb_patch_info.h b/storage/xtradb/handler/innodb_patch_info.h
index 38b97411340..e68f12d0fec 100644
--- a/storage/xtradb/handler/innodb_patch_info.h
+++ b/storage/xtradb/handler/innodb_patch_info.h
@@ -47,5 +47,6 @@ struct innodb_enhancement {
{"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_files_extend","allow >4GB transaction log files, and can vary universal page size of datafiles","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_sys_tables_sys_indexes","Expose InnoDB SYS_TABLES and SYS_INDEXES schema tables","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_buffer_pool_shm","Put buffer pool contents to shared memory segment and reuse it at clean restart [experimental]","","http://www.percona.com/docs/wiki/percona-xtradb"},
{NULL, NULL, NULL, NULL}
};
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index f93510be6d6..a7854e3038d 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -36,6 +36,7 @@ Created 11/5/1995 Heikki Tuuri
#include "ut0rbt.h"
#ifndef UNIV_HOTBACKUP
#include "os0proc.h"
+#include "srv0srv.h"
/** @name Modes for buf_page_get_gen */
/* @{ */
@@ -1301,11 +1302,23 @@ struct buf_block_struct{
/**********************************************************************//**
Compute the hash fold value for blocks in buf_pool->zip_hash. */
/* @{ */
-#define BUF_POOL_ZIP_FOLD_PTR(ptr) ((ulint) (ptr) / UNIV_PAGE_SIZE)
+/* the fold should be relative when srv_buffer_pool_shm_key is enabled */
+#define BUF_POOL_ZIP_FOLD_PTR(ptr) (!srv_buffer_pool_shm_key\
+ ?((ulint) (ptr) / UNIV_PAGE_SIZE)\
+ :((ulint) ((char*)ptr - (char*)(buf_pool->chunks->blocks->frame)) / UNIV_PAGE_SIZE))
#define BUF_POOL_ZIP_FOLD(b) BUF_POOL_ZIP_FOLD_PTR((b)->frame)
#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
/* @} */
+/** A chunk of buffers. The buffer pool is allocated in chunks. */
+struct buf_chunk_struct{
+ ulint mem_size; /*!< allocated size of the chunk */
+ ulint size; /*!< size of frames[] and blocks[] */
+ void* mem; /*!< pointer to the memory area which
+ was allocated for the frames */
+ buf_block_t* blocks; /*!< array of buffer control blocks */
+};
+
/** @brief The buffer pool statistics structure. */
struct buf_pool_stat_struct{
ulint n_page_gets; /*!< number of page gets performed;
diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h
index 0a7d01c95cf..d3b59e8b579 100644
--- a/storage/xtradb/include/buf0lru.h
+++ b/storage/xtradb/include/buf0lru.h
@@ -96,7 +96,7 @@ buf_LRU_insert_zip_clean(
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.
-NOTE: If this function returns BUF_LRU_FREED, it will not temporarily
+NOTE: If this function returns BUF_LRU_FREED, it will temporarily
release buf_pool_mutex. Furthermore, the page frame will no longer be
accessible via bpage.
diff --git a/storage/xtradb/include/buf0rea.h b/storage/xtradb/include/buf0rea.h
index 71f62ff7b49..56d3d24a3b7 100644
--- a/storage/xtradb/include/buf0rea.h
+++ b/storage/xtradb/include/buf0rea.h
@@ -158,8 +158,7 @@ buf_read_recv_pages(
/** The size in pages of the area which the read-ahead algorithms read if
invoked */
-#define BUF_READ_AHEAD_AREA \
- ut_min(64, ut_2_power_up(buf_pool->curr_size / 32))
+#define BUF_READ_AHEAD_AREA 64
/** @name Modes used in read-ahead @{ */
/** read only pages belonging to the insert buffer tree */
diff --git a/storage/xtradb/include/db0err.h b/storage/xtradb/include/db0err.h
index 747e9b5364e..c841c2b4afe 100644
--- a/storage/xtradb/include/db0err.h
+++ b/storage/xtradb/include/db0err.h
@@ -28,6 +28,8 @@ Created 5/24/1996 Heikki Tuuri
enum db_err {
+ DB_SUCCESS_LOCKED_REC = 9, /*!< like DB_SUCCESS, but a new
+ explicit record lock was created */
DB_SUCCESS = 10,
/* The following are error codes */
diff --git a/storage/xtradb/include/dict0boot.h b/storage/xtradb/include/dict0boot.h
index 1a13bd1503a..9239e031a7f 100644
--- a/storage/xtradb/include/dict0boot.h
+++ b/storage/xtradb/include/dict0boot.h
@@ -46,13 +46,14 @@ dict_hdr_get(
/*=========*/
mtr_t* mtr); /*!< in: mtr */
/**********************************************************************//**
-Returns a new row, table, index, or tree id.
-@return the new id */
+Returns a new table, index, or space id. */
UNIV_INTERN
-dulint
+void
dict_hdr_get_new_id(
/*================*/
- ulint type); /*!< in: DICT_HDR_ROW_ID, ... */
+ dulint* table_id, /*!< out: table id (not assigned if NULL) */
+ dulint* index_id, /*!< out: index id (not assigned if NULL) */
+ ulint* space_id); /*!< out: space id (not assigned if NULL) */
/**********************************************************************//**
Returns a new row id.
@return the new id */
@@ -100,6 +101,7 @@ dict_create(void);
#define DICT_COLUMNS_ID ut_dulint_create(0, 2)
#define DICT_INDEXES_ID ut_dulint_create(0, 3)
#define DICT_FIELDS_ID ut_dulint_create(0, 4)
+#define DICT_STATS_ID ut_dulint_create(0, 6)
/* The following is a secondary index on SYS_TABLES */
#define DICT_TABLE_IDS_ID ut_dulint_create(0, 5)
@@ -119,17 +121,21 @@ dict_create(void);
#define DICT_HDR_ROW_ID 0 /* The latest assigned row id */
#define DICT_HDR_TABLE_ID 8 /* The latest assigned table id */
#define DICT_HDR_INDEX_ID 16 /* The latest assigned index id */
-#define DICT_HDR_MIX_ID 24 /* Obsolete, always 0. */
+#define DICT_HDR_MAX_SPACE_ID 24 /* The latest assigned space id, or 0*/
+#define DICT_HDR_MIX_ID_LOW 28 /* Obsolete,always DICT_HDR_FIRST_ID */
#define DICT_HDR_TABLES 32 /* Root of the table index tree */
#define DICT_HDR_TABLE_IDS 36 /* Root of the table index tree */
#define DICT_HDR_COLUMNS 40 /* Root of the column index tree */
#define DICT_HDR_INDEXES 44 /* Root of the index index tree */
#define DICT_HDR_FIELDS 48 /* Root of the index field
index tree */
+#define DICT_HDR_STATS 52 /* Root of the stats tree */
#define DICT_HDR_FSEG_HEADER 56 /* Segment header for the tablespace
segment into which the dictionary
header is created */
+
+#define DICT_HDR_XTRADB_MARK 256 /* Flag to distinguish expansion of XtraDB */
/*-------------------------------------------------------------*/
/* The field number of the page number field in the sys_indexes table
@@ -139,11 +145,15 @@ clustered index */
#define DICT_SYS_INDEXES_TYPE_FIELD 6
#define DICT_SYS_INDEXES_NAME_FIELD 4
+#define DICT_SYS_STATS_DIFF_VALS_FIELD 4
+
/* When a row id which is zero modulo this number (which must be a power of
two) is assigned, the field DICT_HDR_ROW_ID on the dictionary header page is
updated */
#define DICT_HDR_ROW_ID_WRITE_MARGIN 256
+#define DICT_HDR_XTRADB_FLAG ut_dulint_create(0x58545241UL,0x44425F31UL) /* "XTRADB_1" */
+
#ifndef UNIV_NONINL
#include "dict0boot.ic"
#endif
diff --git a/storage/xtradb/include/dict0crea.h b/storage/xtradb/include/dict0crea.h
index cce1246b789..0249091a195 100644
--- a/storage/xtradb/include/dict0crea.h
+++ b/storage/xtradb/include/dict0crea.h
@@ -53,6 +53,14 @@ ind_create_graph_create(
dict_index_t* index, /*!< in: index to create, built as a memory data
structure */
mem_heap_t* heap); /*!< in: heap where created */
+/*********************************************************************//**
+*/
+UNIV_INTERN
+ind_node_t*
+ind_insert_stats_graph_create(
+/*==========================*/
+ dict_index_t* index,
+ mem_heap_t* heap);
/***********************************************************//**
Creates a table. This is a high-level function used in SQL execution graphs.
@return query thread to run next or NULL */
@@ -62,6 +70,13 @@ dict_create_table_step(
/*===================*/
que_thr_t* thr); /*!< in: query thread */
/***********************************************************//**
+*/
+UNIV_INTERN
+que_thr_t*
+dict_insert_stats_step(
+/*===================*/
+ que_thr_t* thr);
+/***********************************************************//**
Creates an index. This is a high-level function used in SQL execution
graphs.
@return query thread to run next or NULL */
@@ -170,6 +185,7 @@ struct ind_node_struct{
ins_node_t* field_def; /* child node which does the inserts of
the field definitions; the row to be inserted
is built by the parent node */
+ ins_node_t* stats_def;
commit_node_t* commit_node;
/* child node which performs a commit after
a successful index creation */
@@ -180,6 +196,7 @@ struct ind_node_struct{
dict_table_t* table; /*!< table which owns the index */
dtuple_t* ind_row;/* index definition row built */
ulint field_no;/* next field definition to insert */
+ ulint stats_no;
mem_heap_t* heap; /*!< memory heap used as auxiliary storage */
};
@@ -189,6 +206,7 @@ struct ind_node_struct{
#define INDEX_CREATE_INDEX_TREE 3
#define INDEX_COMMIT_WORK 4
#define INDEX_ADD_TO_CACHE 5
+#define INDEX_BUILD_STATS_COLS 6
#ifndef UNIV_NONINL
#include "dict0crea.ic"
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index 0879e91ab33..3c5e620d3c1 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -352,6 +352,7 @@ dict_create_foreign_constraints(
name before it: test.table2; the
default database id the database of
parameter name */
+ size_t sql_length, /*!< in: length of sql_string */
const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
@@ -1039,8 +1040,9 @@ void
dict_update_statistics_low(
/*=======================*/
dict_table_t* table, /*!< in/out: table */
- ibool has_dict_mutex);/*!< in: TRUE if the caller has the
+ ibool has_dict_mutex, /*!< in: TRUE if the caller has the
dictionary mutex */
+ ibool sync);
/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
@@ -1048,7 +1050,8 @@ UNIV_INTERN
void
dict_update_statistics(
/*===================*/
- dict_table_t* table); /*!< in/out: table */
+ dict_table_t* table, /*!< in/out: table */
+ ibool sync);
/********************************************************************//**
Reserves the dictionary system mutex for MySQL. */
UNIV_INTERN
@@ -1159,6 +1162,7 @@ struct dict_sys_struct{
dict_table_t* sys_columns; /*!< SYS_COLUMNS table */
dict_table_t* sys_indexes; /*!< SYS_INDEXES table */
dict_table_t* sys_fields; /*!< SYS_FIELDS table */
+ dict_table_t* sys_stats; /*!< SYS_STATS table */
};
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index ee3107a3be1..37c5a4a24fc 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -382,7 +382,7 @@ initialized to 0, NULL or FALSE in dict_mem_table_create(). */
struct dict_table_struct{
dulint id; /*!< id of the table */
mem_heap_t* heap; /*!< memory heap */
- const char* name; /*!< table name */
+ char* name; /*!< table name */
const char* dir_path_of_temp_table;/*!< NULL or the directory path
where a TEMPORARY table that was explicitly
created by a user should be placed if
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 163cacf2892..07c80ef8609 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -226,6 +226,16 @@ fil_space_create(
0 for uncompressed tablespaces */
ulint purpose);/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
/*******************************************************************//**
+Assigns a new space id for a new single-table tablespace. This works simply by
+incrementing the global counter. If 4 billion id's is not enough, we may need
+to recycle id's.
+@return TRUE if assigned, FALSE if not */
+UNIV_INTERN
+ibool
+fil_assign_new_space_id(
+/*====================*/
+ ulint* space_id); /*!< in/out: space id */
+/*******************************************************************//**
Returns the size of the space in pages. The tablespace must be cached in the
memory cache.
@return space size, 0 if space not found */
@@ -428,9 +438,7 @@ UNIV_INTERN
ulint
fil_create_new_single_table_tablespace(
/*===================================*/
- ulint* space_id, /*!< in/out: space id; if this is != 0,
- then this is an input parameter,
- otherwise output */
+ ulint space_id, /*!< in: space id */
const char* tablename, /*!< in: the table name in the usual
databasename/tablename format
of InnoDB, or a dir path to a temp
@@ -499,16 +507,6 @@ UNIV_INTERN
ulint
fil_load_single_table_tablespaces(void);
/*===================================*/
-/********************************************************************//**
-If we need crash recovery, and we have called
-fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(),
-we can call this function to print an error message of orphaned .ibd files
-for which there is not a data dictionary entry with a matching table name
-and space id. */
-UNIV_INTERN
-void
-fil_print_orphaned_tablespaces(void);
-/*================================*/
/*******************************************************************//**
Returns TRUE if a single-table tablespace does not exist in the memory cache,
or is being deleted there.
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index b737a00b3dc..445d94eeabb 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -215,11 +215,21 @@ innobase_casedn_str(
/**********************************************************************//**
Determines the connection character set.
@return connection character set */
+UNIV_INTERN
struct charset_info_st*
innobase_get_charset(
/*=================*/
void* mysql_thd); /*!< in: MySQL thread handle */
-
+/**********************************************************************//**
+Determines the current SQL statement.
+@return SQL statement string */
+UNIV_INTERN
+const char*
+innobase_get_stmt(
+/*==============*/
+ void* mysql_thd, /*!< in: MySQL thread handle */
+ size_t* length) /*!< out: length of the SQL statement */
+ __attribute__((nonnull));
/******************************************************************//**
This function is used to find the storage length in bytes of the first n
characters for prefix indexes using a multibyte character set. The function
@@ -258,4 +268,12 @@ thd_lock_wait_timeout(
void* thd); /*!< in: thread handle (THD*), or NULL to query
the global innodb_lock_wait_timeout */
+/******************************************************************//**
+*/
+
+ulong
+thd_flush_log_at_trx_commit_session(
+/*================================*/
+ void* thd);
+
#endif
diff --git a/storage/xtradb/include/hash0hash.h b/storage/xtradb/include/hash0hash.h
index b17c21a45ef..9dc20cc057f 100644
--- a/storage/xtradb/include/hash0hash.h
+++ b/storage/xtradb/include/hash0hash.h
@@ -49,6 +49,28 @@ hash_table_t*
hash_create(
/*========*/
ulint n); /*!< in: number of array cells */
+
+/*************************************************************//**
+*/
+UNIV_INTERN
+ulint
+hash_create_needed(
+/*===============*/
+ ulint n);
+
+UNIV_INTERN
+void
+hash_create_init(
+/*=============*/
+ hash_table_t* table,
+ ulint n);
+
+UNIV_INTERN
+void
+hash_create_reuse(
+/*==============*/
+ hash_table_t* table);
+
#ifndef UNIV_HOTBACKUP
/*************************************************************//**
Creates a mutex array to protect a hash table. */
@@ -328,6 +350,33 @@ do {\
}\
} while (0)
+/********************************************************************//**
+Align nodes with moving location.*/
+#define HASH_OFFSET(TABLE, NODE_TYPE, PTR_NAME, FADDR, FOFFSET, BOFFSET) \
+do {\
+ ulint i2222;\
+ ulint cell_count2222;\
+\
+ cell_count2222 = hash_get_n_cells(TABLE);\
+\
+ for (i2222 = 0; i2222 < cell_count2222; i2222++) {\
+ NODE_TYPE* node2222;\
+\
+ if ((TABLE)->array[i2222].node) \
+ (TABLE)->array[i2222].node = (void*)((char*)(TABLE)->array[i2222].node \
+ + (((TABLE)->array[i2222].node > (void*)FADDR)?FOFFSET:BOFFSET));\
+ node2222 = HASH_GET_FIRST((TABLE), i2222);\
+\
+ while (node2222) {\
+ if (node2222->PTR_NAME) \
+ node2222->PTR_NAME = (void*)((char*)node2222->PTR_NAME \
+ + ((((void*)node2222->PTR_NAME) > (void*)FADDR)?FOFFSET:BOFFSET));\
+\
+ node2222 = node2222->PTR_NAME;\
+ }\
+ }\
+} while (0)
+
/************************************************************//**
Gets the mutex index for a fold value in a hash table.
@return mutex number */
diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h
index 89a6977b589..73f885ecf04 100644
--- a/storage/xtradb/include/lock0lock.h
+++ b/storage/xtradb/include/lock0lock.h
@@ -341,11 +341,12 @@ lock_sec_rec_modify_check_and_lock(
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr); /*!< in/out: mini-transaction */
/*********************************************************************//**
-Like the counterpart for a clustered index below, but now we read a
+Like lock_clust_rec_read_check_and_lock(), but reads a
secondary index record.
-@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
+or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
-ulint
+enum db_err
lock_sec_rec_read_check_and_lock(
/*=============================*/
ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
@@ -372,9 +373,10 @@ if the query thread should anyway be suspended for some reason; if not, then
puts the transaction and the query thread to the lock wait state and inserts a
waiting request for a record lock to the lock queue. Sets the requested mode
lock on the record.
-@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
+or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
-ulint
+enum db_err
lock_clust_rec_read_check_and_lock(
/*===============================*/
ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
diff --git a/storage/xtradb/include/log0log.ic b/storage/xtradb/include/log0log.ic
index 139f4041a36..1ce00fd7313 100644
--- a/storage/xtradb/include/log0log.ic
+++ b/storage/xtradb/include/log0log.ic
@@ -433,7 +433,10 @@ void
log_free_check(void)
/*================*/
{
- /* ut_ad(sync_thread_levels_empty()); */
+
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(sync_thread_levels_empty_gen(TRUE));
+#endif /* UNIV_SYNC_DEBUG */
if (log_sys->check_flush_or_checkpoint) {
diff --git a/storage/xtradb/include/mach0data.ic b/storage/xtradb/include/mach0data.ic
index ef20356bd31..96d2417ac81 100644
--- a/storage/xtradb/include/mach0data.ic
+++ b/storage/xtradb/include/mach0data.ic
@@ -36,7 +36,7 @@ mach_write_to_1(
ulint n) /*!< in: ulint integer to be stored, >= 0, < 256 */
{
ut_ad(b);
- ut_ad(n <= 0xFFUL);
+ ut_ad((n | 0xFFUL) <= 0xFFUL);
b[0] = (byte)n;
}
@@ -65,7 +65,7 @@ mach_write_to_2(
ulint n) /*!< in: ulint integer to be stored */
{
ut_ad(b);
- ut_ad(n <= 0xFFFFUL);
+ ut_ad((n | 0xFFFFUL) <= 0xFFFFUL);
b[0] = (byte)(n >> 8);
b[1] = (byte)(n);
@@ -81,10 +81,7 @@ mach_read_from_2(
/*=============*/
const byte* b) /*!< in: pointer to 2 bytes */
{
- ut_ad(b);
- return( ((ulint)(b[0]) << 8)
- + (ulint)(b[1])
- );
+ return(((ulint)(b[0]) << 8) | (ulint)(b[1]));
}
/********************************************************//**
@@ -129,7 +126,7 @@ mach_write_to_3(
ulint n) /*!< in: ulint integer to be stored */
{
ut_ad(b);
- ut_ad(n <= 0xFFFFFFUL);
+ ut_ad((n | 0xFFFFFFUL) <= 0xFFFFFFUL);
b[0] = (byte)(n >> 16);
b[1] = (byte)(n >> 8);
@@ -148,8 +145,8 @@ mach_read_from_3(
{
ut_ad(b);
return( ((ulint)(b[0]) << 16)
- + ((ulint)(b[1]) << 8)
- + (ulint)(b[2])
+ | ((ulint)(b[1]) << 8)
+ | (ulint)(b[2])
);
}
@@ -183,9 +180,9 @@ mach_read_from_4(
{
ut_ad(b);
return( ((ulint)(b[0]) << 24)
- + ((ulint)(b[1]) << 16)
- + ((ulint)(b[2]) << 8)
- + (ulint)(b[3])
+ | ((ulint)(b[1]) << 16)
+ | ((ulint)(b[2]) << 8)
+ | (ulint)(b[3])
);
}
@@ -721,7 +718,7 @@ mach_read_from_2_little_endian(
/*===========================*/
const byte* buf) /*!< in: from where to read */
{
- return((ulint)(*buf) + ((ulint)(*(buf + 1))) * 256);
+ return((ulint)(buf[0]) | ((ulint)(buf[1]) << 8));
}
/*********************************************************//**
diff --git a/storage/xtradb/include/mtr0log.ic b/storage/xtradb/include/mtr0log.ic
index db017c7d16e..63af02ba409 100644
--- a/storage/xtradb/include/mtr0log.ic
+++ b/storage/xtradb/include/mtr0log.ic
@@ -203,7 +203,7 @@ mlog_write_initial_log_record_fast(
system tablespace */
if ((space == TRX_SYS_SPACE
|| (srv_doublewrite_file && space == TRX_DOUBLEWRITE_SPACE))
- && offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) {
+ && offset >= (ulint)FSP_EXTENT_SIZE && offset < 3 * (ulint)FSP_EXTENT_SIZE) {
if (trx_doublewrite_buf_is_being_created) {
/* Do nothing: we only come to this branch in an
InnoDB database creation. We do not redo log
diff --git a/storage/xtradb/include/os0proc.h b/storage/xtradb/include/os0proc.h
index fd46bd7db87..582cef6f803 100644
--- a/storage/xtradb/include/os0proc.h
+++ b/storage/xtradb/include/os0proc.h
@@ -32,6 +32,11 @@ Created 9/30/1995 Heikki Tuuri
#ifdef UNIV_LINUX
#include <sys/ipc.h>
#include <sys/shm.h>
+#else
+# if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
+#include <sys/ipc.h>
+#include <sys/shm.h>
+# endif
#endif
typedef void* os_process_t;
@@ -70,6 +75,29 @@ os_mem_free_large(
ulint size); /*!< in: size returned by
os_mem_alloc_large() */
+
+/****************************************************************//**
+Allocates or attaches and reuses shared memory segment.
+The content is not cleared automatically.
+@return allocated memory */
+UNIV_INTERN
+void*
+os_shm_alloc(
+/*=========*/
+ ulint* n, /*!< in/out: number of bytes */
+ uint key,
+ ibool* is_new);
+
+/****************************************************************//**
+Detach shared memory segment. */
+UNIV_INTERN
+void
+os_shm_free(
+/*========*/
+ void *ptr, /*!< in: pointer returned by
+ os_shm_alloc() */
+ ulint size); /*!< in: size returned by
+ os_shm_alloc() */
#ifndef UNIV_NONINL
#include "os0proc.ic"
#endif
diff --git a/storage/xtradb/include/page0page.h b/storage/xtradb/include/page0page.h
index e182c8f58be..5b2bcf7c054 100644
--- a/storage/xtradb/include/page0page.h
+++ b/storage/xtradb/include/page0page.h
@@ -500,7 +500,7 @@ ibool
page_is_leaf(
/*=========*/
const page_t* page) /*!< in: page */
- __attribute__((nonnull, pure));
+ __attribute__((pure));
/************************************************************//**
Gets the pointer to the next record on the page.
@return pointer to next record */
diff --git a/storage/xtradb/include/page0page.ic b/storage/xtradb/include/page0page.ic
index 9655e6c7e27..dab9dc742e4 100644
--- a/storage/xtradb/include/page0page.ic
+++ b/storage/xtradb/include/page0page.ic
@@ -275,6 +275,9 @@ page_is_leaf(
/*=========*/
const page_t* page) /*!< in: page */
{
+ if (!page) {
+ return(FALSE);
+ }
return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
}
diff --git a/storage/xtradb/include/page0zip.h b/storage/xtradb/include/page0zip.h
index 574809e5227..4d37302ed20 100644
--- a/storage/xtradb/include/page0zip.h
+++ b/storage/xtradb/include/page0zip.h
@@ -114,7 +114,7 @@ page_zip_compress(
const page_t* page, /*!< in: uncompressed page */
dict_index_t* index, /*!< in: index of the B-tree node */
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
- __attribute__((nonnull(1,2,3)));
+ __attribute__((nonnull(1,3)));
/**********************************************************************//**
Decompress a page. This function should tolerate errors on the compressed
diff --git a/storage/xtradb/include/que0que.h b/storage/xtradb/include/que0que.h
index 39f8d07af89..09a671f49b1 100644
--- a/storage/xtradb/include/que0que.h
+++ b/storage/xtradb/include/que0que.h
@@ -492,6 +492,8 @@ struct que_fork_struct{
#define QUE_NODE_CALL 31
#define QUE_NODE_EXIT 32
+#define QUE_NODE_INSERT_STATS 34
+
/* Query thread states */
#define QUE_THR_RUNNING 1
#define QUE_THR_PROCEDURE_WAIT 2
diff --git a/storage/xtradb/include/rem0cmp.h b/storage/xtradb/include/rem0cmp.h
index 421308af49b..fcea62ad486 100644
--- a/storage/xtradb/include/rem0cmp.h
+++ b/storage/xtradb/include/rem0cmp.h
@@ -148,7 +148,9 @@ cmp_rec_rec_simple(
const rec_t* rec2, /*!< in: physical record */
const ulint* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
const ulint* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
- const dict_index_t* index); /*!< in: data dictionary index */
+ const dict_index_t* index, /*!< in: data dictionary index */
+ ibool* null_eq);/*!< out: set to TRUE if
+ found matching null values */
/*************************************************************//**
This function is used to compare two physical records. Only the common
first fields are compared, and if an externally stored field is
diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h
index d2a8734c61f..a604f6e3724 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -253,15 +253,6 @@ row_table_got_default_clust_index(
/*==============================*/
const dict_table_t* table); /*!< in: table */
/*********************************************************************//**
-Calculates the key number used inside MySQL for an Innobase index. We have
-to take into account if we generated a default clustered index for the table
-@return the key number used inside MySQL */
-UNIV_INTERN
-ulint
-row_get_mysql_key_number_for_index(
-/*===============================*/
- const dict_index_t* index); /*!< in: index */
-/*********************************************************************//**
Does an update or delete of a row for MySQL.
@return error code or DB_SUCCESS */
UNIV_INTERN
@@ -273,27 +264,26 @@ row_update_for_mysql(
row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
handle */
/*********************************************************************//**
-This can only be used when srv_locks_unsafe_for_binlog is TRUE or
-session is using a READ COMMITTED isolation level. Before
-calling this function we must use trx_reset_new_rec_lock_info() and
-trx_register_new_rec_lock() to store the information which new record locks
-really were set. This function removes a newly set lock under prebuilt->pcur,
-and also under prebuilt->clust_pcur. Currently, this is only used and tested
-in the case of an UPDATE or a DELETE statement, where the row lock is of the
-LOCK_X type.
-Thus, this implements a 'mini-rollback' that releases the latest record
-locks we set.
-@return error code or DB_SUCCESS */
+This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
+session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
+Before calling this function row_search_for_mysql() must have
+initialized prebuilt->new_rec_locks to store the information which new
+record locks really were set. This function removes a newly set
+clustered index record lock under prebuilt->pcur or
+prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that
+releases the latest clustered index record lock we set.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_unlock_for_mysql(
/*=================*/
- row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct in MySQL
handle */
- ibool has_latches_on_recs);/*!< TRUE if called so that we have
- the latches on the records under pcur
- and clust_pcur, and we do not need to
- reposition the cursors. */
+ ibool has_latches_on_recs);/*!< in: TRUE if called
+ so that we have the latches on
+ the records under pcur and
+ clust_pcur, and we do not need
+ to reposition the cursors. */
/*********************************************************************//**
Creates an query graph node of 'update' type to be used in the MySQL
interface.
@@ -386,6 +376,14 @@ row_create_index_for_mysql(
then checked for not being too
large. */
/*********************************************************************//**
+*/
+UNIV_INTERN
+int
+row_insert_stats_for_mysql(
+/*=======================*/
+ dict_index_t* index,
+ trx_t* trx);
+/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created.
@@ -403,6 +401,7 @@ row_table_add_foreign_constraints(
FOREIGN KEY (a, b) REFERENCES table2(c, d),
table2 can be written also with the
database name before it: test.table2 */
+ size_t sql_length, /*!< in: length of sql_string */
const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
@@ -710,18 +709,17 @@ struct row_prebuilt_struct {
ulint new_rec_locks; /*!< normally 0; if
srv_locks_unsafe_for_binlog is
TRUE or session is using READ
- COMMITTED isolation level, in a
- cursor search, if we set a new
- record lock on an index, this is
- incremented; this is used in
- releasing the locks under the
- cursors if we are performing an
- UPDATE and we determine after
- retrieving the row that it does
- not need to be locked; thus,
- these can be used to implement a
- 'mini-rollback' that releases
- the latest record locks */
+ COMMITTED or READ UNCOMMITTED
+ isolation level, set in
+ row_search_for_mysql() if we set a new
+ record lock on the secondary
+ or clustered index; this is
+ used in row_unlock_for_mysql()
+ when releasing the lock under
+ the cursor if we determine
+ after retrieving the row that
+ it does not need to be locked
+ ('mini-rollback') */
ulint mysql_prefix_len;/*!< byte offset of the end of
the last requested column */
ulint mysql_row_len; /*!< length in bytes of a row in the
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index a463075f435..0904a5da1eb 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -156,6 +156,8 @@ extern ulint srv_buf_pool_curr_size; /*!< current size in bytes */
extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size;
+extern uint srv_buffer_pool_shm_key;
+
extern ibool srv_thread_concurrency_timer_based;
extern ulint srv_n_file_io_threads;
@@ -207,6 +209,7 @@ extern ulong srv_stats_method;
#define SRV_STATS_METHOD_IGNORE_NULLS 2
extern ulong srv_stats_auto_update;
extern ulint srv_stats_update_need_lock;
+extern ibool srv_use_sys_stats_table;
extern ibool srv_use_doublewrite_buf;
extern ibool srv_use_checksums;
@@ -367,8 +370,9 @@ enum {
when writing data files, but do flush
after writing to log files */
SRV_UNIX_NOSYNC, /*!< do not flush after writing */
- SRV_UNIX_O_DIRECT /*!< invoke os_file_set_nocache() on
+ SRV_UNIX_O_DIRECT, /*!< invoke os_file_set_nocache() on
data files */
+ SRV_UNIX_ALL_O_DIRECT /* new method for examination: logfile also open O_DIRECT */
};
/** Alternatives for file i/o in Windows */
diff --git a/storage/xtradb/include/sync0rw.h b/storage/xtradb/include/sync0rw.h
index 1fe517ab30a..4edf93f4042 100644
--- a/storage/xtradb/include/sync0rw.h
+++ b/storage/xtradb/include/sync0rw.h
@@ -556,11 +556,12 @@ struct rw_lock_struct {
//unsigned cline:14; /*!< Line where created */
unsigned last_s_line:14; /*!< Line number where last time s-locked */
unsigned last_x_line:14; /*!< Line number where last time x-locked */
+#ifdef UNIV_DEBUG
ulint magic_n; /*!< RW_LOCK_MAGIC_N */
-};
-
/** Value of rw_lock_struct::magic_n */
#define RW_LOCK_MAGIC_N 22643
+#endif /* UNIV_DEBUG */
+};
#ifdef UNIV_SYNC_DEBUG
/** The structure for storing debug info of an rw-lock */
diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h
index 7e210ea82f1..a500cf1da45 100644
--- a/storage/xtradb/include/sync0sync.h
+++ b/storage/xtradb/include/sync0sync.h
@@ -438,7 +438,7 @@ or row lock! */
#define SYNC_FILE_FORMAT_TAG 1200 /* Used to serialize access to the
file format tag */
#define SYNC_DICT_OPERATION 1001 /* table create, drop, etc. reserve
- this in X-mode, implicit or backround
+ this in X-mode; implicit or backround
operations purge, rollback, foreign
key checks reserve this in S-mode */
#define SYNC_DICT 1000
diff --git a/storage/xtradb/include/trx0sys.h b/storage/xtradb/include/trx0sys.h
index 8b941cdd4e6..9ef9485b611 100644
--- a/storage/xtradb/include/trx0sys.h
+++ b/storage/xtradb/include/trx0sys.h
@@ -326,6 +326,7 @@ UNIV_INTERN
void
trx_sys_update_mysql_binlog_offset(
/*===============================*/
+ trx_sysf_t* sys_header,
const char* file_name_in,/*!< in: MySQL log file name */
ib_int64_t offset, /*!< in: position in that log file */
ulint field, /*!< in: offset of the MySQL log info field in
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index 4a4b54b93a0..4c0ce392bcd 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -497,6 +497,7 @@ struct trx_struct{
FALSE, one can save CPU time and about
150 bytes in the undo log size as then
we skip XA steps */
+ ulint flush_log_at_trx_commit_session;
ulint flush_log_later;/* In 2PC, we hold the
prepare_commit mutex across
both phases. In that case, we
@@ -560,9 +561,6 @@ struct trx_struct{
/*------------------------------*/
void* mysql_thd; /*!< MySQL thread handle corresponding
to this trx, or NULL */
- char** mysql_query_str;/* pointer to the field in mysqld_thd
- which contains the pointer to the
- current SQL query string */
const char* mysql_log_file_name;
/* if MySQL binlog is used, this field
contains a pointer to the latest file
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 90ce618b9da..71476443964 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -46,8 +46,8 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
-#define INNODB_VERSION_BUGFIX 8
-#define PERCONA_INNODB_VERSION 11.2
+#define INNODB_VERSION_BUGFIX 10
+#define PERCONA_INNODB_VERSION 12.0
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
@@ -170,7 +170,7 @@ command. Not tested on Windows. */
#if defined(HAVE_valgrind)&& defined(HAVE_VALGRIND_MEMCHECK_H)
# define UNIV_DEBUG_VALGRIND
-#endif /* HAVE_valgrind */
+#endif
#if 0
#define UNIV_DEBUG_VALGRIND /* Enable extra
Valgrind instrumentation */
@@ -208,10 +208,6 @@ operations (very slow); also UNIV_DEBUG must be defined */
adaptive hash index */
#define UNIV_SRV_PRINT_LATCH_WAITS /* enable diagnostic output
in sync0sync.c */
-#define UNIV_BTR_AVOID_COPY /* when splitting B-tree nodes,
- do not move any records when
- all the records would
- be moved */
#define UNIV_BTR_PRINT /* enable functions for
printing B-trees */
#define UNIV_ZIP_DEBUG /* extensive consistency checks
@@ -301,6 +297,12 @@ management to ensure correct alignment for doubles etc. */
/* Maximum number of parallel threads in a parallelized operation */
#define UNIV_MAX_PARALLELISM 32
+/* The maximum length of a table name. This is the MySQL limit and is
+defined in mysql_com.h like NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN, the
+number does not include a terminating '\0'. InnoDB probably can handle
+longer names internally */
+#define MAX_TABLE_NAME_LEN 192
+
/*
UNIVERSAL TYPE DEFINITIONS
==========================
diff --git a/storage/xtradb/include/ut0lst.h b/storage/xtradb/include/ut0lst.h
index 7b15c052978..4305f6571b5 100644
--- a/storage/xtradb/include/ut0lst.h
+++ b/storage/xtradb/include/ut0lst.h
@@ -257,5 +257,48 @@ do { \
ut_a(ut_list_node_313 == NULL); \
} while (0)
+/********************************************************************//**
+Align nodes with moving location.
+@param NAME the name of the list
+@param TYPE node type
+@param BASE base node (not a pointer to it)
+@param OFFSET offset moved */
+#define UT_LIST_OFFSET(NAME, TYPE, BASE, FADDR, FOFFSET, BOFFSET) \
+do { \
+ ulint ut_list_i_313; \
+ TYPE* ut_list_node_313; \
+ \
+ if ((BASE).start) \
+ (BASE).start = (void*)((char*)((BASE).start) \
+ + (((void*)((BASE).start) > (void*)FADDR)?FOFFSET:BOFFSET));\
+ if ((BASE).end) \
+ (BASE).end = (void*)((char*)((BASE).end) \
+ + (((void*)((BASE).end) > (void*)FADDR)?FOFFSET:BOFFSET));\
+ \
+ ut_list_node_313 = (BASE).start; \
+ \
+ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
+ ut_a(ut_list_node_313); \
+ if ((ut_list_node_313->NAME).prev) \
+ (ut_list_node_313->NAME).prev = (void*)((char*)((ut_list_node_313->NAME).prev) \
+ + (((void*)((ut_list_node_313->NAME).prev) > (void*)FADDR)?FOFFSET:BOFFSET));\
+ if ((ut_list_node_313->NAME).next) \
+ (ut_list_node_313->NAME).next = (void *)((char*)((ut_list_node_313->NAME).next) \
+ + (((void*)((ut_list_node_313->NAME).next)> (void*)FADDR)?FOFFSET:BOFFSET));\
+ ut_list_node_313 = (ut_list_node_313->NAME).next; \
+ } \
+ \
+ ut_a(ut_list_node_313 == NULL); \
+ \
+ ut_list_node_313 = (BASE).end; \
+ \
+ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
+ ut_a(ut_list_node_313); \
+ ut_list_node_313 = (ut_list_node_313->NAME).prev; \
+ } \
+ \
+ ut_a(ut_list_node_313 == NULL); \
+} while (0)
+
#endif
diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c
index b103ee79578..7ec4a53e0ea 100644
--- a/storage/xtradb/lock/lock0lock.c
+++ b/storage/xtradb/lock/lock0lock.c
@@ -1733,11 +1733,11 @@ lock_rec_create(
Enqueues a waiting request for a lock which cannot be granted immediately.
Checks for deadlocks.
@return DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED, or
-DB_SUCCESS; DB_SUCCESS means that there was a deadlock, but another
-transaction was chosen as a victim, and we got the lock immediately:
-no need to wait then */
+DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that
+there was a deadlock, but another transaction was chosen as a victim,
+and we got the lock immediately: no need to wait then */
static
-ulint
+enum db_err
lock_rec_enqueue_waiting(
/*=====================*/
ulint type_mode,/*!< in: lock mode this
@@ -1811,7 +1811,7 @@ lock_rec_enqueue_waiting(
if (trx->wait_lock == NULL) {
- return(DB_SUCCESS);
+ return(DB_SUCCESS_LOCKED_REC);
}
trx->que_state = TRX_QUE_LOCK_WAIT;
@@ -1931,6 +1931,16 @@ somebody_waits:
return(lock_rec_create(type_mode, block, heap_no, index, trx));
}
+/** Record locking request status */
+enum lock_rec_req_status {
+ /** Failed to acquire a lock */
+ LOCK_REC_FAIL,
+ /** Succeeded in acquiring a lock (implicit or already acquired) */
+ LOCK_REC_SUCCESS,
+ /** Explicitly created a new lock */
+ LOCK_REC_SUCCESS_CREATED
+};
+
/*********************************************************************//**
This is a fast routine for locking a record in the most common cases:
there are no explicit locks on the page, or there is just one lock, owned
@@ -1938,9 +1948,9 @@ by this transaction, and of the right type_mode. This is a low-level function
which does NOT look at implicit locks! Checks lock compatibility within
explicit locks. This function sets a normal next-key lock, or in the case of
a page supremum record, a gap type lock.
-@return TRUE if locking succeeded */
+@return whether the locking succeeded */
UNIV_INLINE
-ibool
+enum lock_rec_req_status
lock_rec_lock_fast(
/*===============*/
ibool impl, /*!< in: if TRUE, no lock is set
@@ -1979,19 +1989,19 @@ lock_rec_lock_fast(
lock_rec_create(mode, block, heap_no, index, trx);
}
- return(TRUE);
+ return(LOCK_REC_SUCCESS_CREATED);
}
if (lock_rec_get_next_on_page(lock)) {
- return(FALSE);
+ return(LOCK_REC_FAIL);
}
if (lock->trx != trx
|| lock->type_mode != (mode | LOCK_REC)
|| lock_rec_get_n_bits(lock) <= heap_no) {
- return(FALSE);
+ return(LOCK_REC_FAIL);
}
if (!impl) {
@@ -2000,10 +2010,11 @@ lock_rec_lock_fast(
if (!lock_rec_get_nth_bit(lock, heap_no)) {
lock_rec_set_nth_bit(lock, heap_no);
+ return(LOCK_REC_SUCCESS_CREATED);
}
}
- return(TRUE);
+ return(LOCK_REC_SUCCESS);
}
/*********************************************************************//**
@@ -2011,9 +2022,10 @@ This is the general, and slower, routine for locking a record. This is a
low-level function which does NOT look at implicit locks! Checks lock
compatibility within explicit locks. This function sets a normal next-key
lock, or in the case of a page supremum record, a gap type lock.
-@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
+or DB_QUE_THR_SUSPENDED */
static
-ulint
+enum db_err
lock_rec_lock_slow(
/*===============*/
ibool impl, /*!< in: if TRUE, no lock is set
@@ -2030,7 +2042,6 @@ lock_rec_lock_slow(
que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
- ulint err;
ut_ad(mutex_own(&kernel_mutex));
ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
@@ -2049,27 +2060,23 @@ lock_rec_lock_slow(
/* The trx already has a strong enough lock on rec: do
nothing */
- err = DB_SUCCESS;
} else if (lock_rec_other_has_conflicting(mode, block, heap_no, trx)) {
/* If another transaction has a non-gap conflicting request in
the queue, as this transaction does not have a lock strong
enough already granted on the record, we have to wait. */
- err = lock_rec_enqueue_waiting(mode, block, heap_no,
- index, thr);
- } else {
- if (!impl) {
- /* Set the requested lock on the record */
-
- lock_rec_add_to_queue(LOCK_REC | mode, block,
- heap_no, index, trx);
- }
+ return(lock_rec_enqueue_waiting(mode, block, heap_no,
+ index, thr));
+ } else if (!impl) {
+ /* Set the requested lock on the record */
- err = DB_SUCCESS;
+ lock_rec_add_to_queue(LOCK_REC | mode, block,
+ heap_no, index, trx);
+ return(DB_SUCCESS_LOCKED_REC);
}
- return(err);
+ return(DB_SUCCESS);
}
/*********************************************************************//**
@@ -2078,9 +2085,10 @@ possible, enqueues a waiting lock request. This is a low-level function
which does NOT look at implicit locks! Checks lock compatibility within
explicit locks. This function sets a normal next-key lock, or in the case
of a page supremum record, a gap type lock.
-@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
+or DB_QUE_THR_SUSPENDED */
static
-ulint
+enum db_err
lock_rec_lock(
/*==========*/
ibool impl, /*!< in: if TRUE, no lock is set
@@ -2096,8 +2104,6 @@ lock_rec_lock(
dict_index_t* index, /*!< in: index of record */
que_thr_t* thr) /*!< in: query thread */
{
- ulint err;
-
ut_ad(mutex_own(&kernel_mutex));
ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
|| lock_table_has(thr_get_trx(thr), index->table, LOCK_IS));
@@ -2109,18 +2115,20 @@ lock_rec_lock(
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP
|| mode - (LOCK_MODE_MASK & mode) == 0);
- if (lock_rec_lock_fast(impl, mode, block, heap_no, index, thr)) {
-
- /* We try a simplified and faster subroutine for the most
- common cases */
-
- err = DB_SUCCESS;
- } else {
- err = lock_rec_lock_slow(impl, mode, block,
- heap_no, index, thr);
+ /* We try a simplified and faster subroutine for the most
+ common cases */
+ switch (lock_rec_lock_fast(impl, mode, block, heap_no, index, thr)) {
+ case LOCK_REC_SUCCESS:
+ return(DB_SUCCESS);
+ case LOCK_REC_SUCCESS_CREATED:
+ return(DB_SUCCESS_LOCKED_REC);
+ case LOCK_REC_FAIL:
+ return(lock_rec_lock_slow(impl, mode, block,
+ heap_no, index, thr));
}
- return(err);
+ ut_error;
+ return(DB_ERROR);
}
/*********************************************************************//**
@@ -3948,8 +3956,8 @@ lock_rec_unlock(
const rec_t* rec, /*!< in: record */
enum lock_mode lock_mode)/*!< in: LOCK_S or LOCK_X */
{
+ lock_t* first_lock;
lock_t* lock;
- lock_t* release_lock = NULL;
ulint heap_no;
ut_ad(trx && rec);
@@ -3959,48 +3967,40 @@ lock_rec_unlock(
mutex_enter(&kernel_mutex);
- lock = lock_rec_get_first(block, heap_no);
+ first_lock = lock_rec_get_first(block, heap_no);
/* Find the last lock with the same lock_mode and transaction
from the record. */
- while (lock != NULL) {
+ for (lock = first_lock; lock != NULL;
+ lock = lock_rec_get_next(heap_no, lock)) {
if (lock->trx == trx && lock_get_mode(lock) == lock_mode) {
- release_lock = lock;
ut_a(!lock_get_wait(lock));
+ lock_rec_reset_nth_bit(lock, heap_no);
+ goto released;
}
-
- lock = lock_rec_get_next(heap_no, lock);
}
- /* If a record lock is found, release the record lock */
-
- if (UNIV_LIKELY(release_lock != NULL)) {
- lock_rec_reset_nth_bit(release_lock, heap_no);
- } else {
- mutex_exit(&kernel_mutex);
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Error: unlock row could not"
- " find a %lu mode lock on the record\n",
- (ulong) lock_mode);
+ mutex_exit(&kernel_mutex);
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Error: unlock row could not"
+ " find a %lu mode lock on the record\n",
+ (ulong) lock_mode);
- return;
- }
+ return;
+released:
/* Check if we can now grant waiting lock requests */
- lock = lock_rec_get_first(block, heap_no);
-
- while (lock != NULL) {
+ for (lock = first_lock; lock != NULL;
+ lock = lock_rec_get_next(heap_no, lock)) {
if (lock_get_wait(lock)
&& !lock_rec_has_to_wait_in_queue(lock)) {
/* Grant the lock */
lock_grant(lock);
}
-
- lock = lock_rec_get_next(heap_no, lock);
}
mutex_exit(&kernel_mutex);
@@ -5095,7 +5095,14 @@ lock_rec_insert_check_and_lock(
lock_mutex_exit_kernel();
- if ((err == DB_SUCCESS) && !dict_index_is_clust(index)) {
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ err = DB_SUCCESS;
+ /* fall through */
+ case DB_SUCCESS:
+ if (dict_index_is_clust(index)) {
+ break;
+ }
/* Update the page max trx id field */
page_update_max_trx_id(block,
buf_block_get_page_zip(block),
@@ -5218,6 +5225,10 @@ lock_clust_rec_modify_check_and_lock(
ut_ad(lock_rec_queue_validate(block, rec, index, offsets));
+ if (UNIV_UNLIKELY(err == DB_SUCCESS_LOCKED_REC)) {
+ err = DB_SUCCESS;
+ }
+
return(err);
}
@@ -5284,22 +5295,27 @@ lock_sec_rec_modify_check_and_lock(
}
#endif /* UNIV_DEBUG */
- if (err == DB_SUCCESS) {
+ if (err == DB_SUCCESS || err == DB_SUCCESS_LOCKED_REC) {
/* Update the page max trx id field */
+ /* It might not be necessary to do this if
+ err == DB_SUCCESS (no new lock created),
+ but it should not cost too much performance. */
page_update_max_trx_id(block,
buf_block_get_page_zip(block),
thr_get_trx(thr)->id, mtr);
+ err = DB_SUCCESS;
}
return(err);
}
/*********************************************************************//**
-Like the counterpart for a clustered index below, but now we read a
+Like lock_clust_rec_read_check_and_lock(), but reads a
secondary index record.
-@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
+or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
-ulint
+enum db_err
lock_sec_rec_read_check_and_lock(
/*=============================*/
ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
@@ -5320,8 +5336,8 @@ lock_sec_rec_read_check_and_lock(
LOCK_REC_NOT_GAP */
que_thr_t* thr) /*!< in: query thread */
{
- ulint err;
- ulint heap_no;
+ enum db_err err;
+ ulint heap_no;
ut_ad(!dict_index_is_clust(index));
ut_ad(block->frame == page_align(rec));
@@ -5372,9 +5388,10 @@ if the query thread should anyway be suspended for some reason; if not, then
puts the transaction and the query thread to the lock wait state and inserts a
waiting request for a record lock to the lock queue. Sets the requested mode
lock on the record.
-@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK,
+or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
-ulint
+enum db_err
lock_clust_rec_read_check_and_lock(
/*===============================*/
ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
@@ -5395,8 +5412,8 @@ lock_clust_rec_read_check_and_lock(
LOCK_REC_NOT_GAP */
que_thr_t* thr) /*!< in: query thread */
{
- ulint err;
- ulint heap_no;
+ enum db_err err;
+ ulint heap_no;
ut_ad(dict_index_is_clust(index));
ut_ad(block->frame == page_align(rec));
@@ -5467,17 +5484,22 @@ lock_clust_rec_read_check_and_lock_alt(
mem_heap_t* tmp_heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
- ulint ret;
+ ulint err;
rec_offs_init(offsets_);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &tmp_heap);
- ret = lock_clust_rec_read_check_and_lock(flags, block, rec, index,
+ err = lock_clust_rec_read_check_and_lock(flags, block, rec, index,
offsets, mode, gap_mode, thr);
if (tmp_heap) {
mem_heap_free(tmp_heap);
}
- return(ret);
+
+ if (UNIV_UNLIKELY(err == DB_SUCCESS_LOCKED_REC)) {
+ err = DB_SUCCESS;
+ }
+
+ return(err);
}
/*******************************************************************//**
diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c
index 03d097d1c12..fade31037b5 100644
--- a/storage/xtradb/log/log0log.c
+++ b/storage/xtradb/log/log0log.c
@@ -1111,6 +1111,7 @@ log_io_complete(
group = (log_group_t*)((ulint)group - 1);
if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC
+ && srv_unix_file_flush_method != SRV_UNIX_ALL_O_DIRECT
&& srv_unix_file_flush_method != SRV_UNIX_NOSYNC) {
fil_flush(group->space_id);
@@ -1132,6 +1133,7 @@ log_io_complete(
logs and cannot end up here! */
if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC
+ && srv_unix_file_flush_method != SRV_UNIX_ALL_O_DIRECT
&& srv_unix_file_flush_method != SRV_UNIX_NOSYNC
&& srv_flush_log_at_trx_commit != 2) {
@@ -1512,7 +1514,8 @@ loop:
mutex_exit(&(log_sys->mutex));
- if (srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
+ if (srv_unix_file_flush_method == SRV_UNIX_O_DSYNC
+ || srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT) {
/* O_DSYNC means the OS did not buffer the log file at all:
so we have also flushed to disk what we have written */
diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c
index 1c9b4960ee4..bbb634addb0 100644
--- a/storage/xtradb/log/log0recv.c
+++ b/storage/xtradb/log/log0recv.c
@@ -2965,9 +2965,12 @@ recv_recovery_from_checkpoint_start_func(
ib_uint64_t contiguous_lsn;
ib_uint64_t archived_lsn;
byte* buf;
- byte log_hdr_buf[LOG_FILE_HDR_SIZE];
+ byte* log_hdr_buf;
+ byte log_hdr_buf_base[LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE];
ulint err;
+ log_hdr_buf = ut_align(log_hdr_buf_base, OS_FILE_LOG_BLOCK_SIZE);
+
#ifdef UNIV_LOG_ARCHIVE
ut_ad(type != LOG_CHECKPOINT || limit_lsn == IB_ULONGLONG_MAX);
/** TRUE when recovering from a checkpoint */
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index c79a41626c9..48d796c38e1 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -214,7 +214,7 @@ static os_aio_array_t* os_aio_sync_array = NULL; /*!< Synchronous I/O */
/* Per thread buffer used for merged IO requests. Used by
os_aio_simulated_handle so that a buffer doesn't have to be allocated
for each request. */
-static char* os_aio_thread_buffer[SRV_MAX_N_IO_THREADS];
+static byte* os_aio_thread_buffer[SRV_MAX_N_IO_THREADS];
static ulint os_aio_thread_buffer_size[SRV_MAX_N_IO_THREADS];
/** Number of asynchronous I/O segments. Set by os_aio_init(). */
@@ -1379,7 +1379,11 @@ try_again:
/* When srv_file_per_table is on, file creation failure may not
be critical to the whole instance. Do not crash the server in
- case of unknown errors. */
+ case of unknown errors.
+ Please note "srv_file_per_table" is a global variable with
+ no explicit synchronization protection. It could be
+ changed during this execution path. It might not have the
+ same value as the one when building the table definition */
if (srv_file_per_table) {
retry = os_file_handle_error_no_exit(name,
create_mode == OS_FILE_CREATE ?
@@ -1466,7 +1470,11 @@ try_again:
/* When srv_file_per_table is on, file creation failure may not
be critical to the whole instance. Do not crash the server in
- case of unknown errors. */
+ case of unknown errors.
+ Please note "srv_file_per_table" is a global variable with
+ no explicit synchronization protection. It could be
+ changed during this execution path. It might not have the
+ same value as the one when building the table definition */
if (srv_file_per_table) {
retry = os_file_handle_error_no_exit(name,
create_mode == OS_FILE_CREATE ?
@@ -1494,6 +1502,11 @@ try_again:
os_file_set_nocache(file, name, mode_str);
}
+ /* ALL_O_DIRECT: O_DIRECT also for transaction log file */
+ if (srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT) {
+ os_file_set_nocache(file, name, mode_str);
+ }
+
#ifdef USE_FILE_LOCK
if (create_mode != OS_FILE_OPEN_RAW && os_file_lock(file, name)) {
diff --git a/storage/xtradb/os/os0proc.c b/storage/xtradb/os/os0proc.c
index 48922886f23..c101db3d179 100644
--- a/storage/xtradb/os/os0proc.c
+++ b/storage/xtradb/os/os0proc.c
@@ -229,3 +229,175 @@ os_mem_free_large(
}
#endif
}
+
+/****************************************************************//**
+Allocates or attaches and reuses shared memory segment.
+The content is not cleared automatically.
+@return allocated memory */
+UNIV_INTERN
+void*
+os_shm_alloc(
+/*=========*/
+ ulint* n, /*!< in/out: number of bytes */
+ uint key,
+ ibool* is_new)
+{
+ void* ptr;
+#if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
+ ulint size;
+ int shmid;
+#endif
+
+ *is_new = FALSE;
+#if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
+ fprintf(stderr,
+ "InnoDB: The shared memory key %#x (%d) is specified.\n",
+ key, key);
+# if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
+ if (!os_use_large_pages || !os_large_page_size) {
+ goto skip;
+ }
+
+ /* Align block size to os_large_page_size */
+ ut_ad(ut_is_2pow(os_large_page_size));
+ size = ut_2pow_round(*n + (os_large_page_size - 1),
+ os_large_page_size);
+
+ shmid = shmget((key_t)key, (size_t)size,
+ IPC_CREAT | IPC_EXCL | SHM_HUGETLB | SHM_R | SHM_W);
+ if (shmid < 0) {
+ if (errno == EEXIST) {
+ fprintf(stderr,
+ "InnoDB: HugeTLB: The shared memory segment seems to exist already.\n");
+ shmid = shmget((key_t)key, (size_t)size,
+ SHM_HUGETLB | SHM_R | SHM_W);
+ if (shmid < 0) {
+ fprintf(stderr,
+ "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes.(reuse) errno %d\n",
+ size, errno);
+ goto skip;
+ } else {
+ fprintf(stderr,
+ "InnoDB: HugeTLB: The existent shared memory segment is used.\n");
+ }
+ } else {
+ fprintf(stderr,
+ "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes.(new) errno %d\n",
+ size, errno);
+ goto skip;
+ }
+ } else {
+ *is_new = TRUE;
+ fprintf(stderr,
+ "InnoDB: HugeTLB: The new shared memory segment is created.\n");
+ }
+
+ ptr = shmat(shmid, NULL, 0);
+ if (ptr == (void *)-1) {
+ fprintf(stderr,
+ "InnoDB: HugeTLB: Warning: Failed to attach shared memory segment, errno %d\n",
+ errno);
+ ptr = NULL;
+ }
+
+ if (ptr) {
+ *n = size;
+ os_fast_mutex_lock(&ut_list_mutex);
+ ut_total_allocated_memory += size;
+ os_fast_mutex_unlock(&ut_list_mutex);
+ UNIV_MEM_ALLOC(ptr, size);
+ return(ptr);
+ }
+skip:
+ *is_new = FALSE;
+# endif /* HAVE_LARGE_PAGES && defined UNIV_LINUX */
+# ifdef HAVE_GETPAGESIZE
+ size = getpagesize();
+# else
+ size = UNIV_PAGE_SIZE;
+# endif
+ /* Align block size to system page size */
+ ut_ad(ut_is_2pow(size));
+ size = *n = ut_2pow_round(*n + (size - 1), size);
+
+ shmid = shmget((key_t)key, (size_t)size,
+ IPC_CREAT | IPC_EXCL | SHM_R | SHM_W);
+ if (shmid < 0) {
+ if (errno == EEXIST) {
+ fprintf(stderr,
+ "InnoDB: The shared memory segment seems to exist already.\n");
+ shmid = shmget((key_t)key, (size_t)size,
+ SHM_R | SHM_W);
+ if (shmid < 0) {
+ fprintf(stderr,
+ "InnoDB: Warning: Failed to allocate %lu bytes.(reuse) errno %d\n",
+ size, errno);
+ ptr = NULL;
+ goto end;
+ } else {
+ fprintf(stderr,
+ "InnoDB: The existent shared memory segment is used.\n");
+ }
+ } else {
+ fprintf(stderr,
+ "InnoDB: Warning: Failed to allocate %lu bytes.(new) errno %d\n",
+ size, errno);
+ ptr = NULL;
+ goto end;
+ }
+ } else {
+ *is_new = TRUE;
+ fprintf(stderr,
+ "InnoDB: The new shared memory segment is created.\n");
+ }
+
+ ptr = shmat(shmid, NULL, 0);
+ if (ptr == (void *)-1) {
+ fprintf(stderr,
+ "InnoDB: Warning: Failed to attach shared memory segment, errno %d\n",
+ errno);
+ ptr = NULL;
+ }
+
+ if (ptr) {
+ *n = size;
+ os_fast_mutex_lock(&ut_list_mutex);
+ ut_total_allocated_memory += size;
+ os_fast_mutex_unlock(&ut_list_mutex);
+ UNIV_MEM_ALLOC(ptr, size);
+ }
+end:
+#else /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
+ fprintf(stderr, "InnoDB: shared memory segment is not supported.\n");
+ ptr = NULL;
+#endif /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
+ return(ptr);
+}
+
+/****************************************************************//**
+Detach shared memory segment. */
+UNIV_INTERN
+void
+os_shm_free(
+/*========*/
+ void *ptr, /*!< in: pointer returned by
+ os_shm_alloc() */
+ ulint size) /*!< in: size returned by
+ os_shm_alloc() */
+{
+ os_fast_mutex_lock(&ut_list_mutex);
+ ut_a(ut_total_allocated_memory >= size);
+ os_fast_mutex_unlock(&ut_list_mutex);
+
+#if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
+ if (!shmdt(ptr)) {
+ os_fast_mutex_lock(&ut_list_mutex);
+ ut_a(ut_total_allocated_memory >= size);
+ ut_total_allocated_memory -= size;
+ os_fast_mutex_unlock(&ut_list_mutex);
+ UNIV_MEM_FREE(ptr, size);
+ }
+#else /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
+ fprintf(stderr, "InnoDB: shared memory segment is not supported.\n");
+#endif /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
+}
diff --git a/storage/xtradb/page/page0zip.c b/storage/xtradb/page/page0zip.c
index 7ef44f3246f..a94d2d54417 100644
--- a/storage/xtradb/page/page0zip.c
+++ b/storage/xtradb/page/page0zip.c
@@ -571,7 +571,7 @@ page_zip_dir_encode(
/* Traverse the list of stored records in the collation order,
starting from the first user record. */
- rec = page + PAGE_NEW_INFIMUM, TRUE;
+ rec = page + PAGE_NEW_INFIMUM;
i = 0;
@@ -1153,6 +1153,10 @@ page_zip_compress(
FILE* logfile = NULL;
#endif
+ if (!page) {
+ return(FALSE);
+ }
+
ut_a(page_is_comp(page));
ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX);
ut_ad(page_simple_validate_new((page_t*) page));
@@ -1464,6 +1468,7 @@ page_zip_fields_free(
dict_table_t* table = index->table;
mem_heap_free(index->heap);
mutex_free(&(table->autoinc_mutex));
+ ut_free(table->name);
mem_heap_free(table->heap);
}
}
diff --git a/storage/xtradb/que/que0que.c b/storage/xtradb/que/que0que.c
index 2fe046fa9b8..5c85a04d139 100644
--- a/storage/xtradb/que/que0que.c
+++ b/storage/xtradb/que/que0que.c
@@ -622,11 +622,21 @@ que_graph_free_recursive(
que_graph_free_recursive(cre_ind->ind_def);
que_graph_free_recursive(cre_ind->field_def);
+ if (srv_use_sys_stats_table)
+ que_graph_free_recursive(cre_ind->stats_def);
que_graph_free_recursive(cre_ind->commit_node);
mem_heap_free(cre_ind->heap);
break;
+ case QUE_NODE_INSERT_STATS:
+ cre_ind = node;
+
+ que_graph_free_recursive(cre_ind->stats_def);
+ que_graph_free_recursive(cre_ind->commit_node);
+
+ mem_heap_free(cre_ind->heap);
+ break;
case QUE_NODE_PROC:
que_graph_free_stat_list(((proc_node_t*)node)->stat_list);
@@ -1139,6 +1149,8 @@ que_node_print_info(
str = "CREATE TABLE";
} else if (type == QUE_NODE_CREATE_INDEX) {
str = "CREATE INDEX";
+ } else if (type == QUE_NODE_INSERT_STATS) {
+ str = "INSERT TO SYS_STATS";
} else if (type == QUE_NODE_FOR) {
str = "FOR LOOP";
} else if (type == QUE_NODE_RETURN) {
@@ -1256,6 +1268,8 @@ que_thr_step(
thr = dict_create_table_step(thr);
} else if (type == QUE_NODE_CREATE_INDEX) {
thr = dict_create_index_step(thr);
+ } else if (type == QUE_NODE_INSERT_STATS) {
+ thr = dict_insert_stats_step(thr);
} else if (type == QUE_NODE_ROW_PRINTF) {
thr = row_printf_step(thr);
} else {
diff --git a/storage/xtradb/rem/rem0cmp.c b/storage/xtradb/rem/rem0cmp.c
index 45230f1d7b1..8ee434f85da 100644
--- a/storage/xtradb/rem/rem0cmp.c
+++ b/storage/xtradb/rem/rem0cmp.c
@@ -706,7 +706,9 @@ cmp_rec_rec_simple(
const rec_t* rec2, /*!< in: physical record */
const ulint* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
const ulint* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
- const dict_index_t* index) /*!< in: data dictionary index */
+ const dict_index_t* index, /*!< in: data dictionary index */
+ ibool* null_eq)/*!< out: set to TRUE if
+ found matching null values */
{
ulint rec1_f_len; /*!< length of current field in rec1 */
const byte* rec1_b_ptr; /*!< pointer to the current byte
@@ -753,6 +755,9 @@ cmp_rec_rec_simple(
|| rec2_f_len == UNIV_SQL_NULL) {
if (rec1_f_len == rec2_f_len) {
+ if (null_eq) {
+ *null_eq = TRUE;
+ }
goto next_field;
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index d7475d613ad..d4925e46f97 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -51,6 +51,15 @@ Created 4/20/1996 Heikki Tuuri
#define ROW_INS_PREV 1
#define ROW_INS_NEXT 2
+/*************************************************************************
+IMPORTANT NOTE: Any operation that generates redo MUST check that there
+is enough space in the redo log before for that operation. This is
+done by calling log_free_check(). The reason for checking the
+availability of the redo log space before the start of the operation is
+that we MUST not hold any synchonization objects when performing the
+check.
+If you make a change in this module make sure that no codepath is
+introduced where a call to log_free_check() is bypassed. */
/*********************************************************************//**
Creates an insert node struct.
@@ -1121,9 +1130,9 @@ nonstandard_exit_func:
/*********************************************************************//**
Sets a shared lock on a record. Used in locking possible duplicate key
records and also in checking foreign key constraints.
-@return DB_SUCCESS or error code */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
static
-ulint
+enum db_err
row_ins_set_shared_rec_lock(
/*========================*/
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
@@ -1134,7 +1143,7 @@ row_ins_set_shared_rec_lock(
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
que_thr_t* thr) /*!< in: query thread */
{
- ulint err;
+ enum db_err err;
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -1152,9 +1161,9 @@ row_ins_set_shared_rec_lock(
/*********************************************************************//**
Sets a exclusive lock on a record. Used in locking possible duplicate key
records
-@return DB_SUCCESS or error code */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
static
-ulint
+enum db_err
row_ins_set_exclusive_rec_lock(
/*===========================*/
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
@@ -1165,7 +1174,7 @@ row_ins_set_exclusive_rec_lock(
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
que_thr_t* thr) /*!< in: query thread */
{
- ulint err;
+ enum db_err err;
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -1205,7 +1214,6 @@ row_ins_check_foreign_constraint(
dict_index_t* check_index;
ulint n_fields_cmp;
btr_pcur_t pcur;
- ibool moved;
int cmp;
ulint err;
ulint i;
@@ -1336,7 +1344,7 @@ run_again:
/* Scan index records and check if there is a matching record */
- for (;;) {
+ do {
const rec_t* rec = btr_pcur_get_rec(&pcur);
const buf_block_t* block = btr_pcur_get_block(&pcur);
@@ -1348,7 +1356,7 @@ run_again:
if (page_rec_is_infimum(rec)) {
- goto next_rec;
+ continue;
}
offsets = rec_get_offsets(rec, check_index,
@@ -1359,12 +1367,13 @@ run_again:
err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, block,
rec, check_index,
offsets, thr);
- if (err != DB_SUCCESS) {
-
- break;
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
+ continue;
+ default:
+ goto end_scan;
}
-
- goto next_rec;
}
cmp = cmp_dtuple_rec(entry, rec, offsets);
@@ -1375,9 +1384,12 @@ run_again:
err = row_ins_set_shared_rec_lock(
LOCK_ORDINARY, block,
rec, check_index, offsets, thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
break;
+ default:
+ goto end_scan;
}
} else {
/* Found a matching record. Lock only
@@ -1388,15 +1400,18 @@ run_again:
LOCK_REC_NOT_GAP, block,
rec, check_index, offsets, thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
break;
+ default:
+ goto end_scan;
}
if (check_ref) {
err = DB_SUCCESS;
- break;
+ goto end_scan;
} else if (foreign->type != 0) {
/* There is an ON UPDATE or ON DELETE
condition: check them in a separate
@@ -1422,7 +1437,7 @@ run_again:
err = DB_FOREIGN_DUPLICATE_KEY;
}
- break;
+ goto end_scan;
}
/* row_ins_foreign_check_on_constraint
@@ -1435,49 +1450,41 @@ run_again:
thr, foreign, rec, entry);
err = DB_ROW_IS_REFERENCED;
- break;
+ goto end_scan;
}
}
- }
+ } else {
+ ut_a(cmp < 0);
- if (cmp < 0) {
err = row_ins_set_shared_rec_lock(
LOCK_GAP, block,
rec, check_index, offsets, thr);
- if (err != DB_SUCCESS) {
- break;
- }
-
- if (check_ref) {
- err = DB_NO_REFERENCED_ROW;
- row_ins_foreign_report_add_err(
- trx, foreign, rec, entry);
- } else {
- err = DB_SUCCESS;
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
+ if (check_ref) {
+ err = DB_NO_REFERENCED_ROW;
+ row_ins_foreign_report_add_err(
+ trx, foreign, rec, entry);
+ } else {
+ err = DB_SUCCESS;
+ }
}
- break;
+ goto end_scan;
}
+ } while (btr_pcur_move_to_next(&pcur, &mtr));
- ut_a(cmp == 0);
-next_rec:
- moved = btr_pcur_move_to_next(&pcur, &mtr);
-
- if (!moved) {
- if (check_ref) {
- rec = btr_pcur_get_rec(&pcur);
- row_ins_foreign_report_add_err(
- trx, foreign, rec, entry);
- err = DB_NO_REFERENCED_ROW;
- } else {
- err = DB_SUCCESS;
- }
-
- break;
- }
+ if (check_ref) {
+ row_ins_foreign_report_add_err(
+ trx, foreign, btr_pcur_get_rec(&pcur), entry);
+ err = DB_NO_REFERENCED_ROW;
+ } else {
+ err = DB_SUCCESS;
}
+end_scan:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -1725,9 +1732,13 @@ row_ins_scan_sec_index_for_duplicate(
rec, index, offsets, thr);
}
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ err = DB_SUCCESS;
+ case DB_SUCCESS:
break;
+ default:
+ goto end_scan;
}
if (page_rec_is_supremum(rec)) {
@@ -1744,17 +1755,15 @@ row_ins_scan_sec_index_for_duplicate(
thr_get_trx(thr)->error_info = index;
- break;
+ goto end_scan;
}
+ } else {
+ ut_a(cmp < 0);
+ goto end_scan;
}
-
- if (cmp < 0) {
- break;
- }
-
- ut_a(cmp == 0);
} while (btr_pcur_move_to_next(&pcur, &mtr));
+end_scan:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -1843,7 +1852,11 @@ row_ins_duplicate_error_in_clust(
cursor->index, offsets, thr);
}
- if (err != DB_SUCCESS) {
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
+ break;
+ default:
goto func_exit;
}
@@ -1883,7 +1896,11 @@ row_ins_duplicate_error_in_clust(
rec, cursor->index, offsets, thr);
}
- if (err != DB_SUCCESS) {
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
+ break;
+ default:
goto func_exit;
}
diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c
index 6ee93d24ed3..47c03c77850 100644
--- a/storage/xtradb/row/row0merge.c
+++ b/storage/xtradb/row/row0merge.c
@@ -717,14 +717,16 @@ row_merge_read(
}
/********************************************************************//**
-Read a merge block from the file system.
+Write a merge block to the file system.
@return TRUE if request was successful, FALSE if fail */
static
ibool
row_merge_write(
/*============*/
int fd, /*!< in: file descriptor */
- ulint offset, /*!< in: offset where to write */
+ ulint offset, /*!< in: offset where to read
+ in number of row_merge_block_t
+ elements */
const void* buf) /*!< in: data */
{
ib_uint64_t ofs = ((ib_uint64_t) offset)
@@ -1075,11 +1077,14 @@ row_merge_cmp(
record to be compared */
const ulint* offsets1, /*!< in: first record offsets */
const ulint* offsets2, /*!< in: second record offsets */
- const dict_index_t* index) /*!< in: index */
+ const dict_index_t* index, /*!< in: index */
+ ibool* null_eq) /*!< out: set to TRUE if
+ found matching null values */
{
int cmp;
- cmp = cmp_rec_rec_simple(mrec1, mrec2, offsets1, offsets2, index);
+ cmp = cmp_rec_rec_simple(mrec1, mrec2, offsets1, offsets2, index,
+ null_eq);
#ifdef UNIV_DEBUG
if (row_merge_print_cmp) {
@@ -1452,11 +1457,13 @@ corrupt:
}
while (mrec0 && mrec1) {
+ ibool null_eq = FALSE;
switch (row_merge_cmp(mrec0, mrec1,
- offsets0, offsets1, index)) {
+ offsets0, offsets1, index,
+ &null_eq)) {
case 0:
if (UNIV_UNLIKELY
- (dict_index_is_unique(index))) {
+ (dict_index_is_unique(index) && !null_eq)) {
innobase_rec_to_mysql(table, mrec0,
index, offsets0);
mem_heap_free(heap);
@@ -1578,22 +1585,28 @@ row_merge(
const dict_index_t* index, /*!< in: index being created */
merge_file_t* file, /*!< in/out: file containing
index entries */
- ulint* half, /*!< in/out: half the file */
row_merge_block_t* block, /*!< in/out: 3 buffers */
int* tmpfd, /*!< in/out: temporary file handle */
- TABLE* table) /*!< in/out: MySQL table, for
+ TABLE* table, /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
+ ulint* num_run,/*!< in/out: Number of runs remain
+ to be merged */
+ ulint* run_offset) /*!< in/out: Array contains the
+ first offset number for each merge
+ run */
{
ulint foffs0; /*!< first input offset */
ulint foffs1; /*!< second input offset */
ulint error; /*!< error code */
merge_file_t of; /*!< output file */
- const ulint ihalf = *half;
+ const ulint ihalf = run_offset[*num_run / 2];
/*!< half the input file */
- ulint ohalf; /*!< half the output file */
+ ulint n_run = 0;
+ /*!< num of runs generated from this merge */
UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]);
+
ut_ad(ihalf < file->offset);
of.fd = *tmpfd;
@@ -1601,17 +1614,20 @@ row_merge(
of.n_rec = 0;
/* Merge blocks to the output file. */
- ohalf = 0;
foffs0 = 0;
foffs1 = ihalf;
+ UNIV_MEM_INVALID(run_offset, *num_run * sizeof *run_offset);
+
for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
- ulint ahalf; /*!< arithmetic half the input file */
if (UNIV_UNLIKELY(trx_is_interrupted(trx))) {
return(DB_INTERRUPTED);
}
+ /* Remember the offset number for this run */
+ run_offset[n_run++] = of.offset;
+
error = row_merge_blocks(index, file, block,
&foffs0, &foffs1, &of, table);
@@ -1619,21 +1635,6 @@ row_merge(
return(error);
}
- /* Record the offset of the output file when
- approximately half the output has been generated. In
- this way, the next invocation of row_merge() will
- spend most of the time in this loop. The initial
- estimate is ohalf==0. */
- ahalf = file->offset / 2;
- ut_ad(ohalf <= of.offset);
-
- /* Improve the estimate until reaching half the input
- file size, or we can not get any closer to it. All
- comparands should be non-negative when !(ohalf < ahalf)
- because ohalf <= of.offset. */
- if (ohalf < ahalf || of.offset - ahalf < ohalf - ahalf) {
- ohalf = of.offset;
- }
}
/* Copy the last blocks, if there are any. */
@@ -1643,6 +1644,9 @@ row_merge(
return(DB_INTERRUPTED);
}
+ /* Remember the offset number for this run */
+ run_offset[n_run++] = of.offset;
+
if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) {
return(DB_CORRUPTION);
}
@@ -1655,6 +1659,9 @@ row_merge(
return(DB_INTERRUPTED);
}
+ /* Remember the offset number for this run */
+ run_offset[n_run++] = of.offset;
+
if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) {
return(DB_CORRUPTION);
}
@@ -1666,10 +1673,23 @@ row_merge(
return(DB_CORRUPTION);
}
+ ut_ad(n_run <= *num_run);
+
+ *num_run = n_run;
+
+ /* Each run can contain one or more offsets. As merge goes on,
+ the number of runs (to merge) will reduce until we have one
+ single run. So the number of runs will always be smaller than
+ the number of offsets in file */
+ ut_ad((*num_run) <= file->offset);
+
+ /* The number of offsets in output file is always equal or
+ smaller than input file */
+ ut_ad(of.offset <= file->offset);
+
/* Swap file descriptors for the next pass. */
*tmpfd = file->fd;
*file = of;
- *half = ohalf;
UNIV_MEM_INVALID(block[0], 3 * sizeof block[0]);
@@ -1694,27 +1714,44 @@ row_merge_sort(
if applicable */
{
ulint half = file->offset / 2;
+ ulint num_runs;
+ ulint* run_offset;
+ ulint error = DB_SUCCESS;
+
+ /* Record the number of merge runs we need to perform */
+ num_runs = file->offset;
+
+ /* If num_runs are less than 1, nothing to merge */
+ if (num_runs <= 1) {
+ return(error);
+ }
+
+ /* "run_offset" records each run's first offset number */
+ run_offset = (ulint*) mem_alloc(file->offset * sizeof(ulint));
+
+ /* This tells row_merge() where to start for the first round
+ of merge. */
+ run_offset[half] = half;
/* The file should always contain at least one byte (the end
of file marker). Thus, it must be at least one block. */
ut_ad(file->offset > 0);
+ /* Merge the runs until we have one big run */
do {
- ulint error;
+ error = row_merge(trx, index, file, block, tmpfd,
+ table, &num_runs, run_offset);
- error = row_merge(trx, index, file, &half,
- block, tmpfd, table);
+ UNIV_MEM_ASSERT_RW(run_offset, num_runs * sizeof *run_offset);
if (error != DB_SUCCESS) {
- return(error);
+ break;
}
+ } while (num_runs > 1);
- /* half > 0 should hold except when the file consists
- of one block. No need to merge further then. */
- ut_ad(half > 0 || file->offset == 1);
- } while (half < file->offset && half > 0);
+ mem_free(run_offset);
- return(DB_SUCCESS);
+ return(error);
}
/*************************************************************//**
@@ -1986,6 +2023,8 @@ row_merge_drop_index(
"UPDATE SYS_INDEXES SET NAME=CONCAT('"
TEMP_INDEX_PREFIX_STR "', NAME) WHERE ID = :indexid;\n"
"COMMIT WORK;\n"
+ /* Drop the statistics of the index. */
+ "DELETE FROM SYS_STATS WHERE INDEX_ID = :indexid;\n"
/* Drop the field definitions of the index. */
"DELETE FROM SYS_FIELDS WHERE INDEX_ID = :indexid;\n"
/* Drop the index definition and the B-tree. */
@@ -2094,13 +2133,16 @@ row_merge_drop_temp_indexes(void)
btr_pcur_store_position(&pcur, &mtr);
btr_pcur_commit_specify_mtr(&pcur, &mtr);
- table = dict_load_table_on_id(table_id);
+ table = dict_table_get_on_id_low(table_id);
if (table) {
dict_index_t* index;
+ dict_index_t* next_index;
for (index = dict_table_get_first_index(table);
- index; index = dict_table_get_next_index(index)) {
+ index; index = next_index) {
+
+ next_index = dict_table_get_next_index(index);
if (*index->name == TEMP_INDEX_PREFIX) {
row_merge_drop_index(index, table, trx);
@@ -2303,7 +2345,7 @@ row_merge_rename_tables(
{
ulint err = DB_ERROR;
pars_info_t* info;
- const char* old_name= old_table->name;
+ char old_name[MAX_TABLE_NAME_LEN + 1];
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
ut_ad(old_table != new_table);
@@ -2311,6 +2353,17 @@ row_merge_rename_tables(
ut_a(trx->dict_operation_lock_mode == RW_X_LATCH);
+ /* store the old/current name to an automatic variable */
+ if (strlen(old_table->name) + 1 <= sizeof(old_name)) {
+ memcpy(old_name, old_table->name, strlen(old_table->name) + 1);
+ } else {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, "InnoDB: too long table name: '%s', "
+ "max length is %d\n", old_table->name,
+ MAX_TABLE_NAME_LEN);
+ ut_error;
+ }
+
trx->op_info = "renaming tables";
/* We use the private SQL parser of Innobase to generate the query
diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c
index e520065ea04..62221fa456d 100644
--- a/storage/xtradb/row/row0mysql.c
+++ b/storage/xtradb/row/row0mysql.c
@@ -30,6 +30,7 @@ Created 9/17/2000 Heikki Tuuri
#include "row0mysql.ic"
#endif
+#include "ha_prototypes.h"
#include "row0ins.h"
#include "row0merge.h"
#include "row0sel.h"
@@ -522,6 +523,7 @@ handle_new_error:
case DB_CANNOT_ADD_CONSTRAINT:
case DB_TOO_MANY_CONCURRENT_TRXS:
case DB_OUT_OF_FILE_SPACE:
+ case DB_INTERRUPTED:
if (savept) {
/* Roll back the latest, possibly incomplete
insertion or update */
@@ -624,6 +626,8 @@ row_create_prebuilt(
prebuilt->select_lock_type = LOCK_NONE;
prebuilt->stored_select_lock_type = 99999999;
+ UNIV_MEM_INVALID(&prebuilt->stored_select_lock_type,
+ sizeof prebuilt->stored_select_lock_type);
prebuilt->search_tuple = dtuple_create(
heap, 2 * dict_table_get_n_cols(table));
@@ -864,7 +868,7 @@ row_update_statistics_if_needed(
if (counter > 2000000000
|| ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) {
- dict_update_statistics(table);
+ dict_update_statistics(table, TRUE);
}
}
@@ -1124,6 +1128,13 @@ row_insert_for_mysql(
thr = que_fork_get_first_thr(prebuilt->ins_graph);
+ if (!prebuilt->mysql_has_locked) {
+ fprintf(stderr, "InnoDB: Error: row_insert_for_mysql is called without ha_innobase::external_lock()\n");
+ if (trx->mysql_thd != NULL) {
+ innobase_mysql_print_thd(stderr, trx->mysql_thd, 600);
+ }
+ }
+
if (prebuilt->sql_stat_start) {
node->state = INS_NODE_SET_IX_LOCK;
prebuilt->sql_stat_start = FALSE;
@@ -1430,27 +1441,26 @@ run_again:
}
/*********************************************************************//**
-This can only be used when srv_locks_unsafe_for_binlog is TRUE or
-this session is using a READ COMMITTED isolation level. Before
-calling this function we must use trx_reset_new_rec_lock_info() and
-trx_register_new_rec_lock() to store the information which new record locks
-really were set. This function removes a newly set lock under prebuilt->pcur,
-and also under prebuilt->clust_pcur. Currently, this is only used and tested
-in the case of an UPDATE or a DELETE statement, where the row lock is of the
-LOCK_X type.
-Thus, this implements a 'mini-rollback' that releases the latest record
-locks we set.
-@return error code or DB_SUCCESS */
+This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
+session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
+Before calling this function row_search_for_mysql() must have
+initialized prebuilt->new_rec_locks to store the information which new
+record locks really were set. This function removes a newly set
+clustered index record lock under prebuilt->pcur or
+prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that
+releases the latest clustered index record lock we set.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_unlock_for_mysql(
/*=================*/
- row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct in MySQL
handle */
- ibool has_latches_on_recs)/*!< TRUE if called so that we have
- the latches on the records under pcur
- and clust_pcur, and we do not need to
- reposition the cursors. */
+ ibool has_latches_on_recs)/*!< in: TRUE if called so
+ that we have the latches on
+ the records under pcur and
+ clust_pcur, and we do not need
+ to reposition the cursors. */
{
btr_pcur_t* pcur = prebuilt->pcur;
btr_pcur_t* clust_pcur = prebuilt->clust_pcur;
@@ -1648,37 +1658,6 @@ row_table_got_default_clust_index(
}
/*********************************************************************//**
-Calculates the key number used inside MySQL for an Innobase index. We have
-to take into account if we generated a default clustered index for the table
-@return the key number used inside MySQL */
-UNIV_INTERN
-ulint
-row_get_mysql_key_number_for_index(
-/*===============================*/
- const dict_index_t* index) /*!< in: index */
-{
- const dict_index_t* ind;
- ulint i;
-
- ut_a(index);
-
- i = 0;
- ind = dict_table_get_first_index(index->table);
-
- while (index != ind) {
- ind = dict_table_get_next_index(ind);
- i++;
- }
-
- if (row_table_got_default_clust_index(index->table)) {
- ut_a(i > 0);
- i--;
- }
-
- return(i);
-}
-
-/*********************************************************************//**
Locks the data dictionary in shared mode from modifications, for performing
foreign key check, rollback, or other operation invisible to MySQL. */
UNIV_INTERN
@@ -2044,6 +2023,45 @@ error_handling:
}
/*********************************************************************//**
+*/
+UNIV_INTERN
+int
+row_insert_stats_for_mysql(
+/*=======================*/
+ dict_index_t* index,
+ trx_t* trx)
+{
+ ind_node_t* node;
+ mem_heap_t* heap;
+ que_thr_t* thr;
+ ulint err;
+
+ ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
+
+ trx->op_info = "try to insert rows to SYS_STATS";
+
+ trx_start_if_not_started(trx);
+ trx->error_state = DB_SUCCESS;
+
+ heap = mem_heap_create(512);
+
+ node = ind_insert_stats_graph_create(index, heap);
+
+ thr = pars_complete_graph_for_exec(node, trx, heap);
+
+ ut_a(thr == que_fork_start_command(que_node_get_parent(thr)));
+ que_run_threads(thr);
+
+ err = trx->error_state;
+
+ que_graph_free((que_t*) que_node_get_parent(thr));
+
+ trx->op_info = "";
+
+ return((int) err);
+}
+
+/*********************************************************************//**
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created.
@@ -2062,6 +2080,7 @@ row_table_add_foreign_constraints(
FOREIGN KEY (a, b) REFERENCES table2(c, d),
table2 can be written also with the
database name before it: test.table2 */
+ size_t sql_length, /*!< in: length of sql_string */
const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
@@ -2083,8 +2102,8 @@ row_table_add_foreign_constraints(
trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
- err = dict_create_foreign_constraints(trx, sql_string, name,
- reject_fks);
+ err = dict_create_foreign_constraints(trx, sql_string, sql_length,
+ name, reject_fks);
if (err == DB_SUCCESS) {
/* Check that also referencing constraints are ok */
err = dict_load_foreigns(name, TRUE);
@@ -2428,7 +2447,7 @@ row_discard_tablespace_for_mysql(
goto funct_exit;
}
- new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
+ dict_hdr_get_new_id(&new_id, NULL, NULL);
/* Remove all locks except the table-level S and X locks. */
lock_remove_all_on_table(table, FALSE);
@@ -2790,10 +2809,11 @@ row_truncate_table_for_mysql(
dict_index_t* index;
- space = 0;
+ dict_hdr_get_new_id(NULL, NULL, &space);
- if (fil_create_new_single_table_tablespace(
- &space, table->name, FALSE, flags,
+ if (space == ULINT_UNDEFINED
+ || fil_create_new_single_table_tablespace(
+ space, table->name, FALSE, flags,
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -2898,7 +2918,7 @@ next_rec:
mem_heap_free(heap);
- new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
+ dict_hdr_get_new_id(&new_id, NULL, NULL);
info = pars_info_create();
@@ -2942,7 +2962,7 @@ next_rec:
dict_table_autoinc_lock(table);
dict_table_autoinc_initialize(table, 1);
dict_table_autoinc_unlock(table);
- dict_update_statistics(table);
+ dict_update_statistics(table, TRUE);
trx_commit_for_mysql(trx);
@@ -3244,6 +3264,8 @@ check_next_foreign:
" IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n"
" ELSE\n"
+ " DELETE FROM SYS_STATS\n"
+ " WHERE INDEX_ID = index_id;\n"
" DELETE FROM SYS_FIELDS\n"
" WHERE INDEX_ID = index_id;\n"
" DELETE FROM SYS_INDEXES\n"
diff --git a/storage/xtradb/row/row0purge.c b/storage/xtradb/row/row0purge.c
index 500ebe571ab..835af990672 100644
--- a/storage/xtradb/row/row0purge.c
+++ b/storage/xtradb/row/row0purge.c
@@ -44,6 +44,16 @@ Created 3/14/1997 Heikki Tuuri
#include "row0mysql.h"
#include "log0log.h"
+/*************************************************************************
+IMPORTANT NOTE: Any operation that generates redo MUST check that there
+is enough space in the redo log before for that operation. This is
+done by calling log_free_check(). The reason for checking the
+availability of the redo log space before the start of the operation is
+that we MUST not hold any synchonization objects when performing the
+check.
+If you make a change in this module make sure that no codepath is
+introduced where a call to log_free_check() is bypassed. */
+
/********************************************************************//**
Creates a purge node to a query graph.
@return own: purge node */
@@ -126,6 +136,7 @@ row_purge_remove_clust_if_poss_low(
pcur = &(node->pcur);
btr_cur = btr_pcur_get_btr_cur(pcur);
+ log_free_check();
mtr_start(&mtr);
success = row_purge_reposition_pcur(mode, node, &mtr);
diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c
index 43e67ff6ded..0db4fb6f3db 100644
--- a/storage/xtradb/row/row0sel.c
+++ b/storage/xtradb/row/row0sel.c
@@ -863,8 +863,14 @@ row_sel_get_clust_rec(
clust_rec, index, offsets,
node->row_lock_mode, lock_type, thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS:
+ case DB_SUCCESS_LOCKED_REC:
+ /* Declare the variable uninitialized in Valgrind.
+ It should be set to DB_SUCCESS at func_exit. */
+ UNIV_MEM_INVALID(&err, sizeof err);
+ break;
+ default:
goto err_exit;
}
} else {
@@ -934,9 +940,9 @@ err_exit:
/*********************************************************************//**
Sets a lock on a record.
-@return DB_SUCCESS or error code */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
UNIV_INLINE
-ulint
+enum db_err
sel_set_rec_lock(
/*=============*/
const buf_block_t* block, /*!< in: buffer block of rec */
@@ -948,8 +954,8 @@ sel_set_rec_lock(
LOC_REC_NOT_GAP */
que_thr_t* thr) /*!< in: query thread */
{
- trx_t* trx;
- ulint err;
+ trx_t* trx;
+ enum db_err err;
trx = thr_get_trx(thr);
@@ -1482,11 +1488,15 @@ rec_loop:
node->row_lock_mode,
lock_type, thr);
- if (err != DB_SUCCESS) {
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ err = DB_SUCCESS;
+ case DB_SUCCESS:
+ break;
+ default:
/* Note that in this case we will store in pcur
the PREDECESSOR of the record we are waiting
the lock for */
-
goto lock_wait_or_error;
}
}
@@ -1538,8 +1548,12 @@ skip_lock:
rec, index, offsets,
node->row_lock_mode, lock_type, thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ err = DB_SUCCESS;
+ case DB_SUCCESS:
+ break;
+ default:
goto lock_wait_or_error;
}
}
@@ -2498,6 +2512,7 @@ row_sel_field_store_in_mysql_format(
byte* pad_ptr;
ut_ad(len != UNIV_SQL_NULL);
+ UNIV_MEM_ASSERT_RW(data, len);
switch (templ->type) {
case DATA_INT:
@@ -2752,6 +2767,9 @@ row_sel_store_mysql_rec(
/* MySQL assumes that the field for an SQL
NULL value is set to the default value. */
+ UNIV_MEM_ASSERT_RW(prebuilt->default_rec
+ + templ->mysql_col_offset,
+ templ->mysql_col_len);
mysql_rec[templ->mysql_null_byte_offset]
|= (byte) templ->mysql_null_bit_mask;
memcpy(mysql_rec + templ->mysql_col_offset,
@@ -2803,9 +2821,9 @@ row_sel_build_prev_vers_for_mysql(
Retrieves the clustered index record corresponding to a record in a
non-clustered index. Does the necessary locking. Used in the MySQL
interface.
-@return DB_SUCCESS or error code */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
static
-ulint
+enum db_err
row_sel_get_clust_rec_for_mysql(
/*============================*/
row_prebuilt_t* prebuilt,/*!< in: prebuilt struct in the handle */
@@ -2832,7 +2850,7 @@ row_sel_get_clust_rec_for_mysql(
dict_index_t* clust_index;
const rec_t* clust_rec;
rec_t* old_vers;
- ulint err;
+ enum db_err err;
trx_t* trx;
*out_rec = NULL;
@@ -2891,6 +2909,7 @@ row_sel_get_clust_rec_for_mysql(
clust_rec = NULL;
+ err = DB_SUCCESS;
goto func_exit;
}
@@ -2906,8 +2925,11 @@ row_sel_get_clust_rec_for_mysql(
0, btr_pcur_get_block(prebuilt->clust_pcur),
clust_rec, clust_index, *offsets,
prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS:
+ case DB_SUCCESS_LOCKED_REC:
+ break;
+ default:
goto err_exit;
}
} else {
@@ -2967,6 +2989,8 @@ row_sel_get_clust_rec_for_mysql(
rec, sec_index, clust_rec, clust_index));
#endif
}
+
+ err = DB_SUCCESS;
}
func_exit:
@@ -2979,7 +3003,6 @@ func_exit:
btr_pcur_store_position(prebuilt->clust_pcur, mtr);
}
- err = DB_SUCCESS;
err_exit:
return(err);
}
@@ -3076,6 +3099,11 @@ row_sel_pop_cached_row_for_mysql(
for (i = 0; i < prebuilt->n_template; i++) {
templ = prebuilt->mysql_template + i;
+#if 0 /* Some of the cached_rec may legitimately be uninitialized. */
+ UNIV_MEM_ASSERT_RW(cached_rec
+ + templ->mysql_col_offset,
+ templ->mysql_col_len);
+#endif
ut_memcpy(buf + templ->mysql_col_offset,
cached_rec + templ->mysql_col_offset,
templ->mysql_col_len);
@@ -3090,6 +3118,11 @@ row_sel_pop_cached_row_for_mysql(
}
}
else {
+#if 0 /* Some of the cached_rec may legitimately be uninitialized. */
+ UNIV_MEM_ASSERT_RW(prebuilt->fetch_cache
+ [prebuilt->fetch_cache_first],
+ prebuilt->mysql_prefix_len);
+#endif
ut_memcpy(buf,
prebuilt->fetch_cache[prebuilt->fetch_cache_first],
prebuilt->mysql_prefix_len);
@@ -3140,6 +3173,8 @@ row_sel_push_cache_row_for_mysql(
}
ut_ad(prebuilt->fetch_cache_first == 0);
+ UNIV_MEM_INVALID(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
+ prebuilt->mysql_row_len);
if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
prebuilt->fetch_cache[
@@ -3286,6 +3321,7 @@ row_search_for_mysql(
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
+ ibool problematic_use = FALSE;
rec_offs_init(offsets_);
@@ -3601,6 +3637,13 @@ shortcut_fails_too_big_rec:
trx->has_search_latch = FALSE;
}
+ ut_ad(prebuilt->sql_stat_start || trx->conc_state == TRX_ACTIVE);
+ ut_ad(trx->conc_state == TRX_NOT_STARTED
+ || trx->conc_state == TRX_ACTIVE);
+ ut_ad(prebuilt->sql_stat_start
+ || prebuilt->select_lock_type != LOCK_NONE
+ || trx->read_view);
+
trx_start_if_not_started(trx);
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
@@ -3685,8 +3728,12 @@ shortcut_fails_too_big_rec:
prebuilt->select_lock_type,
LOCK_GAP, thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ err = DB_SUCCESS;
+ case DB_SUCCESS:
+ break;
+ default:
goto lock_wait_or_error;
}
}
@@ -3702,6 +3749,15 @@ shortcut_fails_too_big_rec:
}
}
+ if (!prebuilt->mysql_has_locked) {
+ fprintf(stderr, "InnoDB: Error: row_search_for_mysql() is called without ha_innobase::external_lock()\n");
+ if (trx->mysql_thd != NULL) {
+ innobase_mysql_print_thd(stderr, trx->mysql_thd, 600);
+ }
+ problematic_use = TRUE;
+ }
+retry_check:
+
if (!prebuilt->sql_stat_start) {
/* No need to set an intention lock or assign a read view */
@@ -3712,6 +3768,14 @@ shortcut_fails_too_big_rec:
" perform a consistent read\n"
"InnoDB: but the read view is not assigned!\n",
stderr);
+ if (problematic_use) {
+ fprintf(stderr, "InnoDB: It may be caused by calling "
+ "without ha_innobase::external_lock()\n"
+ "InnoDB: For the first-aid, avoiding the crash. "
+ "But it should be fixed ASAP.\n");
+ prebuilt->sql_stat_start = TRUE;
+ goto retry_check;
+ }
trx_print(stderr, trx, 600);
fputc('\n', stderr);
ut_a(0);
@@ -3791,8 +3855,12 @@ rec_loop:
prebuilt->select_lock_type,
LOCK_ORDINARY, thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ err = DB_SUCCESS;
+ case DB_SUCCESS:
+ break;
+ default:
goto lock_wait_or_error;
}
}
@@ -3922,8 +3990,11 @@ wrong_offs:
prebuilt->select_lock_type, LOCK_GAP,
thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
+ break;
+ default:
goto lock_wait_or_error;
}
}
@@ -3958,8 +4029,11 @@ wrong_offs:
prebuilt->select_lock_type, LOCK_GAP,
thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
+ break;
+ default:
goto lock_wait_or_error;
}
}
@@ -4029,15 +4103,21 @@ no_gap_lock:
switch (err) {
const rec_t* old_vers;
- case DB_SUCCESS:
+ case DB_SUCCESS_LOCKED_REC:
if (srv_locks_unsafe_for_binlog
- || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
+ || trx->isolation_level
+ <= TRX_ISO_READ_COMMITTED) {
/* Note that a record of
prebuilt->index was locked. */
prebuilt->new_rec_locks = 1;
}
+ err = DB_SUCCESS;
+ case DB_SUCCESS:
break;
case DB_LOCK_WAIT:
+ /* Never unlock rows that were part of a conflict. */
+ prebuilt->new_rec_locks = 0;
+
if (UNIV_LIKELY(prebuilt->row_read_type
!= ROW_READ_TRY_SEMI_CONSISTENT)
|| unique_search
@@ -4067,7 +4147,6 @@ no_gap_lock:
if (UNIV_LIKELY(trx->wait_lock != NULL)) {
lock_cancel_waiting_and_release(
trx->wait_lock);
- prebuilt->new_rec_locks = 0;
} else {
mutex_exit(&kernel_mutex);
@@ -4079,9 +4158,6 @@ no_gap_lock:
ULINT_UNDEFINED,
&heap);
err = DB_SUCCESS;
- /* Note that a record of
- prebuilt->index was locked. */
- prebuilt->new_rec_locks = 1;
break;
}
mutex_exit(&kernel_mutex);
@@ -4218,27 +4294,30 @@ requires_clust_rec:
err = row_sel_get_clust_rec_for_mysql(prebuilt, index, rec,
thr, &clust_rec,
&offsets, &heap, &mtr);
- if (err != DB_SUCCESS) {
+ switch (err) {
+ case DB_SUCCESS:
+ if (clust_rec == NULL) {
+ /* The record did not exist in the read view */
+ ut_ad(prebuilt->select_lock_type == LOCK_NONE);
+ goto next_rec;
+ }
+ break;
+ case DB_SUCCESS_LOCKED_REC:
+ ut_a(clust_rec != NULL);
+ if (srv_locks_unsafe_for_binlog
+ || trx->isolation_level
+ <= TRX_ISO_READ_COMMITTED) {
+ /* Note that the clustered index record
+ was locked. */
+ prebuilt->new_rec_locks = 2;
+ }
+ err = DB_SUCCESS;
+ break;
+ default:
goto lock_wait_or_error;
}
- if (clust_rec == NULL) {
- /* The record did not exist in the read view */
- ut_ad(prebuilt->select_lock_type == LOCK_NONE);
-
- goto next_rec;
- }
-
- if ((srv_locks_unsafe_for_binlog
- || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
- && prebuilt->select_lock_type != LOCK_NONE) {
- /* Note that both the secondary index record
- and the clustered index record were locked. */
- ut_ad(prebuilt->new_rec_locks == 1);
- prebuilt->new_rec_locks = 2;
- }
-
if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) {
/* The record is delete marked: we can skip it */
diff --git a/storage/xtradb/row/row0uins.c b/storage/xtradb/row/row0uins.c
index 9f9c814f1a5..930a5cf13b6 100644
--- a/storage/xtradb/row/row0uins.c
+++ b/storage/xtradb/row/row0uins.c
@@ -46,6 +46,16 @@ Created 2/25/1997 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "log0log.h"
+/*************************************************************************
+IMPORTANT NOTE: Any operation that generates redo MUST check that there
+is enough space in the redo log before for that operation. This is
+done by calling log_free_check(). The reason for checking the
+availability of the redo log space before the start of the operation is
+that we MUST not hold any synchonization objects when performing the
+check.
+If you make a change in this module make sure that no codepath is
+introduced where a call to log_free_check() is bypassed. */
+
/***************************************************************//**
Removes a clustered index record. The pcur in node was positioned on the
record, now it is detached.
@@ -152,7 +162,6 @@ row_undo_ins_remove_sec_low(
ulint err;
mtr_t mtr;
- log_free_check();
mtr_start(&mtr);
found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
@@ -335,6 +344,7 @@ row_undo_ins(
transactions. */
ut_a(trx_is_recv(node->trx));
} else {
+ log_free_check();
err = row_undo_ins_remove_sec(node->index, entry);
if (err != DB_SUCCESS) {
@@ -346,5 +356,6 @@ row_undo_ins(
node->index = dict_table_get_next_index(node->index);
}
+ log_free_check();
return(row_undo_ins_remove_clust_rec(node));
}
diff --git a/storage/xtradb/row/row0umod.c b/storage/xtradb/row/row0umod.c
index e7245dbee41..8464b0f95cc 100644
--- a/storage/xtradb/row/row0umod.c
+++ b/storage/xtradb/row/row0umod.c
@@ -58,12 +58,22 @@ delete marked clustered index record was delete unmarked and possibly also
some of its fields were changed. Now, it is possible that the delete marked
version has become obsolete at the time the undo is started. */
+/*************************************************************************
+IMPORTANT NOTE: Any operation that generates redo MUST check that there
+is enough space in the redo log before for that operation. This is
+done by calling log_free_check(). The reason for checking the
+availability of the redo log space before the start of the operation is
+that we MUST not hold any synchonization objects when performing the
+check.
+If you make a change in this module make sure that no codepath is
+introduced where a call to log_free_check() is bypassed. */
+
/***********************************************************//**
Checks if also the previous version of the clustered index record was
modified or inserted by the same transaction, and its undo number is such
that it should be undone in the same rollback.
@return TRUE if also previous modify or insert of this row should be undone */
-UNIV_INLINE
+static
ibool
row_undo_mod_undo_also_prev_vers(
/*=============================*/
@@ -231,6 +241,8 @@ row_undo_mod_clust(
ut_ad(node && thr);
+ log_free_check();
+
/* Check if also the previous version of the clustered index record
should be undone in this same rollback operation */
@@ -657,24 +669,55 @@ row_undo_mod_upd_exist_sec(
/* Build the newest version of the index entry */
entry = row_build_index_entry(node->row, node->ext,
index, heap);
- ut_a(entry);
- /* NOTE that if we updated the fields of a
- delete-marked secondary index record so that
- alphabetically they stayed the same, e.g.,
- 'abc' -> 'aBc', we cannot return to the original
- values because we do not know them. But this should
- not cause problems because in row0sel.c, in queries
- we always retrieve the clustered index record or an
- earlier version of it, if the secondary index record
- through which we do the search is delete-marked. */
-
- err = row_undo_mod_del_mark_or_remove_sec(node, thr,
- index,
- entry);
- if (err != DB_SUCCESS) {
- mem_heap_free(heap);
-
- return(err);
+ if (UNIV_UNLIKELY(!entry)) {
+ /* The server must have crashed in
+ row_upd_clust_rec_by_insert(), in
+ row_ins_index_entry_low() before
+ btr_store_big_rec_extern_fields()
+ has written the externally stored columns
+ (BLOBs) of the new clustered index entry. */
+
+ /* The table must be in DYNAMIC or COMPRESSED
+ format. REDUNDANT and COMPACT formats
+ store a local 768-byte prefix of each
+ externally stored column. */
+ ut_a(dict_table_get_format(index->table)
+ >= DICT_TF_FORMAT_ZIP);
+
+ /* This is only legitimate when
+ rolling back an incomplete transaction
+ after crash recovery. */
+ ut_a(thr_get_trx(thr)->is_recovered);
+
+ /* The server must have crashed before
+ completing the insert of the new
+ clustered index entry and before
+ inserting to the secondary indexes.
+ Because node->row was not yet written
+ to this index, we can ignore it. But
+ we must restore node->undo_row. */
+ } else {
+ /* NOTE that if we updated the fields of a
+ delete-marked secondary index record so that
+ alphabetically they stayed the same, e.g.,
+ 'abc' -> 'aBc', we cannot return to the
+ original values because we do not know them.
+ But this should not cause problems because
+ in row0sel.c, in queries we always retrieve
+ the clustered index record or an earlier
+ version of it, if the secondary index record
+ through which we do the search is
+ delete-marked. */
+
+ err = row_undo_mod_del_mark_or_remove_sec(
+ node, thr, index, entry);
+ if (err != DB_SUCCESS) {
+ mem_heap_free(heap);
+
+ return(err);
+ }
+
+ mem_heap_empty(heap);
}
/* We may have to update the delete mark in the
@@ -683,7 +726,6 @@ row_undo_mod_upd_exist_sec(
the secondary index record if we updated its fields
but alphabetically they stayed the same, e.g.,
'abc' -> 'aBc'. */
- mem_heap_empty(heap);
entry = row_build_index_entry(node->undo_row,
node->undo_ext,
index, heap);
diff --git a/storage/xtradb/row/row0undo.c b/storage/xtradb/row/row0undo.c
index 3d739c9689a..9ef842b5114 100644
--- a/storage/xtradb/row/row0undo.c
+++ b/storage/xtradb/row/row0undo.c
@@ -297,7 +297,7 @@ row_undo(
if (locked_data_dict) {
- row_mysql_lock_data_dictionary(trx);
+ row_mysql_freeze_data_dictionary(trx);
}
if (node->state == UNDO_NODE_INSERT) {
@@ -312,7 +312,7 @@ row_undo(
if (locked_data_dict) {
- row_mysql_unlock_data_dictionary(trx);
+ row_mysql_unfreeze_data_dictionary(trx);
}
/* Do some cleanup */
diff --git a/storage/xtradb/row/row0upd.c b/storage/xtradb/row/row0upd.c
index 95d1d00aeef..d0aaecd3dae 100644
--- a/storage/xtradb/row/row0upd.c
+++ b/storage/xtradb/row/row0upd.c
@@ -92,6 +92,16 @@ the x-latch freed? The most efficient way for performing a
searched delete is obviously to keep the x-latch for several
steps of query graph execution. */
+/*************************************************************************
+IMPORTANT NOTE: Any operation that generates redo MUST check that there
+is enough space in the redo log before for that operation. This is
+done by calling log_free_check(). The reason for checking the
+availability of the redo log space before the start of the operation is
+that we MUST not hold any synchonization objects when performing the
+check.
+If you make a change in this module make sure that no codepath is
+introduced where a call to log_free_check() is bypassed. */
+
/***********************************************************//**
Checks if an update vector changes some of the first ordering fields of an
index record. This is only used in foreign key checks and we can assume
@@ -1453,7 +1463,6 @@ row_upd_sec_index_entry(
entry = row_build_index_entry(node->row, node->ext, index, heap);
ut_a(entry);
- log_free_check();
mtr_start(&mtr);
found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
@@ -1529,7 +1538,7 @@ Updates the secondary index record if it is changed in the row update or
deletes it if this is a delete.
@return DB_SUCCESS if operation successfully completed, else error
code or DB_LOCK_WAIT */
-UNIV_INLINE
+static
ulint
row_upd_sec_step(
/*=============*/
@@ -2015,6 +2024,7 @@ row_upd(
if (node->state == UPD_NODE_UPDATE_CLUSTERED
|| node->state == UPD_NODE_INSERT_CLUSTERED) {
+ log_free_check();
err = row_upd_clust_step(node, thr);
if (err != DB_SUCCESS) {
@@ -2029,6 +2039,8 @@ row_upd(
}
while (node->index != NULL) {
+
+ log_free_check();
err = row_upd_sec_step(node, thr);
if (err != DB_SUCCESS) {
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index bc2dd562697..b9905116603 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -211,6 +211,9 @@ UNIV_INTERN ulint srv_buf_pool_curr_size = 0;
UNIV_INTERN ulint srv_mem_pool_size = ULINT_MAX;
UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX;
+/* key value for shm */
+UNIV_INTERN uint srv_buffer_pool_shm_key = 0;
+
/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
instead. */
UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
@@ -380,6 +383,7 @@ UNIV_INTERN unsigned long long srv_stats_sample_pages = 8;
UNIV_INTERN ulong srv_stats_method = 0;
UNIV_INTERN ulong srv_stats_auto_update = 1;
UNIV_INTERN ulint srv_stats_update_need_lock = 1;
+UNIV_INTERN ibool srv_use_sys_stats_table = FALSE;
UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
UNIV_INTERN ibool srv_use_checksums = TRUE;
@@ -1758,12 +1762,16 @@ srv_suspend_mysql_thread(
innodb_lock_wait_timeout, because trx->mysql_thd == NULL. */
lock_wait_timeout = thd_lock_wait_timeout(trx->mysql_thd);
- if (trx_is_interrupted(trx)
- || (lock_wait_timeout < 100000000
- && wait_time > (double) lock_wait_timeout)) {
+ if (lock_wait_timeout < 100000000
+ && wait_time > (double) lock_wait_timeout) {
trx->error_state = DB_LOCK_WAIT_TIMEOUT;
}
+
+ if (trx_is_interrupted(trx)) {
+
+ trx->error_state = DB_INTERRUPTED;
+ }
}
/********************************************************************//**
diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c
index 7b5581a24f0..62ffa366f18 100644
--- a/storage/xtradb/srv/srv0start.c
+++ b/storage/xtradb/srv/srv0start.c
@@ -1302,6 +1302,9 @@ innobase_start_or_create_for_mysql(void)
} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
+ } else if (0 == ut_strcmp(srv_file_flush_method_str, "ALL_O_DIRECT")) {
+ srv_unix_file_flush_method = SRV_UNIX_ALL_O_DIRECT;
+
} else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
@@ -1716,6 +1719,8 @@ innobase_start_or_create_for_mysql(void)
Note that this is not as heavy weight as it seems. At
this point there will be only ONE page in the buf_LRU
and there must be no page in the buf_flush list. */
+ /* TODO: treat more correctly */
+ if (!srv_buffer_pool_shm_key)
buf_pool_invalidate();
/* We always try to do a recovery, even if the database had
diff --git a/storage/xtradb/sync/sync0arr.c b/storage/xtradb/sync/sync0arr.c
index cfa52cdcc88..223e1715944 100644
--- a/storage/xtradb/sync/sync0arr.c
+++ b/storage/xtradb/sync/sync0arr.c
@@ -498,7 +498,9 @@ sync_array_cell_print(
|| type == RW_LOCK_WAIT_EX
|| type == RW_LOCK_SHARED) {
- fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file);
+ fputs(type == RW_LOCK_EX ? "X-lock on"
+ : type == RW_LOCK_WAIT_EX ? "X-lock (wait_ex) on"
+ : "S-lock on", file);
rwlock = cell->old_wait_rw_lock;
diff --git a/storage/xtradb/sync/sync0rw.c b/storage/xtradb/sync/sync0rw.c
index 07eac403dfe..9e10f6e943b 100644
--- a/storage/xtradb/sync/sync0rw.c
+++ b/storage/xtradb/sync/sync0rw.c
@@ -268,7 +268,7 @@ rw_lock_create_func(
lock->level = level;
#endif /* UNIV_SYNC_DEBUG */
- lock->magic_n = RW_LOCK_MAGIC_N;
+ ut_d(lock->magic_n = RW_LOCK_MAGIC_N);
lock->lock_name = cmutex_name;
@@ -282,10 +282,8 @@ rw_lock_create_func(
mutex_enter(&rw_lock_list_mutex);
- if (UT_LIST_GET_LEN(rw_lock_list) > 0) {
- ut_a(UT_LIST_GET_FIRST(rw_lock_list)->magic_n
- == RW_LOCK_MAGIC_N);
- }
+ ut_ad(UT_LIST_GET_FIRST(rw_lock_list) == NULL
+ || UT_LIST_GET_FIRST(rw_lock_list)->magic_n == RW_LOCK_MAGIC_N);
UT_LIST_ADD_FIRST(list, rw_lock_list, lock);
@@ -314,18 +312,16 @@ rw_lock_free(
os_event_free(lock->wait_ex_event);
- if (UT_LIST_GET_PREV(list, lock)) {
- ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N);
- }
- if (UT_LIST_GET_NEXT(list, lock)) {
- ut_a(UT_LIST_GET_NEXT(list, lock)->magic_n == RW_LOCK_MAGIC_N);
- }
+ ut_ad(UT_LIST_GET_PREV(list, lock) == NULL
+ || UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N);
+ ut_ad(UT_LIST_GET_NEXT(list, lock) == NULL
+ || UT_LIST_GET_NEXT(list, lock)->magic_n == RW_LOCK_MAGIC_N);
UT_LIST_REMOVE(list, rw_lock_list, lock);
mutex_exit(&rw_lock_list_mutex);
- lock->magic_n = 0;
+ ut_d(lock->magic_n = 0);
}
#ifdef UNIV_DEBUG
@@ -344,7 +340,7 @@ rw_lock_validate(
ulint waiters = rw_lock_get_waiters(lock);
lint lock_word = lock->lock_word;
- ut_a(lock->magic_n == RW_LOCK_MAGIC_N);
+ ut_ad(lock->magic_n == RW_LOCK_MAGIC_N);
ut_a(waiters == 0 || waiters == 1);
ut_a(lock_word > -X_LOCK_DECR ||(-lock_word) % X_LOCK_DECR == 0);
diff --git a/storage/xtradb/sync/sync0sync.c b/storage/xtradb/sync/sync0sync.c
index fe14cbf0886..225f28df78e 100644
--- a/storage/xtradb/sync/sync0sync.c
+++ b/storage/xtradb/sync/sync0sync.c
@@ -434,20 +434,19 @@ mutex_set_waiters(
mutex_t* mutex, /*!< in: mutex */
ulint n) /*!< in: value to set */
{
-#ifndef INNODB_RW_LOCKS_USE_ATOMICS
- volatile ulint* ptr; /* declared volatile to ensure that
- the value is stored to memory */
-#endif
-
+#ifdef INNODB_RW_LOCKS_USE_ATOMICS
ut_ad(mutex);
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
if (n) {
os_compare_and_swap_ulint(&mutex->waiters, 0, 1);
} else {
os_compare_and_swap_ulint(&mutex->waiters, 1, 0);
}
#else
+ volatile ulint* ptr; /* declared volatile to ensure that
+ the value is stored to memory */
+ ut_ad(mutex);
+
ptr = &(mutex->waiters);
*ptr = n; /* Here we assume that the write of a single
diff --git a/storage/xtradb/trx/trx0i_s.c b/storage/xtradb/trx/trx0i_s.c
index c160eb2942a..5bc8302d0c0 100644
--- a/storage/xtradb/trx/trx0i_s.c
+++ b/storage/xtradb/trx/trx0i_s.c
@@ -429,6 +429,9 @@ fill_trx_row(
which to copy volatile
strings */
{
+ const char* stmt;
+ size_t stmt_len;
+
row->trx_id = trx_get_id(trx);
row->trx_started = (ib_time_t) trx->start_time;
row->trx_state = trx_get_que_state_str(trx);
@@ -449,37 +452,32 @@ fill_trx_row(
row->trx_weight = (ullint) ut_conv_dulint_to_longlong(TRX_WEIGHT(trx));
- if (trx->mysql_thd != NULL) {
- row->trx_mysql_thread_id
- = thd_get_thread_id(trx->mysql_thd);
- } else {
+ if (trx->mysql_thd == NULL) {
/* For internal transactions e.g., purge and transactions
being recovered at startup there is no associated MySQL
thread data structure. */
row->trx_mysql_thread_id = 0;
+ row->trx_query = NULL;
+ return(TRUE);
}
- if (trx->mysql_query_str != NULL && *trx->mysql_query_str != NULL) {
+ row->trx_mysql_thread_id = thd_get_thread_id(trx->mysql_thd);
+ stmt = innobase_get_stmt(trx->mysql_thd, &stmt_len);
- if (strlen(*trx->mysql_query_str)
- > TRX_I_S_TRX_QUERY_MAX_LEN) {
+ if (stmt != NULL) {
- char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];
+ char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];
- memcpy(query, *trx->mysql_query_str,
- TRX_I_S_TRX_QUERY_MAX_LEN);
- query[TRX_I_S_TRX_QUERY_MAX_LEN] = '\0';
+ if (stmt_len > TRX_I_S_TRX_QUERY_MAX_LEN) {
+ stmt_len = TRX_I_S_TRX_QUERY_MAX_LEN;
+ }
- row->trx_query = ha_storage_put_memlim(
- cache->storage, query,
- TRX_I_S_TRX_QUERY_MAX_LEN + 1,
- MAX_ALLOWED_FOR_STORAGE(cache));
- } else {
+ memcpy(query, stmt, stmt_len);
+ query[stmt_len] = '\0';
- row->trx_query = ha_storage_put_str_memlim(
- cache->storage, *trx->mysql_query_str,
- MAX_ALLOWED_FOR_STORAGE(cache));
- }
+ row->trx_query = ha_storage_put_memlim(
+ cache->storage, stmt, stmt_len + 1,
+ MAX_ALLOWED_FOR_STORAGE(cache));
if (row->trx_query == NULL) {
diff --git a/storage/xtradb/trx/trx0purge.c b/storage/xtradb/trx/trx0purge.c
index 41e16b35e85..1c317665878 100644
--- a/storage/xtradb/trx/trx0purge.c
+++ b/storage/xtradb/trx/trx0purge.c
@@ -1148,8 +1148,7 @@ trx_purge(void)
/* If we cannot advance the 'purge view' because of an old
'consistent read view', then the DML statements cannot be delayed.
Also, srv_max_purge_lag <= 0 means 'infinity'. */
- if (srv_max_purge_lag > 0
- && !UT_LIST_GET_LAST(trx_sys->view_list)) {
+ if (srv_max_purge_lag > 0) {
float ratio = (float) trx_sys->rseg_history_len
/ srv_max_purge_lag;
if (ratio > ULINT_MAX / 10000) {
diff --git a/storage/xtradb/trx/trx0sys.c b/storage/xtradb/trx/trx0sys.c
index 47a21c3a318..ad4471ada0b 100644
--- a/storage/xtradb/trx/trx0sys.c
+++ b/storage/xtradb/trx/trx0sys.c
@@ -840,13 +840,13 @@ UNIV_INTERN
void
trx_sys_update_mysql_binlog_offset(
/*===============================*/
+ trx_sysf_t* sys_header,
const char* file_name_in,/*!< in: MySQL log file name */
ib_int64_t offset, /*!< in: position in that log file */
ulint field, /*!< in: offset of the MySQL log info field in
the trx sys header */
mtr_t* mtr) /*!< in: mtr */
{
- trx_sysf_t* sys_header;
const char* file_name;
if (ut_strlen(file_name_in) >= TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN) {
@@ -860,8 +860,6 @@ trx_sys_update_mysql_binlog_offset(
file_name = file_name_in;
}
- sys_header = trx_sysf_get(mtr);
-
if (mach_read_from_4(sys_header + field
+ TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
!= TRX_SYS_MYSQL_LOG_MAGIC_N) {
@@ -1143,14 +1141,8 @@ trx_sysf_dummy_create(
ulint space,
mtr_t* mtr)
{
-#ifdef UNDEFINED
- trx_sysf_t* sys_header;
- ulint slot_no;
- ulint page_no;
- ulint i;
-#endif
- page_t* page;
buf_block_t* block;
+ page_t* page;
ut_ad(mtr);
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index f150d64f8dc..9584f0c4c46 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -109,6 +109,8 @@ trx_create(
trx->support_xa = TRUE;
+ trx->flush_log_at_trx_commit_session = 3; /* means to use innodb_flush_log_at_trx_commit value */
+
trx->check_foreigns = TRUE;
trx->check_unique_secondary = TRUE;
@@ -119,7 +121,6 @@ trx_create(
trx->table_id = ut_dulint_zero;
trx->mysql_thd = NULL;
- trx->mysql_query_str = NULL;
trx->active_trans = 0;
trx->duplicates = 0;
@@ -736,6 +737,9 @@ trx_start(
generated by the same transaction, doesn't. */
trx->support_xa = thd_supports_xa(trx->mysql_thd);
+ trx->flush_log_at_trx_commit_session =
+ thd_flush_log_at_trx_commit_session(trx->mysql_thd);
+
mutex_enter(&kernel_mutex);
ret = trx_start_low(trx, rseg_id);
@@ -758,6 +762,7 @@ trx_commit_off_kernel(
trx_rseg_t* rseg;
trx_undo_t* undo;
mtr_t mtr;
+ trx_sysf_t* sys_header = NULL;
ut_ad(mutex_own(&kernel_mutex));
@@ -815,7 +820,11 @@ trx_commit_off_kernel(
if (trx->mysql_log_file_name
&& trx->mysql_log_file_name[0] != '\0') {
+ if (!sys_header) {
+ sys_header = trx_sysf_get(&mtr);
+ }
trx_sys_update_mysql_binlog_offset(
+ sys_header,
trx->mysql_log_file_name,
trx->mysql_log_offset,
TRX_SYS_MYSQL_LOG_INFO, &mtr);
@@ -824,11 +833,16 @@ trx_commit_off_kernel(
if (trx->mysql_master_log_file_name[0] != '\0') {
/* This database server is a MySQL replication slave */
+ if (!sys_header) {
+ sys_header = trx_sysf_get(&mtr);
+ }
trx_sys_update_mysql_binlog_offset(
+ sys_header,
trx->mysql_relay_log_file_name,
trx->mysql_relay_log_pos,
TRX_SYS_MYSQL_RELAY_LOG_INFO, &mtr);
trx_sys_update_mysql_binlog_offset(
+ sys_header,
trx->mysql_master_log_file_name,
trx->mysql_master_log_pos,
TRX_SYS_MYSQL_MASTER_LOG_INFO, &mtr);
@@ -907,6 +921,7 @@ trx_commit_off_kernel(
trx->read_view = NULL;
if (lsn) {
+ ulint flush_log_at_trx_commit;
mutex_exit(&kernel_mutex);
@@ -915,6 +930,12 @@ trx_commit_off_kernel(
trx_undo_insert_cleanup(trx);
}
+ if (trx->flush_log_at_trx_commit_session == 3) {
+ flush_log_at_trx_commit = srv_flush_log_at_trx_commit;
+ } else {
+ flush_log_at_trx_commit = trx->flush_log_at_trx_commit_session;
+ }
+
/* NOTE that we could possibly make a group commit more
efficient here: call os_thread_yield here to allow also other
trxs to come to commit! */
@@ -946,9 +967,9 @@ trx_commit_off_kernel(
if (trx->flush_log_later) {
/* Do nothing yet */
trx->must_flush_log_later = TRUE;
- } else if (srv_flush_log_at_trx_commit == 0) {
+ } else if (flush_log_at_trx_commit == 0) {
/* Do nothing */
- } else if (srv_flush_log_at_trx_commit == 1) {
+ } else if (flush_log_at_trx_commit == 1) {
if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
/* Write the log but do not flush it to disk */
@@ -960,7 +981,7 @@ trx_commit_off_kernel(
log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
}
- } else if (srv_flush_log_at_trx_commit == 2) {
+ } else if (flush_log_at_trx_commit == 2) {
/* Write the log but do not flush it to disk */
@@ -983,7 +1004,6 @@ trx_commit_off_kernel(
trx->rseg = NULL;
trx->undo_no = ut_dulint_zero;
trx->last_sql_stat_start.least_undo_no = ut_dulint_zero;
- trx->mysql_query_str = NULL;
ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0);
ut_ad(UT_LIST_GET_LEN(trx->trx_locks) == 0);
@@ -1641,16 +1661,23 @@ trx_commit_complete_for_mysql(
trx_t* trx) /*!< in: trx handle */
{
ib_uint64_t lsn = trx->commit_lsn;
+ ulint flush_log_at_trx_commit;
ut_a(trx);
trx->op_info = "flushing log";
+ if (trx->flush_log_at_trx_commit_session == 3) {
+ flush_log_at_trx_commit = srv_flush_log_at_trx_commit;
+ } else {
+ flush_log_at_trx_commit = trx->flush_log_at_trx_commit_session;
+ }
+
if (!trx->must_flush_log_later) {
/* Do nothing */
- } else if (srv_flush_log_at_trx_commit == 0) {
+ } else if (flush_log_at_trx_commit == 0) {
/* Do nothing */
- } else if (srv_flush_log_at_trx_commit == 1) {
+ } else if (flush_log_at_trx_commit == 1) {
if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
/* Write the log but do not flush it to disk */
@@ -1661,7 +1688,7 @@ trx_commit_complete_for_mysql(
log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
}
- } else if (srv_flush_log_at_trx_commit == 2) {
+ } else if (flush_log_at_trx_commit == 2) {
/* Write the log but do not flush it to disk */
@@ -1922,6 +1949,8 @@ trx_prepare_off_kernel(
/*--------------------------------------*/
if (lsn) {
+ ulint flush_log_at_trx_commit;
+
/* Depending on the my.cnf options, we may now write the log
buffer to the log files, making the prepared state of the
transaction durable if the OS does not crash. We may also
@@ -1941,9 +1970,15 @@ trx_prepare_off_kernel(
mutex_exit(&kernel_mutex);
- if (srv_flush_log_at_trx_commit == 0) {
+ if (trx->flush_log_at_trx_commit_session == 3) {
+ flush_log_at_trx_commit = srv_flush_log_at_trx_commit;
+ } else {
+ flush_log_at_trx_commit = trx->flush_log_at_trx_commit_session;
+ }
+
+ if (flush_log_at_trx_commit == 0) {
/* Do nothing */
- } else if (srv_flush_log_at_trx_commit == 1) {
+ } else if (flush_log_at_trx_commit == 1) {
if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
/* Write the log but do not flush it to disk */
@@ -1955,7 +1990,7 @@ trx_prepare_off_kernel(
log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
}
- } else if (srv_flush_log_at_trx_commit == 2) {
+ } else if (flush_log_at_trx_commit == 2) {
/* Write the log but do not flush it to disk */
diff --git a/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c b/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c
deleted file mode 100644
index 30de5aa6f17..00000000000
--- a/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/*****************************************************************************
-If this program compiles, then pthread_t objects can be used as arguments
-to GCC atomic builtin functions.
-
-Created March 5, 2009 Vasil Dimov
-*****************************************************************************/
-
-#include <pthread.h>
-#include <string.h>
-
-int
-main(int argc, char** argv)
-{
- pthread_t x1;
- pthread_t x2;
- pthread_t x3;
-
- memset(&x1, 0x0, sizeof(x1));
- memset(&x2, 0x0, sizeof(x2));
- memset(&x3, 0x0, sizeof(x3));
-
- __sync_bool_compare_and_swap(&x1, x2, x3);
-
- return(0);
-}
diff --git a/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c b/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c
deleted file mode 100644
index 310603c7503..00000000000
--- a/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/*****************************************************************************
-If this program compiles and returns 0, then pthread_t objects can be used as
-arguments to Solaris libc atomic functions.
-
-Created April 18, 2009 Vasil Dimov
-*****************************************************************************/
-
-#include <pthread.h>
-#include <string.h>
-
-int
-main(int argc, char** argv)
-{
- pthread_t x1;
- pthread_t x2;
- pthread_t x3;
-
- memset(&x1, 0x0, sizeof(x1));
- memset(&x2, 0x0, sizeof(x2));
- memset(&x3, 0x0, sizeof(x3));
-
- if (sizeof(pthread_t) == 4) {
-
- atomic_cas_32(&x1, x2, x3);
-
- } else if (sizeof(pthread_t) == 8) {
-
- atomic_cas_64(&x1, x2, x3);
-
- } else {
-
- return(1);
- }
-
- return(0);
-}
diff --git a/storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c b/storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c
deleted file mode 100644
index da5c13d7d79..00000000000
--- a/storage/xtradb/ut/ut0auxconf_have_gcc_atomics.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/*****************************************************************************
-If this program compiles and returns 0, then GCC atomic funcions are available.
-
-Created September 12, 2009 Vasil Dimov
-*****************************************************************************/
-
-int
-main(int argc, char** argv)
-{
- long x;
- long y;
- long res;
- char c;
-
- x = 10;
- y = 123;
- res = __sync_bool_compare_and_swap(&x, x, y);
- if (!res || x != y) {
- return(1);
- }
-
- x = 10;
- y = 123;
- res = __sync_bool_compare_and_swap(&x, x + 1, y);
- if (res || x != 10) {
- return(1);
- }
-
- x = 10;
- y = 123;
- res = __sync_add_and_fetch(&x, y);
- if (res != 123 + 10 || x != 123 + 10) {
- return(1);
- }
-
- c = 10;
- res = __sync_lock_test_and_set(&c, 123);
- if (res != 10 || c != 123) {
- return(1);
- }
-
- return(0);
-}
diff --git a/storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c b/storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c
deleted file mode 100644
index 7eb704edd4b..00000000000
--- a/storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/*****************************************************************************
-If this program compiles, then Solaris libc atomic funcions are available.
-
-Created April 18, 2009 Vasil Dimov
-*****************************************************************************/
-#include <atomic.h>
-
-int
-main(int argc, char** argv)
-{
- ulong_t ulong = 0;
- uint32_t uint32 = 0;
- uint64_t uint64 = 0;
-
- atomic_cas_ulong(&ulong, 0, 1);
- atomic_cas_32(&uint32, 0, 1);
- atomic_cas_64(&uint64, 0, 1);
- atomic_add_long(&ulong, 0);
-
- return(0);
-}
diff --git a/storage/xtradb/ut/ut0auxconf_pause.c b/storage/xtradb/ut/ut0auxconf_pause.c
deleted file mode 100644
index 54d63bdd9bc..00000000000
--- a/storage/xtradb/ut/ut0auxconf_pause.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/*****************************************************************************
-If this program compiles and can be run and returns 0, then the pause
-instruction is available.
-
-Created Jul 21, 2009 Vasil Dimov
-*****************************************************************************/
-
-int
-main(int argc, char** argv)
-{
- __asm__ __volatile__ ("pause");
-
- return(0);
-}
diff --git a/storage/xtradb/ut/ut0auxconf_sizeof_pthread_t.c b/storage/xtradb/ut/ut0auxconf_sizeof_pthread_t.c
deleted file mode 100644
index 96add4526ef..00000000000
--- a/storage/xtradb/ut/ut0auxconf_sizeof_pthread_t.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2009, Innobase Oy. All Rights Reserved.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
-
-*****************************************************************************/
-
-/*****************************************************************************
-This program should compile and when run, print a single line like:
-#define SIZEOF_PTHREAD_T %d
-
-Created April 18, 2009 Vasil Dimov
-*****************************************************************************/
-
-#include <stdio.h>
-#include <pthread.h>
-
-int
-main(int argc, char** argv)
-{
- printf("#define SIZEOF_PTHREAD_T %d\n", (int) sizeof(pthread_t));
-
- return(0);
-}
diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt
index 339fe7854c7..ec9e9a3a3af 100755
--- a/strings/CMakeLists.txt
+++ b/strings/CMakeLists.txt
@@ -18,7 +18,7 @@ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUT
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
-SET(STRINGS_SOURCES bchange.c bcmp.c bfill.c bmove512.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c
+SET(STRINGS_SOURCES bchange.c bfill.c bmove512.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c
ctype-czech.c ctype-euc_kr.c ctype-eucjpms.c ctype-extra.c ctype-gb2312.c ctype-gbk.c
ctype-latin1.c ctype-mb.c ctype-simple.c ctype-sjis.c ctype-tis620.c ctype-uca.c
ctype-ucs2.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype.c decimal.c int2str.c
diff --git a/strings/Makefile.am b/strings/Makefile.am
index 94e24045d03..9b0c1a33250 100644
--- a/strings/Makefile.am
+++ b/strings/Makefile.am
@@ -79,7 +79,3 @@ test_decimal$(EXEEXT): decimal.c $(pkglib_LIBRARIES)
$(CP) $(srcdir)/decimal.c ./test_decimal.c
$(LINK) $(FLAGS) -DMAIN ./test_decimal.c $(LDADD) $(pkglib_LIBRARIES)
$(RM) -f ./test_decimal.c
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
-
diff --git a/strings/bzero.c b/strings/bzero.c
index b720de65eed..59c7a19385e 100644
--- a/strings/bzero.c
+++ b/strings/bzero.c
@@ -35,10 +35,10 @@
#if VaxAsm
-static void _bzero64 _A((char *dst,int len));
+static void _bzero64 _A((void *dst,int len));
void bzero(dst, len)
-char *dst;
+void *dst;
uint len;
{
while ((int) len >= 64*K)
@@ -51,7 +51,7 @@ uint len;
}
_bzero64(dst, len)
-char *dst;
+void *dst;
int len;
{
asm("movc5 $0,*4(ap),$0,8(ap),*4(ap)");
@@ -62,7 +62,7 @@ int len;
#if defined(MC68000) && defined(DS90)
void bzero(dst, len)
-char *dst;
+void *dst;
uint len;
{
bfill(dst,len,0); /* This is very optimized ! */
@@ -71,7 +71,7 @@ uint len;
#else
void bzero(dst, len)
-register char *dst;
+register void *dst;
register uint len;
{
while (len-- != 0) *dst++ = 0;
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index 4c29886d307..c9450973866 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -377,86 +377,6 @@ static int my_strxfrm_big5(uchar *dest, const uchar *src, int len)
#endif
-/*
-** Calculate min_str and max_str that ranges a LIKE string.
-** Arguments:
-** ptr Pointer to LIKE string.
-** ptr_length Length of LIKE string.
-** escape Escape character in LIKE. (Normally '\').
-** All escape characters should be removed from min_str and max_str
-** res_length Length of min_str and max_str.
-** min_str Smallest case sensitive string that ranges LIKE.
-** Should be space padded to res_length.
-** max_str Largest case sensitive string that ranges LIKE.
-** Normally padded with the biggest character sort value.
-**
-** The function should return 0 if ok and 1 if the LIKE string can't be
-** optimized !
-*/
-
-#define max_sort_char ((char) 255)
-
-static my_bool my_like_range_big5(CHARSET_INFO *cs __attribute__((unused)),
- const char *ptr,size_t ptr_length,
- pbool escape, pbool w_one, pbool w_many,
- size_t res_length,
- char *min_str, char *max_str,
- size_t *min_length, size_t *max_length)
-{
- const char *end= ptr + ptr_length;
- char *min_org=min_str;
- char *min_end=min_str+res_length;
- size_t charlen= res_length / cs->mbmaxlen;
-
- for (; ptr != end && min_str != min_end && charlen > 0; ptr++, charlen--)
- {
- if (ptr+1 != end && isbig5code(ptr[0],ptr[1]))
- {
- *min_str++= *max_str++ = *ptr++;
- *min_str++= *max_str++ = *ptr;
- continue;
- }
- if (*ptr == escape && ptr+1 != end)
- {
- ptr++; /* Skip escape */
- if (isbig5code(ptr[0], ptr[1]))
- *min_str++= *max_str++ = *ptr++;
- if (min_str < min_end)
- *min_str++= *max_str++= *ptr;
- continue;
- }
- if (*ptr == w_one) /* '_' in SQL */
- {
- *min_str++='\0'; /* This should be min char */
- *max_str++=max_sort_char;
- continue;
- }
- if (*ptr == w_many) /* '%' in SQL */
- {
- /*
- Calculate length of keys:
- 'a\0\0... is the smallest possible string when we have space expand
- a\ff\ff... is the biggest possible string
- */
- *min_length= ((cs->state & MY_CS_BINSORT) ? (size_t) (min_str - min_org) :
- res_length);
- *max_length= res_length;
- do {
- *min_str++ = 0;
- *max_str++ = max_sort_char;
- } while (min_str != min_end);
- return 0;
- }
- *min_str++= *max_str++ = *ptr;
- }
-
- *min_length= *max_length= (size_t) (min_str-min_org);
- while (min_str != min_end)
- *min_str++= *max_str++= ' ';
- return 0;
-}
-
-
static uint ismbchar_big5(CHARSET_INFO *cs __attribute__((unused)),
const char* p, const char *e)
{
@@ -6338,7 +6258,7 @@ static MY_COLLATION_HANDLER my_collation_big5_chinese_ci_handler =
my_strnncollsp_big5,
my_strnxfrm_big5,
my_strnxfrmlen_simple,
- my_like_range_big5,
+ my_like_range_mb,
my_wildcmp_mb,
my_strcasecmp_mb,
my_instr_mb,
@@ -6402,7 +6322,7 @@ struct charset_info_st my_charset_big5_chinese_ci=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xF9D5, /* max_sort_char */
' ', /* pad char */
1, /* escape_with_backslash_is_dangerous */
&my_charset_big5_handler,
@@ -6435,7 +6355,7 @@ struct charset_info_st my_charset_big5_bin=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xF9FE, /* max_sort_char */
' ', /* pad char */
1, /* escape_with_backslash_is_dangerous */
&my_charset_big5_handler,
diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c
index 2caffe7aea2..4453516c7b3 100644
--- a/strings/ctype-cp932.c
+++ b/strings/ctype-cp932.c
@@ -306,76 +306,6 @@ static size_t my_strnxfrm_cp932(CHARSET_INFO *cs __attribute__((unused)),
}
-/*
-** Calculate min_str and max_str that ranges a LIKE string.
-** Arguments:
-** ptr Pointer to LIKE string.
-** ptr_length Length of LIKE string.
-** escape Escape character in LIKE. (Normally '\').
-** All escape characters should be removed from min_str and max_str
-** res_length Length of min_str and max_str.
-** min_str Smallest case sensitive string that ranges LIKE.
-** Should be space padded to res_length.
-** max_str Largest case sensitive string that ranges LIKE.
-** Normally padded with the biggest character sort value.
-**
-** The function should return 0 if ok and 1 if the LIKE string can't be
-** optimized !
-*/
-
-#define max_sort_char ((char) 255)
-
-static my_bool my_like_range_cp932(CHARSET_INFO *cs __attribute__((unused)),
- const char *ptr,size_t ptr_length,
- pbool escape, pbool w_one, pbool w_many,
- size_t res_length,
- char *min_str,char *max_str,
- size_t *min_length, size_t *max_length)
-{
- const char *end=ptr+ptr_length;
- char *min_org=min_str;
- char *min_end=min_str+res_length;
-
- while (ptr < end && min_str < min_end) {
- if (ismbchar_cp932(cs, ptr, end)) {
- *min_str++ = *max_str++ = *ptr++;
- if (min_str < min_end)
- *min_str++ = *max_str++ = *ptr++;
- continue;
- }
- if (*ptr == escape && ptr+1 < end) {
- ptr++; /* Skip escape */
- if (ismbchar_cp932(cs, ptr, end))
- *min_str++ = *max_str++ = *ptr++;
- if (min_str < min_end)
- *min_str++ = *max_str++ = *ptr++;
- continue;
- }
- if (*ptr == w_one) { /* '_' in SQL */
- *min_str++ = '\0'; /* This should be min char */
- *max_str++ = max_sort_char;
- ptr++;
- continue;
- }
- if (*ptr == w_many)
- { /* '%' in SQL */
- *min_length = (size_t)(min_str - min_org);
- *max_length = res_length;
- do
- {
- *min_str++= 0;
- *max_str++= max_sort_char;
- } while (min_str < min_end);
- return 0;
- }
- *min_str++ = *max_str++ = *ptr++;
- }
- *min_length = *max_length = (size_t) (min_str - min_org);
- while (min_str < min_end)
- *min_str++ = *max_str++ = ' '; /* Because if key compression */
- return 0;
-}
-
/* page 0 0x00A1-0x00DF */
static const uint16 tab_cp932_uni0[]={
0xFF61,0xFF62,0xFF63,0xFF64,0xFF65,0xFF66,0xFF67,0xFF68,
@@ -5467,7 +5397,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
my_strnncollsp_cp932,
my_strnxfrm_cp932,
my_strnxfrmlen_simple,
- my_like_range_cp932,
+ my_like_range_mb,
my_wildcmp_mb, /* wildcmp */
my_strcasecmp_8bit,
my_instr_mb,
@@ -5533,7 +5463,7 @@ struct charset_info_st my_charset_cp932_japanese_ci=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFCFC, /* max_sort_char */
' ', /* pad char */
1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
@@ -5565,7 +5495,7 @@ struct charset_info_st my_charset_cp932_bin=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFCFC, /* max_sort_char */
' ', /* pad char */
1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c
index a5d5c1ee6ea..c16793a9539 100644
--- a/strings/ctype-euc_kr.c
+++ b/strings/ctype-euc_kr.c
@@ -8762,7 +8762,7 @@ struct charset_info_st my_charset_euckr_korean_ci=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFEFE, /* max_sort_char */
' ', /* pad char */
0, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
@@ -8795,7 +8795,7 @@ struct charset_info_st my_charset_euckr_bin=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFEFE, /* max_sort_char */
' ', /* pad char */
0, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c
index 119135c7515..d954c618ed4 100644
--- a/strings/ctype-eucjpms.c
+++ b/strings/ctype-eucjpms.c
@@ -8710,7 +8710,7 @@ struct charset_info_st my_charset_eucjpms_japanese_ci=
1, /* mbminlen */
3, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFEFE, /* max_sort_char */
' ', /* pad_char */
0, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
@@ -8743,7 +8743,7 @@ struct charset_info_st my_charset_eucjpms_bin=
1, /* mbminlen */
3, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFEFE, /* max_sort_char */
' ', /* pad_char */
0, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c
index 641fe2ea24e..37d0e44a4c6 100644
--- a/strings/ctype-gb2312.c
+++ b/strings/ctype-gb2312.c
@@ -5790,7 +5790,7 @@ struct charset_info_st my_charset_gb2312_chinese_ci=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xF7FE, /* max_sort_char */
' ', /* pad char */
0, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
@@ -5822,7 +5822,7 @@ struct charset_info_st my_charset_gb2312_bin=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xF7FE, /* max_sort_char */
' ', /* pad char */
0, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index 46b711d92be..bb9426a4b08 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -2689,86 +2689,6 @@ static size_t my_strnxfrm_gbk(CHARSET_INFO *cs __attribute__((unused)),
}
-/*
-** Calculate min_str and max_str that ranges a LIKE string.
-** Arguments:
-** ptr Pointer to LIKE string.
-** ptr_length Length of LIKE string.
-** escape Escape character in LIKE. (Normally '\').
-** All escape characters should be removed from min_str and max_str
-** res_length Length of min_str and max_str.
-** min_str Smallest case sensitive string that ranges LIKE.
-** Should be space padded to res_length.
-** max_str Largest case sensitive string that ranges LIKE.
-** Normally padded with the biggest character sort value.
-**
-** The function should return 0 if ok and 1 if the LIKE string can't be
-** optimized !
-*/
-
-#define max_sort_char ((uchar) 255)
-
-static my_bool my_like_range_gbk(CHARSET_INFO *cs __attribute__((unused)),
- const char *ptr,size_t ptr_length,
- pbool escape, pbool w_one, pbool w_many,
- size_t res_length,
- char *min_str,char *max_str,
- size_t *min_length,size_t *max_length)
-{
- const char *end= ptr + ptr_length;
- char *min_org=min_str;
- char *min_end=min_str+res_length;
- size_t charlen= res_length / cs->mbmaxlen;
-
- for (; ptr != end && min_str != min_end && charlen > 0; ptr++, charlen--)
- {
- if (ptr+1 != end && isgbkcode(ptr[0],ptr[1]))
- {
- *min_str++= *max_str++ = *ptr++;
- *min_str++= *max_str++ = *ptr;
- continue;
- }
- if (*ptr == escape && ptr+1 != end)
- {
- ptr++; /* Skip escape */
- if (isgbkcode(ptr[0], ptr[1]))
- *min_str++= *max_str++ = *ptr;
- if (min_str < min_end)
- *min_str++= *max_str++= *ptr;
- continue;
- }
- if (*ptr == w_one) /* '_' in SQL */
- {
- *min_str++='\0'; /* This should be min char */
- *max_str++=max_sort_char;
- continue;
- }
- if (*ptr == w_many) /* '%' in SQL */
- {
- /*
- Calculate length of keys:
- 'a\0\0... is the smallest possible string when we have space expand
- a\ff\ff... is the biggest possible string
- */
- *min_length= ((cs->state & MY_CS_BINSORT) ? (size_t) (min_str - min_org) :
- res_length);
- *max_length= res_length;
- do {
- *min_str++= 0;
- *max_str++= max_sort_char;
- } while (min_str != min_end);
- return 0;
- }
- *min_str++= *max_str++ = *ptr;
- }
-
- *min_length= *max_length = (size_t) (min_str - min_org);
- while (min_str != min_end)
- *min_str++= *max_str++= ' '; /* Because if key compression */
- return 0;
-}
-
-
static uint ismbchar_gbk(CHARSET_INFO *cs __attribute__((unused)),
const char* p, const char *e)
{
@@ -9982,7 +9902,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
my_strnncollsp_gbk,
my_strnxfrm_gbk,
my_strnxfrmlen_simple,
- my_like_range_gbk,
+ my_like_range_mb,
my_wildcmp_mb,
my_strcasecmp_mb,
my_instr_mb,
@@ -10047,7 +9967,7 @@ struct charset_info_st my_charset_gbk_chinese_ci=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xA967, /* max_sort_char */
' ', /* pad char */
1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
@@ -10079,7 +9999,7 @@ struct charset_info_st my_charset_gbk_bin=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFEFE, /* max_sort_char */
' ', /* pad char */
1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index 6bb7977c294..ad9edf18bbe 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -498,7 +498,9 @@ static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
DESCRIPTION
Write max key:
- for non-Unicode character sets:
- just set to 255.
+ just bfill using max_sort_char if max_sort_char is one byte.
+ In case when max_sort_char is two bytes, fill with double-byte pairs
+ and optionally pad with a single space character.
- for Unicode character set (utf-8):
create a buffer with multibyte representation of the max_sort_char
character, and copy it into max_str in a loop.
@@ -510,12 +512,20 @@ static void pad_max_char(CHARSET_INFO *cs, char *str, char *end)
if (!(cs->state & MY_CS_UNICODE))
{
- bfill(str, end - str, 255);
- return;
+ if (cs->max_sort_char <= 255)
+ {
+ bfill(str, end - str, cs->max_sort_char);
+ return;
+ }
+ buf[0]= cs->max_sort_char >> 8;
+ buf[1]= cs->max_sort_char & 0xFF;
+ buflen= 2;
+ }
+ else
+ {
+ buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf,
+ (uchar*) buf + sizeof(buf));
}
-
- buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf,
- (uchar*) buf + sizeof(buf));
DBUG_ASSERT(buflen > 0);
do
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index 81d1c57412d..a79eff70683 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -304,85 +304,6 @@ static size_t my_strnxfrm_sjis(CHARSET_INFO *cs __attribute__((unused)),
}
-/*
-** Calculate min_str and max_str that ranges a LIKE string.
-** Arguments:
-** ptr Pointer to LIKE string.
-** ptr_length Length of LIKE string.
-** escape Escape character in LIKE. (Normally '\').
-** All escape characters should be removed from min_str and max_str
-** res_length Length of min_str and max_str.
-** min_str Smallest case sensitive string that ranges LIKE.
-** Should be space padded to res_length.
-** max_str Largest case sensitive string that ranges LIKE.
-** Normally padded with the biggest character sort value.
-**
-** The function should return 0 if ok and 1 if the LIKE string can't be
-** optimized !
-*/
-
-#define max_sort_char ((char) 255)
-
-static my_bool my_like_range_sjis(CHARSET_INFO *cs __attribute__((unused)),
- const char *ptr,size_t ptr_length,
- pbool escape, pbool w_one, pbool w_many,
- size_t res_length,
- char *min_str,char *max_str,
- size_t *min_length,size_t *max_length)
-{
- const char *end= ptr + ptr_length;
- char *min_org=min_str;
- char *min_end=min_str+res_length;
- size_t charlen= res_length / cs->mbmaxlen;
-
- for ( ; ptr < end && min_str < min_end && charlen > 0 ; charlen--)
- {
- if (ismbchar_sjis(cs, ptr, end)) {
- *min_str++ = *max_str++ = *ptr++;
- if (min_str < min_end)
- *min_str++ = *max_str++ = *ptr++;
- continue;
- }
- if (*ptr == escape && ptr+1 < end) {
- ptr++; /* Skip escape */
- if (ismbchar_sjis(cs, ptr, end))
- *min_str++ = *max_str++ = *ptr++;
- if (min_str < min_end)
- *min_str++ = *max_str++ = *ptr++;
- continue;
- }
- if (*ptr == w_one) { /* '_' in SQL */
- *min_str++ = '\0'; /* This should be min char */
- *max_str++ = max_sort_char;
- ptr++;
- continue;
- }
- if (*ptr == w_many)
- { /* '%' in SQL */
- /*
- Calculate length of keys:
- 'a\0\0... is the smallest possible string when we have space expand
- a\ff\ff... is the biggest possible string
- */
- *min_length= ((cs->state & MY_CS_BINSORT) ? (size_t) (min_str - min_org) :
- res_length);
- *max_length= res_length;
- do
- {
- *min_str++= 0;
- *max_str++= max_sort_char;
- } while (min_str < min_end);
- return 0;
- }
- *min_str++ = *max_str++ = *ptr++;
- }
-
- *min_length= *max_length= (size_t) (min_str - min_org);
- while (min_str != min_end)
- *min_str++= *max_str++= ' '; /* Because if key compression */
- return 0;
-}
-
/* page 0 0x00A1-0x00DF */
static const uint16 tab_sjis_uni0[]={
0xFF61,0xFF62,0xFF63,0xFF64,0xFF65,0xFF66,0xFF67,0xFF68,
@@ -4628,7 +4549,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
my_strnncollsp_sjis,
my_strnxfrm_sjis,
my_strnxfrmlen_simple,
- my_like_range_sjis,
+ my_like_range_mb,
my_wildcmp_mb, /* wildcmp */
my_strcasecmp_8bit,
my_instr_mb,
@@ -4694,7 +4615,7 @@ struct charset_info_st my_charset_sjis_japanese_ci=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFCFC, /* max_sort_char */
' ', /* pad char */
1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
@@ -4726,7 +4647,7 @@ struct charset_info_st my_charset_sjis_bin=
1, /* mbminlen */
2, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFCFC, /* max_sort_char */
' ', /* pad char */
1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 7f170ca3b40..932f58d142f 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -7006,7 +7006,7 @@ static my_uca_scanner_handler my_ucs2_uca_scanner_handler=
my_uca_scanner_next_ucs2
};
-#endif
+#endif /* HAVE_CHARSET_ucs2 */
/*
@@ -8836,7 +8836,7 @@ struct charset_info_st my_charset_ucs2_croatian_uca_ci=
};
-#endif
+#endif /* HAVE_CHARSET_ucs2 */
#ifdef HAVE_CHARSET_utf8
diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c
index 3adee2cff07..4ee26acdc4c 100644
--- a/strings/ctype-ujis.c
+++ b/strings/ctype-ujis.c
@@ -8567,7 +8567,7 @@ struct charset_info_st my_charset_ujis_japanese_ci=
1, /* mbminlen */
3, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFEFE, /* max_sort_char */
' ', /* pad char */
0, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
@@ -8600,7 +8600,7 @@ struct charset_info_st my_charset_ujis_bin=
1, /* mbminlen */
3, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFEFE, /* max_sort_char */
' ', /* pad char */
0, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
diff --git a/strings/decimal.c b/strings/decimal.c
index 631750cf219..236b62b9296 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1934,8 +1934,7 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
int decimal_intg(decimal_t *from)
{
int res;
- dec1 *tmp_res;
- tmp_res= remove_leading_zeroes(from, &res);
+ remove_leading_zeroes(from, &res);
return res;
}
diff --git a/strings/make-ccc b/strings/make-ccc
index 78d5ad1ce42..93be2bbf862 100755
--- a/strings/make-ccc
+++ b/strings/make-ccc
@@ -1,3 +1,3 @@
-ccc -DHAVE_CONFIG_H -I. -I. -I.. -I./../include -I../include -O -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c atof.c bchange.c bcmp.c bfill.c bmove.c bmove512.c bmove_upp.c ct_init.c ctype-latin1.c int2str.c is_prefix.c llstr.c longlong2str.c r_strinstr.c str2int.c strappend.c strcend.c strcont.c strend.c strfill.c strinstr.c strmake.c strmov.c strnmov.c strstr.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c
+ccc -DHAVE_CONFIG_H -I. -I. -I.. -I./../include -I../include -O -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c atof.c bchange.c bfill.c bmove.c bmove512.c bmove_upp.c ct_init.c ctype-latin1.c int2str.c is_prefix.c llstr.c longlong2str.c r_strinstr.c str2int.c strappend.c strcend.c strcont.c strend.c strfill.c strinstr.c strmake.c strmov.c strnmov.c strstr.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c
rm libmystrings.a
ar -cr libmystrings.a atof.o
diff --git a/strings/strxmov.c b/strings/strxmov.c
index 9dd2c936620..d5d81fd9274 100644
--- a/strings/strxmov.c
+++ b/strings/strxmov.c
@@ -32,7 +32,6 @@
#include <my_global.h>
#include "m_string.h"
-#include <stdarg.h>
char *strxmov(char *dst,const char *src, ...)
{
diff --git a/strings/xml.c b/strings/xml.c
index 1b697ec6b26..14da69e088a 100644
--- a/strings/xml.c
+++ b/strings/xml.c
@@ -123,16 +123,16 @@ static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a)
a->beg=p->cur;
a->end=p->cur;
- if ((p->end - p->cur > 3) && !bcmp(p->cur,"<!--",4))
+ if ((p->end - p->cur > 3) && !bcmp((uchar*) p->cur, (uchar*) "<!--",4))
{
- for (; (p->cur < p->end) && bcmp(p->cur, "-->", 3); p->cur++)
+ for (; (p->cur < p->end) && bcmp((uchar*) p->cur, (uchar*) "-->", 3); p->cur++)
{}
- if (!bcmp(p->cur, "-->", 3))
+ if (!bcmp((uchar*) p->cur, (uchar*) "-->", 3))
p->cur+=3;
a->end=p->cur;
lex=MY_XML_COMMENT;
}
- else if (!bcmp(p->cur, "<![CDATA[",9))
+ else if (!bcmp((uchar*) p->cur, (uchar*) "<![CDATA[",9))
{
p->cur+= 9;
for (; p->cur < p->end - 2 ; p->cur++)
diff --git a/support-files/Makefile.am b/support-files/Makefile.am
index be6b9cc0dcb..f6500e82be0 100644
--- a/support-files/Makefile.am
+++ b/support-files/Makefile.am
@@ -129,6 +129,3 @@ SUFFIXES = .sh
-e 's!@''PERL_DATA_DUMPER''@!@PERL_DATA_DUMPER@!' \
$< > $@-t
@MV@ $@-t $@
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/support-files/compiler_warnings.supp b/support-files/compiler_warnings.supp
index 41ebf1bcf8a..a56c39b51a0 100644
--- a/support-files/compiler_warnings.supp
+++ b/support-files/compiler_warnings.supp
@@ -24,7 +24,9 @@ sql_yacc.cc : .*switch statement contains 'default' but no 'case' labels.*
# Things that can be ignored in InnoDB
#
pars0grm.tab.c: .*'yyerrorlab' : unreferenced label.*
+pars0grm.c: 'yyerrorlab' : unreferenced label
_flex_tmp.c: .*not enough actual parameters for macro 'yywrap'.*
+lexyy.c : not enough actual parameters for macro 'yywrap'
pars0lex.l: .*conversion from 'ulint' to 'int', possible loss of data.*
btr/btr0cur\.c: .*value computed is not used.*: 3175-3375
include/buf0buf\.ic: unused parameter .*mtr.*
@@ -44,7 +46,7 @@ buf/buf0buf\.c: .*block_mutex.* might be used uninitialized
btr/btr0cur\.c: null argument where non-null required: 1800-3000
btr/btr0btr\.c: null argument where non-null required: 2500-3000
ibuf/ibuf0ibuf.c: null argument where non-null required: 700-1000
-fsp/fsp0fsp\.c: result of 32-bit shift implicitly converted to 64 bits
+fsp0fsp\.c: result of 32-bit shift implicitly converted to 64 bits
#
# bdb is not critical to keep up to date
@@ -110,6 +112,11 @@ signal\.c : .*unused parameter.*
.* : conversion from '.*size_t' to 'uInt'.*
.* : conversion from '.*size_t' to 'uint16'.*
.* : The following environment variables were not found.*
+.* : no public symbols found; archive member will be inaccessible
+.* : DESCRIPTION statement not supported
+
+# Ignore uninitialized local variables on windows
+.* : uninitialized local variable .* used
#
# The following should be fixed by the ndb team
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ddc6da86e1c..ca4a2a4e986 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -60,6 +60,3 @@ DEFS = -DMYSQL_CLIENT_NO_THREADS
thread_test.o: thread_test.c
$(COMPILE) -c $(INCLUDES) $<
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 5c75dd0a30d..789ba236a87 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -3326,7 +3326,7 @@ static void test_long_data_str()
DIE_UNLESS(rc == 1);
mysql_free_result(result);
- my_sprintf(data, (data, "%d", i*5));
+ sprintf(data, "%d", i*5);
verify_col_data("test_long_data_str", "LENGTH(longstr)", data);
data[0]= '\0';
while (i--)
@@ -3424,10 +3424,10 @@ static void test_long_data_str1()
DIE_UNLESS(rc == 1);
mysql_free_result(result);
- my_sprintf(data, (data, "%ld", (long)i*length));
+ sprintf(data, "%ld", (long)i*length);
verify_col_data("test_long_data_str", "length(longstr)", data);
- my_sprintf(data, (data, "%d", i*2));
+ sprintf(data, "%d", i*2);
verify_col_data("test_long_data_str", "length(blb)", data);
/* Test length of field->max_length */
@@ -13287,37 +13287,52 @@ static void test_bug15518()
}
-static void disable_general_log()
+static void disable_query_logs()
{
int rc;
rc= mysql_query(mysql, "set @@global.general_log=off");
myquery(rc);
+ rc= mysql_query(mysql, "set @@global.slow_query_log=off");
+ myquery(rc);
}
-static void enable_general_log(int truncate)
+static void enable_query_logs(int truncate)
{
int rc;
rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log");
myquery(rc);
+ rc= mysql_query(mysql, "set @save_global_slow_query_log=@@global.slow_query_log");
+ myquery(rc);
+
rc= mysql_query(mysql, "set @@global.general_log=on");
myquery(rc);
+ rc= mysql_query(mysql, "set @@global.slow_query_log=on");
+ myquery(rc);
+
+
if (truncate)
{
rc= mysql_query(mysql, "truncate mysql.general_log");
myquery(rc);
+
+ rc= mysql_query(mysql, "truncate mysql.slow_log");
+ myquery(rc);
}
}
-static void restore_general_log()
+static void restore_query_logs()
{
int rc;
rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log");
myquery(rc);
+
+ rc= mysql_query(mysql, "set @@global.slow_query_log=@save_global_slow_query_log");
+ myquery(rc);
}
@@ -15488,7 +15503,7 @@ static void test_bug17667()
return;
}
- enable_general_log(1);
+ enable_query_logs(1);
for (statement_cursor= statements; statement_cursor->buffer != NULL;
statement_cursor++)
@@ -15568,7 +15583,7 @@ static void test_bug17667()
statement_cursor->buffer);
}
- restore_general_log();
+ restore_query_logs();
if (!opt_silent)
printf("success. All queries found intact in the log.\n");
@@ -17432,7 +17447,7 @@ static void test_bug28386()
}
mysql_free_result(result);
- enable_general_log(1);
+ enable_query_logs(1);
stmt= mysql_simple_prepare(mysql, "SELECT ?");
check_stmt(stmt);
@@ -17471,7 +17486,7 @@ static void test_bug28386()
mysql_free_result(result);
- restore_general_log();
+ restore_query_logs();
DBUG_VOID_RETURN;
}
@@ -18140,7 +18155,7 @@ static void test_bug53371()
static void test_bug53907()
{
int rc;
- char buf[] = "\x4test\x14../client_test_db/t1";
+ uchar buf[] = "\x4test\x14../client_test_db/t1";
myheader("test_bug53907");
@@ -18160,7 +18175,7 @@ static void test_bug53907()
rc= mysql_change_user(mysql, "testbug", NULL, "bug53907");
myquery(rc);
- rc= simple_command(mysql, COM_TABLE_DUMP, (uchar*) buf, sizeof(buf), 0);
+ rc= simple_command(mysql, COM_TABLE_DUMP, buf, sizeof(buf), 0);
fprintf(stderr, ">>>>>>>>> %d\n", mysql_errno(mysql));
DIE_UNLESS(mysql_errno(mysql) == 1103); /* ER_WRONG_TABLE_NAME */
@@ -18259,7 +18274,7 @@ static void test_bug42373()
Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
*/
-static void test_bug54041()
+static void test_bug54041_impl()
{
int rc;
MYSQL_STMT *stmt;
@@ -18274,7 +18289,7 @@ static void test_bug54041()
rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
myquery(rc);
- stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (a) VALUES (?)");
+ stmt= mysql_simple_prepare(mysql, "SELECT a FROM t1 WHERE a > ?");
check_stmt(stmt);
verify_param_count(stmt, 1);
@@ -18312,6 +18327,20 @@ static void test_bug54041()
}
+/**
+ Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
+*/
+
+static void test_bug54041()
+{
+ enable_query_logs(0);
+ test_bug54041_impl();
+ disable_query_logs();
+ test_bug54041_impl();
+ restore_query_logs();
+}
+
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -18392,7 +18421,7 @@ and you are welcome to modify and redistribute it under the GPL license\n");
static struct my_tests_st my_tests[]= {
- { "disable_general_log", disable_general_log },
+ { "disable_query_logs", disable_query_logs },
{ "test_view_sp_list_fields", test_view_sp_list_fields },
{ "client_query", client_query },
{ "test_prepare_insert_update", test_prepare_insert_update},
diff --git a/unittest/Makefile.am b/unittest/Makefile.am
index f1c4f7bb7dd..01d27eb8cd2 100644
--- a/unittest/Makefile.am
+++ b/unittest/Makefile.am
@@ -13,18 +13,15 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-SUBDIRS = mytap mysys examples
+SUBDIRS = mytap . mysys examples strings
EXTRA_DIST = unit.pl
CLEANFILES = unit
-unittests = mytap mysys @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@ ../dbug
+unittests = mytap mysys strings @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@ ../dbug
test:
perl unit.pl run $(unittests)
test-verbose:
HARNESS_VERBOSE=1 perl unit.pl run $(unittests)
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/unittest/mysys/Makefile.am b/unittest/mysys/Makefile.am
index e9ec6210e20..3aa9e58b6ec 100644
--- a/unittest/mysys/Makefile.am
+++ b/unittest/mysys/Makefile.am
@@ -27,12 +27,5 @@ EXTRA_DIST = CMakeLists.txt
noinst_PROGRAMS = bitmap-t base64-t my_atomic-t lf-t waiting_threads-t \
my_vsnprintf-t
-if NEED_THREAD
-# my_atomic-t is used to check thread functions, so it is safe to
-# ignore the file in non-threaded builds.
-# In fact, it will not compile without thread support.
-noinst_PROGRAMS += my_atomic-t
-endif
-
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/unittest/strings/Makefile.am b/unittest/strings/Makefile.am
new file mode 100644
index 00000000000..5b18d89f58e
--- /dev/null
+++ b/unittest/strings/Makefile.am
@@ -0,0 +1,27 @@
+# Copyright 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include
+AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap
+
+LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
+ $(top_builddir)/mysys/libmysys.a \
+ $(top_builddir)/dbug/libdbug.a \
+ $(top_builddir)/strings/libmystrings.a
+
+noinst_PROGRAMS = strings-t
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/unittest/strings/strings-t.c b/unittest/strings/strings-t.c
new file mode 100644
index 00000000000..cb33af3ac03
--- /dev/null
+++ b/unittest/strings/strings-t.c
@@ -0,0 +1,116 @@
+/* Copyright 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include <tap.h>
+#include <my_global.h>
+#include <my_sys.h>
+
+
+/*
+ Test that like_range() returns well-formed results.
+*/
+static int
+test_like_range_for_charset(CHARSET_INFO *cs, const char *src, size_t src_len)
+{
+ char min_str[32], max_str[32];
+ size_t min_len, max_len, min_well_formed_len, max_well_formed_len;
+ int error= 0;
+
+ cs->coll->like_range(cs, src, src_len, '\\', '_', '%',
+ sizeof(min_str), min_str, max_str, &min_len, &max_len);
+ diag("min_len=%d\tmax_len=%d\t%s", (int) min_len, (int) max_len, cs->name);
+ min_well_formed_len= cs->cset->well_formed_len(cs,
+ min_str, min_str + min_len,
+ 10000, &error);
+ max_well_formed_len= cs->cset->well_formed_len(cs,
+ max_str, max_str + max_len,
+ 10000, &error);
+ if (min_len != min_well_formed_len)
+ diag("Bad min_str: min_well_formed_len=%d min_str[%d]=0x%02X",
+ (int) min_well_formed_len, (int) min_well_formed_len,
+ (uchar) min_str[min_well_formed_len]);
+ if (max_len != max_well_formed_len)
+ diag("Bad max_str: max_well_formed_len=%d max_str[%d]=0x%02X",
+ (int) max_well_formed_len, (int) max_well_formed_len,
+ (uchar) max_str[max_well_formed_len]);
+ return
+ min_len == min_well_formed_len &&
+ max_len == max_well_formed_len ? 0 : 1;
+}
+
+
+static CHARSET_INFO *charset_list[]=
+{
+#ifdef HAVE_CHARSET_big5
+ &my_charset_big5_chinese_ci,
+ &my_charset_big5_bin,
+#endif
+#ifdef HAVE_CHARSET_euckr
+ &my_charset_euckr_korean_ci,
+ &my_charset_euckr_bin,
+#endif
+#ifdef HAVE_CHARSET_gb2312
+ &my_charset_gb2312_chinese_ci,
+ &my_charset_gb2312_bin,
+#endif
+#ifdef HAVE_CHARSET_gbk
+ &my_charset_gbk_chinese_ci,
+ &my_charset_gbk_bin,
+#endif
+#ifdef HAVE_CHARSET_latin1
+ &my_charset_latin1,
+ &my_charset_latin1_bin,
+#endif
+#ifdef HAVE_CHARSET_sjis
+ &my_charset_sjis_japanese_ci,
+ &my_charset_sjis_bin,
+#endif
+#ifdef HAVE_CHARSET_tis620
+ &my_charset_tis620_thai_ci,
+ &my_charset_tis620_bin,
+#endif
+#ifdef HAVE_CHARSET_ujis
+ &my_charset_ujis_japanese_ci,
+ &my_charset_ujis_bin,
+#endif
+#ifdef HAVE_CHARSET_utf8
+ &my_charset_utf8_general_ci,
+#ifdef HAVE_HAVE_UCA_COLLATIONS
+ &my_charset_utf8_unicode_ci,
+#endif
+ &my_charset_utf8_bin,
+#endif
+};
+
+
+int main()
+{
+ size_t i, failed= 0;
+
+ plan(1);
+ diag("Testing my_like_range_xxx() functions");
+
+ for (i= 0; i < array_elements(charset_list); i++)
+ {
+ CHARSET_INFO *cs= charset_list[i];
+ if (test_like_range_for_charset(cs, "abc%", 4))
+ {
+ ++failed;
+ diag("Failed for %s", cs->name);
+ }
+ }
+ ok(failed == 0, "Testing my_like_range_xxx() functions");
+ return exit_status();
+}
diff --git a/vio/Makefile.am b/vio/Makefile.am
index 27596bb2fa4..c70af1008cd 100644
--- a/vio/Makefile.am
+++ b/vio/Makefile.am
@@ -23,6 +23,3 @@ noinst_HEADERS = vio_priv.h
libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
EXTRA_DIST= CMakeLists.txt
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/win/Makefile.am b/win/Makefile.am
index 18bfe8ddf81..19a1b6a64d6 100644
--- a/win/Makefile.am
+++ b/win/Makefile.am
@@ -20,5 +20,3 @@ EXTRA_DIST = build-vs71.bat build-vs8.bat build-vs8_x64.bat build-vs9.bat \
build-nmake-x64.bat configure-mariadb.sh make_mariadb_win_dist \
build-vs10.bat build-vs10_x64.bat
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/zlib/Makefile.am b/zlib/Makefile.am
index edcbd5f4a75..277f6445a85 100644
--- a/zlib/Makefile.am
+++ b/zlib/Makefile.am
@@ -33,6 +33,3 @@ libz_la_SOURCES = adler32.c compress.c crc32.c deflate.c gzio.c \
libzlt_la_SOURCES = $(libz_la_SOURCES)
EXTRA_DIST= README FAQ INDEX ChangeLog algorithm.txt zlib.3 CMakeLists.txt
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%